From 6365b842aae4490ebfafadfc6bb27a6d3cc54757 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Wed, 3 Jul 2019 13:34:04 -0700 Subject: x86/syscalls: Split the x32 syscalls into their own table For unfortunate historical reasons, the x32 syscalls and the x86_64 syscalls are not all numbered the same. As an example, ioctl() is nr 16 on x86_64 but 514 on x32. This has potentially nasty consequences, since it means that there are two valid RAX values to do ioctl(2) and two invalid RAX values. The valid values are 16 (i.e. ioctl(2) using the x86_64 ABI) and (514 | 0x40000000) (i.e. ioctl(2) using the x32 ABI). The invalid values are 514 and (16 | 0x40000000). 514 will enter the "COMPAT_SYSCALL_DEFINE3(ioctl, ...)" entry point with in_compat_syscall() and in_x32_syscall() returning false, whereas (16 | 0x40000000) will enter the native entry point with in_compat_syscall() and in_x32_syscall() returning true. Both are bogus, and both will exercise code paths in the kernel and in any running seccomp filters that really ought to be unreachable. Splitting out the x32 syscalls into their own tables, allows both bogus invocations to return -ENOSYS. I've checked glibc, musl, and Bionic, and all of them appear to call syscalls with their correct numbers, so this change should have no effect on them. There is an added benefit going forward: new syscalls that need special handling on x32 can share the same number on x32 and x86_64. This means that the special syscall range 512-547 can be treated as a legacy wart instead of something that may need to be extended in the future. Also add a selftest to verify the new behavior. Signed-off-by: Andy Lutomirski Signed-off-by: Thomas Gleixner Link: https://lkml.kernel.org/r/208024256b764312598f014ebfb0a42472c19354.1562185330.git.luto@kernel.org --- tools/testing/selftests/x86/Makefile | 2 +- tools/testing/selftests/x86/syscall_numbering.c | 89 +++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/x86/syscall_numbering.c (limited to 'tools') diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index fa07d526fe39..07b6387f28cf 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile @@ -17,7 +17,7 @@ TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap TARGETS_C_32BIT_ONLY := entry_from_vm86 test_syscall_vdso unwind_vdso \ test_FCMOV test_FCOMI test_FISTTP \ vdso_restorer -TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip +TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip syscall_numbering # Some selftests require 32bit support enabled also on 64bit systems TARGETS_C_32BIT_NEEDED := ldt_gdt ptrace_syscall diff --git a/tools/testing/selftests/x86/syscall_numbering.c b/tools/testing/selftests/x86/syscall_numbering.c new file mode 100644 index 000000000000..d6b09cb1aa2c --- /dev/null +++ b/tools/testing/selftests/x86/syscall_numbering.c @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * syscall_arg_fault.c - tests faults 32-bit fast syscall stack args + * Copyright (c) 2018 Andrew Lutomirski + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include + +static int nerrs; + +#define X32_BIT 0x40000000UL + +static void check_enosys(unsigned long nr, bool *ok) +{ + /* If this fails, a segfault is reasonably likely. */ + fflush(stdout); + + long ret = syscall(nr, 0, 0, 0, 0, 0, 0); + if (ret == 0) { + printf("[FAIL]\tsyscall %lu succeeded, but it should have failed\n", nr); + *ok = false; + } else if (errno != ENOSYS) { + printf("[FAIL]\tsyscall %lu had error code %d, but it should have reported ENOSYS\n", nr, errno); + *ok = false; + } +} + +static void test_x32_without_x32_bit(void) +{ + bool ok = true; + + /* + * Syscalls 512-547 are "x32" syscalls. They are intended to be + * called with the x32 (0x40000000) bit set. Calling them without + * the x32 bit set is nonsense and should not work. + */ + printf("[RUN]\tChecking syscalls 512-547\n"); + for (int i = 512; i <= 547; i++) + check_enosys(i, &ok); + + /* + * Check that a handful of 64-bit-only syscalls are rejected if the x32 + * bit is set. + */ + printf("[RUN]\tChecking some 64-bit syscalls in x32 range\n"); + check_enosys(16 | X32_BIT, &ok); /* ioctl */ + check_enosys(19 | X32_BIT, &ok); /* readv */ + check_enosys(20 | X32_BIT, &ok); /* writev */ + + /* + * Check some syscalls with high bits set. + */ + printf("[RUN]\tChecking numbers above 2^32-1\n"); + check_enosys((1UL << 32), &ok); + check_enosys(X32_BIT | (1UL << 32), &ok); + + if (!ok) + nerrs++; + else + printf("[OK]\tThey all returned -ENOSYS\n"); +} + +int main() +{ + /* + * Anyone diagnosing a failure will want to know whether the kernel + * supports x32. Tell them. + */ + printf("\tChecking for x32..."); + fflush(stdout); + if (syscall(39 | X32_BIT, 0, 0, 0, 0, 0, 0) >= 0) { + printf(" supported\n"); + } else if (errno == ENOSYS) { + printf(" not supported\n"); + } else { + printf(" confused\n"); + } + + test_x32_without_x32_bit(); + + return nerrs ? 1 : 0; +} -- cgit v1.2.3-59-g8ed1b From 48febc03e6c239d96f46d8b38d91863769fc18c8 Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Fri, 5 Jul 2019 10:53:18 -0700 Subject: x86/mpx: Remove selftests Makefile entry MPX is being removed from the kernel due to a lack of support in the toolchain going forward (gcc). This is the smallest possible patch to fix some issues that have been reported around running the MPX selftests. It it would also have been part of any removal series, it is offered first. Signed-off-by: Dave Hansen Signed-off-by: Thomas Gleixner Link: https://lkml.kernel.org/r/20190705175318.784C233E@viggo.jf.intel.com --- tools/testing/selftests/x86/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index fa07d526fe39..3bc5b744e644 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile @@ -11,7 +11,7 @@ CAN_BUILD_X86_64 := $(shell ./check_cc.sh $(CC) trivial_64bit_program.c) CAN_BUILD_WITH_NOPIE := $(shell ./check_cc.sh $(CC) trivial_program.c -no-pie) TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap_vdso \ - check_initial_reg_state sigreturn iopl mpx-mini-test ioperm \ + check_initial_reg_state sigreturn iopl ioperm \ protection_keys test_vdso test_vsyscall mov_ss_trap \ syscall_arg_fault TARGETS_C_32BIT_ONLY := entry_from_vm86 test_syscall_vdso unwind_vdso \ -- cgit v1.2.3-59-g8ed1b From e28df79ae2dfebf18e08dc66c0948b7950e4368a Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Fri, 5 Jul 2019 10:53:20 -0700 Subject: x86/mpx: Remove selftests themselves MPX is being removed from the kernel due to a lack of support in the toolchain going forward (gcc). Remove the x86 selftests since they have been causing some issues because of their propensity to do some debug-aiding tracepoint mucking. Signed-off-by: Dave Hansen Signed-off-by: Thomas Gleixner Link: https://lkml.kernel.org/r/20190705175320.6542F8AE@viggo.jf.intel.com --- tools/testing/selftests/x86/mpx-debug.h | 15 - tools/testing/selftests/x86/mpx-dig.c | 497 --------- tools/testing/selftests/x86/mpx-hw.h | 124 -- tools/testing/selftests/x86/mpx-mini-test.c | 1613 --------------------------- tools/testing/selftests/x86/mpx-mm.h | 10 - 5 files changed, 2259 deletions(-) delete mode 100644 tools/testing/selftests/x86/mpx-debug.h delete mode 100644 tools/testing/selftests/x86/mpx-dig.c delete mode 100644 tools/testing/selftests/x86/mpx-hw.h delete mode 100644 tools/testing/selftests/x86/mpx-mini-test.c delete mode 100644 tools/testing/selftests/x86/mpx-mm.h (limited to 'tools') diff --git a/tools/testing/selftests/x86/mpx-debug.h b/tools/testing/selftests/x86/mpx-debug.h deleted file mode 100644 index 7546eba7f17a..000000000000 --- a/tools/testing/selftests/x86/mpx-debug.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _MPX_DEBUG_H -#define _MPX_DEBUG_H - -#ifndef DEBUG_LEVEL -#define DEBUG_LEVEL 0 -#endif -#define dprintf_level(level, args...) do { if(level <= DEBUG_LEVEL) printf(args); } while(0) -#define dprintf1(args...) dprintf_level(1, args) -#define dprintf2(args...) dprintf_level(2, args) -#define dprintf3(args...) dprintf_level(3, args) -#define dprintf4(args...) dprintf_level(4, args) -#define dprintf5(args...) dprintf_level(5, args) - -#endif /* _MPX_DEBUG_H */ diff --git a/tools/testing/selftests/x86/mpx-dig.c b/tools/testing/selftests/x86/mpx-dig.c deleted file mode 100644 index 880fbf676968..000000000000 --- a/tools/testing/selftests/x86/mpx-dig.c +++ /dev/null @@ -1,497 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Written by Dave Hansen - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "mpx-debug.h" -#include "mpx-mm.h" -#include "mpx-hw.h" - -unsigned long bounds_dir_global; - -#define mpx_dig_abort() __mpx_dig_abort(__FILE__, __func__, __LINE__) -static void inline __mpx_dig_abort(const char *file, const char *func, int line) -{ - fprintf(stderr, "MPX dig abort @ %s::%d in %s()\n", file, line, func); - printf("MPX dig abort @ %s::%d in %s()\n", file, line, func); - abort(); -} - -/* - * run like this (BDIR finds the probably bounds directory): - * - * BDIR="$(cat /proc/$pid/smaps | grep -B1 2097152 \ - * | head -1 | awk -F- '{print $1}')"; - * ./mpx-dig $pid 0x$BDIR - * - * NOTE: - * assumes that the only 2097152-kb VMA is the bounds dir - */ - -long nr_incore(void *ptr, unsigned long size_bytes) -{ - int i; - long ret = 0; - long vec_len = size_bytes / PAGE_SIZE; - unsigned char *vec = malloc(vec_len); - int incore_ret; - - if (!vec) - mpx_dig_abort(); - - incore_ret = mincore(ptr, size_bytes, vec); - if (incore_ret) { - printf("mincore ret: %d\n", incore_ret); - perror("mincore"); - mpx_dig_abort(); - } - for (i = 0; i < vec_len; i++) - ret += vec[i]; - free(vec); - return ret; -} - -int open_proc(int pid, char *file) -{ - static char buf[100]; - int fd; - - snprintf(&buf[0], sizeof(buf), "/proc/%d/%s", pid, file); - fd = open(&buf[0], O_RDONLY); - if (fd < 0) - perror(buf); - - return fd; -} - -struct vaddr_range { - unsigned long start; - unsigned long end; -}; -struct vaddr_range *ranges; -int nr_ranges_allocated; -int nr_ranges_populated; -int last_range = -1; - -int __pid_load_vaddrs(int pid) -{ - int ret = 0; - int proc_maps_fd = open_proc(pid, "maps"); - char linebuf[10000]; - unsigned long start; - unsigned long end; - char rest[1000]; - FILE *f = fdopen(proc_maps_fd, "r"); - - if (!f) - mpx_dig_abort(); - nr_ranges_populated = 0; - while (!feof(f)) { - char *readret = fgets(linebuf, sizeof(linebuf), f); - int parsed; - - if (readret == NULL) { - if (feof(f)) - break; - mpx_dig_abort(); - } - - parsed = sscanf(linebuf, "%lx-%lx%s", &start, &end, rest); - if (parsed != 3) - mpx_dig_abort(); - - dprintf4("result[%d]: %lx-%lx<->%s\n", parsed, start, end, rest); - if (nr_ranges_populated >= nr_ranges_allocated) { - ret = -E2BIG; - break; - } - ranges[nr_ranges_populated].start = start; - ranges[nr_ranges_populated].end = end; - nr_ranges_populated++; - } - last_range = -1; - fclose(f); - close(proc_maps_fd); - return ret; -} - -int pid_load_vaddrs(int pid) -{ - int ret; - - dprintf2("%s(%d)\n", __func__, pid); - if (!ranges) { - nr_ranges_allocated = 4; - ranges = malloc(nr_ranges_allocated * sizeof(ranges[0])); - dprintf2("%s(%d) allocated %d ranges @ %p\n", __func__, pid, - nr_ranges_allocated, ranges); - assert(ranges != NULL); - } - do { - ret = __pid_load_vaddrs(pid); - if (!ret) - break; - if (ret == -E2BIG) { - dprintf2("%s(%d) need to realloc\n", __func__, pid); - nr_ranges_allocated *= 2; - ranges = realloc(ranges, - nr_ranges_allocated * sizeof(ranges[0])); - dprintf2("%s(%d) allocated %d ranges @ %p\n", __func__, - pid, nr_ranges_allocated, ranges); - assert(ranges != NULL); - dprintf1("reallocating to hold %d ranges\n", nr_ranges_allocated); - } - } while (1); - - dprintf2("%s(%d) done\n", __func__, pid); - - return ret; -} - -static inline int vaddr_in_range(unsigned long vaddr, struct vaddr_range *r) -{ - if (vaddr < r->start) - return 0; - if (vaddr >= r->end) - return 0; - return 1; -} - -static inline int vaddr_mapped_by_range(unsigned long vaddr) -{ - int i; - - if (last_range > 0 && vaddr_in_range(vaddr, &ranges[last_range])) - return 1; - - for (i = 0; i < nr_ranges_populated; i++) { - struct vaddr_range *r = &ranges[i]; - - if (vaddr_in_range(vaddr, r)) - continue; - last_range = i; - return 1; - } - return 0; -} - -const int bt_entry_size_bytes = sizeof(unsigned long) * 4; - -void *read_bounds_table_into_buf(unsigned long table_vaddr) -{ -#ifdef MPX_DIG_STANDALONE - static char bt_buf[MPX_BOUNDS_TABLE_SIZE_BYTES]; - off_t seek_ret = lseek(fd, table_vaddr, SEEK_SET); - if (seek_ret != table_vaddr) - mpx_dig_abort(); - - int read_ret = read(fd, &bt_buf, sizeof(bt_buf)); - if (read_ret != sizeof(bt_buf)) - mpx_dig_abort(); - return &bt_buf; -#else - return (void *)table_vaddr; -#endif -} - -int dump_table(unsigned long table_vaddr, unsigned long base_controlled_vaddr, - unsigned long bde_vaddr) -{ - unsigned long offset_inside_bt; - int nr_entries = 0; - int do_abort = 0; - char *bt_buf; - - dprintf3("%s() base_controlled_vaddr: 0x%012lx bde_vaddr: 0x%012lx\n", - __func__, base_controlled_vaddr, bde_vaddr); - - bt_buf = read_bounds_table_into_buf(table_vaddr); - - dprintf4("%s() read done\n", __func__); - - for (offset_inside_bt = 0; - offset_inside_bt < MPX_BOUNDS_TABLE_SIZE_BYTES; - offset_inside_bt += bt_entry_size_bytes) { - unsigned long bt_entry_index; - unsigned long bt_entry_controls; - unsigned long this_bt_entry_for_vaddr; - unsigned long *bt_entry_buf; - int i; - - dprintf4("%s() offset_inside_bt: 0x%lx of 0x%llx\n", __func__, - offset_inside_bt, MPX_BOUNDS_TABLE_SIZE_BYTES); - bt_entry_buf = (void *)&bt_buf[offset_inside_bt]; - if (!bt_buf) { - printf("null bt_buf\n"); - mpx_dig_abort(); - } - if (!bt_entry_buf) { - printf("null bt_entry_buf\n"); - mpx_dig_abort(); - } - dprintf4("%s() reading *bt_entry_buf @ %p\n", __func__, - bt_entry_buf); - if (!bt_entry_buf[0] && - !bt_entry_buf[1] && - !bt_entry_buf[2] && - !bt_entry_buf[3]) - continue; - - nr_entries++; - - bt_entry_index = offset_inside_bt/bt_entry_size_bytes; - bt_entry_controls = sizeof(void *); - this_bt_entry_for_vaddr = - base_controlled_vaddr + bt_entry_index*bt_entry_controls; - /* - * We sign extend vaddr bits 48->63 which effectively - * creates a hole in the virtual address space. - * This calculation corrects for the hole. - */ - if (this_bt_entry_for_vaddr > 0x00007fffffffffffUL) - this_bt_entry_for_vaddr |= 0xffff800000000000; - - if (!vaddr_mapped_by_range(this_bt_entry_for_vaddr)) { - printf("bt_entry_buf: %p\n", bt_entry_buf); - printf("there is a bte for %lx but no mapping\n", - this_bt_entry_for_vaddr); - printf(" bde vaddr: %016lx\n", bde_vaddr); - printf("base_controlled_vaddr: %016lx\n", base_controlled_vaddr); - printf(" table_vaddr: %016lx\n", table_vaddr); - printf(" entry vaddr: %016lx @ offset %lx\n", - table_vaddr + offset_inside_bt, offset_inside_bt); - do_abort = 1; - mpx_dig_abort(); - } - if (DEBUG_LEVEL < 4) - continue; - - printf("table entry[%lx]: ", offset_inside_bt); - for (i = 0; i < bt_entry_size_bytes; i += sizeof(unsigned long)) - printf("0x%016lx ", bt_entry_buf[i]); - printf("\n"); - } - if (do_abort) - mpx_dig_abort(); - dprintf4("%s() done\n", __func__); - return nr_entries; -} - -int search_bd_buf(char *buf, int len_bytes, unsigned long bd_offset_bytes, - int *nr_populated_bdes) -{ - unsigned long i; - int total_entries = 0; - - dprintf3("%s(%p, %x, %lx, ...) buf end: %p\n", __func__, buf, - len_bytes, bd_offset_bytes, buf + len_bytes); - - for (i = 0; i < len_bytes; i += sizeof(unsigned long)) { - unsigned long bd_index = (bd_offset_bytes + i) / sizeof(unsigned long); - unsigned long *bounds_dir_entry_ptr = (unsigned long *)&buf[i]; - unsigned long bounds_dir_entry; - unsigned long bd_for_vaddr; - unsigned long bt_start; - unsigned long bt_tail; - int nr_entries; - - dprintf4("%s() loop i: %ld bounds_dir_entry_ptr: %p\n", __func__, i, - bounds_dir_entry_ptr); - - bounds_dir_entry = *bounds_dir_entry_ptr; - if (!bounds_dir_entry) { - dprintf4("no bounds dir at index 0x%lx / 0x%lx " - "start at offset:%lx %lx\n", bd_index, bd_index, - bd_offset_bytes, i); - continue; - } - dprintf3("found bounds_dir_entry: 0x%lx @ " - "index 0x%lx buf ptr: %p\n", bounds_dir_entry, i, - &buf[i]); - /* mask off the enable bit: */ - bounds_dir_entry &= ~0x1; - (*nr_populated_bdes)++; - dprintf4("nr_populated_bdes: %p\n", nr_populated_bdes); - dprintf4("*nr_populated_bdes: %d\n", *nr_populated_bdes); - - bt_start = bounds_dir_entry; - bt_tail = bounds_dir_entry + MPX_BOUNDS_TABLE_SIZE_BYTES - 1; - if (!vaddr_mapped_by_range(bt_start)) { - printf("bounds directory 0x%lx points to nowhere\n", - bounds_dir_entry); - mpx_dig_abort(); - } - if (!vaddr_mapped_by_range(bt_tail)) { - printf("bounds directory end 0x%lx points to nowhere\n", - bt_tail); - mpx_dig_abort(); - } - /* - * Each bounds directory entry controls 1MB of virtual address - * space. This variable is the virtual address in the process - * of the beginning of the area controlled by this bounds_dir. - */ - bd_for_vaddr = bd_index * (1UL<<20); - - nr_entries = dump_table(bounds_dir_entry, bd_for_vaddr, - bounds_dir_global+bd_offset_bytes+i); - total_entries += nr_entries; - dprintf5("dir entry[%4ld @ %p]: 0x%lx %6d entries " - "total this buf: %7d bd_for_vaddrs: 0x%lx -> 0x%lx\n", - bd_index, buf+i, - bounds_dir_entry, nr_entries, total_entries, - bd_for_vaddr, bd_for_vaddr + (1UL<<20)); - } - dprintf3("%s(%p, %x, %lx, ...) done\n", __func__, buf, len_bytes, - bd_offset_bytes); - return total_entries; -} - -int proc_pid_mem_fd = -1; - -void *fill_bounds_dir_buf_other(long byte_offset_inside_bounds_dir, - long buffer_size_bytes, void *buffer) -{ - unsigned long seekto = bounds_dir_global + byte_offset_inside_bounds_dir; - int read_ret; - off_t seek_ret = lseek(proc_pid_mem_fd, seekto, SEEK_SET); - - if (seek_ret != seekto) - mpx_dig_abort(); - - read_ret = read(proc_pid_mem_fd, buffer, buffer_size_bytes); - /* there shouldn't practically be short reads of /proc/$pid/mem */ - if (read_ret != buffer_size_bytes) - mpx_dig_abort(); - - return buffer; -} -void *fill_bounds_dir_buf_self(long byte_offset_inside_bounds_dir, - long buffer_size_bytes, void *buffer) - -{ - unsigned char vec[buffer_size_bytes / PAGE_SIZE]; - char *dig_bounds_dir_ptr = - (void *)(bounds_dir_global + byte_offset_inside_bounds_dir); - /* - * use mincore() to quickly find the areas of the bounds directory - * that have memory and thus will be worth scanning. - */ - int incore_ret; - - int incore = 0; - int i; - - dprintf4("%s() dig_bounds_dir_ptr: %p\n", __func__, dig_bounds_dir_ptr); - - incore_ret = mincore(dig_bounds_dir_ptr, buffer_size_bytes, &vec[0]); - if (incore_ret) { - printf("mincore ret: %d\n", incore_ret); - perror("mincore"); - mpx_dig_abort(); - } - for (i = 0; i < sizeof(vec); i++) - incore += vec[i]; - dprintf4("%s() total incore: %d\n", __func__, incore); - if (!incore) - return NULL; - dprintf3("%s() total incore: %d\n", __func__, incore); - return dig_bounds_dir_ptr; -} - -int inspect_pid(int pid) -{ - static int dig_nr; - long offset_inside_bounds_dir; - char bounds_dir_buf[sizeof(unsigned long) * (1UL << 15)]; - char *dig_bounds_dir_ptr; - int total_entries = 0; - int nr_populated_bdes = 0; - int inspect_self; - - if (getpid() == pid) { - dprintf4("inspecting self\n"); - inspect_self = 1; - } else { - dprintf4("inspecting pid %d\n", pid); - mpx_dig_abort(); - } - - for (offset_inside_bounds_dir = 0; - offset_inside_bounds_dir < MPX_BOUNDS_TABLE_SIZE_BYTES; - offset_inside_bounds_dir += sizeof(bounds_dir_buf)) { - static int bufs_skipped; - int this_entries; - - if (inspect_self) { - dig_bounds_dir_ptr = - fill_bounds_dir_buf_self(offset_inside_bounds_dir, - sizeof(bounds_dir_buf), - &bounds_dir_buf[0]); - } else { - dig_bounds_dir_ptr = - fill_bounds_dir_buf_other(offset_inside_bounds_dir, - sizeof(bounds_dir_buf), - &bounds_dir_buf[0]); - } - if (!dig_bounds_dir_ptr) { - bufs_skipped++; - continue; - } - this_entries = search_bd_buf(dig_bounds_dir_ptr, - sizeof(bounds_dir_buf), - offset_inside_bounds_dir, - &nr_populated_bdes); - total_entries += this_entries; - } - printf("mpx dig (%3d) complete, SUCCESS (%8d / %4d)\n", ++dig_nr, - total_entries, nr_populated_bdes); - return total_entries + nr_populated_bdes; -} - -#ifdef MPX_DIG_REMOTE -int main(int argc, char **argv) -{ - int err; - char *c; - unsigned long bounds_dir_entry; - int pid; - - printf("mpx-dig starting...\n"); - err = sscanf(argv[1], "%d", &pid); - printf("parsing: '%s', err: %d\n", argv[1], err); - if (err != 1) - mpx_dig_abort(); - - err = sscanf(argv[2], "%lx", &bounds_dir_global); - printf("parsing: '%s': %d\n", argv[2], err); - if (err != 1) - mpx_dig_abort(); - - proc_pid_mem_fd = open_proc(pid, "mem"); - if (proc_pid_mem_fd < 0) - mpx_dig_abort(); - - inspect_pid(pid); - return 0; -} -#endif - -long inspect_me(struct mpx_bounds_dir *bounds_dir) -{ - int pid = getpid(); - - pid_load_vaddrs(pid); - bounds_dir_global = (unsigned long)bounds_dir; - dprintf4("enter %s() bounds dir: %p\n", __func__, bounds_dir); - return inspect_pid(pid); -} diff --git a/tools/testing/selftests/x86/mpx-hw.h b/tools/testing/selftests/x86/mpx-hw.h deleted file mode 100644 index d1b61ab870f8..000000000000 --- a/tools/testing/selftests/x86/mpx-hw.h +++ /dev/null @@ -1,124 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _MPX_HW_H -#define _MPX_HW_H - -#include - -/* Describe the MPX Hardware Layout in here */ - -#define NR_MPX_BOUNDS_REGISTERS 4 - -#ifdef __i386__ - -#define MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES 16 /* 4 * 32-bits */ -#define MPX_BOUNDS_TABLE_SIZE_BYTES (1ULL << 14) /* 16k */ -#define MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES 4 -#define MPX_BOUNDS_DIR_SIZE_BYTES (1ULL << 22) /* 4MB */ - -#define MPX_BOUNDS_TABLE_BOTTOM_BIT 2 -#define MPX_BOUNDS_TABLE_TOP_BIT 11 -#define MPX_BOUNDS_DIR_BOTTOM_BIT 12 -#define MPX_BOUNDS_DIR_TOP_BIT 31 - -#else - -/* - * Linear Address of "pointer" (LAp) - * 0 -> 2: ignored - * 3 -> 19: index in to bounds table - * 20 -> 47: index in to bounds directory - * 48 -> 63: ignored - */ - -#define MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES 32 -#define MPX_BOUNDS_TABLE_SIZE_BYTES (1ULL << 22) /* 4MB */ -#define MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES 8 -#define MPX_BOUNDS_DIR_SIZE_BYTES (1ULL << 31) /* 2GB */ - -#define MPX_BOUNDS_TABLE_BOTTOM_BIT 3 -#define MPX_BOUNDS_TABLE_TOP_BIT 19 -#define MPX_BOUNDS_DIR_BOTTOM_BIT 20 -#define MPX_BOUNDS_DIR_TOP_BIT 47 - -#endif - -#define MPX_BOUNDS_DIR_NR_ENTRIES \ - (MPX_BOUNDS_DIR_SIZE_BYTES/MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES) -#define MPX_BOUNDS_TABLE_NR_ENTRIES \ - (MPX_BOUNDS_TABLE_SIZE_BYTES/MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES) - -#define MPX_BOUNDS_TABLE_ENTRY_VALID_BIT 0x1 - -struct mpx_bd_entry { - union { - char x[MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES]; - void *contents[0]; - }; -} __attribute__((packed)); - -struct mpx_bt_entry { - union { - char x[MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES]; - unsigned long contents[0]; - }; -} __attribute__((packed)); - -struct mpx_bounds_dir { - struct mpx_bd_entry entries[MPX_BOUNDS_DIR_NR_ENTRIES]; -} __attribute__((packed)); - -struct mpx_bounds_table { - struct mpx_bt_entry entries[MPX_BOUNDS_TABLE_NR_ENTRIES]; -} __attribute__((packed)); - -static inline unsigned long GET_BITS(unsigned long val, int bottombit, int topbit) -{ - int total_nr_bits = topbit - bottombit; - unsigned long mask = (1UL << total_nr_bits)-1; - return (val >> bottombit) & mask; -} - -static inline unsigned long __vaddr_bounds_table_index(void *vaddr) -{ - return GET_BITS((unsigned long)vaddr, MPX_BOUNDS_TABLE_BOTTOM_BIT, - MPX_BOUNDS_TABLE_TOP_BIT); -} - -static inline unsigned long __vaddr_bounds_directory_index(void *vaddr) -{ - return GET_BITS((unsigned long)vaddr, MPX_BOUNDS_DIR_BOTTOM_BIT, - MPX_BOUNDS_DIR_TOP_BIT); -} - -static inline struct mpx_bd_entry *mpx_vaddr_to_bd_entry(void *vaddr, - struct mpx_bounds_dir *bounds_dir) -{ - unsigned long index = __vaddr_bounds_directory_index(vaddr); - return &bounds_dir->entries[index]; -} - -static inline int bd_entry_valid(struct mpx_bd_entry *bounds_dir_entry) -{ - unsigned long __bd_entry = (unsigned long)bounds_dir_entry->contents; - return (__bd_entry & MPX_BOUNDS_TABLE_ENTRY_VALID_BIT); -} - -static inline struct mpx_bounds_table * -__bd_entry_to_bounds_table(struct mpx_bd_entry *bounds_dir_entry) -{ - unsigned long __bd_entry = (unsigned long)bounds_dir_entry->contents; - assert(__bd_entry & MPX_BOUNDS_TABLE_ENTRY_VALID_BIT); - __bd_entry &= ~MPX_BOUNDS_TABLE_ENTRY_VALID_BIT; - return (struct mpx_bounds_table *)__bd_entry; -} - -static inline struct mpx_bt_entry * -mpx_vaddr_to_bt_entry(void *vaddr, struct mpx_bounds_dir *bounds_dir) -{ - struct mpx_bd_entry *bde = mpx_vaddr_to_bd_entry(vaddr, bounds_dir); - struct mpx_bounds_table *bt = __bd_entry_to_bounds_table(bde); - unsigned long index = __vaddr_bounds_table_index(vaddr); - return &bt->entries[index]; -} - -#endif /* _MPX_HW_H */ diff --git a/tools/testing/selftests/x86/mpx-mini-test.c b/tools/testing/selftests/x86/mpx-mini-test.c deleted file mode 100644 index 23ddd453f362..000000000000 --- a/tools/testing/selftests/x86/mpx-mini-test.c +++ /dev/null @@ -1,1613 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * mpx-mini-test.c: routines to test Intel MPX (Memory Protection eXtentions) - * - * Written by: - * "Ren, Qiaowei" - * "Wei, Gang" - * "Hansen, Dave" - */ - -/* - * 2014-12-05: Dave Hansen: fixed all of the compiler warnings, and made sure - * it works on 32-bit. - */ - -int inspect_every_this_many_mallocs = 100; -int zap_all_every_this_many_mallocs = 1000; - -#define _GNU_SOURCE -#define _LARGEFILE64_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mpx-hw.h" -#include "mpx-debug.h" -#include "mpx-mm.h" - -#ifndef __always_inline -#define __always_inline inline __attribute__((always_inline) -#endif - -#ifndef TEST_DURATION_SECS -#define TEST_DURATION_SECS 3 -#endif - -void write_int_to(char *prefix, char *file, int int_to_write) -{ - char buf[100]; - int fd = open(file, O_RDWR); - int len; - int ret; - - assert(fd >= 0); - len = snprintf(buf, sizeof(buf), "%s%d", prefix, int_to_write); - assert(len >= 0); - assert(len < sizeof(buf)); - ret = write(fd, buf, len); - assert(ret == len); - ret = close(fd); - assert(!ret); -} - -void write_pid_to(char *prefix, char *file) -{ - write_int_to(prefix, file, getpid()); -} - -void trace_me(void) -{ -/* tracing events dir */ -#define TED "/sys/kernel/debug/tracing/events/" -/* - write_pid_to("common_pid=", TED "signal/filter"); - write_pid_to("common_pid=", TED "exceptions/filter"); - write_int_to("", TED "signal/enable", 1); - write_int_to("", TED "exceptions/enable", 1); -*/ - write_pid_to("", "/sys/kernel/debug/tracing/set_ftrace_pid"); - write_int_to("", "/sys/kernel/debug/tracing/trace", 0); -} - -#define test_failed() __test_failed(__FILE__, __LINE__) -static void __test_failed(char *f, int l) -{ - fprintf(stderr, "abort @ %s::%d\n", f, l); - abort(); -} - -/* Error Printf */ -#define eprintf(args...) fprintf(stderr, args) - -#ifdef __i386__ - -/* i386 directory size is 4MB */ -#define REG_IP_IDX REG_EIP -#define REX_PREFIX - -#define XSAVE_OFFSET_IN_FPMEM sizeof(struct _libc_fpstate) - -/* - * __cpuid() is from the Linux Kernel: - */ -static inline void __cpuid(unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) -{ - /* ecx is often an input as well as an output. */ - asm volatile( - "push %%ebx;" - "cpuid;" - "mov %%ebx, %1;" - "pop %%ebx" - : "=a" (*eax), - "=g" (*ebx), - "=c" (*ecx), - "=d" (*edx) - : "0" (*eax), "2" (*ecx)); -} - -#else /* __i386__ */ - -#define REG_IP_IDX REG_RIP -#define REX_PREFIX "0x48, " - -#define XSAVE_OFFSET_IN_FPMEM 0 - -/* - * __cpuid() is from the Linux Kernel: - */ -static inline void __cpuid(unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) -{ - /* ecx is often an input as well as an output. */ - asm volatile( - "cpuid;" - : "=a" (*eax), - "=b" (*ebx), - "=c" (*ecx), - "=d" (*edx) - : "0" (*eax), "2" (*ecx)); -} - -#endif /* !__i386__ */ - -struct xsave_hdr_struct { - uint64_t xstate_bv; - uint64_t reserved1[2]; - uint64_t reserved2[5]; -} __attribute__((packed)); - -struct bndregs_struct { - uint64_t bndregs[8]; -} __attribute__((packed)); - -struct bndcsr_struct { - uint64_t cfg_reg_u; - uint64_t status_reg; -} __attribute__((packed)); - -struct xsave_struct { - uint8_t fpu_sse[512]; - struct xsave_hdr_struct xsave_hdr; - uint8_t ymm[256]; - uint8_t lwp[128]; - struct bndregs_struct bndregs; - struct bndcsr_struct bndcsr; -} __attribute__((packed)); - -uint8_t __attribute__((__aligned__(64))) buffer[4096]; -struct xsave_struct *xsave_buf = (struct xsave_struct *)buffer; - -uint8_t __attribute__((__aligned__(64))) test_buffer[4096]; -struct xsave_struct *xsave_test_buf = (struct xsave_struct *)test_buffer; - -uint64_t num_bnd_chk; - -static __always_inline void xrstor_state(struct xsave_struct *fx, uint64_t mask) -{ - uint32_t lmask = mask; - uint32_t hmask = mask >> 32; - - asm volatile(".byte " REX_PREFIX "0x0f,0xae,0x2f\n\t" - : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) - : "memory"); -} - -static __always_inline void xsave_state_1(void *_fx, uint64_t mask) -{ - uint32_t lmask = mask; - uint32_t hmask = mask >> 32; - unsigned char *fx = _fx; - - asm volatile(".byte " REX_PREFIX "0x0f,0xae,0x27\n\t" - : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) - : "memory"); -} - -static inline uint64_t xgetbv(uint32_t index) -{ - uint32_t eax, edx; - - asm volatile(".byte 0x0f,0x01,0xd0" /* xgetbv */ - : "=a" (eax), "=d" (edx) - : "c" (index)); - return eax + ((uint64_t)edx << 32); -} - -static uint64_t read_mpx_status_sig(ucontext_t *uctxt) -{ - memset(buffer, 0, sizeof(buffer)); - memcpy(buffer, - (uint8_t *)uctxt->uc_mcontext.fpregs + XSAVE_OFFSET_IN_FPMEM, - sizeof(struct xsave_struct)); - - return xsave_buf->bndcsr.status_reg; -} - -#include - -static uint8_t *get_next_inst_ip(uint8_t *addr) -{ - uint8_t *ip = addr; - uint8_t sib; - uint8_t rm; - uint8_t mod; - uint8_t base; - uint8_t modrm; - - /* determine the prefix. */ - switch(*ip) { - case 0xf2: - case 0xf3: - case 0x66: - ip++; - break; - } - - /* look for rex prefix */ - if ((*ip & 0x40) == 0x40) - ip++; - - /* Make sure we have a MPX instruction. */ - if (*ip++ != 0x0f) - return addr; - - /* Skip the op code byte. */ - ip++; - - /* Get the modrm byte. */ - modrm = *ip++; - - /* Break it down into parts. */ - rm = modrm & 7; - mod = (modrm >> 6); - - /* Init the parts of the address mode. */ - base = 8; - - /* Is it a mem mode? */ - if (mod != 3) { - /* look for scaled indexed addressing */ - if (rm == 4) { - /* SIB addressing */ - sib = *ip++; - base = sib & 7; - switch (mod) { - case 0: - if (base == 5) - ip += 4; - break; - - case 1: - ip++; - break; - - case 2: - ip += 4; - break; - } - - } else { - /* MODRM addressing */ - switch (mod) { - case 0: - /* DISP32 addressing, no base */ - if (rm == 5) - ip += 4; - break; - - case 1: - ip++; - break; - - case 2: - ip += 4; - break; - } - } - } - return ip; -} - -#ifdef si_lower -static inline void *__si_bounds_lower(siginfo_t *si) -{ - return si->si_lower; -} - -static inline void *__si_bounds_upper(siginfo_t *si) -{ - return si->si_upper; -} -#else - -/* - * This deals with old version of _sigfault in some distros: - * - -old _sigfault: - struct { - void *si_addr; - } _sigfault; - -new _sigfault: - struct { - void __user *_addr; - int _trapno; - short _addr_lsb; - union { - struct { - void __user *_lower; - void __user *_upper; - } _addr_bnd; - __u32 _pkey; - }; - } _sigfault; - * - */ - -static inline void **__si_bounds_hack(siginfo_t *si) -{ - void *sigfault = &si->_sifields._sigfault; - void *end_sigfault = sigfault + sizeof(si->_sifields._sigfault); - int *trapno = (int*)end_sigfault; - /* skip _trapno and _addr_lsb */ - void **__si_lower = (void**)(trapno + 2); - - return __si_lower; -} - -static inline void *__si_bounds_lower(siginfo_t *si) -{ - return *__si_bounds_hack(si); -} - -static inline void *__si_bounds_upper(siginfo_t *si) -{ - return *(__si_bounds_hack(si) + 1); -} -#endif - -static int br_count; -static int expected_bnd_index = -1; -uint64_t shadow_plb[NR_MPX_BOUNDS_REGISTERS][2]; /* shadow MPX bound registers */ -unsigned long shadow_map[NR_MPX_BOUNDS_REGISTERS]; - -/* Failed address bound checks: */ -#ifndef SEGV_BNDERR -# define SEGV_BNDERR 3 -#endif - -/* - * The kernel is supposed to provide some information about the bounds - * exception in the siginfo. It should match what we have in the bounds - * registers that we are checking against. Just check against the shadow copy - * since it is easily available, and we also check that *it* matches the real - * registers. - */ -void check_siginfo_vs_shadow(siginfo_t* si) -{ - int siginfo_ok = 1; - void *shadow_lower = (void *)(unsigned long)shadow_plb[expected_bnd_index][0]; - void *shadow_upper = (void *)(unsigned long)shadow_plb[expected_bnd_index][1]; - - if ((expected_bnd_index < 0) || - (expected_bnd_index >= NR_MPX_BOUNDS_REGISTERS)) { - fprintf(stderr, "ERROR: invalid expected_bnd_index: %d\n", - expected_bnd_index); - exit(6); - } - if (__si_bounds_lower(si) != shadow_lower) - siginfo_ok = 0; - if (__si_bounds_upper(si) != shadow_upper) - siginfo_ok = 0; - - if (!siginfo_ok) { - fprintf(stderr, "ERROR: siginfo bounds do not match " - "shadow bounds for register %d\n", expected_bnd_index); - exit(7); - } -} - -void handler(int signum, siginfo_t *si, void *vucontext) -{ - int i; - ucontext_t *uctxt = vucontext; - int trapno; - unsigned long ip; - - dprintf1("entered signal handler\n"); - - trapno = uctxt->uc_mcontext.gregs[REG_TRAPNO]; - ip = uctxt->uc_mcontext.gregs[REG_IP_IDX]; - - if (trapno == 5) { - typeof(si->si_addr) *si_addr_ptr = &si->si_addr; - uint64_t status = read_mpx_status_sig(uctxt); - uint64_t br_reason = status & 0x3; - - br_count++; - dprintf1("#BR 0x%jx (total seen: %d)\n", status, br_count); - - dprintf2("Saw a #BR! status 0x%jx at %016lx br_reason: %jx\n", - status, ip, br_reason); - dprintf2("si_signo: %d\n", si->si_signo); - dprintf2(" signum: %d\n", signum); - dprintf2("info->si_code == SEGV_BNDERR: %d\n", - (si->si_code == SEGV_BNDERR)); - dprintf2("info->si_code: %d\n", si->si_code); - dprintf2("info->si_lower: %p\n", __si_bounds_lower(si)); - dprintf2("info->si_upper: %p\n", __si_bounds_upper(si)); - - for (i = 0; i < 8; i++) - dprintf3("[%d]: %p\n", i, si_addr_ptr[i]); - switch (br_reason) { - case 0: /* traditional BR */ - fprintf(stderr, - "Undefined status with bound exception:%jx\n", - status); - exit(5); - case 1: /* #BR MPX bounds exception */ - /* these are normal and we expect to see them */ - - check_siginfo_vs_shadow(si); - - dprintf1("bounds exception (normal): status 0x%jx at %p si_addr: %p\n", - status, (void *)ip, si->si_addr); - num_bnd_chk++; - uctxt->uc_mcontext.gregs[REG_IP_IDX] = - (greg_t)get_next_inst_ip((uint8_t *)ip); - break; - case 2: - fprintf(stderr, "#BR status == 2, missing bounds table," - "kernel should have handled!!\n"); - exit(4); - break; - default: - fprintf(stderr, "bound check error: status 0x%jx at %p\n", - status, (void *)ip); - num_bnd_chk++; - uctxt->uc_mcontext.gregs[REG_IP_IDX] = - (greg_t)get_next_inst_ip((uint8_t *)ip); - fprintf(stderr, "bound check error: si_addr %p\n", si->si_addr); - exit(3); - } - } else if (trapno == 14) { - eprintf("ERROR: In signal handler, page fault, trapno = %d, ip = %016lx\n", - trapno, ip); - eprintf("si_addr %p\n", si->si_addr); - eprintf("REG_ERR: %lx\n", (unsigned long)uctxt->uc_mcontext.gregs[REG_ERR]); - test_failed(); - } else { - eprintf("unexpected trap %d! at 0x%lx\n", trapno, ip); - eprintf("si_addr %p\n", si->si_addr); - eprintf("REG_ERR: %lx\n", (unsigned long)uctxt->uc_mcontext.gregs[REG_ERR]); - test_failed(); - } -} - -static inline void cpuid_count(unsigned int op, int count, - unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) -{ - *eax = op; - *ecx = count; - __cpuid(eax, ebx, ecx, edx); -} - -#define XSTATE_CPUID 0x0000000d - -/* - * List of XSAVE features Linux knows about: - */ -enum xfeature_bit { - XSTATE_BIT_FP, - XSTATE_BIT_SSE, - XSTATE_BIT_YMM, - XSTATE_BIT_BNDREGS, - XSTATE_BIT_BNDCSR, - XSTATE_BIT_OPMASK, - XSTATE_BIT_ZMM_Hi256, - XSTATE_BIT_Hi16_ZMM, - - XFEATURES_NR_MAX, -}; - -#define XSTATE_FP (1 << XSTATE_BIT_FP) -#define XSTATE_SSE (1 << XSTATE_BIT_SSE) -#define XSTATE_YMM (1 << XSTATE_BIT_YMM) -#define XSTATE_BNDREGS (1 << XSTATE_BIT_BNDREGS) -#define XSTATE_BNDCSR (1 << XSTATE_BIT_BNDCSR) -#define XSTATE_OPMASK (1 << XSTATE_BIT_OPMASK) -#define XSTATE_ZMM_Hi256 (1 << XSTATE_BIT_ZMM_Hi256) -#define XSTATE_Hi16_ZMM (1 << XSTATE_BIT_Hi16_ZMM) - -#define MPX_XSTATES (XSTATE_BNDREGS | XSTATE_BNDCSR) /* 0x18 */ - -bool one_bit(unsigned int x, int bit) -{ - return !!(x & (1<xsave_hdr.xstate_bv = 0x10; - xsave_buf->bndcsr.cfg_reg_u = (unsigned long)l1base | 1; - xsave_buf->bndcsr.status_reg = 0; - - dprintf2("bf xrstor\n"); - dprintf2("xsave cndcsr: status %jx, configu %jx\n", - xsave_buf->bndcsr.status_reg, xsave_buf->bndcsr.cfg_reg_u); - xrstor_state(xsave_buf, 0x18); - dprintf2("after xrstor\n"); - - xsave_state_1(xsave_buf, 0x18); - - dprintf1("xsave bndcsr: status %jx, configu %jx\n", - xsave_buf->bndcsr.status_reg, xsave_buf->bndcsr.cfg_reg_u); -} - -#include - -struct mpx_bounds_dir *bounds_dir_ptr; - -unsigned long __bd_incore(const char *func, int line) -{ - unsigned long ret = nr_incore(bounds_dir_ptr, MPX_BOUNDS_DIR_SIZE_BYTES); - return ret; -} -#define bd_incore() __bd_incore(__func__, __LINE__) - -void check_clear(void *ptr, unsigned long sz) -{ - unsigned long *i; - - for (i = ptr; (void *)i < ptr + sz; i++) { - if (*i) { - dprintf1("%p is NOT clear at %p\n", ptr, i); - assert(0); - } - } - dprintf1("%p is clear for %lx\n", ptr, sz); -} - -void check_clear_bd(void) -{ - check_clear(bounds_dir_ptr, 2UL << 30); -} - -#define USE_MALLOC_FOR_BOUNDS_DIR 1 -bool process_specific_init(void) -{ - unsigned long size; - unsigned long *dir; - /* Guarantee we have the space to align it, add padding: */ - unsigned long pad = getpagesize(); - - size = 2UL << 30; /* 2GB */ - if (sizeof(unsigned long) == 4) - size = 4UL << 20; /* 4MB */ - dprintf1("trying to allocate %ld MB bounds directory\n", (size >> 20)); - - if (USE_MALLOC_FOR_BOUNDS_DIR) { - unsigned long _dir; - - dir = malloc(size + pad); - assert(dir); - _dir = (unsigned long)dir; - _dir += 0xfffUL; - _dir &= ~0xfffUL; - dir = (void *)_dir; - } else { - /* - * This makes debugging easier because the address - * calculations are simpler: - */ - dir = mmap((void *)0x200000000000, size + pad, - PROT_READ|PROT_WRITE, - MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); - if (dir == (void *)-1) { - perror("unable to allocate bounds directory"); - abort(); - } - check_clear(dir, size); - } - bounds_dir_ptr = (void *)dir; - madvise(bounds_dir_ptr, size, MADV_NOHUGEPAGE); - bd_incore(); - dprintf1("bounds directory: 0x%p -> 0x%p\n", bounds_dir_ptr, - (char *)bounds_dir_ptr + size); - check_clear(dir, size); - enable_mpx(dir); - check_clear(dir, size); - if (prctl(43, 0, 0, 0, 0)) { - printf("no MPX support\n"); - abort(); - return false; - } - return true; -} - -bool process_specific_finish(void) -{ - if (prctl(44)) { - printf("no MPX support\n"); - return false; - } - return true; -} - -void setup_handler() -{ - int r, rs; - struct sigaction newact; - struct sigaction oldact; - - /* #BR is mapped to sigsegv */ - int signum = SIGSEGV; - - newact.sa_handler = 0; /* void(*)(int)*/ - newact.sa_sigaction = handler; /* void (*)(int, siginfo_t*, void *) */ - - /*sigset_t - signals to block while in the handler */ - /* get the old signal mask. */ - rs = sigprocmask(SIG_SETMASK, 0, &newact.sa_mask); - assert(rs == 0); - - /* call sa_sigaction, not sa_handler*/ - newact.sa_flags = SA_SIGINFO; - - newact.sa_restorer = 0; /* void(*)(), obsolete */ - r = sigaction(signum, &newact, &oldact); - assert(r == 0); -} - -void mpx_prepare(void) -{ - dprintf2("%s()\n", __func__); - setup_handler(); - process_specific_init(); -} - -void mpx_cleanup(void) -{ - printf("%s(): %jd BRs. bye...\n", __func__, num_bnd_chk); - process_specific_finish(); -} - -/*-------------- the following is test case ---------------*/ -#include -#include -#include -#include -#include - -uint64_t num_lower_brs; -uint64_t num_upper_brs; - -#define MPX_CONFIG_OFFSET 1024 -#define MPX_BOUNDS_OFFSET 960 -#define MPX_HEADER_OFFSET 512 -#define MAX_ADDR_TESTED (1<<28) -#define TEST_ROUNDS 100 - -/* - 0F 1A /r BNDLDX-Load - 0F 1B /r BNDSTX-Store Extended Bounds Using Address Translation - 66 0F 1A /r BNDMOV bnd1, bnd2/m128 - 66 0F 1B /r BNDMOV bnd1/m128, bnd2 - F2 0F 1A /r BNDCU bnd, r/m64 - F2 0F 1B /r BNDCN bnd, r/m64 - F3 0F 1A /r BNDCL bnd, r/m64 - F3 0F 1B /r BNDMK bnd, m64 -*/ - -static __always_inline void xsave_state(void *_fx, uint64_t mask) -{ - uint32_t lmask = mask; - uint32_t hmask = mask >> 32; - unsigned char *fx = _fx; - - asm volatile(".byte " REX_PREFIX "0x0f,0xae,0x27\n\t" - : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) - : "memory"); -} - -static __always_inline void mpx_clear_bnd0(void) -{ - long size = 0; - void *ptr = NULL; - /* F3 0F 1B /r BNDMK bnd, m64 */ - /* f3 0f 1b 04 11 bndmk (%rcx,%rdx,1),%bnd0 */ - asm volatile(".byte 0xf3,0x0f,0x1b,0x04,0x11\n\t" - : : "c" (ptr), "d" (size-1) - : "memory"); -} - -static __always_inline void mpx_make_bound_helper(unsigned long ptr, - unsigned long size) -{ - /* F3 0F 1B /r BNDMK bnd, m64 */ - /* f3 0f 1b 04 11 bndmk (%rcx,%rdx,1),%bnd0 */ - asm volatile(".byte 0xf3,0x0f,0x1b,0x04,0x11\n\t" - : : "c" (ptr), "d" (size-1) - : "memory"); -} - -static __always_inline void mpx_check_lowerbound_helper(unsigned long ptr) -{ - /* F3 0F 1A /r NDCL bnd, r/m64 */ - /* f3 0f 1a 01 bndcl (%rcx),%bnd0 */ - asm volatile(".byte 0xf3,0x0f,0x1a,0x01\n\t" - : : "c" (ptr) - : "memory"); -} - -static __always_inline void mpx_check_upperbound_helper(unsigned long ptr) -{ - /* F2 0F 1A /r BNDCU bnd, r/m64 */ - /* f2 0f 1a 01 bndcu (%rcx),%bnd0 */ - asm volatile(".byte 0xf2,0x0f,0x1a,0x01\n\t" - : : "c" (ptr) - : "memory"); -} - -static __always_inline void mpx_movbndreg_helper() -{ - /* 66 0F 1B /r BNDMOV bnd1/m128, bnd2 */ - /* 66 0f 1b c2 bndmov %bnd0,%bnd2 */ - - asm volatile(".byte 0x66,0x0f,0x1b,0xc2\n\t"); -} - -static __always_inline void mpx_movbnd2mem_helper(uint8_t *mem) -{ - /* 66 0F 1B /r BNDMOV bnd1/m128, bnd2 */ - /* 66 0f 1b 01 bndmov %bnd0,(%rcx) */ - asm volatile(".byte 0x66,0x0f,0x1b,0x01\n\t" - : : "c" (mem) - : "memory"); -} - -static __always_inline void mpx_movbnd_from_mem_helper(uint8_t *mem) -{ - /* 66 0F 1A /r BNDMOV bnd1, bnd2/m128 */ - /* 66 0f 1a 01 bndmov (%rcx),%bnd0 */ - asm volatile(".byte 0x66,0x0f,0x1a,0x01\n\t" - : : "c" (mem) - : "memory"); -} - -static __always_inline void mpx_store_dsc_helper(unsigned long ptr_addr, - unsigned long ptr_val) -{ - /* 0F 1B /r BNDSTX-Store Extended Bounds Using Address Translation */ - /* 0f 1b 04 11 bndstx %bnd0,(%rcx,%rdx,1) */ - asm volatile(".byte 0x0f,0x1b,0x04,0x11\n\t" - : : "c" (ptr_addr), "d" (ptr_val) - : "memory"); -} - -static __always_inline void mpx_load_dsc_helper(unsigned long ptr_addr, - unsigned long ptr_val) -{ - /* 0F 1A /r BNDLDX-Load */ - /*/ 0f 1a 04 11 bndldx (%rcx,%rdx,1),%bnd0 */ - asm volatile(".byte 0x0f,0x1a,0x04,0x11\n\t" - : : "c" (ptr_addr), "d" (ptr_val) - : "memory"); -} - -void __print_context(void *__print_xsave_buffer, int line) -{ - uint64_t *bounds = (uint64_t *)(__print_xsave_buffer + MPX_BOUNDS_OFFSET); - uint64_t *cfg = (uint64_t *)(__print_xsave_buffer + MPX_CONFIG_OFFSET); - - int i; - eprintf("%s()::%d\n", "print_context", line); - for (i = 0; i < 4; i++) { - eprintf("bound[%d]: 0x%016lx 0x%016lx(0x%016lx)\n", i, - (unsigned long)bounds[i*2], - ~(unsigned long)bounds[i*2+1], - (unsigned long)bounds[i*2+1]); - } - - eprintf("cpcfg: %jx cpstatus: %jx\n", cfg[0], cfg[1]); -} -#define print_context(x) __print_context(x, __LINE__) -#ifdef DEBUG -#define dprint_context(x) print_context(x) -#else -#define dprint_context(x) do{}while(0) -#endif - -void init() -{ - int i; - - srand((unsigned int)time(NULL)); - - for (i = 0; i < 4; i++) { - shadow_plb[i][0] = 0; - shadow_plb[i][1] = ~(unsigned long)0; - } -} - -long int __mpx_random(int line) -{ -#ifdef NOT_SO_RANDOM - static long fake = 722122311; - fake += 563792075; - return fakse; -#else - return random(); -#endif -} -#define mpx_random() __mpx_random(__LINE__) - -uint8_t *get_random_addr() -{ - uint8_t*addr = (uint8_t *)(unsigned long)(rand() % MAX_ADDR_TESTED); - return (addr - (unsigned long)addr % sizeof(uint8_t *)); -} - -static inline bool compare_context(void *__xsave_buffer) -{ - uint64_t *bounds = (uint64_t *)(__xsave_buffer + MPX_BOUNDS_OFFSET); - - int i; - for (i = 0; i < 4; i++) { - dprintf3("shadow[%d]{%016lx/%016lx}\nbounds[%d]{%016lx/%016lx}\n", - i, (unsigned long)shadow_plb[i][0], (unsigned long)shadow_plb[i][1], - i, (unsigned long)bounds[i*2], ~(unsigned long)bounds[i*2+1]); - if ((shadow_plb[i][0] != bounds[i*2]) || - (shadow_plb[i][1] != ~(unsigned long)bounds[i*2+1])) { - eprintf("ERROR comparing shadow to real bound register %d\n", i); - eprintf("shadow{0x%016lx/0x%016lx}\nbounds{0x%016lx/0x%016lx}\n", - (unsigned long)shadow_plb[i][0], (unsigned long)shadow_plb[i][1], - (unsigned long)bounds[i*2], (unsigned long)bounds[i*2+1]); - return false; - } - } - - return true; -} - -void mkbnd_shadow(uint8_t *ptr, int index, long offset) -{ - uint64_t *lower = (uint64_t *)&(shadow_plb[index][0]); - uint64_t *upper = (uint64_t *)&(shadow_plb[index][1]); - *lower = (unsigned long)ptr; - *upper = (unsigned long)ptr + offset - 1; -} - -void check_lowerbound_shadow(uint8_t *ptr, int index) -{ - uint64_t *lower = (uint64_t *)&(shadow_plb[index][0]); - if (*lower > (uint64_t)(unsigned long)ptr) - num_lower_brs++; - else - dprintf1("LowerBoundChk passed:%p\n", ptr); -} - -void check_upperbound_shadow(uint8_t *ptr, int index) -{ - uint64_t upper = *(uint64_t *)&(shadow_plb[index][1]); - if (upper < (uint64_t)(unsigned long)ptr) - num_upper_brs++; - else - dprintf1("UpperBoundChk passed:%p\n", ptr); -} - -__always_inline void movbndreg_shadow(int src, int dest) -{ - shadow_plb[dest][0] = shadow_plb[src][0]; - shadow_plb[dest][1] = shadow_plb[src][1]; -} - -__always_inline void movbnd2mem_shadow(int src, unsigned long *dest) -{ - unsigned long *lower = (unsigned long *)&(shadow_plb[src][0]); - unsigned long *upper = (unsigned long *)&(shadow_plb[src][1]); - *dest = *lower; - *(dest+1) = *upper; -} - -__always_inline void movbnd_from_mem_shadow(unsigned long *src, int dest) -{ - unsigned long *lower = (unsigned long *)&(shadow_plb[dest][0]); - unsigned long *upper = (unsigned long *)&(shadow_plb[dest][1]); - *lower = *src; - *upper = *(src+1); -} - -__always_inline void stdsc_shadow(int index, uint8_t *ptr, uint8_t *ptr_val) -{ - shadow_map[0] = (unsigned long)shadow_plb[index][0]; - shadow_map[1] = (unsigned long)shadow_plb[index][1]; - shadow_map[2] = (unsigned long)ptr_val; - dprintf3("%s(%d, %p, %p) set shadow map[2]: %p\n", __func__, - index, ptr, ptr_val, ptr_val); - /*ptr ignored */ -} - -void lddsc_shadow(int index, uint8_t *ptr, uint8_t *ptr_val) -{ - uint64_t lower = shadow_map[0]; - uint64_t upper = shadow_map[1]; - uint8_t *value = (uint8_t *)shadow_map[2]; - - if (value != ptr_val) { - dprintf2("%s(%d, %p, %p) init shadow bounds[%d] " - "because %p != %p\n", __func__, index, ptr, - ptr_val, index, value, ptr_val); - shadow_plb[index][0] = 0; - shadow_plb[index][1] = ~(unsigned long)0; - } else { - shadow_plb[index][0] = lower; - shadow_plb[index][1] = upper; - } - /* ptr ignored */ -} - -static __always_inline void mpx_test_helper0(uint8_t *buf, uint8_t *ptr) -{ - mpx_make_bound_helper((unsigned long)ptr, 0x1800); -} - -static __always_inline void mpx_test_helper0_shadow(uint8_t *buf, uint8_t *ptr) -{ - mkbnd_shadow(ptr, 0, 0x1800); -} - -static __always_inline void mpx_test_helper1(uint8_t *buf, uint8_t *ptr) -{ - /* these are hard-coded to check bnd0 */ - expected_bnd_index = 0; - mpx_check_lowerbound_helper((unsigned long)(ptr-1)); - mpx_check_upperbound_helper((unsigned long)(ptr+0x1800)); - /* reset this since we do not expect any more bounds exceptions */ - expected_bnd_index = -1; -} - -static __always_inline void mpx_test_helper1_shadow(uint8_t *buf, uint8_t *ptr) -{ - check_lowerbound_shadow(ptr-1, 0); - check_upperbound_shadow(ptr+0x1800, 0); -} - -static __always_inline void mpx_test_helper2(uint8_t *buf, uint8_t *ptr) -{ - mpx_make_bound_helper((unsigned long)ptr, 0x1800); - mpx_movbndreg_helper(); - mpx_movbnd2mem_helper(buf); - mpx_make_bound_helper((unsigned long)(ptr+0x12), 0x1800); -} - -static __always_inline void mpx_test_helper2_shadow(uint8_t *buf, uint8_t *ptr) -{ - mkbnd_shadow(ptr, 0, 0x1800); - movbndreg_shadow(0, 2); - movbnd2mem_shadow(0, (unsigned long *)buf); - mkbnd_shadow(ptr+0x12, 0, 0x1800); -} - -static __always_inline void mpx_test_helper3(uint8_t *buf, uint8_t *ptr) -{ - mpx_movbnd_from_mem_helper(buf); -} - -static __always_inline void mpx_test_helper3_shadow(uint8_t *buf, uint8_t *ptr) -{ - movbnd_from_mem_shadow((unsigned long *)buf, 0); -} - -static __always_inline void mpx_test_helper4(uint8_t *buf, uint8_t *ptr) -{ - mpx_store_dsc_helper((unsigned long)buf, (unsigned long)ptr); - mpx_make_bound_helper((unsigned long)(ptr+0x12), 0x1800); -} - -static __always_inline void mpx_test_helper4_shadow(uint8_t *buf, uint8_t *ptr) -{ - stdsc_shadow(0, buf, ptr); - mkbnd_shadow(ptr+0x12, 0, 0x1800); -} - -static __always_inline void mpx_test_helper5(uint8_t *buf, uint8_t *ptr) -{ - mpx_load_dsc_helper((unsigned long)buf, (unsigned long)ptr); -} - -static __always_inline void mpx_test_helper5_shadow(uint8_t *buf, uint8_t *ptr) -{ - lddsc_shadow(0, buf, ptr); -} - -#define NR_MPX_TEST_FUNCTIONS 6 - -/* - * For compatibility reasons, MPX will clear the bounds registers - * when you make function calls (among other things). We have to - * preserve the registers in between calls to the "helpers" since - * they build on each other. - * - * Be very careful not to make any function calls inside the - * helpers, or anywhere else beween the xrstor and xsave. - */ -#define run_helper(helper_nr, buf, buf_shadow, ptr) do { \ - xrstor_state(xsave_test_buf, flags); \ - mpx_test_helper##helper_nr(buf, ptr); \ - xsave_state(xsave_test_buf, flags); \ - mpx_test_helper##helper_nr##_shadow(buf_shadow, ptr); \ -} while (0) - -static void run_helpers(int nr, uint8_t *buf, uint8_t *buf_shadow, uint8_t *ptr) -{ - uint64_t flags = 0x18; - - dprint_context(xsave_test_buf); - switch (nr) { - case 0: - run_helper(0, buf, buf_shadow, ptr); - break; - case 1: - run_helper(1, buf, buf_shadow, ptr); - break; - case 2: - run_helper(2, buf, buf_shadow, ptr); - break; - case 3: - run_helper(3, buf, buf_shadow, ptr); - break; - case 4: - run_helper(4, buf, buf_shadow, ptr); - break; - case 5: - run_helper(5, buf, buf_shadow, ptr); - break; - default: - test_failed(); - break; - } - dprint_context(xsave_test_buf); -} - -unsigned long buf_shadow[1024]; /* used to check load / store descriptors */ -extern long inspect_me(struct mpx_bounds_dir *bounds_dir); - -long cover_buf_with_bt_entries(void *buf, long buf_len) -{ - int i; - long nr_to_fill; - int ratio = 1000; - unsigned long buf_len_in_ptrs; - - /* Fill about 1/100 of the space with bt entries */ - nr_to_fill = buf_len / (sizeof(unsigned long) * ratio); - - if (!nr_to_fill) - dprintf3("%s() nr_to_fill: %ld\n", __func__, nr_to_fill); - - /* Align the buffer to pointer size */ - while (((unsigned long)buf) % sizeof(void *)) { - buf++; - buf_len--; - } - /* We are storing pointers, so make */ - buf_len_in_ptrs = buf_len / sizeof(void *); - - for (i = 0; i < nr_to_fill; i++) { - long index = (mpx_random() % buf_len_in_ptrs); - void *ptr = buf + index * sizeof(unsigned long); - unsigned long ptr_addr = (unsigned long)ptr; - - /* ptr and size can be anything */ - mpx_make_bound_helper((unsigned long)ptr, 8); - - /* - * take bnd0 and put it in to bounds tables "buf + index" is an - * address inside the buffer where we are pretending that we - * are going to put a pointer We do not, though because we will - * never load entries from the table, so it doesn't matter. - */ - mpx_store_dsc_helper(ptr_addr, (unsigned long)ptr); - dprintf4("storing bound table entry for %lx (buf start @ %p)\n", - ptr_addr, buf); - } - return nr_to_fill; -} - -unsigned long align_down(unsigned long alignme, unsigned long align_to) -{ - return alignme & ~(align_to-1); -} - -unsigned long align_up(unsigned long alignme, unsigned long align_to) -{ - return (alignme + align_to - 1) & ~(align_to-1); -} - -/* - * Using 1MB alignment guarantees that each no allocation - * will overlap with another's bounds tables. - * - * We have to cook our own allocator here. malloc() can - * mix other allocation with ours which means that even - * if we free all of our allocations, there might still - * be bounds tables for the *areas* since there is other - * valid memory there. - * - * We also can't use malloc() because a free() of an area - * might not free it back to the kernel. We want it - * completely unmapped an malloc() does not guarantee - * that. - */ -#ifdef __i386__ -long alignment = 4096; -long sz_alignment = 4096; -#else -long alignment = 1 * MB; -long sz_alignment = 1 * MB; -#endif -void *mpx_mini_alloc(unsigned long sz) -{ - unsigned long long tries = 0; - static void *last; - void *ptr; - void *try_at; - - sz = align_up(sz, sz_alignment); - - try_at = last + alignment; - while (1) { - ptr = mmap(try_at, sz, PROT_READ|PROT_WRITE, - MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); - if (ptr == (void *)-1) - return NULL; - if (ptr == try_at) - break; - - munmap(ptr, sz); - try_at += alignment; -#ifdef __i386__ - /* - * This isn't quite correct for 32-bit binaries - * on 64-bit kernels since they can use the - * entire 32-bit address space, but it's close - * enough. - */ - if (try_at > (void *)0xC0000000) -#else - if (try_at > (void *)0x0000800000000000) -#endif - try_at = (void *)0x0; - if (!(++tries % 10000)) - dprintf1("stuck in %s(), tries: %lld\n", __func__, tries); - continue; - } - last = ptr; - dprintf3("mpx_mini_alloc(0x%lx) returning: %p\n", sz, ptr); - return ptr; -} -void mpx_mini_free(void *ptr, long sz) -{ - dprintf2("%s() ptr: %p\n", __func__, ptr); - if ((unsigned long)ptr > 0x100000000000) { - dprintf1("uh oh !!!!!!!!!!!!!!! pointer too high: %p\n", ptr); - test_failed(); - } - sz = align_up(sz, sz_alignment); - dprintf3("%s() ptr: %p before munmap\n", __func__, ptr); - munmap(ptr, sz); - dprintf3("%s() ptr: %p DONE\n", __func__, ptr); -} - -#define NR_MALLOCS 100 -struct one_malloc { - char *ptr; - int nr_filled_btes; - unsigned long size; -}; -struct one_malloc mallocs[NR_MALLOCS]; - -void free_one_malloc(int index) -{ - unsigned long free_ptr; - unsigned long mask; - - if (!mallocs[index].ptr) - return; - - mpx_mini_free(mallocs[index].ptr, mallocs[index].size); - dprintf4("freed[%d]: %p\n", index, mallocs[index].ptr); - - free_ptr = (unsigned long)mallocs[index].ptr; - mask = alignment-1; - dprintf4("lowerbits: %lx / %lx mask: %lx\n", free_ptr, - (free_ptr & mask), mask); - assert((free_ptr & mask) == 0); - - mallocs[index].ptr = NULL; -} - -#ifdef __i386__ -#define MPX_BOUNDS_TABLE_COVERS 4096 -#else -#define MPX_BOUNDS_TABLE_COVERS (1 * MB) -#endif -void zap_everything(void) -{ - long after_zap; - long before_zap; - int i; - - before_zap = inspect_me(bounds_dir_ptr); - dprintf1("zapping everything start: %ld\n", before_zap); - for (i = 0; i < NR_MALLOCS; i++) - free_one_malloc(i); - - after_zap = inspect_me(bounds_dir_ptr); - dprintf1("zapping everything done: %ld\n", after_zap); - /* - * We only guarantee to empty the thing out if our allocations are - * exactly aligned on the boundaries of a boudns table. - */ - if ((alignment >= MPX_BOUNDS_TABLE_COVERS) && - (sz_alignment >= MPX_BOUNDS_TABLE_COVERS)) { - if (after_zap != 0) - test_failed(); - - assert(after_zap == 0); - } -} - -void do_one_malloc(void) -{ - static int malloc_counter; - long sz; - int rand_index = (mpx_random() % NR_MALLOCS); - void *ptr = mallocs[rand_index].ptr; - - dprintf3("%s() enter\n", __func__); - - if (ptr) { - dprintf3("freeing one malloc at index: %d\n", rand_index); - free_one_malloc(rand_index); - if (mpx_random() % (NR_MALLOCS*3) == 3) { - int i; - dprintf3("zapping some more\n"); - for (i = rand_index; i < NR_MALLOCS; i++) - free_one_malloc(i); - } - if ((mpx_random() % zap_all_every_this_many_mallocs) == 4) - zap_everything(); - } - - /* 1->~1M */ - sz = (1 + mpx_random() % 1000) * 1000; - ptr = mpx_mini_alloc(sz); - if (!ptr) { - /* - * If we are failing allocations, just assume we - * are out of memory and zap everything. - */ - dprintf3("zapping everything because out of memory\n"); - zap_everything(); - goto out; - } - - dprintf3("malloc: %p size: 0x%lx\n", ptr, sz); - mallocs[rand_index].nr_filled_btes = cover_buf_with_bt_entries(ptr, sz); - mallocs[rand_index].ptr = ptr; - mallocs[rand_index].size = sz; -out: - if ((++malloc_counter) % inspect_every_this_many_mallocs == 0) - inspect_me(bounds_dir_ptr); -} - -void run_timed_test(void (*test_func)(void)) -{ - int done = 0; - long iteration = 0; - static time_t last_print; - time_t now; - time_t start; - - time(&start); - while (!done) { - time(&now); - if ((now - start) > TEST_DURATION_SECS) - done = 1; - - test_func(); - iteration++; - - if ((now - last_print > 1) || done) { - printf("iteration %ld complete, OK so far\n", iteration); - last_print = now; - } - } -} - -void check_bounds_table_frees(void) -{ - printf("executing unmaptest\n"); - inspect_me(bounds_dir_ptr); - run_timed_test(&do_one_malloc); - printf("done with malloc() fun\n"); -} - -void insn_test_failed(int test_nr, int test_round, void *buf, - void *buf_shadow, void *ptr) -{ - print_context(xsave_test_buf); - eprintf("ERROR: test %d round %d failed\n", test_nr, test_round); - while (test_nr == 5) { - struct mpx_bt_entry *bte; - struct mpx_bounds_dir *bd = (void *)bounds_dir_ptr; - struct mpx_bd_entry *bde = mpx_vaddr_to_bd_entry(buf, bd); - - printf(" bd: %p\n", bd); - printf("&bde: %p\n", bde); - printf("*bde: %lx\n", *(unsigned long *)bde); - if (!bd_entry_valid(bde)) - break; - - bte = mpx_vaddr_to_bt_entry(buf, bd); - printf(" te: %p\n", bte); - printf("bte[0]: %lx\n", bte->contents[0]); - printf("bte[1]: %lx\n", bte->contents[1]); - printf("bte[2]: %lx\n", bte->contents[2]); - printf("bte[3]: %lx\n", bte->contents[3]); - break; - } - test_failed(); -} - -void check_mpx_insns_and_tables(void) -{ - int successes = 0; - int failures = 0; - int buf_size = (1024*1024); - unsigned long *buf = malloc(buf_size); - const int total_nr_tests = NR_MPX_TEST_FUNCTIONS * TEST_ROUNDS; - int i, j; - - memset(buf, 0, buf_size); - memset(buf_shadow, 0, sizeof(buf_shadow)); - - for (i = 0; i < TEST_ROUNDS; i++) { - uint8_t *ptr = get_random_addr() + 8; - - for (j = 0; j < NR_MPX_TEST_FUNCTIONS; j++) { - if (0 && j != 5) { - successes++; - continue; - } - dprintf2("starting test %d round %d\n", j, i); - dprint_context(xsave_test_buf); - /* - * test5 loads an address from the bounds tables. - * The load will only complete if 'ptr' matches - * the load and the store, so with random addrs, - * the odds of this are very small. Make it - * higher by only moving 'ptr' 1/10 times. - */ - if (random() % 10 <= 0) - ptr = get_random_addr() + 8; - dprintf3("random ptr{%p}\n", ptr); - dprint_context(xsave_test_buf); - run_helpers(j, (void *)buf, (void *)buf_shadow, ptr); - dprint_context(xsave_test_buf); - if (!compare_context(xsave_test_buf)) { - insn_test_failed(j, i, buf, buf_shadow, ptr); - failures++; - goto exit; - } - successes++; - dprint_context(xsave_test_buf); - dprintf2("finished test %d round %d\n", j, i); - dprintf3("\n"); - dprint_context(xsave_test_buf); - } - } - -exit: - dprintf2("\nabout to free:\n"); - free(buf); - dprintf1("successes: %d\n", successes); - dprintf1(" failures: %d\n", failures); - dprintf1(" tests: %d\n", total_nr_tests); - dprintf1(" expected: %jd #BRs\n", num_upper_brs + num_lower_brs); - dprintf1(" saw: %d #BRs\n", br_count); - if (failures) { - eprintf("ERROR: non-zero number of failures\n"); - exit(20); - } - if (successes != total_nr_tests) { - eprintf("ERROR: succeeded fewer than number of tries (%d != %d)\n", - successes, total_nr_tests); - exit(21); - } - if (num_upper_brs + num_lower_brs != br_count) { - eprintf("ERROR: unexpected number of #BRs: %jd %jd %d\n", - num_upper_brs, num_lower_brs, br_count); - eprintf("successes: %d\n", successes); - eprintf(" failures: %d\n", failures); - eprintf(" tests: %d\n", total_nr_tests); - eprintf(" expected: %jd #BRs\n", num_upper_brs + num_lower_brs); - eprintf(" saw: %d #BRs\n", br_count); - exit(22); - } -} - -/* - * This is supposed to SIGSEGV nicely once the kernel - * can no longer allocate vaddr space. - */ -void exhaust_vaddr_space(void) -{ - unsigned long ptr; - /* Try to make sure there is no room for a bounds table anywhere */ - unsigned long skip = MPX_BOUNDS_TABLE_SIZE_BYTES - PAGE_SIZE; -#ifdef __i386__ - unsigned long max_vaddr = 0xf7788000UL; -#else - unsigned long max_vaddr = 0x800000000000UL; -#endif - - dprintf1("%s() start\n", __func__); - /* do not start at 0, we aren't allowed to map there */ - for (ptr = PAGE_SIZE; ptr < max_vaddr; ptr += skip) { - void *ptr_ret; - int ret = madvise((void *)ptr, PAGE_SIZE, MADV_NORMAL); - - if (!ret) { - dprintf1("madvise() %lx ret: %d\n", ptr, ret); - continue; - } - ptr_ret = mmap((void *)ptr, PAGE_SIZE, PROT_READ|PROT_WRITE, - MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); - if (ptr_ret != (void *)ptr) { - perror("mmap"); - dprintf1("mmap(%lx) ret: %p\n", ptr, ptr_ret); - break; - } - if (!(ptr & 0xffffff)) - dprintf1("mmap(%lx) ret: %p\n", ptr, ptr_ret); - } - for (ptr = PAGE_SIZE; ptr < max_vaddr; ptr += skip) { - dprintf2("covering 0x%lx with bounds table entries\n", ptr); - cover_buf_with_bt_entries((void *)ptr, PAGE_SIZE); - } - dprintf1("%s() end\n", __func__); - printf("done with vaddr space fun\n"); -} - -void mpx_table_test(void) -{ - printf("starting mpx bounds table test\n"); - run_timed_test(check_mpx_insns_and_tables); - printf("done with mpx bounds table test\n"); -} - -int main(int argc, char **argv) -{ - int unmaptest = 0; - int vaddrexhaust = 0; - int tabletest = 0; - int i; - - check_mpx_support(); - mpx_prepare(); - srandom(11179); - - bd_incore(); - init(); - bd_incore(); - - trace_me(); - - xsave_state((void *)xsave_test_buf, 0x1f); - if (!compare_context(xsave_test_buf)) - printf("Init failed\n"); - - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "unmaptest")) - unmaptest = 1; - if (!strcmp(argv[i], "vaddrexhaust")) - vaddrexhaust = 1; - if (!strcmp(argv[i], "tabletest")) - tabletest = 1; - } - if (!(unmaptest || vaddrexhaust || tabletest)) { - unmaptest = 1; - /* vaddrexhaust = 1; */ - tabletest = 1; - } - if (unmaptest) - check_bounds_table_frees(); - if (tabletest) - mpx_table_test(); - if (vaddrexhaust) - exhaust_vaddr_space(); - printf("%s completed successfully\n", argv[0]); - exit(0); -} - -#include "mpx-dig.c" diff --git a/tools/testing/selftests/x86/mpx-mm.h b/tools/testing/selftests/x86/mpx-mm.h deleted file mode 100644 index 6dbdd66b8242..000000000000 --- a/tools/testing/selftests/x86/mpx-mm.h +++ /dev/null @@ -1,10 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _MPX_MM_H -#define _MPX_MM_H - -#define PAGE_SIZE 4096 -#define MB (1UL<<20) - -extern long nr_incore(void *ptr, unsigned long size_bytes); - -#endif /* _MPX_MM_H */ -- cgit v1.2.3-59-g8ed1b From be261ffce6f13229dad50f59c5e491f933d3167f Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 4 Jul 2019 10:46:37 -0500 Subject: x86: Remove X86_FEATURE_MFENCE_RDTSC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AMD and Intel both have serializing lfence (X86_FEATURE_LFENCE_RDTSC). They've both had it for a long time, and AMD has had it enabled in Linux since Spectre v1 was announced. Back then, there was a proposal to remove the serializing mfence feature bit (X86_FEATURE_MFENCE_RDTSC), since both AMD and Intel have serializing lfence. At the time, it was (ahem) speculated that some hypervisors might not yet support its removal, so it remained for the time being. Now a year-and-a-half later, it should be safe to remove. I asked Andrew Cooper about whether it's still needed: So if you're virtualised, you've got no choice in the matter.  lfence is either dispatch-serialising or not on AMD, and you won't be able to change it. Furthermore, you can't accurately tell what state the bit is in, because the MSR might not be virtualised at all, or may not reflect the true state in hardware.  Worse still, attempting to set the bit may not be successful even if there isn't a fault for doing so. Xen sets the DE_CFG bit unconditionally, as does Linux by the looks of things (see MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT).  ISTR other hypervisor vendors saying the same, but I don't have any information to hand. If you are running under a hypervisor which has been updated, then lfence will almost certainly be dispatch-serialising in practice, and you'll almost certainly see the bit already set in DE_CFG.  If you're running under a hypervisor which hasn't been patched since Spectre, you've already lost in many more ways. I'd argue that X86_FEATURE_MFENCE_RDTSC is not worth keeping. So remove it. This will reduce some code rot, and also make it easier to hook barrier_nospec() up to a cmdline disable for performance raisins, without having to need an alternative_3() macro. Signed-off-by: Josh Poimboeuf Signed-off-by: Thomas Gleixner Link: https://lkml.kernel.org/r/d990aa51e40063acb9888e8c1b688e41355a9588.1562255067.git.jpoimboe@redhat.com --- arch/x86/include/asm/barrier.h | 3 +-- arch/x86/include/asm/cpufeatures.h | 1 - arch/x86/include/asm/msr.h | 3 +-- arch/x86/kernel/cpu/amd.c | 21 +++------------------ arch/x86/kernel/cpu/hygon.c | 21 +++------------------ tools/arch/x86/include/asm/cpufeatures.h | 1 - 6 files changed, 8 insertions(+), 42 deletions(-) (limited to 'tools') diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h index 84f848c2541a..7f828fe49797 100644 --- a/arch/x86/include/asm/barrier.h +++ b/arch/x86/include/asm/barrier.h @@ -49,8 +49,7 @@ static inline unsigned long array_index_mask_nospec(unsigned long index, #define array_index_mask_nospec array_index_mask_nospec /* Prevent speculative execution past this barrier. */ -#define barrier_nospec() alternative_2("", "mfence", X86_FEATURE_MFENCE_RDTSC, \ - "lfence", X86_FEATURE_LFENCE_RDTSC) +#define barrier_nospec() alternative("", "lfence", X86_FEATURE_LFENCE_RDTSC) #define dma_rmb() barrier() #define dma_wmb() barrier() diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index 56f53bf3bbbf..fcc70ffd88c2 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -96,7 +96,6 @@ #define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in IA32 userspace */ #define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in IA32 userspace */ #define X86_FEATURE_REP_GOOD ( 3*32+16) /* REP microcode works well */ -#define X86_FEATURE_MFENCE_RDTSC ( 3*32+17) /* "" MFENCE synchronizes RDTSC */ #define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" LFENCE synchronizes RDTSC */ #define X86_FEATURE_ACC_POWER ( 3*32+19) /* AMD Accumulated Power Mechanism */ #define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */ diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 5cc3930cb465..86f20d520a07 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -233,8 +233,7 @@ static __always_inline unsigned long long rdtsc_ordered(void) * Thus, use the preferred barrier on the respective CPU, aiming for * RDTSCP as the default. */ - asm volatile(ALTERNATIVE_3("rdtsc", - "mfence; rdtsc", X86_FEATURE_MFENCE_RDTSC, + asm volatile(ALTERNATIVE_2("rdtsc", "lfence; rdtsc", X86_FEATURE_LFENCE_RDTSC, "rdtscp", X86_FEATURE_RDTSCP) : EAX_EDX_RET(val, low, high) diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 8d4e50428b68..3afe07d602dd 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -879,12 +879,8 @@ static void init_amd(struct cpuinfo_x86 *c) init_amd_cacheinfo(c); if (cpu_has(c, X86_FEATURE_XMM2)) { - unsigned long long val; - int ret; - /* - * A serializing LFENCE has less overhead than MFENCE, so - * use it for execution serialization. On families which + * Use LFENCE for execution serialization. On families which * don't have that MSR, LFENCE is already serializing. * msr_set_bit() uses the safe accessors, too, even if the MSR * is not present. @@ -892,19 +888,8 @@ static void init_amd(struct cpuinfo_x86 *c) msr_set_bit(MSR_F10H_DECFG, MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT); - /* - * Verify that the MSR write was successful (could be running - * under a hypervisor) and only then assume that LFENCE is - * serializing. - */ - ret = rdmsrl_safe(MSR_F10H_DECFG, &val); - if (!ret && (val & MSR_F10H_DECFG_LFENCE_SERIALIZE)) { - /* A serializing LFENCE stops RDTSC speculation */ - set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); - } else { - /* MFENCE stops RDTSC speculation */ - set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC); - } + /* A serializing LFENCE stops RDTSC speculation */ + set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); } /* diff --git a/arch/x86/kernel/cpu/hygon.c b/arch/x86/kernel/cpu/hygon.c index 415621ddb8a2..4e28c1fc8749 100644 --- a/arch/x86/kernel/cpu/hygon.c +++ b/arch/x86/kernel/cpu/hygon.c @@ -330,12 +330,8 @@ static void init_hygon(struct cpuinfo_x86 *c) init_hygon_cacheinfo(c); if (cpu_has(c, X86_FEATURE_XMM2)) { - unsigned long long val; - int ret; - /* - * A serializing LFENCE has less overhead than MFENCE, so - * use it for execution serialization. On families which + * Use LFENCE for execution serialization. On families which * don't have that MSR, LFENCE is already serializing. * msr_set_bit() uses the safe accessors, too, even if the MSR * is not present. @@ -343,19 +339,8 @@ static void init_hygon(struct cpuinfo_x86 *c) msr_set_bit(MSR_F10H_DECFG, MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT); - /* - * Verify that the MSR write was successful (could be running - * under a hypervisor) and only then assume that LFENCE is - * serializing. - */ - ret = rdmsrl_safe(MSR_F10H_DECFG, &val); - if (!ret && (val & MSR_F10H_DECFG_LFENCE_SERIALIZE)) { - /* A serializing LFENCE stops RDTSC speculation */ - set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); - } else { - /* MFENCE stops RDTSC speculation */ - set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC); - } + /* A serializing LFENCE stops RDTSC speculation */ + set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); } /* diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h index 998c2cc08363..9b98edb6b2d3 100644 --- a/tools/arch/x86/include/asm/cpufeatures.h +++ b/tools/arch/x86/include/asm/cpufeatures.h @@ -96,7 +96,6 @@ #define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in IA32 userspace */ #define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in IA32 userspace */ #define X86_FEATURE_REP_GOOD ( 3*32+16) /* REP microcode works well */ -#define X86_FEATURE_MFENCE_RDTSC ( 3*32+17) /* "" MFENCE synchronizes RDTSC */ #define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" LFENCE synchronizes RDTSC */ #define X86_FEATURE_ACC_POWER ( 3*32+19) /* AMD Accumulated Power Mechanism */ #define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */ -- cgit v1.2.3-59-g8ed1b From 3e3bb69589e482e0783f28d4cd1d8e56fda0bcbb Mon Sep 17 00:00:00 2001 From: Roman Mashak Date: Tue, 23 Jul 2019 15:01:59 -0400 Subject: tc-testing: added tdc tests for [b|p]fifo qdisc Signed-off-by: Roman Mashak Signed-off-by: David S. Miller --- .../selftests/tc-testing/tc-tests/qdiscs/fifo.json | 304 +++++++++++++++++++++ 1 file changed, 304 insertions(+) create mode 100644 tools/testing/selftests/tc-testing/tc-tests/qdiscs/fifo.json (limited to 'tools') diff --git a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/fifo.json b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/fifo.json new file mode 100644 index 000000000000..9de61fa10878 --- /dev/null +++ b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/fifo.json @@ -0,0 +1,304 @@ +[ + { + "id": "a519", + "name": "Add bfifo qdisc with system default parameters on egress", + "__comment": "When omitted, queue size in bfifo is calculated as: txqueuelen * (MTU + LinkLayerHdrSize), where LinkLayerHdrSize=14 for Ethernet", + "category": [ + "qdisc", + "fifo" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root bfifo", + "expExitCode": "0", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc bfifo 1: root.*limit [0-9]+b", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 handle 1: root bfifo", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "585c", + "name": "Add pfifo qdisc with system default parameters on egress", + "__comment": "When omitted, queue size in pfifo is defaulted to the interface's txqueuelen value.", + "category": [ + "qdisc", + "fifo" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root pfifo", + "expExitCode": "0", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc pfifo 1: root.*limit [0-9]+p", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 handle 1: root pfifo", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "a86e", + "name": "Add bfifo qdisc with system default parameters on egress with handle of maximum value", + "category": [ + "qdisc", + "fifo" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 root handle ffff: bfifo", + "expExitCode": "0", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc bfifo ffff: root.*limit [0-9]+b", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 handle ffff: root bfifo", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "9ac8", + "name": "Add bfifo qdisc on egress with queue size of 3000 bytes", + "category": [ + "qdisc", + "fifo" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root bfifo limit 3000b", + "expExitCode": "0", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc bfifo 1: root.*limit 3000b", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 handle 1: root bfifo", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "f4e6", + "name": "Add pfifo qdisc on egress with queue size of 3000 packets", + "category": [ + "qdisc", + "fifo" + ], + "setup": [ + "$IP link add dev $DEV1 txqueuelen 3000 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root pfifo limit 3000", + "expExitCode": "0", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc pfifo 1: root.*limit 3000p", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 handle 1: root pfifo", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "b1b1", + "name": "Add bfifo qdisc with system default parameters on egress with invalid handle exceeding maximum value", + "category": [ + "qdisc", + "fifo" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 root handle 10000: bfifo", + "expExitCode": "255", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc bfifo 10000: root.*limit [0-9]+b", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "8d5e", + "name": "Add bfifo qdisc on egress with unsupported argument", + "category": [ + "qdisc", + "fifo" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root bfifo foorbar", + "expExitCode": "1", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc bfifo 1: root", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "7787", + "name": "Add pfifo qdisc on egress with unsupported argument", + "category": [ + "qdisc", + "fifo" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root pfifo foorbar", + "expExitCode": "1", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc pfifo 1: root", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "c4b6", + "name": "Replace bfifo qdisc on egress with new queue size", + "category": [ + "qdisc", + "fifo" + ], + "setup": [ + "$IP link del dev $DEV1 type dummy || /bin/true", + "$IP link add dev $DEV1 txqueuelen 1000 type dummy", + "$TC qdisc add dev $DEV1 handle 1: root bfifo" + ], + "cmdUnderTest": "$TC qdisc replace dev $DEV1 handle 1: root bfifo limit 3000b", + "expExitCode": "0", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc bfifo 1: root.*limit 3000b", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 handle 1: root bfifo", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "3df6", + "name": "Replace pfifo qdisc on egress with new queue size", + "category": [ + "qdisc", + "fifo" + ], + "setup": [ + "$IP link del dev $DEV1 type dummy || /bin/true", + "$IP link add dev $DEV1 txqueuelen 1000 type dummy", + "$TC qdisc add dev $DEV1 handle 1: root pfifo" + ], + "cmdUnderTest": "$TC qdisc replace dev $DEV1 handle 1: root pfifo limit 30", + "expExitCode": "0", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc pfifo 1: root.*limit 30p", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 handle 1: root pfifo", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "7a67", + "name": "Add bfifo qdisc on egress with queue size in invalid format", + "category": [ + "qdisc", + "fifo" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root bfifo limit foo-bar", + "expExitCode": "1", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc bfifo 1: root.*limit foo-bar", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "1298", + "name": "Add duplicate bfifo qdisc on egress", + "category": [ + "qdisc", + "fifo" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 handle 1: root bfifo" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root bfifo", + "expExitCode": "2", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc bfifo 1: root", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 handle 1: root bfifo", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "45a0", + "name": "Delete nonexistent bfifo qdisc", + "category": [ + "qdisc", + "fifo" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc del dev $DEV1 root handle 1: bfifo", + "expExitCode": "2", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc bfifo 1: root", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "972b", + "name": "Add prio qdisc on egress with invalid format for handles", + "category": [ + "qdisc", + "fifo" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 root handle 123^ bfifo limit 100b", + "expExitCode": "255", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc bfifo 123 root", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "4d39", + "name": "Delete bfifo qdisc twice", + "category": [ + "qdisc", + "fifo" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 root handle 1: bfifo", + "$TC qdisc del dev $DEV1 root handle 1: bfifo" + ], + "cmdUnderTest": "$TC qdisc del dev $DEV1 handle 1: root bfifo", + "expExitCode": "2", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc bfifo 1: root", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + } +] -- cgit v1.2.3-59-g8ed1b From f2a3e4e95f408314938d37fa3146a9f7b304ce74 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Tue, 23 Jul 2019 14:11:33 -0700 Subject: libbpf: provide more helpful message on uninitialized global var When BPF program defines uninitialized global variable, it's put into a special COMMON section. Libbpf will reject such programs, but will provide very unhelpful message with garbage-looking section index. This patch detects special section cases and gives more explicit error message. Signed-off-by: Andrii Nakryiko Acked-by: Song Liu Signed-off-by: Alexei Starovoitov --- tools/lib/bpf/libbpf.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 794dd5064ae8..8741c39adb1c 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -1760,15 +1760,22 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr, (long long) sym.st_value, sym.st_name, name); shdr_idx = sym.st_shndx; + insn_idx = rel.r_offset / sizeof(struct bpf_insn); + pr_debug("relocation: insn_idx=%u, shdr_idx=%u\n", + insn_idx, shdr_idx); + + if (shdr_idx >= SHN_LORESERVE) { + pr_warning("relocation: not yet supported relo for non-static global \'%s\' variable in special section (0x%x) found in insns[%d].code 0x%x\n", + name, shdr_idx, insn_idx, + insns[insn_idx].code); + return -LIBBPF_ERRNO__RELOC; + } if (!bpf_object__relo_in_known_section(obj, shdr_idx)) { pr_warning("Program '%s' contains unrecognized relo data pointing to section %u\n", prog->section_name, shdr_idx); return -LIBBPF_ERRNO__RELOC; } - insn_idx = rel.r_offset / sizeof(struct bpf_insn); - pr_debug("relocation: insn_idx=%u\n", insn_idx); - if (insns[insn_idx].code == (BPF_JMP | BPF_CALL)) { if (insns[insn_idx].src_reg != BPF_PSEUDO_CALL) { pr_warning("incorrect bpf_call opcode\n"); -- cgit v1.2.3-59-g8ed1b From 58b80815362ef18f528e17711f0abec842f56d59 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Tue, 23 Jul 2019 14:34:41 -0700 Subject: selftests/bpf: convert test_get_stack_raw_tp to perf_buffer API Convert test_get_stack_raw_tp test to new perf_buffer API. Signed-off-by: Andrii Nakryiko Acked-by: Song Liu Signed-off-by: Alexei Starovoitov --- .../selftests/bpf/prog_tests/get_stack_raw_tp.c | 78 ++++++++++++---------- .../selftests/bpf/progs/test_get_stack_rawtp.c | 2 +- 2 files changed, 44 insertions(+), 36 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c b/tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c index c2a0a9d5591b..9d73a8f932ac 100644 --- a/tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c +++ b/tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c @@ -1,8 +1,15 @@ // SPDX-License-Identifier: GPL-2.0 +#define _GNU_SOURCE +#include +#include +#include #include #define MAX_CNT_RAWTP 10ull #define MAX_STACK_RAWTP 100 + +static int duration = 0; + struct get_stack_trace_t { int pid; int kern_stack_size; @@ -13,7 +20,7 @@ struct get_stack_trace_t { struct bpf_stack_build_id user_stack_buildid[MAX_STACK_RAWTP]; }; -static int get_stack_print_output(void *data, int size) +static void get_stack_print_output(void *ctx, int cpu, void *data, __u32 size) { bool good_kern_stack = false, good_user_stack = false; const char *nonjit_func = "___bpf_prog_run"; @@ -65,75 +72,76 @@ static int get_stack_print_output(void *data, int size) if (e->user_stack_size > 0 && e->user_stack_buildid_size > 0) good_user_stack = true; } - if (!good_kern_stack || !good_user_stack) - return LIBBPF_PERF_EVENT_ERROR; - if (cnt == MAX_CNT_RAWTP) - return LIBBPF_PERF_EVENT_DONE; - - return LIBBPF_PERF_EVENT_CONT; + if (!good_kern_stack) + CHECK(!good_kern_stack, "kern_stack", "corrupted kernel stack\n"); + if (!good_user_stack) + CHECK(!good_user_stack, "user_stack", "corrupted user stack\n"); } void test_get_stack_raw_tp(void) { const char *file = "./test_get_stack_rawtp.o"; - int i, efd, err, prog_fd, pmu_fd, perfmap_fd; - struct perf_event_attr attr = {}; + const char *prog_name = "raw_tracepoint/sys_enter"; + int i, err, prog_fd, exp_cnt = MAX_CNT_RAWTP; + struct perf_buffer_opts pb_opts = {}; + struct perf_buffer *pb = NULL; + struct bpf_link *link = NULL; struct timespec tv = {0, 10}; - __u32 key = 0, duration = 0; + struct bpf_program *prog; struct bpf_object *obj; + struct bpf_map *map; + cpu_set_t cpu_set; err = bpf_prog_load(file, BPF_PROG_TYPE_RAW_TRACEPOINT, &obj, &prog_fd); if (CHECK(err, "prog_load raw tp", "err %d errno %d\n", err, errno)) return; - efd = bpf_raw_tracepoint_open("sys_enter", prog_fd); - if (CHECK(efd < 0, "raw_tp_open", "err %d errno %d\n", efd, errno)) + prog = bpf_object__find_program_by_title(obj, prog_name); + if (CHECK(!prog, "find_probe", "prog '%s' not found\n", prog_name)) goto close_prog; - perfmap_fd = bpf_find_map(__func__, obj, "perfmap"); - if (CHECK(perfmap_fd < 0, "bpf_find_map", "err %d errno %d\n", - perfmap_fd, errno)) + map = bpf_object__find_map_by_name(obj, "perfmap"); + if (CHECK(!map, "bpf_find_map", "not found\n")) goto close_prog; err = load_kallsyms(); if (CHECK(err < 0, "load_kallsyms", "err %d errno %d\n", err, errno)) goto close_prog; - attr.sample_type = PERF_SAMPLE_RAW; - attr.type = PERF_TYPE_SOFTWARE; - attr.config = PERF_COUNT_SW_BPF_OUTPUT; - pmu_fd = syscall(__NR_perf_event_open, &attr, getpid()/*pid*/, -1/*cpu*/, - -1/*group_fd*/, 0); - if (CHECK(pmu_fd < 0, "perf_event_open", "err %d errno %d\n", pmu_fd, - errno)) + CPU_ZERO(&cpu_set); + CPU_SET(0, &cpu_set); + err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set); + if (CHECK(err, "set_affinity", "err %d, errno %d\n", err, errno)) goto close_prog; - err = bpf_map_update_elem(perfmap_fd, &key, &pmu_fd, BPF_ANY); - if (CHECK(err < 0, "bpf_map_update_elem", "err %d errno %d\n", err, - errno)) + link = bpf_program__attach_raw_tracepoint(prog, "sys_enter"); + if (CHECK(IS_ERR(link), "attach_raw_tp", "err %ld\n", PTR_ERR(link))) goto close_prog; - err = ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0); - if (CHECK(err < 0, "ioctl PERF_EVENT_IOC_ENABLE", "err %d errno %d\n", - err, errno)) - goto close_prog; - - err = perf_event_mmap(pmu_fd); - if (CHECK(err < 0, "perf_event_mmap", "err %d errno %d\n", err, errno)) + pb_opts.sample_cb = get_stack_print_output; + pb = perf_buffer__new(bpf_map__fd(map), 8, &pb_opts); + if (CHECK(IS_ERR(pb), "perf_buf__new", "err %ld\n", PTR_ERR(pb))) goto close_prog; /* trigger some syscall action */ for (i = 0; i < MAX_CNT_RAWTP; i++) nanosleep(&tv, NULL); - err = perf_event_poller(pmu_fd, get_stack_print_output); - if (CHECK(err < 0, "perf_event_poller", "err %d errno %d\n", err, errno)) - goto close_prog; + while (exp_cnt > 0) { + err = perf_buffer__poll(pb, 100); + if (err < 0 && CHECK(err < 0, "pb__poll", "err %d\n", err)) + goto close_prog; + exp_cnt -= err; + } goto close_prog_noerr; close_prog: error_cnt++; close_prog_noerr: + if (!IS_ERR_OR_NULL(link)) + bpf_link__destroy(link); + if (!IS_ERR_OR_NULL(pb)) + perf_buffer__free(pb); bpf_object__close(obj); } diff --git a/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c b/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c index 33254b771384..f8ffa3f3d44b 100644 --- a/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c +++ b/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c @@ -55,7 +55,7 @@ struct { __type(value, raw_stack_trace_t); } rawdata_map SEC(".maps"); -SEC("tracepoint/raw_syscalls/sys_enter") +SEC("raw_tracepoint/sys_enter") int bpf_prog1(void *ctx) { int max_len, max_buildid_len, usize, ksize, total_size; -- cgit v1.2.3-59-g8ed1b From 898ca681cd78e57cec1f5d18df0829d35c464fe8 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Tue, 23 Jul 2019 14:34:42 -0700 Subject: selftests/bpf: switch test_tcpnotify to perf_buffer API Switch test_tcpnotify test to use libbpf's perf_buffer API instead of re-implementing portion of it. Signed-off-by: Andrii Nakryiko Acked-by: Song Liu Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/test_tcpnotify_user.c | 90 +++++++++-------------- 1 file changed, 36 insertions(+), 54 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_tcpnotify_user.c b/tools/testing/selftests/bpf/test_tcpnotify_user.c index 86152d9ae95b..f9765ddf0761 100644 --- a/tools/testing/selftests/bpf/test_tcpnotify_user.c +++ b/tools/testing/selftests/bpf/test_tcpnotify_user.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "bpf_rlimit.h" #include "bpf_util.h" @@ -30,28 +31,34 @@ pthread_t tid; int rx_callbacks; -static int dummyfn(void *data, int size) +static void dummyfn(void *ctx, int cpu, void *data, __u32 size) { struct tcp_notifier *t = data; if (t->type != 0xde || t->subtype != 0xad || t->source != 0xbe || t->hash != 0xef) - return 1; + return; rx_callbacks++; - return 0; } -void tcp_notifier_poller(int fd) +void tcp_notifier_poller(struct perf_buffer *pb) { - while (1) - perf_event_poller(fd, dummyfn); + int err; + + while (1) { + err = perf_buffer__poll(pb, 100); + if (err < 0 && err != -EINTR) { + printf("failed perf_buffer__poll: %d\n", err); + return; + } + } } static void *poller_thread(void *arg) { - int fd = *(int *)arg; + struct perf_buffer *pb = arg; - tcp_notifier_poller(fd); + tcp_notifier_poller(pb); return arg; } @@ -60,52 +67,20 @@ int verify_result(const struct tcpnotify_globals *result) return (result->ncalls > 0 && result->ncalls == rx_callbacks ? 0 : 1); } -static int bpf_find_map(const char *test, struct bpf_object *obj, - const char *name) -{ - struct bpf_map *map; - - map = bpf_object__find_map_by_name(obj, name); - if (!map) { - printf("%s:FAIL:map '%s' not found\n", test, name); - return -1; - } - return bpf_map__fd(map); -} - -static int setup_bpf_perf_event(int mapfd) -{ - struct perf_event_attr attr = { - .sample_type = PERF_SAMPLE_RAW, - .type = PERF_TYPE_SOFTWARE, - .config = PERF_COUNT_SW_BPF_OUTPUT, - }; - int key = 0; - int pmu_fd; - - pmu_fd = syscall(__NR_perf_event_open, &attr, -1, 0, -1, 0); - if (pmu_fd < 0) - return pmu_fd; - bpf_map_update_elem(mapfd, &key, &pmu_fd, BPF_ANY); - - ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0); - return pmu_fd; -} - int main(int argc, char **argv) { const char *file = "test_tcpnotify_kern.o"; - int prog_fd, map_fd, perf_event_fd; + struct bpf_map *perf_map, *global_map; + struct perf_buffer_opts pb_opts = {}; struct tcpnotify_globals g = {0}; + struct perf_buffer *pb = NULL; const char *cg_path = "/foo"; + int prog_fd, rv, cg_fd = -1; int error = EXIT_FAILURE; struct bpf_object *obj; - int cg_fd = -1; - __u32 key = 0; - int rv; char test_script[80]; - int pmu_fd; cpu_set_t cpuset; + __u32 key = 0; CPU_ZERO(&cpuset); CPU_SET(0, &cpuset); @@ -133,19 +108,24 @@ int main(int argc, char **argv) goto err; } - perf_event_fd = bpf_find_map(__func__, obj, "perf_event_map"); - if (perf_event_fd < 0) + perf_map = bpf_object__find_map_by_name(obj, "perf_event_map"); + if (!perf_map) { + printf("FAIL:map '%s' not found\n", "perf_event_map"); goto err; + } - map_fd = bpf_find_map(__func__, obj, "global_map"); - if (map_fd < 0) - goto err; + global_map = bpf_object__find_map_by_name(obj, "global_map"); + if (!global_map) { + printf("FAIL:map '%s' not found\n", "global_map"); + return -1; + } - pmu_fd = setup_bpf_perf_event(perf_event_fd); - if (pmu_fd < 0 || perf_event_mmap(pmu_fd) < 0) + pb_opts.sample_cb = dummyfn; + pb = perf_buffer__new(bpf_map__fd(perf_map), 8, &pb_opts); + if (IS_ERR(pb)) goto err; - pthread_create(&tid, NULL, poller_thread, (void *)&pmu_fd); + pthread_create(&tid, NULL, poller_thread, pb); sprintf(test_script, "iptables -A INPUT -p tcp --dport %d -j DROP", @@ -162,7 +142,7 @@ int main(int argc, char **argv) TESTPORT); system(test_script); - rv = bpf_map_lookup_elem(map_fd, &key, &g); + rv = bpf_map_lookup_elem(bpf_map__fd(global_map), &key, &g); if (rv != 0) { printf("FAILED: bpf_map_lookup_elem returns %d\n", rv); goto err; @@ -182,5 +162,7 @@ err: bpf_prog_detach(cg_fd, BPF_CGROUP_SOCK_OPS); close(cg_fd); cleanup_cgroup_environment(); + if (!IS_ERR_OR_NULL(pb)) + perf_buffer__free(pb); return error; } -- cgit v1.2.3-59-g8ed1b From 47da6e4dc3d37fefd913233c71575666c96491b5 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Tue, 23 Jul 2019 14:34:45 -0700 Subject: selftests/bpf: remove perf buffer helpers libbpf's perf_buffer API supersedes trace_helper.h's helpers. Remove those helpers after all existing users were already moved to perf_buffer API. Signed-off-by: Andrii Nakryiko Acked-by: Song Liu Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/trace_helpers.c | 125 ---------------------------- tools/testing/selftests/bpf/trace_helpers.h | 9 -- 2 files changed, 134 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c index b47f205f0310..7f989b3e4e22 100644 --- a/tools/testing/selftests/bpf/trace_helpers.c +++ b/tools/testing/selftests/bpf/trace_helpers.c @@ -86,128 +86,3 @@ long ksym_get_addr(const char *name) return 0; } - -static int page_size; -static int page_cnt = 8; -static struct perf_event_mmap_page *header; - -int perf_event_mmap_header(int fd, struct perf_event_mmap_page **header) -{ - void *base; - int mmap_size; - - page_size = getpagesize(); - mmap_size = page_size * (page_cnt + 1); - - base = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (base == MAP_FAILED) { - printf("mmap err\n"); - return -1; - } - - *header = base; - return 0; -} - -int perf_event_mmap(int fd) -{ - return perf_event_mmap_header(fd, &header); -} - -static int perf_event_poll(int fd) -{ - struct pollfd pfd = { .fd = fd, .events = POLLIN }; - - return poll(&pfd, 1, 1000); -} - -struct perf_event_sample { - struct perf_event_header header; - __u32 size; - char data[]; -}; - -static enum bpf_perf_event_ret -bpf_perf_event_print(struct perf_event_header *hdr, void *private_data) -{ - struct perf_event_sample *e = (struct perf_event_sample *)hdr; - perf_event_print_fn fn = private_data; - int ret; - - if (e->header.type == PERF_RECORD_SAMPLE) { - ret = fn(e->data, e->size); - if (ret != LIBBPF_PERF_EVENT_CONT) - return ret; - } else if (e->header.type == PERF_RECORD_LOST) { - struct { - struct perf_event_header header; - __u64 id; - __u64 lost; - } *lost = (void *) e; - printf("lost %lld events\n", lost->lost); - } else { - printf("unknown event type=%d size=%d\n", - e->header.type, e->header.size); - } - - return LIBBPF_PERF_EVENT_CONT; -} - -int perf_event_poller(int fd, perf_event_print_fn output_fn) -{ - enum bpf_perf_event_ret ret; - void *buf = NULL; - size_t len = 0; - - for (;;) { - perf_event_poll(fd); - ret = bpf_perf_event_read_simple(header, page_cnt * page_size, - page_size, &buf, &len, - bpf_perf_event_print, - output_fn); - if (ret != LIBBPF_PERF_EVENT_CONT) - break; - } - free(buf); - - return ret; -} - -int perf_event_poller_multi(int *fds, struct perf_event_mmap_page **headers, - int num_fds, perf_event_print_fn output_fn) -{ - enum bpf_perf_event_ret ret; - struct pollfd *pfds; - void *buf = NULL; - size_t len = 0; - int i; - - pfds = calloc(num_fds, sizeof(*pfds)); - if (!pfds) - return LIBBPF_PERF_EVENT_ERROR; - - for (i = 0; i < num_fds; i++) { - pfds[i].fd = fds[i]; - pfds[i].events = POLLIN; - } - - for (;;) { - poll(pfds, num_fds, 1000); - for (i = 0; i < num_fds; i++) { - if (!pfds[i].revents) - continue; - - ret = bpf_perf_event_read_simple(headers[i], - page_cnt * page_size, - page_size, &buf, &len, - bpf_perf_event_print, - output_fn); - if (ret != LIBBPF_PERF_EVENT_CONT) - break; - } - } - free(buf); - free(pfds); - - return ret; -} diff --git a/tools/testing/selftests/bpf/trace_helpers.h b/tools/testing/selftests/bpf/trace_helpers.h index 18924f23db1b..aa4dcfe18050 100644 --- a/tools/testing/selftests/bpf/trace_helpers.h +++ b/tools/testing/selftests/bpf/trace_helpers.h @@ -3,7 +3,6 @@ #define __TRACE_HELPER_H #include -#include struct ksym { long addr; @@ -14,12 +13,4 @@ int load_kallsyms(void); struct ksym *ksym_search(long key); long ksym_get_addr(const char *name); -typedef enum bpf_perf_event_ret (*perf_event_print_fn)(void *data, int size); - -int perf_event_mmap(int fd); -int perf_event_mmap_header(int fd, struct perf_event_mmap_page **header); -/* return LIBBPF_PERF_EVENT_DONE or LIBBPF_PERF_EVENT_ERROR */ -int perf_event_poller(int fd, perf_event_print_fn output_fn); -int perf_event_poller_multi(int *fds, struct perf_event_mmap_page **headers, - int num_fds, perf_event_print_fn output_fn); #endif -- cgit v1.2.3-59-g8ed1b From e62088ea6a20c3517c490d94bcc437ab4c24c9d1 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Thu, 25 Jul 2019 00:29:51 +0900 Subject: selftests: mlxsw: Fix typo in qos_mc_aware.sh This patch fix some spelling typo in qos_mc_aware.sh Signed-off-by: Masanari Iida Acked-by: Randy Dunlap Reviewed-by: Ido Schimmel Signed-off-by: David S. Miller --- tools/testing/selftests/drivers/net/mlxsw/qos_mc_aware.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_mc_aware.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_mc_aware.sh index 71231ad2dbfb..47315fe48d5a 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/qos_mc_aware.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_mc_aware.sh @@ -262,7 +262,7 @@ test_mc_aware() stop_traffic - log_test "UC performace under MC overload" + log_test "UC performance under MC overload" echo "UC-only throughput $(humanize $ucth1)" echo "UC+MC throughput $(humanize $ucth2)" @@ -316,7 +316,7 @@ test_uc_aware() stop_traffic - log_test "MC performace under UC overload" + log_test "MC performance under UC overload" echo " ingress UC throughput $(humanize ${uc_ir})" echo " egress UC throughput $(humanize ${uc_er})" echo " sent $attempts BC ARPs, got $passes responses" -- cgit v1.2.3-59-g8ed1b From 6389a62ff798e781567645c0b0ca3dd7b8a4289d Mon Sep 17 00:00:00 2001 From: "Liu, Changcheng" Date: Thu, 25 Jul 2019 21:22:09 +0800 Subject: usbip: tools: fix GCC8 warning for strncpy GCC8 started emitting warning about using strncpy with number of bytes exactly equal destination size which could lead to non-zero terminated string being copied. Use "SYSFS_PATH_MAX - 1" & "SYSFS_BUS_ID_SIZE - 1" as number of bytes to ensure name is always zero-terminated. Signed-off-by: Changcheng Liu Acked-by: Shuah Khan Link: https://lore.kernel.org/r/20190725132209.GA27590@jerryopenix Signed-off-by: Greg Kroah-Hartman --- tools/usb/usbip/libsrc/usbip_common.c | 6 ++++-- tools/usb/usbip/libsrc/usbip_device_driver.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/usb/usbip/libsrc/usbip_common.c b/tools/usb/usbip/libsrc/usbip_common.c index bb424638d75b..b8d7d480595a 100644 --- a/tools/usb/usbip/libsrc/usbip_common.c +++ b/tools/usb/usbip/libsrc/usbip_common.c @@ -226,8 +226,10 @@ int read_usb_device(struct udev_device *sdev, struct usbip_usb_device *udev) path = udev_device_get_syspath(sdev); name = udev_device_get_sysname(sdev); - strncpy(udev->path, path, SYSFS_PATH_MAX); - strncpy(udev->busid, name, SYSFS_BUS_ID_SIZE); + strncpy(udev->path, path, SYSFS_PATH_MAX - 1); + udev->path[SYSFS_PATH_MAX - 1] = '\0'; + strncpy(udev->busid, name, SYSFS_BUS_ID_SIZE - 1); + udev->busid[SYSFS_BUS_ID_SIZE - 1] = '\0'; sscanf(name, "%u-%u", &busnum, &devnum); udev->busnum = busnum; diff --git a/tools/usb/usbip/libsrc/usbip_device_driver.c b/tools/usb/usbip/libsrc/usbip_device_driver.c index 5a3726eb44ab..051d7d3f443b 100644 --- a/tools/usb/usbip/libsrc/usbip_device_driver.c +++ b/tools/usb/usbip/libsrc/usbip_device_driver.c @@ -91,7 +91,8 @@ int read_usb_vudc_device(struct udev_device *sdev, struct usbip_usb_device *dev) copy_descr_attr16(dev, &descr, idProduct); copy_descr_attr16(dev, &descr, bcdDevice); - strncpy(dev->path, path, SYSFS_PATH_MAX); + strncpy(dev->path, path, SYSFS_PATH_MAX - 1); + dev->path[SYSFS_PATH_MAX - 1] = '\0'; dev->speed = USB_SPEED_UNKNOWN; speed = udev_device_get_sysattr_value(sdev, "current_speed"); @@ -110,7 +111,8 @@ int read_usb_vudc_device(struct udev_device *sdev, struct usbip_usb_device *dev) dev->busnum = 0; name = udev_device_get_sysname(plat); - strncpy(dev->busid, name, SYSFS_BUS_ID_SIZE); + strncpy(dev->busid, name, SYSFS_BUS_ID_SIZE - 1); + dev->busid[SYSFS_BUS_ID_SIZE - 1] = '\0'; return 0; err: fclose(fd); -- cgit v1.2.3-59-g8ed1b From bb4e9af0348dfeafd66c7e7f82e8a0983fe5390c Mon Sep 17 00:00:00 2001 From: Jacek Anaszewski Date: Sun, 9 Jun 2019 20:19:04 +0200 Subject: leds: core: Add support for composing LED class device names Add generic support for composing LED class device name. The newly introduced led_compose_name() function composes device name according to either or pattern, depending on the configuration of initialization data. Backward compatibility with in-driver hard-coded LED class device names is assured thanks to the default_label and devicename properties of newly introduced struct led_init_data. In case none of the aforementioned properties was found, then, for OF nodes, the node name is adopted for LED class device name. At the occassion of amending the Documentation/leds/leds-class.txt unify spelling: colour -> color. Alongside these changes added is a new tool - tools/leds/get_led_device_info.sh. The tool allows retrieving details of a LED class device's parent device, which proves that using vendor or product name for devicename part of LED name doesn't convey any added value since that information had been already available in sysfs. The script performs also basic validation of a LED class device name. Signed-off-by: Jacek Anaszewski Cc: Baolin Wang Cc: Dan Murphy Cc: Daniel Mack Cc: Linus Walleij Cc: Oleh Kravchenko Cc: Sakari Ailus Cc: Simon Shields Reviewed-by: Linus Walleij Acked-by: Pavel Machek --- Documentation/leds/leds-class.rst | 70 ++++++++++++- drivers/leds/led-class.c | 20 +++- drivers/leds/led-core.c | 127 ++++++++++++++++++++++++ drivers/leds/leds.h | 1 + include/linux/leds.h | 45 +++++++++ tools/leds/get_led_device_info.sh | 201 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 458 insertions(+), 6 deletions(-) create mode 100755 tools/leds/get_led_device_info.sh (limited to 'tools') diff --git a/Documentation/leds/leds-class.rst b/Documentation/leds/leds-class.rst index df0120a1ee3c..a0708d3f3d0b 100644 --- a/Documentation/leds/leds-class.rst +++ b/Documentation/leds/leds-class.rst @@ -43,9 +43,73 @@ LED Device Naming Is currently of the form: - "devicename:colour:function" - -There have been calls for LED properties such as colour to be exported as + "devicename:color:function" + +- devicename: + it should refer to a unique identifier created by the kernel, + like e.g. phyN for network devices or inputN for input devices, rather + than to the hardware; the information related to the product and the bus + to which given device is hooked is available in sysfs and can be + retrieved using get_led_device_info.sh script from tools/leds; generally + this section is expected mostly for LEDs that are somehow associated with + other devices. + +- color: + one of LED_COLOR_ID_* definitions from the header + include/dt-bindings/leds/common.h. + +- function: + one of LED_FUNCTION_* definitions from the header + include/dt-bindings/leds/common.h. + +If required color or function is missing, please submit a patch +to linux-leds@vger.kernel.org. + +It is possible that more than one LED with the same color and function will +be required for given platform, differing only with an ordinal number. +In this case it is preferable to just concatenate the predefined LED_FUNCTION_* +name with required "-N" suffix in the driver. fwnode based drivers can use +function-enumerator property for that and then the concatenation will be handled +automatically by the LED core upon LED class device registration. + +LED subsystem has also a protection against name clash, that may occur +when LED class device is created by a driver of hot-pluggable device and +it doesn't provide unique devicename section. In this case numerical +suffix (e.g. "_1", "_2", "_3" etc.) is added to the requested LED class +device name. + +There might be still LED class drivers around using vendor or product name +for devicename, but this approach is now deprecated as it doesn't convey +any added value. Product information can be found in other places in sysfs +(see tools/leds/get_led_device_info.sh). + +Examples of proper LED names: + + - "red:disk" + - "white:flash" + - "red:indicator" + - "phy1:green:wlan" + - "phy3::wlan" + - ":kbd_backlight" + - "input5::kbd_backlight" + - "input3::numlock" + - "input3::scrolllock" + - "input3::capslock" + - "mmc1::status" + - "white:status" + +get_led_device_info.sh script can be used for verifying if the LED name +meets the requirements pointed out here. It performs validation of the LED class +devicename sections and gives hints on expected value for a section in case +the validation fails for it. So far the script supports validation +of associations between LEDs and following types of devices: + + - input devices + - ieee80211 compliant USB devices + +The script is open to extensions. + +There have been calls for LED properties such as color to be exported as individual led class attributes. As a solution which doesn't incur as much overhead, I suggest these become part of the device name. The naming scheme above leaves scope for further attributes should they be needed. If sections diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 242122f49333..508d6477d0b8 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -254,17 +254,31 @@ int led_classdev_register_ext(struct device *parent, struct led_classdev *led_cdev, struct led_init_data *init_data) { - char name[LED_MAX_NAME_SIZE]; + char composed_name[LED_MAX_NAME_SIZE]; + char final_name[LED_MAX_NAME_SIZE]; + const char *proposed_name = composed_name; int ret; - ret = led_classdev_next_name(led_cdev->name, name, sizeof(name)); + if (init_data) { + if (init_data->devname_mandatory && !init_data->devicename) { + dev_err(parent, "Mandatory device name is missing"); + return -EINVAL; + } + ret = led_compose_name(parent, init_data, composed_name); + if (ret < 0) + return ret; + } else { + proposed_name = led_cdev->name; + } + + ret = led_classdev_next_name(proposed_name, final_name, sizeof(final_name)); if (ret < 0) return ret; mutex_init(&led_cdev->led_access); mutex_lock(&led_cdev->led_access); led_cdev->dev = device_create_with_groups(leds_class, parent, 0, - led_cdev, led_cdev->groups, "%s", name); + led_cdev, led_cdev->groups, "%s", final_name); if (IS_ERR(led_cdev->dev)) { mutex_unlock(&led_cdev->led_access); return PTR_ERR(led_cdev->dev); diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index 7107cd7e87cf..f0c1c403f678 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -13,8 +13,10 @@ #include #include #include +#include #include #include +#include #include "leds.h" DECLARE_RWSEM(leds_list_lock); @@ -23,6 +25,18 @@ EXPORT_SYMBOL_GPL(leds_list_lock); LIST_HEAD(leds_list); EXPORT_SYMBOL_GPL(leds_list); +const char * const led_colors[LED_COLOR_ID_MAX] = { + [LED_COLOR_ID_WHITE] = "white", + [LED_COLOR_ID_RED] = "red", + [LED_COLOR_ID_GREEN] = "green", + [LED_COLOR_ID_BLUE] = "blue", + [LED_COLOR_ID_AMBER] = "amber", + [LED_COLOR_ID_VIOLET] = "violet", + [LED_COLOR_ID_YELLOW] = "yellow", + [LED_COLOR_ID_IR] = "ir", +}; +EXPORT_SYMBOL_GPL(led_colors); + static int __led_set_brightness(struct led_classdev *led_cdev, enum led_brightness value) { @@ -353,3 +367,116 @@ void led_sysfs_enable(struct led_classdev *led_cdev) led_cdev->flags &= ~LED_SYSFS_DISABLE; } EXPORT_SYMBOL_GPL(led_sysfs_enable); + +static void led_parse_fwnode_props(struct device *dev, + struct fwnode_handle *fwnode, + struct led_properties *props) +{ + int ret; + + if (!fwnode) + return; + + if (fwnode_property_present(fwnode, "label")) { + ret = fwnode_property_read_string(fwnode, "label", &props->label); + if (ret) + dev_err(dev, "Error parsing 'label' property (%d)\n", ret); + return; + } + + if (fwnode_property_present(fwnode, "color")) { + ret = fwnode_property_read_u32(fwnode, "color", &props->color); + if (ret) + dev_err(dev, "Error parsing 'color' property (%d)\n", ret); + else if (props->color >= LED_COLOR_ID_MAX) + dev_err(dev, "LED color identifier out of range\n"); + else + props->color_present = true; + } + + + if (!fwnode_property_present(fwnode, "function")) + return; + + ret = fwnode_property_read_string(fwnode, "function", &props->function); + if (ret) { + dev_err(dev, + "Error parsing 'function' property (%d)\n", + ret); + } + + if (!fwnode_property_present(fwnode, "function-enumerator")) + return; + + ret = fwnode_property_read_u32(fwnode, "function-enumerator", + &props->func_enum); + if (ret) { + dev_err(dev, + "Error parsing 'function-enumerator' property (%d)\n", + ret); + } else { + props->func_enum_present = true; + } +} + +int led_compose_name(struct device *dev, struct led_init_data *init_data, + char *led_classdev_name) +{ + struct led_properties props = {}; + struct fwnode_handle *fwnode = init_data->fwnode; + const char *devicename = init_data->devicename; + + if (!led_classdev_name) + return -EINVAL; + + led_parse_fwnode_props(dev, fwnode, &props); + + if (props.label) { + /* + * If init_data.devicename is NULL, then it indicates that + * DT label should be used as-is for LED class device name. + * Otherwise the label is prepended with devicename to compose + * the final LED class device name. + */ + if (!devicename) { + strscpy(led_classdev_name, props.label, + LED_MAX_NAME_SIZE); + } else { + snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s", + devicename, props.label); + } + } else if (props.function || props.color_present) { + char tmp_buf[LED_MAX_NAME_SIZE]; + + if (props.func_enum_present) { + snprintf(tmp_buf, LED_MAX_NAME_SIZE, "%s:%s-%d", + props.color_present ? led_colors[props.color] : "", + props.function ?: "", props.func_enum); + } else { + snprintf(tmp_buf, LED_MAX_NAME_SIZE, "%s:%s", + props.color_present ? led_colors[props.color] : "", + props.function ?: ""); + } + if (init_data->devname_mandatory) { + snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s", + devicename, tmp_buf); + } else { + strscpy(led_classdev_name, tmp_buf, LED_MAX_NAME_SIZE); + + } + } else if (init_data->default_label) { + if (!devicename) { + dev_err(dev, "Legacy LED naming requires devicename segment"); + return -EINVAL; + } + snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s", + devicename, init_data->default_label); + } else if (is_of_node(fwnode)) { + strscpy(led_classdev_name, to_of_node(fwnode)->name, + LED_MAX_NAME_SIZE); + } else + return -EINVAL; + + return 0; +} +EXPORT_SYMBOL_GPL(led_compose_name); diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h index 47b229469069..0b577cece8f7 100644 --- a/drivers/leds/leds.h +++ b/drivers/leds/leds.h @@ -27,5 +27,6 @@ void led_set_brightness_nosleep(struct led_classdev *led_cdev, extern struct rw_semaphore leds_list_lock; extern struct list_head leds_list; extern struct list_head trigger_list; +extern const char * const led_colors[LED_COLOR_ID_MAX]; #endif /* __LEDS_H_INCLUDED */ diff --git a/include/linux/leds.h b/include/linux/leds.h index 2bbe8a38fe39..d101fd13e18e 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -8,6 +8,7 @@ #ifndef __LINUX_LEDS_H_INCLUDED #define __LINUX_LEDS_H_INCLUDED +#include #include #include #include @@ -33,6 +34,25 @@ enum led_brightness { struct led_init_data { /* device fwnode handle */ struct fwnode_handle *fwnode; + /* + * default tuple, for backward compatibility + * with in-driver hard-coded LED names used as a fallback when + * DT "label" property is absent; it should be set to NULL + * in new LED class drivers. + */ + const char *default_label; + /* + * string to be used for devicename section of LED class device + * either for label based LED name composition path or for fwnode + * based when devname_mandatory is true + */ + const char *devicename; + /* + * indicates if LED name should always comprise devicename section; + * only LEDs exposed by drivers of hot-pluggable devices should + * set it to true + */ + bool devname_mandatory; }; struct led_classdev { @@ -257,6 +277,22 @@ extern void led_sysfs_disable(struct led_classdev *led_cdev); */ extern void led_sysfs_enable(struct led_classdev *led_cdev); +/** + * led_compose_name - compose LED class device name + * @dev: LED controller device object + * @child: child fwnode_handle describing a LED or a group of synchronized LEDs; + * it must be provided only for fwnode based LEDs + * @led_classdev_name: composed LED class device name + * + * Create LED class device name basing on the provided init_data argument. + * The name can have or . + * form, depending on the init_data configuration. + * + * Returns: 0 on success or negative error value on failure + */ +extern int led_compose_name(struct device *dev, struct led_init_data *init_data, + char *led_classdev_name); + /** * led_sysfs_is_disabled - check if LED sysfs interface is disabled * @led_cdev: the LED to query @@ -434,6 +470,15 @@ struct led_platform_data { struct led_info *leds; }; +struct led_properties { + u32 color; + bool color_present; + const char *function; + u32 func_enum; + bool func_enum_present; + const char *label; +}; + struct gpio_desc; typedef int (*gpio_blink_set_t)(struct gpio_desc *desc, int state, unsigned long *delay_on, diff --git a/tools/leds/get_led_device_info.sh b/tools/leds/get_led_device_info.sh new file mode 100755 index 000000000000..ccfa442db5fe --- /dev/null +++ b/tools/leds/get_led_device_info.sh @@ -0,0 +1,201 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +led_common_defs_path="include/dt-bindings/leds/common.h" + +num_args=$# +if [ $num_args -eq 1 ]; then + linux_top=$(dirname `realpath $0` | awk -F/ \ + '{ \ + i=1; \ + while (i <= NF - 2) { \ + printf $i"/"; \ + i++; \ + }; \ + }') + led_defs_path=$linux_top/$led_common_defs_path +elif [ $num_args -eq 2 ]; then + led_defs_path=`realpath $2` +else + echo "Usage: get_led_device_info.sh LED_CDEV_PATH [LED_COMMON_DEFS_PATH]" + exit 1 +fi + +if [ ! -f $led_defs_path ]; then + echo "$led_defs_path doesn't exist" + exit 1 +fi + +led_cdev_path=`echo $1 | sed s'/\/$//'` + +ls "$led_cdev_path/brightness" > /dev/null 2>&1 +if [ $? -ne 0 ]; then + echo "Device \"$led_cdev_path\" does not exist." + exit 1 +fi + +bus=`readlink $led_cdev_path/device/subsystem | sed s'/.*\///'` +usb_subdev=`readlink $led_cdev_path | grep usb | sed s'/\(.*usb[0-9]*\/[0-9]*-[0-9]*\)\/.*/\1/'` +ls "$led_cdev_path/device/of_node/compatible" > /dev/null 2>&1 +of_node_missing=$? + +if [ "$bus" = "input" ]; then + input_node=`readlink $led_cdev_path/device | sed s'/.*\///'` + if [ ! -z "$usb_subdev" ]; then + bus="usb" + fi +fi + +if [ "$bus" = "usb" ]; then + usb_interface=`readlink $led_cdev_path | sed s'/.*\(usb[0-9]*\)/\1/' | cut -d\/ -f3` + cd $led_cdev_path/../$usb_subdev + driver=`readlink $usb_interface/driver | sed s'/.*\///'` + if [ -d "$usb_interface/ieee80211" ]; then + wifi_phy=`ls -l $usb_interface/ieee80211 | grep phy | awk '{print $9}'` + fi + idVendor=`cat idVendor` + idProduct=`cat idProduct` + manufacturer=`cat manufacturer` + product=`cat product` +elif [ "$bus" = "input" ]; then + cd $led_cdev_path + product=`cat device/name` + driver=`cat device/device/driver/description` +elif [ $of_node_missing -eq 0 ]; then + cd $led_cdev_path + compatible=`cat device/of_node/compatible` + if [ "$compatible" = "gpio-leds" ]; then + driver="leds-gpio" + elif [ "$compatible" = "pwm-leds" ]; then + driver="leds-pwm" + else + manufacturer=`echo $compatible | awk -F, '{print $1}'` + product=`echo $compatible | awk -F, '{print $2}'` + fi +else + echo "Unknown device type." + exit 1 +fi + +printf "\n#####################################\n" +printf "# LED class device hardware details #\n" +printf "#####################################\n\n" + +printf "bus:\t\t\t$bus\n" + +if [ ! -z "$idVendor" ]; then + printf "idVendor:\t\t$idVendor\n" +fi + +if [ ! -z "$idProduct" ]; then + printf "idProduct:\t\t$idProduct\n" +fi + +if [ ! -z "$manufacturer" ]; then + printf "manufacturer:\t\t$manufacturer\n" +fi + +if [ ! -z "$product" ]; then + printf "product:\t\t$product\n" +fi + +if [ ! -z "$driver" ]; then + printf "driver:\t\t\t$driver\n" +fi + +if [ ! -z "$input_node" ]; then + printf "associated input node:\t$input_node\n" +fi + +printf "\n####################################\n" +printf "# LED class device name validation #\n" +printf "####################################\n\n" + +led_name=`echo $led_cdev_path | sed s'/.*\///'` + +num_sections=`echo $led_name | awk -F: '{print NF}'` + +if [ $num_sections -eq 1 ]; then + printf "\":\" delimiter not detected.\t[ FAILED ]\n" + exit 1 +elif [ $num_sections -eq 2 ]; then + color=`echo $led_name | cut -d: -f1` + function=`echo $led_name | cut -d: -f2` +elif [ $num_sections -eq 3 ]; then + devicename=`echo $led_name | cut -d: -f1` + color=`echo $led_name | cut -d: -f2` + function=`echo $led_name | cut -d: -f3` +else + printf "Detected %d sections in the LED class device name - should the script be updated?\n" $num_sections + exit 1 +fi + +S_DEV="devicename" +S_CLR="color " +S_FUN="function " +status_tab=20 + +print_msg_ok() +{ + local section_name="$1" + local section_val="$2" + local msg="$3" + printf "$section_name :\t%-${status_tab}.${status_tab}s %s %s\n" "$section_val" "[ OK ] " "$msg" +} + +print_msg_failed() +{ + local section_name="$1" + local section_val="$2" + local msg="$3" + printf "$section_name :\t%-${status_tab}.${status_tab}s %s %s\n" "$section_val" "[ FAILED ]" "$msg" +} + +if [ ! -z "$input_node" ]; then + expected_devname=$input_node +elif [ ! -z "$wifi_phy" ]; then + expected_devname=$wifi_phy +fi + +if [ ! -z "$devicename" ]; then + if [ ! -z "$expected_devname" ]; then + if [ "$devicename" = "$expected_devname" ]; then + print_msg_ok "$S_DEV" "$devicename" + else + print_msg_failed "$S_DEV" "$devicename" "Expected: $expected_devname" + fi + else + if [ "$devicename" = "$manufacturer" ]; then + print_msg_failed "$S_DEV" "$devicename" "Redundant: use of vendor name is discouraged" + elif [ "$devicename" = "$product" ]; then + print_msg_failed "$S_DEV" "$devicename" "Redundant: use of product name is discouraged" + else + print_msg_failed "$S_DEV" "$devicename" "Unknown devicename - should the script be updated?" + fi + fi +elif [ ! -z "$expected_devname" ]; then + print_msg_failed "$S_DEV" "blank" "Expected: $expected_devname" +fi + +if [ ! -z "$color" ]; then + color_upper=`echo $color | tr [:lower:] [:upper:]` + color_id_definition=$(cat $led_defs_path | grep "_$color_upper\s" | awk '{print $2}') + if [ ! -z "$color_id_definition" ]; then + print_msg_ok "$S_CLR" "$color" "Matching definition: $color_id_definition" + else + print_msg_failed "$S_CLR" "$color" "Definition not found in $led_defs_path" + fi + +fi + +if [ ! -z "$function" ]; then + # strip optional enumerator + function=`echo $function | sed s'/\(.*\)-[0-9]*$/\1/'` + fun_definition=$(cat $led_defs_path | grep "\"$function\"" | awk '{print $2}') + if [ ! -z "$fun_definition" ]; then + print_msg_ok "$S_FUN" "$function" "Matching definition: $fun_definition" + else + print_msg_failed "$S_FUN" "$function" "Definition not found in $led_defs_path" + fi + +fi -- cgit v1.2.3-59-g8ed1b From 03cd1d1a493e92a80d60040d6aa8160aff239942 Mon Sep 17 00:00:00 2001 From: Allan Zhang Date: Tue, 23 Jul 2019 17:07:25 -0700 Subject: selftests/bpf: Add selftests for bpf_perf_event_output Software event output is only enabled by a few prog types. This test is to ensure that all supported types are enabled for bpf_perf_event_output successfully. Signed-off-by: Allan Zhang Acked-by: Song Liu Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/test_verifier.c | 12 ++- .../testing/selftests/bpf/verifier/event_output.c | 94 ++++++++++++++++++++++ 2 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/bpf/verifier/event_output.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index 84135d5f4b35..44e2d640b088 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c @@ -50,7 +50,7 @@ #define MAX_INSNS BPF_MAXINSNS #define MAX_TEST_INSNS 1000000 #define MAX_FIXUPS 8 -#define MAX_NR_MAPS 18 +#define MAX_NR_MAPS 19 #define MAX_TEST_RUNS 8 #define POINTER_VALUE 0xcafe4all #define TEST_DATA_LEN 64 @@ -84,6 +84,7 @@ struct bpf_test { int fixup_map_array_wo[MAX_FIXUPS]; int fixup_map_array_small[MAX_FIXUPS]; int fixup_sk_storage_map[MAX_FIXUPS]; + int fixup_map_event_output[MAX_FIXUPS]; const char *errstr; const char *errstr_unpriv; uint32_t insn_processed; @@ -632,6 +633,7 @@ static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type, int *fixup_map_array_wo = test->fixup_map_array_wo; int *fixup_map_array_small = test->fixup_map_array_small; int *fixup_sk_storage_map = test->fixup_sk_storage_map; + int *fixup_map_event_output = test->fixup_map_event_output; if (test->fill_helper) { test->fill_insns = calloc(MAX_TEST_INSNS, sizeof(struct bpf_insn)); @@ -793,6 +795,14 @@ static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type, fixup_sk_storage_map++; } while (*fixup_sk_storage_map); } + if (*fixup_map_event_output) { + map_fds[18] = __create_map(BPF_MAP_TYPE_PERF_EVENT_ARRAY, + sizeof(int), sizeof(int), 1, 0); + do { + prog[*fixup_map_event_output].imm = map_fds[18]; + fixup_map_event_output++; + } while (*fixup_map_event_output); + } } static int set_admin(bool admin) diff --git a/tools/testing/selftests/bpf/verifier/event_output.c b/tools/testing/selftests/bpf/verifier/event_output.c new file mode 100644 index 000000000000..130553e19eca --- /dev/null +++ b/tools/testing/selftests/bpf/verifier/event_output.c @@ -0,0 +1,94 @@ +/* instructions used to output a skb based software event, produced + * from code snippet: + * struct TMP { + * uint64_t tmp; + * } tt; + * tt.tmp = 5; + * bpf_perf_event_output(skb, &connection_tracking_event_map, 0, + * &tt, sizeof(tt)); + * return 1; + * + * the bpf assembly from llvm is: + * 0: b7 02 00 00 05 00 00 00 r2 = 5 + * 1: 7b 2a f8 ff 00 00 00 00 *(u64 *)(r10 - 8) = r2 + * 2: bf a4 00 00 00 00 00 00 r4 = r10 + * 3: 07 04 00 00 f8 ff ff ff r4 += -8 + * 4: 18 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r2 = 0ll + * 6: b7 03 00 00 00 00 00 00 r3 = 0 + * 7: b7 05 00 00 08 00 00 00 r5 = 8 + * 8: 85 00 00 00 19 00 00 00 call 25 + * 9: b7 00 00 00 01 00 00 00 r0 = 1 + * 10: 95 00 00 00 00 00 00 00 exit + * + * The reason I put the code here instead of fill_helpers is that map fixup + * is against the insns, instead of filled prog. + */ + +#define __PERF_EVENT_INSNS__ \ + BPF_MOV64_IMM(BPF_REG_2, 5), \ + BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -8), \ + BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), \ + BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), \ + BPF_LD_MAP_FD(BPF_REG_2, 0), \ + BPF_MOV64_IMM(BPF_REG_3, 0), \ + BPF_MOV64_IMM(BPF_REG_5, 8), \ + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, \ + BPF_FUNC_perf_event_output), \ + BPF_MOV64_IMM(BPF_REG_0, 1), \ + BPF_EXIT_INSN(), +{ + "perfevent for sockops", + .insns = { __PERF_EVENT_INSNS__ }, + .prog_type = BPF_PROG_TYPE_SOCK_OPS, + .fixup_map_event_output = { 4 }, + .result = ACCEPT, + .retval = 1, +}, +{ + "perfevent for tc", + .insns = { __PERF_EVENT_INSNS__ }, + .prog_type = BPF_PROG_TYPE_SCHED_CLS, + .fixup_map_event_output = { 4 }, + .result = ACCEPT, + .retval = 1, +}, +{ + "perfevent for lwt out", + .insns = { __PERF_EVENT_INSNS__ }, + .prog_type = BPF_PROG_TYPE_LWT_OUT, + .fixup_map_event_output = { 4 }, + .result = ACCEPT, + .retval = 1, +}, +{ + "perfevent for xdp", + .insns = { __PERF_EVENT_INSNS__ }, + .prog_type = BPF_PROG_TYPE_XDP, + .fixup_map_event_output = { 4 }, + .result = ACCEPT, + .retval = 1, +}, +{ + "perfevent for socket filter", + .insns = { __PERF_EVENT_INSNS__ }, + .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, + .fixup_map_event_output = { 4 }, + .result = ACCEPT, + .retval = 1, +}, +{ + "perfevent for sk_skb", + .insns = { __PERF_EVENT_INSNS__ }, + .prog_type = BPF_PROG_TYPE_SK_SKB, + .fixup_map_event_output = { 4 }, + .result = ACCEPT, + .retval = 1, +}, +{ + "perfevent for cgroup skb", + .insns = { __PERF_EVENT_INSNS__ }, + .prog_type = BPF_PROG_TYPE_CGROUP_SKB, + .fixup_map_event_output = { 4 }, + .result = ACCEPT, + .retval = 1, +}, -- cgit v1.2.3-59-g8ed1b From 57debff23c4cd47f25850a5f42a903aebe535e95 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Thu, 25 Jul 2019 15:52:28 -0700 Subject: tools/bpf: sync bpf_flow_keys flags Export bpf_flow_keys flags to tools/libbpf/selftests. Acked-by: Petar Penkov Acked-by: Willem de Bruijn Acked-by: Song Liu Cc: Song Liu Cc: Willem de Bruijn Cc: Petar Penkov Signed-off-by: Stanislav Fomichev Signed-off-by: Alexei Starovoitov --- tools/include/uapi/linux/bpf.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools') diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 4e455018da65..2e4b0848d795 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -3504,6 +3504,10 @@ enum bpf_task_fd_type { BPF_FD_TYPE_URETPROBE, /* filename + offset */ }; +#define BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG (1U << 0) +#define BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL (1U << 1) +#define BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP (1U << 2) + struct bpf_flow_keys { __u16 nhoff; __u16 thoff; @@ -3525,6 +3529,7 @@ struct bpf_flow_keys { __u32 ipv6_dst[4]; /* in6_addr; network order */ }; }; + __u32 flags; }; struct bpf_func_info { -- cgit v1.2.3-59-g8ed1b From ae173a915785e55574c1fc54edf58b9b87b28c22 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Thu, 25 Jul 2019 15:52:29 -0700 Subject: selftests/bpf: support BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG bpf_flow.c: exit early unless BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG is passed in flags. Also, set ip_proto earlier, this makes sure we have correct value with fragmented packets. Add selftest cases to test ipv4/ipv6 fragments and skip eth_get_headlen tests that don't have BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG flag. eth_get_headlen calls flow dissector with BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG flag so we can't run tests that have different set of input flags against it. v2: * sefltests -> selftests (Willem de Bruijn) * Reword a comment about eth_get_headlen flags (Song Liu) Acked-by: Petar Penkov Acked-by: Willem de Bruijn Acked-by: Song Liu Cc: Song Liu Cc: Willem de Bruijn Cc: Petar Penkov Signed-off-by: Stanislav Fomichev Signed-off-by: Alexei Starovoitov --- .../selftests/bpf/prog_tests/flow_dissector.c | 133 ++++++++++++++++++++- tools/testing/selftests/bpf/progs/bpf_flow.c | 29 ++++- 2 files changed, 155 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c index c938283ac232..8e8c18aced9b 100644 --- a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c +++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c @@ -5,6 +5,10 @@ #include #include +#ifndef IP_MF +#define IP_MF 0x2000 +#endif + #define CHECK_FLOW_KEYS(desc, got, expected) \ CHECK_ATTR(memcmp(&got, &expected, sizeof(got)) != 0, \ desc, \ @@ -49,6 +53,18 @@ struct ipv6_pkt { struct tcphdr tcp; } __packed; +struct ipv6_frag_pkt { + struct ethhdr eth; + struct ipv6hdr iph; + struct frag_hdr { + __u8 nexthdr; + __u8 reserved; + __be16 frag_off; + __be32 identification; + } ipf; + struct tcphdr tcp; +} __packed; + struct dvlan_ipv6_pkt { struct ethhdr eth; __u16 vlan_tci; @@ -65,9 +81,11 @@ struct test { struct ipv4_pkt ipv4; struct svlan_ipv4_pkt svlan_ipv4; struct ipv6_pkt ipv6; + struct ipv6_frag_pkt ipv6_frag; struct dvlan_ipv6_pkt dvlan_ipv6; } pkt; struct bpf_flow_keys keys; + __u32 flags; }; #define VLAN_HLEN 4 @@ -143,6 +161,102 @@ struct test tests[] = { .n_proto = __bpf_constant_htons(ETH_P_IPV6), }, }, + { + .name = "ipv4-frag", + .pkt.ipv4 = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IP), + .iph.ihl = 5, + .iph.protocol = IPPROTO_TCP, + .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES), + .iph.frag_off = __bpf_constant_htons(IP_MF), + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .flags = BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG, + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct iphdr), + .addr_proto = ETH_P_IP, + .ip_proto = IPPROTO_TCP, + .n_proto = __bpf_constant_htons(ETH_P_IP), + .is_frag = true, + .is_first_frag = true, + .sport = 80, + .dport = 8080, + }, + .flags = BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG, + }, + { + .name = "ipv4-no-frag", + .pkt.ipv4 = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IP), + .iph.ihl = 5, + .iph.protocol = IPPROTO_TCP, + .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES), + .iph.frag_off = __bpf_constant_htons(IP_MF), + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct iphdr), + .addr_proto = ETH_P_IP, + .ip_proto = IPPROTO_TCP, + .n_proto = __bpf_constant_htons(ETH_P_IP), + .is_frag = true, + .is_first_frag = true, + }, + }, + { + .name = "ipv6-frag", + .pkt.ipv6_frag = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6), + .iph.nexthdr = IPPROTO_FRAGMENT, + .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES), + .ipf.nexthdr = IPPROTO_TCP, + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .flags = BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG, + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct ipv6hdr) + + sizeof(struct frag_hdr), + .addr_proto = ETH_P_IPV6, + .ip_proto = IPPROTO_TCP, + .n_proto = __bpf_constant_htons(ETH_P_IPV6), + .is_frag = true, + .is_first_frag = true, + .sport = 80, + .dport = 8080, + }, + .flags = BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG, + }, + { + .name = "ipv6-no-frag", + .pkt.ipv6_frag = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6), + .iph.nexthdr = IPPROTO_FRAGMENT, + .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES), + .ipf.nexthdr = IPPROTO_TCP, + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct ipv6hdr) + + sizeof(struct frag_hdr), + .addr_proto = ETH_P_IPV6, + .ip_proto = IPPROTO_TCP, + .n_proto = __bpf_constant_htons(ETH_P_IPV6), + .is_frag = true, + .is_first_frag = true, + }, + }, }; static int create_tap(const char *ifname) @@ -225,6 +339,13 @@ void test_flow_dissector(void) .data_size_in = sizeof(tests[i].pkt), .data_out = &flow_keys, }; + static struct bpf_flow_keys ctx = {}; + + if (tests[i].flags) { + tattr.ctx_in = &ctx; + tattr.ctx_size_in = sizeof(ctx); + ctx.flags = tests[i].flags; + } err = bpf_prog_test_run_xattr(&tattr); CHECK_ATTR(tattr.data_size_out != sizeof(flow_keys) || @@ -251,10 +372,20 @@ void test_flow_dissector(void) CHECK(err, "ifup", "err %d errno %d\n", err, errno); for (i = 0; i < ARRAY_SIZE(tests); i++) { - struct bpf_flow_keys flow_keys = {}; + /* Keep in sync with 'flags' from eth_get_headlen. */ + __u32 eth_get_headlen_flags = + BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG; struct bpf_prog_test_run_attr tattr = {}; + struct bpf_flow_keys flow_keys = {}; __u32 key = 0; + /* For skb-less case we can't pass input flags; run + * only the tests that have a matching set of flags. + */ + + if (tests[i].flags != eth_get_headlen_flags) + continue; + err = tx_tap(tap_fd, &tests[i].pkt, sizeof(tests[i].pkt)); CHECK(err < 0, "tx_tap", "err %d errno %d\n", err, errno); diff --git a/tools/testing/selftests/bpf/progs/bpf_flow.c b/tools/testing/selftests/bpf/progs/bpf_flow.c index 5ae485a6af3f..f931cd3db9d4 100644 --- a/tools/testing/selftests/bpf/progs/bpf_flow.c +++ b/tools/testing/selftests/bpf/progs/bpf_flow.c @@ -153,7 +153,6 @@ static __always_inline int parse_ip_proto(struct __sk_buff *skb, __u8 proto) struct tcphdr *tcp, _tcp; struct udphdr *udp, _udp; - keys->ip_proto = proto; switch (proto) { case IPPROTO_ICMP: icmp = bpf_flow_dissect_get_header(skb, sizeof(*icmp), &_icmp); @@ -231,7 +230,6 @@ static __always_inline int parse_ipv6_proto(struct __sk_buff *skb, __u8 nexthdr) { struct bpf_flow_keys *keys = skb->flow_keys; - keys->ip_proto = nexthdr; switch (nexthdr) { case IPPROTO_HOPOPTS: case IPPROTO_DSTOPTS: @@ -266,6 +264,7 @@ PROG(IP)(struct __sk_buff *skb) keys->addr_proto = ETH_P_IP; keys->ipv4_src = iph->saddr; keys->ipv4_dst = iph->daddr; + keys->ip_proto = iph->protocol; keys->thoff += iph->ihl << 2; if (data + keys->thoff > data_end) @@ -273,13 +272,20 @@ PROG(IP)(struct __sk_buff *skb) if (iph->frag_off & bpf_htons(IP_MF | IP_OFFSET)) { keys->is_frag = true; - if (iph->frag_off & bpf_htons(IP_OFFSET)) + if (iph->frag_off & bpf_htons(IP_OFFSET)) { /* From second fragment on, packets do not have headers * we can parse. */ done = true; - else + } else { keys->is_first_frag = true; + /* No need to parse fragmented packet unless + * explicitly asked for. + */ + if (!(keys->flags & + BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG)) + done = true; + } } if (done) @@ -301,6 +307,7 @@ PROG(IPV6)(struct __sk_buff *skb) memcpy(&keys->ipv6_src, &ip6h->saddr, 2*sizeof(ip6h->saddr)); keys->thoff += sizeof(struct ipv6hdr); + keys->ip_proto = ip6h->nexthdr; return parse_ipv6_proto(skb, ip6h->nexthdr); } @@ -317,7 +324,8 @@ PROG(IPV6OP)(struct __sk_buff *skb) /* hlen is in 8-octets and does not include the first 8 bytes * of the header */ - skb->flow_keys->thoff += (1 + ip6h->hdrlen) << 3; + keys->thoff += (1 + ip6h->hdrlen) << 3; + keys->ip_proto = ip6h->nexthdr; return parse_ipv6_proto(skb, ip6h->nexthdr); } @@ -333,9 +341,18 @@ PROG(IPV6FR)(struct __sk_buff *skb) keys->thoff += sizeof(*fragh); keys->is_frag = true; - if (!(fragh->frag_off & bpf_htons(IP6_OFFSET))) + keys->ip_proto = fragh->nexthdr; + + if (!(fragh->frag_off & bpf_htons(IP6_OFFSET))) { keys->is_first_frag = true; + /* No need to parse fragmented packet unless + * explicitly asked for. + */ + if (!(keys->flags & BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG)) + return export_flow_keys(keys, BPF_OK); + } + return parse_ipv6_proto(skb, fragh->nexthdr); } -- cgit v1.2.3-59-g8ed1b From 71c99e32b926159ea628352751f66383d7d04d17 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Thu, 25 Jul 2019 15:52:30 -0700 Subject: bpf/flow_dissector: support ipv6 flow_label and BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL Add support for exporting ipv6 flow label via bpf_flow_keys. Export flow label from bpf_flow.c and also return early when BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL is passed. Acked-by: Petar Penkov Acked-by: Willem de Bruijn Acked-by: Song Liu Cc: Song Liu Cc: Willem de Bruijn Cc: Petar Penkov Signed-off-by: Stanislav Fomichev Signed-off-by: Alexei Starovoitov --- include/uapi/linux/bpf.h | 1 + net/core/flow_dissector.c | 9 +++++ tools/include/uapi/linux/bpf.h | 1 + .../selftests/bpf/prog_tests/flow_dissector.c | 46 ++++++++++++++++++++++ tools/testing/selftests/bpf/progs/bpf_flow.c | 10 +++++ 5 files changed, 67 insertions(+) (limited to 'tools') diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 88b9d743036f..e985f07a98ed 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -3533,6 +3533,7 @@ struct bpf_flow_keys { }; }; __u32 flags; + __be32 flow_label; }; struct bpf_func_info { diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 50ed1a688709..9741b593ea53 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -737,6 +737,7 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys, struct flow_dissector_key_basic *key_basic; struct flow_dissector_key_addrs *key_addrs; struct flow_dissector_key_ports *key_ports; + struct flow_dissector_key_tags *key_tags; key_control = skb_flow_dissector_target(flow_dissector, FLOW_DISSECTOR_KEY_CONTROL, @@ -781,6 +782,14 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys, key_ports->src = flow_keys->sport; key_ports->dst = flow_keys->dport; } + + if (dissector_uses_key(flow_dissector, + FLOW_DISSECTOR_KEY_FLOW_LABEL)) { + key_tags = skb_flow_dissector_target(flow_dissector, + FLOW_DISSECTOR_KEY_FLOW_LABEL, + target_container); + key_tags->flow_label = ntohl(flow_keys->flow_label); + } } bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx, diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 2e4b0848d795..3d7fc67ec1b8 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -3530,6 +3530,7 @@ struct bpf_flow_keys { }; }; __u32 flags; + __be32 flow_label; }; struct bpf_func_info { diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c index 8e8c18aced9b..ef83f145a6f1 100644 --- a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c +++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c @@ -20,6 +20,7 @@ "is_encap=%u/%u " \ "ip_proto=0x%x/0x%x " \ "n_proto=0x%x/0x%x " \ + "flow_label=0x%x/0x%x " \ "sport=%u/%u " \ "dport=%u/%u\n", \ got.nhoff, expected.nhoff, \ @@ -30,6 +31,7 @@ got.is_encap, expected.is_encap, \ got.ip_proto, expected.ip_proto, \ got.n_proto, expected.n_proto, \ + got.flow_label, expected.flow_label, \ got.sport, expected.sport, \ got.dport, expected.dport) @@ -257,6 +259,50 @@ struct test tests[] = { .is_first_frag = true, }, }, + { + .name = "ipv6-flow-label", + .pkt.ipv6 = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6), + .iph.nexthdr = IPPROTO_TCP, + .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES), + .iph.flow_lbl = { 0xb, 0xee, 0xef }, + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct ipv6hdr), + .addr_proto = ETH_P_IPV6, + .ip_proto = IPPROTO_TCP, + .n_proto = __bpf_constant_htons(ETH_P_IPV6), + .sport = 80, + .dport = 8080, + .flow_label = __bpf_constant_htonl(0xbeeef), + }, + }, + { + .name = "ipv6-no-flow-label", + .pkt.ipv6 = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6), + .iph.nexthdr = IPPROTO_TCP, + .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES), + .iph.flow_lbl = { 0xb, 0xee, 0xef }, + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .flags = BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL, + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct ipv6hdr), + .addr_proto = ETH_P_IPV6, + .ip_proto = IPPROTO_TCP, + .n_proto = __bpf_constant_htons(ETH_P_IPV6), + .flow_label = __bpf_constant_htonl(0xbeeef), + }, + .flags = BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL, + }, }; static int create_tap(const char *ifname) diff --git a/tools/testing/selftests/bpf/progs/bpf_flow.c b/tools/testing/selftests/bpf/progs/bpf_flow.c index f931cd3db9d4..7fbfa22f33df 100644 --- a/tools/testing/selftests/bpf/progs/bpf_flow.c +++ b/tools/testing/selftests/bpf/progs/bpf_flow.c @@ -83,6 +83,12 @@ static __always_inline int export_flow_keys(struct bpf_flow_keys *keys, return ret; } +#define IPV6_FLOWLABEL_MASK __bpf_constant_htonl(0x000FFFFF) +static inline __be32 ip6_flowlabel(const struct ipv6hdr *hdr) +{ + return *(__be32 *)hdr & IPV6_FLOWLABEL_MASK; +} + static __always_inline void *bpf_flow_dissect_get_header(struct __sk_buff *skb, __u16 hdr_size, void *buffer) @@ -308,6 +314,10 @@ PROG(IPV6)(struct __sk_buff *skb) keys->thoff += sizeof(struct ipv6hdr); keys->ip_proto = ip6h->nexthdr; + keys->flow_label = ip6_flowlabel(ip6h); + + if (keys->flags & BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL) + return export_flow_keys(keys, BPF_OK); return parse_ipv6_proto(skb, ip6h->nexthdr); } -- cgit v1.2.3-59-g8ed1b From e853ae776a58633492b59badab04f53a6b730d62 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Thu, 25 Jul 2019 15:52:31 -0700 Subject: selftests/bpf: support BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP Exit as soon as we found that packet is encapped when BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP is passed. Add appropriate selftest cases. v2: * Subtract sizeof(struct iphdr) from .iph_inner.tot_len (Willem de Bruijn) Acked-by: Petar Penkov Acked-by: Willem de Bruijn Acked-by: Song Liu Cc: Song Liu Cc: Willem de Bruijn Cc: Petar Penkov Signed-off-by: Stanislav Fomichev Signed-off-by: Alexei Starovoitov --- .../selftests/bpf/prog_tests/flow_dissector.c | 64 ++++++++++++++++++++++ tools/testing/selftests/bpf/progs/bpf_flow.c | 8 +++ 2 files changed, 72 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c index ef83f145a6f1..700d73d2f22a 100644 --- a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c +++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c @@ -41,6 +41,13 @@ struct ipv4_pkt { struct tcphdr tcp; } __packed; +struct ipip_pkt { + struct ethhdr eth; + struct iphdr iph; + struct iphdr iph_inner; + struct tcphdr tcp; +} __packed; + struct svlan_ipv4_pkt { struct ethhdr eth; __u16 vlan_tci; @@ -82,6 +89,7 @@ struct test { union { struct ipv4_pkt ipv4; struct svlan_ipv4_pkt svlan_ipv4; + struct ipip_pkt ipip; struct ipv6_pkt ipv6; struct ipv6_frag_pkt ipv6_frag; struct dvlan_ipv6_pkt dvlan_ipv6; @@ -303,6 +311,62 @@ struct test tests[] = { }, .flags = BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL, }, + { + .name = "ipip-encap", + .pkt.ipip = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IP), + .iph.ihl = 5, + .iph.protocol = IPPROTO_IPIP, + .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES), + .iph_inner.ihl = 5, + .iph_inner.protocol = IPPROTO_TCP, + .iph_inner.tot_len = + __bpf_constant_htons(MAGIC_BYTES) - + sizeof(struct iphdr), + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .nhoff = 0, + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct iphdr) + + sizeof(struct iphdr), + .addr_proto = ETH_P_IP, + .ip_proto = IPPROTO_TCP, + .n_proto = __bpf_constant_htons(ETH_P_IP), + .is_encap = true, + .sport = 80, + .dport = 8080, + }, + }, + { + .name = "ipip-no-encap", + .pkt.ipip = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IP), + .iph.ihl = 5, + .iph.protocol = IPPROTO_IPIP, + .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES), + .iph_inner.ihl = 5, + .iph_inner.protocol = IPPROTO_TCP, + .iph_inner.tot_len = + __bpf_constant_htons(MAGIC_BYTES) - + sizeof(struct iphdr), + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .flags = BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP, + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct iphdr), + .addr_proto = ETH_P_IP, + .ip_proto = IPPROTO_IPIP, + .n_proto = __bpf_constant_htons(ETH_P_IP), + .is_encap = true, + }, + .flags = BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP, + }, }; static int create_tap(const char *ifname) diff --git a/tools/testing/selftests/bpf/progs/bpf_flow.c b/tools/testing/selftests/bpf/progs/bpf_flow.c index 7fbfa22f33df..08bd8b9d58d0 100644 --- a/tools/testing/selftests/bpf/progs/bpf_flow.c +++ b/tools/testing/selftests/bpf/progs/bpf_flow.c @@ -167,9 +167,15 @@ static __always_inline int parse_ip_proto(struct __sk_buff *skb, __u8 proto) return export_flow_keys(keys, BPF_OK); case IPPROTO_IPIP: keys->is_encap = true; + if (keys->flags & BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP) + return export_flow_keys(keys, BPF_OK); + return parse_eth_proto(skb, bpf_htons(ETH_P_IP)); case IPPROTO_IPV6: keys->is_encap = true; + if (keys->flags & BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP) + return export_flow_keys(keys, BPF_OK); + return parse_eth_proto(skb, bpf_htons(ETH_P_IPV6)); case IPPROTO_GRE: gre = bpf_flow_dissect_get_header(skb, sizeof(*gre), &_gre); @@ -189,6 +195,8 @@ static __always_inline int parse_ip_proto(struct __sk_buff *skb, __u8 proto) keys->thoff += 4; /* Step over sequence number */ keys->is_encap = true; + if (keys->flags & BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP) + return export_flow_keys(keys, BPF_OK); if (gre->proto == bpf_htons(ETH_P_TEB)) { eth = bpf_flow_dissect_get_header(skb, sizeof(*eth), -- cgit v1.2.3-59-g8ed1b From 4f22f32356629ab2843e873887d34868b96a82b4 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 10 Jul 2019 13:32:18 +0800 Subject: crypto: Remove orphan tools/crypto directory The directory tools/crypto and the only file under it never gets built anywhere. This program should instead be incorporated into one of the existing user-space projects, crconf or libkcapi. Signed-off-by: Herbert Xu --- tools/crypto/getstat.c | 294 ------------------------------------------------- 1 file changed, 294 deletions(-) delete mode 100644 tools/crypto/getstat.c (limited to 'tools') diff --git a/tools/crypto/getstat.c b/tools/crypto/getstat.c deleted file mode 100644 index 9e8ff76420fa..000000000000 --- a/tools/crypto/getstat.c +++ /dev/null @@ -1,294 +0,0 @@ -/* Heavily copied from libkcapi 2015 - 2017, Stephan Mueller */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define CR_RTA(x) ((struct rtattr *)(((char *)(x)) + NLMSG_ALIGN(sizeof(struct crypto_user_alg)))) - -static int get_stat(const char *drivername) -{ - struct { - struct nlmsghdr n; - struct crypto_user_alg cru; - } req; - struct sockaddr_nl nl; - int sd = 0, ret; - socklen_t addr_len; - struct iovec iov; - struct msghdr msg; - char buf[4096]; - struct nlmsghdr *res_n = (struct nlmsghdr *)buf; - struct crypto_user_alg *cru_res = NULL; - int res_len = 0; - struct rtattr *tb[CRYPTOCFGA_MAX + 1]; - struct rtattr *rta; - struct nlmsgerr *errmsg; - - memset(&req, 0, sizeof(req)); - memset(&buf, 0, sizeof(buf)); - memset(&msg, 0, sizeof(msg)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.cru)); - req.n.nlmsg_flags = NLM_F_REQUEST; - req.n.nlmsg_type = CRYPTO_MSG_GETSTAT; - req.n.nlmsg_seq = time(NULL); - - strncpy(req.cru.cru_driver_name, drivername, strlen(drivername)); - - sd = socket(AF_NETLINK, SOCK_RAW, NETLINK_CRYPTO); - if (sd < 0) { - fprintf(stderr, "Netlink error: cannot open netlink socket"); - return -errno; - } - memset(&nl, 0, sizeof(nl)); - nl.nl_family = AF_NETLINK; - if (bind(sd, (struct sockaddr *)&nl, sizeof(nl)) < 0) { - ret = -errno; - fprintf(stderr, "Netlink error: cannot bind netlink socket"); - goto out; - } - - /* sanity check that netlink socket was successfully opened */ - addr_len = sizeof(nl); - if (getsockname(sd, (struct sockaddr *)&nl, &addr_len) < 0) { - ret = -errno; - printf("Netlink error: cannot getsockname"); - goto out; - } - if (addr_len != sizeof(nl)) { - ret = -errno; - printf("Netlink error: wrong address length %d", addr_len); - goto out; - } - if (nl.nl_family != AF_NETLINK) { - ret = -errno; - printf("Netlink error: wrong address family %d", - nl.nl_family); - goto out; - } - - memset(&nl, 0, sizeof(nl)); - nl.nl_family = AF_NETLINK; - iov.iov_base = (void *)&req.n; - iov.iov_len = req.n.nlmsg_len; - msg.msg_name = &nl; - msg.msg_namelen = sizeof(nl); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - if (sendmsg(sd, &msg, 0) < 0) { - ret = -errno; - printf("Netlink error: sendmsg failed"); - goto out; - } - memset(buf, 0, sizeof(buf)); - iov.iov_base = buf; - while (1) { - iov.iov_len = sizeof(buf); - ret = recvmsg(sd, &msg, 0); - if (ret < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - ret = -errno; - printf("Netlink error: netlink receive error"); - goto out; - } - if (ret == 0) { - ret = -errno; - printf("Netlink error: no data"); - goto out; - } - if (ret > sizeof(buf)) { - ret = -errno; - printf("Netlink error: received too much data"); - goto out; - } - break; - } - - ret = -EFAULT; - res_len = res_n->nlmsg_len; - if (res_n->nlmsg_type == NLMSG_ERROR) { - errmsg = NLMSG_DATA(res_n); - fprintf(stderr, "Fail with %d\n", errmsg->error); - ret = errmsg->error; - goto out; - } - - if (res_n->nlmsg_type == CRYPTO_MSG_GETSTAT) { - cru_res = NLMSG_DATA(res_n); - res_len -= NLMSG_SPACE(sizeof(*cru_res)); - } - if (res_len < 0) { - printf("Netlink error: nlmsg len %d\n", res_len); - goto out; - } - - if (!cru_res) { - ret = -EFAULT; - printf("Netlink error: no cru_res\n"); - goto out; - } - - rta = CR_RTA(cru_res); - memset(tb, 0, sizeof(struct rtattr *) * (CRYPTOCFGA_MAX + 1)); - while (RTA_OK(rta, res_len)) { - if ((rta->rta_type <= CRYPTOCFGA_MAX) && (!tb[rta->rta_type])) - tb[rta->rta_type] = rta; - rta = RTA_NEXT(rta, res_len); - } - if (res_len) { - printf("Netlink error: unprocessed data %d", - res_len); - goto out; - } - - if (tb[CRYPTOCFGA_STAT_HASH]) { - struct rtattr *rta = tb[CRYPTOCFGA_STAT_HASH]; - struct crypto_stat_hash *rhash = - (struct crypto_stat_hash *)RTA_DATA(rta); - printf("%s\tHash\n\tHash: %llu bytes: %llu\n\tErrors: %llu\n", - drivername, - rhash->stat_hash_cnt, rhash->stat_hash_tlen, - rhash->stat_err_cnt); - } else if (tb[CRYPTOCFGA_STAT_COMPRESS]) { - struct rtattr *rta = tb[CRYPTOCFGA_STAT_COMPRESS]; - struct crypto_stat_compress *rblk = - (struct crypto_stat_compress *)RTA_DATA(rta); - printf("%s\tCompress\n\tCompress: %llu bytes: %llu\n\tDecompress: %llu bytes: %llu\n\tErrors: %llu\n", - drivername, - rblk->stat_compress_cnt, rblk->stat_compress_tlen, - rblk->stat_decompress_cnt, rblk->stat_decompress_tlen, - rblk->stat_err_cnt); - } else if (tb[CRYPTOCFGA_STAT_ACOMP]) { - struct rtattr *rta = tb[CRYPTOCFGA_STAT_ACOMP]; - struct crypto_stat_compress *rcomp = - (struct crypto_stat_compress *)RTA_DATA(rta); - printf("%s\tACompress\n\tCompress: %llu bytes: %llu\n\tDecompress: %llu bytes: %llu\n\tErrors: %llu\n", - drivername, - rcomp->stat_compress_cnt, rcomp->stat_compress_tlen, - rcomp->stat_decompress_cnt, rcomp->stat_decompress_tlen, - rcomp->stat_err_cnt); - } else if (tb[CRYPTOCFGA_STAT_AEAD]) { - struct rtattr *rta = tb[CRYPTOCFGA_STAT_AEAD]; - struct crypto_stat_aead *raead = - (struct crypto_stat_aead *)RTA_DATA(rta); - printf("%s\tAEAD\n\tEncrypt: %llu bytes: %llu\n\tDecrypt: %llu bytes: %llu\n\tErrors: %llu\n", - drivername, - raead->stat_encrypt_cnt, raead->stat_encrypt_tlen, - raead->stat_decrypt_cnt, raead->stat_decrypt_tlen, - raead->stat_err_cnt); - } else if (tb[CRYPTOCFGA_STAT_BLKCIPHER]) { - struct rtattr *rta = tb[CRYPTOCFGA_STAT_BLKCIPHER]; - struct crypto_stat_cipher *rblk = - (struct crypto_stat_cipher *)RTA_DATA(rta); - printf("%s\tCipher\n\tEncrypt: %llu bytes: %llu\n\tDecrypt: %llu bytes: %llu\n\tErrors: %llu\n", - drivername, - rblk->stat_encrypt_cnt, rblk->stat_encrypt_tlen, - rblk->stat_decrypt_cnt, rblk->stat_decrypt_tlen, - rblk->stat_err_cnt); - } else if (tb[CRYPTOCFGA_STAT_AKCIPHER]) { - struct rtattr *rta = tb[CRYPTOCFGA_STAT_AKCIPHER]; - struct crypto_stat_akcipher *rblk = - (struct crypto_stat_akcipher *)RTA_DATA(rta); - printf("%s\tAkcipher\n\tEncrypt: %llu bytes: %llu\n\tDecrypt: %llu bytes: %llu\n\tSign: %llu\n\tVerify: %llu\n\tErrors: %llu\n", - drivername, - rblk->stat_encrypt_cnt, rblk->stat_encrypt_tlen, - rblk->stat_decrypt_cnt, rblk->stat_decrypt_tlen, - rblk->stat_sign_cnt, rblk->stat_verify_cnt, - rblk->stat_err_cnt); - } else if (tb[CRYPTOCFGA_STAT_CIPHER]) { - struct rtattr *rta = tb[CRYPTOCFGA_STAT_CIPHER]; - struct crypto_stat_cipher *rblk = - (struct crypto_stat_cipher *)RTA_DATA(rta); - printf("%s\tcipher\n\tEncrypt: %llu bytes: %llu\n\tDecrypt: %llu bytes: %llu\n\tErrors: %llu\n", - drivername, - rblk->stat_encrypt_cnt, rblk->stat_encrypt_tlen, - rblk->stat_decrypt_cnt, rblk->stat_decrypt_tlen, - rblk->stat_err_cnt); - } else if (tb[CRYPTOCFGA_STAT_RNG]) { - struct rtattr *rta = tb[CRYPTOCFGA_STAT_RNG]; - struct crypto_stat_rng *rrng = - (struct crypto_stat_rng *)RTA_DATA(rta); - printf("%s\tRNG\n\tSeed: %llu\n\tGenerate: %llu bytes: %llu\n\tErrors: %llu\n", - drivername, - rrng->stat_seed_cnt, - rrng->stat_generate_cnt, rrng->stat_generate_tlen, - rrng->stat_err_cnt); - } else if (tb[CRYPTOCFGA_STAT_KPP]) { - struct rtattr *rta = tb[CRYPTOCFGA_STAT_KPP]; - struct crypto_stat_kpp *rkpp = - (struct crypto_stat_kpp *)RTA_DATA(rta); - printf("%s\tKPP\n\tSetsecret: %llu\n\tGenerate public key: %llu\n\tCompute_shared_secret: %llu\n\tErrors: %llu\n", - drivername, - rkpp->stat_setsecret_cnt, - rkpp->stat_generate_public_key_cnt, - rkpp->stat_compute_shared_secret_cnt, - rkpp->stat_err_cnt); - } else { - fprintf(stderr, "%s is of an unknown algorithm\n", drivername); - } - ret = 0; -out: - close(sd); - return ret; -} - -int main(int argc, const char *argv[]) -{ - char buf[4096]; - FILE *procfd; - int i, lastspace; - int ret; - - procfd = fopen("/proc/crypto", "r"); - if (!procfd) { - ret = errno; - fprintf(stderr, "Cannot open /proc/crypto %s\n", strerror(errno)); - return ret; - } - if (argc > 1) { - if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { - printf("Usage: %s [-h|--help] display this help\n", argv[0]); - printf("Usage: %s display all crypto statistics\n", argv[0]); - printf("Usage: %s drivername1 drivername2 ... = display crypto statistics about drivername1 ...\n", argv[0]); - return 0; - } - for (i = 1; i < argc; i++) { - ret = get_stat(argv[i]); - if (ret) { - fprintf(stderr, "Failed with %s\n", strerror(-ret)); - return ret; - } - } - return 0; - } - - while (fgets(buf, sizeof(buf), procfd)) { - if (!strncmp(buf, "driver", 6)) { - lastspace = 0; - i = 0; - while (i < strlen(buf)) { - i++; - if (buf[i] == ' ') - lastspace = i; - } - buf[strlen(buf) - 1] = '\0'; - ret = get_stat(buf + lastspace + 1); - if (ret) { - fprintf(stderr, "Failed with %s\n", strerror(-ret)); - goto out; - } - } - } -out: - fclose(procfd); - return ret; -} -- cgit v1.2.3-59-g8ed1b From 5d01ab7bac467edfc530e6ccf953921def935c62 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Fri, 26 Jul 2019 14:24:38 -0700 Subject: libbpf: fix erroneous multi-closing of BTF FD Libbpf stores associated BTF FD per each instance of bpf_program. When program is unloaded, that FD is closed. This is wrong, because leads to a race and possibly closing of unrelated files, if application simultaneously opens new files while bpf_programs are unloaded. It's also unnecessary, because struct btf "owns" that FD, and btf__free(), called from bpf_object__close() will close it. Thus the fix is to never have per-program BTF FD and fetch it from obj->btf, when necessary. Fixes: 2993e0515bb4 ("tools/bpf: add support to read .BTF.ext sections") Reported-by: Andrey Ignatov Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov --- tools/lib/bpf/libbpf.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 2586b6cb8f34..6718d0b90130 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -182,7 +182,6 @@ struct bpf_program { bpf_program_clear_priv_t clear_priv; enum bpf_attach_type expected_attach_type; - int btf_fd; void *func_info; __u32 func_info_rec_size; __u32 func_info_cnt; @@ -313,7 +312,6 @@ void bpf_program__unload(struct bpf_program *prog) prog->instances.nr = -1; zfree(&prog->instances.fds); - zclose(prog->btf_fd); zfree(&prog->func_info); zfree(&prog->line_info); } @@ -392,7 +390,6 @@ bpf_program__init(void *data, size_t size, char *section_name, int idx, prog->instances.fds = NULL; prog->instances.nr = -1; prog->type = BPF_PROG_TYPE_UNSPEC; - prog->btf_fd = -1; return 0; errout: @@ -2288,9 +2285,6 @@ bpf_program_reloc_btf_ext(struct bpf_program *prog, struct bpf_object *obj, prog->line_info_rec_size = btf_ext__line_info_rec_size(obj->btf_ext); } - if (!insn_offset) - prog->btf_fd = btf__fd(obj->btf); - return 0; } @@ -2463,7 +2457,7 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt, char *cp, errmsg[STRERR_BUFSIZE]; int log_buf_size = BPF_LOG_BUF_SIZE; char *log_buf; - int ret; + int btf_fd, ret; if (!insns || !insns_cnt) return -EINVAL; @@ -2478,7 +2472,8 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt, load_attr.license = license; load_attr.kern_version = kern_version; load_attr.prog_ifindex = prog->prog_ifindex; - load_attr.prog_btf_fd = prog->btf_fd >= 0 ? prog->btf_fd : 0; + btf_fd = bpf_object__btf_fd(prog->obj); + load_attr.prog_btf_fd = btf_fd >= 0 ? btf_fd : 0; load_attr.func_info = prog->func_info; load_attr.func_info_rec_size = prog->func_info_rec_size; load_attr.func_info_cnt = prog->func_info_cnt; -- cgit v1.2.3-59-g8ed1b From 61098e89e6c80d6a141774ef8ee41e38471b069e Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Sat, 27 Jul 2019 20:25:23 -0700 Subject: selftests/bpf: prevent headers to be compiled as C code Apprently listing header as a normal dependency for a binary output makes it go through compilation as if it was C code. This currently works without a problem, but in subsequent commits causes problems for differently generated test.h for test_progs. Marking those headers as order-only dependency solves the issue. Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 11c9c62c3362..bb66cc4a7f34 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -235,7 +235,7 @@ PROG_TESTS_H := $(PROG_TESTS_DIR)/tests.h PROG_TESTS_FILES := $(wildcard prog_tests/*.c) test_progs.c: $(PROG_TESTS_H) $(OUTPUT)/test_progs: CFLAGS += $(TEST_PROGS_CFLAGS) -$(OUTPUT)/test_progs: test_progs.c $(PROG_TESTS_H) $(PROG_TESTS_FILES) +$(OUTPUT)/test_progs: test_progs.c $(PROG_TESTS_FILES) | $(PROG_TESTS_H) $(PROG_TESTS_H): $(PROG_TESTS_FILES) | $(PROG_TESTS_DIR) $(shell ( cd prog_tests/; \ echo '/* Generated header, do not edit */'; \ @@ -256,7 +256,7 @@ MAP_TESTS_H := $(MAP_TESTS_DIR)/tests.h MAP_TESTS_FILES := $(wildcard map_tests/*.c) test_maps.c: $(MAP_TESTS_H) $(OUTPUT)/test_maps: CFLAGS += $(TEST_MAPS_CFLAGS) -$(OUTPUT)/test_maps: test_maps.c $(MAP_TESTS_H) $(MAP_TESTS_FILES) +$(OUTPUT)/test_maps: test_maps.c $(MAP_TESTS_FILES) | $(MAP_TESTS_H) $(MAP_TESTS_H): $(MAP_TESTS_FILES) | $(MAP_TESTS_DIR) $(shell ( cd map_tests/; \ echo '/* Generated header, do not edit */'; \ @@ -277,7 +277,7 @@ VERIFIER_TESTS_H := $(VERIFIER_TESTS_DIR)/tests.h VERIFIER_TEST_FILES := $(wildcard verifier/*.c) test_verifier.c: $(VERIFIER_TESTS_H) $(OUTPUT)/test_verifier: CFLAGS += $(TEST_VERIFIER_CFLAGS) -$(OUTPUT)/test_verifier: test_verifier.c $(VERIFIER_TESTS_H) +$(OUTPUT)/test_verifier: test_verifier.c | $(VERIFIER_TEST_FILES) $(VERIFIER_TESTS_H) $(VERIFIER_TESTS_H): $(VERIFIER_TEST_FILES) | $(VERIFIER_TESTS_DIR) $(shell ( cd verifier/; \ echo '/* Generated header, do not edit */'; \ -- cgit v1.2.3-59-g8ed1b From 766f2a59323a7881613af577718bb46cc1267b1f Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Sat, 27 Jul 2019 20:25:24 -0700 Subject: selftests/bpf: revamp test_progs to allow more control Refactor test_progs to allow better control on what's being run. Also use argp to do argument parsing, so that it's easier to keep adding more options. Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/Makefile | 8 +-- tools/testing/selftests/bpf/test_progs.c | 84 +++++++++++++++++++++++++++++--- 2 files changed, 77 insertions(+), 15 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index bb66cc4a7f34..3bd0f4a0336a 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -239,14 +239,8 @@ $(OUTPUT)/test_progs: test_progs.c $(PROG_TESTS_FILES) | $(PROG_TESTS_H) $(PROG_TESTS_H): $(PROG_TESTS_FILES) | $(PROG_TESTS_DIR) $(shell ( cd prog_tests/; \ echo '/* Generated header, do not edit */'; \ - echo '#ifdef DECLARE'; \ ls *.c 2> /dev/null | \ - sed -e 's@\([^\.]*\)\.c@extern void test_\1(void);@'; \ - echo '#endif'; \ - echo '#ifdef CALL'; \ - ls *.c 2> /dev/null | \ - sed -e 's@\([^\.]*\)\.c@test_\1();@'; \ - echo '#endif' \ + sed -e 's@\([^\.]*\)\.c@DEFINE_TEST(\1)@'; \ ) > $(PROG_TESTS_H)) MAP_TESTS_DIR = $(OUTPUT)/map_tests diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index dae0819b1141..eea88ba59225 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -3,6 +3,7 @@ */ #include "test_progs.h" #include "bpf_rlimit.h" +#include int error_cnt, pass_cnt; bool jit_enabled; @@ -156,22 +157,89 @@ void *spin_lock_thread(void *arg) pthread_exit(arg); } -#define DECLARE +/* extern declarations for test funcs */ +#define DEFINE_TEST(name) extern void test_##name(); #include -#undef DECLARE +#undef DEFINE_TEST -int main(int ac, char **av) +struct prog_test_def { + const char *test_name; + void (*run_test)(void); +}; + +static struct prog_test_def prog_test_defs[] = { +#define DEFINE_TEST(name) { \ + .test_name = #name, \ + .run_test = &test_##name, \ +}, +#include +#undef DEFINE_TEST +}; + +const char *argp_program_version = "test_progs 0.1"; +const char *argp_program_bug_address = ""; +const char argp_program_doc[] = "BPF selftests test runner"; + +enum ARG_KEYS { + ARG_VERIFIER_STATS = 's', +}; + +static const struct argp_option opts[] = { + { "verifier-stats", ARG_VERIFIER_STATS, NULL, 0, + "Output verifier statistics", }, + {}, +}; + +struct test_env { + bool verifier_stats; +}; + +static struct test_env env = {}; + +static error_t parse_arg(int key, char *arg, struct argp_state *state) { + struct test_env *env = state->input; + + switch (key) { + case ARG_VERIFIER_STATS: + env->verifier_stats = true; + break; + case ARGP_KEY_ARG: + argp_usage(state); + break; + case ARGP_KEY_END: + break; + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + + +int main(int argc, char **argv) +{ + static const struct argp argp = { + .options = opts, + .parser = parse_arg, + .doc = argp_program_doc, + }; + const struct prog_test_def *def; + int err, i; + + err = argp_parse(&argp, argc, argv, 0, NULL, &env); + if (err) + return err; + srand(time(NULL)); jit_enabled = is_jit_enabled(); - if (ac == 2 && strcmp(av[1], "-s") == 0) - verifier_stats = true; + verifier_stats = env.verifier_stats; -#define CALL -#include -#undef CALL + for (i = 0; i < ARRAY_SIZE(prog_test_defs); i++) { + def = &prog_test_defs[i]; + def->run_test(); + } printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, error_cnt); return error_cnt ? EXIT_FAILURE : EXIT_SUCCESS; -- cgit v1.2.3-59-g8ed1b From 8160bae21fc29de0ec795abcd209cdd7cc144e8e Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Sat, 27 Jul 2019 20:25:25 -0700 Subject: selftests/bpf: add test selectors by number and name to test_progs Add ability to specify either test number or test name substring to narrow down a set of test to run. Usage: sudo ./test_progs -n 1 sudo ./test_progs -t attach_probe Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/test_progs.c | 43 +++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index eea88ba59225..6e04b9f83777 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -4,6 +4,7 @@ #include "test_progs.h" #include "bpf_rlimit.h" #include +#include int error_cnt, pass_cnt; bool jit_enabled; @@ -164,6 +165,7 @@ void *spin_lock_thread(void *arg) struct prog_test_def { const char *test_name; + int test_num; void (*run_test)(void); }; @@ -181,26 +183,49 @@ const char *argp_program_bug_address = ""; const char argp_program_doc[] = "BPF selftests test runner"; enum ARG_KEYS { + ARG_TEST_NUM = 'n', + ARG_TEST_NAME = 't', ARG_VERIFIER_STATS = 's', }; static const struct argp_option opts[] = { + { "num", ARG_TEST_NUM, "NUM", 0, + "Run test number NUM only " }, + { "name", ARG_TEST_NAME, "NAME", 0, + "Run tests with names containing NAME" }, { "verifier-stats", ARG_VERIFIER_STATS, NULL, 0, "Output verifier statistics", }, {}, }; struct test_env { + int test_num_selector; + const char *test_name_selector; bool verifier_stats; }; -static struct test_env env = {}; +static struct test_env env = { + .test_num_selector = -1, +}; static error_t parse_arg(int key, char *arg, struct argp_state *state) { struct test_env *env = state->input; switch (key) { + case ARG_TEST_NUM: { + int test_num; + + errno = 0; + test_num = strtol(arg, NULL, 10); + if (errno) + return -errno; + env->test_num_selector = test_num; + break; + } + case ARG_TEST_NAME: + env->test_name_selector = arg; + break; case ARG_VERIFIER_STATS: env->verifier_stats = true; break; @@ -223,7 +248,7 @@ int main(int argc, char **argv) .parser = parse_arg, .doc = argp_program_doc, }; - const struct prog_test_def *def; + struct prog_test_def *test; int err, i; err = argp_parse(&argp, argc, argv, 0, NULL, &env); @@ -237,8 +262,18 @@ int main(int argc, char **argv) verifier_stats = env.verifier_stats; for (i = 0; i < ARRAY_SIZE(prog_test_defs); i++) { - def = &prog_test_defs[i]; - def->run_test(); + test = &prog_test_defs[i]; + + test->test_num = i + 1; + + if (env.test_num_selector >= 0 && + test->test_num != env.test_num_selector) + continue; + if (env.test_name_selector && + !strstr(test->test_name, env.test_name_selector)) + continue; + + test->run_test(); } printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, error_cnt); -- cgit v1.2.3-59-g8ed1b From e87fd8bae44c3eaa6205c9c81419e773896dc157 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Sat, 27 Jul 2019 20:25:26 -0700 Subject: libbpf: return previous print callback from libbpf_set_print By returning previously set print callback from libbpf_set_print, it's possible to restore it, eventually. This is useful when running many independent test with one default print function, but overriding log verbosity for particular subset of tests. Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov --- tools/lib/bpf/libbpf.c | 5 ++++- tools/lib/bpf/libbpf.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 8741c39adb1c..ead915aec349 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -74,9 +74,12 @@ static int __base_pr(enum libbpf_print_level level, const char *format, static libbpf_print_fn_t __libbpf_pr = __base_pr; -void libbpf_set_print(libbpf_print_fn_t fn) +libbpf_print_fn_t libbpf_set_print(libbpf_print_fn_t fn) { + libbpf_print_fn_t old_print_fn = __libbpf_pr; + __libbpf_pr = fn; + return old_print_fn; } __printf(2, 3) diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 5cbf459ece0b..8a9d462a6f6d 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -57,7 +57,7 @@ enum libbpf_print_level { typedef int (*libbpf_print_fn_t)(enum libbpf_print_level level, const char *, va_list ap); -LIBBPF_API void libbpf_set_print(libbpf_print_fn_t fn); +LIBBPF_API libbpf_print_fn_t libbpf_set_print(libbpf_print_fn_t fn); /* Hide internal to user */ struct bpf_object; -- cgit v1.2.3-59-g8ed1b From 329e38f76cc2a77085264ce6e0dbe902c33fd7a3 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Sat, 27 Jul 2019 20:25:27 -0700 Subject: selftest/bpf: centralize libbpf logging management for test_progs Make test_progs test runner own libbpf logging. Also introduce two levels of verbosity: -v and -vv. First one will be used in subsequent patches to enable test log output always. Second one increases verbosity level of libbpf logging further to include debug output as well. Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov --- .../selftests/bpf/prog_tests/bpf_verif_scale.c | 6 ++++- .../selftests/bpf/prog_tests/reference_tracking.c | 15 +++-------- tools/testing/selftests/bpf/test_progs.c | 29 ++++++++++++++++++++++ 3 files changed, 38 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c b/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c index e1b55261526f..ceddb8cc86f4 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c @@ -70,10 +70,11 @@ void test_bpf_verif_scale(void) const char *cg_sysctl[] = { "./test_sysctl_loop1.o", "./test_sysctl_loop2.o", }; + libbpf_print_fn_t old_print_fn = NULL; int err, i; if (verifier_stats) - libbpf_set_print(libbpf_debug_print); + old_print_fn = libbpf_set_print(libbpf_debug_print); err = check_load("./loop3.o", BPF_PROG_TYPE_RAW_TRACEPOINT); printf("test_scale:loop3:%s\n", err ? (error_cnt--, "OK") : "FAIL"); @@ -97,4 +98,7 @@ void test_bpf_verif_scale(void) err = check_load("./test_seg6_loop.o", BPF_PROG_TYPE_LWT_SEG6LOCAL); printf("test_scale:test_seg6_loop:%s\n", err ? "FAIL" : "OK"); + + if (verifier_stats) + libbpf_set_print(old_print_fn); } diff --git a/tools/testing/selftests/bpf/prog_tests/reference_tracking.c b/tools/testing/selftests/bpf/prog_tests/reference_tracking.c index 5633be43828f..4a4f428d1a78 100644 --- a/tools/testing/selftests/bpf/prog_tests/reference_tracking.c +++ b/tools/testing/selftests/bpf/prog_tests/reference_tracking.c @@ -1,15 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include -static int libbpf_debug_print(enum libbpf_print_level level, - const char *format, va_list args) -{ - if (level == LIBBPF_DEBUG) - return 0; - - return vfprintf(stderr, format, args); -} - void test_reference_tracking(void) { const char *file = "./test_sk_lookup_kern.o"; @@ -36,9 +27,11 @@ void test_reference_tracking(void) /* Expect verifier failure if test name has 'fail' */ if (strstr(title, "fail") != NULL) { - libbpf_set_print(NULL); + libbpf_print_fn_t old_print_fn; + + old_print_fn = libbpf_set_print(NULL); err = !bpf_program__load(prog, "GPL", 0); - libbpf_set_print(libbpf_debug_print); + libbpf_set_print(old_print_fn); } else { err = bpf_program__load(prog, "GPL", 0); } diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index 6e04b9f83777..94b6951b90b3 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -186,6 +186,8 @@ enum ARG_KEYS { ARG_TEST_NUM = 'n', ARG_TEST_NAME = 't', ARG_VERIFIER_STATS = 's', + + ARG_VERBOSE = 'v', }; static const struct argp_option opts[] = { @@ -195,6 +197,8 @@ static const struct argp_option opts[] = { "Run tests with names containing NAME" }, { "verifier-stats", ARG_VERIFIER_STATS, NULL, 0, "Output verifier statistics", }, + { "verbose", ARG_VERBOSE, "LEVEL", OPTION_ARG_OPTIONAL, + "Verbose output (use -vv for extra verbose output)" }, {}, }; @@ -202,12 +206,22 @@ struct test_env { int test_num_selector; const char *test_name_selector; bool verifier_stats; + bool verbose; + bool very_verbose; }; static struct test_env env = { .test_num_selector = -1, }; +static int libbpf_print_fn(enum libbpf_print_level level, + const char *format, va_list args) +{ + if (!env.very_verbose && level == LIBBPF_DEBUG) + return 0; + return vfprintf(stderr, format, args); +} + static error_t parse_arg(int key, char *arg, struct argp_state *state) { struct test_env *env = state->input; @@ -229,6 +243,19 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) case ARG_VERIFIER_STATS: env->verifier_stats = true; break; + case ARG_VERBOSE: + if (arg) { + if (strcmp(arg, "v") == 0) { + env->very_verbose = true; + } else { + fprintf(stderr, + "Unrecognized verbosity setting ('%s'), only -v and -vv are supported\n", + arg); + return -EINVAL; + } + } + env->verbose = true; + break; case ARGP_KEY_ARG: argp_usage(state); break; @@ -255,6 +282,8 @@ int main(int argc, char **argv) if (err) return err; + libbpf_set_print(libbpf_print_fn); + srand(time(NULL)); jit_enabled = is_jit_enabled(); -- cgit v1.2.3-59-g8ed1b From 0ff97e56c0986ea6633083c3487d9231bbbd881b Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Sat, 27 Jul 2019 20:25:28 -0700 Subject: selftests/bpf: abstract away test log output This patch changes how test output is printed out. By default, if test had no errors, the only output will be a single line with test number, name, and verdict at the end, e.g.: #31 xdp:OK If test had any errors, all log output captured during test execution will be output after test completes. It's possible to force output of log with `-v` (`--verbose`) option, in which case output won't be buffered and will be output immediately. To support this, individual tests are required to use helper methods for logging: `test__printf()` and `test__vprintf()`. Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov --- .../testing/selftests/bpf/prog_tests/bpf_obj_id.c | 6 +- .../selftests/bpf/prog_tests/bpf_verif_scale.c | 31 +++-- .../selftests/bpf/prog_tests/get_stack_raw_tp.c | 4 +- tools/testing/selftests/bpf/prog_tests/l4lb_all.c | 2 +- tools/testing/selftests/bpf/prog_tests/map_lock.c | 10 +- .../testing/selftests/bpf/prog_tests/send_signal.c | 8 +- tools/testing/selftests/bpf/prog_tests/spinlock.c | 2 +- .../selftests/bpf/prog_tests/stacktrace_build_id.c | 4 +- .../bpf/prog_tests/stacktrace_build_id_nmi.c | 4 +- .../selftests/bpf/prog_tests/xdp_noinline.c | 3 +- tools/testing/selftests/bpf/test_progs.c | 145 ++++++++++++++++----- tools/testing/selftests/bpf/test_progs.h | 37 +++++- 12 files changed, 183 insertions(+), 73 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c b/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c index cb827383db4d..fb5840a62548 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c @@ -106,8 +106,8 @@ void test_bpf_obj_id(void) if (CHECK(err || prog_infos[i].type != BPF_PROG_TYPE_SOCKET_FILTER || info_len != sizeof(struct bpf_prog_info) || - (jit_enabled && !prog_infos[i].jited_prog_len) || - (jit_enabled && + (env.jit_enabled && !prog_infos[i].jited_prog_len) || + (env.jit_enabled && !memcmp(jited_insns, zeros, sizeof(zeros))) || !prog_infos[i].xlated_prog_len || !memcmp(xlated_insns, zeros, sizeof(zeros)) || @@ -121,7 +121,7 @@ void test_bpf_obj_id(void) err, errno, i, prog_infos[i].type, BPF_PROG_TYPE_SOCKET_FILTER, info_len, sizeof(struct bpf_prog_info), - jit_enabled, + env.jit_enabled, prog_infos[i].jited_prog_len, prog_infos[i].xlated_prog_len, !!memcmp(jited_insns, zeros, sizeof(zeros)), diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c b/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c index ceddb8cc86f4..b59017279e0b 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c @@ -4,12 +4,15 @@ static int libbpf_debug_print(enum libbpf_print_level level, const char *format, va_list args) { - if (level != LIBBPF_DEBUG) - return vfprintf(stderr, format, args); + if (level != LIBBPF_DEBUG) { + test__vprintf(format, args); + return 0; + } if (!strstr(format, "verifier log")) return 0; - return vfprintf(stderr, "%s", args); + test__vprintf("%s", args); + return 0; } static int check_load(const char *file, enum bpf_prog_type type) @@ -73,32 +76,38 @@ void test_bpf_verif_scale(void) libbpf_print_fn_t old_print_fn = NULL; int err, i; - if (verifier_stats) + if (env.verifier_stats) { + test__force_log(); old_print_fn = libbpf_set_print(libbpf_debug_print); + } err = check_load("./loop3.o", BPF_PROG_TYPE_RAW_TRACEPOINT); - printf("test_scale:loop3:%s\n", err ? (error_cnt--, "OK") : "FAIL"); + test__printf("test_scale:loop3:%s\n", + err ? (error_cnt--, "OK") : "FAIL"); for (i = 0; i < ARRAY_SIZE(sched_cls); i++) { err = check_load(sched_cls[i], BPF_PROG_TYPE_SCHED_CLS); - printf("test_scale:%s:%s\n", sched_cls[i], err ? "FAIL" : "OK"); + test__printf("test_scale:%s:%s\n", sched_cls[i], + err ? "FAIL" : "OK"); } for (i = 0; i < ARRAY_SIZE(raw_tp); i++) { err = check_load(raw_tp[i], BPF_PROG_TYPE_RAW_TRACEPOINT); - printf("test_scale:%s:%s\n", raw_tp[i], err ? "FAIL" : "OK"); + test__printf("test_scale:%s:%s\n", raw_tp[i], + err ? "FAIL" : "OK"); } for (i = 0; i < ARRAY_SIZE(cg_sysctl); i++) { err = check_load(cg_sysctl[i], BPF_PROG_TYPE_CGROUP_SYSCTL); - printf("test_scale:%s:%s\n", cg_sysctl[i], err ? "FAIL" : "OK"); + test__printf("test_scale:%s:%s\n", cg_sysctl[i], + err ? "FAIL" : "OK"); } err = check_load("./test_xdp_loop.o", BPF_PROG_TYPE_XDP); - printf("test_scale:test_xdp_loop:%s\n", err ? "FAIL" : "OK"); + test__printf("test_scale:test_xdp_loop:%s\n", err ? "FAIL" : "OK"); err = check_load("./test_seg6_loop.o", BPF_PROG_TYPE_LWT_SEG6LOCAL); - printf("test_scale:test_seg6_loop:%s\n", err ? "FAIL" : "OK"); + test__printf("test_scale:test_seg6_loop:%s\n", err ? "FAIL" : "OK"); - if (verifier_stats) + if (env.verifier_stats) libbpf_set_print(old_print_fn); } diff --git a/tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c b/tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c index 9d73a8f932ac..3d59b3c841fe 100644 --- a/tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c +++ b/tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c @@ -41,7 +41,7 @@ static void get_stack_print_output(void *ctx, int cpu, void *data, __u32 size) * just assume it is good if the stack is not empty. * This could be improved in the future. */ - if (jit_enabled) { + if (env.jit_enabled) { found = num_stack > 0; } else { for (i = 0; i < num_stack; i++) { @@ -58,7 +58,7 @@ static void get_stack_print_output(void *ctx, int cpu, void *data, __u32 size) } } else { num_stack = e->kern_stack_size / sizeof(__u64); - if (jit_enabled) { + if (env.jit_enabled) { good_kern_stack = num_stack > 0; } else { for (i = 0; i < num_stack; i++) { diff --git a/tools/testing/selftests/bpf/prog_tests/l4lb_all.c b/tools/testing/selftests/bpf/prog_tests/l4lb_all.c index 20ddca830e68..5ce572c03a5f 100644 --- a/tools/testing/selftests/bpf/prog_tests/l4lb_all.c +++ b/tools/testing/selftests/bpf/prog_tests/l4lb_all.c @@ -74,7 +74,7 @@ static void test_l4lb(const char *file) } if (bytes != MAGIC_BYTES * NUM_ITER * 2 || pkts != NUM_ITER * 2) { error_cnt++; - printf("test_l4lb:FAIL:stats %lld %lld\n", bytes, pkts); + test__printf("test_l4lb:FAIL:stats %lld %lld\n", bytes, pkts); } out: bpf_object__close(obj); diff --git a/tools/testing/selftests/bpf/prog_tests/map_lock.c b/tools/testing/selftests/bpf/prog_tests/map_lock.c index ee99368c595c..2e78217ed3fd 100644 --- a/tools/testing/selftests/bpf/prog_tests/map_lock.c +++ b/tools/testing/selftests/bpf/prog_tests/map_lock.c @@ -9,12 +9,12 @@ static void *parallel_map_access(void *arg) for (i = 0; i < 10000; i++) { err = bpf_map_lookup_elem_flags(map_fd, &key, vars, BPF_F_LOCK); if (err) { - printf("lookup failed\n"); + test__printf("lookup failed\n"); error_cnt++; goto out; } if (vars[0] != 0) { - printf("lookup #%d var[0]=%d\n", i, vars[0]); + test__printf("lookup #%d var[0]=%d\n", i, vars[0]); error_cnt++; goto out; } @@ -22,8 +22,8 @@ static void *parallel_map_access(void *arg) for (j = 2; j < 17; j++) { if (vars[j] == rnd) continue; - printf("lookup #%d var[1]=%d var[%d]=%d\n", - i, rnd, j, vars[j]); + test__printf("lookup #%d var[1]=%d var[%d]=%d\n", + i, rnd, j, vars[j]); error_cnt++; goto out; } @@ -43,7 +43,7 @@ void test_map_lock(void) err = bpf_prog_load(file, BPF_PROG_TYPE_CGROUP_SKB, &obj, &prog_fd); if (err) { - printf("test_map_lock:bpf_prog_load errno %d\n", errno); + test__printf("test_map_lock:bpf_prog_load errno %d\n", errno); goto close_prog; } map_fd[0] = bpf_find_map(__func__, obj, "hash_map"); diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c index 54218ee3c004..d950f4558897 100644 --- a/tools/testing/selftests/bpf/prog_tests/send_signal.c +++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c @@ -202,8 +202,8 @@ static int test_send_signal_nmi(void) -1 /* cpu */, -1 /* group_fd */, 0 /* flags */); if (pmu_fd == -1) { if (errno == ENOENT) { - printf("%s:SKIP:no PERF_COUNT_HW_CPU_CYCLES\n", - __func__); + test__printf("%s:SKIP:no PERF_COUNT_HW_CPU_CYCLES\n", + __func__); return 0; } /* Let the test fail with a more informative message */ @@ -222,8 +222,4 @@ void test_send_signal(void) ret |= test_send_signal_tracepoint(); ret |= test_send_signal_perf(); ret |= test_send_signal_nmi(); - if (!ret) - printf("test_send_signal:OK\n"); - else - printf("test_send_signal:FAIL\n"); } diff --git a/tools/testing/selftests/bpf/prog_tests/spinlock.c b/tools/testing/selftests/bpf/prog_tests/spinlock.c index 114ebe6a438e..deb2db5b85b0 100644 --- a/tools/testing/selftests/bpf/prog_tests/spinlock.c +++ b/tools/testing/selftests/bpf/prog_tests/spinlock.c @@ -12,7 +12,7 @@ void test_spinlock(void) err = bpf_prog_load(file, BPF_PROG_TYPE_CGROUP_SKB, &obj, &prog_fd); if (err) { - printf("test_spin_lock:bpf_prog_load errno %d\n", errno); + test__printf("test_spin_lock:bpf_prog_load errno %d\n", errno); goto close_prog; } for (i = 0; i < 4; i++) diff --git a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c index ac44fda84833..356d2c017a9c 100644 --- a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c +++ b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c @@ -109,8 +109,8 @@ retry: if (build_id_matches < 1 && retry--) { bpf_link__destroy(link); bpf_object__close(obj); - printf("%s:WARN:Didn't find expected build ID from the map, retrying\n", - __func__); + test__printf("%s:WARN:Didn't find expected build ID from the map, retrying\n", + __func__); goto retry; } diff --git a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c index 9557b7dfb782..f44f2c159714 100644 --- a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c +++ b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c @@ -140,8 +140,8 @@ retry: if (build_id_matches < 1 && retry--) { bpf_link__destroy(link); bpf_object__close(obj); - printf("%s:WARN:Didn't find expected build ID from the map, retrying\n", - __func__); + test__printf("%s:WARN:Didn't find expected build ID from the map, retrying\n", + __func__); goto retry; } diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_noinline.c b/tools/testing/selftests/bpf/prog_tests/xdp_noinline.c index 09e6b46f5515..b5404494b8aa 100644 --- a/tools/testing/selftests/bpf/prog_tests/xdp_noinline.c +++ b/tools/testing/selftests/bpf/prog_tests/xdp_noinline.c @@ -75,7 +75,8 @@ void test_xdp_noinline(void) } if (bytes != MAGIC_BYTES * NUM_ITER * 2 || pkts != NUM_ITER * 2) { error_cnt++; - printf("test_xdp_noinline:FAIL:stats %lld %lld\n", bytes, pkts); + test__printf("test_xdp_noinline:FAIL:stats %lld %lld\n", + bytes, pkts); } out: bpf_object__close(obj); diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index 94b6951b90b3..1b7470d3da22 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -6,9 +6,85 @@ #include #include +/* defined in test_progs.h */ +struct test_env env = { + .test_num_selector = -1, +}; int error_cnt, pass_cnt; -bool jit_enabled; -bool verifier_stats = false; + +struct prog_test_def { + const char *test_name; + int test_num; + void (*run_test)(void); + bool force_log; + int pass_cnt; + int error_cnt; + bool tested; +}; + +void test__force_log() { + env.test->force_log = true; +} + +void test__vprintf(const char *fmt, va_list args) +{ + size_t rem_sz; + int ret = 0; + + if (env.verbose || (env.test && env.test->force_log)) { + vfprintf(stderr, fmt, args); + return; + } + +try_again: + rem_sz = env.log_cap - env.log_cnt; + if (rem_sz) { + va_list ap; + + va_copy(ap, args); + /* we reserved extra byte for \0 at the end */ + ret = vsnprintf(env.log_buf + env.log_cnt, rem_sz + 1, fmt, ap); + va_end(ap); + + if (ret < 0) { + env.log_buf[env.log_cnt] = '\0'; + fprintf(stderr, "failed to log w/ fmt '%s'\n", fmt); + return; + } + } + + if (!rem_sz || ret > rem_sz) { + size_t new_sz = env.log_cap * 3 / 2; + char *new_buf; + + if (new_sz < 4096) + new_sz = 4096; + if (new_sz < ret + env.log_cnt) + new_sz = ret + env.log_cnt; + + /* +1 for guaranteed space for terminating \0 */ + new_buf = realloc(env.log_buf, new_sz + 1); + if (!new_buf) { + fprintf(stderr, "failed to realloc log buffer: %d\n", + errno); + return; + } + env.log_buf = new_buf; + env.log_cap = new_sz; + goto try_again; + } + + env.log_cnt += ret; +} + +void test__printf(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + test__vprintf(fmt, args); + va_end(args); +} struct ipv4_packet pkt_v4 = { .eth.h_proto = __bpf_constant_htons(ETH_P_IP), @@ -163,20 +239,15 @@ void *spin_lock_thread(void *arg) #include #undef DEFINE_TEST -struct prog_test_def { - const char *test_name; - int test_num; - void (*run_test)(void); -}; - static struct prog_test_def prog_test_defs[] = { -#define DEFINE_TEST(name) { \ - .test_name = #name, \ - .run_test = &test_##name, \ +#define DEFINE_TEST(name) { \ + .test_name = #name, \ + .run_test = &test_##name, \ }, #include #undef DEFINE_TEST }; +const int prog_test_cnt = ARRAY_SIZE(prog_test_defs); const char *argp_program_version = "test_progs 0.1"; const char *argp_program_bug_address = ""; @@ -186,7 +257,6 @@ enum ARG_KEYS { ARG_TEST_NUM = 'n', ARG_TEST_NAME = 't', ARG_VERIFIER_STATS = 's', - ARG_VERBOSE = 'v', }; @@ -202,24 +272,13 @@ static const struct argp_option opts[] = { {}, }; -struct test_env { - int test_num_selector; - const char *test_name_selector; - bool verifier_stats; - bool verbose; - bool very_verbose; -}; - -static struct test_env env = { - .test_num_selector = -1, -}; - static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) { if (!env.very_verbose && level == LIBBPF_DEBUG) return 0; - return vfprintf(stderr, format, args); + test__vprintf(format, args); + return 0; } static error_t parse_arg(int key, char *arg, struct argp_state *state) @@ -267,7 +326,6 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) return 0; } - int main(int argc, char **argv) { static const struct argp argp = { @@ -275,7 +333,6 @@ int main(int argc, char **argv) .parser = parse_arg, .doc = argp_program_doc, }; - struct prog_test_def *test; int err, i; err = argp_parse(&argp, argc, argv, 0, NULL, &env); @@ -286,13 +343,14 @@ int main(int argc, char **argv) srand(time(NULL)); - jit_enabled = is_jit_enabled(); + env.jit_enabled = is_jit_enabled(); - verifier_stats = env.verifier_stats; - - for (i = 0; i < ARRAY_SIZE(prog_test_defs); i++) { - test = &prog_test_defs[i]; + for (i = 0; i < prog_test_cnt; i++) { + struct prog_test_def *test = &prog_test_defs[i]; + int old_pass_cnt = pass_cnt; + int old_error_cnt = error_cnt; + env.test = test; test->test_num = i + 1; if (env.test_num_selector >= 0 && @@ -303,8 +361,29 @@ int main(int argc, char **argv) continue; test->run_test(); + test->tested = true; + test->pass_cnt = pass_cnt - old_pass_cnt; + test->error_cnt = error_cnt - old_error_cnt; + if (test->error_cnt) + env.fail_cnt++; + else + env.succ_cnt++; + + if (env.verbose || test->force_log || test->error_cnt) { + if (env.log_cnt) { + fprintf(stdout, "%s", env.log_buf); + if (env.log_buf[env.log_cnt - 1] != '\n') + fprintf(stdout, "\n"); + } + } + env.log_cnt = 0; + + printf("#%d %s:%s\n", test->test_num, test->test_name, + test->error_cnt ? "FAIL" : "OK"); } + printf("Summary: %d PASSED, %d FAILED\n", env.succ_cnt, env.fail_cnt); + + free(env.log_buf); - printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, error_cnt); return error_cnt ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h index 49e0f7d85643..62f55a4231e9 100644 --- a/tools/testing/selftests/bpf/test_progs.h +++ b/tools/testing/selftests/bpf/test_progs.h @@ -38,9 +38,33 @@ typedef __u16 __sum16; #include "trace_helpers.h" #include "flow_dissector_load.h" -extern int error_cnt, pass_cnt; -extern bool jit_enabled; -extern bool verifier_stats; +struct prog_test_def; + +struct test_env { + int test_num_selector; + const char *test_name_selector; + bool verifier_stats; + bool verbose; + bool very_verbose; + + bool jit_enabled; + + struct prog_test_def *test; + char *log_buf; + size_t log_cnt; + size_t log_cap; + + int succ_cnt; + int fail_cnt; +}; + +extern int error_cnt; +extern int pass_cnt; +extern struct test_env env; + +extern void test__printf(const char *fmt, ...); +extern void test__vprintf(const char *fmt, va_list args); +extern void test__force_log(); #define MAGIC_BYTES 123 @@ -64,11 +88,12 @@ extern struct ipv6_packet pkt_v6; int __ret = !!(condition); \ if (__ret) { \ error_cnt++; \ - printf("%s:FAIL:%s ", __func__, tag); \ - printf(format); \ + test__printf("%s:FAIL:%s ", __func__, tag); \ + test__printf(format); \ } else { \ pass_cnt++; \ - printf("%s:PASS:%s %d nsec\n", __func__, tag, duration);\ + test__printf("%s:PASS:%s %d nsec\n", \ + __func__, tag, duration); \ } \ __ret; \ }) -- cgit v1.2.3-59-g8ed1b From 3a516a0a3a7b21ec038db83ffb0d3cddc42514c9 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Sat, 27 Jul 2019 20:25:29 -0700 Subject: selftests/bpf: add sub-tests support for test_progs Allow tests to have their own set of sub-tests. Also add ability to do test/subtest selection using `-t /` and `-n /`, as an extension of existing -t/-n selector options. For the format: it's a comma-separated list of either individual test numbers (1-based), or range of test numbers. E.g., all of the following are valid sets of test numbers: - 10 - 1,2,3 - 1-3 - 5-10,1,3-4 '/ Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/test_progs.c | 198 +++++++++++++++++++++++++++---- tools/testing/selftests/bpf/test_progs.h | 16 ++- 2 files changed, 185 insertions(+), 29 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index 1b7470d3da22..546d99b3ec34 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -7,9 +7,7 @@ #include /* defined in test_progs.h */ -struct test_env env = { - .test_num_selector = -1, -}; +struct test_env env; int error_cnt, pass_cnt; struct prog_test_def { @@ -20,8 +18,82 @@ struct prog_test_def { int pass_cnt; int error_cnt; bool tested; + + const char *subtest_name; + int subtest_num; + + /* store counts before subtest started */ + int old_pass_cnt; + int old_error_cnt; }; +static bool should_run(struct test_selector *sel, int num, const char *name) +{ + if (sel->name && sel->name[0] && !strstr(name, sel->name)) + return false; + + if (!sel->num_set) + return true; + + return num < sel->num_set_len && sel->num_set[num]; +} + +static void dump_test_log(const struct prog_test_def *test, bool failed) +{ + if (env.verbose || test->force_log || failed) { + if (env.log_cnt) { + fprintf(stdout, "%s", env.log_buf); + if (env.log_buf[env.log_cnt - 1] != '\n') + fprintf(stdout, "\n"); + } + env.log_cnt = 0; + } +} + +void test__end_subtest() +{ + struct prog_test_def *test = env.test; + int sub_error_cnt = error_cnt - test->old_error_cnt; + + if (sub_error_cnt) + env.fail_cnt++; + else + env.sub_succ_cnt++; + + dump_test_log(test, sub_error_cnt); + + printf("#%d/%d %s:%s\n", + test->test_num, test->subtest_num, + test->subtest_name, sub_error_cnt ? "FAIL" : "OK"); +} + +bool test__start_subtest(const char *name) +{ + struct prog_test_def *test = env.test; + + if (test->subtest_name) { + test__end_subtest(); + test->subtest_name = NULL; + } + + test->subtest_num++; + + if (!name || !name[0]) { + fprintf(stderr, "Subtest #%d didn't provide sub-test name!\n", + test->subtest_num); + return false; + } + + if (!should_run(&env.subtest_selector, test->subtest_num, name)) + return false; + + test->subtest_name = name; + env.test->old_pass_cnt = pass_cnt; + env.test->old_error_cnt = error_cnt; + + return true; +} + void test__force_log() { env.test->force_log = true; } @@ -281,24 +353,103 @@ static int libbpf_print_fn(enum libbpf_print_level level, return 0; } +int parse_num_list(const char *s, struct test_selector *sel) +{ + int i, set_len = 0, num, start = 0, end = -1; + bool *set = NULL, *tmp, parsing_end = false; + char *next; + + while (s[0]) { + errno = 0; + num = strtol(s, &next, 10); + if (errno) + return -errno; + + if (parsing_end) + end = num; + else + start = num; + + if (!parsing_end && *next == '-') { + s = next + 1; + parsing_end = true; + continue; + } else if (*next == ',') { + parsing_end = false; + s = next + 1; + end = num; + } else if (*next == '\0') { + parsing_end = false; + s = next; + end = num; + } else { + return -EINVAL; + } + + if (start > end) + return -EINVAL; + + if (end + 1 > set_len) { + set_len = end + 1; + tmp = realloc(set, set_len); + if (!tmp) { + free(set); + return -ENOMEM; + } + set = tmp; + } + for (i = start; i <= end; i++) { + set[i] = true; + } + + } + + if (!set) + return -EINVAL; + + sel->num_set = set; + sel->num_set_len = set_len; + + return 0; +} + static error_t parse_arg(int key, char *arg, struct argp_state *state) { struct test_env *env = state->input; switch (key) { case ARG_TEST_NUM: { - int test_num; + char *subtest_str = strchr(arg, '/'); - errno = 0; - test_num = strtol(arg, NULL, 10); - if (errno) - return -errno; - env->test_num_selector = test_num; + if (subtest_str) { + *subtest_str = '\0'; + if (parse_num_list(subtest_str + 1, + &env->subtest_selector)) { + fprintf(stderr, + "Failed to parse subtest numbers.\n"); + return -EINVAL; + } + } + if (parse_num_list(arg, &env->test_selector)) { + fprintf(stderr, "Failed to parse test numbers.\n"); + return -EINVAL; + } break; } - case ARG_TEST_NAME: - env->test_name_selector = arg; + case ARG_TEST_NAME: { + char *subtest_str = strchr(arg, '/'); + + if (subtest_str) { + *subtest_str = '\0'; + env->subtest_selector.name = strdup(subtest_str + 1); + if (!env->subtest_selector.name) + return -ENOMEM; + } + env->test_selector.name = strdup(arg); + if (!env->test_selector.name) + return -ENOMEM; break; + } case ARG_VERIFIER_STATS: env->verifier_stats = true; break; @@ -353,14 +504,15 @@ int main(int argc, char **argv) env.test = test; test->test_num = i + 1; - if (env.test_num_selector >= 0 && - test->test_num != env.test_num_selector) - continue; - if (env.test_name_selector && - !strstr(test->test_name, env.test_name_selector)) + if (!should_run(&env.test_selector, + test->test_num, test->test_name)) continue; test->run_test(); + /* ensure last sub-test is finalized properly */ + if (test->subtest_name) + test__end_subtest(); + test->tested = true; test->pass_cnt = pass_cnt - old_pass_cnt; test->error_cnt = error_cnt - old_error_cnt; @@ -369,21 +521,17 @@ int main(int argc, char **argv) else env.succ_cnt++; - if (env.verbose || test->force_log || test->error_cnt) { - if (env.log_cnt) { - fprintf(stdout, "%s", env.log_buf); - if (env.log_buf[env.log_cnt - 1] != '\n') - fprintf(stdout, "\n"); - } - } - env.log_cnt = 0; + dump_test_log(test, test->error_cnt); printf("#%d %s:%s\n", test->test_num, test->test_name, test->error_cnt ? "FAIL" : "OK"); } - printf("Summary: %d PASSED, %d FAILED\n", env.succ_cnt, env.fail_cnt); + printf("Summary: %d/%d PASSED, %d FAILED\n", + env.succ_cnt, env.sub_succ_cnt, env.fail_cnt); free(env.log_buf); + free(env.test_selector.num_set); + free(env.subtest_selector.num_set); return error_cnt ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h index 62f55a4231e9..afd14962456f 100644 --- a/tools/testing/selftests/bpf/test_progs.h +++ b/tools/testing/selftests/bpf/test_progs.h @@ -40,9 +40,15 @@ typedef __u16 __sum16; struct prog_test_def; +struct test_selector { + const char *name; + bool *num_set; + int num_set_len; +}; + struct test_env { - int test_num_selector; - const char *test_name_selector; + struct test_selector test_selector; + struct test_selector subtest_selector; bool verifier_stats; bool verbose; bool very_verbose; @@ -54,8 +60,9 @@ struct test_env { size_t log_cnt; size_t log_cap; - int succ_cnt; - int fail_cnt; + int succ_cnt; /* successful tests */ + int sub_succ_cnt; /* successful sub-tests */ + int fail_cnt; /* total failed tests + sub-tests */ }; extern int error_cnt; @@ -65,6 +72,7 @@ extern struct test_env env; extern void test__printf(const char *fmt, ...); extern void test__vprintf(const char *fmt, va_list args); extern void test__force_log(); +extern bool test__start_subtest(const char *name); #define MAGIC_BYTES 123 -- cgit v1.2.3-59-g8ed1b From 51436ed78d59d0a0b7e64a2a2b997ac66a6c050e Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Sat, 27 Jul 2019 20:25:30 -0700 Subject: selftests/bpf: convert bpf_verif_scale.c to sub-tests API Expose each BPF verifier scale test as individual sub-test to allow independent results output and test selection. Test run results now look like this: $ sudo ./test_progs -t verif/ #3/1 loop3.o:OK #3/2 test_verif_scale1.o:OK #3/3 test_verif_scale2.o:OK #3/4 test_verif_scale3.o:OK #3/5 pyperf50.o:OK #3/6 pyperf100.o:OK #3/7 pyperf180.o:OK #3/8 pyperf600.o:OK #3/9 pyperf600_nounroll.o:OK #3/10 loop1.o:OK #3/11 loop2.o:OK #3/12 strobemeta.o:OK #3/13 strobemeta_nounroll1.o:OK #3/14 strobemeta_nounroll2.o:OK #3/15 test_sysctl_loop1.o:OK #3/16 test_sysctl_loop2.o:OK #3/17 test_xdp_loop.o:OK #3/18 test_seg6_loop.o:OK #3 bpf_verif_scale:OK Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov --- .../selftests/bpf/prog_tests/bpf_verif_scale.c | 77 +++++++++++----------- 1 file changed, 40 insertions(+), 37 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c b/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c index b59017279e0b..b4be96162ff4 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c @@ -33,14 +33,25 @@ static int check_load(const char *file, enum bpf_prog_type type) return err; } +struct scale_test_def { + const char *file; + enum bpf_prog_type attach_type; + bool fails; +}; + void test_bpf_verif_scale(void) { - const char *sched_cls[] = { - "./test_verif_scale1.o", "./test_verif_scale2.o", "./test_verif_scale3.o", - }; - const char *raw_tp[] = { + struct scale_test_def tests[] = { + { "loop3.o", BPF_PROG_TYPE_RAW_TRACEPOINT, true /* fails */ }, + + { "test_verif_scale1.o", BPF_PROG_TYPE_SCHED_CLS }, + { "test_verif_scale2.o", BPF_PROG_TYPE_SCHED_CLS }, + { "test_verif_scale3.o", BPF_PROG_TYPE_SCHED_CLS }, + /* full unroll by llvm */ - "./pyperf50.o", "./pyperf100.o", "./pyperf180.o", + { "pyperf50.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, + { "pyperf100.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, + { "pyperf180.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, /* partial unroll. llvm will unroll loop ~150 times. * C loop count -> 600. @@ -48,7 +59,7 @@ void test_bpf_verif_scale(void) * 16k insns in loop body. * Total of 5 such loops. Total program size ~82k insns. */ - "./pyperf600.o", + { "pyperf600.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, /* no unroll at all. * C loop count -> 600. @@ -56,22 +67,26 @@ void test_bpf_verif_scale(void) * ~110 insns in loop body. * Total of 5 such loops. Total program size ~1500 insns. */ - "./pyperf600_nounroll.o", + { "pyperf600_nounroll.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, - "./loop1.o", "./loop2.o", + { "loop1.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, + { "loop2.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, /* partial unroll. 19k insn in a loop. * Total program size 20.8k insn. * ~350k processed_insns */ - "./strobemeta.o", + { "strobemeta.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, /* no unroll, tiny loops */ - "./strobemeta_nounroll1.o", - "./strobemeta_nounroll2.o", - }; - const char *cg_sysctl[] = { - "./test_sysctl_loop1.o", "./test_sysctl_loop2.o", + { "strobemeta_nounroll1.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, + { "strobemeta_nounroll2.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, + + { "test_sysctl_loop1.o", BPF_PROG_TYPE_CGROUP_SYSCTL }, + { "test_sysctl_loop2.o", BPF_PROG_TYPE_CGROUP_SYSCTL }, + + { "test_xdp_loop.o", BPF_PROG_TYPE_XDP }, + { "test_seg6_loop.o", BPF_PROG_TYPE_LWT_SEG6LOCAL }, }; libbpf_print_fn_t old_print_fn = NULL; int err, i; @@ -81,33 +96,21 @@ void test_bpf_verif_scale(void) old_print_fn = libbpf_set_print(libbpf_debug_print); } - err = check_load("./loop3.o", BPF_PROG_TYPE_RAW_TRACEPOINT); - test__printf("test_scale:loop3:%s\n", - err ? (error_cnt--, "OK") : "FAIL"); + for (i = 0; i < ARRAY_SIZE(tests); i++) { + const struct scale_test_def *test = &tests[i]; - for (i = 0; i < ARRAY_SIZE(sched_cls); i++) { - err = check_load(sched_cls[i], BPF_PROG_TYPE_SCHED_CLS); - test__printf("test_scale:%s:%s\n", sched_cls[i], - err ? "FAIL" : "OK"); - } + if (!test__start_subtest(test->file)) + continue; - for (i = 0; i < ARRAY_SIZE(raw_tp); i++) { - err = check_load(raw_tp[i], BPF_PROG_TYPE_RAW_TRACEPOINT); - test__printf("test_scale:%s:%s\n", raw_tp[i], - err ? "FAIL" : "OK"); + err = check_load(test->file, test->attach_type); + if (test->fails) { /* expected to fail */ + if (err) + error_cnt--; + else + error_cnt++; + } } - for (i = 0; i < ARRAY_SIZE(cg_sysctl); i++) { - err = check_load(cg_sysctl[i], BPF_PROG_TYPE_CGROUP_SYSCTL); - test__printf("test_scale:%s:%s\n", cg_sysctl[i], - err ? "FAIL" : "OK"); - } - err = check_load("./test_xdp_loop.o", BPF_PROG_TYPE_XDP); - test__printf("test_scale:test_xdp_loop:%s\n", err ? "FAIL" : "OK"); - - err = check_load("./test_seg6_loop.o", BPF_PROG_TYPE_LWT_SEG6LOCAL); - test__printf("test_scale:test_seg6_loop:%s\n", err ? "FAIL" : "OK"); - if (env.verifier_stats) libbpf_set_print(old_print_fn); } -- cgit v1.2.3-59-g8ed1b From b207edfe4e021f3d992ec8a277edee103840dfd9 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Sat, 27 Jul 2019 20:25:31 -0700 Subject: selftests/bpf: convert send_signal.c to use subtests Convert send_signal set of tests to be exposed as three sub-tests. Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/prog_tests/send_signal.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c index d950f4558897..461b423d0584 100644 --- a/tools/testing/selftests/bpf/prog_tests/send_signal.c +++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c @@ -219,7 +219,10 @@ void test_send_signal(void) { int ret = 0; - ret |= test_send_signal_tracepoint(); - ret |= test_send_signal_perf(); - ret |= test_send_signal_nmi(); + if (test__start_subtest("send_signal_tracepoint")) + ret |= test_send_signal_tracepoint(); + if (test__start_subtest("send_signal_perf")) + ret |= test_send_signal_perf(); + if (test__start_subtest("send_signal_nmi")) + ret |= test_send_signal_nmi(); } -- cgit v1.2.3-59-g8ed1b From 10fbe21163fc6f05f5991d9cf9a2da9bdee4e834 Mon Sep 17 00:00:00 2001 From: Toke Høiland-Jørgensen Date: Fri, 26 Jul 2019 18:06:56 +0200 Subject: tools/include/uapi: Add devmap_hash BPF map type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds the devmap_hash BPF map type to the uapi headers in tools/. Signed-off-by: Toke Høiland-Jørgensen Acked-by: Yonghong Song Acked-by: Jesper Dangaard Brouer Signed-off-by: Alexei Starovoitov --- tools/include/uapi/linux/bpf.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 3d7fc67ec1b8..21d0f6863df3 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -134,6 +134,7 @@ enum bpf_map_type { BPF_MAP_TYPE_QUEUE, BPF_MAP_TYPE_STACK, BPF_MAP_TYPE_SK_STORAGE, + BPF_MAP_TYPE_DEVMAP_HASH, }; /* Note that tracing related programs such as -- cgit v1.2.3-59-g8ed1b From e42346192c9f179a9a47845e4663ad2f453d2b7b Mon Sep 17 00:00:00 2001 From: Toke Høiland-Jørgensen Date: Fri, 26 Jul 2019 18:06:57 +0200 Subject: tools/libbpf_probes: Add new devmap_hash type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds the definition for BPF_MAP_TYPE_DEVMAP_HASH to libbpf_probes.c in tools/lib/bpf. Signed-off-by: Toke Høiland-Jørgensen Acked-by: Yonghong Song Acked-by: Jesper Dangaard Brouer --- tools/lib/bpf/libbpf_probes.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c index ace1a0708d99..4b0b0364f5fc 100644 --- a/tools/lib/bpf/libbpf_probes.c +++ b/tools/lib/bpf/libbpf_probes.c @@ -244,6 +244,7 @@ bool bpf_probe_map_type(enum bpf_map_type map_type, __u32 ifindex) case BPF_MAP_TYPE_ARRAY_OF_MAPS: case BPF_MAP_TYPE_HASH_OF_MAPS: case BPF_MAP_TYPE_DEVMAP: + case BPF_MAP_TYPE_DEVMAP_HASH: case BPF_MAP_TYPE_SOCKMAP: case BPF_MAP_TYPE_CPUMAP: case BPF_MAP_TYPE_XSKMAP: -- cgit v1.2.3-59-g8ed1b From 1375dc4a4579d5e767dd8c2d2abcd929ff59d0a7 Mon Sep 17 00:00:00 2001 From: Toke Høiland-Jørgensen Date: Fri, 26 Jul 2019 18:06:58 +0200 Subject: tools: Add definitions for devmap_hash map type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds selftest and bpftool updates for the devmap_hash map type. Signed-off-by: Toke Høiland-Jørgensen Acked-by: Jesper Dangaard Brouer Signed-off-by: Alexei Starovoitov --- tools/bpf/bpftool/Documentation/bpftool-map.rst | 2 +- tools/bpf/bpftool/bash-completion/bpftool | 4 ++-- tools/bpf/bpftool/map.c | 3 ++- tools/testing/selftests/bpf/test_maps.c | 16 ++++++++++++++++ 4 files changed, 21 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/Documentation/bpftool-map.rst b/tools/bpf/bpftool/Documentation/bpftool-map.rst index 490b4501cb6e..61d1d270eb5e 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-map.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-map.rst @@ -46,7 +46,7 @@ MAP COMMANDS | *TYPE* := { **hash** | **array** | **prog_array** | **perf_event_array** | **percpu_hash** | | **percpu_array** | **stack_trace** | **cgroup_array** | **lru_hash** | | **lru_percpu_hash** | **lpm_trie** | **array_of_maps** | **hash_of_maps** -| | **devmap** | **sockmap** | **cpumap** | **xskmap** | **sockhash** +| | **devmap** | **devmap_hash** | **sockmap** | **cpumap** | **xskmap** | **sockhash** | | **cgroup_storage** | **reuseport_sockarray** | **percpu_cgroup_storage** | | **queue** | **stack** } diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool index c8f42e1fcbc9..6b961a5ed100 100644 --- a/tools/bpf/bpftool/bash-completion/bpftool +++ b/tools/bpf/bpftool/bash-completion/bpftool @@ -489,8 +489,8 @@ _bpftool() perf_event_array percpu_hash percpu_array \ stack_trace cgroup_array lru_hash \ lru_percpu_hash lpm_trie array_of_maps \ - hash_of_maps devmap sockmap cpumap xskmap \ - sockhash cgroup_storage reuseport_sockarray \ + hash_of_maps devmap devmap_hash sockmap cpumap \ + xskmap sockhash cgroup_storage reuseport_sockarray \ percpu_cgroup_storage queue stack' -- \ "$cur" ) ) return 0 diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c index 5da5a7311f13..bfbbc6b4cb83 100644 --- a/tools/bpf/bpftool/map.c +++ b/tools/bpf/bpftool/map.c @@ -37,6 +37,7 @@ const char * const map_type_name[] = { [BPF_MAP_TYPE_ARRAY_OF_MAPS] = "array_of_maps", [BPF_MAP_TYPE_HASH_OF_MAPS] = "hash_of_maps", [BPF_MAP_TYPE_DEVMAP] = "devmap", + [BPF_MAP_TYPE_DEVMAP_HASH] = "devmap_hash", [BPF_MAP_TYPE_SOCKMAP] = "sockmap", [BPF_MAP_TYPE_CPUMAP] = "cpumap", [BPF_MAP_TYPE_XSKMAP] = "xskmap", @@ -1271,7 +1272,7 @@ static int do_help(int argc, char **argv) " TYPE := { hash | array | prog_array | perf_event_array | percpu_hash |\n" " percpu_array | stack_trace | cgroup_array | lru_hash |\n" " lru_percpu_hash | lpm_trie | array_of_maps | hash_of_maps |\n" - " devmap | sockmap | cpumap | xskmap | sockhash |\n" + " devmap | devmap_hash | sockmap | cpumap | xskmap | sockhash |\n" " cgroup_storage | reuseport_sockarray | percpu_cgroup_storage }\n" " " HELP_SPEC_OPTIONS "\n" "", diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c index 5443b9bd75ed..e1f1becda529 100644 --- a/tools/testing/selftests/bpf/test_maps.c +++ b/tools/testing/selftests/bpf/test_maps.c @@ -508,6 +508,21 @@ static void test_devmap(unsigned int task, void *data) close(fd); } +static void test_devmap_hash(unsigned int task, void *data) +{ + int fd; + __u32 key, value; + + fd = bpf_create_map(BPF_MAP_TYPE_DEVMAP_HASH, sizeof(key), sizeof(value), + 2, 0); + if (fd < 0) { + printf("Failed to create devmap_hash '%s'!\n", strerror(errno)); + exit(1); + } + + close(fd); +} + static void test_queuemap(unsigned int task, void *data) { const int MAP_SIZE = 32; @@ -1684,6 +1699,7 @@ static void run_all_tests(void) test_arraymap_percpu_many_keys(); test_devmap(0, NULL); + test_devmap_hash(0, NULL); test_sockmap(0, NULL); test_map_large(); -- cgit v1.2.3-59-g8ed1b From 941a7658e065e339ebdaf27b9a7702f9935d1d4a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 15 Jul 2019 15:25:41 -0300 Subject: perf include bpf: Add bpf_tail_call() prototype MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Will be used together with BPF_MAP_TYPE_PROG_ARRAY in tools/perf/examples/bpf/augmented_raw_syscalls.c. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-pd1bpy8i31nta6jqwdex871g@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/include/bpf/bpf.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/perf/include/bpf/bpf.h b/tools/perf/include/bpf/bpf.h index 2eac6d804b2d..b422aeef5339 100644 --- a/tools/perf/include/bpf/bpf.h +++ b/tools/perf/include/bpf/bpf.h @@ -45,6 +45,8 @@ struct ____btf_map_##name __attribute__((section(".maps." #name), used)) \ static int (*bpf_map_update_elem)(struct bpf_map *map, void *key, void *value, u64 flags) = (void *)BPF_FUNC_map_update_elem; static void *(*bpf_map_lookup_elem)(struct bpf_map *map, void *key) = (void *)BPF_FUNC_map_lookup_elem; +static void (*bpf_tail_call)(void *ctx, void *map, int index) = (void *)BPF_FUNC_tail_call; + #define SEC(NAME) __attribute__((section(NAME), used)) #define probe(function, vars) \ -- cgit v1.2.3-59-g8ed1b From 2620b7e3696a9470c7cda0a08e55813fd5e57e5c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 15 Jul 2019 15:29:34 -0300 Subject: perf bpf: Do not attach a BPF prog to a tracepoint if its name starts with ! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With BPF_MAP_TYPE_PROG_ARRAY + bpf_tail_call() we want to have BPF programs, i.e. functions in a object file that perf's BPF loader shouldn't try to attach to anything, i.e. "!syscalls:sys_enter_open" should just stay there, not be attached to a tracepoint with that name, it'll be used by, for instance, 'perf trace' to associate with syscalls that copy, in addition to the syscall raw args, a filename pointed by the first arg, i.e. multiple syscalls that need copying the same pointer arg in the same way, as a filename, for instance, will share the same BPF program/function. Right now when perf's BPF loader sees a function with a name "sys:name" it'll look for a tracepoint and will associate that BPF program with it, say: SEC("raw_syscalls:sys_enter") int sys_enter(struct syscall_enter_args *args) { //SNIP } Will crate a perf_evsel tracepoint event and then associate with it that BPF program. This convention at some point will switch to the one used by the BPF loader in libbpf, but to experiment with BPF_MAP_TYPE_PROG_ARRAY in 'perf trace' lets do this, that will not require changing too much stuff. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-lk6dasjr1yf9rtvl292b2hpc@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/parse-events.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'tools') diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 371ff3aee769..fac6b32ef94a 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -639,6 +639,15 @@ static int add_bpf_event(const char *group, const char *event, int fd, struct list_head *list = param->list; struct perf_evsel *pos; int err; + /* + * Check if we should add the event, i.e. if it is a TP but starts with a '!', + * then don't add the tracepoint, this will be used for something else, like + * adding to a BPF_MAP_TYPE_PROG_ARRAY. + * + * See tools/perf/examples/bpf/augmented_raw_syscalls.c + */ + if (group[0] == '!') + return 0; pr_debug("add bpf event %s:%s and attach bpf program %d\n", group, event, fd); -- cgit v1.2.3-59-g8ed1b From af4a0991f40a1e50e5caff0317f152df2c82bdeb Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 15 Jul 2019 16:22:57 -0300 Subject: perf evsel: Store backpointer to attached bpf_object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We may want to get to this bpf_object, to search for other BPF programs, etc. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-3y8hrb6lszjfi23vjlic3cib@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf-loader.c | 4 ++-- tools/perf/util/bpf-loader.h | 2 +- tools/perf/util/evsel.c | 1 + tools/perf/util/evsel.h | 3 +++ tools/perf/util/parse-events.c | 3 ++- 5 files changed, 9 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index c61974a50aa5..6d0dfb777a79 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -763,7 +763,7 @@ int bpf__foreach_event(struct bpf_object *obj, if (priv->is_tp) { fd = bpf_program__fd(prog); - err = (*func)(priv->sys_name, priv->evt_name, fd, arg); + err = (*func)(priv->sys_name, priv->evt_name, fd, obj, arg); if (err) { pr_debug("bpf: tracepoint call back failed, stop iterate\n"); return err; @@ -788,7 +788,7 @@ int bpf__foreach_event(struct bpf_object *obj, return fd; } - err = (*func)(tev->group, tev->event, fd, arg); + err = (*func)(tev->group, tev->event, fd, obj, arg); if (err) { pr_debug("bpf: call back failed, stop iterate\n"); return err; diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h index 3f46856e3330..8c3441a4b72c 100644 --- a/tools/perf/util/bpf-loader.h +++ b/tools/perf/util/bpf-loader.h @@ -46,7 +46,7 @@ struct parse_events_term; #define PERF_BPF_PROBE_GROUP "perf_bpf_probe" typedef int (*bpf_prog_iter_callback_t)(const char *group, const char *event, - int fd, void *arg); + int fd, struct bpf_object *obj, void *arg); #ifdef HAVE_LIBBPF_SUPPORT struct bpf_object *bpf__prepare_load(const char *filename, bool source); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 52459dd5ad0c..7d1757a2ec46 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -234,6 +234,7 @@ void perf_evsel__init(struct perf_evsel *evsel, evsel->scale = 1.0; evsel->max_events = ULONG_MAX; evsel->evlist = NULL; + evsel->bpf_obj = NULL; evsel->bpf_fd = -1; INIT_LIST_HEAD(&evsel->node); INIT_LIST_HEAD(&evsel->config_terms); diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index cad54e8ba522..b27935a6d36c 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -82,6 +82,8 @@ enum perf_tool_event { PERF_TOOL_DURATION_TIME = 1, }; +struct bpf_object; + /** struct perf_evsel - event selector * * @evlist - evlist this evsel is in, if it is in one. @@ -152,6 +154,7 @@ struct perf_evsel { char *group_name; bool cmdline_group_boundary; struct list_head config_terms; + struct bpf_object *bpf_obj; int bpf_fd; bool auto_merge_stats; bool merged_stat; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index fac6b32ef94a..0540303e5e97 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -630,7 +630,7 @@ struct __add_bpf_event_param { struct list_head *head_config; }; -static int add_bpf_event(const char *group, const char *event, int fd, +static int add_bpf_event(const char *group, const char *event, int fd, struct bpf_object *obj, void *_param) { LIST_HEAD(new_evsels); @@ -672,6 +672,7 @@ static int add_bpf_event(const char *group, const char *event, int fd, pr_debug("adding %s:%s to %p\n", group, event, pos); pos->bpf_fd = fd; + pos->bpf_obj = obj; } list_splice(&new_evsels, list); return 0; -- cgit v1.2.3-59-g8ed1b From c8c805707ed4c5d976210821da3242af8610a533 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 15 Jul 2019 16:58:23 -0300 Subject: perf trace: Add pointer to BPF object containing __augmented_syscalls__ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So that we can use it when looking for other components of that object file, such as other programs to add to the BPF_MAP_TYPE_PROG_ARRAY and use with bpf_tail_call(). Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-1ibmz7ouv6llqxajy7m8igtd@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 4f0bbffee05f..6aa080845a84 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -96,6 +96,7 @@ struct trace { struct perf_evlist *evlist; struct machine *host; struct thread *current; + struct bpf_object *bpf_obj; struct cgroup *cgroup; u64 base_time; FILE *output; @@ -3895,6 +3896,20 @@ int cmd_trace(int argc, const char **argv) if (evsel) { trace.syscalls.events.augmented = evsel; + + evsel = perf_evlist__find_tracepoint_by_name(trace.evlist, "raw_syscalls:sys_enter"); + if (evsel == NULL) { + pr_err("ERROR: raw_syscalls:sys_enter not found in the augmented BPF object\n"); + goto out; + } + + if (evsel->bpf_obj == NULL) { + pr_err("ERROR: raw_syscalls:sys_enter not associated to a BPF object\n"); + goto out; + } + + trace.bpf_obj = evsel->bpf_obj; + trace__set_bpf_map_filtered_pids(&trace); trace__set_bpf_map_syscalls(&trace); } -- cgit v1.2.3-59-g8ed1b From 5ca0b7f5004a5f1a35c1cb47894790ad98e34ed1 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 15 Jul 2019 17:03:10 -0300 Subject: perf trace: Look up maps just on the __augmented_syscalls__ BPF object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can conceivably have multiple BPF object files for other purposes, so better look just on the BPF object containing the __augmented_syscalls__ map for all things augmented_syscalls related. Cc: Adrian Hunter Cc: Brendan Gregg Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-3jt8knkuae9lt705r1lns202@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 6aa080845a84..bfd739a321d1 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3669,28 +3669,22 @@ static int trace__parse_cgroups(const struct option *opt, const char *str, int u return 0; } -static struct bpf_map *bpf__find_map_by_name(const char *name) +static struct bpf_map *trace__find_bpf_map_by_name(struct trace *trace, const char *name) { - struct bpf_object *obj, *tmp; - - bpf_object__for_each_safe(obj, tmp) { - struct bpf_map *map = bpf_object__find_map_by_name(obj, name); - if (map) - return map; - - } + if (trace->bpf_obj == NULL) + return NULL; - return NULL; + return bpf_object__find_map_by_name(trace->bpf_obj, name); } static void trace__set_bpf_map_filtered_pids(struct trace *trace) { - trace->filter_pids.map = bpf__find_map_by_name("pids_filtered"); + trace->filter_pids.map = trace__find_bpf_map_by_name(trace, "pids_filtered"); } static void trace__set_bpf_map_syscalls(struct trace *trace) { - trace->syscalls.map = bpf__find_map_by_name("syscalls"); + trace->syscalls.map = trace__find_bpf_map_by_name(trace, "syscalls"); } static int trace__config(const char *var, const char *value, void *arg) @@ -3924,7 +3918,7 @@ int cmd_trace(int argc, const char **argv) err = -1; if (map_dump_str) { - trace.dump.map = bpf__find_map_by_name(map_dump_str); + trace.dump.map = trace__find_bpf_map_by_name(&trace, map_dump_str); if (trace.dump.map == NULL) { pr_err("ERROR: BPF map \"%s\" not found\n", map_dump_str); goto out; -- cgit v1.2.3-59-g8ed1b From 83e69b92b10c2a8b75e1919b7074338f8bdbacaf Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 15 Jul 2019 17:28:25 -0300 Subject: perf trace: Order -e syscalls table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ev_qualifier is an array with the syscall ids passed via -e on the command line, sort it as we'll search it when setting up the BPF_MAP_TYPE_PROG_ARRAY. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-c8hprylp3ai6e0z9burn2r3s@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index bfd739a321d1..9bd5ecd6a8dd 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1528,6 +1528,13 @@ static int trace__read_syscall_info(struct trace *trace, int id) return syscall__set_arg_fmts(sc); } +static int intcmp(const void *a, const void *b) +{ + const int *one = a, *another = b; + + return *one - *another; +} + static int trace__validate_ev_qualifier(struct trace *trace) { int err = 0; @@ -1591,6 +1598,7 @@ matches: } trace->ev_qualifier_ids.nr = nr_used; + qsort(trace->ev_qualifier_ids.entries, nr_used, sizeof(int), intcmp); out: if (printed_invalid_prefix) pr_debug("\n"); -- cgit v1.2.3-59-g8ed1b From 5834da7f10917245d191032f76f132e62e57197c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 15 Jul 2019 17:51:43 -0300 Subject: perf trace: Add BPF handler for unaugmented syscalls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Will be used to assign to syscalls that don't need augmentation, i.e. those with just integer args. All syscalls will be in a BPF_MAP_TYPE_PROG_ARRAY, and the bpf_tail_call() keyed by the syscall id will either find nothing in place, which means the syscall is being filtered, or a function that will either add things like filenames to the ring buffer, right after the raw syscall args, or be this unaugmented handler that will just return 1, meaning don't filter the original raw_syscalls:sys_{enter,exit} tracepoint. For now it is not really being used, this is just leg work to break the patch into smaller pieces. It introduces a trace__find_bpf_program_by_title() helper that in turn uses libbpf's bpf_object__find_program_by_title() on the BPF object with the __augmented_syscalls__ map. "title" is how libbpf calls the SEC() argument for functions, i.e. the ELF section that follows a convention to specify what BPF program (a function with this SEC() marking) should be connected to which tracepoint, kprobes, etc. In perf anything that is of the form SEC("sys:event_name") will be connected to that tracepoint by perf's BPF loader. In this case its something that will be bpf_tail_call()ed from either the "raw_syscalls:sys_enter" or "raw_syscall:sys_exit" tracepoints, so its named "!raw_syscalls:unaugmented" to convey that idea, i.e. its not going to be directly attached to a tracepoint, thus it starts with a "!". Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-meucpjx2u0slpkayx56lxqq6@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 16 ++++++++++++++++ tools/perf/examples/bpf/augmented_raw_syscalls.c | 6 ++++++ 2 files changed, 22 insertions(+) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 9bd5ecd6a8dd..07df952a0d7f 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -88,6 +88,7 @@ struct trace { *sys_exit, *augmented; } events; + struct bpf_program *unaugmented_prog; } syscalls; struct { struct bpf_map *map; @@ -2733,6 +2734,14 @@ out_enomem: } #ifdef HAVE_LIBBPF_SUPPORT +static struct bpf_program *trace__find_bpf_program_by_title(struct trace *trace, const char *name) +{ + if (trace->bpf_obj == NULL) + return NULL; + + return bpf_object__find_program_by_title(trace->bpf_obj, name); +} + static void trace__init_bpf_map_syscall_args(struct trace *trace, int id, struct bpf_map_syscall_entry *entry) { struct syscall *sc = trace__syscall_info(trace, NULL, id); @@ -2814,6 +2823,12 @@ static int trace__init_syscalls_bpf_map(struct trace *trace __maybe_unused) { return 0; } + +static struct bpf_program *trace__find_bpf_program_by_title(struct trace *trace __maybe_unused, + const char *name __maybe_unused) +{ + return NULL; +} #endif // HAVE_LIBBPF_SUPPORT static int trace__set_ev_qualifier_filter(struct trace *trace) @@ -3914,6 +3929,7 @@ int cmd_trace(int argc, const char **argv) trace__set_bpf_map_filtered_pids(&trace); trace__set_bpf_map_syscalls(&trace); + trace.syscalls.unaugmented_prog = trace__find_bpf_program_by_title(&trace, "!raw_syscalls:unaugmented"); } err = bpf__setup_stdout(trace.evlist); diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index 2f822bb51717..48a536b1be6d 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -88,6 +88,12 @@ unsigned int augmented_filename__read(struct augmented_filename *augmented_filen return len; } +SEC("!raw_syscalls:unaugmented") +int syscall_unaugmented(struct syscall_enter_args *args) +{ + return 1; +} + SEC("raw_syscalls:sys_enter") int sys_enter(struct syscall_enter_args *args) { -- cgit v1.2.3-59-g8ed1b From 6ff8fff45611e0b5ff4c0979cd0470b5cbc0a031 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 16 Jul 2019 10:59:19 -0300 Subject: perf trace: Allow specifying the bpf prog to augment specific syscalls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a step in the direction of being able to use a BPF_MAP_TYPE_PROG_ARRAY to handle syscalls that need to copy pointer payloads in addition to the raw tracepoint syscall args. There is a first example in tools/perf/examples/bpf/augmented_raw_syscalls.c for the 'open' syscall. Next step is to introduce the prog array map and use this 'open' augmenter, then use that augmenter in other syscalls that also only copy the first arg as a string, and then show how to use with a syscall that reads more than one filename, like 'rename', etc. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-pys4v57x5qqrybb4cery2mc8@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 50 +++++++++++++++++++++++- tools/perf/examples/bpf/augmented_raw_syscalls.c | 23 +++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 07df952a0d7f..6cc696edf24a 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -690,6 +690,10 @@ struct syscall_arg_fmt { static struct syscall_fmt { const char *name; const char *alias; + struct { + const char *sys_enter, + *sys_exit; + } bpf_prog_name; struct syscall_arg_fmt arg[6]; u8 nr_args; bool errpid; @@ -823,6 +827,7 @@ static struct syscall_fmt { { .name = "newfstatat", .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, { .name = "open", + .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_open", }, .arg = { [1] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, { .name = "open_by_handle_at", .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, @@ -967,6 +972,10 @@ struct syscall { struct tep_event *tp_format; int nr_args; int args_size; + struct { + struct bpf_program *sys_enter, + *sys_exit; + } bpf_prog; bool is_exit; bool is_open; struct tep_format_field *args; @@ -2742,6 +2751,39 @@ static struct bpf_program *trace__find_bpf_program_by_title(struct trace *trace, return bpf_object__find_program_by_title(trace->bpf_obj, name); } +static struct bpf_program *trace__find_syscall_bpf_prog(struct trace *trace, struct syscall *sc, + const char *prog_name, const char *type) +{ + struct bpf_program *prog; + + if (prog_name == NULL) + goto out_unaugmented; + + prog = trace__find_bpf_program_by_title(trace, prog_name); + if (prog != NULL) + return prog; + + pr_debug("Couldn't find BPF prog \"%s\" to associate with syscalls:sys_%s_%s, not augmenting it\n", + prog_name, type, sc->name); +out_unaugmented: + return trace->syscalls.unaugmented_prog; +} + +static void trace__init_syscall_bpf_progs(struct trace *trace, int id) +{ + struct syscall *sc = trace__syscall_info(trace, NULL, id); + + if (sc == NULL) + return; + + if (sc->fmt != NULL) { + sc->bpf_prog.sys_enter = trace__find_syscall_bpf_prog(trace, sc, sc->fmt->bpf_prog_name.sys_enter, "enter"); + sc->bpf_prog.sys_exit = trace__find_syscall_bpf_prog(trace, sc, sc->fmt->bpf_prog_name.sys_exit, "exit"); + } else { + sc->bpf_prog.sys_enter = sc->bpf_prog.sys_exit = trace->syscalls.unaugmented_prog; + } +} + static void trace__init_bpf_map_syscall_args(struct trace *trace, int id, struct bpf_map_syscall_entry *entry) { struct syscall *sc = trace__syscall_info(trace, NULL, id); @@ -2773,8 +2815,10 @@ static int trace__set_ev_qualifier_bpf_filter(struct trace *trace) for (i = 0; i < trace->ev_qualifier_ids.nr; ++i) { int key = trace->ev_qualifier_ids.entries[i]; - if (value.enabled) + if (value.enabled) { trace__init_bpf_map_syscall_args(trace, key, &value); + trace__init_syscall_bpf_progs(trace, key); + } err = bpf_map_update_elem(fd, &key, &value, BPF_EXIST); if (err) @@ -2793,8 +2837,10 @@ static int __trace__init_syscalls_bpf_map(struct trace *trace, bool enabled) int err = 0, key; for (key = 0; key < trace->sctbl->syscalls.nr_entries; ++key) { - if (enabled) + if (enabled) { trace__init_bpf_map_syscall_args(trace, key, &value); + trace__init_syscall_bpf_progs(trace, key); + } err = bpf_map_update_elem(fd, &key, &value, BPF_ANY); if (err) diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index 48a536b1be6d..66b33b299349 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -94,6 +94,29 @@ int syscall_unaugmented(struct syscall_enter_args *args) return 1; } +/* + * This will be tail_called from SEC("raw_syscalls:sys_enter"), so will find in + * augmented_filename_map what was read by that raw_syscalls:sys_enter and go + * on from there, reading the first syscall arg as a string, i.e. open's + * filename. + */ +SEC("!syscalls:sys_enter_open") +int sys_enter_open(struct syscall_enter_args *args) +{ + int key = 0; + struct augmented_args_filename *augmented_args = bpf_map_lookup_elem(&augmented_filename_map, &key); + const void *filename_arg = (const void *)args->args[0]; + unsigned int len = sizeof(augmented_args->args); + + if (augmented_args == NULL) + return 1; /* Failure: don't filter */ + + len += augmented_filename__read(&augmented_args->filename, filename_arg, sizeof(augmented_args->filename.value)); + + /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ + return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); +} + SEC("raw_syscalls:sys_enter") int sys_enter(struct syscall_enter_args *args) { -- cgit v1.2.3-59-g8ed1b From 3803a229312de539d2878f2fc5c6ee0202ce6728 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 16 Jul 2019 11:27:03 -0300 Subject: perf trace: Put the per-syscall entry/exit prog_array BPF map infrastructure in place MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I.e. look for "syscalls_sys_enter" and "syscalls_sys_exit" BPF maps of type PROG_ARRAY and populate it with the handlers as specified per syscall, for now only 'open' is wiring it to something, in time all syscalls that need to copy arguments entering a syscall or returning from one will set these to the right handlers, reusing when possible pre-existing ones. Next step is to use bpf_tail_call() into that. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-t0p4u43i9vbpzs1xtowna3gb@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 76 ++++++++++++++++++++++-- tools/perf/examples/bpf/augmented_raw_syscalls.c | 14 +++++ 2 files changed, 86 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 6cc696edf24a..fb8b8e78d7b5 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1,4 +1,3 @@ -// SPDX-License-Identifier: GPL-2.0-only /* * builtin-trace.c * @@ -83,6 +82,10 @@ struct trace { int max; struct syscall *table; struct bpf_map *map; + struct { // per syscall BPF_MAP_TYPE_PROG_ARRAY + struct bpf_map *sys_enter, + *sys_exit; + } prog_array; struct { struct perf_evsel *sys_enter, *sys_exit, @@ -1619,6 +1622,22 @@ out_free: goto out; } +static __maybe_unused bool trace__syscall_enabled(struct trace *trace, int id) +{ + bool in_ev_qualifier; + + if (trace->ev_qualifier_ids.nr == 0) + return true; + + in_ev_qualifier = bsearch(&id, trace->ev_qualifier_ids.entries, + trace->ev_qualifier_ids.nr, sizeof(int), intcmp) != NULL; + + if (in_ev_qualifier) + return !trace->not_ev_qualifier; + + return trace->not_ev_qualifier; +} + /* * args is to be interpreted as a series of longs but we need to handle * 8-byte unaligned accesses. args points to raw_data within the event @@ -2784,6 +2803,18 @@ static void trace__init_syscall_bpf_progs(struct trace *trace, int id) } } +static int trace__bpf_prog_sys_enter_fd(struct trace *trace, int id) +{ + struct syscall *sc = trace__syscall_info(trace, NULL, id); + return sc ? bpf_program__fd(sc->bpf_prog.sys_enter) : bpf_program__fd(trace->syscalls.unaugmented_prog); +} + +static int trace__bpf_prog_sys_exit_fd(struct trace *trace, int id) +{ + struct syscall *sc = trace__syscall_info(trace, NULL, id); + return sc ? bpf_program__fd(sc->bpf_prog.sys_exit) : bpf_program__fd(trace->syscalls.unaugmented_prog); +} + static void trace__init_bpf_map_syscall_args(struct trace *trace, int id, struct bpf_map_syscall_entry *entry) { struct syscall *sc = trace__syscall_info(trace, NULL, id); @@ -2837,10 +2868,8 @@ static int __trace__init_syscalls_bpf_map(struct trace *trace, bool enabled) int err = 0, key; for (key = 0; key < trace->sctbl->syscalls.nr_entries; ++key) { - if (enabled) { + if (enabled) trace__init_bpf_map_syscall_args(trace, key, &value); - trace__init_syscall_bpf_progs(trace, key); - } err = bpf_map_update_elem(fd, &key, &value, BPF_ANY); if (err) @@ -2859,6 +2888,34 @@ static int trace__init_syscalls_bpf_map(struct trace *trace) return __trace__init_syscalls_bpf_map(trace, enabled); } + +static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace) +{ + int map_enter_fd = bpf_map__fd(trace->syscalls.prog_array.sys_enter), + map_exit_fd = bpf_map__fd(trace->syscalls.prog_array.sys_exit); + int err = 0, key; + + for (key = 0; key < trace->sctbl->syscalls.nr_entries; ++key) { + int prog_fd; + + if (!trace__syscall_enabled(trace, key)) + continue; + + trace__init_syscall_bpf_progs(trace, key); + + // It'll get at least the "!raw_syscalls:unaugmented" + prog_fd = trace__bpf_prog_sys_enter_fd(trace, key); + err = bpf_map_update_elem(map_enter_fd, &key, &prog_fd, BPF_ANY); + if (err) + break; + prog_fd = trace__bpf_prog_sys_exit_fd(trace, key); + err = bpf_map_update_elem(map_exit_fd, &key, &prog_fd, BPF_ANY); + if (err) + break; + } + + return err; +} #else static int trace__set_ev_qualifier_bpf_filter(struct trace *trace __maybe_unused) { @@ -2875,6 +2932,11 @@ static struct bpf_program *trace__find_bpf_program_by_title(struct trace *trace { return NULL; } + +static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace __maybe_unused) +{ + return 0; +} #endif // HAVE_LIBBPF_SUPPORT static int trace__set_ev_qualifier_filter(struct trace *trace) @@ -3129,6 +3191,10 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (trace->syscalls.map) trace__init_syscalls_bpf_map(trace); + if (trace->syscalls.prog_array.sys_enter) + trace__init_syscalls_bpf_prog_array_maps(trace); + + if (trace->ev_qualifier_ids.nr > 0) { err = trace__set_ev_qualifier_filter(trace); if (err < 0) @@ -3754,6 +3820,8 @@ static void trace__set_bpf_map_filtered_pids(struct trace *trace) static void trace__set_bpf_map_syscalls(struct trace *trace) { trace->syscalls.map = trace__find_bpf_map_by_name(trace, "syscalls"); + trace->syscalls.prog_array.sys_enter = trace__find_bpf_map_by_name(trace, "syscalls_sys_enter"); + trace->syscalls.prog_array.sys_exit = trace__find_bpf_map_by_name(trace, "syscalls_sys_exit"); } static int trace__config(const char *var, const char *value, void *arg) diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index 66b33b299349..c66474a6ccf4 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -33,6 +33,20 @@ struct syscall { bpf_map(syscalls, ARRAY, int, struct syscall, 512); +/* + * What to augment at entry? + * + * Pointer arg payloads (filenames, etc) passed from userspace to the kernel + */ +bpf_map(syscalls_sys_enter, PROG_ARRAY, u32, u32, 512); + +/* + * What to augment at exit? + * + * Pointer arg payloads returned from the kernel (struct stat, etc) to userspace. + */ +bpf_map(syscalls_sys_exit, PROG_ARRAY, u32, u32, 512); + struct syscall_enter_args { unsigned long long common_tp_fields; long syscall_nr; -- cgit v1.2.3-59-g8ed1b From b119970aa541091e405373399690c24ead9d2920 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 16 Jul 2019 11:53:03 -0300 Subject: perf trace: Handle raw_syscalls:sys_enter just like the BPF_OUTPUT augmented event MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So, we use a PERF_COUNT_SW_BPF_OUTPUT to output the augmented sys_enter payload, i.e. to output more than just the raw syscall args, and if something goes wrong when handling an unfiltered syscall, we bail out and just return 1 in the bpf program associated with raw_syscalls:sys_enter, meaning, don't filter that tracepoint, in which case what will appear in the perf ring buffer isn't the BPF_OUTPUT event, but the original raw_syscalls:sys_enter event with its normal payload. Now that we're switching to using a bpf_tail_call + BPF_MAP_TYPE_PROG_ARRAY we're going to use this in the common case, so a bug where raw_syscalls:sys_enter wasn't being handled by trace__sys_enter() surfaced and for that case, instead of using the strace-like augmenter (trace__sys_enter()), we continued to use the normal generic tracepoint handler: (gdb) p evsel $2 = (struct perf_evsel *) 0xc03e40 (gdb) p evsel->name $3 = 0xbc56c0 "raw_syscalls:sys_enter" (gdb) p ((struct perf_evsel *) 0xc03e40)->name $4 = 0xbc56c0 "raw_syscalls:sys_enter" (gdb) p ((struct perf_evsel *) 0xc03e40)->handler $5 = (void *) 0x495eb3 This resulted in this: 0.027 raw_syscalls:sys_enter:NR 12 (0, 7fcfcac64c9b, 4d, 7fcfcac64c9b, 7fcfcac6ce00, 19) ... [continued]: brk()) = 0x563b88677000 I.e. only the sys_exit tracepoint was being properly handled, but since the sys_enter went to the generic trace__event_handler() we printed it using libtraceevent's formatter instead of 'perf trace's strace-like one. Fix it by setting trace__sys_enter() as the handler for raw_syscalls:sys_enter and setup the tp_field tracepoint field accessors. Now, to test it we just make raw_syscalls:sys_enter return 1 right after checking if the pid is filtered, making it not use bpf_perf_output_event() but rather ask for the tracepoint not to be filtered and the result is the expected one: brk(NULL) = 0x556f42d6e000 I.e. raw_syscalls:sys_enter returns 1, gets handled by trace__sys_enter() and gets it combined with the raw_syscalls:sys_exit in a strace-like way. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-0mkocgk31nmy0odknegcby4z@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index fb8b8e78d7b5..872c9cc982a5 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -4128,7 +4128,22 @@ int cmd_trace(int argc, const char **argv) if (perf_evsel__init_augmented_syscall_tp(augmented, evsel) || perf_evsel__init_augmented_syscall_tp_args(augmented)) goto out; + /* + * Augmented is __augmented_syscalls__ BPF_OUTPUT event + * Above we made sure we can get from the payload the tp fields + * that we get from syscalls:sys_enter tracefs format file. + */ augmented->handler = trace__sys_enter; + /* + * Now we do the same for the *syscalls:sys_enter event so that + * if we handle it directly, i.e. if the BPF prog returns 0 so + * as not to filter it, then we'll handle it just like we would + * for the BPF_OUTPUT one: + */ + if (perf_evsel__init_augmented_syscall_tp(evsel, evsel) || + perf_evsel__init_augmented_syscall_tp_args(evsel)) + goto out; + evsel->handler = trace__sys_enter; } if (strstarts(perf_evsel__name(evsel), "syscalls:sys_exit_")) { -- cgit v1.2.3-59-g8ed1b From 236dd5838871024d58d354ff8d0dab00ee59a867 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 16 Jul 2019 12:31:10 -0300 Subject: perf augmented_raw_syscalls: Add handler for "openat" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I.e. for a syscall that has its second argument being a string, its difficult these days to find 'open' being used in the wild :-) Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-yf3kbzirqrukd3fb2sp5qx4p@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 1 + tools/perf/examples/bpf/augmented_raw_syscalls.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 872c9cc982a5..a681b8c2ee4e 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -836,6 +836,7 @@ static struct syscall_fmt { .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, [2] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, { .name = "openat", + .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_openat", }, .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, [2] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, { .name = "perf_event_open", diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index c66474a6ccf4..661936f90fe0 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -131,6 +131,23 @@ int sys_enter_open(struct syscall_enter_args *args) return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); } +SEC("!syscalls:sys_enter_openat") +int sys_enter_openat(struct syscall_enter_args *args) +{ + int key = 0; + struct augmented_args_filename *augmented_args = bpf_map_lookup_elem(&augmented_filename_map, &key); + const void *filename_arg = (const void *)args->args[1]; + unsigned int len = sizeof(augmented_args->args); + + if (augmented_args == NULL) + return 1; /* Failure: don't filter */ + + len += augmented_filename__read(&augmented_args->filename, filename_arg, sizeof(augmented_args->filename.value)); + + /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ + return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); +} + SEC("raw_syscalls:sys_enter") int sys_enter(struct syscall_enter_args *args) { -- cgit v1.2.3-59-g8ed1b From bf134ca6c8eafd7ddc28840f767259b97e950bac Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 16 Jul 2019 12:34:59 -0300 Subject: perf augmented_raw_syscalls: Switch to using BPF_MAP_TYPE_PROG_ARRAY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trying to control what arguments to copy, which ones were strings, etc all from userspace via maps went nowhere, lots of difficulties to get the verifier satisfied, so use what the fine BPF guys designed for such a syscall handling mechanism: bpf_tail_call + BPF_MAP_TYPE_PROG_ARRAY. The series leading to this should have explained it thoroughly, but the end result, explained via gdb should help understand this: Breakpoint 1, syscall_arg__scnprintf_filename (bf=0xc002b1 "", size=2031, arg=0x7fffffff7970) at builtin-trace.c:1268 1268 { (gdb) n 1269 unsigned long ptr = arg->val; (gdb) n 1271 if (arg->augmented.args) (gdb) n 1272 return syscall_arg__scnprintf_augmented_string(arg, bf, size); (gdb) s syscall_arg__scnprintf_augmented_string (arg=0x7fffffff7970, bf=0xc002b1 "", size=2031) at builtin-trace.c:1251 1251 { (gdb) n 1252 struct augmented_arg *augmented_arg = arg->augmented.args; (gdb) n 1253 size_t printed = scnprintf(bf, size, "\"%.*s\"", augmented_arg->size, augmented_arg->value); (gdb) n 1258 int consumed = sizeof(*augmented_arg) + augmented_arg->size; (gdb) p bf $1 = 0xc002b1 "\"/etc/ld.so.cache\"" (gdb) bt #0 syscall_arg__scnprintf_augmented_string (arg=0x7fffffff7970, bf=0xc002b1 "\"/etc/ld.so.cache\"", size=2031) at builtin-trace.c:1258 #1 0x0000000000492634 in syscall_arg__scnprintf_filename (bf=0xc002b1 "\"/etc/ld.so.cache\"", size=2031, arg=0x7fffffff7970) at builtin-trace.c:1272 #2 0x0000000000493cd7 in syscall__scnprintf_val (sc=0xc0de68, bf=0xc002b1 "\"/etc/ld.so.cache\"", size=2031, arg=0x7fffffff7970, val=140737354091036) at builtin-trace.c:1689 #3 0x000000000049404f in syscall__scnprintf_args (sc=0xc0de68, bf=0xc002a7 "AT_FDCWD, \"/etc/ld.so.cache\"", size=2041, args=0x7ffff6cbf1ec "\234\377\377\377", augmented_args=0x7ffff6cbf21c, augmented_args_size=28, trace=0x7fffffffa170, thread=0xbff940) at builtin-trace.c:1756 #4 0x0000000000494a97 in trace__sys_enter (trace=0x7fffffffa170, evsel=0xbe1900, event=0x7ffff6cbf1a0, sample=0x7fffffff7b00) at builtin-trace.c:1975 #5 0x0000000000496ff1 in trace__handle_event (trace=0x7fffffffa170, event=0x7ffff6cbf1a0, sample=0x7fffffff7b00) at builtin-trace.c:2685 #6 0x0000000000497edb in __trace__deliver_event (trace=0x7fffffffa170, event=0x7ffff6cbf1a0) at builtin-trace.c:3029 #7 0x000000000049801e in trace__deliver_event (trace=0x7fffffffa170, event=0x7ffff6cbf1a0) at builtin-trace.c:3056 #8 0x00000000004988de in trace__run (trace=0x7fffffffa170, argc=2, argv=0x7fffffffd660) at builtin-trace.c:3258 #9 0x000000000049c2d3 in cmd_trace (argc=2, argv=0x7fffffffd660) at builtin-trace.c:4220 #10 0x00000000004dcb6c in run_builtin (p=0xa18e00 , argc=5, argv=0x7fffffffd660) at perf.c:304 #11 0x00000000004dcdd9 in handle_internal_command (argc=5, argv=0x7fffffffd660) at perf.c:356 #12 0x00000000004dcf20 in run_argv (argcp=0x7fffffffd4bc, argv=0x7fffffffd4b0) at perf.c:400 #13 0x00000000004dd28c in main (argc=5, argv=0x7fffffffd660) at perf.c:522 (gdb) (gdb) continue Continuing. openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 Now its a matter of automagically assigning the BPF programs copying syscall arg pointers to functions that are "open"-like (i.e. that need only the first syscall arg copied as a string), or "openat"-like (2nd arg, etc). End result in tool output: # perf trace -e open* ls /tmp/notthere LLVM: dumping /home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib64/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib64/libpcre2-8.so.0", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/usr/share/locale/en_US.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = ls: cannot access '/tmp/notthere'-1 ENOENT (No such file or directory) openat(AT_FDCWD, "/usr/share/locale/en_US.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/usr/share/locale/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/usr/share/locale/en.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/usr/share/locale/en.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY: No such file or directory) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/usr/share/locale/en_US.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/usr/share/locale/en.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/usr/share/locale/en.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) # Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-snc7ry99cl6r0pqaspjim98x@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_raw_syscalls.c | 127 +++-------------------- 1 file changed, 16 insertions(+), 111 deletions(-) (limited to 'tools') diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index 661936f90fe0..ce308b9a317c 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -174,131 +174,36 @@ int sys_enter(struct syscall_enter_args *args) probe_read(&augmented_args->args, sizeof(augmented_args->args), args); - syscall = bpf_map_lookup_elem(&syscalls, &augmented_args->args.syscall_nr); - if (syscall == NULL || !syscall->enabled) - return 0; /* - * Yonghong and Edward Cree sayz: - * - * https://www.spinics.net/lists/netdev/msg531645.html - * - * >> R0=inv(id=0) R1=inv2 R6=ctx(id=0,off=0,imm=0) R7=inv64 R10=fp0,call_-1 - * >> 10: (bf) r1 = r6 - * >> 11: (07) r1 += 16 - * >> 12: (05) goto pc+2 - * >> 15: (79) r3 = *(u64 *)(r1 +0) - * >> dereference of modified ctx ptr R1 off=16 disallowed - * > Aha, we at least got a different error message this time. - * > And indeed llvm has done that optimisation, rather than the more obvious - * > 11: r3 = *(u64 *)(r1 +16) - * > because it wants to have lots of reads share a single insn. You may be able - * > to defeat that optimisation by adding compiler barriers, idk. Maybe someone - * > with llvm knowledge can figure out how to stop it (ideally, llvm would know - * > when it's generating for bpf backend and not do that). -O0? ¯\_(ツ)_/¯ - * - * The optimization mostly likes below: - * - * br1: - * ... - * r1 += 16 - * goto merge - * br2: - * ... - * r1 += 20 - * goto merge - * merge: - * *(u64 *)(r1 + 0) - * - * The compiler tries to merge common loads. There is no easy way to - * stop this compiler optimization without turning off a lot of other - * optimizations. The easiest way is to add barriers: - * - * __asm__ __volatile__("": : :"memory") - * - * after the ctx memory access to prevent their down stream merging. + * Jump to syscall specific augmenter, even if the default one, + * "!raw_syscalls:unaugmented" that will just return 1 to return the + * unagmented tracepoint payload. */ - /* - * For now copy just the first string arg, we need to improve the protocol - * and have more than one. - * - * Using the unrolled loop is not working, only when we do it manually, - * check this out later... - - u8 arg; -#pragma clang loop unroll(full) - for (arg = 0; arg < 6; ++arg) { - if (syscall->string_args_len[arg] != 0) { - filename_len = syscall->string_args_len[arg]; - filename_arg = (const void *)args->args[arg]; - __asm__ __volatile__("": : :"memory"); - break; - } - } - - verifier log: - -; if (syscall->string_args_len[arg] != 0) { -37: (69) r3 = *(u16 *)(r0 +2) - R0=map_value(id=0,off=0,ks=4,vs=14,imm=0) R1_w=inv0 R2_w=map_value(id=0,off=2,ks=4,vs=14,imm=0) R6=ctx(id=0,off=0,imm=0) R7=map_value(id=0,off=0,ks=4,vs=4168,imm=0) R10=fp0,call_-1 fp-8=mmmmmmmm -; if (syscall->string_args_len[arg] != 0) { -38: (55) if r3 != 0x0 goto pc+5 - R0=map_value(id=0,off=0,ks=4,vs=14,imm=0) R1=inv0 R2=map_value(id=0,off=2,ks=4,vs=14,imm=0) R3=inv0 R6=ctx(id=0,off=0,imm=0) R7=map_value(id=0,off=0,ks=4,vs=4168,imm=0) R10=fp0,call_-1 fp-8=mmmmmmmm -39: (b7) r1 = 1 -; if (syscall->string_args_len[arg] != 0) { -40: (bf) r2 = r0 -41: (07) r2 += 4 -42: (69) r3 = *(u16 *)(r0 +4) - R0=map_value(id=0,off=0,ks=4,vs=14,imm=0) R1_w=inv1 R2_w=map_value(id=0,off=4,ks=4,vs=14,imm=0) R3_w=inv0 R6=ctx(id=0,off=0,imm=0) R7=map_value(id=0,off=0,ks=4,vs=4168,imm=0) R10=fp0,call_-1 fp-8=mmmmmmmm -; if (syscall->string_args_len[arg] != 0) { -43: (15) if r3 == 0x0 goto pc+32 - R0=map_value(id=0,off=0,ks=4,vs=14,imm=0) R1=inv1 R2=map_value(id=0,off=4,ks=4,vs=14,imm=0) R3=inv(id=0,umax_value=65535,var_off=(0x0; 0xffff)) R6=ctx(id=0,off=0,imm=0) R7=map_value(id=0,off=0,ks=4,vs=4168,imm=0) R10=fp0,call_-1 fp-8=mmmmmmmm -; filename_arg = (const void *)args->args[arg]; -44: (67) r1 <<= 3 -45: (bf) r3 = r6 -46: (0f) r3 += r1 -47: (b7) r5 = 64 -48: (79) r3 = *(u64 *)(r3 +16) -dereference of modified ctx ptr R3 off=8 disallowed -processed 46 insns (limit 1000000) max_states_per_insn 0 total_states 12 peak_states 12 mark_read 7 - */ - -#define __loop_iter(arg) \ - if (syscall->string_args_len[arg] != 0) { \ - unsigned int filename_len = syscall->string_args_len[arg]; \ - const void *filename_arg = (const void *)args->args[arg]; \ - if (filename_len <= sizeof(augmented_args->filename.value)) \ - len += augmented_filename__read(&augmented_args->filename, filename_arg, filename_len); -#define loop_iter_first() __loop_iter(0); } -#define loop_iter(arg) else __loop_iter(arg); } -#define loop_iter_last(arg) else __loop_iter(arg); __asm__ __volatile__("": : :"memory"); } - - loop_iter_first() - loop_iter(1) - loop_iter(2) - loop_iter(3) - loop_iter(4) - loop_iter_last(5) + bpf_tail_call(args, &syscalls_sys_enter, augmented_args->args.syscall_nr); - /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ - return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); + // If not found on the PROG_ARRAY syscalls map, then we're filtering it: + return 0; } SEC("raw_syscalls:sys_exit") int sys_exit(struct syscall_exit_args *args) { struct syscall_exit_args exit_args; - struct syscall *syscall; if (pid_filter__has(&pids_filtered, getpid())) return 0; probe_read(&exit_args, sizeof(exit_args), args); - - syscall = bpf_map_lookup_elem(&syscalls, &exit_args.syscall_nr); - if (syscall == NULL || !syscall->enabled) - return 0; - - return 1; + /* + * Jump to syscall specific return augmenter, even if the default one, + * "!raw_syscalls:unaugmented" that will just return 1 to return the + * unagmented tracepoint payload. + */ + bpf_tail_call(args, &syscalls_sys_exit, exit_args.syscall_nr); + /* + * If not found on the PROG_ARRAY syscalls map, then we're filtering it: + */ + return 0; } license(GPL); -- cgit v1.2.3-59-g8ed1b From 8d5da2649d8211e63c5f65ccf8945f2c46a9c0b8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 16 Jul 2019 14:55:57 -0300 Subject: perf augmented_raw_syscalls: Support copying two string syscall args MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Starting with the renameat and renameat2 syscall, that both receive as second and fourth parameters a pathname: # perf trace -e rename* mv one ANOTHER LLVM: dumping /home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o mv: cannot stat 'one': No such file or directory renameat2(AT_FDCWD, "one", AT_FDCWD, "ANOTHER", RENAME_NOREPLACE) = -1 ENOENT (No such file or directory) # Since the per CPU scratch buffer map has space for two maximum sized pathnames, the verifier is satisfied that there will be no overrun. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-x2uboyg5kx2wqeru288209b6@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 2 ++ tools/perf/examples/bpf/augmented_raw_syscalls.c | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index a681b8c2ee4e..c64f7c99db15 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -873,9 +873,11 @@ static struct syscall_fmt { { .name = "recvmsg", .arg = { [2] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, { .name = "renameat", + .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_renameat", }, .arg = { [0] = { .scnprintf = SCA_FDAT, /* olddirfd */ }, [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ }, }, }, { .name = "renameat2", + .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_renameat", }, .arg = { [0] = { .scnprintf = SCA_FDAT, /* olddirfd */ }, [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ }, [4] = { .scnprintf = SCA_RENAMEAT2_FLAGS, /* flags */ }, }, }, diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index ce308b9a317c..df52d92e1c69 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -70,6 +70,7 @@ pid_filter(pids_filtered); struct augmented_args_filename { struct syscall_enter_args args; struct augmented_filename filename; + struct augmented_filename filename2; }; bpf_map(augmented_filename_map, PERCPU_ARRAY, int, struct augmented_args_filename, 1); @@ -148,6 +149,25 @@ int sys_enter_openat(struct syscall_enter_args *args) return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); } +SEC("!syscalls:sys_enter_renameat") +int sys_enter_renameat(struct syscall_enter_args *args) +{ + int key = 0; + struct augmented_args_filename *augmented_args = bpf_map_lookup_elem(&augmented_filename_map, &key); + const void *oldpath_arg = (const void *)args->args[1], + *newpath_arg = (const void *)args->args[3]; + unsigned int len = sizeof(augmented_args->args), oldpath_len; + + if (augmented_args == NULL) + return 1; /* Failure: don't filter */ + + oldpath_len = augmented_filename__read(&augmented_args->filename, oldpath_arg, sizeof(augmented_args->filename.value)); + len += oldpath_len + augmented_filename__read((void *)(&augmented_args->filename) + oldpath_len, newpath_arg, sizeof(augmented_args->filename.value)); + + /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ + return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); +} + SEC("raw_syscalls:sys_enter") int sys_enter(struct syscall_enter_args *args) { -- cgit v1.2.3-59-g8ed1b From 8b8044e5c9527cdfff3b0937f2d17470cc4acf9e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 16 Jul 2019 15:24:58 -0300 Subject: perf trace: Look for default name for entries in the syscalls prog array MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I.e. just look for "!syscalls:sys_enter_" or "exit_" plus the syscall name, that way we need just to add entries to the augmented_raw_syscalls.c BPF source to add handlers. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-6xavwddruokp6ohs7tf4qilb@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index c64f7c99db15..5258399a1c94 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -830,13 +830,11 @@ static struct syscall_fmt { { .name = "newfstatat", .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, { .name = "open", - .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_open", }, .arg = { [1] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, { .name = "open_by_handle_at", .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, [2] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, { .name = "openat", - .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_openat", }, .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, [2] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, { .name = "perf_event_open", @@ -873,7 +871,6 @@ static struct syscall_fmt { { .name = "recvmsg", .arg = { [2] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, { .name = "renameat", - .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_renameat", }, .arg = { [0] = { .scnprintf = SCA_FDAT, /* olddirfd */ }, [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ }, }, }, { .name = "renameat2", @@ -2778,12 +2775,27 @@ static struct bpf_program *trace__find_syscall_bpf_prog(struct trace *trace, str { struct bpf_program *prog; - if (prog_name == NULL) + if (prog_name == NULL) { + char default_prog_name[256]; + scnprintf(default_prog_name, sizeof(default_prog_name), "!syscalls:sys_%s_%s", type, sc->name); + prog = trace__find_bpf_program_by_title(trace, default_prog_name); + if (prog != NULL) + goto out_found; + if (sc->fmt && sc->fmt->alias) { + scnprintf(default_prog_name, sizeof(default_prog_name), "!syscalls:sys_%s_%s", type, sc->fmt->alias); + prog = trace__find_bpf_program_by_title(trace, default_prog_name); + if (prog != NULL) + goto out_found; + } goto out_unaugmented; + } prog = trace__find_bpf_program_by_title(trace, prog_name); - if (prog != NULL) + + if (prog != NULL) { +out_found: return prog; + } pr_debug("Couldn't find BPF prog \"%s\" to associate with syscalls:sys_%s_%s, not augmenting it\n", prog_name, type, sc->name); @@ -2798,12 +2810,8 @@ static void trace__init_syscall_bpf_progs(struct trace *trace, int id) if (sc == NULL) return; - if (sc->fmt != NULL) { - sc->bpf_prog.sys_enter = trace__find_syscall_bpf_prog(trace, sc, sc->fmt->bpf_prog_name.sys_enter, "enter"); - sc->bpf_prog.sys_exit = trace__find_syscall_bpf_prog(trace, sc, sc->fmt->bpf_prog_name.sys_exit, "exit"); - } else { - sc->bpf_prog.sys_enter = sc->bpf_prog.sys_exit = trace->syscalls.unaugmented_prog; - } + sc->bpf_prog.sys_enter = trace__find_syscall_bpf_prog(trace, sc, sc->fmt ? sc->fmt->bpf_prog_name.sys_enter : NULL, "enter"); + sc->bpf_prog.sys_exit = trace__find_syscall_bpf_prog(trace, sc, sc->fmt ? sc->fmt->bpf_prog_name.sys_exit : NULL, "exit"); } static int trace__bpf_prog_sys_enter_fd(struct trace *trace, int id) -- cgit v1.2.3-59-g8ed1b From 6f563674935e6dc9e2190ce798c1917f51af6eed Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 16 Jul 2019 15:33:20 -0300 Subject: perf augmented_raw_syscalls: Rename augmented_args_filename to augmented_args_payload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It'll get other stuff in there than just filenames, starting with sockaddr for 'connect' and 'bind'. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-bsexidtsn91ehdpzcd6n5fm9@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_raw_syscalls.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index df52d92e1c69..77bb6a0edce3 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -67,13 +67,15 @@ struct augmented_filename { pid_filter(pids_filtered); -struct augmented_args_filename { +struct augmented_args_payload { struct syscall_enter_args args; - struct augmented_filename filename; - struct augmented_filename filename2; + struct { + struct augmented_filename filename; + struct augmented_filename filename2; + }; }; -bpf_map(augmented_filename_map, PERCPU_ARRAY, int, struct augmented_args_filename, 1); +bpf_map(augmented_args_tmp, PERCPU_ARRAY, int, struct augmented_args_payload, 1); static inline unsigned int augmented_filename__read(struct augmented_filename *augmented_filename, @@ -111,7 +113,7 @@ int syscall_unaugmented(struct syscall_enter_args *args) /* * This will be tail_called from SEC("raw_syscalls:sys_enter"), so will find in - * augmented_filename_map what was read by that raw_syscalls:sys_enter and go + * augmented_args_tmp what was read by that raw_syscalls:sys_enter and go * on from there, reading the first syscall arg as a string, i.e. open's * filename. */ @@ -119,7 +121,7 @@ SEC("!syscalls:sys_enter_open") int sys_enter_open(struct syscall_enter_args *args) { int key = 0; - struct augmented_args_filename *augmented_args = bpf_map_lookup_elem(&augmented_filename_map, &key); + struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(&augmented_args_tmp, &key); const void *filename_arg = (const void *)args->args[0]; unsigned int len = sizeof(augmented_args->args); @@ -136,7 +138,7 @@ SEC("!syscalls:sys_enter_openat") int sys_enter_openat(struct syscall_enter_args *args) { int key = 0; - struct augmented_args_filename *augmented_args = bpf_map_lookup_elem(&augmented_filename_map, &key); + struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(&augmented_args_tmp, &key); const void *filename_arg = (const void *)args->args[1]; unsigned int len = sizeof(augmented_args->args); @@ -153,7 +155,7 @@ SEC("!syscalls:sys_enter_renameat") int sys_enter_renameat(struct syscall_enter_args *args) { int key = 0; - struct augmented_args_filename *augmented_args = bpf_map_lookup_elem(&augmented_filename_map, &key); + struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(&augmented_args_tmp, &key); const void *oldpath_arg = (const void *)args->args[1], *newpath_arg = (const void *)args->args[3]; unsigned int len = sizeof(augmented_args->args), oldpath_len; @@ -171,7 +173,7 @@ int sys_enter_renameat(struct syscall_enter_args *args) SEC("raw_syscalls:sys_enter") int sys_enter(struct syscall_enter_args *args) { - struct augmented_args_filename *augmented_args; + struct augmented_args_payload *augmented_args; /* * We start len, the amount of data that will be in the perf ring * buffer, if this is not filtered out by one of pid_filter__has(), @@ -185,7 +187,7 @@ int sys_enter(struct syscall_enter_args *args) struct syscall *syscall; int key = 0; - augmented_args = bpf_map_lookup_elem(&augmented_filename_map, &key); + augmented_args = bpf_map_lookup_elem(&augmented_args_tmp, &key); if (augmented_args == NULL) return 1; -- cgit v1.2.3-59-g8ed1b From 212b9ab6775b5f340de848b5b6eef6968ccf7f20 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 16 Jul 2019 16:28:14 -0300 Subject: perf augmented_raw_syscalls: Augment sockaddr arg in 'connect' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already had a beautifier for an augmented sockaddr payload, but that was when we were hooking on each syscalls:sys_enter_foo tracepoints, since now we're almost doing that by doing a tail call from raw_syscalls:sys_enter, its almost the same, we can reuse it straight away. # perf trace -e connec* ssh www.bla.com connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 0x6e) = -1 ENOENT (No such file or directory) connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 0x6e) = -1 ENOENT (No such file or directory) connect(4, { .family: PF_LOCAL, path: /var/lib/sss/pipes/nss }, 0x6e) = 0 connect(7, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 0x6e) = -1 ENOENT (No such file or directory) connect(7, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 0x6e) = -1 ENOENT (No such file or directory) connect(5, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 0x6e) = -1 ENOENT (No such file or directory) connect(5, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 0x6e) = -1 ENOENT (No such file or directory) connect(5, { .family: PF_INET, port: 53, addr: 192.168.44.1 }, 0x10) = 0 connect(5, { .family: PF_INET, port: 22, addr: 146.112.61.108 }, 0x10) = 0 connect(5, { .family: PF_INET6, port: 22, addr: ::ffff:146.112.61.108 }, 0x1c) = 0 ^C# Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-5xkrbcpjsgnr3zt1aqdd7nvc@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_raw_syscalls.c | 35 ++++++++++++++++++++---- 1 file changed, 30 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index 77bb6a0edce3..d7a292d7ee2f 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -16,6 +16,7 @@ #include #include +#include #include /* bpf-output associated map */ @@ -69,10 +70,13 @@ pid_filter(pids_filtered); struct augmented_args_payload { struct syscall_enter_args args; - struct { - struct augmented_filename filename; - struct augmented_filename filename2; - }; + union { + struct { + struct augmented_filename filename, + filename2; + }; + struct sockaddr_storage saddr; + }; }; bpf_map(augmented_args_tmp, PERCPU_ARRAY, int, struct augmented_args_payload, 1); @@ -112,11 +116,32 @@ int syscall_unaugmented(struct syscall_enter_args *args) } /* - * This will be tail_called from SEC("raw_syscalls:sys_enter"), so will find in + * These will be tail_called from SEC("raw_syscalls:sys_enter"), so will find in * augmented_args_tmp what was read by that raw_syscalls:sys_enter and go * on from there, reading the first syscall arg as a string, i.e. open's * filename. */ +SEC("!syscalls:sys_enter_connect") +int sys_enter_connect(struct syscall_enter_args *args) +{ + int key = 0; + struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(&augmented_args_tmp, &key); + const void *sockaddr_arg = (const void *)args->args[1]; + unsigned int socklen = args->args[2]; + unsigned int len = sizeof(augmented_args->args); + + if (augmented_args == NULL) + return 1; /* Failure: don't filter */ + + if (socklen > sizeof(augmented_args->saddr)) + socklen = sizeof(augmented_args->saddr); + + probe_read(&augmented_args->saddr, socklen, sockaddr_arg); + + /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ + return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len + socklen); +} + SEC("!syscalls:sys_enter_open") int sys_enter_open(struct syscall_enter_args *args) { -- cgit v1.2.3-59-g8ed1b From 1d86275225b4c9db3fb426e992886df5051f0047 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 16 Jul 2019 16:34:27 -0300 Subject: perf trace beauty: Make connect's addrlen be printed as an int, not hex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # perf trace -e connec* ssh www.bla.com connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) connect(4, { .family: PF_LOCAL, path: /var/lib/sss/pipes/nss }, 110) = 0 connect(7, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) connect(7, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) connect(5, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) connect(5, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) connect(5, { .family: PF_INET, port: 53, addr: 192.168.44.1 }, 16) = 0 connect(5, { .family: PF_INET, port: 22, addr: 146.112.61.108 }, 16) = 0 connect(5, { .family: PF_INET6, port: 22, addr: ::ffff:146.112.61.108 }, 28) = 0 ^Cconnect(5, { .family: PF_INET, port: 22, addr: 146.112.61.108 }, 16) = -1 (unknown) (INTERNAL ERROR: strerror_r(512, [buf], 128)=22) # Argh, the SCA_FD needs to invalidate its cache when close is done... It works if the 'close' syscall is not filtered out ;-\ # perf trace -e close,connec* ssh www.bla.com close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(4) = 0 close(3) = 0 close(3) = 0 connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) close(3) = 0 connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 connect(4, { .family: PF_LOCAL, path: /var/lib/sss/pipes/nss }, 110) = 0 ^C # Will disable this beautifier when 'close' is filtered out... Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-ekuiciyx4znchvy95c8p1yyi@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 5258399a1c94..123d7efc12e8 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -725,7 +725,8 @@ static struct syscall_fmt { { .name = "close", .arg = { [0] = { .scnprintf = SCA_CLOSE_FD, /* fd */ }, }, }, { .name = "connect", - .arg = { [1] = { .scnprintf = SCA_SOCKADDR, /* servaddr */ }, }, }, + .arg = { [1] = { .scnprintf = SCA_SOCKADDR, /* servaddr */ }, + [2] = { .scnprintf = SCA_INT, /* addrlen */ }, }, }, { .name = "epoll_ctl", .arg = { [1] = STRARRAY(op, epoll_ctl_ops), }, }, { .name = "eventfd2", -- cgit v1.2.3-59-g8ed1b From 79d725cdf24dec7bfe7ad27b107f5cb06cd3785a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 16 Jul 2019 16:56:49 -0300 Subject: perf trace beauty: Disable fd->pathname when close() not enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As we invalidate the fd->pathname table in the SCA_CLOSE_FD beautifier, if we don't have it we may end up keeping an fd->pathname association that then gets misprinted. The previous behaviour continues when the close() syscall is enabled, which may still be a a problem if we lose records (i.e. we may lose a 'close' record and then get that fd reused by socket()) but then the tool will notify that records are being lost and the user will be warned that some of the heuristics will fall apart. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-b7t6h8sq9lebemvfy2zh3qq1@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 123d7efc12e8..94c33bb573c1 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -127,6 +127,7 @@ struct trace { unsigned int min_stack; int raw_augmented_syscalls_args_size; bool raw_augmented_syscalls; + bool fd_path_disabled; bool sort_events; bool not_ev_qualifier; bool live; @@ -1178,7 +1179,7 @@ static const char *thread__fd_path(struct thread *thread, int fd, { struct thread_trace *ttrace = thread__priv(thread); - if (ttrace == NULL) + if (ttrace == NULL || trace->fd_path_disabled) return NULL; if (fd < 0) @@ -2097,7 +2098,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, ret = perf_evsel__sc_tp_uint(evsel, ret, sample); - if (sc->is_open && ret >= 0 && ttrace->filename.pending_open) { + if (!trace->fd_path_disabled && sc->is_open && ret >= 0 && ttrace->filename.pending_open) { trace__set_fd_pathname(thread, ret, ttrace->filename.name); ttrace->filename.pending_open = false; ++trace->stats.vfs_getname; @@ -3206,7 +3207,6 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (trace->syscalls.prog_array.sys_enter) trace__init_syscalls_bpf_prog_array_maps(trace); - if (trace->ev_qualifier_ids.nr > 0) { err = trace__set_ev_qualifier_filter(trace); if (err < 0) @@ -3218,6 +3218,19 @@ static int trace__run(struct trace *trace, int argc, const char **argv) } } + /* + * If the "close" syscall is not traced, then we will not have the + * opportunity to, in syscall_arg__scnprintf_close_fd() invalidate the + * fd->pathname table and were ending up showing the last value set by + * syscalls opening a pathname and associating it with a descriptor or + * reading it from /proc/pid/fd/ in cases where that doesn't make + * sense. + * + * So just disable this beautifier (SCA_FD, SCA_FDAT) when 'close' is + * not in use. + */ + trace->fd_path_disabled = !trace__syscall_enabled(trace, syscalltbl__id(trace->sctbl, "close")); + err = perf_evlist__apply_filters(evlist, &evsel); if (err < 0) goto out_error_apply_filters; -- cgit v1.2.3-59-g8ed1b From ef969ca64d04161ccbde2aaf8b0767f91a6d32ff Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 16 Jul 2019 17:21:09 -0300 Subject: perf trace beauty: Do not try to use the fd->pathname beautifier for bind/connect fd arg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Doesn't make sense and also we now beautify the sockaddr, which provides enough info: # trace -e close,socket,connec* ssh www.bla.com close(5) = 0 socket(PF_INET, SOCK_DGRAM|CLOEXEC|NONBLOCK, IPPROTO_IP) = 5 connect(5, { .family: PF_INET, port: 53, addr: 192.168.44.1 }, 16) = 0 close(5) = 0 socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 5 ^C# Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-h9drpb7ail808d2mh4n7tla4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 94c33bb573c1..010aa9e9a561 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -710,7 +710,8 @@ static struct syscall_fmt { .arg = { [0] = { .scnprintf = SCA_X86_ARCH_PRCTL_CODE, /* code */ }, [1] = { .scnprintf = SCA_PTR, /* arg2 */ }, }, }, { .name = "bind", - .arg = { [1] = { .scnprintf = SCA_SOCKADDR, /* umyaddr */ }, }, }, + .arg = { [0] = { .scnprintf = SCA_INT, /* fd */ }, + [1] = { .scnprintf = SCA_SOCKADDR, /* umyaddr */ }, }, }, { .name = "bpf", .arg = { [0] = STRARRAY(cmd, bpf_cmd), }, }, { .name = "brk", .hexret = true, @@ -726,7 +727,8 @@ static struct syscall_fmt { { .name = "close", .arg = { [0] = { .scnprintf = SCA_CLOSE_FD, /* fd */ }, }, }, { .name = "connect", - .arg = { [1] = { .scnprintf = SCA_SOCKADDR, /* servaddr */ }, + .arg = { [0] = { .scnprintf = SCA_INT, /* fd */ }, + [1] = { .scnprintf = SCA_SOCKADDR, /* servaddr */ }, [2] = { .scnprintf = SCA_INT, /* addrlen */ }, }, }, { .name = "epoll_ctl", .arg = { [1] = STRARRAY(op, epoll_ctl_ops), }, }, -- cgit v1.2.3-59-g8ed1b From 3c475bc021be1f5e0a00dc1a13dc85ce7924a7d6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 16 Jul 2019 17:33:39 -0300 Subject: perf trace beauty: Beautify 'sendto's sockaddr arg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By just writing the collector in the augmented_raw_syscalls.c BPF program: # perf trace -e sendto ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 Socket Thread/3573 sendto(247, 0x7fb32d49c000, 120, NONE, { .family: PF_UNSPEC }, NULL) = 120 DNS Res~er #18/11374 sendto(242, 0x7fb342cfe420, 20, NONE, { .family: PF_NETLINK }, 0xc) = 20 DNS Res~er #18/11374 sendto(242, 0x7fb342cfcca0, 42, MSG_NOSIGNAL, { .family: PF_UNSPEC }, NULL) = 42 DNS Res~er #18/11374 sendto(242, 0x7fb342cfcccc, 42, MSG_NOSIGNAL, { .family: PF_UNSPEC }, NULL) = 42 ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 Socket Thread/3573 sendto(242, 0x7fb308bb1c08, 296, NONE, { .family: PF_UNSPEC }, NULL) = 296 ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 ping/23492 sendto(3, 0x56253bbef700, 64, NONE, { .family: PF_INET, port: 0, addr: 10.10.161.32 }, 0x10) = 64 ^C # Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-p0l0rlvq19v5zf8qc2x2itow@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_raw_syscalls.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'tools') diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index d7a292d7ee2f..9c2228b01ee6 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -142,6 +142,27 @@ int sys_enter_connect(struct syscall_enter_args *args) return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len + socklen); } +SEC("!syscalls:sys_enter_sendto") +int sys_enter_sendto(struct syscall_enter_args *args) +{ + int key = 0; + struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(&augmented_args_tmp, &key); + const void *sockaddr_arg = (const void *)args->args[4]; + unsigned int socklen = args->args[5]; + unsigned int len = sizeof(augmented_args->args); + + if (augmented_args == NULL) + return 1; /* Failure: don't filter */ + + if (socklen > sizeof(augmented_args->saddr)) + socklen = sizeof(augmented_args->saddr); + + probe_read(&augmented_args->saddr, socklen, sockaddr_arg); + + /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ + return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len + socklen); +} + SEC("!syscalls:sys_enter_open") int sys_enter_open(struct syscall_enter_args *args) { -- cgit v1.2.3-59-g8ed1b From 247dd65b909f1cd62a178febe3f6f8d5efdd7dd2 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 16 Jul 2019 17:38:26 -0300 Subject: perf trace beauty: Beautify bind's sockaddr arg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By reusing the "connect" BPF collector. Testing it system wide and stopping/starting sshd: # perf trace -e bind LLVM: dumping /home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.o DNS Res~er #18/15132 bind(243, { .family: PF_NETLINK }, 12) = 0 DNS Res~er #19/4833 bind(247, { .family: PF_NETLINK }, 12) = 0 DNS Res~er #19/4833 bind(238, { .family: PF_NETLINK }, 12) = 0 DNS Res~er #18/15132 bind(243, { .family: PF_NETLINK }, 12) = 0 DNS Res~er #18/10327 bind(258, { .family: PF_NETLINK }, 12) = 0 :6507/6507 bind(24, { .family: PF_NETLINK }, 12) = 0 DNS Res~er #19/4833 bind(238, { .family: PF_NETLINK }, 12) = 0 DNS Res~er #18/15132 bind(242, { .family: PF_NETLINK }, 12) = 0 sshd/6514 bind(3, { .family: PF_NETLINK }, 12) = 0 sshd/6514 bind(5, { .family: PF_INET, port: 22, addr: 0.0.0.0 }, 16) = 0 sshd/6514 bind(7, { .family: PF_INET6, port: 22, addr: :: }, 28) = 0 DNS Res~er #18/10327 bind(229, { .family: PF_NETLINK }, 12) = 0 DNS Res~er #18/15132 bind(231, { .family: PF_NETLINK }, 12) = 0 DNS Res~er #19/4833 bind(229, { .family: PF_NETLINK }, 12) = 0 ^C# Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-m2hmxqrckxxw2ciki0tu889u@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 010aa9e9a561..d403b09812d1 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -710,8 +710,10 @@ static struct syscall_fmt { .arg = { [0] = { .scnprintf = SCA_X86_ARCH_PRCTL_CODE, /* code */ }, [1] = { .scnprintf = SCA_PTR, /* arg2 */ }, }, }, { .name = "bind", + .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_connect", }, .arg = { [0] = { .scnprintf = SCA_INT, /* fd */ }, - [1] = { .scnprintf = SCA_SOCKADDR, /* umyaddr */ }, }, }, + [1] = { .scnprintf = SCA_SOCKADDR, /* umyaddr */ }, + [2] = { .scnprintf = SCA_INT, /* addrlen */ }, }, }, { .name = "bpf", .arg = { [0] = STRARRAY(cmd, bpf_cmd), }, }, { .name = "brk", .hexret = true, -- cgit v1.2.3-59-g8ed1b From cfa9ac73d6f9790f569959a729cbc9d52bff4270 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 17 Jul 2019 11:47:37 -0300 Subject: perf trace beauty: Add BPF augmenter for the 'rename' syscall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I.e. two strings: # perf trace -e rename systemd/1 rename("/run/systemd/units/.#invocation:dnf-makecache.service970761b7f2840dcc", "/run/systemd/units/invocation:dnf-makecache.service") = 0 systemd-journa/715 rename("/run/systemd/journal/streams/.#9:17539785BJDblc", "/run/systemd/journal/streams/9:17539785") = 0 mv/1936 rename("/tmp/build/perf/fd/.array.o.tmp", "/tmp/build/perf/fd/.array.o.cmd") = 0 sh/1949 rename("/tmp/build/perf/.cpu.o.tmp", "/tmp/build/perf/.cpu.o.cmd") = 0 mv/1954 rename("/tmp/build/perf/fs/.tracing_path.o.tmp", "/tmp/build/perf/fs/.tracing_path.o.cmd") = 0 mv/1963 rename("/tmp/build/perf/common-cmds.h+", "/tmp/build/perf/common-cmds.h") = 0 :1975/1975 rename("/tmp/build/perf/.exec-cmd.o.tmp", "/tmp/build/perf/.exec-cmd.o.cmd") = 0 mv/1979 rename("/tmp/build/perf/fs/.fs.o.tmp", "/tmp/build/perf/fs/.fs.o.cmd") = 0 mv/2005 rename("/tmp/build/perf/.debug.o.tmp", "/tmp/build/perf/.debug.o.cmd") = 0 mv/2012 rename("/tmp/build/perf/.str_error_r.o.tmp", "/tmp/build/perf/.str_error_r.o.cmd") = 0 mv/2019 rename("/tmp/build/perf/.help.o.tmp", "/tmp/build/perf/.help.o.cmd") = 0 mv/2031 rename("/tmp/build/perf/.trace-seq.o.tmp", "/tmp/build/perf/.trace-seq.o.cmd") = 0 make/2038 ... [continued]: rename()) = 0 :2038/2038 rename("/tmp/build/perf/.event-plugin.o.tmp", "/tmp/build/perf/.event-plugin.o.cmd") ... ar/2035 rename("/tmp/build/perf/stzwBX3a", "/tmp/build/perf/libapi.a") = 0 mv/2051 rename("/tmp/build/perf/.parse-utils.o.tmp", "/tmp/build/perf/.parse-utils.o.cmd") = 0 mv/2069 rename("/tmp/build/perf/.subcmd-config.o.tmp", "/tmp/build/perf/.subcmd-config.o.cmd") = 0 make/2080 rename("/tmp/build/perf/.parse-filter.o.tmp", "/tmp/build/perf/.parse-filter.o.cmd") = 0 mv/2099 rename("/tmp/build/perf/.pager.o.tmp", "/tmp/build/perf/.pager.o.cmd") = 0 :2124/2124 rename("/tmp/build/perf/.sigchain.o.tmp", "/tmp/build/perf/.sigchain.o.cmd") = 0 make/2140 rename("/tmp/build/perf/.event-parse.o.tmp", "/tmp/build/perf/.event-parse.o.cmd") = 0 mv/2164 rename("/tmp/build/perf/.kbuffer-parse.o.tmp", "/tmp/build/perf/.kbuffer-parse.o.cmd") = 0 sh/2174 rename("/tmp/build/perf/.run-command.o.tmp", "/tmp/build/perf/.run-command.o.cmd") = 0 mv/2190 rename("/tmp/build/perf/.tep_strerror.o.tmp", "/tmp/build/perf/.tep_strerror.o.cmd") = 0 :2261/2261 rename("/tmp/build/perf/.event-parse-api.o.tmp", "/tmp/build/perf/.event-parse-api.o.cmd") = 0 :2480/2480 rename("/tmp/build/perf/stLv3kG2", "/tmp/build/perf/libtraceevent.a") = 0 ^C# Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-6hh2rl27uri6gsxhmk6q3hx5@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_raw_syscalls.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'tools') diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index 9c2228b01ee6..79787cf4fce9 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -197,6 +197,25 @@ int sys_enter_openat(struct syscall_enter_args *args) return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); } +SEC("!syscalls:sys_enter_rename") +int sys_enter_rename(struct syscall_enter_args *args) +{ + int key = 0; + struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(&augmented_args_tmp, &key); + const void *oldpath_arg = (const void *)args->args[0], + *newpath_arg = (const void *)args->args[1]; + unsigned int len = sizeof(augmented_args->args), oldpath_len; + + if (augmented_args == NULL) + return 1; /* Failure: don't filter */ + + oldpath_len = augmented_filename__read(&augmented_args->filename, oldpath_arg, sizeof(augmented_args->filename.value)); + len += oldpath_len + augmented_filename__read((void *)(&augmented_args->filename) + oldpath_len, newpath_arg, sizeof(augmented_args->filename.value)); + + /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ + return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); +} + SEC("!syscalls:sys_enter_renameat") int sys_enter_renameat(struct syscall_enter_args *args) { -- cgit v1.2.3-59-g8ed1b From 5d2bd88975117062766a48b5f36ce31d2c1a8269 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 17 Jul 2019 19:53:51 -0300 Subject: perf trace: Forward error codes when trying to read syscall info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We iterate thru the syscall table produced from the kernel syscall tables reading info, propagate the error and add to the debug message. This helps in fixing further bugs, such as failing to read the "sendfile" syscall info when it really should try the aliasm "sendfile64". Problems reading syscall 40: 2 (No such file or directory)(sendfile) information # grep sendfile /tmp/build/perf/arch/x86/include/generated/asm/syscalls_64.c [40] = "sendfile", # I.e. in the tracefs format file for the syscall tracepoints we have it as sendfile64: # find /sys -type f -name format | grep sendfile /sys/kernel/debug/tracing/events/syscalls/sys_enter_sendfile64/format /sys/kernel/debug/tracing/events/syscalls/sys_exit_sendfile64/format # But as "sendfile" in the file used to build the syscall table used in perf: $ grep sendfile arch/x86/entry/syscalls/syscall_64.tbl 40 common sendfile __x64_sys_sendfile64 $ So we need to add, in followup patches, aliases in 'perf trace' syscall data structures to cope with thie. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-w3eluap63x9je0bb8o3t79tz@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index d403b09812d1..5dae7b172291 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1492,13 +1492,13 @@ static int trace__read_syscall_info(struct trace *trace, int id) const char *name = syscalltbl__name(trace->sctbl, id); if (name == NULL) - return -1; + return -EINVAL; if (id > trace->syscalls.max) { struct syscall *nsyscalls = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc)); if (nsyscalls == NULL) - return -1; + return -ENOMEM; if (trace->syscalls.max != -1) { memset(nsyscalls + trace->syscalls.max + 1, 0, @@ -1525,10 +1525,10 @@ static int trace__read_syscall_info(struct trace *trace, int id) } if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ? 6 : sc->tp_format->format.nr_fields)) - return -1; + return -ENOMEM; if (IS_ERR(sc->tp_format)) - return -1; + return PTR_ERR(sc->tp_format); sc->args = sc->tp_format->format.fields; /* @@ -1789,6 +1789,7 @@ typedef int (*tracepoint_handler)(struct trace *trace, struct perf_evsel *evsel, static struct syscall *trace__syscall_info(struct trace *trace, struct perf_evsel *evsel, int id) { + int err = 0; if (id < 0) { @@ -1811,9 +1812,10 @@ static struct syscall *trace__syscall_info(struct trace *trace, } if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL) && - trace__read_syscall_info(trace, id)) + (err = trace__read_syscall_info(trace, id)) != 0) goto out_cant_read; + err = -EINVAL; if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL)) goto out_cant_read; @@ -1821,7 +1823,8 @@ static struct syscall *trace__syscall_info(struct trace *trace, out_cant_read: if (verbose > 0) { - fprintf(trace->output, "Problems reading syscall %d", id); + char sbuf[STRERR_BUFSIZE]; + fprintf(trace->output, "Problems reading syscall %d: %d (%s)", id, -err, str_error_r(-err, sbuf, sizeof(sbuf))); if (id <= trace->syscalls.max && trace->syscalls.table[id].name != NULL) fprintf(trace->output, "(%s)", trace->syscalls.table[id].name); fputs(" information\n", trace->output); -- cgit v1.2.3-59-g8ed1b From b8b1033fcaa091d82289698d7179e84e28cbd92a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 17 Jul 2019 20:21:37 -0300 Subject: perf trace: Mark syscall ids that are not allocated to avoid unnecessary error messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are holes in syscall tables with IDs not associated with any syscall, mark those when trying to read information for syscalls, which could happen when iterating thru all syscalls from 0 to the highest numbered syscall id. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-cku9mpcrcsqaiq0jepu86r68@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 5dae7b172291..765b998755ce 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -976,6 +976,7 @@ static struct syscall_fmt *syscall_fmt__find_by_alias(const char *alias) * is_exit: is this "exit" or "exit_group"? * is_open: is this "open" or "openat"? To associate the fd returned in sys_exit with the pathname in sys_enter. * args_size: sum of the sizes of the syscall arguments, anything after that is augmented stuff: pathname for openat, etc. + * nonexistent: Just a hole in the syscall table, syscall id not allocated */ struct syscall { struct tep_event *tp_format; @@ -987,6 +988,7 @@ struct syscall { } bpf_prog; bool is_exit; bool is_open; + bool nonexistent; struct tep_format_field *args; const char *name; struct syscall_fmt *fmt; @@ -1491,9 +1493,6 @@ static int trace__read_syscall_info(struct trace *trace, int id) struct syscall *sc; const char *name = syscalltbl__name(trace->sctbl, id); - if (name == NULL) - return -EINVAL; - if (id > trace->syscalls.max) { struct syscall *nsyscalls = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc)); @@ -1512,8 +1511,15 @@ static int trace__read_syscall_info(struct trace *trace, int id) } sc = trace->syscalls.table + id; - sc->name = name; + if (sc->nonexistent) + return 0; + if (name == NULL) { + sc->nonexistent = true; + return 0; + } + + sc->name = name; sc->fmt = syscall_fmt__find(sc->name); snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->name); @@ -1811,14 +1817,21 @@ static struct syscall *trace__syscall_info(struct trace *trace, return NULL; } + err = -EINVAL; + if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL) && (err = trace__read_syscall_info(trace, id)) != 0) goto out_cant_read; - err = -EINVAL; - if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL)) + if (id > trace->syscalls.max) goto out_cant_read; + if (trace->syscalls.table[id].name == NULL) { + if (trace->syscalls.table[id].nonexistent) + return NULL; + goto out_cant_read; + } + return &trace->syscalls.table[id]; out_cant_read: -- cgit v1.2.3-59-g8ed1b From 30a910d7d3e04dd920e4ca3e8dcabf10c67fb03e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 18 Jul 2019 20:19:30 -0300 Subject: perf trace: Preallocate the syscall table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We'll continue reading its details from tracefs as we need it, but preallocate the whole thing otherwise we may realloc and end up with pointers to the previous buffer. I.e. in an upcoming algorithm we'll look for syscalls that have function signatures that are similar to a given syscall to see if we can reuse its BPF augmenter, so we may be at syscall 42, having a 'struct syscall' pointing to that slot in trace->syscalls.table[] and try to read the slot for an yet unread syscall, which would realloc that table to read the info for syscall 43, say, which would trigger a realoc of trace->syscalls.table[], and then the pointer we had for syscall 42 would be pointing to the previous block of memory. b00m. Cc: Adrian Hunter Cc: Brendan Gregg Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-m3cjzzifibs13imafhkk77a0@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 29 +++++++---------------------- tools/perf/util/syscalltbl.c | 1 + tools/perf/util/syscalltbl.h | 1 + 3 files changed, 9 insertions(+), 22 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 765b998755ce..d8565c9a18a2 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -79,7 +79,6 @@ struct trace { struct perf_tool tool; struct syscalltbl *sctbl; struct { - int max; struct syscall *table; struct bpf_map *map; struct { // per syscall BPF_MAP_TYPE_PROG_ARRAY @@ -1493,21 +1492,10 @@ static int trace__read_syscall_info(struct trace *trace, int id) struct syscall *sc; const char *name = syscalltbl__name(trace->sctbl, id); - if (id > trace->syscalls.max) { - struct syscall *nsyscalls = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc)); - - if (nsyscalls == NULL) + if (trace->syscalls.table == NULL) { + trace->syscalls.table = calloc(trace->sctbl->syscalls.nr_entries, sizeof(*sc)); + if (trace->syscalls.table == NULL) return -ENOMEM; - - if (trace->syscalls.max != -1) { - memset(nsyscalls + trace->syscalls.max + 1, 0, - (id - trace->syscalls.max) * sizeof(*sc)); - } else { - memset(nsyscalls, 0, (id + 1) * sizeof(*sc)); - } - - trace->syscalls.table = nsyscalls; - trace->syscalls.max = id; } sc = trace->syscalls.table + id; @@ -1819,11 +1807,11 @@ static struct syscall *trace__syscall_info(struct trace *trace, err = -EINVAL; - if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL) && - (err = trace__read_syscall_info(trace, id)) != 0) + if (id > trace->sctbl->syscalls.max_id) goto out_cant_read; - if (id > trace->syscalls.max) + if ((trace->syscalls.table == NULL || trace->syscalls.table[id].name == NULL) && + (err = trace__read_syscall_info(trace, id)) != 0) goto out_cant_read; if (trace->syscalls.table[id].name == NULL) { @@ -1838,7 +1826,7 @@ out_cant_read: if (verbose > 0) { char sbuf[STRERR_BUFSIZE]; fprintf(trace->output, "Problems reading syscall %d: %d (%s)", id, -err, str_error_r(-err, sbuf, sizeof(sbuf))); - if (id <= trace->syscalls.max && trace->syscalls.table[id].name != NULL) + if (id <= trace->sctbl->syscalls.max_id && trace->syscalls.table[id].name != NULL) fprintf(trace->output, "(%s)", trace->syscalls.table[id].name); fputs(" information\n", trace->output); } @@ -3922,9 +3910,6 @@ int cmd_trace(int argc, const char **argv) NULL }; struct trace trace = { - .syscalls = { - . max = -1, - }, .opts = { .target = { .uid = UINT_MAX, diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c index 022a9c670338..820fceeb19a9 100644 --- a/tools/perf/util/syscalltbl.c +++ b/tools/perf/util/syscalltbl.c @@ -79,6 +79,7 @@ static int syscalltbl__init_native(struct syscalltbl *tbl) qsort(tbl->syscalls.entries, nr_entries, sizeof(struct syscall), syscallcmp); tbl->syscalls.nr_entries = nr_entries; + tbl->syscalls.max_id = syscalltbl_native_max_id; return 0; } diff --git a/tools/perf/util/syscalltbl.h b/tools/perf/util/syscalltbl.h index c8e7e9ce0f01..9172613028d0 100644 --- a/tools/perf/util/syscalltbl.h +++ b/tools/perf/util/syscalltbl.h @@ -6,6 +6,7 @@ struct syscalltbl { union { int audit_machine; struct { + int max_id; int nr_entries; void *entries; } syscalls; -- cgit v1.2.3-59-g8ed1b From ad4153f964ebb756617e1586ba372156db0efeed Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 17 Jul 2019 18:27:33 -0300 Subject: perf trace: Reuse BPF augmenters from syscalls with similar args signature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have an augmenter for the "open" syscall, which has just one pointer, in the first argument, a "const char *", so any other syscall that has just one pointer and that is the first can reuse the "open" BPF augmenter program. Even more, syscalls that get two pointers with the first being a string can reuse "open"'s BPF augmenter till we have an augmenter that better matches that syscall with two pointers. With this the few augmenters we have, for open (first arg is a string), openat (2nd arg is a string), renameat (2nd and 4th are strings) can be reused by a lot of syscalls, ditto for "bind" reusing "connect" because both have the 2nd argument as a sockaddr and the 3rd as its len. Lets see how this makes the "bind" syscall reuse the "connect" BPF prog augmenter found in tools/perf/examples/bpf/augmented_raw_syscalls.c: # perf trace -e bind,connect systemctl restart sshd connect(3, { .family: PF_LOCAL, path: /run/systemd/private }, 23) = 0 # Oh, it just connects to some daemon, so we better do it system wide and then stop/start sshd: # perf trace -e bind,connect systemctl/10124 connect(3, { .family: PF_LOCAL, path: /run/systemd/private }, 23) = 0 sshd/10102 connect(7, { .family: PF_LOCAL, path: /dev/log }, 110) = 0 systemctl/10126 connect(3, { .family: PF_LOCAL, path: /run/systemd/private }, 23) = 0 systemd/10128 ... [continued]: connect()) = 0 (sshd)/10128 connect(3, { .family: PF_LOCAL, path: /run/systemd/journal/stdout }, 30) ... sshd/10128 bind(3, { .family: PF_NETLINK }, 12) = 0 sshd/10128 connect(4, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) sshd/10128 connect(3, { .family: PF_INET6, port: 22, addr: :: }, 28) = 0 sshd/10128 connect(3, { .family: PF_UNSPEC }, 16) = 0 sshd/10128 connect(3, { .family: PF_INET, port: 22, addr: 0.0.0.0 }, 16) = 0 sshd/10128 connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) sshd/10128 connect(3, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) sshd/10128 connect(5, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) sshd/10128 connect(5, { .family: PF_LOCAL, path: /var/run/nscd/socket }, 110) = -1 ENOENT (No such file or directory) sshd/10128 bind(4, { .family: PF_INET, port: 22, addr: 0.0.0.0 }, 16) = 0 sshd/10128 connect(6, { .family: PF_LOCAL, path: /dev/log }, 110) = 0 sshd/10128 bind(6, { .family: PF_INET6, port: 22, addr: :: }, 28) = 0 sshd/10128 connect(7, { .family: PF_LOCAL, path: /dev/log }, 110) = 0 ^C# Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-zfley2ghs4nim1uq4nu6ed3l@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 154 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 152 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index d8565c9a18a2..200fbe33d5de 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -709,7 +709,6 @@ static struct syscall_fmt { .arg = { [0] = { .scnprintf = SCA_X86_ARCH_PRCTL_CODE, /* code */ }, [1] = { .scnprintf = SCA_PTR, /* arg2 */ }, }, }, { .name = "bind", - .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_connect", }, .arg = { [0] = { .scnprintf = SCA_INT, /* fd */ }, [1] = { .scnprintf = SCA_SOCKADDR, /* umyaddr */ }, [2] = { .scnprintf = SCA_INT, /* addrlen */ }, }, }, @@ -879,7 +878,6 @@ static struct syscall_fmt { .arg = { [0] = { .scnprintf = SCA_FDAT, /* olddirfd */ }, [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ }, }, }, { .name = "renameat2", - .bpf_prog_name = { .sys_enter = "!syscalls:sys_enter_renameat", }, .arg = { [0] = { .scnprintf = SCA_FDAT, /* olddirfd */ }, [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ }, [4] = { .scnprintf = SCA_RENAMEAT2_FLAGS, /* flags */ }, }, }, @@ -2910,6 +2908,94 @@ static int trace__init_syscalls_bpf_map(struct trace *trace) return __trace__init_syscalls_bpf_map(trace, enabled); } +static struct bpf_program *trace__find_usable_bpf_prog_entry(struct trace *trace, struct syscall *sc) +{ + struct tep_format_field *field, *candidate_field; + int id; + + /* + * We're only interested in syscalls that have a pointer: + */ + for (field = sc->args; field; field = field->next) { + if (field->flags & TEP_FIELD_IS_POINTER) + goto try_to_find_pair; + } + + return NULL; + +try_to_find_pair: + for (id = 0; id < trace->sctbl->syscalls.nr_entries; ++id) { + struct syscall *pair = trace__syscall_info(trace, NULL, id); + struct bpf_program *pair_prog; + bool is_candidate = false; + + if (pair == NULL || pair == sc || + pair->bpf_prog.sys_enter == trace->syscalls.unaugmented_prog) + continue; + + for (field = sc->args, candidate_field = pair->args; + field && candidate_field; field = field->next, candidate_field = candidate_field->next) { + bool is_pointer = field->flags & TEP_FIELD_IS_POINTER, + candidate_is_pointer = candidate_field->flags & TEP_FIELD_IS_POINTER; + + if (is_pointer) { + if (!candidate_is_pointer) { + // The candidate just doesn't copies our pointer arg, might copy other pointers we want. + continue; + } + } else { + if (candidate_is_pointer) { + // The candidate might copy a pointer we don't have, skip it. + goto next_candidate; + } + continue; + } + + if (strcmp(field->type, candidate_field->type)) + goto next_candidate; + + is_candidate = true; + } + + if (!is_candidate) + goto next_candidate; + + /* + * Check if the tentative pair syscall augmenter has more pointers, if it has, + * then it may be collecting that and we then can't use it, as it would collect + * more than what is common to the two syscalls. + */ + if (candidate_field) { + for (candidate_field = candidate_field->next; candidate_field; candidate_field = candidate_field->next) + if (candidate_field->flags & TEP_FIELD_IS_POINTER) + goto next_candidate; + } + + pair_prog = pair->bpf_prog.sys_enter; + /* + * If the pair isn't enabled, then its bpf_prog.sys_enter will not + * have been searched for, so search it here and if it returns the + * unaugmented one, then ignore it, otherwise we'll reuse that BPF + * program for a filtered syscall on a non-filtered one. + * + * For instance, we have "!syscalls:sys_enter_renameat" and that is + * useful for "renameat2". + */ + if (pair_prog == NULL) { + pair_prog = trace__find_syscall_bpf_prog(trace, pair, pair->fmt ? pair->fmt->bpf_prog_name.sys_enter : NULL, "enter"); + if (pair_prog == trace->syscalls.unaugmented_prog) + goto next_candidate; + } + + pr_debug("Reusing \"%s\" BPF sys_enter augmenter for \"%s\"\n", pair->name, sc->name); + return pair_prog; + next_candidate: + continue; + } + + return NULL; +} + static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace) { int map_enter_fd = bpf_map__fd(trace->syscalls.prog_array.sys_enter), @@ -2935,6 +3021,70 @@ static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace) break; } + /* + * Now lets do a second pass looking for enabled syscalls without + * an augmenter that have a signature that is a superset of another + * syscall with an augmenter so that we can auto-reuse it. + * + * I.e. if we have an augmenter for the "open" syscall that has + * this signature: + * + * int open(const char *pathname, int flags, mode_t mode); + * + * I.e. that will collect just the first string argument, then we + * can reuse it for the 'creat' syscall, that has this signature: + * + * int creat(const char *pathname, mode_t mode); + * + * and for: + * + * int stat(const char *pathname, struct stat *statbuf); + * int lstat(const char *pathname, struct stat *statbuf); + * + * Because the 'open' augmenter will collect the first arg as a string, + * and leave alone all the other args, which already helps with + * beautifying 'stat' and 'lstat''s pathname arg. + * + * Then, in time, when 'stat' gets an augmenter that collects both + * first and second arg (this one on the raw_syscalls:sys_exit prog + * array tail call, then that one will be used. + */ + for (key = 0; key < trace->sctbl->syscalls.nr_entries; ++key) { + struct syscall *sc = trace__syscall_info(trace, NULL, key); + struct bpf_program *pair_prog; + int prog_fd; + + if (sc == NULL || sc->bpf_prog.sys_enter == NULL) + continue; + + /* + * For now we're just reusing the sys_enter prog, and if it + * already has an augmenter, we don't need to find one. + */ + if (sc->bpf_prog.sys_enter != trace->syscalls.unaugmented_prog) + continue; + + /* + * Look at all the other syscalls for one that has a signature + * that is close enough that we can share: + */ + pair_prog = trace__find_usable_bpf_prog_entry(trace, sc); + if (pair_prog == NULL) + continue; + + sc->bpf_prog.sys_enter = pair_prog; + + /* + * Update the BPF_MAP_TYPE_PROG_SHARED for raw_syscalls:sys_enter + * with the fd for the program we're reusing: + */ + prog_fd = bpf_program__fd(sc->bpf_prog.sys_enter); + err = bpf_map_update_elem(map_enter_fd, &key, &prog_fd, BPF_ANY); + if (err) + break; + } + + return err; } #else -- cgit v1.2.3-59-g8ed1b From e4b00e930bf71ef32189716e6cb6b0565592f078 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 17 Jul 2019 20:32:13 -0300 Subject: perf trace: Add "sendfile64" alias to the "sendfile" syscall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were looking in tracefs for: /sys/kernel/debug/tracing/events/syscalls/sys_enter_sendfile/format when what is there is just /sys/kernel/debug/tracing/events/syscalls/sys_enter_sendfile/format Its the same id, 40 in x86_64, so just add an alias and let the existing logic take care of that. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-km2hmg7hru6u4pawi5fi903q@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 200fbe33d5de..ca28c48f812e 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -895,6 +895,7 @@ static struct syscall_fmt { .arg = { [0] = { .scnprintf = SCA_SECCOMP_OP, /* op */ }, [1] = { .scnprintf = SCA_SECCOMP_FLAGS, /* flags */ }, }, }, { .name = "select", .timeout = true, }, + { .name = "sendfile", .alias = "sendfile64", }, { .name = "sendmmsg", .arg = { [3] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, { .name = "sendmsg", -- cgit v1.2.3-59-g8ed1b From df1d6856eaa7ec9ad1e670685b370f3e66326079 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:23:48 +0200 Subject: perf stat: Move loaded out of struct perf_counts_values Because we will make struct perf_counts_values public in following patches and 'loaded' is implementation related. No functional change is expected. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-2-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 4 ++-- tools/perf/util/counts.c | 11 +++++++++++ tools/perf/util/counts.h | 14 +++++++++++++- tools/perf/util/evsel.c | 3 ++- 4 files changed, 28 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 352cf39d7c2f..7b9c26f9cf34 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -287,7 +287,7 @@ static int read_counter(struct perf_evsel *counter, struct timespec *rs) * The leader's group read loads data into its group members * (via perf_evsel__read_counter) and sets threir count->loaded. */ - if (!count->loaded && + if (!perf_counts__is_loaded(counter->counts, cpu, thread) && read_single_counter(counter, cpu, thread, rs)) { counter->counts->scaled = -1; perf_counts(counter->counts, cpu, thread)->ena = 0; @@ -295,7 +295,7 @@ static int read_counter(struct perf_evsel *counter, struct timespec *rs) return -1; } - count->loaded = false; + perf_counts__set_loaded(counter->counts, cpu, thread, false); if (STAT_RECORD) { if (perf_evsel__write_stat_event(counter, cpu, thread, count)) { diff --git a/tools/perf/util/counts.c b/tools/perf/util/counts.c index 88be9c4365e0..01ee81df3fe5 100644 --- a/tools/perf/util/counts.c +++ b/tools/perf/util/counts.c @@ -19,6 +19,15 @@ struct perf_counts *perf_counts__new(int ncpus, int nthreads) } counts->values = values; + + values = xyarray__new(ncpus, nthreads, sizeof(bool)); + if (!values) { + xyarray__delete(counts->values); + free(counts); + return NULL; + } + + counts->loaded = values; } return counts; @@ -27,6 +36,7 @@ struct perf_counts *perf_counts__new(int ncpus, int nthreads) void perf_counts__delete(struct perf_counts *counts) { if (counts) { + xyarray__delete(counts->loaded); xyarray__delete(counts->values); free(counts); } @@ -34,6 +44,7 @@ void perf_counts__delete(struct perf_counts *counts) static void perf_counts__reset(struct perf_counts *counts) { + xyarray__reset(counts->loaded); xyarray__reset(counts->values); } diff --git a/tools/perf/util/counts.h b/tools/perf/util/counts.h index 0d1050ccc586..460b56ce3252 100644 --- a/tools/perf/util/counts.h +++ b/tools/perf/util/counts.h @@ -13,13 +13,13 @@ struct perf_counts_values { }; u64 values[3]; }; - bool loaded; }; struct perf_counts { s8 scaled; struct perf_counts_values aggr; struct xyarray *values; + struct xyarray *loaded; }; @@ -29,6 +29,18 @@ perf_counts(struct perf_counts *counts, int cpu, int thread) return xyarray__entry(counts->values, cpu, thread); } +static inline bool +perf_counts__is_loaded(struct perf_counts *counts, int cpu, int thread) +{ + return *((bool *) xyarray__entry(counts->loaded, cpu, thread)); +} + +static inline void +perf_counts__set_loaded(struct perf_counts *counts, int cpu, int thread, bool loaded) +{ + *((bool *) xyarray__entry(counts->loaded, cpu, thread)) = loaded; +} + struct perf_counts *perf_counts__new(int ncpus, int nthreads); void perf_counts__delete(struct perf_counts *counts); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 7d1757a2ec46..d23b9574f793 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1439,7 +1439,8 @@ perf_evsel__set_count(struct perf_evsel *counter, int cpu, int thread, count->val = val; count->ena = ena; count->run = run; - count->loaded = true; + + perf_counts__set_loaded(counter->counts, cpu, thread, true); } static int -- cgit v1.2.3-59-g8ed1b From f854839ba2a546a888159667c5ade96793e5cd10 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:23:49 +0200 Subject: perf cpu_map: Rename struct cpu_map to struct perf_cpu_map Rename struct cpu_map to struct perf_cpu_map, so it could be part of libperf. Committer notes: Added fixes for arm64, provided by Jiri. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-3-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 16 ++--- tools/perf/arch/arm64/util/header.c | 2 +- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/arch/x86/util/intel-bts.c | 2 +- tools/perf/arch/x86/util/intel-pt.c | 2 +- tools/perf/bench/epoll-ctl.c | 4 +- tools/perf/bench/epoll-wait.c | 4 +- tools/perf/bench/futex-hash.c | 2 +- tools/perf/bench/futex-lock-pi.c | 4 +- tools/perf/bench/futex-requeue.c | 4 +- tools/perf/bench/futex-wake-parallel.c | 4 +- tools/perf/bench/futex-wake.c | 4 +- tools/perf/builtin-c2c.c | 2 +- tools/perf/builtin-ftrace.c | 6 +- tools/perf/builtin-sched.c | 8 +-- tools/perf/builtin-script.c | 2 +- tools/perf/builtin-stat.c | 46 ++++++------- tools/perf/tests/bitmap.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/cpumap.c | 8 +-- tools/perf/tests/event-times.c | 4 +- tools/perf/tests/event_update.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mem2node.c | 2 +- tools/perf/tests/mmap-basic.c | 2 +- tools/perf/tests/openat-syscall-all-cpus.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/tests/topology.c | 4 +- tools/perf/util/cpumap.c | 78 +++++++++++----------- tools/perf/util/cpumap.h | 52 +++++++-------- tools/perf/util/cputopo.c | 4 +- tools/perf/util/env.h | 2 +- tools/perf/util/event.c | 18 ++--- tools/perf/util/event.h | 8 +-- tools/perf/util/evlist.c | 10 +-- tools/perf/util/evlist.h | 8 +-- tools/perf/util/evsel.c | 8 +-- tools/perf/util/evsel.h | 12 ++-- tools/perf/util/header.c | 4 +- tools/perf/util/mmap.c | 2 +- tools/perf/util/parse-events.c | 2 +- tools/perf/util/pmu.c | 10 +-- tools/perf/util/pmu.h | 2 +- tools/perf/util/python.c | 6 +- tools/perf/util/record.c | 6 +- .../util/scripting-engines/trace-event-python.c | 2 +- tools/perf/util/session.c | 2 +- tools/perf/util/stat.c | 2 +- tools/perf/util/stat.h | 6 +- tools/perf/util/svghelper.c | 2 +- 52 files changed, 198 insertions(+), 198 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 4208974c24f8..d08b55c27774 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -155,8 +155,8 @@ static int cs_etm_set_option(struct auxtrace_record *itr, struct perf_evsel *evsel, u32 option) { int i, err = -EINVAL; - struct cpu_map *event_cpus = evsel->evlist->cpus; - struct cpu_map *online_cpus = cpu_map__new(NULL); + struct perf_cpu_map *event_cpus = evsel->evlist->cpus; + struct perf_cpu_map *online_cpus = cpu_map__new(NULL); /* Set option of each CPU we have */ for (i = 0; i < cpu__max_cpu(); i++) { @@ -253,7 +253,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, container_of(itr, struct cs_etm_recording, itr); struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu; struct perf_evsel *evsel, *cs_etm_evsel = NULL; - struct cpu_map *cpus = evlist->cpus; + struct perf_cpu_map *cpus = evlist->cpus; bool privileged = (geteuid() == 0 || perf_event_paranoid() < 0); int err = 0; @@ -489,8 +489,8 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused, { int i; int etmv3 = 0, etmv4 = 0; - struct cpu_map *event_cpus = evlist->cpus; - struct cpu_map *online_cpus = cpu_map__new(NULL); + struct perf_cpu_map *event_cpus = evlist->cpus; + struct perf_cpu_map *online_cpus = cpu_map__new(NULL); /* cpu map is not empty, we have specific CPUs to work with */ if (!cpu_map__empty(event_cpus)) { @@ -635,9 +635,9 @@ static int cs_etm_info_fill(struct auxtrace_record *itr, int i; u32 offset; u64 nr_cpu, type; - struct cpu_map *cpu_map; - struct cpu_map *event_cpus = session->evlist->cpus; - struct cpu_map *online_cpus = cpu_map__new(NULL); + struct perf_cpu_map *cpu_map; + struct perf_cpu_map *event_cpus = session->evlist->cpus; + struct perf_cpu_map *online_cpus = cpu_map__new(NULL); struct cs_etm_recording *ptr = container_of(itr, struct cs_etm_recording, itr); struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu; diff --git a/tools/perf/arch/arm64/util/header.c b/tools/perf/arch/arm64/util/header.c index 534cd2507d83..b3e73a413f5a 100644 --- a/tools/perf/arch/arm64/util/header.c +++ b/tools/perf/arch/arm64/util/header.c @@ -16,7 +16,7 @@ char *get_cpuid_str(struct perf_pmu *pmu) const char *sysfs = sysfs__mountpoint(); int cpu; u64 midr = 0; - struct cpu_map *cpus; + struct perf_cpu_map *cpus; FILE *file; if (!sysfs || !pmu || !pmu->cpus) diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index 7a7721604b86..4676fd967dc6 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -50,7 +50,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe .sample_time = true, }; struct thread_map *threads = NULL; - struct cpu_map *cpus = NULL; + struct perf_cpu_map *cpus = NULL; struct perf_evlist *evlist = NULL; struct perf_evsel *evsel = NULL; int err = -1, ret, i; diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index ec5c1bb84095..da1583d27efd 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -106,7 +106,7 @@ static int intel_bts_recording_options(struct auxtrace_record *itr, container_of(itr, struct intel_bts_recording, itr); struct perf_pmu *intel_bts_pmu = btsr->intel_bts_pmu; struct perf_evsel *evsel, *intel_bts_evsel = NULL; - const struct cpu_map *cpus = evlist->cpus; + const struct perf_cpu_map *cpus = evlist->cpus; bool privileged = geteuid() == 0 || perf_event_paranoid() < 0; btsr->evlist = evlist; diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 609088c01e3a..69a23e40abc9 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -557,7 +557,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, struct perf_pmu *intel_pt_pmu = ptr->intel_pt_pmu; bool have_timing_info, need_immediate = false; struct perf_evsel *evsel, *intel_pt_evsel = NULL; - const struct cpu_map *cpus = evlist->cpus; + const struct perf_cpu_map *cpus = evlist->cpus; bool privileged = geteuid() == 0 || perf_event_paranoid() < 0; u64 tsc_bit; int err; diff --git a/tools/perf/bench/epoll-ctl.c b/tools/perf/bench/epoll-ctl.c index 2af067859966..1fd724f1d48b 100644 --- a/tools/perf/bench/epoll-ctl.c +++ b/tools/perf/bench/epoll-ctl.c @@ -219,7 +219,7 @@ static void init_fdmaps(struct worker *w, int pct) } } -static int do_threads(struct worker *worker, struct cpu_map *cpu) +static int do_threads(struct worker *worker, struct perf_cpu_map *cpu) { pthread_attr_t thread_attr, *attrp = NULL; cpu_set_t cpuset; @@ -301,7 +301,7 @@ int bench_epoll_ctl(int argc, const char **argv) int j, ret = 0; struct sigaction act; struct worker *worker = NULL; - struct cpu_map *cpu; + struct perf_cpu_map *cpu; struct rlimit rl, prevrl; unsigned int i; diff --git a/tools/perf/bench/epoll-wait.c b/tools/perf/bench/epoll-wait.c index fe85448abd45..79a254fff2d1 100644 --- a/tools/perf/bench/epoll-wait.c +++ b/tools/perf/bench/epoll-wait.c @@ -288,7 +288,7 @@ static void print_summary(void) (int) runtime.tv_sec); } -static int do_threads(struct worker *worker, struct cpu_map *cpu) +static int do_threads(struct worker *worker, struct perf_cpu_map *cpu) { pthread_attr_t thread_attr, *attrp = NULL; cpu_set_t cpuset; @@ -415,7 +415,7 @@ int bench_epoll_wait(int argc, const char **argv) struct sigaction act; unsigned int i; struct worker *worker = NULL; - struct cpu_map *cpu; + struct perf_cpu_map *cpu; pthread_t wthread; struct rlimit rl, prevrl; diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c index a80797763e1f..b4fea8e3a368 100644 --- a/tools/perf/bench/futex-hash.c +++ b/tools/perf/bench/futex-hash.c @@ -124,7 +124,7 @@ int bench_futex_hash(int argc, const char **argv) unsigned int i; pthread_attr_t thread_attr; struct worker *worker = NULL; - struct cpu_map *cpu; + struct perf_cpu_map *cpu; argc = parse_options(argc, argv, options, bench_futex_hash_usage, 0); if (argc) { diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c index d02330a69745..596769924709 100644 --- a/tools/perf/bench/futex-lock-pi.c +++ b/tools/perf/bench/futex-lock-pi.c @@ -116,7 +116,7 @@ static void *workerfn(void *arg) } static void create_threads(struct worker *w, pthread_attr_t thread_attr, - struct cpu_map *cpu) + struct perf_cpu_map *cpu) { cpu_set_t cpuset; unsigned int i; @@ -150,7 +150,7 @@ int bench_futex_lock_pi(int argc, const char **argv) unsigned int i; struct sigaction act; pthread_attr_t thread_attr; - struct cpu_map *cpu; + struct perf_cpu_map *cpu; argc = parse_options(argc, argv, options, bench_futex_lock_pi_usage, 0); if (argc) diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index fc692efa0c05..1fd32a4f9c14 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c @@ -84,7 +84,7 @@ static void *workerfn(void *arg __maybe_unused) } static void block_threads(pthread_t *w, - pthread_attr_t thread_attr, struct cpu_map *cpu) + pthread_attr_t thread_attr, struct perf_cpu_map *cpu) { cpu_set_t cpuset; unsigned int i; @@ -117,7 +117,7 @@ int bench_futex_requeue(int argc, const char **argv) unsigned int i, j; struct sigaction act; pthread_attr_t thread_attr; - struct cpu_map *cpu; + struct perf_cpu_map *cpu; argc = parse_options(argc, argv, options, bench_futex_requeue_usage, 0); if (argc) diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c index 69d8fdc87315..884c73e5bd1b 100644 --- a/tools/perf/bench/futex-wake-parallel.c +++ b/tools/perf/bench/futex-wake-parallel.c @@ -138,7 +138,7 @@ static void *blocked_workerfn(void *arg __maybe_unused) } static void block_threads(pthread_t *w, pthread_attr_t thread_attr, - struct cpu_map *cpu) + struct perf_cpu_map *cpu) { cpu_set_t cpuset; unsigned int i; @@ -224,7 +224,7 @@ int bench_futex_wake_parallel(int argc, const char **argv) struct sigaction act; pthread_attr_t thread_attr; struct thread_data *waking_worker; - struct cpu_map *cpu; + struct perf_cpu_map *cpu; argc = parse_options(argc, argv, options, bench_futex_wake_parallel_usage, 0); diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c index e8181ad7d088..2288fa8412ff 100644 --- a/tools/perf/bench/futex-wake.c +++ b/tools/perf/bench/futex-wake.c @@ -90,7 +90,7 @@ static void print_summary(void) } static void block_threads(pthread_t *w, - pthread_attr_t thread_attr, struct cpu_map *cpu) + pthread_attr_t thread_attr, struct perf_cpu_map *cpu) { cpu_set_t cpuset; unsigned int i; @@ -123,7 +123,7 @@ int bench_futex_wake(int argc, const char **argv) unsigned int i, j; struct sigaction act; pthread_attr_t thread_attr; - struct cpu_map *cpu; + struct perf_cpu_map *cpu; argc = parse_options(argc, argv, options, bench_futex_wake_usage, 0); if (argc) { diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index e3776f5c2e01..52035dacf253 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -2049,7 +2049,7 @@ static int setup_nodes(struct perf_session *session) c2c.cpu2node = cpu2node; for (node = 0; node < c2c.nodes_cnt; node++) { - struct cpu_map *map = n[node].map; + struct perf_cpu_map *map = n[node].map; unsigned long *set; set = bitmap_alloc(c2c.cpus_cnt); diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 66d5a6658daf..3e81e0b6628f 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -165,7 +165,7 @@ static int set_tracing_pid(struct perf_ftrace *ftrace) return 0; } -static int set_tracing_cpumask(struct cpu_map *cpumap) +static int set_tracing_cpumask(struct perf_cpu_map *cpumap) { char *cpumask; size_t mask_size; @@ -192,7 +192,7 @@ static int set_tracing_cpumask(struct cpu_map *cpumap) static int set_tracing_cpu(struct perf_ftrace *ftrace) { - struct cpu_map *cpumap = ftrace->evlist->cpus; + struct perf_cpu_map *cpumap = ftrace->evlist->cpus; if (!target__has_cpu(&ftrace->target)) return 0; @@ -202,7 +202,7 @@ static int set_tracing_cpu(struct perf_ftrace *ftrace) static int reset_tracing_cpu(void) { - struct cpu_map *cpumap = cpu_map__new(NULL); + struct perf_cpu_map *cpumap = cpu_map__new(NULL); int ret; ret = set_tracing_cpumask(cpumap); diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 56d1907b1215..51dd48f20972 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -161,9 +161,9 @@ struct perf_sched_map { bool comp; struct thread_map *color_pids; const char *color_pids_str; - struct cpu_map *color_cpus; + struct perf_cpu_map *color_cpus; const char *color_cpus_str; - struct cpu_map *cpus; + struct perf_cpu_map *cpus; const char *cpus_str; }; @@ -3170,7 +3170,7 @@ static int perf_sched__lat(struct perf_sched *sched) static int setup_map_cpus(struct perf_sched *sched) { - struct cpu_map *map; + struct perf_cpu_map *map; sched->max_cpu = sysconf(_SC_NPROCESSORS_CONF); @@ -3212,7 +3212,7 @@ static int setup_color_pids(struct perf_sched *sched) static int setup_color_cpus(struct perf_sched *sched) { - struct cpu_map *map; + struct perf_cpu_map *map; if (!sched->map.color_cpus_str) return 0; diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 0140ddb8dd0b..0109c8710b93 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1627,7 +1627,7 @@ struct perf_script { bool show_bpf_events; bool allocated; bool per_event_dump; - struct cpu_map *cpus; + struct perf_cpu_map *cpus; struct thread_map *threads; int name_width; const char *time_str; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 7b9c26f9cf34..d68738b5bd0c 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -164,7 +164,7 @@ struct perf_stat { u64 bytes_written; struct perf_tool tool; bool maps_allocated; - struct cpu_map *cpus; + struct perf_cpu_map *cpus; struct thread_map *threads; enum aggr_mode aggr_mode; }; @@ -803,24 +803,24 @@ static struct option stat_options[] = { }; static int perf_stat__get_socket(struct perf_stat_config *config __maybe_unused, - struct cpu_map *map, int cpu) + struct perf_cpu_map *map, int cpu) { return cpu_map__get_socket(map, cpu, NULL); } static int perf_stat__get_die(struct perf_stat_config *config __maybe_unused, - struct cpu_map *map, int cpu) + struct perf_cpu_map *map, int cpu) { return cpu_map__get_die(map, cpu, NULL); } static int perf_stat__get_core(struct perf_stat_config *config __maybe_unused, - struct cpu_map *map, int cpu) + struct perf_cpu_map *map, int cpu) { return cpu_map__get_core(map, cpu, NULL); } -static int cpu_map__get_max(struct cpu_map *map) +static int cpu_map__get_max(struct perf_cpu_map *map) { int i, max = -1; @@ -833,7 +833,7 @@ static int cpu_map__get_max(struct cpu_map *map) } static int perf_stat__get_aggr(struct perf_stat_config *config, - aggr_get_id_t get_id, struct cpu_map *map, int idx) + aggr_get_id_t get_id, struct perf_cpu_map *map, int idx) { int cpu; @@ -849,19 +849,19 @@ static int perf_stat__get_aggr(struct perf_stat_config *config, } static int perf_stat__get_socket_cached(struct perf_stat_config *config, - struct cpu_map *map, int idx) + struct perf_cpu_map *map, int idx) { return perf_stat__get_aggr(config, perf_stat__get_socket, map, idx); } static int perf_stat__get_die_cached(struct perf_stat_config *config, - struct cpu_map *map, int idx) + struct perf_cpu_map *map, int idx) { return perf_stat__get_aggr(config, perf_stat__get_die, map, idx); } static int perf_stat__get_core_cached(struct perf_stat_config *config, - struct cpu_map *map, int idx) + struct perf_cpu_map *map, int idx) { return perf_stat__get_aggr(config, perf_stat__get_core, map, idx); } @@ -939,7 +939,7 @@ static void perf_stat__exit_aggr_mode(void) stat_config.cpus_aggr_map = NULL; } -static inline int perf_env__get_cpu(struct perf_env *env, struct cpu_map *map, int idx) +static inline int perf_env__get_cpu(struct perf_env *env, struct perf_cpu_map *map, int idx) { int cpu; @@ -954,7 +954,7 @@ static inline int perf_env__get_cpu(struct perf_env *env, struct cpu_map *map, i return cpu; } -static int perf_env__get_socket(struct cpu_map *map, int idx, void *data) +static int perf_env__get_socket(struct perf_cpu_map *map, int idx, void *data) { struct perf_env *env = data; int cpu = perf_env__get_cpu(env, map, idx); @@ -962,7 +962,7 @@ static int perf_env__get_socket(struct cpu_map *map, int idx, void *data) return cpu == -1 ? -1 : env->cpu[cpu].socket_id; } -static int perf_env__get_die(struct cpu_map *map, int idx, void *data) +static int perf_env__get_die(struct perf_cpu_map *map, int idx, void *data) { struct perf_env *env = data; int die_id = -1, cpu = perf_env__get_cpu(env, map, idx); @@ -986,7 +986,7 @@ static int perf_env__get_die(struct cpu_map *map, int idx, void *data) return die_id; } -static int perf_env__get_core(struct cpu_map *map, int idx, void *data) +static int perf_env__get_core(struct perf_cpu_map *map, int idx, void *data) { struct perf_env *env = data; int core = -1, cpu = perf_env__get_cpu(env, map, idx); @@ -1016,37 +1016,37 @@ static int perf_env__get_core(struct cpu_map *map, int idx, void *data) return core; } -static int perf_env__build_socket_map(struct perf_env *env, struct cpu_map *cpus, - struct cpu_map **sockp) +static int perf_env__build_socket_map(struct perf_env *env, struct perf_cpu_map *cpus, + struct perf_cpu_map **sockp) { return cpu_map__build_map(cpus, sockp, perf_env__get_socket, env); } -static int perf_env__build_die_map(struct perf_env *env, struct cpu_map *cpus, - struct cpu_map **diep) +static int perf_env__build_die_map(struct perf_env *env, struct perf_cpu_map *cpus, + struct perf_cpu_map **diep) { return cpu_map__build_map(cpus, diep, perf_env__get_die, env); } -static int perf_env__build_core_map(struct perf_env *env, struct cpu_map *cpus, - struct cpu_map **corep) +static int perf_env__build_core_map(struct perf_env *env, struct perf_cpu_map *cpus, + struct perf_cpu_map **corep) { return cpu_map__build_map(cpus, corep, perf_env__get_core, env); } static int perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused, - struct cpu_map *map, int idx) + struct perf_cpu_map *map, int idx) { return perf_env__get_socket(map, idx, &perf_stat.session->header.env); } static int perf_stat__get_die_file(struct perf_stat_config *config __maybe_unused, - struct cpu_map *map, int idx) + struct perf_cpu_map *map, int idx) { return perf_env__get_die(map, idx, &perf_stat.session->header.env); } static int perf_stat__get_core_file(struct perf_stat_config *config __maybe_unused, - struct cpu_map *map, int idx) + struct perf_cpu_map *map, int idx) { return perf_env__get_core(map, idx, &perf_stat.session->header.env); } @@ -1551,7 +1551,7 @@ int process_cpu_map_event(struct perf_session *session, { struct perf_tool *tool = session->tool; struct perf_stat *st = container_of(tool, struct perf_stat, tool); - struct cpu_map *cpus; + struct perf_cpu_map *cpus; if (st->cpus) { pr_warning("Extra cpu map event, ignoring.\n"); diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c index 96e7fc1ad3f9..74d0cd32a5c4 100644 --- a/tools/perf/tests/bitmap.c +++ b/tools/perf/tests/bitmap.c @@ -9,7 +9,7 @@ static unsigned long *get_bitmap(const char *str, int nbits) { - struct cpu_map *map = cpu_map__new(str); + struct perf_cpu_map *map = cpu_map__new(str); unsigned long *bm = NULL; int i; diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index aa6df122b175..948ec278ad06 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -553,7 +553,7 @@ static int do_test_code_reading(bool try_kcore) .done_cnt = 0, }; struct thread_map *threads = NULL; - struct cpu_map *cpus = NULL; + struct perf_cpu_map *cpus = NULL; struct perf_evlist *evlist = NULL; struct perf_evsel *evsel = NULL; int err = -1, ret; diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index e78b897677bd..10da4400493d 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -17,7 +17,7 @@ static int process_event_mask(struct perf_tool *tool __maybe_unused, struct cpu_map_event *map_event = &event->cpu_map; struct cpu_map_mask *mask; struct cpu_map_data *data; - struct cpu_map *map; + struct perf_cpu_map *map; int i; data = &map_event->data; @@ -51,7 +51,7 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused, struct cpu_map_event *map_event = &event->cpu_map; struct cpu_map_entries *cpus; struct cpu_map_data *data; - struct cpu_map *map; + struct perf_cpu_map *map; data = &map_event->data; @@ -75,7 +75,7 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused, int test__cpu_map_synthesize(struct test *test __maybe_unused, int subtest __maybe_unused) { - struct cpu_map *cpus; + struct perf_cpu_map *cpus; /* This one is better stores in mask. */ cpus = cpu_map__new("0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19"); @@ -97,7 +97,7 @@ int test__cpu_map_synthesize(struct test *test __maybe_unused, int subtest __may static int cpu_map_print(const char *str) { - struct cpu_map *map = cpu_map__new(str); + struct perf_cpu_map *map = cpu_map__new(str); char buf[100]; if (!map) diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 1a2686f1fcf0..ed90b62bf048 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -110,7 +110,7 @@ static int detach__disable(struct perf_evlist *evlist) static int attach__cpu_disabled(struct perf_evlist *evlist) { struct perf_evsel *evsel = perf_evlist__last(evlist); - struct cpu_map *cpus; + struct perf_cpu_map *cpus; int err; pr_debug("attaching to CPU 0 as enabled\n"); @@ -139,7 +139,7 @@ static int attach__cpu_disabled(struct perf_evlist *evlist) static int attach__cpu_enabled(struct perf_evlist *evlist) { struct perf_evsel *evsel = perf_evlist__last(evlist); - struct cpu_map *cpus; + struct perf_cpu_map *cpus; int err; pr_debug("attaching to CPU 0 as enabled\n"); diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index f14dcd613438..b5042f019ec4 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -61,7 +61,7 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused, { struct event_update_event *ev = (struct event_update_event*) event; struct event_update_event_cpus *ev_data; - struct cpu_map *map; + struct perf_cpu_map *map; ev_data = (struct event_update_event_cpus*) ev->data; diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 17c46f3e6f1e..68331a81bcdd 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -66,7 +66,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un }, }; struct thread_map *threads = NULL; - struct cpu_map *cpus = NULL; + struct perf_cpu_map *cpus = NULL; struct perf_evlist *evlist = NULL; struct perf_evsel *evsel = NULL; int found, err = -1; diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c index 520cc91af256..e12eedfba781 100644 --- a/tools/perf/tests/mem2node.c +++ b/tools/perf/tests/mem2node.c @@ -19,7 +19,7 @@ static struct node { static unsigned long *get_bitmap(const char *str, int nbits) { - struct cpu_map *map = cpu_map__new(str); + struct perf_cpu_map *map = cpu_map__new(str); unsigned long *bm = NULL; int i; diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 0919b0793e5b..1bc8fd3ea510 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -28,7 +28,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse int err = -1; union perf_event *event; struct thread_map *threads; - struct cpu_map *cpus; + struct perf_cpu_map *cpus; struct perf_evlist *evlist; cpu_set_t cpu_set; const char *syscall_names[] = { "getsid", "getppid", "getpgid", }; diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index 493ecb611540..f393aa836dfb 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -20,7 +20,7 @@ int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = -1, fd, cpu; - struct cpu_map *cpus; + struct perf_cpu_map *cpus; struct perf_evsel *evsel; unsigned int nr_openat_calls = 111, i; cpu_set_t cpu_set; diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index f9490b237893..d9121b5033b7 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -37,7 +37,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) .disabled = 1, .freq = 1, }; - struct cpu_map *cpus; + struct perf_cpu_map *cpus; struct thread_map *threads; struct perf_mmap *md; diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 6cdab5f4812a..826f20a4cb51 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -328,7 +328,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ }, }; struct thread_map *threads = NULL; - struct cpu_map *cpus = NULL; + struct perf_cpu_map *cpus = NULL; struct perf_evlist *evlist = NULL; struct perf_evsel *evsel, *cpu_clocks_evsel, *cycles_evsel; struct perf_evsel *switch_evsel, *tracking_evsel; diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index e92fa6029ac7..d66767be4c45 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -45,7 +45,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused }; const char *argv[] = { "true", NULL }; char sbuf[STRERR_BUFSIZE]; - struct cpu_map *cpus; + struct perf_cpu_map *cpus; struct thread_map *threads; struct perf_mmap *md; diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index 9497d02f69e6..443d0272ebbd 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -57,7 +57,7 @@ static int session_write_header(char *path) return 0; } -static int check_cpu_topology(char *path, struct cpu_map *map) +static int check_cpu_topology(char *path, struct perf_cpu_map *map) { struct perf_session *session; struct perf_data data = { @@ -116,7 +116,7 @@ static int check_cpu_topology(char *path, struct cpu_map *map) int test__session_topology(struct test *test __maybe_unused, int subtest __maybe_unused) { char path[PATH_MAX]; - struct cpu_map *map; + struct perf_cpu_map *map; int ret = TEST_FAIL; TEST_ASSERT_VAL("can't get templ file", !get_temp(path)); diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 3acfbe34ebaf..5eb4e1fbb877 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -17,9 +17,9 @@ static int max_present_cpu_num; static int max_node_num; static int *cpunode_map; -static struct cpu_map *cpu_map__default_new(void) +static struct perf_cpu_map *cpu_map__default_new(void) { - struct cpu_map *cpus; + struct perf_cpu_map *cpus; int nr_cpus; nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); @@ -39,10 +39,10 @@ static struct cpu_map *cpu_map__default_new(void) return cpus; } -static struct cpu_map *cpu_map__trim_new(int nr_cpus, int *tmp_cpus) +static struct perf_cpu_map *cpu_map__trim_new(int nr_cpus, int *tmp_cpus) { size_t payload_size = nr_cpus * sizeof(int); - struct cpu_map *cpus = malloc(sizeof(*cpus) + payload_size); + struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + payload_size); if (cpus != NULL) { cpus->nr = nr_cpus; @@ -53,9 +53,9 @@ static struct cpu_map *cpu_map__trim_new(int nr_cpus, int *tmp_cpus) return cpus; } -struct cpu_map *cpu_map__read(FILE *file) +struct perf_cpu_map *cpu_map__read(FILE *file) { - struct cpu_map *cpus = NULL; + struct perf_cpu_map *cpus = NULL; int nr_cpus = 0; int *tmp_cpus = NULL, *tmp; int max_entries = 0; @@ -108,9 +108,9 @@ out_free_tmp: return cpus; } -static struct cpu_map *cpu_map__read_all_cpu_map(void) +static struct perf_cpu_map *cpu_map__read_all_cpu_map(void) { - struct cpu_map *cpus = NULL; + struct perf_cpu_map *cpus = NULL; FILE *onlnf; onlnf = fopen("/sys/devices/system/cpu/online", "r"); @@ -122,9 +122,9 @@ static struct cpu_map *cpu_map__read_all_cpu_map(void) return cpus; } -struct cpu_map *cpu_map__new(const char *cpu_list) +struct perf_cpu_map *cpu_map__new(const char *cpu_list) { - struct cpu_map *cpus = NULL; + struct perf_cpu_map *cpus = NULL; unsigned long start_cpu, end_cpu = 0; char *p = NULL; int i, nr_cpus = 0; @@ -196,9 +196,9 @@ out: return cpus; } -static struct cpu_map *cpu_map__from_entries(struct cpu_map_entries *cpus) +static struct perf_cpu_map *cpu_map__from_entries(struct cpu_map_entries *cpus) { - struct cpu_map *map; + struct perf_cpu_map *map; map = cpu_map__empty_new(cpus->nr); if (map) { @@ -220,9 +220,9 @@ static struct cpu_map *cpu_map__from_entries(struct cpu_map_entries *cpus) return map; } -static struct cpu_map *cpu_map__from_mask(struct cpu_map_mask *mask) +static struct perf_cpu_map *cpu_map__from_mask(struct cpu_map_mask *mask) { - struct cpu_map *map; + struct perf_cpu_map *map; int nr, nbits = mask->nr * mask->long_size * BITS_PER_BYTE; nr = bitmap_weight(mask->mask, nbits); @@ -238,7 +238,7 @@ static struct cpu_map *cpu_map__from_mask(struct cpu_map_mask *mask) } -struct cpu_map *cpu_map__new_data(struct cpu_map_data *data) +struct perf_cpu_map *cpu_map__new_data(struct cpu_map_data *data) { if (data->type == PERF_CPU_MAP__CPUS) return cpu_map__from_entries((struct cpu_map_entries *)data->data); @@ -246,7 +246,7 @@ struct cpu_map *cpu_map__new_data(struct cpu_map_data *data) return cpu_map__from_mask((struct cpu_map_mask *)data->data); } -size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp) +size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp) { #define BUFSIZE 1024 char buf[BUFSIZE]; @@ -256,9 +256,9 @@ size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp) #undef BUFSIZE } -struct cpu_map *cpu_map__dummy_new(void) +struct perf_cpu_map *cpu_map__dummy_new(void) { - struct cpu_map *cpus = malloc(sizeof(*cpus) + sizeof(int)); + struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + sizeof(int)); if (cpus != NULL) { cpus->nr = 1; @@ -269,9 +269,9 @@ struct cpu_map *cpu_map__dummy_new(void) return cpus; } -struct cpu_map *cpu_map__empty_new(int nr) +struct perf_cpu_map *cpu_map__empty_new(int nr) { - struct cpu_map *cpus = malloc(sizeof(*cpus) + sizeof(int) * nr); + struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + sizeof(int) * nr); if (cpus != NULL) { int i; @@ -286,7 +286,7 @@ struct cpu_map *cpu_map__empty_new(int nr) return cpus; } -static void cpu_map__delete(struct cpu_map *map) +static void cpu_map__delete(struct perf_cpu_map *map) { if (map) { WARN_ONCE(refcount_read(&map->refcnt) != 0, @@ -295,14 +295,14 @@ static void cpu_map__delete(struct cpu_map *map) } } -struct cpu_map *cpu_map__get(struct cpu_map *map) +struct perf_cpu_map *cpu_map__get(struct perf_cpu_map *map) { if (map) refcount_inc(&map->refcnt); return map; } -void cpu_map__put(struct cpu_map *map) +void cpu_map__put(struct perf_cpu_map *map) { if (map && refcount_dec_and_test(&map->refcnt)) cpu_map__delete(map); @@ -324,7 +324,7 @@ int cpu_map__get_socket_id(int cpu) return ret ?: value; } -int cpu_map__get_socket(struct cpu_map *map, int idx, void *data __maybe_unused) +int cpu_map__get_socket(struct perf_cpu_map *map, int idx, void *data __maybe_unused) { int cpu; @@ -341,11 +341,11 @@ static int cmp_ids(const void *a, const void *b) return *(int *)a - *(int *)b; } -int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res, - int (*f)(struct cpu_map *map, int cpu, void *data), +int cpu_map__build_map(struct perf_cpu_map *cpus, struct perf_cpu_map **res, + int (*f)(struct perf_cpu_map *map, int cpu, void *data), void *data) { - struct cpu_map *c; + struct perf_cpu_map *c; int nr = cpus->nr; int cpu, s1, s2; @@ -380,7 +380,7 @@ int cpu_map__get_die_id(int cpu) return ret ?: value; } -int cpu_map__get_die(struct cpu_map *map, int idx, void *data) +int cpu_map__get_die(struct perf_cpu_map *map, int idx, void *data) { int cpu, die_id, s; @@ -419,7 +419,7 @@ int cpu_map__get_core_id(int cpu) return ret ?: value; } -int cpu_map__get_core(struct cpu_map *map, int idx, void *data) +int cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data) { int cpu, s_die; @@ -448,17 +448,17 @@ int cpu_map__get_core(struct cpu_map *map, int idx, void *data) return (s_die << 16) | (cpu & 0xffff); } -int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp) +int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct perf_cpu_map **sockp) { return cpu_map__build_map(cpus, sockp, cpu_map__get_socket, NULL); } -int cpu_map__build_die_map(struct cpu_map *cpus, struct cpu_map **diep) +int cpu_map__build_die_map(struct perf_cpu_map *cpus, struct perf_cpu_map **diep) { return cpu_map__build_map(cpus, diep, cpu_map__get_die, NULL); } -int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep) +int cpu_map__build_core_map(struct perf_cpu_map *cpus, struct perf_cpu_map **corep) { return cpu_map__build_map(cpus, corep, cpu_map__get_core, NULL); } @@ -670,12 +670,12 @@ int cpu__setup_cpunode_map(void) return 0; } -bool cpu_map__has(struct cpu_map *cpus, int cpu) +bool cpu_map__has(struct perf_cpu_map *cpus, int cpu) { return cpu_map__idx(cpus, cpu) != -1; } -int cpu_map__idx(struct cpu_map *cpus, int cpu) +int cpu_map__idx(struct perf_cpu_map *cpus, int cpu) { int i; @@ -687,12 +687,12 @@ int cpu_map__idx(struct cpu_map *cpus, int cpu) return -1; } -int cpu_map__cpu(struct cpu_map *cpus, int idx) +int cpu_map__cpu(struct perf_cpu_map *cpus, int idx) { return cpus->map[idx]; } -size_t cpu_map__snprint(struct cpu_map *map, char *buf, size_t size) +size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size) { int i, cpu, start = -1; bool first = true; @@ -744,7 +744,7 @@ static char hex_char(unsigned char val) return '?'; } -size_t cpu_map__snprint_mask(struct cpu_map *map, char *buf, size_t size) +size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size) { int i, cpu; char *ptr = buf; @@ -781,9 +781,9 @@ size_t cpu_map__snprint_mask(struct cpu_map *map, char *buf, size_t size) return ptr - buf; } -const struct cpu_map *cpu_map__online(void) /* thread unsafe */ +const struct perf_cpu_map *cpu_map__online(void) /* thread unsafe */ { - static const struct cpu_map *online = NULL; + static const struct perf_cpu_map *online = NULL; if (!online) online = cpu_map__new(NULL); /* from /sys/devices/system/cpu/online */ diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index 1265f0e33920..22729beae959 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -9,35 +9,35 @@ #include "perf.h" #include "util/debug.h" -struct cpu_map { +struct perf_cpu_map { refcount_t refcnt; int nr; int map[]; }; -struct cpu_map *cpu_map__new(const char *cpu_list); -struct cpu_map *cpu_map__empty_new(int nr); -struct cpu_map *cpu_map__dummy_new(void); -struct cpu_map *cpu_map__new_data(struct cpu_map_data *data); -struct cpu_map *cpu_map__read(FILE *file); -size_t cpu_map__snprint(struct cpu_map *map, char *buf, size_t size); -size_t cpu_map__snprint_mask(struct cpu_map *map, char *buf, size_t size); -size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp); +struct perf_cpu_map *cpu_map__new(const char *cpu_list); +struct perf_cpu_map *cpu_map__empty_new(int nr); +struct perf_cpu_map *cpu_map__dummy_new(void); +struct perf_cpu_map *cpu_map__new_data(struct cpu_map_data *data); +struct perf_cpu_map *cpu_map__read(FILE *file); +size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size); +size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size); +size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp); int cpu_map__get_socket_id(int cpu); -int cpu_map__get_socket(struct cpu_map *map, int idx, void *data); +int cpu_map__get_socket(struct perf_cpu_map *map, int idx, void *data); int cpu_map__get_die_id(int cpu); -int cpu_map__get_die(struct cpu_map *map, int idx, void *data); +int cpu_map__get_die(struct perf_cpu_map *map, int idx, void *data); int cpu_map__get_core_id(int cpu); -int cpu_map__get_core(struct cpu_map *map, int idx, void *data); -int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp); -int cpu_map__build_die_map(struct cpu_map *cpus, struct cpu_map **diep); -int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep); -const struct cpu_map *cpu_map__online(void); /* thread unsafe */ +int cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data); +int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct perf_cpu_map **sockp); +int cpu_map__build_die_map(struct perf_cpu_map *cpus, struct perf_cpu_map **diep); +int cpu_map__build_core_map(struct perf_cpu_map *cpus, struct perf_cpu_map **corep); +const struct perf_cpu_map *cpu_map__online(void); /* thread unsafe */ -struct cpu_map *cpu_map__get(struct cpu_map *map); -void cpu_map__put(struct cpu_map *map); +struct perf_cpu_map *cpu_map__get(struct perf_cpu_map *map); +void cpu_map__put(struct perf_cpu_map *map); -static inline int cpu_map__socket(struct cpu_map *sock, int s) +static inline int cpu_map__socket(struct perf_cpu_map *sock, int s) { if (!sock || s > sock->nr || s < 0) return 0; @@ -59,12 +59,12 @@ static inline int cpu_map__id_to_cpu(int id) return id & 0xffff; } -static inline int cpu_map__nr(const struct cpu_map *map) +static inline int cpu_map__nr(const struct perf_cpu_map *map) { return map ? map->nr : 1; } -static inline bool cpu_map__empty(const struct cpu_map *map) +static inline bool cpu_map__empty(const struct perf_cpu_map *map) { return map ? map->map[0] == -1 : true; } @@ -76,11 +76,11 @@ int cpu__max_cpu(void); int cpu__max_present_cpu(void); int cpu__get_node(int cpu); -int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res, - int (*f)(struct cpu_map *map, int cpu, void *data), +int cpu_map__build_map(struct perf_cpu_map *cpus, struct perf_cpu_map **res, + int (*f)(struct perf_cpu_map *map, int cpu, void *data), void *data); -int cpu_map__cpu(struct cpu_map *cpus, int idx); -bool cpu_map__has(struct cpu_map *cpus, int cpu); -int cpu_map__idx(struct cpu_map *cpus, int cpu); +int cpu_map__cpu(struct perf_cpu_map *cpus, int idx); +bool cpu_map__has(struct perf_cpu_map *cpus, int cpu); +int cpu_map__idx(struct perf_cpu_map *cpus, int cpu); #endif /* __PERF_CPUMAP_H */ diff --git a/tools/perf/util/cputopo.c b/tools/perf/util/cputopo.c index 64336a280967..157b0988435e 100644 --- a/tools/perf/util/cputopo.c +++ b/tools/perf/util/cputopo.c @@ -176,7 +176,7 @@ struct cpu_topology *cpu_topology__new(void) size_t sz; long ncpus; int ret = -1; - struct cpu_map *map; + struct perf_cpu_map *map; bool has_die = has_die_topology(); ncpus = cpu__max_present_cpu(); @@ -289,7 +289,7 @@ err: struct numa_topology *numa_topology__new(void) { - struct cpu_map *node_map = NULL; + struct perf_cpu_map *node_map = NULL; struct numa_topology *tp = NULL; char path[MAXPATHLEN]; char *buf = NULL; diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h index d5d9865aa812..d8e083d42610 100644 --- a/tools/perf/util/env.h +++ b/tools/perf/util/env.h @@ -27,7 +27,7 @@ struct numa_node { u32 node; u64 mem_total; u64 mem_free; - struct cpu_map *map; + struct perf_cpu_map *map; }; struct memory_node { diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index f1f4848947ce..406ad8772907 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1008,7 +1008,7 @@ int perf_event__synthesize_thread_map2(struct perf_tool *tool, } static void synthesize_cpus(struct cpu_map_entries *cpus, - struct cpu_map *map) + struct perf_cpu_map *map) { int i; @@ -1019,7 +1019,7 @@ static void synthesize_cpus(struct cpu_map_entries *cpus, } static void synthesize_mask(struct cpu_map_mask *mask, - struct cpu_map *map, int max) + struct perf_cpu_map *map, int max) { int i; @@ -1030,12 +1030,12 @@ static void synthesize_mask(struct cpu_map_mask *mask, set_bit(map->map[i], mask->mask); } -static size_t cpus_size(struct cpu_map *map) +static size_t cpus_size(struct perf_cpu_map *map) { return sizeof(struct cpu_map_entries) + map->nr * sizeof(u16); } -static size_t mask_size(struct cpu_map *map, int *max) +static size_t mask_size(struct perf_cpu_map *map, int *max) { int i; @@ -1052,7 +1052,7 @@ static size_t mask_size(struct cpu_map *map, int *max) return sizeof(struct cpu_map_mask) + BITS_TO_LONGS(*max) * sizeof(long); } -void *cpu_map_data__alloc(struct cpu_map *map, size_t *size, u16 *type, int *max) +void *cpu_map_data__alloc(struct perf_cpu_map *map, size_t *size, u16 *type, int *max) { size_t size_cpus, size_mask; bool is_dummy = cpu_map__empty(map); @@ -1086,7 +1086,7 @@ void *cpu_map_data__alloc(struct cpu_map *map, size_t *size, u16 *type, int *max return zalloc(*size); } -void cpu_map_data__synthesize(struct cpu_map_data *data, struct cpu_map *map, +void cpu_map_data__synthesize(struct cpu_map_data *data, struct perf_cpu_map *map, u16 type, int max) { data->type = type; @@ -1102,7 +1102,7 @@ void cpu_map_data__synthesize(struct cpu_map_data *data, struct cpu_map *map, }; } -static struct cpu_map_event* cpu_map_event__new(struct cpu_map *map) +static struct cpu_map_event* cpu_map_event__new(struct perf_cpu_map *map) { size_t size = sizeof(struct cpu_map_event); struct cpu_map_event *event; @@ -1122,7 +1122,7 @@ static struct cpu_map_event* cpu_map_event__new(struct cpu_map *map) } int perf_event__synthesize_cpu_map(struct perf_tool *tool, - struct cpu_map *map, + struct perf_cpu_map *map, perf_event__handler_t process, struct machine *machine) { @@ -1393,7 +1393,7 @@ size_t perf_event__fprintf_thread_map(union perf_event *event, FILE *fp) size_t perf_event__fprintf_cpu_map(union perf_event *event, FILE *fp) { - struct cpu_map *cpus = cpu_map__new_data(&event->cpu_map.data); + struct perf_cpu_map *cpus = cpu_map__new_data(&event->cpu_map.data); size_t ret; ret = fprintf(fp, ": "); diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 1f1da6082806..cafaac5128ab 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -675,7 +675,7 @@ void perf_event__print_totals(void); struct perf_tool; struct thread_map; -struct cpu_map; +struct perf_cpu_map; struct perf_stat_config; struct perf_counts_values; @@ -693,7 +693,7 @@ int perf_event__synthesize_thread_map2(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine); int perf_event__synthesize_cpu_map(struct perf_tool *tool, - struct cpu_map *cpus, + struct perf_cpu_map *cpus, perf_event__handler_t process, struct machine *machine); int perf_event__synthesize_threads(struct perf_tool *tool, @@ -844,8 +844,8 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp); int kallsyms__get_function_start(const char *kallsyms_filename, const char *symbol_name, u64 *addr); -void *cpu_map_data__alloc(struct cpu_map *map, size_t *size, u16 *type, int *max); -void cpu_map_data__synthesize(struct cpu_map_data *data, struct cpu_map *map, +void *cpu_map_data__alloc(struct perf_cpu_map *map, size_t *size, u16 *type, int *max); +void cpu_map_data__synthesize(struct cpu_map_data *data, struct perf_cpu_map *map, u16 type, int max); void event_attr_init(struct perf_event_attr *attr); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index b0364d923f76..bce883eaf0dc 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -41,7 +41,7 @@ int sigqueue(pid_t pid, int sig, const union sigval value); #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) #define SID(e, x, y) xyarray__entry(e->sample_id, x, y) -void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus, +void perf_evlist__init(struct perf_evlist *evlist, struct perf_cpu_map *cpus, struct thread_map *threads) { int i; @@ -1012,7 +1012,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, int comp_level) { struct perf_evsel *evsel; - const struct cpu_map *cpus = evlist->cpus; + const struct perf_cpu_map *cpus = evlist->cpus; const struct thread_map *threads = evlist->threads; /* * Delay setting mp.prot: set it before calling perf_mmap__mmap. @@ -1058,7 +1058,7 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages) int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) { bool all_threads = (target->per_thread && target->system_wide); - struct cpu_map *cpus; + struct perf_cpu_map *cpus; struct thread_map *threads; /* @@ -1104,7 +1104,7 @@ out_delete_threads: return -1; } -void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, +void perf_evlist__set_maps(struct perf_evlist *evlist, struct perf_cpu_map *cpus, struct thread_map *threads) { /* @@ -1358,7 +1358,7 @@ void perf_evlist__close(struct perf_evlist *evlist) static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist) { - struct cpu_map *cpus; + struct perf_cpu_map *cpus; struct thread_map *threads; int err = -ENOMEM; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 49354fe24d5f..c8cda300b584 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -18,7 +18,7 @@ struct pollfd; struct thread_map; -struct cpu_map; +struct perf_cpu_map; struct record_opts; #define PERF_EVLIST__HLIST_BITS 8 @@ -45,7 +45,7 @@ struct perf_evlist { struct perf_mmap *mmap; struct perf_mmap *overwrite_mmap; struct thread_map *threads; - struct cpu_map *cpus; + struct perf_cpu_map *cpus; struct perf_evsel *selected; struct events_stats stats; struct perf_env *env; @@ -68,7 +68,7 @@ struct perf_evsel_str_handler { struct perf_evlist *perf_evlist__new(void); struct perf_evlist *perf_evlist__new_default(void); struct perf_evlist *perf_evlist__new_dummy(void); -void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus, +void perf_evlist__init(struct perf_evlist *evlist, struct perf_cpu_map *cpus, struct thread_map *threads); void perf_evlist__exit(struct perf_evlist *evlist); void perf_evlist__delete(struct perf_evlist *evlist); @@ -194,7 +194,7 @@ int perf_evlist__enable_event_idx(struct perf_evlist *evlist, void perf_evlist__set_selected(struct perf_evlist *evlist, struct perf_evsel *evsel); -void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, +void perf_evlist__set_maps(struct perf_evlist *evlist, struct perf_cpu_map *cpus, struct thread_map *threads); int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target); int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index d23b9574f793..958206c538c3 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1825,7 +1825,7 @@ static int perf_event_open(struct perf_evsel *evsel, return fd; } -int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, +int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus, struct thread_map *threads) { int cpu, thread, nthreads; @@ -1837,7 +1837,7 @@ int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, return -EINVAL; if (cpus == NULL) { - static struct cpu_map *empty_cpu_map; + static struct perf_cpu_map *empty_cpu_map; if (empty_cpu_map == NULL) { empty_cpu_map = cpu_map__dummy_new(); @@ -2084,7 +2084,7 @@ void perf_evsel__close(struct perf_evsel *evsel) } int perf_evsel__open_per_cpu(struct perf_evsel *evsel, - struct cpu_map *cpus) + struct perf_cpu_map *cpus) { return perf_evsel__open(evsel, cpus, NULL); } @@ -3064,7 +3064,7 @@ static int store_evsel_ids(struct perf_evsel *evsel, struct perf_evlist *evlist) int perf_evsel__store_ids(struct perf_evsel *evsel, struct perf_evlist *evlist) { - struct cpu_map *cpus = evsel->cpus; + struct perf_cpu_map *cpus = evsel->cpus; struct thread_map *threads = evsel->threads; if (perf_evsel__alloc_id(evsel, cpus->nr, threads->nr)) diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index b27935a6d36c..76b14037f260 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -124,8 +124,8 @@ struct perf_evsel { u64 db_id; struct cgroup *cgrp; void *handler; - struct cpu_map *cpus; - struct cpu_map *own_cpus; + struct perf_cpu_map *cpus; + struct perf_cpu_map *own_cpus; struct thread_map *threads; unsigned int sample_size; int id_pos; @@ -192,12 +192,12 @@ struct perf_missing_features { extern struct perf_missing_features perf_missing_features; -struct cpu_map; +struct perf_cpu_map; struct target; struct thread_map; struct record_opts; -static inline struct cpu_map *perf_evsel__cpus(struct perf_evsel *evsel) +static inline struct perf_cpu_map *perf_evsel__cpus(struct perf_evsel *evsel) { return evsel->cpus; } @@ -300,10 +300,10 @@ int perf_evsel__enable(struct perf_evsel *evsel); int perf_evsel__disable(struct perf_evsel *evsel); int perf_evsel__open_per_cpu(struct perf_evsel *evsel, - struct cpu_map *cpus); + struct perf_cpu_map *cpus); int perf_evsel__open_per_thread(struct perf_evsel *evsel, struct thread_map *threads); -int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, +int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus, struct thread_map *threads); void perf_evsel__close(struct perf_evsel *evsel); diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 1903d7ec9797..4be216f3598b 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -3886,7 +3886,7 @@ size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp) struct event_update_event *ev = &event->event_update; struct event_update_event_scale *ev_scale; struct event_update_event_cpus *ev_cpus; - struct cpu_map *map; + struct perf_cpu_map *map; size_t ret; ret = fprintf(fp, "\n... id: %" PRIu64 "\n", ev->id); @@ -4054,7 +4054,7 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused, struct event_update_event_cpus *ev_cpus; struct perf_evlist *evlist; struct perf_evsel *evsel; - struct cpu_map *map; + struct perf_cpu_map *map; if (!pevlist || *pevlist == NULL) return -EINVAL; diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 9f0b6391af33..177c41fc9842 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -325,7 +325,7 @@ void perf_mmap__munmap(struct perf_mmap *map) static void build_node_mask(int node, cpu_set_t *mask) { int c, cpu, nr_cpus; - const struct cpu_map *cpu_map = NULL; + const struct perf_cpu_map *cpu_map = NULL; cpu_map = cpu_map__online(); if (!cpu_map) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 0540303e5e97..077509609d03 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -322,7 +322,7 @@ __add_event(struct list_head *list, int *idx, const char *cpu_list) { struct perf_evsel *evsel; - struct cpu_map *cpus = pmu ? pmu->cpus : + struct perf_cpu_map *cpus = pmu ? pmu->cpus : cpu_list ? cpu_map__new(cpu_list) : NULL; event_attr_init(attr); diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index f32b710347db..4929a50c0973 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -572,10 +572,10 @@ static void pmu_read_sysfs(void) closedir(dir); } -static struct cpu_map *__pmu_cpumask(const char *path) +static struct perf_cpu_map *__pmu_cpumask(const char *path) { FILE *file; - struct cpu_map *cpus; + struct perf_cpu_map *cpus; file = fopen(path, "r"); if (!file) @@ -593,10 +593,10 @@ static struct cpu_map *__pmu_cpumask(const char *path) #define CPUS_TEMPLATE_UNCORE "%s/bus/event_source/devices/%s/cpumask" #define CPUS_TEMPLATE_CPU "%s/bus/event_source/devices/%s/cpus" -static struct cpu_map *pmu_cpumask(const char *name) +static struct perf_cpu_map *pmu_cpumask(const char *name) { char path[PATH_MAX]; - struct cpu_map *cpus; + struct perf_cpu_map *cpus; const char *sysfs = sysfs__mountpoint(); const char *templates[] = { CPUS_TEMPLATE_UNCORE, @@ -621,7 +621,7 @@ static struct cpu_map *pmu_cpumask(const char *name) static bool pmu_is_uncore(const char *name) { char path[PATH_MAX]; - struct cpu_map *cpus; + struct perf_cpu_map *cpus; const char *sysfs = sysfs__mountpoint(); snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name); diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index bd9ec2704a57..3f8b79b1dd85 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -28,7 +28,7 @@ struct perf_pmu { bool is_uncore; int max_precise; struct perf_event_attr *default_config; - struct cpu_map *cpus; + struct perf_cpu_map *cpus; struct list_head format; /* HEAD struct perf_pmu_format -> list */ struct list_head aliases; /* HEAD struct perf_pmu_alias -> list */ struct list_head list; /* ELEM */ diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 1e5b6718dcea..be27956ae080 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -536,7 +536,7 @@ static PyObject *pyrf_event__new(union perf_event *event) struct pyrf_cpu_map { PyObject_HEAD - struct cpu_map *cpus; + struct perf_cpu_map *cpus; }; static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus, @@ -796,7 +796,7 @@ static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel, PyObject *args, PyObject *kwargs) { struct perf_evsel *evsel = &pevsel->evsel; - struct cpu_map *cpus = NULL; + struct perf_cpu_map *cpus = NULL; struct thread_map *threads = NULL; PyObject *pcpus = NULL, *pthreads = NULL; int group = 0, inherit = 0; @@ -865,7 +865,7 @@ static int pyrf_evlist__init(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs __maybe_unused) { PyObject *pcpus = NULL, *pthreads = NULL; - struct cpu_map *cpus; + struct perf_cpu_map *cpus; struct thread_map *threads; if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads)) diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 9cfc7bf16531..051c67f82548 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -60,7 +60,7 @@ out_delete: static bool perf_probe_api(setup_probe_fn_t fn) { const char *try[] = {"cycles:u", "instructions:u", "cpu-clock:u", NULL}; - struct cpu_map *cpus; + struct perf_cpu_map *cpus; int cpu, ret, i = 0; cpus = cpu_map__new(NULL); @@ -115,7 +115,7 @@ bool perf_can_record_cpu_wide(void) .config = PERF_COUNT_SW_CPU_CLOCK, .exclude_kernel = 1, }; - struct cpu_map *cpus; + struct perf_cpu_map *cpus; int cpu, fd; cpus = cpu_map__new(NULL); @@ -275,7 +275,7 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str) evsel = perf_evlist__last(temp_evlist); if (!evlist || cpu_map__empty(evlist->cpus)) { - struct cpu_map *cpus = cpu_map__new(NULL); + struct perf_cpu_map *cpus = cpu_map__new(NULL); cpu = cpus ? cpus->map[0] : 0; cpu_map__put(cpus); diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 25dc1d765553..a53b30b8819b 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -1393,7 +1393,7 @@ static void python_process_stat(struct perf_stat_config *config, struct perf_evsel *counter, u64 tstamp) { struct thread_map *threads = counter->threads; - struct cpu_map *cpus = counter->cpus; + struct perf_cpu_map *cpus = counter->cpus; int cpu, thread; if (config->aggr_mode == AGGR_GLOBAL) { diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 37efa1f43d8b..69d1d158a610 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -2273,7 +2273,7 @@ int perf_session__cpu_bitmap(struct perf_session *session, const char *cpu_list, unsigned long *cpu_bitmap) { int i, err = -1; - struct cpu_map *map; + struct perf_cpu_map *map; for (i = 0; i < PERF_TYPE_MAX; ++i) { struct perf_evsel *evsel; diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index db8a6cf336be..62791c063f7a 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -215,7 +215,7 @@ static int check_per_pkg(struct perf_evsel *counter, struct perf_counts_values *vals, int cpu, bool *skip) { unsigned long *mask = counter->per_pkg_mask; - struct cpu_map *cpus = perf_evsel__cpus(counter); + struct perf_cpu_map *cpus = perf_evsel__cpus(counter); int s; *skip = false; diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 7032dd1eeac2..fa675d09febd 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -92,7 +92,7 @@ struct runtime_stat { }; typedef int (*aggr_get_id_t)(struct perf_stat_config *config, - struct cpu_map *m, int cpu); + struct perf_cpu_map *m, int cpu); struct perf_stat_config { enum aggr_mode aggr_mode; @@ -122,9 +122,9 @@ struct perf_stat_config { const char *csv_sep; struct stats *walltime_nsecs_stats; struct rusage ru_data; - struct cpu_map *aggr_map; + struct perf_cpu_map *aggr_map; aggr_get_id_t aggr_get_id; - struct cpu_map *cpus_aggr_map; + struct perf_cpu_map *cpus_aggr_map; u64 *walltime_run; struct rblist metric_events; }; diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index 76cc54000483..99132c6a30a6 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c @@ -728,7 +728,7 @@ static int str_to_bitmap(char *s, cpumask_t *b) { int i; int ret = 0; - struct cpu_map *m; + struct perf_cpu_map *m; int c; m = cpu_map__new(s); -- cgit v1.2.3-59-g8ed1b From 9749b90e566ca1a235fc8e2118f99c5690969342 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:23:50 +0200 Subject: perf tools: Rename struct thread_map to struct perf_thread_map Rename struct thread_map to struct perf_thread_map, so it could be part of libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-4-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-sched.c | 4 +- tools/perf/builtin-script.c | 2 +- tools/perf/builtin-stat.c | 4 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/event-times.c | 4 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c | 2 +- tools/perf/tests/mmap-thread-lookup.c | 2 +- tools/perf/tests/openat-syscall-all-cpus.c | 2 +- tools/perf/tests/openat-syscall.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/tests/thread-map.c | 8 +-- tools/perf/util/event.c | 6 +-- tools/perf/util/event.h | 6 +-- tools/perf/util/evlist.c | 10 ++-- tools/perf/util/evlist.h | 6 +-- tools/perf/util/evsel.c | 10 ++-- tools/perf/util/evsel.h | 6 +-- tools/perf/util/machine.c | 2 +- tools/perf/util/machine.h | 4 +- tools/perf/util/parse-events.c | 2 +- tools/perf/util/python.c | 6 +-- .../util/scripting-engines/trace-event-python.c | 2 +- tools/perf/util/thread_map.c | 60 +++++++++++----------- tools/perf/util/thread_map.h | 40 +++++++-------- 29 files changed, 102 insertions(+), 102 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index 4676fd967dc6..f542b878bdb5 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -49,7 +49,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe }, .sample_time = true, }; - struct thread_map *threads = NULL; + struct perf_thread_map *threads = NULL; struct perf_cpu_map *cpus = NULL; struct perf_evlist *evlist = NULL; struct perf_evsel *evsel = NULL; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 8779cee58185..bcfc16450608 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1047,7 +1047,7 @@ record__finish_output(struct record *rec) static int record__synthesize_workload(struct record *rec, bool tail) { int err; - struct thread_map *thread_map; + struct perf_thread_map *thread_map; if (rec->opts.tail_synthesize != tail) return 0; diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 51dd48f20972..ac6a0c5d6d6b 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -159,7 +159,7 @@ struct perf_sched_map { DECLARE_BITMAP(comp_cpus_mask, MAX_CPUS); int *comp_cpus; bool comp; - struct thread_map *color_pids; + struct perf_thread_map *color_pids; const char *color_pids_str; struct perf_cpu_map *color_cpus; const char *color_cpus_str; @@ -3195,7 +3195,7 @@ static int setup_map_cpus(struct perf_sched *sched) static int setup_color_pids(struct perf_sched *sched) { - struct thread_map *map; + struct perf_thread_map *map; if (!sched->map.color_pids_str) return 0; diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 0109c8710b93..fccc960df92b 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1628,7 +1628,7 @@ struct perf_script { bool allocated; bool per_event_dump; struct perf_cpu_map *cpus; - struct thread_map *threads; + struct perf_thread_map *threads; int name_width; const char *time_str; struct perf_time_interval *ptime_range; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index d68738b5bd0c..2b9518a38baf 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -165,7 +165,7 @@ struct perf_stat { struct perf_tool tool; bool maps_allocated; struct perf_cpu_map *cpus; - struct thread_map *threads; + struct perf_thread_map *threads; enum aggr_mode aggr_mode; }; @@ -395,7 +395,7 @@ static bool perf_evsel__should_store_id(struct perf_evsel *counter) } static bool is_target_alive(struct target *_target, - struct thread_map *threads) + struct perf_thread_map *threads) { struct stat st; int i; diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 948ec278ad06..88c218eacc43 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -552,7 +552,7 @@ static int do_test_code_reading(bool try_kcore) struct state state = { .done_cnt = 0, }; - struct thread_map *threads = NULL; + struct perf_thread_map *threads = NULL; struct perf_cpu_map *cpus = NULL; struct perf_evlist *evlist = NULL; struct perf_evsel *evsel = NULL; diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index ed90b62bf048..684ad56f7b0f 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -57,7 +57,7 @@ static int detach__enable_on_exec(struct perf_evlist *evlist) static int attach__current_disabled(struct perf_evlist *evlist) { struct perf_evsel *evsel = perf_evlist__last(evlist); - struct thread_map *threads; + struct perf_thread_map *threads; int err; pr_debug("attaching to current thread as disabled\n"); @@ -83,7 +83,7 @@ static int attach__current_disabled(struct perf_evlist *evlist) static int attach__current_enabled(struct perf_evlist *evlist) { struct perf_evsel *evsel = perf_evlist__last(evlist); - struct thread_map *threads; + struct perf_thread_map *threads; int err; pr_debug("attaching to current thread as enabled\n"); diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 68331a81bcdd..e1e5e32cbb53 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -65,7 +65,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un .uses_mmap = true, }, }; - struct thread_map *threads = NULL; + struct perf_thread_map *threads = NULL; struct perf_cpu_map *cpus = NULL; struct perf_evlist *evlist = NULL; struct perf_evsel *evsel = NULL; diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 1bc8fd3ea510..c1e2fe087b67 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -27,7 +27,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse { int err = -1; union perf_event *event; - struct thread_map *threads; + struct perf_thread_map *threads; struct perf_cpu_map *cpus; struct perf_evlist *evlist; cpu_set_t cpu_set; diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c index 0a4301a5155c..ad6ca943e568 100644 --- a/tools/perf/tests/mmap-thread-lookup.c +++ b/tools/perf/tests/mmap-thread-lookup.c @@ -138,7 +138,7 @@ static int synth_all(struct machine *machine) static int synth_process(struct machine *machine) { - struct thread_map *map; + struct perf_thread_map *map; int err; map = thread_map__new_by_pid(getpid()); diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index f393aa836dfb..9cd5bf63bec1 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -24,7 +24,7 @@ int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int struct perf_evsel *evsel; unsigned int nr_openat_calls = 111, i; cpu_set_t cpu_set; - struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX); + struct perf_thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX); char sbuf[STRERR_BUFSIZE]; char errbuf[BUFSIZ]; diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c index 00cd63f90b92..652b8328ca93 100644 --- a/tools/perf/tests/openat-syscall.c +++ b/tools/perf/tests/openat-syscall.c @@ -16,7 +16,7 @@ int test__openat_syscall_event(struct test *test __maybe_unused, int subtest __m int err = -1, fd; struct perf_evsel *evsel; unsigned int nr_openat_calls = 111, i; - struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX); + struct perf_thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX); char sbuf[STRERR_BUFSIZE]; char errbuf[BUFSIZ]; diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index d9121b5033b7..d57b8d9c1575 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -38,7 +38,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) .freq = 1, }; struct perf_cpu_map *cpus; - struct thread_map *threads; + struct perf_thread_map *threads; struct perf_mmap *md; attr.sample_freq = 500; diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 826f20a4cb51..3652c548cc22 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -327,7 +327,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ .uses_mmap = true, }, }; - struct thread_map *threads = NULL; + struct perf_thread_map *threads = NULL; struct perf_cpu_map *cpus = NULL; struct perf_evlist *evlist = NULL; struct perf_evsel *evsel, *cpu_clocks_evsel, *cycles_evsel; diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index d66767be4c45..9602ff91a3c7 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -46,7 +46,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused const char *argv[] = { "true", NULL }; char sbuf[STRERR_BUFSIZE]; struct perf_cpu_map *cpus; - struct thread_map *threads; + struct perf_thread_map *threads; struct perf_mmap *md; signal(SIGCHLD, sig_handler); diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c index ccc17aced49e..367dfe708e4c 100644 --- a/tools/perf/tests/thread-map.c +++ b/tools/perf/tests/thread-map.c @@ -13,7 +13,7 @@ int test__thread_map(struct test *test __maybe_unused, int subtest __maybe_unused) { - struct thread_map *map; + struct perf_thread_map *map; TEST_ASSERT_VAL("failed to set process name", !prctl(PR_SET_NAME, NAMEUL, 0, 0, 0)); @@ -57,7 +57,7 @@ static int process_event(struct perf_tool *tool __maybe_unused, struct machine *machine __maybe_unused) { struct thread_map_event *map = &event->thread_map; - struct thread_map *threads; + struct perf_thread_map *threads; TEST_ASSERT_VAL("wrong nr", map->nr == 1); TEST_ASSERT_VAL("wrong pid", map->entries[0].pid == (u64) getpid()); @@ -80,7 +80,7 @@ static int process_event(struct perf_tool *tool __maybe_unused, int test__thread_map_synthesize(struct test *test __maybe_unused, int subtest __maybe_unused) { - struct thread_map *threads; + struct perf_thread_map *threads; TEST_ASSERT_VAL("failed to set process name", !prctl(PR_SET_NAME, NAMEUL, 0, 0, 0)); @@ -99,7 +99,7 @@ int test__thread_map_synthesize(struct test *test __maybe_unused, int subtest __ int test__thread_map_remove(struct test *test __maybe_unused, int subtest __maybe_unused) { - struct thread_map *threads; + struct perf_thread_map *threads; char *str; int i; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 406ad8772907..f78837788b14 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -616,7 +616,7 @@ static int __event__synthesize_thread(union perf_event *comm_event, } int perf_event__synthesize_thread_map(struct perf_tool *tool, - struct thread_map *threads, + struct perf_thread_map *threads, perf_event__handler_t process, struct machine *machine, bool mmap_data) @@ -972,7 +972,7 @@ int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, } int perf_event__synthesize_thread_map2(struct perf_tool *tool, - struct thread_map *threads, + struct perf_thread_map *threads, perf_event__handler_t process, struct machine *machine) { @@ -1377,7 +1377,7 @@ size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp) size_t perf_event__fprintf_thread_map(union perf_event *event, FILE *fp) { - struct thread_map *threads = thread_map__new_event(&event->thread_map); + struct perf_thread_map *threads = thread_map__new_event(&event->thread_map); size_t ret; ret = fprintf(fp, " nr: "); diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index cafaac5128ab..70841d115349 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -674,7 +674,7 @@ union perf_event { void perf_event__print_totals(void); struct perf_tool; -struct thread_map; +struct perf_thread_map; struct perf_cpu_map; struct perf_stat_config; struct perf_counts_values; @@ -685,11 +685,11 @@ typedef int (*perf_event__handler_t)(struct perf_tool *tool, struct machine *machine); int perf_event__synthesize_thread_map(struct perf_tool *tool, - struct thread_map *threads, + struct perf_thread_map *threads, perf_event__handler_t process, struct machine *machine, bool mmap_data); int perf_event__synthesize_thread_map2(struct perf_tool *tool, - struct thread_map *threads, + struct perf_thread_map *threads, perf_event__handler_t process, struct machine *machine); int perf_event__synthesize_cpu_map(struct perf_tool *tool, diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index bce883eaf0dc..a95d0461f718 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -42,7 +42,7 @@ int sigqueue(pid_t pid, int sig, const union sigval value); #define SID(e, x, y) xyarray__entry(e->sample_id, x, y) void perf_evlist__init(struct perf_evlist *evlist, struct perf_cpu_map *cpus, - struct thread_map *threads) + struct perf_thread_map *threads) { int i; @@ -1013,7 +1013,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, { struct perf_evsel *evsel; const struct perf_cpu_map *cpus = evlist->cpus; - const struct thread_map *threads = evlist->threads; + const struct perf_thread_map *threads = evlist->threads; /* * Delay setting mp.prot: set it before calling perf_mmap__mmap. * Its value is decided by evsel's write_backward. @@ -1059,7 +1059,7 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) { bool all_threads = (target->per_thread && target->system_wide); struct perf_cpu_map *cpus; - struct thread_map *threads; + struct perf_thread_map *threads; /* * If specify '-a' and '--per-thread' to perf record, perf record @@ -1105,7 +1105,7 @@ out_delete_threads: } void perf_evlist__set_maps(struct perf_evlist *evlist, struct perf_cpu_map *cpus, - struct thread_map *threads) + struct perf_thread_map *threads) { /* * Allow for the possibility that one or another of the maps isn't being @@ -1359,7 +1359,7 @@ void perf_evlist__close(struct perf_evlist *evlist) static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist) { struct perf_cpu_map *cpus; - struct thread_map *threads; + struct perf_thread_map *threads; int err = -ENOMEM; /* diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index c8cda300b584..ab2f0b6c7640 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -44,7 +44,7 @@ struct perf_evlist { struct fdarray pollfd; struct perf_mmap *mmap; struct perf_mmap *overwrite_mmap; - struct thread_map *threads; + struct perf_thread_map *threads; struct perf_cpu_map *cpus; struct perf_evsel *selected; struct events_stats stats; @@ -69,7 +69,7 @@ struct perf_evlist *perf_evlist__new(void); struct perf_evlist *perf_evlist__new_default(void); struct perf_evlist *perf_evlist__new_dummy(void); void perf_evlist__init(struct perf_evlist *evlist, struct perf_cpu_map *cpus, - struct thread_map *threads); + struct perf_thread_map *threads); void perf_evlist__exit(struct perf_evlist *evlist); void perf_evlist__delete(struct perf_evlist *evlist); @@ -195,7 +195,7 @@ void perf_evlist__set_selected(struct perf_evlist *evlist, struct perf_evsel *evsel); void perf_evlist__set_maps(struct perf_evlist *evlist, struct perf_cpu_map *cpus, - struct thread_map *threads); + struct perf_thread_map *threads); int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target); int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 958206c538c3..ab66d65b7968 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1743,7 +1743,7 @@ static int update_fds(struct perf_evsel *evsel, static bool ignore_missing_thread(struct perf_evsel *evsel, int nr_cpus, int cpu, - struct thread_map *threads, + struct perf_thread_map *threads, int thread, int err) { pid_t ignore_pid = thread_map__pid(threads, thread); @@ -1826,7 +1826,7 @@ static int perf_event_open(struct perf_evsel *evsel, } int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus, - struct thread_map *threads) + struct perf_thread_map *threads) { int cpu, thread, nthreads; unsigned long flags = PERF_FLAG_FD_CLOEXEC; @@ -1849,7 +1849,7 @@ int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus, } if (threads == NULL) { - static struct thread_map *empty_thread_map; + static struct perf_thread_map *empty_thread_map; if (empty_thread_map == NULL) { empty_thread_map = thread_map__new_by_tid(-1); @@ -2090,7 +2090,7 @@ int perf_evsel__open_per_cpu(struct perf_evsel *evsel, } int perf_evsel__open_per_thread(struct perf_evsel *evsel, - struct thread_map *threads) + struct perf_thread_map *threads) { return perf_evsel__open(evsel, NULL, threads); } @@ -3065,7 +3065,7 @@ static int store_evsel_ids(struct perf_evsel *evsel, struct perf_evlist *evlist) int perf_evsel__store_ids(struct perf_evsel *evsel, struct perf_evlist *evlist) { struct perf_cpu_map *cpus = evsel->cpus; - struct thread_map *threads = evsel->threads; + struct perf_thread_map *threads = evsel->threads; if (perf_evsel__alloc_id(evsel, cpus->nr, threads->nr)) return -ENOMEM; diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 76b14037f260..ba2385f22e28 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -126,7 +126,7 @@ struct perf_evsel { void *handler; struct perf_cpu_map *cpus; struct perf_cpu_map *own_cpus; - struct thread_map *threads; + struct perf_thread_map *threads; unsigned int sample_size; int id_pos; int is_pos; @@ -302,9 +302,9 @@ int perf_evsel__disable(struct perf_evsel *evsel); int perf_evsel__open_per_cpu(struct perf_evsel *evsel, struct perf_cpu_map *cpus); int perf_evsel__open_per_thread(struct perf_evsel *evsel, - struct thread_map *threads); + struct perf_thread_map *threads); int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus, - struct thread_map *threads); + struct perf_thread_map *threads); void perf_evsel__close(struct perf_evsel *evsel); struct perf_sample; diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index cf826eca3aaf..a2359a33c748 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -2599,7 +2599,7 @@ int machines__for_each_thread(struct machines *machines, } int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, - struct target *target, struct thread_map *threads, + struct target *target, struct perf_thread_map *threads, perf_event__handler_t process, bool data_mmap, unsigned int nr_threads_synthesize) { diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index f70ab98a7bde..7f64016758e0 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -251,12 +251,12 @@ int machines__for_each_thread(struct machines *machines, void *priv); int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, - struct target *target, struct thread_map *threads, + struct target *target, struct perf_thread_map *threads, perf_event__handler_t process, bool data_mmap, unsigned int nr_threads_synthesize); static inline int machine__synthesize_threads(struct machine *machine, struct target *target, - struct thread_map *threads, bool data_mmap, + struct perf_thread_map *threads, bool data_mmap, unsigned int nr_threads_synthesize) { return __machine__synthesize_threads(machine, NULL, target, threads, diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 077509609d03..352c5198b453 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -2313,7 +2313,7 @@ static bool is_event_supported(u8 type, unsigned config) .config = config, .disabled = 1, }; - struct thread_map *tmap = thread_map__new_by_tid(0); + struct perf_thread_map *tmap = thread_map__new_by_tid(0); if (tmap == NULL) return false; diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index be27956ae080..62dda70227e5 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -605,7 +605,7 @@ static int pyrf_cpu_map__setup_types(void) struct pyrf_thread_map { PyObject_HEAD - struct thread_map *threads; + struct perf_thread_map *threads; }; static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads, @@ -797,7 +797,7 @@ static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel, { struct perf_evsel *evsel = &pevsel->evsel; struct perf_cpu_map *cpus = NULL; - struct thread_map *threads = NULL; + struct perf_thread_map *threads = NULL; PyObject *pcpus = NULL, *pthreads = NULL; int group = 0, inherit = 0; static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL }; @@ -866,7 +866,7 @@ static int pyrf_evlist__init(struct pyrf_evlist *pevlist, { PyObject *pcpus = NULL, *pthreads = NULL; struct perf_cpu_map *cpus; - struct thread_map *threads; + struct perf_thread_map *threads; if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads)) return -1; diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index a53b30b8819b..0a7e662036b4 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -1392,7 +1392,7 @@ process_stat(struct perf_evsel *counter, int cpu, int thread, u64 tstamp, static void python_process_stat(struct perf_stat_config *config, struct perf_evsel *counter, u64 tstamp) { - struct thread_map *threads = counter->threads; + struct perf_thread_map *threads = counter->threads; struct perf_cpu_map *cpus = counter->cpus; int cpu, thread; diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index 5b3511f2b6b1..e89496c39d58 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c @@ -28,7 +28,7 @@ static int filter(const struct dirent *dir) return 1; } -static void thread_map__reset(struct thread_map *map, int start, int nr) +static void thread_map__reset(struct perf_thread_map *map, int start, int nr) { size_t size = (nr - start) * sizeof(map->map[0]); @@ -36,7 +36,7 @@ static void thread_map__reset(struct thread_map *map, int start, int nr) map->err_thread = -1; } -static struct thread_map *thread_map__realloc(struct thread_map *map, int nr) +static struct perf_thread_map *thread_map__realloc(struct perf_thread_map *map, int nr) { size_t size = sizeof(*map) + sizeof(map->map[0]) * nr; int start = map ? map->nr : 0; @@ -53,9 +53,9 @@ static struct thread_map *thread_map__realloc(struct thread_map *map, int nr) #define thread_map__alloc(__nr) thread_map__realloc(NULL, __nr) -struct thread_map *thread_map__new_by_pid(pid_t pid) +struct perf_thread_map *thread_map__new_by_pid(pid_t pid) { - struct thread_map *threads; + struct perf_thread_map *threads; char name[256]; int items; struct dirent **namelist = NULL; @@ -81,9 +81,9 @@ struct thread_map *thread_map__new_by_pid(pid_t pid) return threads; } -struct thread_map *thread_map__new_by_tid(pid_t tid) +struct perf_thread_map *thread_map__new_by_tid(pid_t tid) { - struct thread_map *threads = thread_map__alloc(1); + struct perf_thread_map *threads = thread_map__alloc(1); if (threads != NULL) { thread_map__set_pid(threads, 0, tid); @@ -94,13 +94,13 @@ struct thread_map *thread_map__new_by_tid(pid_t tid) return threads; } -static struct thread_map *__thread_map__new_all_cpus(uid_t uid) +static struct perf_thread_map *__thread_map__new_all_cpus(uid_t uid) { DIR *proc; int max_threads = 32, items, i; char path[NAME_MAX + 1 + 6]; struct dirent *dirent, **namelist = NULL; - struct thread_map *threads = thread_map__alloc(max_threads); + struct perf_thread_map *threads = thread_map__alloc(max_threads); if (threads == NULL) goto out; @@ -140,7 +140,7 @@ static struct thread_map *__thread_map__new_all_cpus(uid_t uid) } if (grow) { - struct thread_map *tmp; + struct perf_thread_map *tmp; tmp = thread_map__realloc(threads, max_threads); if (tmp == NULL) @@ -180,17 +180,17 @@ out_free_closedir: goto out_closedir; } -struct thread_map *thread_map__new_all_cpus(void) +struct perf_thread_map *thread_map__new_all_cpus(void) { return __thread_map__new_all_cpus(UINT_MAX); } -struct thread_map *thread_map__new_by_uid(uid_t uid) +struct perf_thread_map *thread_map__new_by_uid(uid_t uid) { return __thread_map__new_all_cpus(uid); } -struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid) +struct perf_thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid) { if (pid != -1) return thread_map__new_by_pid(pid); @@ -201,9 +201,9 @@ struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid) return thread_map__new_by_tid(tid); } -static struct thread_map *thread_map__new_by_pid_str(const char *pid_str) +static struct perf_thread_map *thread_map__new_by_pid_str(const char *pid_str) { - struct thread_map *threads = NULL, *nt; + struct perf_thread_map *threads = NULL, *nt; char name[256]; int items, total_tasks = 0; struct dirent **namelist = NULL; @@ -263,9 +263,9 @@ out_free_threads: goto out; } -struct thread_map *thread_map__new_dummy(void) +struct perf_thread_map *thread_map__new_dummy(void) { - struct thread_map *threads = thread_map__alloc(1); + struct perf_thread_map *threads = thread_map__alloc(1); if (threads != NULL) { thread_map__set_pid(threads, 0, -1); @@ -275,9 +275,9 @@ struct thread_map *thread_map__new_dummy(void) return threads; } -struct thread_map *thread_map__new_by_tid_str(const char *tid_str) +struct perf_thread_map *thread_map__new_by_tid_str(const char *tid_str) { - struct thread_map *threads = NULL, *nt; + struct perf_thread_map *threads = NULL, *nt; int ntasks = 0; pid_t tid, prev_tid = INT_MAX; char *end_ptr; @@ -324,7 +324,7 @@ out_free_threads: goto out; } -struct thread_map *thread_map__new_str(const char *pid, const char *tid, +struct perf_thread_map *thread_map__new_str(const char *pid, const char *tid, uid_t uid, bool all_threads) { if (pid) @@ -339,7 +339,7 @@ struct thread_map *thread_map__new_str(const char *pid, const char *tid, return thread_map__new_by_tid_str(tid); } -static void thread_map__delete(struct thread_map *threads) +static void thread_map__delete(struct perf_thread_map *threads) { if (threads) { int i; @@ -352,20 +352,20 @@ static void thread_map__delete(struct thread_map *threads) } } -struct thread_map *thread_map__get(struct thread_map *map) +struct perf_thread_map *thread_map__get(struct perf_thread_map *map) { if (map) refcount_inc(&map->refcnt); return map; } -void thread_map__put(struct thread_map *map) +void thread_map__put(struct perf_thread_map *map) { if (map && refcount_dec_and_test(&map->refcnt)) thread_map__delete(map); } -size_t thread_map__fprintf(struct thread_map *threads, FILE *fp) +size_t thread_map__fprintf(struct perf_thread_map *threads, FILE *fp) { int i; size_t printed = fprintf(fp, "%d thread%s: ", @@ -400,7 +400,7 @@ static int get_comm(char **comm, pid_t pid) return err; } -static void comm_init(struct thread_map *map, int i) +static void comm_init(struct perf_thread_map *map, int i) { pid_t pid = thread_map__pid(map, i); char *comm = NULL; @@ -421,7 +421,7 @@ static void comm_init(struct thread_map *map, int i) map->map[i].comm = comm; } -void thread_map__read_comms(struct thread_map *threads) +void thread_map__read_comms(struct perf_thread_map *threads) { int i; @@ -429,7 +429,7 @@ void thread_map__read_comms(struct thread_map *threads) comm_init(threads, i); } -static void thread_map__copy_event(struct thread_map *threads, +static void thread_map__copy_event(struct perf_thread_map *threads, struct thread_map_event *event) { unsigned i; @@ -444,9 +444,9 @@ static void thread_map__copy_event(struct thread_map *threads, refcount_set(&threads->refcnt, 1); } -struct thread_map *thread_map__new_event(struct thread_map_event *event) +struct perf_thread_map *thread_map__new_event(struct thread_map_event *event) { - struct thread_map *threads; + struct perf_thread_map *threads; threads = thread_map__alloc(event->nr); if (threads) @@ -455,7 +455,7 @@ struct thread_map *thread_map__new_event(struct thread_map_event *event) return threads; } -bool thread_map__has(struct thread_map *threads, pid_t pid) +bool thread_map__has(struct perf_thread_map *threads, pid_t pid) { int i; @@ -467,7 +467,7 @@ bool thread_map__has(struct thread_map *threads, pid_t pid) return false; } -int thread_map__remove(struct thread_map *threads, int idx) +int thread_map__remove(struct perf_thread_map *threads, int idx) { int i; diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h index 2f689c90a8c6..9358b1b6e657 100644 --- a/tools/perf/util/thread_map.h +++ b/tools/perf/util/thread_map.h @@ -11,7 +11,7 @@ struct thread_map_data { char *comm; }; -struct thread_map { +struct perf_thread_map { refcount_t refcnt; int nr; int err_thread; @@ -20,46 +20,46 @@ struct thread_map { struct thread_map_event; -struct thread_map *thread_map__new_dummy(void); -struct thread_map *thread_map__new_by_pid(pid_t pid); -struct thread_map *thread_map__new_by_tid(pid_t tid); -struct thread_map *thread_map__new_by_uid(uid_t uid); -struct thread_map *thread_map__new_all_cpus(void); -struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid); -struct thread_map *thread_map__new_event(struct thread_map_event *event); +struct perf_thread_map *thread_map__new_dummy(void); +struct perf_thread_map *thread_map__new_by_pid(pid_t pid); +struct perf_thread_map *thread_map__new_by_tid(pid_t tid); +struct perf_thread_map *thread_map__new_by_uid(uid_t uid); +struct perf_thread_map *thread_map__new_all_cpus(void); +struct perf_thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid); +struct perf_thread_map *thread_map__new_event(struct thread_map_event *event); -struct thread_map *thread_map__get(struct thread_map *map); -void thread_map__put(struct thread_map *map); +struct perf_thread_map *thread_map__get(struct perf_thread_map *map); +void thread_map__put(struct perf_thread_map *map); -struct thread_map *thread_map__new_str(const char *pid, +struct perf_thread_map *thread_map__new_str(const char *pid, const char *tid, uid_t uid, bool all_threads); -struct thread_map *thread_map__new_by_tid_str(const char *tid_str); +struct perf_thread_map *thread_map__new_by_tid_str(const char *tid_str); -size_t thread_map__fprintf(struct thread_map *threads, FILE *fp); +size_t thread_map__fprintf(struct perf_thread_map *threads, FILE *fp); -static inline int thread_map__nr(struct thread_map *threads) +static inline int thread_map__nr(struct perf_thread_map *threads) { return threads ? threads->nr : 1; } -static inline pid_t thread_map__pid(struct thread_map *map, int thread) +static inline pid_t thread_map__pid(struct perf_thread_map *map, int thread) { return map->map[thread].pid; } static inline void -thread_map__set_pid(struct thread_map *map, int thread, pid_t pid) +thread_map__set_pid(struct perf_thread_map *map, int thread, pid_t pid) { map->map[thread].pid = pid; } -static inline char *thread_map__comm(struct thread_map *map, int thread) +static inline char *thread_map__comm(struct perf_thread_map *map, int thread) { return map->map[thread].comm; } -void thread_map__read_comms(struct thread_map *threads); -bool thread_map__has(struct thread_map *threads, pid_t pid); -int thread_map__remove(struct thread_map *threads, int idx); +void thread_map__read_comms(struct perf_thread_map *threads); +bool thread_map__has(struct perf_thread_map *threads, pid_t pid); +int thread_map__remove(struct perf_thread_map *threads, int idx); #endif /* __PERF_THREAD_MAP_H */ -- cgit v1.2.3-59-g8ed1b From 32dcd021d004038ca12ac17319da5aa4756e9312 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:23:51 +0200 Subject: perf evsel: Rename struct perf_evsel to struct evsel Rename struct perf_evsel to struct evsel, so we don't have a name clash when we add struct perf_evsel in libperf. Committer notes: Added fixes for arm64, provided by Jiri. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-5-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/auxtrace.c | 2 +- tools/perf/arch/arm/util/cs-etm.c | 20 +-- tools/perf/arch/arm64/util/arm-spe.c | 6 +- tools/perf/arch/powerpc/util/kvm-stat.c | 6 +- tools/perf/arch/s390/util/auxtrace.c | 2 +- tools/perf/arch/s390/util/kvm-stat.c | 8 +- tools/perf/arch/x86/tests/intel-cqm.c | 2 +- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/arch/x86/util/auxtrace.c | 2 +- tools/perf/arch/x86/util/intel-bts.c | 10 +- tools/perf/arch/x86/util/intel-pt.c | 20 +-- tools/perf/arch/x86/util/kvm-stat.c | 12 +- tools/perf/builtin-annotate.c | 16 +- tools/perf/builtin-c2c.c | 4 +- tools/perf/builtin-diff.c | 12 +- tools/perf/builtin-evlist.c | 2 +- tools/perf/builtin-inject.c | 30 ++-- tools/perf/builtin-kmem.c | 24 +-- tools/perf/builtin-kvm.c | 20 +-- tools/perf/builtin-lock.c | 30 ++-- tools/perf/builtin-mem.c | 2 +- tools/perf/builtin-record.c | 4 +- tools/perf/builtin-report.c | 22 +-- tools/perf/builtin-sched.c | 74 ++++----- tools/perf/builtin-script.c | 90 +++++------ tools/perf/builtin-stat.c | 18 +-- tools/perf/builtin-timechart.c | 44 +++--- tools/perf/builtin-top.c | 30 ++-- tools/perf/builtin-trace.c | 76 +++++----- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/event-times.c | 14 +- tools/perf/tests/event_update.c | 2 +- tools/perf/tests/evsel-roundtrip-name.c | 4 +- tools/perf/tests/evsel-tp-sched.c | 4 +- tools/perf/tests/hists_cumulate.c | 14 +- tools/perf/tests/hists_filter.c | 4 +- tools/perf/tests/hists_link.c | 4 +- tools/perf/tests/hists_output.c | 16 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c | 2 +- tools/perf/tests/openat-syscall-all-cpus.c | 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/openat-syscall.c | 2 +- tools/perf/tests/parse-events.c | 120 +++++++-------- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/sample-parsing.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 10 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/ui/browsers/annotate.c | 14 +- tools/perf/ui/browsers/hists.c | 40 ++--- tools/perf/ui/browsers/res_sample.c | 2 +- tools/perf/ui/browsers/scripts.c | 4 +- tools/perf/ui/gtk/annotate.c | 6 +- tools/perf/ui/gtk/gtk.h | 4 +- tools/perf/ui/gtk/hists.c | 2 +- tools/perf/ui/hist.c | 8 +- tools/perf/util/annotate.c | 32 ++-- tools/perf/util/annotate.h | 26 ++-- tools/perf/util/auxtrace.c | 8 +- tools/perf/util/bpf-loader.c | 12 +- tools/perf/util/bpf-loader.h | 6 +- tools/perf/util/build-id.c | 2 +- tools/perf/util/build-id.h | 2 +- tools/perf/util/callchain.c | 2 +- tools/perf/util/callchain.h | 2 +- tools/perf/util/cgroup.c | 10 +- tools/perf/util/counts.c | 6 +- tools/perf/util/counts.h | 6 +- tools/perf/util/cs-etm.c | 4 +- tools/perf/util/data-convert-bt.c | 18 +-- tools/perf/util/db-export.c | 6 +- tools/perf/util/db-export.h | 10 +- tools/perf/util/evlist.c | 142 ++++++++--------- tools/perf/util/evlist.h | 46 +++--- tools/perf/util/evsel.c | 168 ++++++++++----------- tools/perf/util/evsel.h | 146 +++++++++--------- tools/perf/util/evsel_fprintf.c | 4 +- tools/perf/util/header.c | 58 +++---- tools/perf/util/header.h | 8 +- tools/perf/util/hist.c | 26 ++-- tools/perf/util/hist.h | 28 ++-- tools/perf/util/intel-bts.c | 2 +- tools/perf/util/intel-pt.c | 36 ++--- tools/perf/util/jitdump.c | 4 +- tools/perf/util/kvm-stat.h | 18 +-- tools/perf/util/machine.c | 6 +- tools/perf/util/machine.h | 4 +- tools/perf/util/map.h | 2 +- tools/perf/util/metricgroup.c | 22 +-- tools/perf/util/metricgroup.h | 6 +- tools/perf/util/parse-events.c | 48 +++--- tools/perf/util/parse-events.h | 2 +- tools/perf/util/python.c | 14 +- tools/perf/util/record.c | 16 +- tools/perf/util/s390-cpumsf.c | 2 +- tools/perf/util/s390-sample-raw.c | 2 +- .../perf/util/scripting-engines/trace-event-perl.c | 8 +- .../util/scripting-engines/trace-event-python.c | 22 +-- tools/perf/util/session.c | 30 ++-- tools/perf/util/session.h | 8 +- tools/perf/util/sort.c | 28 ++-- tools/perf/util/stat-display.c | 60 ++++---- tools/perf/util/stat-shadow.c | 38 ++--- tools/perf/util/stat.c | 38 ++--- tools/perf/util/stat.h | 14 +- tools/perf/util/tool.h | 4 +- tools/perf/util/top.c | 2 +- tools/perf/util/top.h | 4 +- tools/perf/util/trace-event-info.c | 4 +- tools/perf/util/trace-event-scripting.c | 2 +- tools/perf/util/trace-event.h | 4 +- 113 files changed, 1056 insertions(+), 1056 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c index 02014740a1aa..fd17dccfcb0b 100644 --- a/tools/perf/arch/arm/util/auxtrace.c +++ b/tools/perf/arch/arm/util/auxtrace.c @@ -53,7 +53,7 @@ struct auxtrace_record *auxtrace_record__init(struct perf_evlist *evlist, int *err) { struct perf_pmu *cs_etm_pmu; - struct perf_evsel *evsel; + struct evsel *evsel; bool found_etm = false; bool found_spe = false; static struct perf_pmu **arm_spe_pmus = NULL; diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index d08b55c27774..476f845be5fe 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -55,7 +55,7 @@ static const char *metadata_etmv4_ro[CS_ETMV4_PRIV_MAX] = { static bool cs_etm_is_etmv4(struct auxtrace_record *itr, int cpu); static int cs_etm_set_context_id(struct auxtrace_record *itr, - struct perf_evsel *evsel, int cpu) + struct evsel *evsel, int cpu) { struct cs_etm_recording *ptr; struct perf_pmu *cs_etm_pmu; @@ -104,7 +104,7 @@ out: } static int cs_etm_set_timestamp(struct auxtrace_record *itr, - struct perf_evsel *evsel, int cpu) + struct evsel *evsel, int cpu) { struct cs_etm_recording *ptr; struct perf_pmu *cs_etm_pmu; @@ -152,7 +152,7 @@ out: } static int cs_etm_set_option(struct auxtrace_record *itr, - struct perf_evsel *evsel, u32 option) + struct evsel *evsel, u32 option) { int i, err = -EINVAL; struct perf_cpu_map *event_cpus = evsel->evlist->cpus; @@ -208,7 +208,7 @@ static int cs_etm_parse_snapshot_options(struct auxtrace_record *itr, } static int cs_etm_set_sink_attr(struct perf_pmu *pmu, - struct perf_evsel *evsel) + struct evsel *evsel) { char msg[BUFSIZ], path[PATH_MAX], *sink; struct perf_evsel_config_term *term; @@ -252,7 +252,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, struct cs_etm_recording *ptr = container_of(itr, struct cs_etm_recording, itr); struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu; - struct perf_evsel *evsel, *cs_etm_evsel = NULL; + struct evsel *evsel, *cs_etm_evsel = NULL; struct perf_cpu_map *cpus = evlist->cpus; bool privileged = (geteuid() == 0 || perf_event_paranoid() < 0); int err = 0; @@ -407,7 +407,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, /* Add dummy event to keep tracking */ if (opts->full_auxtrace) { - struct perf_evsel *tracking_evsel; + struct evsel *tracking_evsel; err = parse_events(evlist, "dummy:u", NULL); if (err) @@ -435,7 +435,7 @@ static u64 cs_etm_get_config(struct auxtrace_record *itr) container_of(itr, struct cs_etm_recording, itr); struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu; struct perf_evlist *evlist = ptr->evlist; - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { if (evsel->attr.type == cs_etm_pmu->type) { @@ -817,7 +817,7 @@ static int cs_etm_snapshot_start(struct auxtrace_record *itr) { struct cs_etm_recording *ptr = container_of(itr, struct cs_etm_recording, itr); - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(ptr->evlist, evsel) { if (evsel->attr.type == ptr->cs_etm_pmu->type) @@ -830,7 +830,7 @@ static int cs_etm_snapshot_finish(struct auxtrace_record *itr) { struct cs_etm_recording *ptr = container_of(itr, struct cs_etm_recording, itr); - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(ptr->evlist, evsel) { if (evsel->attr.type == ptr->cs_etm_pmu->type) @@ -858,7 +858,7 @@ static int cs_etm_read_finish(struct auxtrace_record *itr, int idx) { struct cs_etm_recording *ptr = container_of(itr, struct cs_etm_recording, itr); - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(ptr->evlist, evsel) { if (evsel->attr.type == ptr->cs_etm_pmu->type) diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index 2c009aa74633..103bf20ae32a 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -65,9 +65,9 @@ static int arm_spe_recording_options(struct auxtrace_record *itr, struct arm_spe_recording *sper = container_of(itr, struct arm_spe_recording, itr); struct perf_pmu *arm_spe_pmu = sper->arm_spe_pmu; - struct perf_evsel *evsel, *arm_spe_evsel = NULL; + struct evsel *evsel, *arm_spe_evsel = NULL; bool privileged = geteuid() == 0 || perf_event_paranoid() < 0; - struct perf_evsel *tracking_evsel; + struct evsel *tracking_evsel; int err; sper->evlist = evlist; @@ -160,7 +160,7 @@ static int arm_spe_read_finish(struct auxtrace_record *itr, int idx) { struct arm_spe_recording *sper = container_of(itr, struct arm_spe_recording, itr); - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(sper->evlist, evsel) { if (evsel->attr.type == sper->arm_spe_pmu->type) diff --git a/tools/perf/arch/powerpc/util/kvm-stat.c b/tools/perf/arch/powerpc/util/kvm-stat.c index f9db341c47b6..557c474f0a4b 100644 --- a/tools/perf/arch/powerpc/util/kvm-stat.c +++ b/tools/perf/arch/powerpc/util/kvm-stat.c @@ -32,7 +32,7 @@ const char *ppc_book3s_hv_kvm_tp[] = { const char *kvm_events_tp[NR_TPS + 1]; const char *kvm_exit_reason; -static void hcall_event_get_key(struct perf_evsel *evsel, +static void hcall_event_get_key(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { @@ -55,14 +55,14 @@ static const char *get_hcall_exit_reason(u64 exit_code) return "UNKNOWN"; } -static bool hcall_event_end(struct perf_evsel *evsel, +static bool hcall_event_end(struct evsel *evsel, struct perf_sample *sample __maybe_unused, struct event_key *key __maybe_unused) { return (!strcmp(evsel->name, kvm_events_tp[3])); } -static bool hcall_event_begin(struct perf_evsel *evsel, +static bool hcall_event_begin(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { if (!strcmp(evsel->name, kvm_events_tp[2])) { diff --git a/tools/perf/arch/s390/util/auxtrace.c b/tools/perf/arch/s390/util/auxtrace.c index 0fe1be93f375..aec819b945c5 100644 --- a/tools/perf/arch/s390/util/auxtrace.c +++ b/tools/perf/arch/s390/util/auxtrace.c @@ -86,7 +86,7 @@ struct auxtrace_record *auxtrace_record__init(struct perf_evlist *evlist, int *err) { struct auxtrace_record *aux; - struct perf_evsel *pos; + struct evsel *pos; int diagnose = 0; *err = 0; diff --git a/tools/perf/arch/s390/util/kvm-stat.c b/tools/perf/arch/s390/util/kvm-stat.c index f852f2a77e0a..dac78441338c 100644 --- a/tools/perf/arch/s390/util/kvm-stat.c +++ b/tools/perf/arch/s390/util/kvm-stat.c @@ -23,7 +23,7 @@ const char *kvm_exit_reason = "icptcode"; const char *kvm_entry_trace = "kvm:kvm_s390_sie_enter"; const char *kvm_exit_trace = "kvm:kvm_s390_sie_exit"; -static void event_icpt_insn_get_key(struct perf_evsel *evsel, +static void event_icpt_insn_get_key(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { @@ -34,7 +34,7 @@ static void event_icpt_insn_get_key(struct perf_evsel *evsel, key->exit_reasons = sie_icpt_insn_codes; } -static void event_sigp_get_key(struct perf_evsel *evsel, +static void event_sigp_get_key(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { @@ -42,7 +42,7 @@ static void event_sigp_get_key(struct perf_evsel *evsel, key->exit_reasons = sie_sigp_order_codes; } -static void event_diag_get_key(struct perf_evsel *evsel, +static void event_diag_get_key(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { @@ -50,7 +50,7 @@ static void event_diag_get_key(struct perf_evsel *evsel, key->exit_reasons = sie_diagnose_codes; } -static void event_icpt_prog_get_key(struct perf_evsel *evsel, +static void event_icpt_prog_get_key(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { diff --git a/tools/perf/arch/x86/tests/intel-cqm.c b/tools/perf/arch/x86/tests/intel-cqm.c index 94aa0b673b7f..b88ed71b2e3f 100644 --- a/tools/perf/arch/x86/tests/intel-cqm.c +++ b/tools/perf/arch/x86/tests/intel-cqm.c @@ -41,7 +41,7 @@ static pid_t spawn(void) int test__intel_cqm_count_nmi_context(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_evlist *evlist = NULL; - struct perf_evsel *evsel = NULL; + struct evsel *evsel = NULL; struct perf_event_attr pe; int i, fd[2], flag, ret; size_t mmap_len; diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index f542b878bdb5..43fc7d426d93 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -52,7 +52,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe struct perf_thread_map *threads = NULL; struct perf_cpu_map *cpus = NULL; struct perf_evlist *evlist = NULL; - struct perf_evsel *evsel = NULL; + struct evsel *evsel = NULL; int err = -1, ret, i; const char *comm1, *comm2; struct perf_tsc_conversion tc; diff --git a/tools/perf/arch/x86/util/auxtrace.c b/tools/perf/arch/x86/util/auxtrace.c index d711268af330..02f192114448 100644 --- a/tools/perf/arch/x86/util/auxtrace.c +++ b/tools/perf/arch/x86/util/auxtrace.c @@ -21,7 +21,7 @@ struct auxtrace_record *auxtrace_record__init_intel(struct perf_evlist *evlist, { struct perf_pmu *intel_pt_pmu; struct perf_pmu *intel_bts_pmu; - struct perf_evsel *evsel; + struct evsel *evsel; bool found_pt = false; bool found_bts = false; diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index da1583d27efd..59685a19c3b9 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -105,7 +105,7 @@ static int intel_bts_recording_options(struct auxtrace_record *itr, struct intel_bts_recording *btsr = container_of(itr, struct intel_bts_recording, itr); struct perf_pmu *intel_bts_pmu = btsr->intel_bts_pmu; - struct perf_evsel *evsel, *intel_bts_evsel = NULL; + struct evsel *evsel, *intel_bts_evsel = NULL; const struct perf_cpu_map *cpus = evlist->cpus; bool privileged = geteuid() == 0 || perf_event_paranoid() < 0; @@ -220,7 +220,7 @@ static int intel_bts_recording_options(struct auxtrace_record *itr, /* Add dummy event to keep tracking */ if (opts->full_auxtrace) { - struct perf_evsel *tracking_evsel; + struct evsel *tracking_evsel; int err; err = parse_events(evlist, "dummy:u", NULL); @@ -313,7 +313,7 @@ static int intel_bts_snapshot_start(struct auxtrace_record *itr) { struct intel_bts_recording *btsr = container_of(itr, struct intel_bts_recording, itr); - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(btsr->evlist, evsel) { if (evsel->attr.type == btsr->intel_bts_pmu->type) @@ -326,7 +326,7 @@ static int intel_bts_snapshot_finish(struct auxtrace_record *itr) { struct intel_bts_recording *btsr = container_of(itr, struct intel_bts_recording, itr); - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(btsr->evlist, evsel) { if (evsel->attr.type == btsr->intel_bts_pmu->type) @@ -408,7 +408,7 @@ static int intel_bts_read_finish(struct auxtrace_record *itr, int idx) { struct intel_bts_recording *btsr = container_of(itr, struct intel_bts_recording, itr); - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(btsr->evlist, evsel) { if (evsel->attr.type == btsr->intel_bts_pmu->type) diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 69a23e40abc9..b42df73fd7ff 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -112,7 +112,7 @@ static u64 intel_pt_masked_bits(u64 mask, u64 bits) static int intel_pt_read_config(struct perf_pmu *intel_pt_pmu, const char *str, struct perf_evlist *evlist, u64 *res) { - struct perf_evsel *evsel; + struct evsel *evsel; u64 mask; *res = 0; @@ -271,7 +271,7 @@ intel_pt_pmu_default_config(struct perf_pmu *intel_pt_pmu) static const char *intel_pt_find_filter(struct perf_evlist *evlist, struct perf_pmu *intel_pt_pmu) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { if (evsel->attr.type == intel_pt_pmu->type) @@ -401,7 +401,7 @@ static int intel_pt_info_fill(struct auxtrace_record *itr, static int intel_pt_track_switches(struct perf_evlist *evlist) { const char *sched_switch = "sched:sched_switch"; - struct perf_evsel *evsel; + struct evsel *evsel; int err; if (!perf_evlist__can_select_event(evlist, sched_switch)) @@ -513,7 +513,7 @@ out_err: } static int intel_pt_validate_config(struct perf_pmu *intel_pt_pmu, - struct perf_evsel *evsel) + struct evsel *evsel) { int err; char c; @@ -556,7 +556,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, container_of(itr, struct intel_pt_recording, itr); struct perf_pmu *intel_pt_pmu = ptr->intel_pt_pmu; bool have_timing_info, need_immediate = false; - struct perf_evsel *evsel, *intel_pt_evsel = NULL; + struct evsel *evsel, *intel_pt_evsel = NULL; const struct perf_cpu_map *cpus = evlist->cpus; bool privileged = geteuid() == 0 || perf_event_paranoid() < 0; u64 tsc_bit; @@ -685,7 +685,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, !target__has_task(&opts->target); if (!cpu_wide && perf_can_record_cpu_wide()) { - struct perf_evsel *switch_evsel; + struct evsel *switch_evsel; err = parse_events(evlist, "dummy:u", NULL); if (err) @@ -743,7 +743,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, /* Add dummy event to keep tracking */ if (opts->full_auxtrace) { - struct perf_evsel *tracking_evsel; + struct evsel *tracking_evsel; err = parse_events(evlist, "dummy:u", NULL); if (err) @@ -784,7 +784,7 @@ static int intel_pt_snapshot_start(struct auxtrace_record *itr) { struct intel_pt_recording *ptr = container_of(itr, struct intel_pt_recording, itr); - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(ptr->evlist, evsel) { if (evsel->attr.type == ptr->intel_pt_pmu->type) @@ -797,7 +797,7 @@ static int intel_pt_snapshot_finish(struct auxtrace_record *itr) { struct intel_pt_recording *ptr = container_of(itr, struct intel_pt_recording, itr); - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(ptr->evlist, evsel) { if (evsel->attr.type == ptr->intel_pt_pmu->type) @@ -1070,7 +1070,7 @@ static int intel_pt_read_finish(struct auxtrace_record *itr, int idx) { struct intel_pt_recording *ptr = container_of(itr, struct intel_pt_recording, itr); - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(ptr->evlist, evsel) { if (evsel->attr.type == ptr->intel_pt_pmu->type) diff --git a/tools/perf/arch/x86/util/kvm-stat.c b/tools/perf/arch/x86/util/kvm-stat.c index 865a9762f22e..54a3f2373c35 100644 --- a/tools/perf/arch/x86/util/kvm-stat.c +++ b/tools/perf/arch/x86/util/kvm-stat.c @@ -27,7 +27,7 @@ const char *kvm_exit_trace = "kvm:kvm_exit"; * the time of MMIO write: kvm_mmio(KVM_TRACE_MMIO_WRITE...) -> kvm_entry * the time of MMIO read: kvm_exit -> kvm_mmio(KVM_TRACE_MMIO_READ...). */ -static void mmio_event_get_key(struct perf_evsel *evsel, struct perf_sample *sample, +static void mmio_event_get_key(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { key->key = perf_evsel__intval(evsel, sample, "gpa"); @@ -38,7 +38,7 @@ static void mmio_event_get_key(struct perf_evsel *evsel, struct perf_sample *sam #define KVM_TRACE_MMIO_READ 1 #define KVM_TRACE_MMIO_WRITE 2 -static bool mmio_event_begin(struct perf_evsel *evsel, +static bool mmio_event_begin(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { /* MMIO read begin event in kernel. */ @@ -55,7 +55,7 @@ static bool mmio_event_begin(struct perf_evsel *evsel, return false; } -static bool mmio_event_end(struct perf_evsel *evsel, struct perf_sample *sample, +static bool mmio_event_end(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { /* MMIO write end event in kernel. */ @@ -89,7 +89,7 @@ static struct kvm_events_ops mmio_events = { }; /* The time of emulation pio access is from kvm_pio to kvm_entry. */ -static void ioport_event_get_key(struct perf_evsel *evsel, +static void ioport_event_get_key(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { @@ -97,7 +97,7 @@ static void ioport_event_get_key(struct perf_evsel *evsel, key->info = perf_evsel__intval(evsel, sample, "rw"); } -static bool ioport_event_begin(struct perf_evsel *evsel, +static bool ioport_event_begin(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { @@ -109,7 +109,7 @@ static bool ioport_event_begin(struct perf_evsel *evsel, return false; } -static bool ioport_event_end(struct perf_evsel *evsel, +static bool ioport_event_end(struct evsel *evsel, struct perf_sample *sample __maybe_unused, struct event_key *key __maybe_unused) { diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index e0aa14faf2b5..9bb637165bf9 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -156,7 +156,7 @@ static int hist_iter__branch_callback(struct hist_entry_iter *iter, struct hist_entry *he = iter->he; struct branch_info *bi; struct perf_sample *sample = iter->sample; - struct perf_evsel *evsel = iter->evsel; + struct evsel *evsel = iter->evsel; int err; bi = he->branch_info; @@ -171,7 +171,7 @@ out: return err; } -static int process_branch_callback(struct perf_evsel *evsel, +static int process_branch_callback(struct evsel *evsel, struct perf_sample *sample, struct addr_location *al __maybe_unused, struct perf_annotate *ann, @@ -208,7 +208,7 @@ static bool has_annotation(struct perf_annotate *ann) return ui__has_annotation() || ann->use_stdio2; } -static int perf_evsel__add_sample(struct perf_evsel *evsel, +static int perf_evsel__add_sample(struct evsel *evsel, struct perf_sample *sample, struct addr_location *al, struct perf_annotate *ann, @@ -257,7 +257,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel, static int process_sample_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine) { struct perf_annotate *ann = container_of(tool, struct perf_annotate, tool); @@ -293,7 +293,7 @@ static int process_feature_event(struct perf_session *session, } static int hist_entry__tty_annotate(struct hist_entry *he, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_annotate *ann) { if (!ann->use_stdio2) @@ -303,7 +303,7 @@ static int hist_entry__tty_annotate(struct hist_entry *he, } static void hists__find_annotations(struct hists *hists, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_annotate *ann) { struct rb_node *nd = rb_first_cached(&hists->entries), *next; @@ -333,7 +333,7 @@ find_next: if (use_browser == 2) { int ret; int (*annotate)(struct hist_entry *he, - struct perf_evsel *evsel, + struct evsel *evsel, struct hist_browser_timer *hbt); annotate = dlsym(perf_gtk_handle, @@ -387,7 +387,7 @@ static int __cmd_annotate(struct perf_annotate *ann) { int ret; struct perf_session *session = ann->session; - struct perf_evsel *pos; + struct evsel *pos; u64 total_nr_samples; if (ann->cpu_list) { diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index 52035dacf253..d251a486f329 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -248,7 +248,7 @@ static void compute_stats(struct c2c_hist_entry *c2c_he, static int process_sample_event(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine) { struct c2c_hists *c2c_hists = &c2c.hists; @@ -2237,7 +2237,7 @@ static void print_pareto(FILE *out) static void print_c2c_info(FILE *out, struct perf_session *session) { struct perf_evlist *evlist = session->evlist; - struct perf_evsel *evsel; + struct evsel *evsel; bool first = true; fprintf(out, "=================================================\n"); diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index f6f5dd15bea7..c3b4b8196e00 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -376,7 +376,7 @@ struct hist_entry_ops block_hist_ops = { static int diff__process_sample_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine) { struct perf_diff *pdiff = container_of(tool, struct perf_diff, tool); @@ -448,10 +448,10 @@ static struct perf_diff pdiff = { }, }; -static struct perf_evsel *evsel_match(struct perf_evsel *evsel, +static struct evsel *evsel_match(struct evsel *evsel, struct perf_evlist *evlist) { - struct perf_evsel *e; + struct evsel *e; evlist__for_each_entry(evlist, e) { if (perf_evsel__match2(evsel, e)) @@ -463,7 +463,7 @@ static struct perf_evsel *evsel_match(struct perf_evsel *evsel, static void perf_evlist__collapse_resort(struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { struct hists *hists = evsel__hists(evsel); @@ -1010,7 +1010,7 @@ static void data__fprintf(void) static void data_process(void) { struct perf_evlist *evlist_base = data__files[0].session->evlist; - struct perf_evsel *evsel_base; + struct evsel *evsel_base; bool first = true; evlist__for_each_entry(evlist_base, evsel_base) { @@ -1020,7 +1020,7 @@ static void data_process(void) data__for_each_file_new(i, d) { struct perf_evlist *evlist = d->session->evlist; - struct perf_evsel *evsel; + struct evsel *evsel; struct hists *hists; evsel = evsel_match(evsel_base, evlist); diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c index 6e4f63b0da4a..e4cb61dc6315 100644 --- a/tools/perf/builtin-evlist.c +++ b/tools/perf/builtin-evlist.c @@ -21,7 +21,7 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details) { struct perf_session *session; - struct perf_evsel *pos; + struct evsel *pos; struct perf_data data = { .path = file_name, .mode = PERF_DATA_MODE_READ, diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index f4591a1438b4..646a1bf790fc 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -215,13 +215,13 @@ static int perf_event__drop_aux(struct perf_tool *tool, typedef int (*inject_handler)(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine); static int perf_event__repipe_sample(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine) { if (evsel && evsel->handler) { @@ -424,7 +424,7 @@ static int dso__inject_build_id(struct dso *dso, struct perf_tool *tool, static int perf_event__inject_buildid(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel __maybe_unused, + struct evsel *evsel __maybe_unused, struct machine *machine) { struct addr_location al; @@ -465,7 +465,7 @@ repipe: static int perf_inject__sched_process_exit(struct perf_tool *tool, union perf_event *event __maybe_unused, struct perf_sample *sample, - struct perf_evsel *evsel __maybe_unused, + struct evsel *evsel __maybe_unused, struct machine *machine __maybe_unused) { struct perf_inject *inject = container_of(tool, struct perf_inject, tool); @@ -485,7 +485,7 @@ static int perf_inject__sched_process_exit(struct perf_tool *tool, static int perf_inject__sched_switch(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine) { struct perf_inject *inject = container_of(tool, struct perf_inject, tool); @@ -509,7 +509,7 @@ static int perf_inject__sched_switch(struct perf_tool *tool, static int perf_inject__sched_stat(struct perf_tool *tool, union perf_event *event __maybe_unused, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine) { struct event_entry *ent; @@ -541,7 +541,7 @@ static void sig_handler(int sig __maybe_unused) session_done = 1; } -static int perf_evsel__check_stype(struct perf_evsel *evsel, +static int perf_evsel__check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg) { struct perf_event_attr *attr = &evsel->attr; @@ -559,7 +559,7 @@ static int perf_evsel__check_stype(struct perf_evsel *evsel, static int drop_sample(struct perf_tool *tool __maybe_unused, union perf_event *event __maybe_unused, struct perf_sample *sample __maybe_unused, - struct perf_evsel *evsel __maybe_unused, + struct evsel *evsel __maybe_unused, struct machine *machine __maybe_unused) { return 0; @@ -568,7 +568,7 @@ static int drop_sample(struct perf_tool *tool __maybe_unused, static void strip_init(struct perf_inject *inject) { struct perf_evlist *evlist = inject->session->evlist; - struct perf_evsel *evsel; + struct evsel *evsel; inject->tool.context_switch = perf_event__drop; @@ -576,7 +576,7 @@ static void strip_init(struct perf_inject *inject) evsel->handler = drop_sample; } -static bool has_tracking(struct perf_evsel *evsel) +static bool has_tracking(struct evsel *evsel) { return evsel->attr.mmap || evsel->attr.mmap2 || evsel->attr.comm || evsel->attr.task; @@ -591,9 +591,9 @@ static bool has_tracking(struct perf_evsel *evsel) * and it has a compatible sample type. */ static bool ok_to_remove(struct perf_evlist *evlist, - struct perf_evsel *evsel_to_remove) + struct evsel *evsel_to_remove) { - struct perf_evsel *evsel; + struct evsel *evsel; int cnt = 0; bool ok = false; @@ -615,7 +615,7 @@ static bool ok_to_remove(struct perf_evlist *evlist, static void strip_fini(struct perf_inject *inject) { struct perf_evlist *evlist = inject->session->evlist; - struct perf_evsel *evsel, *tmp; + struct evsel *evsel, *tmp; /* Remove non-synthesized evsels if possible */ evlist__for_each_entry_safe(evlist, tmp, evsel) { @@ -651,7 +651,7 @@ static int __cmd_inject(struct perf_inject *inject) if (inject->build_ids) { inject->tool.sample = perf_event__inject_buildid; } else if (inject->sched_stat) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(session->evlist, evsel) { const char *name = perf_evsel__name(evsel); @@ -712,7 +712,7 @@ static int __cmd_inject(struct perf_inject *inject) * remove the evsel. */ if (inject->itrace_synth_opts.set) { - struct perf_evsel *evsel; + struct evsel *evsel; perf_header__clear_feat(&session->header, HEADER_AUXTRACE); diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 9e5e60898083..46f828936120 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -166,7 +166,7 @@ static int insert_caller_stat(unsigned long call_site, return 0; } -static int perf_evsel__process_alloc_event(struct perf_evsel *evsel, +static int perf_evsel__process_alloc_event(struct evsel *evsel, struct perf_sample *sample) { unsigned long ptr = perf_evsel__intval(evsel, sample, "ptr"), @@ -185,7 +185,7 @@ static int perf_evsel__process_alloc_event(struct perf_evsel *evsel, return 0; } -static int perf_evsel__process_alloc_node_event(struct perf_evsel *evsel, +static int perf_evsel__process_alloc_node_event(struct evsel *evsel, struct perf_sample *sample) { int ret = perf_evsel__process_alloc_event(evsel, sample); @@ -229,7 +229,7 @@ static struct alloc_stat *search_alloc_stat(unsigned long ptr, return NULL; } -static int perf_evsel__process_free_event(struct perf_evsel *evsel, +static int perf_evsel__process_free_event(struct evsel *evsel, struct perf_sample *sample) { unsigned long ptr = perf_evsel__intval(evsel, sample, "ptr"); @@ -381,7 +381,7 @@ static int build_alloc_func_list(void) * Find first non-memory allocation function from callchain. * The allocation functions are in the 'alloc_func_list'. */ -static u64 find_callsite(struct perf_evsel *evsel, struct perf_sample *sample) +static u64 find_callsite(struct evsel *evsel, struct perf_sample *sample) { struct addr_location al; struct machine *machine = &kmem_session->machines.host; @@ -728,7 +728,7 @@ static char *compact_gfp_string(unsigned long gfp_flags) return NULL; } -static int parse_gfp_flags(struct perf_evsel *evsel, struct perf_sample *sample, +static int parse_gfp_flags(struct evsel *evsel, struct perf_sample *sample, unsigned int gfp_flags) { struct tep_record record = { @@ -779,7 +779,7 @@ static int parse_gfp_flags(struct perf_evsel *evsel, struct perf_sample *sample, return 0; } -static int perf_evsel__process_page_alloc_event(struct perf_evsel *evsel, +static int perf_evsel__process_page_alloc_event(struct evsel *evsel, struct perf_sample *sample) { u64 page; @@ -852,7 +852,7 @@ static int perf_evsel__process_page_alloc_event(struct perf_evsel *evsel, return 0; } -static int perf_evsel__process_page_free_event(struct perf_evsel *evsel, +static int perf_evsel__process_page_free_event(struct evsel *evsel, struct perf_sample *sample) { u64 page; @@ -930,13 +930,13 @@ static bool perf_kmem__skip_sample(struct perf_sample *sample) return false; } -typedef int (*tracepoint_handler)(struct perf_evsel *evsel, +typedef int (*tracepoint_handler)(struct evsel *evsel, struct perf_sample *sample); static int process_sample_event(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine) { int err = 0; @@ -1363,8 +1363,8 @@ static void sort_result(void) static int __cmd_kmem(struct perf_session *session) { int err = -EINVAL; - struct perf_evsel *evsel; - const struct perf_evsel_str_handler kmem_tracepoints[] = { + struct evsel *evsel; + const struct evsel_str_handler kmem_tracepoints[] = { /* slab allocator */ { "kmem:kmalloc", perf_evsel__process_alloc_event, }, { "kmem:kmem_cache_alloc", perf_evsel__process_alloc_event, }, @@ -1967,7 +1967,7 @@ int cmd_kmem(int argc, const char **argv) } if (kmem_page) { - struct perf_evsel *evsel; + struct evsel *evsel; evsel = perf_evlist__find_tracepoint_by_name(session->evlist, "kmem:mm_page_alloc"); diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index b33c83489120..cf8f27d05296 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -57,7 +57,7 @@ static const char *get_filename_for_perf_kvm(void) #ifdef HAVE_KVM_STAT_SUPPORT #include "util/kvm-stat.h" -void exit_event_get_key(struct perf_evsel *evsel, +void exit_event_get_key(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { @@ -65,12 +65,12 @@ void exit_event_get_key(struct perf_evsel *evsel, key->key = perf_evsel__intval(evsel, sample, kvm_exit_reason); } -bool kvm_exit_event(struct perf_evsel *evsel) +bool kvm_exit_event(struct evsel *evsel) { return !strcmp(evsel->name, kvm_exit_trace); } -bool exit_event_begin(struct perf_evsel *evsel, +bool exit_event_begin(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { if (kvm_exit_event(evsel)) { @@ -81,12 +81,12 @@ bool exit_event_begin(struct perf_evsel *evsel, return false; } -bool kvm_entry_event(struct perf_evsel *evsel) +bool kvm_entry_event(struct evsel *evsel) { return !strcmp(evsel->name, kvm_entry_trace); } -bool exit_event_end(struct perf_evsel *evsel, +bool exit_event_end(struct evsel *evsel, struct perf_sample *sample __maybe_unused, struct event_key *key __maybe_unused) { @@ -286,7 +286,7 @@ static bool update_kvm_event(struct kvm_event *event, int vcpu_id, } static bool is_child_event(struct perf_kvm_stat *kvm, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { @@ -396,7 +396,7 @@ static bool handle_end_event(struct perf_kvm_stat *kvm, static struct vcpu_event_record *per_vcpu_record(struct thread *thread, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { /* Only kvm_entry records vcpu id. */ @@ -419,7 +419,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread, static bool handle_kvm_event(struct perf_kvm_stat *kvm, struct thread *thread, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { struct vcpu_event_record *vcpu_record; @@ -672,7 +672,7 @@ static bool skip_sample(struct perf_kvm_stat *kvm, static int process_sample_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine) { int err = 0; @@ -1011,7 +1011,7 @@ out: static int kvm_live_open_events(struct perf_kvm_stat *kvm) { int err, rc = -1; - struct perf_evsel *pos; + struct evsel *pos; struct perf_evlist *evlist = kvm->evlist; char sbuf[STRERR_BUFSIZE]; diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 574e30ec6d7c..38500bff4423 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -347,16 +347,16 @@ alloc_failed: } struct trace_lock_handler { - int (*acquire_event)(struct perf_evsel *evsel, + int (*acquire_event)(struct evsel *evsel, struct perf_sample *sample); - int (*acquired_event)(struct perf_evsel *evsel, + int (*acquired_event)(struct evsel *evsel, struct perf_sample *sample); - int (*contended_event)(struct perf_evsel *evsel, + int (*contended_event)(struct evsel *evsel, struct perf_sample *sample); - int (*release_event)(struct perf_evsel *evsel, + int (*release_event)(struct evsel *evsel, struct perf_sample *sample); }; @@ -396,7 +396,7 @@ enum acquire_flags { READ_LOCK = 2, }; -static int report_lock_acquire_event(struct perf_evsel *evsel, +static int report_lock_acquire_event(struct evsel *evsel, struct perf_sample *sample) { void *addr; @@ -468,7 +468,7 @@ end: return 0; } -static int report_lock_acquired_event(struct perf_evsel *evsel, +static int report_lock_acquired_event(struct evsel *evsel, struct perf_sample *sample) { void *addr; @@ -531,7 +531,7 @@ end: return 0; } -static int report_lock_contended_event(struct perf_evsel *evsel, +static int report_lock_contended_event(struct evsel *evsel, struct perf_sample *sample) { void *addr; @@ -586,7 +586,7 @@ end: return 0; } -static int report_lock_release_event(struct perf_evsel *evsel, +static int report_lock_release_event(struct evsel *evsel, struct perf_sample *sample) { void *addr; @@ -656,7 +656,7 @@ static struct trace_lock_handler report_lock_ops = { static struct trace_lock_handler *trace_handler; -static int perf_evsel__process_lock_acquire(struct perf_evsel *evsel, +static int perf_evsel__process_lock_acquire(struct evsel *evsel, struct perf_sample *sample) { if (trace_handler->acquire_event) @@ -664,7 +664,7 @@ static int perf_evsel__process_lock_acquire(struct perf_evsel *evsel, return 0; } -static int perf_evsel__process_lock_acquired(struct perf_evsel *evsel, +static int perf_evsel__process_lock_acquired(struct evsel *evsel, struct perf_sample *sample) { if (trace_handler->acquired_event) @@ -672,7 +672,7 @@ static int perf_evsel__process_lock_acquired(struct perf_evsel *evsel, return 0; } -static int perf_evsel__process_lock_contended(struct perf_evsel *evsel, +static int perf_evsel__process_lock_contended(struct evsel *evsel, struct perf_sample *sample) { if (trace_handler->contended_event) @@ -680,7 +680,7 @@ static int perf_evsel__process_lock_contended(struct perf_evsel *evsel, return 0; } -static int perf_evsel__process_lock_release(struct perf_evsel *evsel, +static int perf_evsel__process_lock_release(struct evsel *evsel, struct perf_sample *sample) { if (trace_handler->release_event) @@ -806,13 +806,13 @@ static int dump_info(void) return rc; } -typedef int (*tracepoint_handler)(struct perf_evsel *evsel, +typedef int (*tracepoint_handler)(struct evsel *evsel, struct perf_sample *sample); static int process_sample_event(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine) { int err = 0; @@ -847,7 +847,7 @@ static void sort_result(void) } } -static const struct perf_evsel_str_handler lock_tracepoints[] = { +static const struct evsel_str_handler lock_tracepoints[] = { { "lock:lock_acquire", perf_evsel__process_lock_acquire, }, /* CONFIG_LOCKDEP */ { "lock:lock_acquired", perf_evsel__process_lock_acquired, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */ { "lock:lock_contended", perf_evsel__process_lock_contended, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */ diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index f45c8b502f63..9e60eda9297d 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -230,7 +230,7 @@ out_put: static int process_sample_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel __maybe_unused, + struct evsel *evsel __maybe_unused, struct machine *machine) { return dump_raw_samples(tool, event, sample, machine); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index bcfc16450608..7ba3a2c32e54 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -713,7 +713,7 @@ static int record__mmap(struct record *rec) static int record__open(struct record *rec) { char msg[BUFSIZ]; - struct perf_evsel *pos; + struct evsel *pos; struct perf_evlist *evlist = rec->evlist; struct perf_session *session = rec->session; struct record_opts *opts = &rec->opts; @@ -782,7 +782,7 @@ out: static int process_sample_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine) { struct record *rec = container_of(tool, struct record, tool); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index abf0b9b8f566..96a506f0d4c1 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -128,7 +128,7 @@ static int hist_iter__report_callback(struct hist_entry_iter *iter, int err = 0; struct report *rep = arg; struct hist_entry *he = iter->he; - struct perf_evsel *evsel = iter->evsel; + struct evsel *evsel = iter->evsel; struct perf_sample *sample = iter->sample; struct mem_info *mi; struct branch_info *bi; @@ -172,7 +172,7 @@ static int hist_iter__branch_callback(struct hist_entry_iter *iter, struct report *rep = arg; struct branch_info *bi; struct perf_sample *sample = iter->sample; - struct perf_evsel *evsel = iter->evsel; + struct evsel *evsel = iter->evsel; int err; if (!ui__has_annotation() && !rep->symbol_ipc) @@ -225,7 +225,7 @@ static int process_feature_event(struct perf_session *session, static int process_sample_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine) { struct report *rep = container_of(tool, struct report, tool); @@ -292,7 +292,7 @@ out_put: static int process_read_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample __maybe_unused, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine __maybe_unused) { struct report *rep = container_of(tool, struct report, tool); @@ -400,7 +400,7 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report char unit; unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE]; u64 nr_events = hists->stats.total_period; - struct perf_evsel *evsel = hists_to_evsel(hists); + struct evsel *evsel = hists_to_evsel(hists); char buf[512]; size_t size = sizeof(buf); int socked_id = hists->socket_filter; @@ -414,7 +414,7 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report } if (perf_evsel__is_group_event(evsel)) { - struct perf_evsel *pos; + struct evsel *pos; perf_evsel__group_desc(evsel, buf, size); evname = buf; @@ -463,7 +463,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, struct report *rep, const char *help) { - struct perf_evsel *pos; + struct evsel *pos; if (!quiet) { fprintf(stdout, "#\n# Total Lost Samples: %" PRIu64 "\n#\n", @@ -586,7 +586,7 @@ static int report__browse_hists(struct report *rep) static int report__collapse_hists(struct report *rep) { struct ui_progress prog; - struct perf_evsel *pos; + struct evsel *pos; int ret = 0; ui_progress__init(&prog, rep->nr_entries, "Merging related events..."); @@ -623,7 +623,7 @@ static int hists__resort_cb(struct hist_entry *he, void *arg) struct symbol *sym = he->ms.sym; if (rep->symbol_ipc && sym && !sym->annotate2) { - struct perf_evsel *evsel = hists_to_evsel(he->hists); + struct evsel *evsel = hists_to_evsel(he->hists); symbol__annotate2(sym, he->ms.map, evsel, &annotation__default_options, NULL); @@ -635,7 +635,7 @@ static int hists__resort_cb(struct hist_entry *he, void *arg) static void report__output_resort(struct report *rep) { struct ui_progress prog; - struct perf_evsel *pos; + struct evsel *pos; ui_progress__init(&prog, rep->nr_entries, "Sorting events for output..."); @@ -818,7 +818,7 @@ static int __cmd_report(struct report *rep) { int ret; struct perf_session *session = rep->session; - struct perf_evsel *pos; + struct evsel *pos; struct perf_data *data = session->data; signal(SIGINT, sig_handler); diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index ac6a0c5d6d6b..55779f496d27 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -133,13 +133,13 @@ typedef int (*sort_fn_t)(struct work_atoms *, struct work_atoms *); struct perf_sched; struct trace_sched_handler { - int (*switch_event)(struct perf_sched *sched, struct perf_evsel *evsel, + int (*switch_event)(struct perf_sched *sched, struct evsel *evsel, struct perf_sample *sample, struct machine *machine); - int (*runtime_event)(struct perf_sched *sched, struct perf_evsel *evsel, + int (*runtime_event)(struct perf_sched *sched, struct evsel *evsel, struct perf_sample *sample, struct machine *machine); - int (*wakeup_event)(struct perf_sched *sched, struct perf_evsel *evsel, + int (*wakeup_event)(struct perf_sched *sched, struct evsel *evsel, struct perf_sample *sample, struct machine *machine); /* PERF_RECORD_FORK event, not sched_process_fork tracepoint */ @@ -147,7 +147,7 @@ struct trace_sched_handler { struct machine *machine); int (*migrate_task_event)(struct perf_sched *sched, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine); }; @@ -799,7 +799,7 @@ static void test_calibrations(struct perf_sched *sched) static int replay_wakeup_event(struct perf_sched *sched, - struct perf_evsel *evsel, struct perf_sample *sample, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine __maybe_unused) { const char *comm = perf_evsel__strval(evsel, sample, "comm"); @@ -820,7 +820,7 @@ replay_wakeup_event(struct perf_sched *sched, } static int replay_switch_event(struct perf_sched *sched, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine __maybe_unused) { @@ -1093,7 +1093,7 @@ add_sched_in_event(struct work_atoms *atoms, u64 timestamp) } static int latency_switch_event(struct perf_sched *sched, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine) { @@ -1163,7 +1163,7 @@ out_put: } static int latency_runtime_event(struct perf_sched *sched, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine) { @@ -1198,7 +1198,7 @@ out_put: } static int latency_wakeup_event(struct perf_sched *sched, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine) { @@ -1259,7 +1259,7 @@ out_put: } static int latency_migrate_task_event(struct perf_sched *sched, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine) { @@ -1470,7 +1470,7 @@ again: } static int process_sched_wakeup_event(struct perf_tool *tool, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine) { @@ -1514,7 +1514,7 @@ map__findnew_thread(struct perf_sched *sched, struct machine *machine, pid_t pid return thread; } -static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, +static int map_switch_event(struct perf_sched *sched, struct evsel *evsel, struct perf_sample *sample, struct machine *machine) { const u32 next_pid = perf_evsel__intval(evsel, sample, "next_pid"); @@ -1655,7 +1655,7 @@ out: } static int process_sched_switch_event(struct perf_tool *tool, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine) { @@ -1681,7 +1681,7 @@ static int process_sched_switch_event(struct perf_tool *tool, } static int process_sched_runtime_event(struct perf_tool *tool, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine) { @@ -1711,7 +1711,7 @@ static int perf_sched__process_fork_event(struct perf_tool *tool, } static int process_sched_migrate_task_event(struct perf_tool *tool, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine) { @@ -1724,14 +1724,14 @@ static int process_sched_migrate_task_event(struct perf_tool *tool, } typedef int (*tracepoint_handler)(struct perf_tool *tool, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine); static int perf_sched__process_tracepoint_sample(struct perf_tool *tool __maybe_unused, union perf_event *event __maybe_unused, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine) { int err = 0; @@ -1777,7 +1777,7 @@ static int perf_sched__process_comm(struct perf_tool *tool __maybe_unused, static int perf_sched__read_events(struct perf_sched *sched) { - const struct perf_evsel_str_handler handlers[] = { + const struct evsel_str_handler handlers[] = { { "sched:sched_switch", process_sched_switch_event, }, { "sched:sched_stat_runtime", process_sched_runtime_event, }, { "sched:sched_wakeup", process_sched_wakeup_event, }, @@ -1839,7 +1839,7 @@ static inline void print_sched_time(unsigned long long nsecs, int width) * returns runtime data for event, allocating memory for it the * first time it is used. */ -static struct evsel_runtime *perf_evsel__get_runtime(struct perf_evsel *evsel) +static struct evsel_runtime *perf_evsel__get_runtime(struct evsel *evsel) { struct evsel_runtime *r = evsel->priv; @@ -1854,7 +1854,7 @@ static struct evsel_runtime *perf_evsel__get_runtime(struct perf_evsel *evsel) /* * save last time event was seen per cpu */ -static void perf_evsel__save_time(struct perf_evsel *evsel, +static void perf_evsel__save_time(struct evsel *evsel, u64 timestamp, u32 cpu) { struct evsel_runtime *r = perf_evsel__get_runtime(evsel); @@ -1881,7 +1881,7 @@ static void perf_evsel__save_time(struct perf_evsel *evsel, } /* returns last time this event was seen on the given cpu */ -static u64 perf_evsel__get_time(struct perf_evsel *evsel, u32 cpu) +static u64 perf_evsel__get_time(struct evsel *evsel, u32 cpu) { struct evsel_runtime *r = perf_evsel__get_runtime(evsel); @@ -1988,7 +1988,7 @@ static char task_state_char(struct thread *thread, int state) } static void timehist_print_sample(struct perf_sched *sched, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct addr_location *al, struct thread *thread, @@ -2121,7 +2121,7 @@ static void timehist_update_runtime_stats(struct thread_runtime *r, } static bool is_idle_sample(struct perf_sample *sample, - struct perf_evsel *evsel) + struct evsel *evsel) { /* pid 0 == swapper == idle task */ if (strcmp(perf_evsel__name(evsel), "sched:sched_switch") == 0) @@ -2132,7 +2132,7 @@ static bool is_idle_sample(struct perf_sample *sample, static void save_task_callchain(struct perf_sched *sched, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine) { struct callchain_cursor *cursor = &callchain_cursor; @@ -2286,7 +2286,7 @@ static void save_idle_callchain(struct perf_sched *sched, static struct thread *timehist_get_thread(struct perf_sched *sched, struct perf_sample *sample, struct machine *machine, - struct perf_evsel *evsel) + struct evsel *evsel) { struct thread *thread; @@ -2332,7 +2332,7 @@ static struct thread *timehist_get_thread(struct perf_sched *sched, static bool timehist_skip_sample(struct perf_sched *sched, struct thread *thread, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { bool rc = false; @@ -2354,7 +2354,7 @@ static bool timehist_skip_sample(struct perf_sched *sched, } static void timehist_print_wakeup_event(struct perf_sched *sched, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine, struct thread *awakened) @@ -2389,7 +2389,7 @@ static void timehist_print_wakeup_event(struct perf_sched *sched, static int timehist_sched_wakeup_event(struct perf_tool *tool, union perf_event *event __maybe_unused, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine) { @@ -2419,7 +2419,7 @@ static int timehist_sched_wakeup_event(struct perf_tool *tool, } static void timehist_print_migration_event(struct perf_sched *sched, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine, struct thread *migrated) @@ -2473,7 +2473,7 @@ static void timehist_print_migration_event(struct perf_sched *sched, static int timehist_migrate_task_event(struct perf_tool *tool, union perf_event *event __maybe_unused, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine) { @@ -2501,7 +2501,7 @@ static int timehist_migrate_task_event(struct perf_tool *tool, static int timehist_sched_change_event(struct perf_tool *tool, union perf_event *event, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine) { @@ -2627,7 +2627,7 @@ out: static int timehist_sched_switch_event(struct perf_tool *tool, union perf_event *event, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine __maybe_unused) { @@ -2897,14 +2897,14 @@ static void timehist_print_summary(struct perf_sched *sched, typedef int (*sched_handler)(struct perf_tool *tool, union perf_event *event, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine); static int perf_timehist__process_sample(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine) { struct perf_sched *sched = container_of(tool, struct perf_sched, tool); @@ -2926,7 +2926,7 @@ static int perf_timehist__process_sample(struct perf_tool *tool, static int timehist_check_attr(struct perf_sched *sched, struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; struct evsel_runtime *er; list_for_each_entry(evsel, &evlist->entries, node) { @@ -2948,12 +2948,12 @@ static int timehist_check_attr(struct perf_sched *sched, static int perf_sched__timehist(struct perf_sched *sched) { - const struct perf_evsel_str_handler handlers[] = { + const struct evsel_str_handler handlers[] = { { "sched:sched_switch", timehist_sched_switch_event, }, { "sched:sched_wakeup", timehist_sched_wakeup_event, }, { "sched:sched_wakeup_new", timehist_sched_wakeup_event, }, }; - const struct perf_evsel_str_handler migrate_handlers[] = { + const struct evsel_str_handler migrate_handlers[] = { { "sched:sched_migrate_task", timehist_migrate_task_event, }, }; struct perf_data data = { diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index fccc960df92b..4f9c8bb7620d 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -242,7 +242,7 @@ static struct { }, }; -struct perf_evsel_script { +struct evsel_script { char *filename; FILE *fp; u64 samples; @@ -251,15 +251,15 @@ struct perf_evsel_script { int gnum; }; -static inline struct perf_evsel_script *evsel_script(struct perf_evsel *evsel) +static inline struct evsel_script *evsel_script(struct evsel *evsel) { - return (struct perf_evsel_script *)evsel->priv; + return (struct evsel_script *)evsel->priv; } -static struct perf_evsel_script *perf_evsel_script__new(struct perf_evsel *evsel, +static struct evsel_script *perf_evsel_script__new(struct evsel *evsel, struct perf_data *data) { - struct perf_evsel_script *es = zalloc(sizeof(*es)); + struct evsel_script *es = zalloc(sizeof(*es)); if (es != NULL) { if (asprintf(&es->filename, "%s.%s.dump", data->file.path, perf_evsel__name(evsel)) < 0) @@ -277,7 +277,7 @@ out_free: return NULL; } -static void perf_evsel_script__delete(struct perf_evsel_script *es) +static void perf_evsel_script__delete(struct evsel_script *es) { zfree(&es->filename); fclose(es->fp); @@ -285,7 +285,7 @@ static void perf_evsel_script__delete(struct perf_evsel_script *es) free(es); } -static int perf_evsel_script__fprintf(struct perf_evsel_script *es, FILE *fp) +static int perf_evsel_script__fprintf(struct evsel_script *es, FILE *fp) { struct stat st; @@ -340,7 +340,7 @@ static const char *output_field2str(enum perf_output_field field) #define PRINT_FIELD(x) (output[output_type(attr->type)].fields & PERF_OUTPUT_##x) -static int perf_evsel__do_check_stype(struct perf_evsel *evsel, +static int perf_evsel__do_check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg, enum perf_output_field field, bool allow_user_set) @@ -372,7 +372,7 @@ static int perf_evsel__do_check_stype(struct perf_evsel *evsel, return 0; } -static int perf_evsel__check_stype(struct perf_evsel *evsel, +static int perf_evsel__check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg, enum perf_output_field field) { @@ -380,7 +380,7 @@ static int perf_evsel__check_stype(struct perf_evsel *evsel, false); } -static int perf_evsel__check_attr(struct perf_evsel *evsel, +static int perf_evsel__check_attr(struct evsel *evsel, struct perf_session *session) { struct perf_event_attr *attr = &evsel->attr; @@ -507,7 +507,7 @@ static void set_print_ip_opts(struct perf_event_attr *attr) static int perf_session__check_output_opt(struct perf_session *session) { unsigned int j; - struct perf_evsel *evsel; + struct evsel *evsel; for (j = 0; j < OUTPUT_TYPE_MAX; ++j) { evsel = perf_session__find_first_evtype(session, attr_type(j)); @@ -614,7 +614,7 @@ static int perf_sample__fprintf_uregs(struct perf_sample *sample, static int perf_sample__fprintf_start(struct perf_sample *sample, struct thread *thread, - struct perf_evsel *evsel, + struct evsel *evsel, u32 type, FILE *fp) { struct perf_event_attr *attr = &evsel->attr; @@ -1162,7 +1162,7 @@ out: } static const char *resolve_branch_sym(struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct thread *thread, struct addr_location *al, u64 *ip) @@ -1191,7 +1191,7 @@ static const char *resolve_branch_sym(struct perf_sample *sample, } static int perf_sample__fprintf_callindent(struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct thread *thread, struct addr_location *al, FILE *fp) { @@ -1285,7 +1285,7 @@ static int perf_sample__fprintf_ipc(struct perf_sample *sample, } static int perf_sample__fprintf_bts(struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct thread *thread, struct addr_location *al, struct machine *machine, FILE *fp) @@ -1593,7 +1593,7 @@ static int perf_sample__fprintf_synth_cbr(struct perf_sample *sample, FILE *fp) } static int perf_sample__fprintf_synth(struct perf_sample *sample, - struct perf_evsel *evsel, FILE *fp) + struct evsel *evsel, FILE *fp) { switch (evsel->attr.config) { case PERF_SYNTH_INTEL_PTWRITE: @@ -1638,7 +1638,7 @@ struct perf_script { static int perf_evlist__max_name_len(struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; int max = 0; evlist__for_each_entry(evlist, evsel) { @@ -1670,7 +1670,7 @@ static int data_src__fprintf(u64 data_src, FILE *fp) struct metric_ctx { struct perf_sample *sample; struct thread *thread; - struct perf_evsel *evsel; + struct evsel *evsel; FILE *fp; }; @@ -1705,7 +1705,7 @@ static void script_new_line(struct perf_stat_config *config __maybe_unused, static void perf_sample__fprint_metric(struct perf_script *script, struct thread *thread, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, FILE *fp) { @@ -1720,7 +1720,7 @@ static void perf_sample__fprint_metric(struct perf_script *script, }, .force_header = false, }; - struct perf_evsel *ev2; + struct evsel *ev2; u64 val; if (!evsel->stats) @@ -1747,7 +1747,7 @@ static void perf_sample__fprint_metric(struct perf_script *script, } static bool show_event(struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct thread *thread, struct addr_location *al) { @@ -1788,14 +1788,14 @@ static bool show_event(struct perf_sample *sample, } static void process_event(struct perf_script *script, - struct perf_sample *sample, struct perf_evsel *evsel, + struct perf_sample *sample, struct evsel *evsel, struct addr_location *al, struct machine *machine) { struct thread *thread = al->thread; struct perf_event_attr *attr = &evsel->attr; unsigned int type = output_type(attr->type); - struct perf_evsel_script *es = evsel->priv; + struct evsel_script *es = evsel->priv; FILE *fp = es->fp; if (output[type].fields == 0) @@ -1897,7 +1897,7 @@ static void process_event(struct perf_script *script, static struct scripting_ops *scripting_ops; -static void __process_stat(struct perf_evsel *counter, u64 tstamp) +static void __process_stat(struct evsel *counter, u64 tstamp) { int nthreads = thread_map__nr(counter->threads); int ncpus = perf_evsel__nr_cpus(counter); @@ -1931,7 +1931,7 @@ static void __process_stat(struct perf_evsel *counter, u64 tstamp) } } -static void process_stat(struct perf_evsel *counter, u64 tstamp) +static void process_stat(struct evsel *counter, u64 tstamp) { if (scripting_ops && scripting_ops->process_stat) scripting_ops->process_stat(&stat_config, counter, tstamp); @@ -1973,7 +1973,7 @@ static bool filter_cpu(struct perf_sample *sample) static int process_sample_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine) { struct perf_script *scr = container_of(tool, struct perf_script, tool); @@ -2022,9 +2022,9 @@ static int process_attr(struct perf_tool *tool, union perf_event *event, { struct perf_script *scr = container_of(tool, struct perf_script, tool); struct perf_evlist *evlist; - struct perf_evsel *evsel, *pos; + struct evsel *evsel, *pos; int err; - static struct perf_evsel_script *es; + static struct evsel_script *es; err = perf_event__process_attr(tool, event, pevlist); if (err) @@ -2071,7 +2071,7 @@ static int process_comm_event(struct perf_tool *tool, struct thread *thread; struct perf_script *script = container_of(tool, struct perf_script, tool); struct perf_session *session = script->session; - struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); + struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); int ret = -1; thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid); @@ -2108,7 +2108,7 @@ static int process_namespaces_event(struct perf_tool *tool, struct thread *thread; struct perf_script *script = container_of(tool, struct perf_script, tool); struct perf_session *session = script->session; - struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); + struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); int ret = -1; thread = machine__findnew_thread(machine, event->namespaces.pid, @@ -2146,7 +2146,7 @@ static int process_fork_event(struct perf_tool *tool, struct thread *thread; struct perf_script *script = container_of(tool, struct perf_script, tool); struct perf_session *session = script->session; - struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); + struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); if (perf_event__process_fork(tool, event, sample, machine) < 0) return -1; @@ -2181,7 +2181,7 @@ static int process_exit_event(struct perf_tool *tool, struct thread *thread; struct perf_script *script = container_of(tool, struct perf_script, tool); struct perf_session *session = script->session; - struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); + struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid); if (thread == NULL) { @@ -2216,7 +2216,7 @@ static int process_mmap_event(struct perf_tool *tool, struct thread *thread; struct perf_script *script = container_of(tool, struct perf_script, tool); struct perf_session *session = script->session; - struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); + struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); if (perf_event__process_mmap(tool, event, sample, machine) < 0) return -1; @@ -2250,7 +2250,7 @@ static int process_mmap2_event(struct perf_tool *tool, struct thread *thread; struct perf_script *script = container_of(tool, struct perf_script, tool); struct perf_session *session = script->session; - struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); + struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); if (perf_event__process_mmap2(tool, event, sample, machine) < 0) return -1; @@ -2284,7 +2284,7 @@ static int process_switch_event(struct perf_tool *tool, struct thread *thread; struct perf_script *script = container_of(tool, struct perf_script, tool); struct perf_session *session = script->session; - struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); + struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); if (perf_event__process_switch(tool, event, sample, machine) < 0) return -1; @@ -2319,7 +2319,7 @@ process_lost_event(struct perf_tool *tool, { struct perf_script *script = container_of(tool, struct perf_script, tool); struct perf_session *session = script->session; - struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); + struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); struct thread *thread; thread = machine__findnew_thread(machine, sample->pid, @@ -2355,7 +2355,7 @@ process_bpf_events(struct perf_tool *tool __maybe_unused, struct thread *thread; struct perf_script *script = container_of(tool, struct perf_script, tool); struct perf_session *session = script->session; - struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); + struct evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); if (machine__process_ksymbol(machine, event, sample) < 0) return -1; @@ -2389,7 +2389,7 @@ static void sig_handler(int sig __maybe_unused) static void perf_script__fclose_per_event_dump(struct perf_script *script) { struct perf_evlist *evlist = script->session->evlist; - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { if (!evsel->priv) @@ -2401,7 +2401,7 @@ static void perf_script__fclose_per_event_dump(struct perf_script *script) static int perf_script__fopen_per_event_dump(struct perf_script *script) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(script->session->evlist, evsel) { /* @@ -2428,8 +2428,8 @@ out_err_fclose: static int perf_script__setup_per_event_dump(struct perf_script *script) { - struct perf_evsel *evsel; - static struct perf_evsel_script es_stdout; + struct evsel *evsel; + static struct evsel_script es_stdout; if (script->per_event_dump) return perf_script__fopen_per_event_dump(script); @@ -2444,10 +2444,10 @@ static int perf_script__setup_per_event_dump(struct perf_script *script) static void perf_script__exit_per_event_dump_stats(struct perf_script *script) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(script->session->evlist, evsel) { - struct perf_evsel_script *es = evsel->priv; + struct evsel_script *es = evsel->priv; perf_evsel_script__fprintf(es, stdout); perf_evsel_script__delete(es); @@ -3003,7 +3003,7 @@ static int check_ev_match(char *dir_name, char *scriptname, { char filename[MAXPATHLEN], evname[128]; char line[BUFSIZ], *p; - struct perf_evsel *pos; + struct evsel *pos; int match, len; FILE *fp; @@ -3236,7 +3236,7 @@ static int process_stat_round_event(struct perf_session *session, union perf_event *event) { struct stat_round_event *round = &event->stat_round; - struct perf_evsel *counter; + struct evsel *counter; evlist__for_each_entry(session->evlist, counter) { perf_stat_process_counter(&stat_config, counter); diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 2b9518a38baf..e0ba97018ad7 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -234,7 +234,7 @@ static int write_stat_round_event(u64 tm, u64 type) #define SID(e, x, y) xyarray__entry(e->sample_id, x, y) static int -perf_evsel__write_stat_event(struct perf_evsel *counter, u32 cpu, u32 thread, +perf_evsel__write_stat_event(struct evsel *counter, u32 cpu, u32 thread, struct perf_counts_values *count) { struct perf_sample_id *sid = SID(counter, cpu, thread); @@ -243,7 +243,7 @@ perf_evsel__write_stat_event(struct perf_evsel *counter, u32 cpu, u32 thread, process_synthesized_event, NULL); } -static int read_single_counter(struct perf_evsel *counter, int cpu, +static int read_single_counter(struct evsel *counter, int cpu, int thread, struct timespec *rs) { if (counter->tool_event == PERF_TOOL_DURATION_TIME) { @@ -261,7 +261,7 @@ static int read_single_counter(struct perf_evsel *counter, int cpu, * Read out the results of a single counter: * do not aggregate counts across CPUs in system-wide mode */ -static int read_counter(struct perf_evsel *counter, struct timespec *rs) +static int read_counter(struct evsel *counter, struct timespec *rs) { int nthreads = thread_map__nr(evsel_list->threads); int ncpus, cpu, thread; @@ -319,7 +319,7 @@ static int read_counter(struct perf_evsel *counter, struct timespec *rs) static void read_counters(struct timespec *rs) { - struct perf_evsel *counter; + struct evsel *counter; int ret; evlist__for_each_entry(evsel_list, counter) { @@ -389,7 +389,7 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *inf workload_exec_errno = info->si_value.sival_int; } -static bool perf_evsel__should_store_id(struct perf_evsel *counter) +static bool perf_evsel__should_store_id(struct evsel *counter) { return STAT_RECORD || counter->attr.read_format & PERF_FORMAT_ID; } @@ -423,7 +423,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) int timeout = stat_config.timeout; char msg[BUFSIZ]; unsigned long long t0, t1; - struct perf_evsel *counter; + struct evsel *counter; struct timespec ts; size_t l; int status = 0; @@ -868,7 +868,7 @@ static int perf_stat__get_core_cached(struct perf_stat_config *config, static bool term_percore_set(void) { - struct perf_evsel *counter; + struct evsel *counter; evlist__for_each_entry(evsel_list, counter) { if (counter->percore) @@ -1462,7 +1462,7 @@ static int process_stat_round_event(struct perf_session *session, union perf_event *event) { struct stat_round_event *stat_round = &event->stat_round; - struct perf_evsel *counter; + struct evsel *counter; struct timespec tsh, *ts = NULL; const char **argv = session->header.env.cmdline_argv; int argc = session->header.env.nr_cmdline; @@ -1676,7 +1676,7 @@ static void setup_system_wide(int forks) if (!forks) target.system_wide = true; else { - struct perf_evsel *counter; + struct evsel *counter; evlist__for_each_entry(evsel_list, counter) { if (!counter->system_wide) diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 4bde3fa245d1..f5f70c83d304 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -545,14 +545,14 @@ exit: } typedef int (*tracepoint_handler)(struct timechart *tchart, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, const char *backtrace); static int process_sample_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine) { struct timechart *tchart = container_of(tool, struct timechart, tool); @@ -575,7 +575,7 @@ static int process_sample_event(struct perf_tool *tool, static int process_sample_cpu_idle(struct timechart *tchart __maybe_unused, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, const char *backtrace __maybe_unused) { @@ -591,7 +591,7 @@ process_sample_cpu_idle(struct timechart *tchart __maybe_unused, static int process_sample_cpu_frequency(struct timechart *tchart, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, const char *backtrace __maybe_unused) { @@ -604,7 +604,7 @@ process_sample_cpu_frequency(struct timechart *tchart, static int process_sample_sched_wakeup(struct timechart *tchart, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, const char *backtrace) { @@ -618,7 +618,7 @@ process_sample_sched_wakeup(struct timechart *tchart, static int process_sample_sched_switch(struct timechart *tchart, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, const char *backtrace) { @@ -634,7 +634,7 @@ process_sample_sched_switch(struct timechart *tchart, #ifdef SUPPORT_OLD_POWER_EVENTS static int process_sample_power_start(struct timechart *tchart __maybe_unused, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, const char *backtrace __maybe_unused) { @@ -647,7 +647,7 @@ process_sample_power_start(struct timechart *tchart __maybe_unused, static int process_sample_power_end(struct timechart *tchart, - struct perf_evsel *evsel __maybe_unused, + struct evsel *evsel __maybe_unused, struct perf_sample *sample, const char *backtrace __maybe_unused) { @@ -657,7 +657,7 @@ process_sample_power_end(struct timechart *tchart, static int process_sample_power_frequency(struct timechart *tchart, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, const char *backtrace __maybe_unused) { @@ -840,7 +840,7 @@ static int pid_end_io_sample(struct timechart *tchart, int pid, int type, static int process_enter_read(struct timechart *tchart, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { long fd = perf_evsel__intval(evsel, sample, "fd"); @@ -850,7 +850,7 @@ process_enter_read(struct timechart *tchart, static int process_exit_read(struct timechart *tchart, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { long ret = perf_evsel__intval(evsel, sample, "ret"); @@ -860,7 +860,7 @@ process_exit_read(struct timechart *tchart, static int process_enter_write(struct timechart *tchart, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { long fd = perf_evsel__intval(evsel, sample, "fd"); @@ -870,7 +870,7 @@ process_enter_write(struct timechart *tchart, static int process_exit_write(struct timechart *tchart, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { long ret = perf_evsel__intval(evsel, sample, "ret"); @@ -880,7 +880,7 @@ process_exit_write(struct timechart *tchart, static int process_enter_sync(struct timechart *tchart, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { long fd = perf_evsel__intval(evsel, sample, "fd"); @@ -890,7 +890,7 @@ process_enter_sync(struct timechart *tchart, static int process_exit_sync(struct timechart *tchart, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { long ret = perf_evsel__intval(evsel, sample, "ret"); @@ -900,7 +900,7 @@ process_exit_sync(struct timechart *tchart, static int process_enter_tx(struct timechart *tchart, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { long fd = perf_evsel__intval(evsel, sample, "fd"); @@ -910,7 +910,7 @@ process_enter_tx(struct timechart *tchart, static int process_exit_tx(struct timechart *tchart, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { long ret = perf_evsel__intval(evsel, sample, "ret"); @@ -920,7 +920,7 @@ process_exit_tx(struct timechart *tchart, static int process_enter_rx(struct timechart *tchart, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { long fd = perf_evsel__intval(evsel, sample, "fd"); @@ -930,7 +930,7 @@ process_enter_rx(struct timechart *tchart, static int process_exit_rx(struct timechart *tchart, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { long ret = perf_evsel__intval(evsel, sample, "ret"); @@ -940,7 +940,7 @@ process_exit_rx(struct timechart *tchart, static int process_enter_poll(struct timechart *tchart, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { long fd = perf_evsel__intval(evsel, sample, "fd"); @@ -950,7 +950,7 @@ process_enter_poll(struct timechart *tchart, static int process_exit_poll(struct timechart *tchart, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { long ret = perf_evsel__intval(evsel, sample, "ret"); @@ -1534,7 +1534,7 @@ static int process_header(struct perf_file_section *section __maybe_unused, static int __cmd_timechart(struct timechart *tchart, const char *output_name) { - const struct perf_evsel_str_handler power_tracepoints[] = { + const struct evsel_str_handler power_tracepoints[] = { { "power:cpu_idle", process_sample_cpu_idle }, { "power:cpu_frequency", process_sample_cpu_frequency }, { "sched:sched_wakeup", process_sample_sched_wakeup }, diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index b46b3c9f57a0..2f22f313985e 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -101,7 +101,7 @@ static void perf_top__resize(struct perf_top *top) static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) { - struct perf_evsel *evsel; + struct evsel *evsel; struct symbol *sym; struct annotation *notes; struct map *map; @@ -186,7 +186,7 @@ static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip) static void perf_top__record_precise_ip(struct perf_top *top, struct hist_entry *he, struct perf_sample *sample, - struct perf_evsel *evsel, u64 ip) + struct evsel *evsel, u64 ip) { struct annotation *notes; struct symbol *sym = he->ms.sym; @@ -228,7 +228,7 @@ static void perf_top__record_precise_ip(struct perf_top *top, static void perf_top__show_details(struct perf_top *top) { struct hist_entry *he = top->sym_filter_entry; - struct perf_evsel *evsel; + struct evsel *evsel; struct annotation *notes; struct symbol *symbol; int more; @@ -270,7 +270,7 @@ static void perf_top__print_sym_table(struct perf_top *top) char bf[160]; int printed = 0; const int win_width = top->winsize.ws_col - 1; - struct perf_evsel *evsel = top->sym_evsel; + struct evsel *evsel = top->sym_evsel; struct hists *hists = evsel__hists(evsel); puts(CONSOLE_CLEAR); @@ -554,7 +554,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c) static void perf_top__sort_new_samples(void *arg) { struct perf_top *t = arg; - struct perf_evsel *evsel = t->sym_evsel; + struct evsel *evsel = t->sym_evsel; struct hists *hists; if (t->evlist->selected != NULL) @@ -586,7 +586,7 @@ static void stop_top(void) static void *display_thread_tui(void *arg) { - struct perf_evsel *pos; + struct evsel *pos; struct perf_top *top = arg; const char *help = "For a higher level overview, try: perf top --sort comm,dso"; struct hist_browser_timer hbt = { @@ -693,7 +693,7 @@ static int hist_iter__top_callback(struct hist_entry_iter *iter, { struct perf_top *top = arg; struct hist_entry *he = iter->he; - struct perf_evsel *evsel = iter->evsel; + struct evsel *evsel = iter->evsel; if (perf_hpp_list.sym && single) perf_top__record_precise_ip(top, he, iter->sample, evsel, al->addr); @@ -705,7 +705,7 @@ static int hist_iter__top_callback(struct hist_entry_iter *iter, static void perf_event__process_sample(struct perf_tool *tool, const union perf_event *event, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct machine *machine) { @@ -813,7 +813,7 @@ static void perf_event__process_sample(struct perf_tool *tool, static void perf_top__process_lost(struct perf_top *top, union perf_event *event, - struct perf_evsel *evsel) + struct evsel *evsel) { struct hists *hists = evsel__hists(evsel); @@ -825,7 +825,7 @@ perf_top__process_lost(struct perf_top *top, union perf_event *event, static void perf_top__process_lost_samples(struct perf_top *top, union perf_event *event, - struct perf_evsel *evsel) + struct evsel *evsel) { struct hists *hists = evsel__hists(evsel); @@ -912,7 +912,7 @@ static int perf_top__overwrite_check(struct perf_top *top) struct perf_evlist *evlist = top->evlist; struct perf_evsel_config_term *term; struct list_head *config_terms; - struct perf_evsel *evsel; + struct evsel *evsel; int set, overwrite = -1; evlist__for_each_entry(evlist, evsel) { @@ -952,11 +952,11 @@ static int perf_top__overwrite_check(struct perf_top *top) } static int perf_top_overwrite_fallback(struct perf_top *top, - struct perf_evsel *evsel) + struct evsel *evsel) { struct record_opts *opts = &top->record_opts; struct perf_evlist *evlist = top->evlist; - struct perf_evsel *counter; + struct evsel *counter; if (!opts->overwrite) return 0; @@ -975,7 +975,7 @@ static int perf_top_overwrite_fallback(struct perf_top *top, static int perf_top__start_counters(struct perf_top *top) { char msg[BUFSIZ]; - struct perf_evsel *counter; + struct evsel *counter; struct perf_evlist *evlist = top->evlist; struct record_opts *opts = &top->record_opts; @@ -1104,7 +1104,7 @@ static int deliver_event(struct ordered_events *qe, struct perf_session *session = top->session; union perf_event *event = qevent->event; struct perf_sample sample; - struct perf_evsel *evsel; + struct evsel *evsel; struct machine *machine; int ret = -1; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index ca28c48f812e..fde7eff811f9 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -86,7 +86,7 @@ struct trace { *sys_exit; } prog_array; struct { - struct perf_evsel *sys_enter, + struct evsel *sys_enter, *sys_exit, *augmented; } events; @@ -242,7 +242,7 @@ struct syscall_tp { }; }; -static int perf_evsel__init_tp_uint_field(struct perf_evsel *evsel, +static int perf_evsel__init_tp_uint_field(struct evsel *evsel, struct tp_field *field, const char *name) { @@ -258,7 +258,7 @@ static int perf_evsel__init_tp_uint_field(struct perf_evsel *evsel, ({ struct syscall_tp *sc = evsel->priv;\ perf_evsel__init_tp_uint_field(evsel, &sc->name, #name); }) -static int perf_evsel__init_tp_ptr_field(struct perf_evsel *evsel, +static int perf_evsel__init_tp_ptr_field(struct evsel *evsel, struct tp_field *field, const char *name) { @@ -274,13 +274,13 @@ static int perf_evsel__init_tp_ptr_field(struct perf_evsel *evsel, ({ struct syscall_tp *sc = evsel->priv;\ perf_evsel__init_tp_ptr_field(evsel, &sc->name, #name); }) -static void perf_evsel__delete_priv(struct perf_evsel *evsel) +static void perf_evsel__delete_priv(struct evsel *evsel) { zfree(&evsel->priv); perf_evsel__delete(evsel); } -static int perf_evsel__init_syscall_tp(struct perf_evsel *evsel) +static int perf_evsel__init_syscall_tp(struct evsel *evsel) { struct syscall_tp *sc = evsel->priv = malloc(sizeof(struct syscall_tp)); @@ -297,7 +297,7 @@ out_delete: return -ENOENT; } -static int perf_evsel__init_augmented_syscall_tp(struct perf_evsel *evsel, struct perf_evsel *tp) +static int perf_evsel__init_augmented_syscall_tp(struct evsel *evsel, struct evsel *tp) { struct syscall_tp *sc = evsel->priv = malloc(sizeof(struct syscall_tp)); @@ -319,21 +319,21 @@ out_delete: return -EINVAL; } -static int perf_evsel__init_augmented_syscall_tp_args(struct perf_evsel *evsel) +static int perf_evsel__init_augmented_syscall_tp_args(struct evsel *evsel) { struct syscall_tp *sc = evsel->priv; return __tp_field__init_ptr(&sc->args, sc->id.offset + sizeof(u64)); } -static int perf_evsel__init_augmented_syscall_tp_ret(struct perf_evsel *evsel) +static int perf_evsel__init_augmented_syscall_tp_ret(struct evsel *evsel) { struct syscall_tp *sc = evsel->priv; return __tp_field__init_uint(&sc->ret, sizeof(u64), sc->id.offset + sizeof(u64), evsel->needs_swap); } -static int perf_evsel__init_raw_syscall_tp(struct perf_evsel *evsel, void *handler) +static int perf_evsel__init_raw_syscall_tp(struct evsel *evsel, void *handler) { evsel->priv = malloc(sizeof(struct syscall_tp)); if (evsel->priv != NULL) { @@ -351,9 +351,9 @@ out_delete: return -ENOENT; } -static struct perf_evsel *perf_evsel__raw_syscall_newtp(const char *direction, void *handler) +static struct evsel *perf_evsel__raw_syscall_newtp(const char *direction, void *handler) { - struct perf_evsel *evsel = perf_evsel__newtp("raw_syscalls", direction); + struct evsel *evsel = perf_evsel__newtp("raw_syscalls", direction); /* older kernel (e.g., RHEL6) use syscalls:{enter,exit} */ if (IS_ERR(evsel)) @@ -1775,12 +1775,12 @@ next_arg: return printed; } -typedef int (*tracepoint_handler)(struct trace *trace, struct perf_evsel *evsel, +typedef int (*tracepoint_handler)(struct trace *trace, struct evsel *evsel, union perf_event *event, struct perf_sample *sample); static struct syscall *trace__syscall_info(struct trace *trace, - struct perf_evsel *evsel, int id) + struct evsel *evsel, int id) { int err = 0; @@ -1886,7 +1886,7 @@ static int trace__printf_interrupted_entry(struct trace *trace) return printed; } -static int trace__fprintf_sample(struct trace *trace, struct perf_evsel *evsel, +static int trace__fprintf_sample(struct trace *trace, struct evsel *evsel, struct perf_sample *sample, struct thread *thread) { int printed = 0; @@ -1929,7 +1929,7 @@ static void *syscall__augmented_args(struct syscall *sc, struct perf_sample *sam return augmented_args; } -static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, +static int trace__sys_enter(struct trace *trace, struct evsel *evsel, union perf_event *event __maybe_unused, struct perf_sample *sample) { @@ -2008,7 +2008,7 @@ out_put: return err; } -static int trace__fprintf_sys_enter(struct trace *trace, struct perf_evsel *evsel, +static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel, struct perf_sample *sample) { struct thread_trace *ttrace; @@ -2041,7 +2041,7 @@ out_put: return err; } -static int trace__resolve_callchain(struct trace *trace, struct perf_evsel *evsel, +static int trace__resolve_callchain(struct trace *trace, struct evsel *evsel, struct perf_sample *sample, struct callchain_cursor *cursor) { @@ -2069,7 +2069,7 @@ static int trace__fprintf_callchain(struct trace *trace, struct perf_sample *sam return sample__fprintf_callchain(sample, 38, print_opts, &callchain_cursor, trace->output); } -static const char *errno_to_name(struct perf_evsel *evsel, int err) +static const char *errno_to_name(struct evsel *evsel, int err) { struct perf_env *env = perf_evsel__env(evsel); const char *arch_name = perf_env__arch(env); @@ -2077,7 +2077,7 @@ static const char *errno_to_name(struct perf_evsel *evsel, int err) return arch_syscalls__strerrno(arch_name, err); } -static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, +static int trace__sys_exit(struct trace *trace, struct evsel *evsel, union perf_event *event __maybe_unused, struct perf_sample *sample) { @@ -2211,7 +2211,7 @@ out_put: return err; } -static int trace__vfs_getname(struct trace *trace, struct perf_evsel *evsel, +static int trace__vfs_getname(struct trace *trace, struct evsel *evsel, union perf_event *event __maybe_unused, struct perf_sample *sample) { @@ -2272,7 +2272,7 @@ out: return 0; } -static int trace__sched_stat_runtime(struct trace *trace, struct perf_evsel *evsel, +static int trace__sched_stat_runtime(struct trace *trace, struct evsel *evsel, union perf_event *event __maybe_unused, struct perf_sample *sample) { @@ -2334,7 +2334,7 @@ static void bpf_output__fprintf(struct trace *trace, ++trace->nr_events_printed; } -static int trace__event_handler(struct trace *trace, struct perf_evsel *evsel, +static int trace__event_handler(struct trace *trace, struct evsel *evsel, union perf_event *event __maybe_unused, struct perf_sample *sample) { @@ -2436,7 +2436,7 @@ static void print_location(FILE *f, struct perf_sample *sample, } static int trace__pgfault(struct trace *trace, - struct perf_evsel *evsel, + struct evsel *evsel, union perf_event *event __maybe_unused, struct perf_sample *sample) { @@ -2511,7 +2511,7 @@ out_put: } static void trace__set_base_time(struct trace *trace, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { /* @@ -2530,7 +2530,7 @@ static void trace__set_base_time(struct trace *trace, static int trace__process_sample(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine __maybe_unused) { struct trace *trace = container_of(tool, struct trace, tool); @@ -2619,7 +2619,7 @@ static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp); static bool perf_evlist__add_vfs_getname(struct perf_evlist *evlist) { bool found = false; - struct perf_evsel *evsel, *tmp; + struct evsel *evsel, *tmp; struct parse_events_error err = { .idx = 0, }; int ret = parse_events(evlist, "probe:vfs_getname*", &err); @@ -2644,9 +2644,9 @@ static bool perf_evlist__add_vfs_getname(struct perf_evlist *evlist) return found; } -static struct perf_evsel *perf_evsel__new_pgfault(u64 config) +static struct evsel *perf_evsel__new_pgfault(u64 config) { - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_event_attr attr = { .type = PERF_TYPE_SOFTWARE, .mmap_data = 1, @@ -2667,7 +2667,7 @@ static struct perf_evsel *perf_evsel__new_pgfault(u64 config) static void trace__handle_event(struct trace *trace, union perf_event *event, struct perf_sample *sample) { const u32 type = event->header.type; - struct perf_evsel *evsel; + struct evsel *evsel; if (type != PERF_RECORD_SAMPLE) { trace__process_event(trace, trace->host, event, sample); @@ -2700,7 +2700,7 @@ static int trace__add_syscall_newtp(struct trace *trace) { int ret = -1; struct perf_evlist *evlist = trace->evlist; - struct perf_evsel *sys_enter, *sys_exit; + struct evsel *sys_enter, *sys_exit; sys_enter = perf_evsel__raw_syscall_newtp("sys_enter", trace__sys_enter); if (sys_enter == NULL) @@ -2748,7 +2748,7 @@ out_delete_sys_enter: static int trace__set_ev_qualifier_tp_filter(struct trace *trace) { int err = -1; - struct perf_evsel *sys_exit; + struct evsel *sys_exit; char *filter = asprintf_expr_inout_ints("id", !trace->not_ev_qualifier, trace->ev_qualifier_ids.nr, trace->ev_qualifier_ids.entries); @@ -3251,7 +3251,7 @@ static int ordered_events__deliver_event(struct ordered_events *oe, static int trace__run(struct trace *trace, int argc, const char **argv) { struct perf_evlist *evlist = trace->evlist; - struct perf_evsel *evsel, *pgfault_maj = NULL, *pgfault_min = NULL; + struct evsel *evsel, *pgfault_maj = NULL, *pgfault_min = NULL; int err = -1, i; unsigned long before; const bool forks = argc > 0; @@ -3543,7 +3543,7 @@ out_errno: static int trace__replay(struct trace *trace) { - const struct perf_evsel_str_handler handlers[] = { + const struct evsel_str_handler handlers[] = { { "probe:vfs_getname", trace__vfs_getname, }, }; struct perf_data data = { @@ -3552,7 +3552,7 @@ static int trace__replay(struct trace *trace) .force = trace->force, }; struct perf_session *session; - struct perf_evsel *evsel; + struct evsel *evsel; int err = -1; trace->tool.sample = trace__process_sample; @@ -3845,7 +3845,7 @@ static int parse_pagefaults(const struct option *opt, const char *str, static void evlist__set_evsel_handler(struct perf_evlist *evlist, void *handler) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) evsel->handler = handler; @@ -3853,7 +3853,7 @@ static void evlist__set_evsel_handler(struct perf_evlist *evlist, void *handler) static int evlist__set_syscall_tp_fields(struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { if (evsel->priv || !evsel->tp_format) @@ -4161,7 +4161,7 @@ int cmd_trace(int argc, const char **argv) }; bool __maybe_unused max_stack_user_set = true; bool mmap_pages_user_set = true; - struct perf_evsel *evsel; + struct evsel *evsel; const char * const trace_subcommands[] = { "record", NULL }; int err = -1; char bf[BUFSIZ]; @@ -4305,7 +4305,7 @@ int cmd_trace(int argc, const char **argv) if (trace.syscalls.events.augmented->priv == NULL && strstr(perf_evsel__name(evsel), "syscalls:sys_enter")) { - struct perf_evsel *augmented = trace.syscalls.events.augmented; + struct evsel *augmented = trace.syscalls.events.augmented; if (perf_evsel__init_augmented_syscall_tp(augmented, evsel) || perf_evsel__init_augmented_syscall_tp_args(augmented)) goto out; diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 1a9c3becf5ff..921af318507c 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -83,7 +83,7 @@ int test__backward_ring_buffer(struct test *test __maybe_unused, int subtest __m int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0; char pid[16], sbuf[STRERR_BUFSIZE]; struct perf_evlist *evlist; - struct perf_evsel *evsel __maybe_unused; + struct evsel *evsel __maybe_unused; struct parse_events_error parse_error; struct record_opts opts = { .target = { diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 88c218eacc43..062d23bba2df 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -555,7 +555,7 @@ static int do_test_code_reading(bool try_kcore) struct perf_thread_map *threads = NULL; struct perf_cpu_map *cpus = NULL; struct perf_evlist *evlist = NULL; - struct perf_evsel *evsel = NULL; + struct evsel *evsel = NULL; int err = -1, ret; pid_t pid; struct map *map; diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 684ad56f7b0f..45fe674233d7 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -14,7 +14,7 @@ static int attach__enable_on_exec(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__last(evlist); + struct evsel *evsel = perf_evlist__last(evlist); struct target target = { .uid = UINT_MAX, }; @@ -56,7 +56,7 @@ static int detach__enable_on_exec(struct perf_evlist *evlist) static int attach__current_disabled(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__last(evlist); + struct evsel *evsel = perf_evlist__last(evlist); struct perf_thread_map *threads; int err; @@ -82,7 +82,7 @@ static int attach__current_disabled(struct perf_evlist *evlist) static int attach__current_enabled(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__last(evlist); + struct evsel *evsel = perf_evlist__last(evlist); struct perf_thread_map *threads; int err; @@ -102,14 +102,14 @@ static int attach__current_enabled(struct perf_evlist *evlist) static int detach__disable(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__last(evlist); + struct evsel *evsel = perf_evlist__last(evlist); return perf_evsel__enable(evsel); } static int attach__cpu_disabled(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__last(evlist); + struct evsel *evsel = perf_evlist__last(evlist); struct perf_cpu_map *cpus; int err; @@ -138,7 +138,7 @@ static int attach__cpu_disabled(struct perf_evlist *evlist) static int attach__cpu_enabled(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__last(evlist); + struct evsel *evsel = perf_evlist__last(evlist); struct perf_cpu_map *cpus; int err; @@ -163,7 +163,7 @@ static int test_times(int (attach)(struct perf_evlist *), { struct perf_counts_values count; struct perf_evlist *evlist = NULL; - struct perf_evsel *evsel; + struct evsel *evsel; int err = -1, i; evlist = perf_evlist__new(); diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index b5042f019ec4..0e5a2e8195e4 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -80,7 +80,7 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused, int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_evlist *evlist; - struct perf_evsel *evsel; + struct evsel *evsel; struct event_name tmp; evlist = perf_evlist__new_default(); diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c index a104728ebf25..bb38489eda1e 100644 --- a/tools/perf/tests/evsel-roundtrip-name.c +++ b/tools/perf/tests/evsel-roundtrip-name.c @@ -11,7 +11,7 @@ static int perf_evsel__roundtrip_cache_name_test(void) { char name[128]; int type, op, err = 0, ret = 0, i, idx; - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_evlist *evlist = perf_evlist__new(); if (evlist == NULL) @@ -67,7 +67,7 @@ static int perf_evsel__roundtrip_cache_name_test(void) static int __perf_evsel__name_array_test(const char *names[], int nr_names) { int i, err; - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_evlist *evlist = perf_evlist__new(); if (evlist == NULL) diff --git a/tools/perf/tests/evsel-tp-sched.c b/tools/perf/tests/evsel-tp-sched.c index 71f60c0f9faa..0170e9d2e329 100644 --- a/tools/perf/tests/evsel-tp-sched.c +++ b/tools/perf/tests/evsel-tp-sched.c @@ -5,7 +5,7 @@ #include "tests.h" #include "debug.h" -static int perf_evsel__test_field(struct perf_evsel *evsel, const char *name, +static int perf_evsel__test_field(struct evsel *evsel, const char *name, int size, bool should_be_signed) { struct tep_format_field *field = perf_evsel__field(evsel, name); @@ -35,7 +35,7 @@ static int perf_evsel__test_field(struct perf_evsel *evsel, const char *name, int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, int subtest __maybe_unused) { - struct perf_evsel *evsel = perf_evsel__newtp("sched", "sched_switch"); + struct evsel *evsel = perf_evsel__newtp("sched", "sched_switch"); int ret = 0; if (IS_ERR(evsel)) { diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index 7a2eed6c783e..b62bf7c3bea2 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -80,7 +80,7 @@ static u64 fake_callchains[][10] = { static int add_hist_entries(struct hists *hists, struct machine *machine) { struct addr_location al; - struct perf_evsel *evsel = hists_to_evsel(hists); + struct evsel *evsel = hists_to_evsel(hists); struct perf_sample sample = { .period = 1000, }; size_t i; @@ -147,7 +147,7 @@ static void del_hist_entries(struct hists *hists) } } -typedef int (*test_fn_t)(struct perf_evsel *, struct machine *); +typedef int (*test_fn_t)(struct evsel *, struct machine *); #define COMM(he) (thread__comm_str(he->thread)) #define DSO(he) (he->ms.map->dso->short_name) @@ -247,7 +247,7 @@ static int do_test(struct hists *hists, struct result *expected, size_t nr_expec } /* NO callchain + NO children */ -static int test1(struct perf_evsel *evsel, struct machine *machine) +static int test1(struct evsel *evsel, struct machine *machine) { int err; struct hists *hists = evsel__hists(evsel); @@ -298,7 +298,7 @@ out: } /* callcain + NO children */ -static int test2(struct perf_evsel *evsel, struct machine *machine) +static int test2(struct evsel *evsel, struct machine *machine) { int err; struct hists *hists = evsel__hists(evsel); @@ -446,7 +446,7 @@ out: } /* NO callchain + children */ -static int test3(struct perf_evsel *evsel, struct machine *machine) +static int test3(struct evsel *evsel, struct machine *machine) { int err; struct hists *hists = evsel__hists(evsel); @@ -503,7 +503,7 @@ out: } /* callchain + children */ -static int test4(struct perf_evsel *evsel, struct machine *machine) +static int test4(struct evsel *evsel, struct machine *machine) { int err; struct hists *hists = evsel__hists(evsel); @@ -694,7 +694,7 @@ int test__hists_cumulate(struct test *test __maybe_unused, int subtest __maybe_u int err = TEST_FAIL; struct machines machines; struct machine *machine; - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_evlist *evlist = perf_evlist__new(); size_t i; test_fn_t testcases[] = { diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index 975844807fe2..3e679bb8da7f 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -50,7 +50,7 @@ static struct sample fake_samples[] = { static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine) { - struct perf_evsel *evsel; + struct evsel *evsel; struct addr_location al; struct perf_sample sample = { .period = 100, }; size_t i; @@ -108,7 +108,7 @@ int test__hists_filter(struct test *test __maybe_unused, int subtest __maybe_unu int err = TEST_FAIL; struct machines machines; struct machine *machine; - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_evlist *evlist = perf_evlist__new(); TEST_ASSERT_VAL("No memory", evlist); diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index af633db63f4d..078ee9876980 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -64,7 +64,7 @@ static struct sample fake_samples[][5] = { static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine) { - struct perf_evsel *evsel; + struct evsel *evsel; struct addr_location al; struct hist_entry *he; struct perf_sample sample = { .period = 1, .weight = 1, }; @@ -271,7 +271,7 @@ int test__hists_link(struct test *test __maybe_unused, int subtest __maybe_unuse struct hists *hists, *first_hists; struct machines machines; struct machine *machine = NULL; - struct perf_evsel *evsel, *first; + struct evsel *evsel, *first; struct perf_evlist *evlist = perf_evlist__new(); if (evlist == NULL) diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index 0a510c524a5d..5cd4b1baa9d1 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -50,7 +50,7 @@ static struct sample fake_samples[] = { static int add_hist_entries(struct hists *hists, struct machine *machine) { struct addr_location al; - struct perf_evsel *evsel = hists_to_evsel(hists); + struct evsel *evsel = hists_to_evsel(hists); struct perf_sample sample = { .period = 100, }; size_t i; @@ -113,7 +113,7 @@ static void del_hist_entries(struct hists *hists) } } -typedef int (*test_fn_t)(struct perf_evsel *, struct machine *); +typedef int (*test_fn_t)(struct evsel *, struct machine *); #define COMM(he) (thread__comm_str(he->thread)) #define DSO(he) (he->ms.map->dso->short_name) @@ -122,7 +122,7 @@ typedef int (*test_fn_t)(struct perf_evsel *, struct machine *); #define PID(he) (he->thread->tid) /* default sort keys (no field) */ -static int test1(struct perf_evsel *evsel, struct machine *machine) +static int test1(struct evsel *evsel, struct machine *machine) { int err; struct hists *hists = evsel__hists(evsel); @@ -224,7 +224,7 @@ out: } /* mixed fields and sort keys */ -static int test2(struct perf_evsel *evsel, struct machine *machine) +static int test2(struct evsel *evsel, struct machine *machine) { int err; struct hists *hists = evsel__hists(evsel); @@ -280,7 +280,7 @@ out: } /* fields only (no sort key) */ -static int test3(struct perf_evsel *evsel, struct machine *machine) +static int test3(struct evsel *evsel, struct machine *machine) { int err; struct hists *hists = evsel__hists(evsel); @@ -354,7 +354,7 @@ out: } /* handle duplicate 'dso' field */ -static int test4(struct perf_evsel *evsel, struct machine *machine) +static int test4(struct evsel *evsel, struct machine *machine) { int err; struct hists *hists = evsel__hists(evsel); @@ -456,7 +456,7 @@ out: } /* full sort keys w/o overhead field */ -static int test5(struct perf_evsel *evsel, struct machine *machine) +static int test5(struct evsel *evsel, struct machine *machine) { int err; struct hists *hists = evsel__hists(evsel); @@ -580,7 +580,7 @@ int test__hists_output(struct test *test __maybe_unused, int subtest __maybe_unu int err = TEST_FAIL; struct machines machines; struct machine *machine; - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_evlist *evlist = perf_evlist__new(); size_t i; test_fn_t testcases[] = { diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index e1e5e32cbb53..8ada3e63f1ba 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -68,7 +68,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un struct perf_thread_map *threads = NULL; struct perf_cpu_map *cpus = NULL; struct perf_evlist *evlist = NULL; - struct perf_evsel *evsel = NULL; + struct evsel *evsel = NULL; int found, err = -1; const char *comm; diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index c1e2fe087b67..76ee42eb1355 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -36,7 +36,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse #define nsyscalls ARRAY_SIZE(syscall_names) unsigned int nr_events[nsyscalls], expected_nr_events[nsyscalls], i, j; - struct perf_evsel *evsels[nsyscalls], *evsel; + struct evsel *evsels[nsyscalls], *evsel; char sbuf[STRERR_BUFSIZE]; struct perf_mmap *md; diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index 9cd5bf63bec1..4bf73896695a 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -21,7 +21,7 @@ int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int { int err = -1, fd, cpu; struct perf_cpu_map *cpus; - struct perf_evsel *evsel; + struct evsel *evsel; unsigned int nr_openat_calls = 111, i; cpu_set_t cpu_set; struct perf_thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX); diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index 344dc3ac2469..2e467448e220 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -33,7 +33,7 @@ int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest const char *filename = "/etc/passwd"; int flags = O_RDONLY | O_DIRECTORY; struct perf_evlist *evlist = perf_evlist__new(); - struct perf_evsel *evsel; + struct evsel *evsel; int err = -1, i, nr_events = 0, nr_polls = 0; char sbuf[STRERR_BUFSIZE]; diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c index 652b8328ca93..f3efadd05863 100644 --- a/tools/perf/tests/openat-syscall.c +++ b/tools/perf/tests/openat-syscall.c @@ -14,7 +14,7 @@ int test__openat_syscall_event(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = -1, fd; - struct perf_evsel *evsel; + struct evsel *evsel; unsigned int nr_openat_calls = 111, i; struct perf_thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX); char sbuf[STRERR_BUFSIZE]; diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 8f3c80e13584..f55ab43d51bd 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -46,7 +46,7 @@ static bool kvm_s390_create_vm_valid(void) static int test__checkevent_tracepoint(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong number of groups", 0 == evlist->nr_groups); @@ -59,7 +59,7 @@ static int test__checkevent_tracepoint(struct perf_evlist *evlist) static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); TEST_ASSERT_VAL("wrong number of groups", 0 == evlist->nr_groups); @@ -77,7 +77,7 @@ static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist) static int test__checkevent_raw(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); @@ -87,7 +87,7 @@ static int test__checkevent_raw(struct perf_evlist *evlist) static int test__checkevent_numeric(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); @@ -97,7 +97,7 @@ static int test__checkevent_numeric(struct perf_evlist *evlist) static int test__checkevent_symbolic_name(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); @@ -108,7 +108,7 @@ static int test__checkevent_symbolic_name(struct perf_evlist *evlist) static int test__checkevent_symbolic_name_config(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); @@ -129,7 +129,7 @@ static int test__checkevent_symbolic_name_config(struct perf_evlist *evlist) static int test__checkevent_symbolic_alias(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type); @@ -140,7 +140,7 @@ static int test__checkevent_symbolic_alias(struct perf_evlist *evlist) static int test__checkevent_genhw(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->attr.type); @@ -150,7 +150,7 @@ static int test__checkevent_genhw(struct perf_evlist *evlist) static int test__checkevent_breakpoint(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); @@ -164,7 +164,7 @@ static int test__checkevent_breakpoint(struct perf_evlist *evlist) static int test__checkevent_breakpoint_x(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); @@ -177,7 +177,7 @@ static int test__checkevent_breakpoint_x(struct perf_evlist *evlist) static int test__checkevent_breakpoint_r(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", @@ -192,7 +192,7 @@ static int test__checkevent_breakpoint_r(struct perf_evlist *evlist) static int test__checkevent_breakpoint_w(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", @@ -207,7 +207,7 @@ static int test__checkevent_breakpoint_w(struct perf_evlist *evlist) static int test__checkevent_breakpoint_rw(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", @@ -222,7 +222,7 @@ static int test__checkevent_breakpoint_rw(struct perf_evlist *evlist) static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); @@ -235,7 +235,7 @@ static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist) static int test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); @@ -253,7 +253,7 @@ test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist) static int test__checkevent_raw_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); @@ -265,7 +265,7 @@ static int test__checkevent_raw_modifier(struct perf_evlist *evlist) static int test__checkevent_numeric_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); @@ -277,7 +277,7 @@ static int test__checkevent_numeric_modifier(struct perf_evlist *evlist) static int test__checkevent_symbolic_name_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); @@ -289,7 +289,7 @@ static int test__checkevent_symbolic_name_modifier(struct perf_evlist *evlist) static int test__checkevent_exclude_host_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); @@ -299,7 +299,7 @@ static int test__checkevent_exclude_host_modifier(struct perf_evlist *evlist) static int test__checkevent_exclude_guest_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); @@ -309,7 +309,7 @@ static int test__checkevent_exclude_guest_modifier(struct perf_evlist *evlist) static int test__checkevent_symbolic_alias_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); @@ -321,7 +321,7 @@ static int test__checkevent_symbolic_alias_modifier(struct perf_evlist *evlist) static int test__checkevent_genhw_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); @@ -333,7 +333,7 @@ static int test__checkevent_genhw_modifier(struct perf_evlist *evlist) static int test__checkevent_exclude_idle_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude idle", evsel->attr.exclude_idle); TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); @@ -348,7 +348,7 @@ static int test__checkevent_exclude_idle_modifier(struct perf_evlist *evlist) static int test__checkevent_exclude_idle_modifier_1(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude idle", evsel->attr.exclude_idle); TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); @@ -363,7 +363,7 @@ static int test__checkevent_exclude_idle_modifier_1(struct perf_evlist *evlist) static int test__checkevent_breakpoint_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); @@ -378,7 +378,7 @@ static int test__checkevent_breakpoint_modifier(struct perf_evlist *evlist) static int test__checkevent_breakpoint_x_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); @@ -392,7 +392,7 @@ static int test__checkevent_breakpoint_x_modifier(struct perf_evlist *evlist) static int test__checkevent_breakpoint_r_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); @@ -406,7 +406,7 @@ static int test__checkevent_breakpoint_r_modifier(struct perf_evlist *evlist) static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); @@ -420,7 +420,7 @@ static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist) static int test__checkevent_breakpoint_rw_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); @@ -435,7 +435,7 @@ static int test__checkevent_breakpoint_rw_modifier(struct perf_evlist *evlist) static int test__checkevent_pmu(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); @@ -453,7 +453,7 @@ static int test__checkevent_pmu(struct perf_evlist *evlist) static int test__checkevent_list(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries); @@ -492,7 +492,7 @@ static int test__checkevent_list(struct perf_evlist *evlist) static int test__checkevent_pmu_name(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); /* cpu/config=1,name=krava/u */ TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); @@ -513,7 +513,7 @@ static int test__checkevent_pmu_name(struct perf_evlist *evlist) static int test__checkevent_pmu_partial_time_callgraph(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); /* cpu/config=1,call-graph=fp,time,period=100000/ */ TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); @@ -546,7 +546,7 @@ static int test__checkevent_pmu_partial_time_callgraph(struct perf_evlist *evlis static int test__checkevent_pmu_events(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); @@ -564,7 +564,7 @@ static int test__checkevent_pmu_events(struct perf_evlist *evlist) static int test__checkevent_pmu_events_mix(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); /* pmu-event:u */ TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); @@ -636,7 +636,7 @@ static int test__checkterms_simple(struct list_head *terms) static int test__group1(struct perf_evlist *evlist) { - struct perf_evsel *evsel, *leader; + struct evsel *evsel, *leader; TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); @@ -678,7 +678,7 @@ static int test__group1(struct perf_evlist *evlist) static int test__group2(struct perf_evlist *evlist) { - struct perf_evsel *evsel, *leader; + struct evsel *evsel, *leader; TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries); TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); @@ -733,7 +733,7 @@ static int test__group2(struct perf_evlist *evlist) static int test__group3(struct perf_evlist *evlist __maybe_unused) { - struct perf_evsel *evsel, *leader; + struct evsel *evsel, *leader; TEST_ASSERT_VAL("wrong number of entries", 5 == evlist->nr_entries); TEST_ASSERT_VAL("wrong number of groups", 2 == evlist->nr_groups); @@ -825,7 +825,7 @@ static int test__group3(struct perf_evlist *evlist __maybe_unused) static int test__group4(struct perf_evlist *evlist __maybe_unused) { - struct perf_evsel *evsel, *leader; + struct evsel *evsel, *leader; TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); @@ -869,7 +869,7 @@ static int test__group4(struct perf_evlist *evlist __maybe_unused) static int test__group5(struct perf_evlist *evlist __maybe_unused) { - struct perf_evsel *evsel, *leader; + struct evsel *evsel, *leader; TEST_ASSERT_VAL("wrong number of entries", 5 == evlist->nr_entries); TEST_ASSERT_VAL("wrong number of groups", 2 == evlist->nr_groups); @@ -955,7 +955,7 @@ static int test__group5(struct perf_evlist *evlist __maybe_unused) static int test__group_gh1(struct perf_evlist *evlist) { - struct perf_evsel *evsel, *leader; + struct evsel *evsel, *leader; TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); @@ -995,7 +995,7 @@ static int test__group_gh1(struct perf_evlist *evlist) static int test__group_gh2(struct perf_evlist *evlist) { - struct perf_evsel *evsel, *leader; + struct evsel *evsel, *leader; TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); @@ -1035,7 +1035,7 @@ static int test__group_gh2(struct perf_evlist *evlist) static int test__group_gh3(struct perf_evlist *evlist) { - struct perf_evsel *evsel, *leader; + struct evsel *evsel, *leader; TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); @@ -1075,7 +1075,7 @@ static int test__group_gh3(struct perf_evlist *evlist) static int test__group_gh4(struct perf_evlist *evlist) { - struct perf_evsel *evsel, *leader; + struct evsel *evsel, *leader; TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); @@ -1115,7 +1115,7 @@ static int test__group_gh4(struct perf_evlist *evlist) static int test__leader_sample1(struct perf_evlist *evlist) { - struct perf_evsel *evsel, *leader; + struct evsel *evsel, *leader; TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries); @@ -1168,7 +1168,7 @@ static int test__leader_sample1(struct perf_evlist *evlist) static int test__leader_sample2(struct perf_evlist *evlist __maybe_unused) { - struct perf_evsel *evsel, *leader; + struct evsel *evsel, *leader; TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); @@ -1207,7 +1207,7 @@ static int test__leader_sample2(struct perf_evlist *evlist __maybe_unused) static int test__checkevent_pinned_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); @@ -1220,7 +1220,7 @@ static int test__checkevent_pinned_modifier(struct perf_evlist *evlist) static int test__pinned_group(struct perf_evlist *evlist) { - struct perf_evsel *evsel, *leader; + struct evsel *evsel, *leader; TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries); @@ -1251,7 +1251,7 @@ static int test__pinned_group(struct perf_evlist *evlist) static int test__checkevent_breakpoint_len(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); @@ -1266,7 +1266,7 @@ static int test__checkevent_breakpoint_len(struct perf_evlist *evlist) static int test__checkevent_breakpoint_len_w(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); @@ -1282,7 +1282,7 @@ static int test__checkevent_breakpoint_len_w(struct perf_evlist *evlist) static int test__checkevent_breakpoint_len_rw_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); @@ -1294,7 +1294,7 @@ test__checkevent_breakpoint_len_rw_modifier(struct perf_evlist *evlist) static int test__checkevent_precise_max_modifier(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type); @@ -1305,7 +1305,7 @@ static int test__checkevent_precise_max_modifier(struct perf_evlist *evlist) static int test__checkevent_config_symbol(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong name setting", strcmp(evsel->name, "insn") == 0); return 0; @@ -1313,7 +1313,7 @@ static int test__checkevent_config_symbol(struct perf_evlist *evlist) static int test__checkevent_config_raw(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong name setting", strcmp(evsel->name, "rawpmu") == 0); return 0; @@ -1321,7 +1321,7 @@ static int test__checkevent_config_raw(struct perf_evlist *evlist) static int test__checkevent_config_num(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong name setting", strcmp(evsel->name, "numpmu") == 0); return 0; @@ -1329,7 +1329,7 @@ static int test__checkevent_config_num(struct perf_evlist *evlist) static int test__checkevent_config_cache(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong name setting", strcmp(evsel->name, "cachepmu") == 0); return 0; @@ -1342,7 +1342,7 @@ static bool test__intel_pt_valid(void) static int test__intel_pt(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong name setting", strcmp(evsel->name, "intel_pt//u") == 0); return 0; @@ -1350,7 +1350,7 @@ static int test__intel_pt(struct perf_evlist *evlist) static int test__checkevent_complex_name(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong complex name parsing", strcmp(evsel->name, "COMPLEX_CYCLES_NAME:orig=cycles,desc=chip-clock-ticks") == 0); return 0; @@ -1358,7 +1358,7 @@ static int test__checkevent_complex_name(struct perf_evlist *evlist) static int test__sym_event_slash(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong type", evsel->attr.type == PERF_TYPE_HARDWARE); TEST_ASSERT_VAL("wrong config", evsel->attr.config == PERF_COUNT_HW_CPU_CYCLES); @@ -1368,7 +1368,7 @@ static int test__sym_event_slash(struct perf_evlist *evlist) static int test__sym_event_dc(struct perf_evlist *evlist) { - struct perf_evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong type", evsel->attr.type == PERF_TYPE_HARDWARE); TEST_ASSERT_VAL("wrong config", evsel->attr.config == PERF_COUNT_HW_CPU_CYCLES); diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 07f6bd8ed719..7e576c2db941 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -51,7 +51,7 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus cpu_set_t cpu_mask; size_t cpu_mask_size = sizeof(cpu_mask); struct perf_evlist *evlist = perf_evlist__new_dummy(); - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_sample sample; const char *cmd = "sleep"; const char *argv[] = { cmd, "1", NULL, }; diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c index 361714e2583c..a8cd3ed3c116 100644 --- a/tools/perf/tests/sample-parsing.c +++ b/tools/perf/tests/sample-parsing.c @@ -153,7 +153,7 @@ static bool samples_same(const struct perf_sample *s1, static int do_test(u64 sample_type, u64 sample_regs, u64 read_format) { - struct perf_evsel evsel = { + struct evsel evsel = { .needs_swap = false, .attr = { .sample_type = sample_type, diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index d57b8d9c1575..620a99aad1e3 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -27,7 +27,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) int nr_samples = 0; char sbuf[STRERR_BUFSIZE]; union perf_event *event; - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_evlist *evlist; struct perf_event_attr attr = { .type = PERF_TYPE_SOFTWARE, diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 3652c548cc22..a946b9fa60dd 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -52,8 +52,8 @@ static int spin_sleep(void) } struct switch_tracking { - struct perf_evsel *switch_evsel; - struct perf_evsel *cycles_evsel; + struct evsel *switch_evsel; + struct evsel *cycles_evsel; pid_t *tids; int nr_tids; int comm_seen[4]; @@ -118,7 +118,7 @@ static int process_sample_event(struct perf_evlist *evlist, struct switch_tracking *switch_tracking) { struct perf_sample sample; - struct perf_evsel *evsel; + struct evsel *evsel; pid_t next_tid, prev_tid; int cpu, err; @@ -330,8 +330,8 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ struct perf_thread_map *threads = NULL; struct perf_cpu_map *cpus = NULL; struct perf_evlist *evlist = NULL; - struct perf_evsel *evsel, *cpu_clocks_evsel, *cycles_evsel; - struct perf_evsel *switch_evsel, *tracking_evsel; + struct evsel *evsel, *cpu_clocks_evsel, *cycles_evsel; + struct evsel *switch_evsel, *tracking_evsel; const char *comm; int err = -1; diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 9602ff91a3c7..e6fb4b8d8bc2 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -37,7 +37,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused { int err = -1; union perf_event *event; - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_evlist *evlist; struct target target = { .uid = UINT_MAX, diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index e67880bf1efe..64cc650c4543 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -299,7 +299,7 @@ static void annotate_browser__set_rb_top(struct annotate_browser *browser, } static void annotate_browser__calc_percent(struct annotate_browser *browser, - struct perf_evsel *evsel) + struct evsel *evsel) { struct map_symbol *ms = browser->b.priv; struct symbol *sym = ms->sym; @@ -406,7 +406,7 @@ static int sym_title(struct symbol *sym, struct map *map, char *title, * to the calling function. */ static bool annotate_browser__callq(struct annotate_browser *browser, - struct perf_evsel *evsel, + struct evsel *evsel, struct hist_browser_timer *hbt) { struct map_symbol *ms = browser->b.priv; @@ -455,7 +455,7 @@ struct disasm_line *annotate_browser__find_offset(struct annotate_browser *brows } static bool annotate_browser__jump(struct annotate_browser *browser, - struct perf_evsel *evsel, + struct evsel *evsel, struct hist_browser_timer *hbt) { struct disasm_line *dl = disasm_line(browser->selection); @@ -656,7 +656,7 @@ switch_percent_type(struct annotation_options *opts, bool base) } static int annotate_browser__run(struct annotate_browser *browser, - struct perf_evsel *evsel, + struct evsel *evsel, struct hist_browser_timer *hbt) { struct rb_node *nd = NULL; @@ -869,14 +869,14 @@ out: return key; } -int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel, +int map_symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel, struct hist_browser_timer *hbt, struct annotation_options *opts) { return symbol__tui_annotate(ms->sym, ms->map, evsel, hbt, opts); } -int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel, +int hist_entry__tui_annotate(struct hist_entry *he, struct evsel *evsel, struct hist_browser_timer *hbt, struct annotation_options *opts) { @@ -888,7 +888,7 @@ int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel, } int symbol__tui_annotate(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, + struct evsel *evsel, struct hist_browser_timer *hbt, struct annotation_options *opts) { diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index a94eb0755e8b..9bc818621eb6 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -2187,7 +2187,7 @@ struct hist_browser *hist_browser__new(struct hists *hists) } static struct hist_browser * -perf_evsel_browser__new(struct perf_evsel *evsel, +perf_evsel_browser__new(struct evsel *evsel, struct hist_browser_timer *hbt, struct perf_env *env, struct annotation_options *annotation_opts) @@ -2352,7 +2352,7 @@ struct popup_action { struct thread *thread; struct map_symbol ms; int socket; - struct perf_evsel *evsel; + struct evsel *evsel; enum rstype rstype; int (*fn)(struct hist_browser *browser, struct popup_action *act); @@ -2361,7 +2361,7 @@ struct popup_action { static int do_annotate(struct hist_browser *browser, struct popup_action *act) { - struct perf_evsel *evsel; + struct evsel *evsel; struct annotation *notes; struct hist_entry *he; int err; @@ -2596,7 +2596,7 @@ static int add_script_opt_2(struct hist_browser *browser __maybe_unused, struct popup_action *act, char **optstr, struct thread *thread, struct symbol *sym, - struct perf_evsel *evsel, const char *tstr) + struct evsel *evsel, const char *tstr) { if (thread) { @@ -2623,7 +2623,7 @@ static int add_script_opt(struct hist_browser *browser, struct popup_action *act, char **optstr, struct thread *thread, struct symbol *sym, - struct perf_evsel *evsel) + struct evsel *evsel) { int n, j; struct hist_entry *he; @@ -2653,7 +2653,7 @@ static int add_res_sample_opt(struct hist_browser *browser __maybe_unused, struct popup_action *act, char **optstr, struct res_sample *res_sample, - struct perf_evsel *evsel, + struct evsel *evsel, enum rstype type) { if (!res_sample) @@ -2814,7 +2814,7 @@ next: } } -static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, +static int perf_evsel__hists_browse(struct evsel *evsel, int nr_events, const char *helpline, bool left_exits, struct hist_browser_timer *hbt, @@ -3198,9 +3198,9 @@ out: return key; } -struct perf_evsel_menu { +struct evsel_menu { struct ui_browser b; - struct perf_evsel *selection; + struct evsel *selection; struct annotation_options *annotation_opts; bool lost_events, lost_events_warned; float min_pcnt; @@ -3210,9 +3210,9 @@ struct perf_evsel_menu { static void perf_evsel_menu__write(struct ui_browser *browser, void *entry, int row) { - struct perf_evsel_menu *menu = container_of(browser, - struct perf_evsel_menu, b); - struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node); + struct evsel_menu *menu = container_of(browser, + struct evsel_menu, b); + struct evsel *evsel = list_entry(entry, struct evsel, node); struct hists *hists = evsel__hists(evsel); bool current_entry = ui_browser__is_current_entry(browser, row); unsigned long nr_events = hists->stats.nr_events[PERF_RECORD_SAMPLE]; @@ -3225,7 +3225,7 @@ static void perf_evsel_menu__write(struct ui_browser *browser, HE_COLORSET_NORMAL); if (perf_evsel__is_group_event(evsel)) { - struct perf_evsel *pos; + struct evsel *pos; ev_name = perf_evsel__group_name(evsel); @@ -3257,13 +3257,13 @@ static void perf_evsel_menu__write(struct ui_browser *browser, menu->selection = evsel; } -static int perf_evsel_menu__run(struct perf_evsel_menu *menu, +static int perf_evsel_menu__run(struct evsel_menu *menu, int nr_events, const char *help, struct hist_browser_timer *hbt, bool warn_lost_event) { struct perf_evlist *evlist = menu->b.priv; - struct perf_evsel *pos; + struct evsel *pos; const char *title = "Available samples"; int delay_secs = hbt ? hbt->refresh : 0; int key; @@ -3351,7 +3351,7 @@ out: static bool filter_group_entries(struct ui_browser *browser __maybe_unused, void *entry) { - struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node); + struct evsel *evsel = list_entry(entry, struct evsel, node); if (symbol_conf.event_group && !perf_evsel__is_group_leader(evsel)) return true; @@ -3367,8 +3367,8 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, bool warn_lost_event, struct annotation_options *annotation_opts) { - struct perf_evsel *pos; - struct perf_evsel_menu menu = { + struct evsel *pos; + struct evsel_menu menu = { .b = { .entries = &evlist->entries, .refresh = ui_browser__list_head_refresh, @@ -3408,7 +3408,7 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, single_entry: if (nr_entries == 1) { - struct perf_evsel *first = perf_evlist__first(evlist); + struct evsel *first = perf_evlist__first(evlist); return perf_evsel__hists_browse(first, nr_entries, help, false, hbt, min_pcnt, @@ -3417,7 +3417,7 @@ single_entry: } if (symbol_conf.event_group) { - struct perf_evsel *pos; + struct evsel *pos; nr_entries = 0; evlist__for_each_entry(evlist, pos) { diff --git a/tools/perf/ui/browsers/res_sample.c b/tools/perf/ui/browsers/res_sample.c index 8aa3547bb9ff..7f3576deafd7 100644 --- a/tools/perf/ui/browsers/res_sample.c +++ b/tools/perf/ui/browsers/res_sample.c @@ -24,7 +24,7 @@ void res_sample_init(void) } int res_sample_browse(struct res_sample *res_samples, int num_res, - struct perf_evsel *evsel, enum rstype rstype) + struct evsel *evsel, enum rstype rstype) { char **names; int i, n; diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c index 4d565cc14076..c0462457e9f9 100644 --- a/tools/perf/ui/browsers/scripts.c +++ b/tools/perf/ui/browsers/scripts.c @@ -78,7 +78,7 @@ static int scripts_config(const char *var, const char *value, void *data) * Return -1 on failure. */ static int list_scripts(char *script_name, bool *custom, - struct perf_evsel *evsel) + struct evsel *evsel) { char *buf, *paths[SCRIPT_MAX_NO], *names[SCRIPT_MAX_NO]; int i, num, choice; @@ -162,7 +162,7 @@ void run_script(char *cmd) SLsmg_refresh(); } -int script_browse(const char *script_opt, struct perf_evsel *evsel) +int script_browse(const char *script_opt, struct evsel *evsel) { char *cmd, script_name[SCRIPT_FULLPATH_LEN]; bool custom = false; diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c index 3af87c18a914..40e263a730e4 100644 --- a/tools/perf/ui/gtk/annotate.c +++ b/tools/perf/ui/gtk/annotate.c @@ -91,7 +91,7 @@ static int perf_gtk__get_line(char *buf, size_t size, struct disasm_line *dl) } static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym, - struct map *map, struct perf_evsel *evsel, + struct map *map, struct evsel *evsel, struct hist_browser_timer *hbt __maybe_unused) { struct disasm_line *pos, *n; @@ -160,7 +160,7 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym, } static int symbol__gtk_annotate(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, + struct evsel *evsel, struct hist_browser_timer *hbt) { GtkWidget *window; @@ -238,7 +238,7 @@ static int symbol__gtk_annotate(struct symbol *sym, struct map *map, } int hist_entry__gtk_annotate(struct hist_entry *he, - struct perf_evsel *evsel, + struct evsel *evsel, struct hist_browser_timer *hbt) { return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt); diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h index 9846ea5c831b..e2f5fbef3c9a 100644 --- a/tools/perf/ui/gtk/gtk.h +++ b/tools/perf/ui/gtk/gtk.h @@ -52,7 +52,7 @@ static inline GtkWidget *perf_gtk__setup_info_bar(void) } #endif -struct perf_evsel; +struct evsel; struct perf_evlist; struct hist_entry; struct hist_browser_timer; @@ -61,7 +61,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help, struct hist_browser_timer *hbt, float min_pcnt); int hist_entry__gtk_annotate(struct hist_entry *he, - struct perf_evsel *evsel, + struct evsel *evsel, struct hist_browser_timer *hbt); void perf_gtk__show_annotations(void); diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index 3955ed1d1bd9..d5c9fe230632 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c @@ -595,7 +595,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, struct hist_browser_timer *hbt __maybe_unused, float min_pcnt) { - struct perf_evsel *pos; + struct evsel *pos; GtkWidget *vbox; GtkWidget *notebook; GtkWidget *info_bar; diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 412d6f1626e3..214af526901b 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -25,7 +25,7 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, { int ret; struct hists *hists = he->hists; - struct perf_evsel *evsel = hists_to_evsel(hists); + struct evsel *evsel = hists_to_evsel(hists); char *buf = hpp->buf; size_t size = hpp->size; @@ -153,7 +153,7 @@ static int __hpp__sort(struct hist_entry *a, struct hist_entry *b, { s64 ret; int i, nr_members; - struct perf_evsel *evsel; + struct evsel *evsel; struct hist_entry *pair; u64 *fields_a, *fields_b; @@ -223,7 +223,7 @@ static int hpp__width_fn(struct perf_hpp_fmt *fmt, struct hists *hists) { int len = fmt->user_len ?: fmt->len; - struct perf_evsel *evsel = hists_to_evsel(hists); + struct evsel *evsel = hists_to_evsel(hists); if (symbol_conf.event_group) len = max(len, evsel->nr_members * fmt->len); @@ -797,7 +797,7 @@ static int add_hierarchy_fmt(struct hists *hists, struct perf_hpp_fmt *fmt) int perf_hpp__setup_hists_formats(struct perf_hpp_list *list, struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_hpp_fmt *fmt; struct hists *hists; int ret; diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index ac9ad2330f93..6ea5d678a81c 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -929,7 +929,7 @@ alloc_histograms: } static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, u64 addr, + struct evsel *evsel, u64 addr, struct perf_sample *sample) { struct annotated_source *src; @@ -1080,13 +1080,13 @@ void annotation__compute_ipc(struct annotation *notes, size_t size) } int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample, - struct perf_evsel *evsel) + struct evsel *evsel) { return symbol__inc_addr_samples(ams->sym, ams->map, evsel, ams->al_addr, sample); } int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample, - struct perf_evsel *evsel, u64 ip) + struct evsel *evsel, u64 ip) { return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evsel, ip, sample); } @@ -1134,7 +1134,7 @@ struct annotate_args { size_t privsize; struct arch *arch; struct map_symbol ms; - struct perf_evsel *evsel; + struct evsel *evsel; struct annotation_options *options; s64 offset; char *line; @@ -1165,7 +1165,7 @@ static struct annotation_line * annotation_line__new(struct annotate_args *args, size_t privsize) { struct annotation_line *al; - struct perf_evsel *evsel = args->evsel; + struct evsel *evsel = args->evsel; size_t size = privsize + sizeof(*al); int nr = 1; @@ -1359,7 +1359,7 @@ static int disasm_line__print(struct disasm_line *dl, u64 start, int addr_fmt_wi static int annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start, - struct perf_evsel *evsel, u64 len, int min_pcnt, int printed, + struct evsel *evsel, u64 len, int min_pcnt, int printed, int max_lines, struct annotation_line *queue, int addr_fmt_width, int percent_type) { @@ -2011,10 +2011,10 @@ static void calc_percent(struct sym_hist *sym_hist, } static void annotation__calc_percent(struct annotation *notes, - struct perf_evsel *leader, s64 len) + struct evsel *leader, s64 len) { struct annotation_line *al, *next; - struct perf_evsel *evsel; + struct evsel *evsel; list_for_each_entry(al, ¬es->src->source, node) { s64 end; @@ -2041,7 +2041,7 @@ static void annotation__calc_percent(struct annotation *notes, } } -void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel) +void symbol__calc_percent(struct symbol *sym, struct evsel *evsel) { struct annotation *notes = symbol__annotation(sym); @@ -2049,7 +2049,7 @@ void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel) } int symbol__annotate(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, size_t privsize, + struct evsel *evsel, size_t privsize, struct annotation_options *options, struct arch **parch) { @@ -2214,7 +2214,7 @@ static void print_summary(struct rb_root *root, const char *filename) } } -static void symbol__annotate_hits(struct symbol *sym, struct perf_evsel *evsel) +static void symbol__annotate_hits(struct symbol *sym, struct evsel *evsel) { struct annotation *notes = symbol__annotation(sym); struct sym_hist *h = annotation__histogram(notes, evsel->idx); @@ -2241,7 +2241,7 @@ static int annotated_source__addr_fmt_width(struct list_head *lines, u64 start) } int symbol__annotate_printf(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, + struct evsel *evsel, struct annotation_options *opts) { struct dso *dso = map->dso; @@ -2405,7 +2405,7 @@ static int symbol__annotate_fprintf2(struct symbol *sym, FILE *fp, return 0; } -int map_symbol__annotation_dump(struct map_symbol *ms, struct perf_evsel *evsel, +int map_symbol__annotation_dump(struct map_symbol *ms, struct evsel *evsel, struct annotation_options *opts) { const char *ev_name = perf_evsel__name(evsel); @@ -2657,7 +2657,7 @@ static void symbol__calc_lines(struct symbol *sym, struct map *map, } int symbol__tty_annotate2(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, + struct evsel *evsel, struct annotation_options *opts) { struct dso *dso = map->dso; @@ -2685,7 +2685,7 @@ int symbol__tty_annotate2(struct symbol *sym, struct map *map, } int symbol__tty_annotate(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, + struct evsel *evsel, struct annotation_options *opts) { struct dso *dso = map->dso; @@ -2956,7 +2956,7 @@ void annotation_line__write(struct annotation_line *al, struct annotation *notes wops->write_graph); } -int symbol__annotate2(struct symbol *sym, struct map *map, struct perf_evsel *evsel, +int symbol__annotate2(struct symbol *sym, struct map *map, struct evsel *evsel, struct annotation_options *options, struct arch **parch) { struct annotation *notes = symbol__annotation(sym); diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 5bc0cf655d37..7c42f320efa2 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -20,7 +20,7 @@ struct map_symbol; struct addr_map_symbol; struct option; struct perf_sample; -struct perf_evsel; +struct evsel; struct symbol; struct ins { @@ -216,12 +216,12 @@ void annotation_line__write(struct annotation_line *al, struct annotation *notes int __annotation__scnprintf_samples_period(struct annotation *notes, char *bf, size_t size, - struct perf_evsel *evsel, + struct evsel *evsel, bool show_freq); int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw, int max_ins_name); size_t disasm__fprintf(struct list_head *head, FILE *fp); -void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel); +void symbol__calc_percent(struct symbol *sym, struct evsel *evsel); struct sym_hist { u64 nr_samples; @@ -335,24 +335,24 @@ static inline struct annotation *symbol__annotation(struct symbol *sym) } int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample, - struct perf_evsel *evsel); + struct evsel *evsel); int addr_map_symbol__account_cycles(struct addr_map_symbol *ams, struct addr_map_symbol *start, unsigned cycles); int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample, - struct perf_evsel *evsel, u64 addr); + struct evsel *evsel, u64 addr); struct annotated_source *symbol__hists(struct symbol *sym, int nr_hists); void symbol__annotate_zero_histograms(struct symbol *sym); int symbol__annotate(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, size_t privsize, + struct evsel *evsel, size_t privsize, struct annotation_options *options, struct arch **parch); int symbol__annotate2(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, + struct evsel *evsel, struct annotation_options *options, struct arch **parch); @@ -378,32 +378,32 @@ int symbol__strerror_disassemble(struct symbol *sym, struct map *map, int errnum, char *buf, size_t buflen); int symbol__annotate_printf(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, + struct evsel *evsel, struct annotation_options *options); void symbol__annotate_zero_histogram(struct symbol *sym, int evidx); void symbol__annotate_decay_histogram(struct symbol *sym, int evidx); void annotated_source__purge(struct annotated_source *as); -int map_symbol__annotation_dump(struct map_symbol *ms, struct perf_evsel *evsel, +int map_symbol__annotation_dump(struct map_symbol *ms, struct evsel *evsel, struct annotation_options *opts); bool ui__has_annotation(void); int symbol__tty_annotate(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, struct annotation_options *opts); + struct evsel *evsel, struct annotation_options *opts); int symbol__tty_annotate2(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, struct annotation_options *opts); + struct evsel *evsel, struct annotation_options *opts); #ifdef HAVE_SLANG_SUPPORT int symbol__tui_annotate(struct symbol *sym, struct map *map, - struct perf_evsel *evsel, + struct evsel *evsel, struct hist_browser_timer *hbt, struct annotation_options *opts); #else static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused, struct map *map __maybe_unused, - struct perf_evsel *evsel __maybe_unused, + struct evsel *evsel __maybe_unused, struct hist_browser_timer *hbt __maybe_unused, struct annotation_options *opts __maybe_unused) { diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index ec0af36697c4..98b151bc9a36 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -2084,7 +2084,7 @@ static char *addr_filter__to_str(struct addr_filter *filt) return err < 0 ? NULL : filter; } -static int parse_addr_filter(struct perf_evsel *evsel, const char *filter, +static int parse_addr_filter(struct evsel *evsel, const char *filter, int max_nr) { struct addr_filters filts; @@ -2135,7 +2135,7 @@ out_exit: return err; } -static struct perf_pmu *perf_evsel__find_pmu(struct perf_evsel *evsel) +static struct perf_pmu *perf_evsel__find_pmu(struct evsel *evsel) { struct perf_pmu *pmu = NULL; @@ -2147,7 +2147,7 @@ static struct perf_pmu *perf_evsel__find_pmu(struct perf_evsel *evsel) return pmu; } -static int perf_evsel__nr_addr_filter(struct perf_evsel *evsel) +static int perf_evsel__nr_addr_filter(struct evsel *evsel) { struct perf_pmu *pmu = perf_evsel__find_pmu(evsel); int nr_addr_filters = 0; @@ -2162,7 +2162,7 @@ static int perf_evsel__nr_addr_filter(struct perf_evsel *evsel) int auxtrace_parse_filters(struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; char *filter; int err, max_nr; diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index 6d0dfb777a79..594ea279e25b 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -817,7 +817,7 @@ struct bpf_map_op { } k; union { u64 value; - struct perf_evsel *evsel; + struct evsel *evsel; } v; }; @@ -1063,7 +1063,7 @@ __bpf_map__config_event(struct bpf_map *map, struct parse_events_term *term, struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; const struct bpf_map_def *def; struct bpf_map_op *op; const char *map_name = bpf_map__name(map); @@ -1401,7 +1401,7 @@ apply_config_value_for_key(int map_fd, void *pkey, static int apply_config_evsel_for_key(const char *name, int map_fd, void *pkey, - struct perf_evsel *evsel) + struct evsel *evsel) { struct xyarray *xy = evsel->fd; struct perf_event_attr *attr; @@ -1523,11 +1523,11 @@ int bpf__apply_obj_config(void) (strcmp(name, \ bpf_map__name(pos)) == 0)) -struct perf_evsel *bpf__setup_output_event(struct perf_evlist *evlist, const char *name) +struct evsel *bpf__setup_output_event(struct perf_evlist *evlist, const char *name) { struct bpf_map_priv *tmpl_priv = NULL; struct bpf_object *obj, *tmp; - struct perf_evsel *evsel = NULL; + struct evsel *evsel = NULL; struct bpf_map *map; int err; bool need_init = false; @@ -1602,7 +1602,7 @@ struct perf_evsel *bpf__setup_output_event(struct perf_evlist *evlist, const cha int bpf__setup_stdout(struct perf_evlist *evlist) { - struct perf_evsel *evsel = bpf__setup_output_event(evlist, "__bpf_stdout__"); + struct evsel *evsel = bpf__setup_output_event(evlist, "__bpf_stdout__"); return PTR_ERR_OR_ZERO(evsel); } diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h index 8c3441a4b72c..e2048c978a24 100644 --- a/tools/perf/util/bpf-loader.h +++ b/tools/perf/util/bpf-loader.h @@ -39,7 +39,7 @@ enum bpf_loader_errno { __BPF_LOADER_ERRNO__END, }; -struct perf_evsel; +struct evsel; struct perf_evlist; struct bpf_object; struct parse_events_term; @@ -80,7 +80,7 @@ int bpf__apply_obj_config(void); int bpf__strerror_apply_obj_config(int err, char *buf, size_t size); int bpf__setup_stdout(struct perf_evlist *evlist); -struct perf_evsel *bpf__setup_output_event(struct perf_evlist *evlist, const char *name); +struct evsel *bpf__setup_output_event(struct perf_evlist *evlist, const char *name); int bpf__strerror_setup_output_event(struct perf_evlist *evlist, int err, char *buf, size_t size); #else #include @@ -137,7 +137,7 @@ bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused) return 0; } -static inline struct perf_evsel * +static inline struct evsel * bpf__setup_output_event(struct perf_evlist *evlist __maybe_unused, const char *name __maybe_unused) { return NULL; diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index f1abfab7aa8c..b98754863de9 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -37,7 +37,7 @@ static bool no_buildid_cache; int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel __maybe_unused, + struct evsel *evsel __maybe_unused, struct machine *machine) { struct addr_location al; diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h index 93668f38f1ed..aad419bb165c 100644 --- a/tools/perf/util/build-id.h +++ b/tools/perf/util/build-id.h @@ -24,7 +24,7 @@ char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size, bool is_debug); int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event, - struct perf_sample *sample, struct perf_evsel *evsel, + struct perf_sample *sample, struct evsel *evsel, struct machine *machine); int dsos__hit_all(struct perf_session *session); diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 8d7d8f62fcca..d077704f9afa 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -1077,7 +1077,7 @@ int callchain_cursor_append(struct callchain_cursor *cursor, int sample__resolve_callchain(struct perf_sample *sample, struct callchain_cursor *cursor, struct symbol **parent, - struct perf_evsel *evsel, struct addr_location *al, + struct evsel *evsel, struct addr_location *al, int max_stack) { if (sample->callchain == NULL && !symbol_conf.show_branchflag_count) diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 80e056a3d882..45b9ed49e2b1 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -236,7 +236,7 @@ int record_opts__parse_callchain(struct record_opts *record, int sample__resolve_callchain(struct perf_sample *sample, struct callchain_cursor *cursor, struct symbol **parent, - struct perf_evsel *evsel, struct addr_location *al, + struct evsel *evsel, struct addr_location *al, int max_stack); int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample); int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *node, diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 484c29830a81..4f5c326a9477 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -92,7 +92,7 @@ static int open_cgroup(const char *name) static struct cgroup *evlist__find_cgroup(struct perf_evlist *evlist, const char *str) { - struct perf_evsel *counter; + struct evsel *counter; /* * check if cgrp is already defined, if so we reuse it */ @@ -139,7 +139,7 @@ struct cgroup *evlist__findnew_cgroup(struct perf_evlist *evlist, const char *na static int add_cgroup(struct perf_evlist *evlist, const char *str) { - struct perf_evsel *counter; + struct evsel *counter; struct cgroup *cgrp = evlist__findnew_cgroup(evlist, str); int n; @@ -184,7 +184,7 @@ struct cgroup *cgroup__get(struct cgroup *cgroup) return cgroup; } -static void evsel__set_default_cgroup(struct perf_evsel *evsel, struct cgroup *cgroup) +static void evsel__set_default_cgroup(struct evsel *evsel, struct cgroup *cgroup) { if (evsel->cgrp == NULL) evsel->cgrp = cgroup__get(cgroup); @@ -192,7 +192,7 @@ static void evsel__set_default_cgroup(struct perf_evsel *evsel, struct cgroup *c void evlist__set_default_cgroup(struct perf_evlist *evlist, struct cgroup *cgroup) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) evsel__set_default_cgroup(evsel, cgroup); @@ -202,7 +202,7 @@ int parse_cgroups(const struct option *opt, const char *str, int unset __maybe_unused) { struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; - struct perf_evsel *counter; + struct evsel *counter; struct cgroup *cgrp = NULL; const char *p, *e, *eos = str + strlen(str); char *s; diff --git a/tools/perf/util/counts.c b/tools/perf/util/counts.c index 01ee81df3fe5..f94e1a23dad6 100644 --- a/tools/perf/util/counts.c +++ b/tools/perf/util/counts.c @@ -48,18 +48,18 @@ static void perf_counts__reset(struct perf_counts *counts) xyarray__reset(counts->values); } -void perf_evsel__reset_counts(struct perf_evsel *evsel) +void perf_evsel__reset_counts(struct evsel *evsel) { perf_counts__reset(evsel->counts); } -int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads) +int perf_evsel__alloc_counts(struct evsel *evsel, int ncpus, int nthreads) { evsel->counts = perf_counts__new(ncpus, nthreads); return evsel->counts != NULL ? 0 : -ENOMEM; } -void perf_evsel__free_counts(struct perf_evsel *evsel) +void perf_evsel__free_counts(struct evsel *evsel) { perf_counts__delete(evsel->counts); evsel->counts = NULL; diff --git a/tools/perf/util/counts.h b/tools/perf/util/counts.h index 460b56ce3252..0f0cb2d8f70d 100644 --- a/tools/perf/util/counts.h +++ b/tools/perf/util/counts.h @@ -44,8 +44,8 @@ perf_counts__set_loaded(struct perf_counts *counts, int cpu, int thread, bool lo struct perf_counts *perf_counts__new(int ncpus, int nthreads); void perf_counts__delete(struct perf_counts *counts); -void perf_evsel__reset_counts(struct perf_evsel *evsel); -int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads); -void perf_evsel__free_counts(struct perf_evsel *evsel); +void perf_evsel__reset_counts(struct evsel *evsel); +int perf_evsel__alloc_counts(struct evsel *evsel, int ncpus, int nthreads); +void perf_evsel__free_counts(struct evsel *evsel); #endif /* __PERF_COUNTS_H */ diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 3d1c34fc4d68..5a9fcb60ec88 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -1223,7 +1223,7 @@ static int cs_etm__synth_events(struct cs_etm_auxtrace *etm, struct perf_session *session) { struct perf_evlist *evlist = session->evlist; - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_event_attr attr; bool found = false; u64 id; @@ -2294,7 +2294,7 @@ static int cs_etm__process_auxtrace_event(struct perf_session *session, static bool cs_etm__is_timeless_decoding(struct cs_etm_auxtrace *etm) { - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_evlist *evlist = etm->session->evlist; bool timeless_decoding = true; diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index ddbcd59f2d9b..042ee5b6f9f1 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -413,7 +413,7 @@ static int add_tracepoint_fields_values(struct ctf_writer *cw, static int add_tracepoint_values(struct ctf_writer *cw, struct bt_ctf_event_class *event_class, struct bt_ctf_event *event, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { struct tep_format_field *common_fields = evsel->tp_format->format.common_fields; @@ -584,7 +584,7 @@ put_len_type: static int add_generic_values(struct ctf_writer *cw, struct bt_ctf_event *event, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample) { u64 type = evsel->attr.sample_type; @@ -753,7 +753,7 @@ static struct ctf_stream *ctf_stream(struct ctf_writer *cw, int cpu) } static int get_sample_cpu(struct ctf_writer *cw, struct perf_sample *sample, - struct perf_evsel *evsel) + struct evsel *evsel) { int cpu = 0; @@ -785,7 +785,7 @@ static bool is_flush_needed(struct ctf_stream *cs) static int process_sample_event(struct perf_tool *tool, union perf_event *_event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine __maybe_unused) { struct convert *c = container_of(tool, struct convert, tool); @@ -1051,7 +1051,7 @@ static int add_tracepoint_fields_types(struct ctf_writer *cw, } static int add_tracepoint_types(struct ctf_writer *cw, - struct perf_evsel *evsel, + struct evsel *evsel, struct bt_ctf_event_class *class) { struct tep_format_field *common_fields = evsel->tp_format->format.common_fields; @@ -1084,7 +1084,7 @@ static int add_bpf_output_types(struct ctf_writer *cw, return bt_ctf_event_class_add_field(class, seq_type, "raw_data"); } -static int add_generic_types(struct ctf_writer *cw, struct perf_evsel *evsel, +static int add_generic_types(struct ctf_writer *cw, struct evsel *evsel, struct bt_ctf_event_class *event_class) { u64 type = evsel->attr.sample_type; @@ -1150,7 +1150,7 @@ static int add_generic_types(struct ctf_writer *cw, struct perf_evsel *evsel, return 0; } -static int add_event(struct ctf_writer *cw, struct perf_evsel *evsel) +static int add_event(struct ctf_writer *cw, struct evsel *evsel) { struct bt_ctf_event_class *event_class; struct evsel_priv *priv; @@ -1202,7 +1202,7 @@ err: static int setup_events(struct ctf_writer *cw, struct perf_session *session) { struct perf_evlist *evlist = session->evlist; - struct perf_evsel *evsel; + struct evsel *evsel; int ret; evlist__for_each_entry(evlist, evsel) { @@ -1309,7 +1309,7 @@ static int setup_non_sample_events(struct ctf_writer *cw, static void cleanup_events(struct perf_session *session) { struct perf_evlist *evlist = session->evlist; - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { struct evsel_priv *priv; diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c index ffbb3e7d3288..dc2d4de772e3 100644 --- a/tools/perf/util/db-export.c +++ b/tools/perf/util/db-export.c @@ -32,7 +32,7 @@ void db_export__exit(struct db_export *dbe) dbe->crp = NULL; } -int db_export__evsel(struct db_export *dbe, struct perf_evsel *evsel) +int db_export__evsel(struct db_export *dbe, struct evsel *evsel) { if (evsel->db_id) return 0; @@ -209,7 +209,7 @@ static struct call_path *call_path_from_sample(struct db_export *dbe, struct machine *machine, struct thread *thread, struct perf_sample *sample, - struct perf_evsel *evsel) + struct evsel *evsel) { u64 kernel_start = machine__kernel_start(machine); struct call_path *current = &dbe->cpr->call_path; @@ -341,7 +341,7 @@ static int db_export__threads(struct db_export *dbe, struct thread *thread, } int db_export__sample(struct db_export *dbe, union perf_event *event, - struct perf_sample *sample, struct perf_evsel *evsel, + struct perf_sample *sample, struct evsel *evsel, struct addr_location *al) { struct thread *thread = al->thread; diff --git a/tools/perf/util/db-export.h b/tools/perf/util/db-export.h index ba1f62a5fe10..9c3d38f5a40d 100644 --- a/tools/perf/util/db-export.h +++ b/tools/perf/util/db-export.h @@ -10,7 +10,7 @@ #include #include -struct perf_evsel; +struct evsel; struct machine; struct thread; struct comm; @@ -25,7 +25,7 @@ struct call_return; struct export_sample { union perf_event *event; struct perf_sample *sample; - struct perf_evsel *evsel; + struct evsel *evsel; struct addr_location *al; u64 db_id; u64 comm_db_id; @@ -39,7 +39,7 @@ struct export_sample { }; struct db_export { - int (*export_evsel)(struct db_export *dbe, struct perf_evsel *evsel); + int (*export_evsel)(struct db_export *dbe, struct evsel *evsel); int (*export_machine)(struct db_export *dbe, struct machine *machine); int (*export_thread)(struct db_export *dbe, struct thread *thread, u64 main_thread_db_id, struct machine *machine); @@ -79,7 +79,7 @@ struct db_export { int db_export__init(struct db_export *dbe); void db_export__exit(struct db_export *dbe); -int db_export__evsel(struct db_export *dbe, struct perf_evsel *evsel); +int db_export__evsel(struct db_export *dbe, struct evsel *evsel); int db_export__machine(struct db_export *dbe, struct machine *machine); int db_export__thread(struct db_export *dbe, struct thread *thread, struct machine *machine, struct thread *main_thread); @@ -96,7 +96,7 @@ int db_export__symbol(struct db_export *dbe, struct symbol *sym, int db_export__branch_type(struct db_export *dbe, u32 branch_type, const char *name); int db_export__sample(struct db_export *dbe, union perf_event *event, - struct perf_sample *sample, struct perf_evsel *evsel, + struct perf_sample *sample, struct evsel *evsel, struct addr_location *al); int db_export__branch_types(struct db_export *dbe); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index a95d0461f718..7e6066cb525b 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -98,7 +98,7 @@ struct perf_evlist *perf_evlist__new_dummy(void) */ void perf_evlist__set_id_pos(struct perf_evlist *evlist) { - struct perf_evsel *first = perf_evlist__first(evlist); + struct evsel *first = perf_evlist__first(evlist); evlist->id_pos = first->id_pos; evlist->is_pos = first->is_pos; @@ -106,7 +106,7 @@ void perf_evlist__set_id_pos(struct perf_evlist *evlist) static void perf_evlist__update_id_pos(struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) perf_evsel__calc_id_pos(evsel); @@ -116,7 +116,7 @@ static void perf_evlist__update_id_pos(struct perf_evlist *evlist) static void perf_evlist__purge(struct perf_evlist *evlist) { - struct perf_evsel *pos, *n; + struct evsel *pos, *n; evlist__for_each_entry_safe(evlist, n, pos) { list_del_init(&pos->node); @@ -151,7 +151,7 @@ void perf_evlist__delete(struct perf_evlist *evlist) } static void __perf_evlist__propagate_maps(struct perf_evlist *evlist, - struct perf_evsel *evsel) + struct evsel *evsel) { /* * We already have cpus for evsel (via PMU sysfs) so @@ -171,13 +171,13 @@ static void __perf_evlist__propagate_maps(struct perf_evlist *evlist, static void perf_evlist__propagate_maps(struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) __perf_evlist__propagate_maps(evlist, evsel); } -void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) +void perf_evlist__add(struct perf_evlist *evlist, struct evsel *entry) { entry->evlist = evlist; list_add_tail(&entry->node, &evlist->entries); @@ -190,7 +190,7 @@ void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) __perf_evlist__propagate_maps(evlist, entry); } -void perf_evlist__remove(struct perf_evlist *evlist, struct perf_evsel *evsel) +void perf_evlist__remove(struct perf_evlist *evlist, struct evsel *evsel) { evsel->evlist = NULL; list_del_init(&evsel->node); @@ -200,7 +200,7 @@ void perf_evlist__remove(struct perf_evlist *evlist, struct perf_evsel *evsel) void perf_evlist__splice_list_tail(struct perf_evlist *evlist, struct list_head *list) { - struct perf_evsel *evsel, *temp; + struct evsel *evsel, *temp; __evlist__for_each_entry_safe(list, temp, evsel) { list_del_init(&evsel->node); @@ -210,10 +210,10 @@ void perf_evlist__splice_list_tail(struct perf_evlist *evlist, void __perf_evlist__set_leader(struct list_head *list) { - struct perf_evsel *evsel, *leader; + struct evsel *evsel, *leader; - leader = list_entry(list->next, struct perf_evsel, node); - evsel = list_entry(list->prev, struct perf_evsel, node); + leader = list_entry(list->next, struct evsel, node); + evsel = list_entry(list->prev, struct evsel, node); leader->nr_members = evsel->idx - leader->idx + 1; @@ -232,7 +232,7 @@ void perf_evlist__set_leader(struct perf_evlist *evlist) int __perf_evlist__add_default(struct perf_evlist *evlist, bool precise) { - struct perf_evsel *evsel = perf_evsel__new_cycles(precise); + struct evsel *evsel = perf_evsel__new_cycles(precise); if (evsel == NULL) return -ENOMEM; @@ -248,7 +248,7 @@ int perf_evlist__add_dummy(struct perf_evlist *evlist) .config = PERF_COUNT_SW_DUMMY, .size = sizeof(attr), /* to capture ABI version */ }; - struct perf_evsel *evsel = perf_evsel__new_idx(&attr, evlist->nr_entries); + struct evsel *evsel = perf_evsel__new_idx(&attr, evlist->nr_entries); if (evsel == NULL) return -ENOMEM; @@ -260,7 +260,7 @@ int perf_evlist__add_dummy(struct perf_evlist *evlist) static int perf_evlist__add_attrs(struct perf_evlist *evlist, struct perf_event_attr *attrs, size_t nr_attrs) { - struct perf_evsel *evsel, *n; + struct evsel *evsel, *n; LIST_HEAD(head); size_t i; @@ -292,10 +292,10 @@ int __perf_evlist__add_default_attrs(struct perf_evlist *evlist, return perf_evlist__add_attrs(evlist, attrs, nr_attrs); } -struct perf_evsel * +struct evsel * perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { if (evsel->attr.type == PERF_TYPE_TRACEPOINT && @@ -306,11 +306,11 @@ perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id) return NULL; } -struct perf_evsel * +struct evsel * perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist, const char *name) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { if ((evsel->attr.type == PERF_TYPE_TRACEPOINT) && @@ -324,7 +324,7 @@ perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist, int perf_evlist__add_newtp(struct perf_evlist *evlist, const char *sys, const char *name, void *handler) { - struct perf_evsel *evsel = perf_evsel__newtp(sys, name); + struct evsel *evsel = perf_evsel__newtp(sys, name); if (IS_ERR(evsel)) return -1; @@ -335,7 +335,7 @@ int perf_evlist__add_newtp(struct perf_evlist *evlist, } static int perf_evlist__nr_threads(struct perf_evlist *evlist, - struct perf_evsel *evsel) + struct evsel *evsel) { if (evsel->system_wide) return 1; @@ -345,7 +345,7 @@ static int perf_evlist__nr_threads(struct perf_evlist *evlist, void perf_evlist__disable(struct perf_evlist *evlist) { - struct perf_evsel *pos; + struct evsel *pos; evlist__for_each_entry(evlist, pos) { if (pos->disabled || !perf_evsel__is_group_leader(pos) || !pos->fd) @@ -358,7 +358,7 @@ void perf_evlist__disable(struct perf_evlist *evlist) void perf_evlist__enable(struct perf_evlist *evlist) { - struct perf_evsel *pos; + struct evsel *pos; evlist__for_each_entry(evlist, pos) { if (!perf_evsel__is_group_leader(pos) || !pos->fd) @@ -375,7 +375,7 @@ void perf_evlist__toggle_enable(struct perf_evlist *evlist) } static int perf_evlist__enable_event_cpu(struct perf_evlist *evlist, - struct perf_evsel *evsel, int cpu) + struct evsel *evsel, int cpu) { int thread; int nr_threads = perf_evlist__nr_threads(evlist, evsel); @@ -392,7 +392,7 @@ static int perf_evlist__enable_event_cpu(struct perf_evlist *evlist, } static int perf_evlist__enable_event_thread(struct perf_evlist *evlist, - struct perf_evsel *evsel, + struct evsel *evsel, int thread) { int cpu; @@ -410,7 +410,7 @@ static int perf_evlist__enable_event_thread(struct perf_evlist *evlist, } int perf_evlist__enable_event_idx(struct perf_evlist *evlist, - struct perf_evsel *evsel, int idx) + struct evsel *evsel, int idx) { bool per_cpu_mmaps = !cpu_map__empty(evlist->cpus); @@ -425,7 +425,7 @@ int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) int nr_cpus = cpu_map__nr(evlist->cpus); int nr_threads = thread_map__nr(evlist->threads); int nfds = 0; - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { if (evsel->system_wide) @@ -484,7 +484,7 @@ int perf_evlist__poll(struct perf_evlist *evlist, int timeout) } static void perf_evlist__id_hash(struct perf_evlist *evlist, - struct perf_evsel *evsel, + struct evsel *evsel, int cpu, int thread, u64 id) { int hash; @@ -496,7 +496,7 @@ static void perf_evlist__id_hash(struct perf_evlist *evlist, hlist_add_head(&sid->node, &evlist->heads[hash]); } -void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel, +void perf_evlist__id_add(struct perf_evlist *evlist, struct evsel *evsel, int cpu, int thread, u64 id) { perf_evlist__id_hash(evlist, evsel, cpu, thread, id); @@ -504,7 +504,7 @@ void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel, } int perf_evlist__id_add_fd(struct perf_evlist *evlist, - struct perf_evsel *evsel, + struct evsel *evsel, int cpu, int thread, int fd) { u64 read_data[4] = { 0, }; @@ -545,7 +545,7 @@ int perf_evlist__id_add_fd(struct perf_evlist *evlist, } static void perf_evlist__set_sid_idx(struct perf_evlist *evlist, - struct perf_evsel *evsel, int idx, int cpu, + struct evsel *evsel, int idx, int cpu, int thread) { struct perf_sample_id *sid = SID(evsel, cpu, thread); @@ -576,7 +576,7 @@ struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id) return NULL; } -struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id) +struct evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id) { struct perf_sample_id *sid; @@ -593,7 +593,7 @@ struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id) return NULL; } -struct perf_evsel *perf_evlist__id2evsel_strict(struct perf_evlist *evlist, +struct evsel *perf_evlist__id2evsel_strict(struct perf_evlist *evlist, u64 id) { struct perf_sample_id *sid; @@ -629,10 +629,10 @@ static int perf_evlist__event2id(struct perf_evlist *evlist, return 0; } -struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist, +struct evsel *perf_evlist__event2evsel(struct perf_evlist *evlist, union perf_event *event) { - struct perf_evsel *first = perf_evlist__first(evlist); + struct evsel *first = perf_evlist__first(evlist); struct hlist_head *head; struct perf_sample_id *sid; int hash; @@ -744,7 +744,7 @@ static struct perf_mmap *perf_evlist__alloc_mmap(struct perf_evlist *evlist, static bool perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused, - struct perf_evsel *evsel) + struct evsel *evsel) { if (evsel->attr.write_backward) return false; @@ -755,7 +755,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, struct mmap_params *mp, int cpu_idx, int thread, int *_output, int *_output_overwrite) { - struct perf_evsel *evsel; + struct evsel *evsel; int revent; int evlist_cpu = cpu_map__cpu(evlist->cpus, cpu_idx); @@ -1011,7 +1011,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, bool auxtrace_overwrite, int nr_cblocks, int affinity, int flush, int comp_level) { - struct perf_evsel *evsel; + struct evsel *evsel; const struct perf_cpu_map *cpus = evlist->cpus; const struct perf_thread_map *threads = evlist->threads; /* @@ -1130,7 +1130,7 @@ void perf_evlist__set_maps(struct perf_evlist *evlist, struct perf_cpu_map *cpus void __perf_evlist__set_sample_bit(struct perf_evlist *evlist, enum perf_event_sample_format bit) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) __perf_evsel__set_sample_bit(evsel, bit); @@ -1139,15 +1139,15 @@ void __perf_evlist__set_sample_bit(struct perf_evlist *evlist, void __perf_evlist__reset_sample_bit(struct perf_evlist *evlist, enum perf_event_sample_format bit) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) __perf_evsel__reset_sample_bit(evsel, bit); } -int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel) +int perf_evlist__apply_filters(struct perf_evlist *evlist, struct evsel **err_evsel) { - struct perf_evsel *evsel; + struct evsel *evsel; int err = 0; evlist__for_each_entry(evlist, evsel) { @@ -1170,7 +1170,7 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **e int perf_evlist__set_tp_filter(struct perf_evlist *evlist, const char *filter) { - struct perf_evsel *evsel; + struct evsel *evsel; int err = 0; evlist__for_each_entry(evlist, evsel) { @@ -1219,7 +1219,7 @@ int perf_evlist__set_tp_filter_pid(struct perf_evlist *evlist, pid_t pid) bool perf_evlist__valid_sample_type(struct perf_evlist *evlist) { - struct perf_evsel *pos; + struct evsel *pos; if (evlist->nr_entries == 1) return true; @@ -1238,7 +1238,7 @@ bool perf_evlist__valid_sample_type(struct perf_evlist *evlist) u64 __perf_evlist__combined_sample_type(struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; if (evlist->combined_sample_type) return evlist->combined_sample_type; @@ -1257,7 +1257,7 @@ u64 perf_evlist__combined_sample_type(struct perf_evlist *evlist) u64 perf_evlist__combined_branch_type(struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; u64 branch_type = 0; evlist__for_each_entry(evlist, evsel) @@ -1267,7 +1267,7 @@ u64 perf_evlist__combined_branch_type(struct perf_evlist *evlist) bool perf_evlist__valid_read_format(struct perf_evlist *evlist) { - struct perf_evsel *first = perf_evlist__first(evlist), *pos = first; + struct evsel *first = perf_evlist__first(evlist), *pos = first; u64 read_format = first->attr.read_format; u64 sample_type = first->attr.sample_type; @@ -1287,13 +1287,13 @@ bool perf_evlist__valid_read_format(struct perf_evlist *evlist) u64 perf_evlist__read_format(struct perf_evlist *evlist) { - struct perf_evsel *first = perf_evlist__first(evlist); + struct evsel *first = perf_evlist__first(evlist); return first->attr.read_format; } u16 perf_evlist__id_hdr_size(struct perf_evlist *evlist) { - struct perf_evsel *first = perf_evlist__first(evlist); + struct evsel *first = perf_evlist__first(evlist); struct perf_sample *data; u64 sample_type; u16 size = 0; @@ -1326,7 +1326,7 @@ out: bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist) { - struct perf_evsel *first = perf_evlist__first(evlist), *pos = first; + struct evsel *first = perf_evlist__first(evlist), *pos = first; evlist__for_each_entry_continue(evlist, pos) { if (first->attr.sample_id_all != pos->attr.sample_id_all) @@ -1338,19 +1338,19 @@ bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist) bool perf_evlist__sample_id_all(struct perf_evlist *evlist) { - struct perf_evsel *first = perf_evlist__first(evlist); + struct evsel *first = perf_evlist__first(evlist); return first->attr.sample_id_all; } void perf_evlist__set_selected(struct perf_evlist *evlist, - struct perf_evsel *evsel) + struct evsel *evsel) { evlist->selected = evsel; } void perf_evlist__close(struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry_reverse(evlist, evsel) perf_evsel__close(evsel); @@ -1389,7 +1389,7 @@ out_put: int perf_evlist__open(struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; int err; /* @@ -1553,7 +1553,7 @@ int perf_evlist__start_workload(struct perf_evlist *evlist) int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event, struct perf_sample *sample) { - struct perf_evsel *evsel = perf_evlist__event2evsel(evlist, event); + struct evsel *evsel = perf_evlist__event2evsel(evlist, event); if (!evsel) return -EFAULT; @@ -1564,7 +1564,7 @@ int perf_evlist__parse_sample_timestamp(struct perf_evlist *evlist, union perf_event *event, u64 *timestamp) { - struct perf_evsel *evsel = perf_evlist__event2evsel(evlist, event); + struct evsel *evsel = perf_evlist__event2evsel(evlist, event); if (!evsel) return -EFAULT; @@ -1573,7 +1573,7 @@ int perf_evlist__parse_sample_timestamp(struct perf_evlist *evlist, size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp) { - struct perf_evsel *evsel; + struct evsel *evsel; size_t printed = 0; evlist__for_each_entry(evlist, evsel) { @@ -1613,7 +1613,7 @@ int perf_evlist__strerror_open(struct perf_evlist *evlist, "Hint:\tThe current value is %d.", value); break; case EINVAL: { - struct perf_evsel *first = perf_evlist__first(evlist); + struct evsel *first = perf_evlist__first(evlist); int max_freq; if (sysctl__read_int("kernel/perf_event_max_sample_rate", &max_freq) < 0) @@ -1670,9 +1670,9 @@ int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, s } void perf_evlist__to_front(struct perf_evlist *evlist, - struct perf_evsel *move_evsel) + struct evsel *move_evsel) { - struct perf_evsel *evsel, *n; + struct evsel *evsel, *n; LIST_HEAD(move); if (move_evsel == perf_evlist__first(evlist)) @@ -1687,9 +1687,9 @@ void perf_evlist__to_front(struct perf_evlist *evlist, } void perf_evlist__set_tracking_event(struct perf_evlist *evlist, - struct perf_evsel *tracking_evsel) + struct evsel *tracking_evsel) { - struct perf_evsel *evsel; + struct evsel *evsel; if (tracking_evsel->tracking) return; @@ -1702,11 +1702,11 @@ void perf_evlist__set_tracking_event(struct perf_evlist *evlist, tracking_evsel->tracking = true; } -struct perf_evsel * +struct evsel * perf_evlist__find_evsel_by_str(struct perf_evlist *evlist, const char *str) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { if (!evsel->name) @@ -1778,7 +1778,7 @@ state_err: bool perf_evlist__exclude_kernel(struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { if (!evsel->attr.exclude_kernel) @@ -1796,17 +1796,17 @@ bool perf_evlist__exclude_kernel(struct perf_evlist *evlist) void perf_evlist__force_leader(struct perf_evlist *evlist) { if (!evlist->nr_groups) { - struct perf_evsel *leader = perf_evlist__first(evlist); + struct evsel *leader = perf_evlist__first(evlist); perf_evlist__set_leader(evlist); leader->forced_leader = true; } } -struct perf_evsel *perf_evlist__reset_weak_group(struct perf_evlist *evsel_list, - struct perf_evsel *evsel) +struct evsel *perf_evlist__reset_weak_group(struct perf_evlist *evsel_list, + struct evsel *evsel) { - struct perf_evsel *c2, *leader; + struct evsel *c2, *leader; bool is_open = true; leader = evsel->leader; @@ -1835,7 +1835,7 @@ int perf_evlist__add_sb_event(struct perf_evlist **evlist, perf_evsel__sb_cb_t cb, void *data) { - struct perf_evsel *evsel; + struct evsel *evsel; bool new_evlist = (*evlist) == NULL; if (*evlist == NULL) @@ -1887,7 +1887,7 @@ static void *perf_evlist__poll_thread(void *arg) if (perf_mmap__read_init(map)) continue; while ((event = perf_mmap__read_event(map)) != NULL) { - struct perf_evsel *evsel = perf_evlist__event2evsel(evlist, event); + struct evsel *evsel = perf_evlist__event2evsel(evlist, event); if (evsel && evsel->side_band.cb) evsel->side_band.cb(event, evsel->side_band.data); @@ -1909,7 +1909,7 @@ static void *perf_evlist__poll_thread(void *arg) int perf_evlist__start_sb_thread(struct perf_evlist *evlist, struct target *target) { - struct perf_evsel *counter; + struct evsel *counter; if (!evlist) return 0; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index ab2f0b6c7640..576d59a0d8cf 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -46,7 +46,7 @@ struct perf_evlist { struct perf_mmap *overwrite_mmap; struct perf_thread_map *threads; struct perf_cpu_map *cpus; - struct perf_evsel *selected; + struct evsel *selected; struct events_stats stats; struct perf_env *env; void (*trace_event_sample_raw)(struct perf_evlist *evlist, @@ -60,7 +60,7 @@ struct perf_evlist { } thread; }; -struct perf_evsel_str_handler { +struct evsel_str_handler { const char *name; void *handler; }; @@ -73,8 +73,8 @@ void perf_evlist__init(struct perf_evlist *evlist, struct perf_cpu_map *cpus, void perf_evlist__exit(struct perf_evlist *evlist); void perf_evlist__delete(struct perf_evlist *evlist); -void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry); -void perf_evlist__remove(struct perf_evlist *evlist, struct perf_evsel *evsel); +void perf_evlist__add(struct perf_evlist *evlist, struct evsel *entry); +void perf_evlist__remove(struct perf_evlist *evlist, struct evsel *evsel); int __perf_evlist__add_default(struct perf_evlist *evlist, bool precise); @@ -117,17 +117,17 @@ int perf_evlist__set_tp_filter(struct perf_evlist *evlist, const char *filter); int perf_evlist__set_tp_filter_pid(struct perf_evlist *evlist, pid_t pid); int perf_evlist__set_tp_filter_pids(struct perf_evlist *evlist, size_t npids, pid_t *pids); -struct perf_evsel * +struct evsel * perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id); -struct perf_evsel * +struct evsel * perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist, const char *name); -void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel, +void perf_evlist__id_add(struct perf_evlist *evlist, struct evsel *evsel, int cpu, int thread, u64 id); int perf_evlist__id_add_fd(struct perf_evlist *evlist, - struct perf_evsel *evsel, + struct evsel *evsel, int cpu, int thread, int fd); int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd); @@ -136,8 +136,8 @@ int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mas int perf_evlist__poll(struct perf_evlist *evlist, int timeout); -struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id); -struct perf_evsel *perf_evlist__id2evsel_strict(struct perf_evlist *evlist, +struct evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id); +struct evsel *perf_evlist__id2evsel_strict(struct perf_evlist *evlist, u64 id); struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id); @@ -189,15 +189,15 @@ void perf_evlist__enable(struct perf_evlist *evlist); void perf_evlist__toggle_enable(struct perf_evlist *evlist); int perf_evlist__enable_event_idx(struct perf_evlist *evlist, - struct perf_evsel *evsel, int idx); + struct evsel *evsel, int idx); void perf_evlist__set_selected(struct perf_evlist *evlist, - struct perf_evsel *evsel); + struct evsel *evsel); void perf_evlist__set_maps(struct perf_evlist *evlist, struct perf_cpu_map *cpus, struct perf_thread_map *threads); int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target); -int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel); +int perf_evlist__apply_filters(struct perf_evlist *evlist, struct evsel **err_evsel); void __perf_evlist__set_leader(struct list_head *list); void perf_evlist__set_leader(struct perf_evlist *evlist); @@ -228,14 +228,14 @@ static inline bool perf_evlist__empty(struct perf_evlist *evlist) return list_empty(&evlist->entries); } -static inline struct perf_evsel *perf_evlist__first(struct perf_evlist *evlist) +static inline struct evsel *perf_evlist__first(struct perf_evlist *evlist) { - return list_entry(evlist->entries.next, struct perf_evsel, node); + return list_entry(evlist->entries.next, struct evsel, node); } -static inline struct perf_evsel *perf_evlist__last(struct perf_evlist *evlist) +static inline struct evsel *perf_evlist__last(struct perf_evlist *evlist) { - return list_entry(evlist->entries.prev, struct perf_evsel, node); + return list_entry(evlist->entries.prev, struct evsel, node); } size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp); @@ -245,7 +245,7 @@ int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, s bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str); void perf_evlist__to_front(struct perf_evlist *evlist, - struct perf_evsel *move_evsel); + struct evsel *move_evsel); /** * __evlist__for_each_entry - iterate thru all the evsels @@ -314,18 +314,18 @@ void perf_evlist__to_front(struct perf_evlist *evlist, __evlist__for_each_entry_safe(&(evlist)->entries, tmp, evsel) void perf_evlist__set_tracking_event(struct perf_evlist *evlist, - struct perf_evsel *tracking_evsel); + struct evsel *tracking_evsel); -struct perf_evsel * +struct evsel * perf_evlist__find_evsel_by_str(struct perf_evlist *evlist, const char *str); -struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist, +struct evsel *perf_evlist__event2evsel(struct perf_evlist *evlist, union perf_event *event); bool perf_evlist__exclude_kernel(struct perf_evlist *evlist); void perf_evlist__force_leader(struct perf_evlist *evlist); -struct perf_evsel *perf_evlist__reset_weak_group(struct perf_evlist *evlist, - struct perf_evsel *evsel); +struct evsel *perf_evlist__reset_weak_group(struct perf_evlist *evlist, + struct evsel *evsel); #endif /* __PERF_EVLIST_H */ diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index ab66d65b7968..44421bbebd64 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -45,30 +45,30 @@ struct perf_missing_features perf_missing_features; static clockid_t clockid; -static int perf_evsel__no_extra_init(struct perf_evsel *evsel __maybe_unused) +static int perf_evsel__no_extra_init(struct evsel *evsel __maybe_unused) { return 0; } void __weak test_attr__ready(void) { } -static void perf_evsel__no_extra_fini(struct perf_evsel *evsel __maybe_unused) +static void perf_evsel__no_extra_fini(struct evsel *evsel __maybe_unused) { } static struct { size_t size; - int (*init)(struct perf_evsel *evsel); - void (*fini)(struct perf_evsel *evsel); + int (*init)(struct evsel *evsel); + void (*fini)(struct evsel *evsel); } perf_evsel__object = { - .size = sizeof(struct perf_evsel), + .size = sizeof(struct evsel), .init = perf_evsel__no_extra_init, .fini = perf_evsel__no_extra_fini, }; int perf_evsel__object_config(size_t object_size, - int (*init)(struct perf_evsel *evsel), - void (*fini)(struct perf_evsel *evsel)) + int (*init)(struct evsel *evsel), + void (*fini)(struct evsel *evsel)) { if (object_size == 0) @@ -167,13 +167,13 @@ static int __perf_evsel__calc_is_pos(u64 sample_type) return idx; } -void perf_evsel__calc_id_pos(struct perf_evsel *evsel) +void perf_evsel__calc_id_pos(struct evsel *evsel) { evsel->id_pos = __perf_evsel__calc_id_pos(evsel->attr.sample_type); evsel->is_pos = __perf_evsel__calc_is_pos(evsel->attr.sample_type); } -void __perf_evsel__set_sample_bit(struct perf_evsel *evsel, +void __perf_evsel__set_sample_bit(struct evsel *evsel, enum perf_event_sample_format bit) { if (!(evsel->attr.sample_type & bit)) { @@ -183,7 +183,7 @@ void __perf_evsel__set_sample_bit(struct perf_evsel *evsel, } } -void __perf_evsel__reset_sample_bit(struct perf_evsel *evsel, +void __perf_evsel__reset_sample_bit(struct evsel *evsel, enum perf_event_sample_format bit) { if (evsel->attr.sample_type & bit) { @@ -193,7 +193,7 @@ void __perf_evsel__reset_sample_bit(struct perf_evsel *evsel, } } -void perf_evsel__set_sample_id(struct perf_evsel *evsel, +void perf_evsel__set_sample_id(struct evsel *evsel, bool can_sample_identifier) { if (can_sample_identifier) { @@ -213,7 +213,7 @@ void perf_evsel__set_sample_id(struct perf_evsel *evsel, * * Return %true if event is function trace event */ -bool perf_evsel__is_function_event(struct perf_evsel *evsel) +bool perf_evsel__is_function_event(struct evsel *evsel) { #define FUNCTION_EVENT "ftrace:function" @@ -223,7 +223,7 @@ bool perf_evsel__is_function_event(struct perf_evsel *evsel) #undef FUNCTION_EVENT } -void perf_evsel__init(struct perf_evsel *evsel, +void perf_evsel__init(struct evsel *evsel, struct perf_event_attr *attr, int idx) { evsel->idx = idx; @@ -249,9 +249,9 @@ void perf_evsel__init(struct perf_evsel *evsel, evsel->pmu_name = NULL; } -struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) +struct evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) { - struct perf_evsel *evsel = zalloc(perf_evsel__object.size); + struct evsel *evsel = zalloc(perf_evsel__object.size); if (!evsel) return NULL; @@ -282,14 +282,14 @@ static bool perf_event_can_profile_kernel(void) return geteuid() == 0 || perf_event_paranoid() == -1; } -struct perf_evsel *perf_evsel__new_cycles(bool precise) +struct evsel *perf_evsel__new_cycles(bool precise) { struct perf_event_attr attr = { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES, .exclude_kernel = !perf_event_can_profile_kernel(), }; - struct perf_evsel *evsel; + struct evsel *evsel; event_attr_init(&attr); @@ -324,9 +324,9 @@ error_free: /* * Returns pointer with encoded error via interface. */ -struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx) +struct evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx) { - struct perf_evsel *evsel = zalloc(perf_evsel__object.size); + struct evsel *evsel = zalloc(perf_evsel__object.size); int err = -ENOMEM; if (evsel == NULL) { @@ -383,7 +383,7 @@ static const char *__perf_evsel__hw_name(u64 config) return "unknown-hardware"; } -static int perf_evsel__add_modifiers(struct perf_evsel *evsel, char *bf, size_t size) +static int perf_evsel__add_modifiers(struct evsel *evsel, char *bf, size_t size) { int colon = 0, r = 0; struct perf_event_attr *attr = &evsel->attr; @@ -419,7 +419,7 @@ static int perf_evsel__add_modifiers(struct perf_evsel *evsel, char *bf, size_t return r; } -static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) +static int perf_evsel__hw_name(struct evsel *evsel, char *bf, size_t size) { int r = scnprintf(bf, size, "%s", __perf_evsel__hw_name(evsel->attr.config)); return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); @@ -445,7 +445,7 @@ static const char *__perf_evsel__sw_name(u64 config) return "unknown-software"; } -static int perf_evsel__sw_name(struct perf_evsel *evsel, char *bf, size_t size) +static int perf_evsel__sw_name(struct evsel *evsel, char *bf, size_t size) { int r = scnprintf(bf, size, "%s", __perf_evsel__sw_name(evsel->attr.config)); return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); @@ -469,7 +469,7 @@ static int __perf_evsel__bp_name(char *bf, size_t size, u64 addr, u64 type) return r; } -static int perf_evsel__bp_name(struct perf_evsel *evsel, char *bf, size_t size) +static int perf_evsel__bp_name(struct evsel *evsel, char *bf, size_t size) { struct perf_event_attr *attr = &evsel->attr; int r = __perf_evsel__bp_name(bf, size, attr->bp_addr, attr->bp_type); @@ -569,13 +569,13 @@ out_err: return scnprintf(bf, size, "%s", err); } -static int perf_evsel__hw_cache_name(struct perf_evsel *evsel, char *bf, size_t size) +static int perf_evsel__hw_cache_name(struct evsel *evsel, char *bf, size_t size) { int ret = __perf_evsel__hw_cache_name(evsel->attr.config, bf, size); return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret); } -static int perf_evsel__raw_name(struct perf_evsel *evsel, char *bf, size_t size) +static int perf_evsel__raw_name(struct evsel *evsel, char *bf, size_t size) { int ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->attr.config); return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret); @@ -587,7 +587,7 @@ static int perf_evsel__tool_name(char *bf, size_t size) return ret; } -const char *perf_evsel__name(struct perf_evsel *evsel) +const char *perf_evsel__name(struct evsel *evsel) { char bf[128]; @@ -639,7 +639,7 @@ out_unknown: return "unknown"; } -const char *perf_evsel__group_name(struct perf_evsel *evsel) +const char *perf_evsel__group_name(struct evsel *evsel) { return evsel->group_name ?: "anon group"; } @@ -654,10 +654,10 @@ const char *perf_evsel__group_name(struct perf_evsel *evsel) * For record -e 'cycles,instructions' and report --group * 'cycles:u, instructions:u' */ -int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size) +int perf_evsel__group_desc(struct evsel *evsel, char *buf, size_t size) { int ret = 0; - struct perf_evsel *pos; + struct evsel *pos; const char *group_name = perf_evsel__group_name(evsel); if (!evsel->forced_leader) @@ -676,7 +676,7 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size) return ret; } -static void __perf_evsel__config_callchain(struct perf_evsel *evsel, +static void __perf_evsel__config_callchain(struct evsel *evsel, struct record_opts *opts, struct callchain_param *param) { @@ -735,7 +735,7 @@ static void __perf_evsel__config_callchain(struct perf_evsel *evsel, } } -void perf_evsel__config_callchain(struct perf_evsel *evsel, +void perf_evsel__config_callchain(struct evsel *evsel, struct record_opts *opts, struct callchain_param *param) { @@ -744,7 +744,7 @@ void perf_evsel__config_callchain(struct perf_evsel *evsel, } static void -perf_evsel__reset_callgraph(struct perf_evsel *evsel, +perf_evsel__reset_callgraph(struct evsel *evsel, struct callchain_param *param) { struct perf_event_attr *attr = &evsel->attr; @@ -761,7 +761,7 @@ perf_evsel__reset_callgraph(struct perf_evsel *evsel, } } -static void apply_config_terms(struct perf_evsel *evsel, +static void apply_config_terms(struct evsel *evsel, struct record_opts *opts, bool track) { struct perf_evsel_config_term *term; @@ -886,7 +886,7 @@ static void apply_config_terms(struct perf_evsel *evsel, } } -static bool is_dummy_event(struct perf_evsel *evsel) +static bool is_dummy_event(struct evsel *evsel) { return (evsel->attr.type == PERF_TYPE_SOFTWARE) && (evsel->attr.config == PERF_COUNT_SW_DUMMY); @@ -920,10 +920,10 @@ static bool is_dummy_event(struct perf_evsel *evsel) * enable/disable events specifically, as there's no * initial traced exec call. */ -void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts, +void perf_evsel__config(struct evsel *evsel, struct record_opts *opts, struct callchain_param *callchain) { - struct perf_evsel *leader = evsel->leader; + struct evsel *leader = evsel->leader; struct perf_event_attr *attr = &evsel->attr; int track = evsel->tracking; bool per_cpu = opts->target.default_per_cpu && !opts->target.per_thread; @@ -1153,7 +1153,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts, perf_evsel__reset_sample_bit(evsel, BRANCH_STACK); } -static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) +static int perf_evsel__alloc_fd(struct evsel *evsel, int ncpus, int nthreads) { evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int)); @@ -1169,7 +1169,7 @@ static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthread return evsel->fd != NULL ? 0 : -ENOMEM; } -static int perf_evsel__run_ioctl(struct perf_evsel *evsel, +static int perf_evsel__run_ioctl(struct evsel *evsel, int ioc, void *arg) { int cpu, thread; @@ -1187,14 +1187,14 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel, return 0; } -int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter) +int perf_evsel__apply_filter(struct evsel *evsel, const char *filter) { return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_SET_FILTER, (void *)filter); } -int perf_evsel__set_filter(struct perf_evsel *evsel, const char *filter) +int perf_evsel__set_filter(struct evsel *evsel, const char *filter) { char *new_filter = strdup(filter); @@ -1207,7 +1207,7 @@ int perf_evsel__set_filter(struct perf_evsel *evsel, const char *filter) return -1; } -static int perf_evsel__append_filter(struct perf_evsel *evsel, +static int perf_evsel__append_filter(struct evsel *evsel, const char *fmt, const char *filter) { char *new_filter; @@ -1224,17 +1224,17 @@ static int perf_evsel__append_filter(struct perf_evsel *evsel, return -1; } -int perf_evsel__append_tp_filter(struct perf_evsel *evsel, const char *filter) +int perf_evsel__append_tp_filter(struct evsel *evsel, const char *filter) { return perf_evsel__append_filter(evsel, "(%s) && (%s)", filter); } -int perf_evsel__append_addr_filter(struct perf_evsel *evsel, const char *filter) +int perf_evsel__append_addr_filter(struct evsel *evsel, const char *filter) { return perf_evsel__append_filter(evsel, "%s,%s", filter); } -int perf_evsel__enable(struct perf_evsel *evsel) +int perf_evsel__enable(struct evsel *evsel) { int err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, 0); @@ -1244,7 +1244,7 @@ int perf_evsel__enable(struct perf_evsel *evsel) return err; } -int perf_evsel__disable(struct perf_evsel *evsel) +int perf_evsel__disable(struct evsel *evsel) { int err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_DISABLE, 0); /* @@ -1259,7 +1259,7 @@ int perf_evsel__disable(struct perf_evsel *evsel) return err; } -int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads) +int perf_evsel__alloc_id(struct evsel *evsel, int ncpus, int nthreads) { if (ncpus == 0 || nthreads == 0) return 0; @@ -1281,13 +1281,13 @@ int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads) return 0; } -static void perf_evsel__free_fd(struct perf_evsel *evsel) +static void perf_evsel__free_fd(struct evsel *evsel) { xyarray__delete(evsel->fd); evsel->fd = NULL; } -static void perf_evsel__free_id(struct perf_evsel *evsel) +static void perf_evsel__free_id(struct evsel *evsel) { xyarray__delete(evsel->sample_id); evsel->sample_id = NULL; @@ -1295,7 +1295,7 @@ static void perf_evsel__free_id(struct perf_evsel *evsel) evsel->ids = 0; } -static void perf_evsel__free_config_terms(struct perf_evsel *evsel) +static void perf_evsel__free_config_terms(struct evsel *evsel) { struct perf_evsel_config_term *term, *h; @@ -1305,7 +1305,7 @@ static void perf_evsel__free_config_terms(struct perf_evsel *evsel) } } -void perf_evsel__close_fd(struct perf_evsel *evsel) +void perf_evsel__close_fd(struct evsel *evsel) { int cpu, thread; @@ -1316,7 +1316,7 @@ void perf_evsel__close_fd(struct perf_evsel *evsel) } } -void perf_evsel__exit(struct perf_evsel *evsel) +void perf_evsel__exit(struct evsel *evsel) { assert(list_empty(&evsel->node)); assert(evsel->evlist == NULL); @@ -1333,13 +1333,13 @@ void perf_evsel__exit(struct perf_evsel *evsel) perf_evsel__object.fini(evsel); } -void perf_evsel__delete(struct perf_evsel *evsel) +void perf_evsel__delete(struct evsel *evsel) { perf_evsel__exit(evsel); free(evsel); } -void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu, int thread, +void perf_evsel__compute_deltas(struct evsel *evsel, int cpu, int thread, struct perf_counts_values *count) { struct perf_counts_values tmp; @@ -1379,7 +1379,7 @@ void perf_counts_values__scale(struct perf_counts_values *count, *pscaled = scaled; } -static int perf_evsel__read_size(struct perf_evsel *evsel) +static int perf_evsel__read_size(struct evsel *evsel) { u64 read_format = evsel->attr.read_format; int entry = sizeof(u64); /* value */ @@ -1404,7 +1404,7 @@ static int perf_evsel__read_size(struct perf_evsel *evsel) return size; } -int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread, +int perf_evsel__read(struct evsel *evsel, int cpu, int thread, struct perf_counts_values *count) { size_t size = perf_evsel__read_size(evsel); @@ -1421,7 +1421,7 @@ int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread, } static int -perf_evsel__read_one(struct perf_evsel *evsel, int cpu, int thread) +perf_evsel__read_one(struct evsel *evsel, int cpu, int thread) { struct perf_counts_values *count = perf_counts(evsel->counts, cpu, thread); @@ -1429,7 +1429,7 @@ perf_evsel__read_one(struct perf_evsel *evsel, int cpu, int thread) } static void -perf_evsel__set_count(struct perf_evsel *counter, int cpu, int thread, +perf_evsel__set_count(struct evsel *counter, int cpu, int thread, u64 val, u64 ena, u64 run) { struct perf_counts_values *count; @@ -1444,7 +1444,7 @@ perf_evsel__set_count(struct perf_evsel *counter, int cpu, int thread, } static int -perf_evsel__process_group_data(struct perf_evsel *leader, +perf_evsel__process_group_data(struct evsel *leader, int cpu, int thread, u64 *data) { u64 read_format = leader->attr.read_format; @@ -1468,7 +1468,7 @@ perf_evsel__process_group_data(struct perf_evsel *leader, v[0].value, ena, run); for (i = 1; i < nr; i++) { - struct perf_evsel *counter; + struct evsel *counter; counter = perf_evlist__id2evsel(leader->evlist, v[i].id); if (!counter) @@ -1482,7 +1482,7 @@ perf_evsel__process_group_data(struct perf_evsel *leader, } static int -perf_evsel__read_group(struct perf_evsel *leader, int cpu, int thread) +perf_evsel__read_group(struct evsel *leader, int cpu, int thread) { struct perf_stat_evsel *ps = leader->stats; u64 read_format = leader->attr.read_format; @@ -1512,7 +1512,7 @@ perf_evsel__read_group(struct perf_evsel *leader, int cpu, int thread) return perf_evsel__process_group_data(leader, cpu, thread, data); } -int perf_evsel__read_counter(struct perf_evsel *evsel, int cpu, int thread) +int perf_evsel__read_counter(struct evsel *evsel, int cpu, int thread) { u64 read_format = evsel->attr.read_format; @@ -1522,7 +1522,7 @@ int perf_evsel__read_counter(struct perf_evsel *evsel, int cpu, int thread) return perf_evsel__read_one(evsel, cpu, thread); } -int __perf_evsel__read_on_cpu(struct perf_evsel *evsel, +int __perf_evsel__read_on_cpu(struct evsel *evsel, int cpu, int thread, bool scale) { struct perf_counts_values count; @@ -1543,9 +1543,9 @@ int __perf_evsel__read_on_cpu(struct perf_evsel *evsel, return 0; } -static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread) +static int get_group_fd(struct evsel *evsel, int cpu, int thread) { - struct perf_evsel *leader = evsel->leader; + struct evsel *leader = evsel->leader; int fd; if (perf_evsel__is_group_leader(evsel)) @@ -1708,7 +1708,7 @@ static int __open_attr__fprintf(FILE *fp, const char *name, const char *val, return fprintf(fp, " %-32s %s\n", name, val); } -static void perf_evsel__remove_fd(struct perf_evsel *pos, +static void perf_evsel__remove_fd(struct evsel *pos, int nr_cpus, int nr_threads, int thread_idx) { @@ -1717,11 +1717,11 @@ static void perf_evsel__remove_fd(struct perf_evsel *pos, FD(pos, cpu, thread) = FD(pos, cpu, thread + 1); } -static int update_fds(struct perf_evsel *evsel, +static int update_fds(struct evsel *evsel, int nr_cpus, int cpu_idx, int nr_threads, int thread_idx) { - struct perf_evsel *pos; + struct evsel *pos; if (cpu_idx >= nr_cpus || thread_idx >= nr_threads) return -EINVAL; @@ -1741,7 +1741,7 @@ static int update_fds(struct perf_evsel *evsel, return 0; } -static bool ignore_missing_thread(struct perf_evsel *evsel, +static bool ignore_missing_thread(struct evsel *evsel, int nr_cpus, int cpu, struct perf_thread_map *threads, int thread, int err) @@ -1788,7 +1788,7 @@ static void display_attr(struct perf_event_attr *attr) } } -static int perf_event_open(struct perf_evsel *evsel, +static int perf_event_open(struct evsel *evsel, pid_t pid, int cpu, int group_fd, unsigned long flags) { @@ -1825,7 +1825,7 @@ static int perf_event_open(struct perf_evsel *evsel, return fd; } -int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus, +int perf_evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus, struct perf_thread_map *threads) { int cpu, thread, nthreads; @@ -2073,7 +2073,7 @@ out_close: return err; } -void perf_evsel__close(struct perf_evsel *evsel) +void perf_evsel__close(struct evsel *evsel) { if (evsel->fd == NULL) return; @@ -2083,19 +2083,19 @@ void perf_evsel__close(struct perf_evsel *evsel) perf_evsel__free_id(evsel); } -int perf_evsel__open_per_cpu(struct perf_evsel *evsel, +int perf_evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus) { return perf_evsel__open(evsel, cpus, NULL); } -int perf_evsel__open_per_thread(struct perf_evsel *evsel, +int perf_evsel__open_per_thread(struct evsel *evsel, struct perf_thread_map *threads) { return perf_evsel__open(evsel, NULL, threads); } -static int perf_evsel__parse_id_sample(const struct perf_evsel *evsel, +static int perf_evsel__parse_id_sample(const struct evsel *evsel, const union perf_event *event, struct perf_sample *sample) { @@ -2185,7 +2185,7 @@ perf_event__check_size(union perf_event *event, unsigned int sample_size) return 0; } -int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, +int perf_evsel__parse_sample(struct evsel *evsel, union perf_event *event, struct perf_sample *data) { u64 type = evsel->attr.sample_type; @@ -2464,7 +2464,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, return 0; } -int perf_evsel__parse_sample_timestamp(struct perf_evsel *evsel, +int perf_evsel__parse_sample_timestamp(struct evsel *evsel, union perf_event *event, u64 *timestamp) { @@ -2785,12 +2785,12 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, return 0; } -struct tep_format_field *perf_evsel__field(struct perf_evsel *evsel, const char *name) +struct tep_format_field *perf_evsel__field(struct evsel *evsel, const char *name) { return tep_find_field(evsel->tp_format, name); } -void *perf_evsel__rawptr(struct perf_evsel *evsel, struct perf_sample *sample, +void *perf_evsel__rawptr(struct evsel *evsel, struct perf_sample *sample, const char *name) { struct tep_format_field *field = perf_evsel__field(evsel, name); @@ -2848,7 +2848,7 @@ u64 format_field__intval(struct tep_format_field *field, struct perf_sample *sam return 0; } -u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample, +u64 perf_evsel__intval(struct evsel *evsel, struct perf_sample *sample, const char *name) { struct tep_format_field *field = perf_evsel__field(evsel, name); @@ -2859,7 +2859,7 @@ u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample, return field ? format_field__intval(field, sample, evsel->needs_swap) : 0; } -bool perf_evsel__fallback(struct perf_evsel *evsel, int err, +bool perf_evsel__fallback(struct evsel *evsel, int err, char *msg, size_t msgsize) { int paranoid; @@ -2946,7 +2946,7 @@ static bool find_process(const char *name) return ret ? false : true; } -int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, +int perf_evsel__open_strerror(struct evsel *evsel, struct target *target, int err, char *msg, size_t size) { char sbuf[STRERR_BUFSIZE]; @@ -3037,14 +3037,14 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, perf_evsel__name(evsel)); } -struct perf_env *perf_evsel__env(struct perf_evsel *evsel) +struct perf_env *perf_evsel__env(struct evsel *evsel) { if (evsel && evsel->evlist) return evsel->evlist->env; return NULL; } -static int store_evsel_ids(struct perf_evsel *evsel, struct perf_evlist *evlist) +static int store_evsel_ids(struct evsel *evsel, struct perf_evlist *evlist) { int cpu, thread; @@ -3062,7 +3062,7 @@ static int store_evsel_ids(struct perf_evsel *evsel, struct perf_evlist *evlist) return 0; } -int perf_evsel__store_ids(struct perf_evsel *evsel, struct perf_evlist *evlist) +int perf_evsel__store_ids(struct evsel *evsel, struct perf_evlist *evlist) { struct perf_cpu_map *cpus = evsel->cpus; struct perf_thread_map *threads = evsel->threads; diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index ba2385f22e28..2c31c5e99524 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -12,7 +12,7 @@ #include "cpumap.h" #include "counts.h" -struct perf_evsel; +struct evsel; /* * Per fd, to map back from PERF_SAMPLE_ID to evsel, only used when there are @@ -21,7 +21,7 @@ struct perf_evsel; struct perf_sample_id { struct hlist_node node; u64 id; - struct perf_evsel *evsel; + struct evsel *evsel; int idx; int cpu; pid_t tid; @@ -84,7 +84,7 @@ enum perf_tool_event { struct bpf_object; -/** struct perf_evsel - event selector +/** struct evsel - event selector * * @evlist - evlist this evsel is in, if it is in one. * @node - To insert it into evlist->entries or in other list_heads, say in @@ -100,7 +100,7 @@ struct bpf_object; * is used there is an id sample appended to non-sample events * @priv: And what is in its containing unnamed union are tool specific */ -struct perf_evsel { +struct evsel { struct list_head node; struct perf_evlist *evlist; struct perf_event_attr attr; @@ -150,7 +150,7 @@ struct perf_evsel { int nr_members; int sample_read; unsigned long *per_pkg_mask; - struct perf_evsel *leader; + struct evsel *leader; char *group_name; bool cmdline_group_boundary; struct list_head config_terms; @@ -160,7 +160,7 @@ struct perf_evsel { bool merged_stat; const char * metric_expr; const char * metric_name; - struct perf_evsel **metric_events; + struct evsel **metric_events; bool collect_stat; bool weak_group; bool percore; @@ -197,12 +197,12 @@ struct target; struct thread_map; struct record_opts; -static inline struct perf_cpu_map *perf_evsel__cpus(struct perf_evsel *evsel) +static inline struct perf_cpu_map *perf_evsel__cpus(struct evsel *evsel) { return evsel->cpus; } -static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel) +static inline int perf_evsel__nr_cpus(struct evsel *evsel) { return perf_evsel__cpus(evsel)->nr; } @@ -210,50 +210,50 @@ static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel) void perf_counts_values__scale(struct perf_counts_values *count, bool scale, s8 *pscaled); -void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu, int thread, +void perf_evsel__compute_deltas(struct evsel *evsel, int cpu, int thread, struct perf_counts_values *count); int perf_evsel__object_config(size_t object_size, - int (*init)(struct perf_evsel *evsel), - void (*fini)(struct perf_evsel *evsel)); + int (*init)(struct evsel *evsel), + void (*fini)(struct evsel *evsel)); -struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx); +struct evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx); -static inline struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr) +static inline struct evsel *perf_evsel__new(struct perf_event_attr *attr) { return perf_evsel__new_idx(attr, 0); } -struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx); +struct evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx); /* * Returns pointer with encoded error via interface. */ -static inline struct perf_evsel *perf_evsel__newtp(const char *sys, const char *name) +static inline struct evsel *perf_evsel__newtp(const char *sys, const char *name) { return perf_evsel__newtp_idx(sys, name, 0); } -struct perf_evsel *perf_evsel__new_cycles(bool precise); +struct evsel *perf_evsel__new_cycles(bool precise); struct tep_event *event_format__new(const char *sys, const char *name); -void perf_evsel__init(struct perf_evsel *evsel, +void perf_evsel__init(struct evsel *evsel, struct perf_event_attr *attr, int idx); -void perf_evsel__exit(struct perf_evsel *evsel); -void perf_evsel__delete(struct perf_evsel *evsel); +void perf_evsel__exit(struct evsel *evsel); +void perf_evsel__delete(struct evsel *evsel); struct callchain_param; -void perf_evsel__config(struct perf_evsel *evsel, +void perf_evsel__config(struct evsel *evsel, struct record_opts *opts, struct callchain_param *callchain); -void perf_evsel__config_callchain(struct perf_evsel *evsel, +void perf_evsel__config_callchain(struct evsel *evsel, struct record_opts *opts, struct callchain_param *callchain); int __perf_evsel__sample_size(u64 sample_type); -void perf_evsel__calc_id_pos(struct perf_evsel *evsel); +void perf_evsel__calc_id_pos(struct evsel *evsel); bool perf_evsel__is_cache_op_valid(u8 type, u8 op); @@ -269,17 +269,17 @@ extern const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX]; extern const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX]; int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, char *bf, size_t size); -const char *perf_evsel__name(struct perf_evsel *evsel); +const char *perf_evsel__name(struct evsel *evsel); -const char *perf_evsel__group_name(struct perf_evsel *evsel); -int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size); +const char *perf_evsel__group_name(struct evsel *evsel); +int perf_evsel__group_desc(struct evsel *evsel, char *buf, size_t size); -int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads); -void perf_evsel__close_fd(struct perf_evsel *evsel); +int perf_evsel__alloc_id(struct evsel *evsel, int ncpus, int nthreads); +void perf_evsel__close_fd(struct evsel *evsel); -void __perf_evsel__set_sample_bit(struct perf_evsel *evsel, +void __perf_evsel__set_sample_bit(struct evsel *evsel, enum perf_event_sample_format bit); -void __perf_evsel__reset_sample_bit(struct perf_evsel *evsel, +void __perf_evsel__reset_sample_bit(struct evsel *evsel, enum perf_event_sample_format bit); #define perf_evsel__set_sample_bit(evsel, bit) \ @@ -288,33 +288,33 @@ void __perf_evsel__reset_sample_bit(struct perf_evsel *evsel, #define perf_evsel__reset_sample_bit(evsel, bit) \ __perf_evsel__reset_sample_bit(evsel, PERF_SAMPLE_##bit) -void perf_evsel__set_sample_id(struct perf_evsel *evsel, +void perf_evsel__set_sample_id(struct evsel *evsel, bool use_sample_identifier); -int perf_evsel__set_filter(struct perf_evsel *evsel, const char *filter); -int perf_evsel__append_tp_filter(struct perf_evsel *evsel, const char *filter); -int perf_evsel__append_addr_filter(struct perf_evsel *evsel, +int perf_evsel__set_filter(struct evsel *evsel, const char *filter); +int perf_evsel__append_tp_filter(struct evsel *evsel, const char *filter); +int perf_evsel__append_addr_filter(struct evsel *evsel, const char *filter); -int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter); -int perf_evsel__enable(struct perf_evsel *evsel); -int perf_evsel__disable(struct perf_evsel *evsel); +int perf_evsel__apply_filter(struct evsel *evsel, const char *filter); +int perf_evsel__enable(struct evsel *evsel); +int perf_evsel__disable(struct evsel *evsel); -int perf_evsel__open_per_cpu(struct perf_evsel *evsel, +int perf_evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus); -int perf_evsel__open_per_thread(struct perf_evsel *evsel, +int perf_evsel__open_per_thread(struct evsel *evsel, struct perf_thread_map *threads); -int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus, +int perf_evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus, struct perf_thread_map *threads); -void perf_evsel__close(struct perf_evsel *evsel); +void perf_evsel__close(struct evsel *evsel); struct perf_sample; -void *perf_evsel__rawptr(struct perf_evsel *evsel, struct perf_sample *sample, +void *perf_evsel__rawptr(struct evsel *evsel, struct perf_sample *sample, const char *name); -u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample, +u64 perf_evsel__intval(struct evsel *evsel, struct perf_sample *sample, const char *name); -static inline char *perf_evsel__strval(struct perf_evsel *evsel, +static inline char *perf_evsel__strval(struct evsel *evsel, struct perf_sample *sample, const char *name) { @@ -325,14 +325,14 @@ struct tep_format_field; u64 format_field__intval(struct tep_format_field *field, struct perf_sample *sample, bool needs_swap); -struct tep_format_field *perf_evsel__field(struct perf_evsel *evsel, const char *name); +struct tep_format_field *perf_evsel__field(struct evsel *evsel, const char *name); #define perf_evsel__match(evsel, t, c) \ (evsel->attr.type == PERF_TYPE_##t && \ evsel->attr.config == PERF_COUNT_##c) -static inline bool perf_evsel__match2(struct perf_evsel *e1, - struct perf_evsel *e2) +static inline bool perf_evsel__match2(struct evsel *e1, + struct evsel *e2) { return (e1->attr.type == e2->attr.type) && (e1->attr.config == e2->attr.config); @@ -344,12 +344,12 @@ static inline bool perf_evsel__match2(struct perf_evsel *e1, (a)->attr.type == (b)->attr.type && \ (a)->attr.config == (b)->attr.config) -int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread, +int perf_evsel__read(struct evsel *evsel, int cpu, int thread, struct perf_counts_values *count); -int perf_evsel__read_counter(struct perf_evsel *evsel, int cpu, int thread); +int perf_evsel__read_counter(struct evsel *evsel, int cpu, int thread); -int __perf_evsel__read_on_cpu(struct perf_evsel *evsel, +int __perf_evsel__read_on_cpu(struct evsel *evsel, int cpu, int thread, bool scale); /** @@ -359,7 +359,7 @@ int __perf_evsel__read_on_cpu(struct perf_evsel *evsel, * @cpu - CPU of interest * @thread - thread of interest */ -static inline int perf_evsel__read_on_cpu(struct perf_evsel *evsel, +static inline int perf_evsel__read_on_cpu(struct evsel *evsel, int cpu, int thread) { return __perf_evsel__read_on_cpu(evsel, cpu, thread, false); @@ -372,27 +372,27 @@ static inline int perf_evsel__read_on_cpu(struct perf_evsel *evsel, * @cpu - CPU of interest * @thread - thread of interest */ -static inline int perf_evsel__read_on_cpu_scaled(struct perf_evsel *evsel, +static inline int perf_evsel__read_on_cpu_scaled(struct evsel *evsel, int cpu, int thread) { return __perf_evsel__read_on_cpu(evsel, cpu, thread, true); } -int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, +int perf_evsel__parse_sample(struct evsel *evsel, union perf_event *event, struct perf_sample *sample); -int perf_evsel__parse_sample_timestamp(struct perf_evsel *evsel, +int perf_evsel__parse_sample_timestamp(struct evsel *evsel, union perf_event *event, u64 *timestamp); -static inline struct perf_evsel *perf_evsel__next(struct perf_evsel *evsel) +static inline struct evsel *perf_evsel__next(struct evsel *evsel) { - return list_entry(evsel->node.next, struct perf_evsel, node); + return list_entry(evsel->node.next, struct evsel, node); } -static inline struct perf_evsel *perf_evsel__prev(struct perf_evsel *evsel) +static inline struct evsel *perf_evsel__prev(struct evsel *evsel) { - return list_entry(evsel->node.prev, struct perf_evsel, node); + return list_entry(evsel->node.prev, struct evsel, node); } /** @@ -402,7 +402,7 @@ static inline struct perf_evsel *perf_evsel__prev(struct perf_evsel *evsel) * * Return %true if @evsel is a group leader or a stand-alone event */ -static inline bool perf_evsel__is_group_leader(const struct perf_evsel *evsel) +static inline bool perf_evsel__is_group_leader(const struct evsel *evsel) { return evsel->leader == evsel; } @@ -415,7 +415,7 @@ static inline bool perf_evsel__is_group_leader(const struct perf_evsel *evsel) * Return %true iff event group view is enabled and @evsel is a actual group * leader which has other members in the group */ -static inline bool perf_evsel__is_group_event(struct perf_evsel *evsel) +static inline bool perf_evsel__is_group_event(struct evsel *evsel) { if (!symbol_conf.event_group) return false; @@ -423,14 +423,14 @@ static inline bool perf_evsel__is_group_event(struct perf_evsel *evsel) return perf_evsel__is_group_leader(evsel) && evsel->nr_members > 1; } -bool perf_evsel__is_function_event(struct perf_evsel *evsel); +bool perf_evsel__is_function_event(struct evsel *evsel); -static inline bool perf_evsel__is_bpf_output(struct perf_evsel *evsel) +static inline bool perf_evsel__is_bpf_output(struct evsel *evsel) { return perf_evsel__match(evsel, SOFTWARE, SW_BPF_OUTPUT); } -static inline bool perf_evsel__is_clock(struct perf_evsel *evsel) +static inline bool perf_evsel__is_clock(struct evsel *evsel) { return perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) || perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK); @@ -444,7 +444,7 @@ struct perf_attr_details { bool trace_fields; }; -int perf_evsel__fprintf(struct perf_evsel *evsel, +int perf_evsel__fprintf(struct evsel *evsel, struct perf_attr_details *details, FILE *fp); #define EVSEL__PRINT_IP (1<<0) @@ -467,34 +467,34 @@ int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al, int left_alignment, unsigned int print_opts, struct callchain_cursor *cursor, FILE *fp); -bool perf_evsel__fallback(struct perf_evsel *evsel, int err, +bool perf_evsel__fallback(struct evsel *evsel, int err, char *msg, size_t msgsize); -int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, +int perf_evsel__open_strerror(struct evsel *evsel, struct target *target, int err, char *msg, size_t size); -static inline int perf_evsel__group_idx(struct perf_evsel *evsel) +static inline int perf_evsel__group_idx(struct evsel *evsel) { return evsel->idx - evsel->leader->idx; } /* Iterates group WITHOUT the leader. */ #define for_each_group_member(_evsel, _leader) \ -for ((_evsel) = list_entry((_leader)->node.next, struct perf_evsel, node); \ +for ((_evsel) = list_entry((_leader)->node.next, struct evsel, node); \ (_evsel) && (_evsel)->leader == (_leader); \ - (_evsel) = list_entry((_evsel)->node.next, struct perf_evsel, node)) + (_evsel) = list_entry((_evsel)->node.next, struct evsel, node)) /* Iterates group WITH the leader. */ #define for_each_group_evsel(_evsel, _leader) \ for ((_evsel) = _leader; \ (_evsel) && (_evsel)->leader == (_leader); \ - (_evsel) = list_entry((_evsel)->node.next, struct perf_evsel, node)) + (_evsel) = list_entry((_evsel)->node.next, struct evsel, node)) -static inline bool perf_evsel__has_branch_callstack(const struct perf_evsel *evsel) +static inline bool perf_evsel__has_branch_callstack(const struct evsel *evsel) { return evsel->attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK; } -static inline bool evsel__has_callchain(const struct perf_evsel *evsel) +static inline bool evsel__has_callchain(const struct evsel *evsel) { return (evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) != 0; } @@ -504,7 +504,7 @@ typedef int (*attr__fprintf_f)(FILE *, const char *, const char *, void *); int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr, attr__fprintf_f attr__fprintf, void *priv); -struct perf_env *perf_evsel__env(struct perf_evsel *evsel); +struct perf_env *perf_evsel__env(struct evsel *evsel); -int perf_evsel__store_ids(struct perf_evsel *evsel, struct perf_evlist *evlist); +int perf_evsel__store_ids(struct evsel *evsel, struct perf_evlist *evlist); #endif /* __PERF_EVSEL_H */ diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c index 95ea147f9e18..1fddb7da4b51 100644 --- a/tools/perf/util/evsel_fprintf.c +++ b/tools/perf/util/evsel_fprintf.c @@ -33,14 +33,14 @@ static int __print_attr__fprintf(FILE *fp, const char *name, const char *val, vo return comma_fprintf(fp, (bool *)priv, " %s: %s", name, val); } -int perf_evsel__fprintf(struct perf_evsel *evsel, +int perf_evsel__fprintf(struct evsel *evsel, struct perf_attr_details *details, FILE *fp) { bool first = true; int printed = 0; if (details->event_group) { - struct perf_evsel *pos; + struct evsel *pos; if (!perf_evsel__is_group_leader(evsel)) return 0; diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 4be216f3598b..132bbc29f977 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -74,7 +74,7 @@ struct feat_fd { void *buf; /* Either buf != NULL or fd >= 0 */ ssize_t offset; size_t size; - struct perf_evsel *events; + struct evsel *events; }; void perf_header__set_feat(struct perf_header *header, int feat) @@ -472,7 +472,7 @@ static int write_nrcpus(struct feat_fd *ff, static int write_event_desc(struct feat_fd *ff, struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; u32 nre, nri, sz; int ret; @@ -762,7 +762,7 @@ static int write_group_desc(struct feat_fd *ff, struct perf_evlist *evlist) { u32 nr_groups = evlist->nr_groups; - struct perf_evsel *evsel; + struct evsel *evsel; int ret; ret = do_write(ff, &nr_groups, sizeof(nr_groups)); @@ -1568,9 +1568,9 @@ static void print_bpf_btf(struct feat_fd *ff, FILE *fp) up_read(&env->bpf_progs.lock); } -static void free_event_desc(struct perf_evsel *events) +static void free_event_desc(struct evsel *events) { - struct perf_evsel *evsel; + struct evsel *evsel; if (!events) return; @@ -1583,9 +1583,9 @@ static void free_event_desc(struct perf_evsel *events) free(events); } -static struct perf_evsel *read_event_desc(struct feat_fd *ff) +static struct evsel *read_event_desc(struct feat_fd *ff) { - struct perf_evsel *evsel, *events = NULL; + struct evsel *evsel, *events = NULL; u64 *id; void *buf = NULL; u32 nre, sz, nr, i, j; @@ -1669,7 +1669,7 @@ static int __desc_attr__fprintf(FILE *fp, const char *name, const char *val, static void print_event_desc(struct feat_fd *ff, FILE *fp) { - struct perf_evsel *evsel, *events; + struct evsel *evsel, *events; u32 j; u64 *id; @@ -1804,7 +1804,7 @@ error: static void print_group_desc(struct feat_fd *ff, FILE *fp) { struct perf_session *session; - struct perf_evsel *evsel; + struct evsel *evsel; u32 nr = 0; session = container_of(ff->ph, struct perf_session, header); @@ -2089,10 +2089,10 @@ static int process_total_mem(struct feat_fd *ff, void *data __maybe_unused) return 0; } -static struct perf_evsel * +static struct evsel * perf_evlist__find_by_index(struct perf_evlist *evlist, int idx) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { if (evsel->idx == idx) @@ -2104,9 +2104,9 @@ perf_evlist__find_by_index(struct perf_evlist *evlist, int idx) static void perf_evlist__set_event_name(struct perf_evlist *evlist, - struct perf_evsel *event) + struct evsel *event) { - struct perf_evsel *evsel; + struct evsel *evsel; if (!event->name) return; @@ -2125,7 +2125,7 @@ static int process_event_desc(struct feat_fd *ff, void *data __maybe_unused) { struct perf_session *session; - struct perf_evsel *evsel, *events = read_event_desc(ff); + struct evsel *evsel, *events = read_event_desc(ff); if (!events) return 0; @@ -2415,7 +2415,7 @@ static int process_group_desc(struct feat_fd *ff, void *data __maybe_unused) size_t ret = -1; u32 i, nr, nr_groups; struct perf_session *session; - struct perf_evsel *evsel, *leader = NULL; + struct evsel *evsel, *leader = NULL; struct group_desc { char *name; u32 leader_idx; @@ -3050,7 +3050,7 @@ int perf_session__write_header(struct perf_session *session, struct perf_file_header f_header; struct perf_file_attr f_attr; struct perf_header *header = &session->header; - struct perf_evsel *evsel; + struct evsel *evsel; struct feat_fd ff; u64 attr_offset; int err; @@ -3479,7 +3479,7 @@ static int read_attr(int fd, struct perf_header *ph, return ret <= 0 ? -1 : 0; } -static int perf_evsel__prepare_tracepoint_event(struct perf_evsel *evsel, +static int perf_evsel__prepare_tracepoint_event(struct evsel *evsel, struct tep_handle *pevent) { struct tep_event *event; @@ -3514,7 +3514,7 @@ static int perf_evsel__prepare_tracepoint_event(struct perf_evsel *evsel, static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist, struct tep_handle *pevent) { - struct perf_evsel *pos; + struct evsel *pos; evlist__for_each_entry(evlist, pos) { if (pos->attr.type == PERF_TYPE_TRACEPOINT && @@ -3570,7 +3570,7 @@ int perf_session__read_header(struct perf_session *session) lseek(fd, f_header.attrs.offset, SEEK_SET); for (i = 0; i < nr_attrs; i++) { - struct perf_evsel *evsel; + struct evsel *evsel; off_t tmp; if (read_attr(fd, header, &f_attr) < 0) @@ -3794,7 +3794,7 @@ event_update_event__new(size_t size, u64 type, u64 id) int perf_event__synthesize_event_update_unit(struct perf_tool *tool, - struct perf_evsel *evsel, + struct evsel *evsel, perf_event__handler_t process) { struct event_update_event *ev; @@ -3813,7 +3813,7 @@ perf_event__synthesize_event_update_unit(struct perf_tool *tool, int perf_event__synthesize_event_update_scale(struct perf_tool *tool, - struct perf_evsel *evsel, + struct evsel *evsel, perf_event__handler_t process) { struct event_update_event *ev; @@ -3833,7 +3833,7 @@ perf_event__synthesize_event_update_scale(struct perf_tool *tool, int perf_event__synthesize_event_update_name(struct perf_tool *tool, - struct perf_evsel *evsel, + struct evsel *evsel, perf_event__handler_t process) { struct event_update_event *ev; @@ -3852,7 +3852,7 @@ perf_event__synthesize_event_update_name(struct perf_tool *tool, int perf_event__synthesize_event_update_cpus(struct perf_tool *tool, - struct perf_evsel *evsel, + struct evsel *evsel, perf_event__handler_t process) { size_t size = sizeof(struct event_update_event); @@ -3924,7 +3924,7 @@ int perf_event__synthesize_attrs(struct perf_tool *tool, struct perf_evlist *evlist, perf_event__handler_t process) { - struct perf_evsel *evsel; + struct evsel *evsel; int err = 0; evlist__for_each_entry(evlist, evsel) { @@ -3939,12 +3939,12 @@ int perf_event__synthesize_attrs(struct perf_tool *tool, return err; } -static bool has_unit(struct perf_evsel *counter) +static bool has_unit(struct evsel *counter) { return counter->unit && *counter->unit; } -static bool has_scale(struct perf_evsel *counter) +static bool has_scale(struct evsel *counter) { return counter->scale != 1; } @@ -3954,7 +3954,7 @@ int perf_event__synthesize_extra_attr(struct perf_tool *tool, perf_event__handler_t process, bool is_pipe) { - struct perf_evsel *counter; + struct evsel *counter; int err; /* @@ -4012,7 +4012,7 @@ int perf_event__process_attr(struct perf_tool *tool __maybe_unused, struct perf_evlist **pevlist) { u32 i, ids, n_ids; - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_evlist *evlist = *pevlist; if (evlist == NULL) { @@ -4053,7 +4053,7 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused, struct event_update_event_scale *ev_scale; struct event_update_event_cpus *ev_cpus; struct perf_evlist *evlist; - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_cpu_map *map; if (!pevlist || *pevlist == NULL) diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 5b3abe4172e2..437d8617de27 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -135,16 +135,16 @@ int perf_event__synthesize_attrs(struct perf_tool *tool, struct perf_evlist *evlist, perf_event__handler_t process); int perf_event__synthesize_event_update_unit(struct perf_tool *tool, - struct perf_evsel *evsel, + struct evsel *evsel, perf_event__handler_t process); int perf_event__synthesize_event_update_scale(struct perf_tool *tool, - struct perf_evsel *evsel, + struct evsel *evsel, perf_event__handler_t process); int perf_event__synthesize_event_update_name(struct perf_tool *tool, - struct perf_evsel *evsel, + struct evsel *evsel, perf_event__handler_t process); int perf_event__synthesize_event_update_cpus(struct perf_tool *tool, - struct perf_evsel *evsel, + struct evsel *evsel, perf_event__handler_t process); int perf_event__process_attr(struct perf_tool *tool, union perf_event *event, struct perf_evlist **pevlist); diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index f24fd1954f6c..3da49c479880 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -816,7 +816,7 @@ static int iter_finish_mem_entry(struct hist_entry_iter *iter, struct addr_location *al __maybe_unused) { - struct perf_evsel *evsel = iter->evsel; + struct evsel *evsel = iter->evsel; struct hists *hists = evsel__hists(evsel); struct hist_entry *he = iter->he; int err = -EINVAL; @@ -886,7 +886,7 @@ static int iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *al) { struct branch_info *bi; - struct perf_evsel *evsel = iter->evsel; + struct evsel *evsel = iter->evsel; struct hists *hists = evsel__hists(evsel); struct perf_sample *sample = iter->sample; struct hist_entry *he = NULL; @@ -938,7 +938,7 @@ iter_prepare_normal_entry(struct hist_entry_iter *iter __maybe_unused, static int iter_add_single_normal_entry(struct hist_entry_iter *iter, struct addr_location *al) { - struct perf_evsel *evsel = iter->evsel; + struct evsel *evsel = iter->evsel; struct perf_sample *sample = iter->sample; struct hist_entry *he; @@ -956,7 +956,7 @@ iter_finish_normal_entry(struct hist_entry_iter *iter, struct addr_location *al __maybe_unused) { struct hist_entry *he = iter->he; - struct perf_evsel *evsel = iter->evsel; + struct evsel *evsel = iter->evsel; struct perf_sample *sample = iter->sample; if (he == NULL) @@ -996,7 +996,7 @@ static int iter_add_single_cumulative_entry(struct hist_entry_iter *iter, struct addr_location *al) { - struct perf_evsel *evsel = iter->evsel; + struct evsel *evsel = iter->evsel; struct hists *hists = evsel__hists(evsel); struct perf_sample *sample = iter->sample; struct hist_entry **he_cache = iter->priv; @@ -1041,7 +1041,7 @@ static int iter_add_next_cumulative_entry(struct hist_entry_iter *iter, struct addr_location *al) { - struct perf_evsel *evsel = iter->evsel; + struct evsel *evsel = iter->evsel; struct perf_sample *sample = iter->sample; struct hist_entry **he_cache = iter->priv; struct hist_entry *he; @@ -1873,7 +1873,7 @@ static void output_resort(struct hists *hists, struct ui_progress *prog, } } -void perf_evsel__output_resort_cb(struct perf_evsel *evsel, struct ui_progress *prog, +void perf_evsel__output_resort_cb(struct evsel *evsel, struct ui_progress *prog, hists__resort_cb_t cb, void *cb_arg) { bool use_callchain; @@ -1888,7 +1888,7 @@ void perf_evsel__output_resort_cb(struct perf_evsel *evsel, struct ui_progress * output_resort(evsel__hists(evsel), prog, use_callchain, cb, cb_arg); } -void perf_evsel__output_resort(struct perf_evsel *evsel, struct ui_progress *prog) +void perf_evsel__output_resort(struct evsel *evsel, struct ui_progress *prog) { return perf_evsel__output_resort_cb(evsel, prog, NULL, NULL); } @@ -2575,7 +2575,7 @@ void hist__account_cycles(struct branch_stack *bs, struct addr_location *al, size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp) { - struct perf_evsel *pos; + struct evsel *pos; size_t ret = 0; evlist__for_each_entry(evlist, pos) { @@ -2602,7 +2602,7 @@ int __hists__scnprintf_title(struct hists *hists, char *bf, size_t size, bool sh int socket_id = hists->socket_filter; unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE]; u64 nr_events = hists->stats.total_period; - struct perf_evsel *evsel = hists_to_evsel(hists); + struct evsel *evsel = hists_to_evsel(hists); const char *ev_name = perf_evsel__name(evsel); char buf[512], sample_freq_str[64] = ""; size_t buflen = sizeof(buf); @@ -2615,7 +2615,7 @@ int __hists__scnprintf_title(struct hists *hists, char *bf, size_t size, bool sh } if (perf_evsel__is_group_event(evsel)) { - struct perf_evsel *pos; + struct evsel *pos; perf_evsel__group_desc(evsel, buf, buflen); ev_name = buf; @@ -2731,7 +2731,7 @@ static void hists__delete_all_entries(struct hists *hists) hists__delete_remaining_entries(&hists->entries_collapsed); } -static void hists_evsel__exit(struct perf_evsel *evsel) +static void hists_evsel__exit(struct evsel *evsel) { struct hists *hists = evsel__hists(evsel); struct perf_hpp_fmt *fmt, *pos; @@ -2749,7 +2749,7 @@ static void hists_evsel__exit(struct perf_evsel *evsel) } } -static int hists_evsel__init(struct perf_evsel *evsel) +static int hists_evsel__init(struct evsel *evsel) { struct hists *hists = evsel__hists(evsel); diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 24635f36148d..9bf247c638b8 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -116,7 +116,7 @@ struct hist_entry_iter { bool hide_unresolved; - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_sample *sample; struct hist_entry *he; struct symbol *parent; @@ -171,9 +171,9 @@ void hist_entry__delete(struct hist_entry *he); typedef int (*hists__resort_cb_t)(struct hist_entry *he, void *arg); -void perf_evsel__output_resort_cb(struct perf_evsel *evsel, struct ui_progress *prog, +void perf_evsel__output_resort_cb(struct evsel *evsel, struct ui_progress *prog, hists__resort_cb_t cb, void *cb_arg); -void perf_evsel__output_resort(struct perf_evsel *evsel, struct ui_progress *prog); +void perf_evsel__output_resort(struct evsel *evsel, struct ui_progress *prog); void hists__output_resort(struct hists *hists, struct ui_progress *prog); void hists__output_resort_cb(struct hists *hists, struct ui_progress *prog, hists__resort_cb_t cb); @@ -219,17 +219,17 @@ void hists__match(struct hists *leader, struct hists *other); int hists__link(struct hists *leader, struct hists *other); struct hists_evsel { - struct perf_evsel evsel; + struct evsel evsel; struct hists hists; }; -static inline struct perf_evsel *hists_to_evsel(struct hists *hists) +static inline struct evsel *hists_to_evsel(struct hists *hists) { struct hists_evsel *hevsel = container_of(hists, struct hists_evsel, hists); return &hevsel->evsel; } -static inline struct hists *evsel__hists(struct perf_evsel *evsel) +static inline struct hists *evsel__hists(struct evsel *evsel) { struct hists_evsel *hevsel = (struct hists_evsel *)evsel; return &hevsel->hists; @@ -453,11 +453,11 @@ enum rstype { #include "../ui/keysyms.h" void attr_to_script(char *buf, struct perf_event_attr *attr); -int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel, +int map_symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel, struct hist_browser_timer *hbt, struct annotation_options *annotation_opts); -int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel, +int hist_entry__tui_annotate(struct hist_entry *he, struct evsel *evsel, struct hist_browser_timer *hbt, struct annotation_options *annotation_opts); @@ -468,11 +468,11 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, bool warn_lost_event, struct annotation_options *annotation_options); -int script_browse(const char *script_opt, struct perf_evsel *evsel); +int script_browse(const char *script_opt, struct evsel *evsel); void run_script(char *cmd); int res_sample_browse(struct res_sample *res_samples, int num_res, - struct perf_evsel *evsel, enum rstype rstype); + struct evsel *evsel, enum rstype rstype); void res_sample_init(void); #else static inline @@ -487,7 +487,7 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused, return 0; } static inline int map_symbol__tui_annotate(struct map_symbol *ms __maybe_unused, - struct perf_evsel *evsel __maybe_unused, + struct evsel *evsel __maybe_unused, struct hist_browser_timer *hbt __maybe_unused, struct annotation_options *annotation_options __maybe_unused) { @@ -495,7 +495,7 @@ static inline int map_symbol__tui_annotate(struct map_symbol *ms __maybe_unused, } static inline int hist_entry__tui_annotate(struct hist_entry *he __maybe_unused, - struct perf_evsel *evsel __maybe_unused, + struct evsel *evsel __maybe_unused, struct hist_browser_timer *hbt __maybe_unused, struct annotation_options *annotation_opts __maybe_unused) { @@ -503,14 +503,14 @@ static inline int hist_entry__tui_annotate(struct hist_entry *he __maybe_unused, } static inline int script_browse(const char *script_opt __maybe_unused, - struct perf_evsel *evsel __maybe_unused) + struct evsel *evsel __maybe_unused) { return 0; } static inline int res_sample_browse(struct res_sample *res_samples __maybe_unused, int num_res __maybe_unused, - struct perf_evsel *evsel __maybe_unused, + struct evsel *evsel __maybe_unused, enum rstype rstype __maybe_unused) { return 0; diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index 5560e95afdda..8fd46d5f4b39 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c @@ -761,7 +761,7 @@ static int intel_bts_synth_events(struct intel_bts *bts, struct perf_session *session) { struct perf_evlist *evlist = session->evlist; - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_event_attr attr; bool found = false; u64 id; diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index df061599fef4..f1595b86d7c7 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -56,7 +56,7 @@ struct intel_pt { u32 auxtrace_type; struct perf_session *session; struct machine *machine; - struct perf_evsel *switch_evsel; + struct evsel *switch_evsel; struct thread *unknown_thread; bool timeless_decoding; bool sampling_mode; @@ -104,7 +104,7 @@ struct intel_pt { u64 cbr_id; bool sample_pebs; - struct perf_evsel *pebs_evsel; + struct evsel *pebs_evsel; u64 tsc_bit; u64 mtc_bit; @@ -723,7 +723,7 @@ static bool intel_pt_get_config(struct intel_pt *pt, static bool intel_pt_exclude_kernel(struct intel_pt *pt) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(pt->session->evlist, evsel) { if (intel_pt_get_config(pt, &evsel->attr, NULL) && @@ -735,7 +735,7 @@ static bool intel_pt_exclude_kernel(struct intel_pt *pt) static bool intel_pt_return_compression(struct intel_pt *pt) { - struct perf_evsel *evsel; + struct evsel *evsel; u64 config; if (!pt->noretcomp_bit) @@ -751,7 +751,7 @@ static bool intel_pt_return_compression(struct intel_pt *pt) static bool intel_pt_branch_enable(struct intel_pt *pt) { - struct perf_evsel *evsel; + struct evsel *evsel; u64 config; evlist__for_each_entry(pt->session->evlist, evsel) { @@ -764,7 +764,7 @@ static bool intel_pt_branch_enable(struct intel_pt *pt) static unsigned int intel_pt_mtc_period(struct intel_pt *pt) { - struct perf_evsel *evsel; + struct evsel *evsel; unsigned int shift; u64 config; @@ -783,7 +783,7 @@ static unsigned int intel_pt_mtc_period(struct intel_pt *pt) static bool intel_pt_timeless_decoding(struct intel_pt *pt) { - struct perf_evsel *evsel; + struct evsel *evsel; bool timeless_decoding = true; u64 config; @@ -805,7 +805,7 @@ static bool intel_pt_timeless_decoding(struct intel_pt *pt) static bool intel_pt_tracing_kernel(struct intel_pt *pt) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(pt->session->evlist, evsel) { if (intel_pt_get_config(pt, &evsel->attr, NULL) && @@ -817,7 +817,7 @@ static bool intel_pt_tracing_kernel(struct intel_pt *pt) static bool intel_pt_have_tsc(struct intel_pt *pt) { - struct perf_evsel *evsel; + struct evsel *evsel; bool have_tsc = false; u64 config; @@ -1702,7 +1702,7 @@ static int intel_pt_synth_pebs_sample(struct intel_pt_queue *ptq) struct perf_sample sample = { .ip = 0, }; union perf_event *event = ptq->event_buf; struct intel_pt *pt = ptq->pt; - struct perf_evsel *evsel = pt->pebs_evsel; + struct evsel *evsel = pt->pebs_evsel; u64 sample_type = evsel->attr.sample_type; u64 id = evsel->id[0]; u8 cpumode; @@ -2401,7 +2401,7 @@ static int intel_pt_sync_switch(struct intel_pt *pt, int cpu, pid_t tid, static int intel_pt_process_switch(struct intel_pt *pt, struct perf_sample *sample) { - struct perf_evsel *evsel; + struct evsel *evsel; pid_t tid; int cpu, ret; @@ -2716,7 +2716,7 @@ static int intel_pt_synth_event(struct perf_session *session, const char *name, static void intel_pt_set_event_name(struct perf_evlist *evlist, u64 id, const char *name) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { if (evsel->id && evsel->id[0] == id) { @@ -2728,10 +2728,10 @@ static void intel_pt_set_event_name(struct perf_evlist *evlist, u64 id, } } -static struct perf_evsel *intel_pt_evsel(struct intel_pt *pt, +static struct evsel *intel_pt_evsel(struct intel_pt *pt, struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { if (evsel->attr.type == pt->pmu_type && evsel->ids) @@ -2745,7 +2745,7 @@ static int intel_pt_synth_events(struct intel_pt *pt, struct perf_session *session) { struct perf_evlist *evlist = session->evlist; - struct perf_evsel *evsel = intel_pt_evsel(pt, evlist); + struct evsel *evsel = intel_pt_evsel(pt, evlist); struct perf_event_attr attr; u64 id; int err; @@ -2894,9 +2894,9 @@ static int intel_pt_synth_events(struct intel_pt *pt, return 0; } -static struct perf_evsel *intel_pt_find_sched_switch(struct perf_evlist *evlist) +static struct evsel *intel_pt_find_sched_switch(struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry_reverse(evlist, evsel) { const char *name = perf_evsel__name(evsel); @@ -2910,7 +2910,7 @@ static struct perf_evsel *intel_pt_find_sched_switch(struct perf_evlist *evlist) static bool intel_pt_find_switch(struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { if (evsel->attr.context_switch) diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c index 18c34f0c1966..8df60703411a 100644 --- a/tools/perf/util/jitdump.c +++ b/tools/perf/util/jitdump.c @@ -118,7 +118,7 @@ jit_close(struct jit_buf_desc *jd) static int jit_validate_events(struct perf_session *session) { - struct perf_evsel *evsel; + struct evsel *evsel; /* * check that all events use CLOCK_MONOTONIC @@ -758,7 +758,7 @@ jit_process(struct perf_session *session, pid_t pid, u64 *nbytes) { - struct perf_evsel *first; + struct evsel *first; struct jit_buf_desc jd; int ret; diff --git a/tools/perf/util/kvm-stat.h b/tools/perf/util/kvm-stat.h index 1403dec189b4..299edd32d3d4 100644 --- a/tools/perf/util/kvm-stat.h +++ b/tools/perf/util/kvm-stat.h @@ -6,7 +6,7 @@ #include "tool.h" #include "stat.h" -struct perf_evsel; +struct evsel; struct perf_evlist; struct perf_session; @@ -45,17 +45,17 @@ struct kvm_event_key { struct perf_kvm_stat; struct child_event_ops { - void (*get_key)(struct perf_evsel *evsel, + void (*get_key)(struct evsel *evsel, struct perf_sample *sample, struct event_key *key); const char *name; }; struct kvm_events_ops { - bool (*is_begin_event)(struct perf_evsel *evsel, + bool (*is_begin_event)(struct evsel *evsel, struct perf_sample *sample, struct event_key *key); - bool (*is_end_event)(struct perf_evsel *evsel, + bool (*is_end_event)(struct evsel *evsel, struct perf_sample *sample, struct event_key *key); struct child_event_ops *child_ops; void (*decode_key)(struct perf_kvm_stat *kvm, struct event_key *key, @@ -109,21 +109,21 @@ struct kvm_reg_events_ops { struct kvm_events_ops *ops; }; -void exit_event_get_key(struct perf_evsel *evsel, +void exit_event_get_key(struct evsel *evsel, struct perf_sample *sample, struct event_key *key); -bool exit_event_begin(struct perf_evsel *evsel, +bool exit_event_begin(struct evsel *evsel, struct perf_sample *sample, struct event_key *key); -bool exit_event_end(struct perf_evsel *evsel, +bool exit_event_end(struct evsel *evsel, struct perf_sample *sample, struct event_key *key); void exit_event_decode_key(struct perf_kvm_stat *kvm, struct event_key *key, char *decode); -bool kvm_exit_event(struct perf_evsel *evsel); -bool kvm_entry_event(struct perf_evsel *evsel); +bool kvm_exit_event(struct evsel *evsel); +bool kvm_entry_event(struct evsel *evsel); int setup_kvm_events_tp(struct perf_kvm_stat *kvm); #define define_exit_reasons_table(name, symbols) \ diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index a2359a33c748..ec0675b0caa8 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -2287,7 +2287,7 @@ static int find_prev_cpumode(struct ip_callchain *chain, struct thread *thread, static int thread__resolve_callchain_sample(struct thread *thread, struct callchain_cursor *cursor, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct symbol **parent, struct addr_location *root_al, @@ -2493,7 +2493,7 @@ static int unwind_entry(struct unwind_entry *entry, void *arg) static int thread__resolve_callchain_unwind(struct thread *thread, struct callchain_cursor *cursor, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, int max_stack) { @@ -2513,7 +2513,7 @@ static int thread__resolve_callchain_unwind(struct thread *thread, int thread__resolve_callchain(struct thread *thread, struct callchain_cursor *cursor, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct symbol **parent, struct addr_location *root_al, diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 7f64016758e0..ef803f08ae12 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -11,7 +11,7 @@ struct addr_location; struct branch_stack; -struct perf_evsel; +struct evsel; struct perf_sample; struct symbol; struct thread; @@ -175,7 +175,7 @@ struct callchain_cursor; int thread__resolve_callchain(struct thread *thread, struct callchain_cursor *cursor, - struct perf_evsel *evsel, + struct evsel *evsel, struct perf_sample *sample, struct symbol **parent, struct addr_location *root_al, diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index dc93787c74f0..c3614195ddc7 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -16,7 +16,7 @@ struct ip_callchain; struct ref_reloc_sym; struct map_groups; struct machine; -struct perf_evsel; +struct evsel; struct map { union { diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 416a9015405e..14c423974d63 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -21,7 +21,7 @@ #include struct metric_event *metricgroup__lookup(struct rblist *metric_events, - struct perf_evsel *evsel, + struct evsel *evsel, bool create) { struct rb_node *nd; @@ -86,10 +86,10 @@ struct egroup { const char *metric_expr; }; -static bool record_evsel(int *ind, struct perf_evsel **start, +static bool record_evsel(int *ind, struct evsel **start, int idnum, - struct perf_evsel **metric_events, - struct perf_evsel *ev) + struct evsel **metric_events, + struct evsel *ev) { metric_events[*ind] = ev; if (*ind == 0) @@ -101,12 +101,12 @@ static bool record_evsel(int *ind, struct perf_evsel **start, return false; } -static struct perf_evsel *find_evsel_group(struct perf_evlist *perf_evlist, - const char **ids, - int idnum, - struct perf_evsel **metric_events) +static struct evsel *find_evsel_group(struct perf_evlist *perf_evlist, + const char **ids, + int idnum, + struct evsel **metric_events) { - struct perf_evsel *ev, *start = NULL; + struct evsel *ev, *start = NULL; int ind = 0; evlist__for_each_entry (perf_evlist, ev) { @@ -148,10 +148,10 @@ static int metricgroup__setup_events(struct list_head *groups, int i = 0; int ret = 0; struct egroup *eg; - struct perf_evsel *evsel; + struct evsel *evsel; list_for_each_entry (eg, groups, nd) { - struct perf_evsel **metric_events; + struct evsel **metric_events; metric_events = calloc(sizeof(void *), eg->idnum + 1); if (!metric_events) { diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index 5c52097a5c63..500e828533f8 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -9,7 +9,7 @@ struct metric_event { struct rb_node nd; - struct perf_evsel *evsel; + struct evsel *evsel; struct list_head head; /* list of metric_expr */ }; @@ -17,11 +17,11 @@ struct metric_expr { struct list_head nd; const char *metric_expr; const char *metric_name; - struct perf_evsel **metric_events; + struct evsel **metric_events; }; struct metric_event *metricgroup__lookup(struct rblist *metric_events, - struct perf_evsel *evsel, + struct evsel *evsel, bool create); int metricgroup__parse_groups(const struct option *opt, const char *str, diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 352c5198b453..dfde9cb31562 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -314,14 +314,14 @@ static char *get_config_name(struct list_head *head_terms) return NULL; } -static struct perf_evsel * +static struct evsel * __add_event(struct list_head *list, int *idx, struct perf_event_attr *attr, char *name, struct perf_pmu *pmu, struct list_head *config_terms, bool auto_merge_stats, const char *cpu_list) { - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_cpu_map *cpus = pmu ? pmu->cpus : cpu_list ? cpu_map__new(cpu_list) : NULL; @@ -357,7 +357,7 @@ static int add_event(struct list_head *list, int *idx, static int add_event_tool(struct list_head *list, int *idx, enum perf_tool_event tool_event) { - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_event_attr attr = { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_DUMMY, @@ -510,7 +510,7 @@ static int add_tracepoint(struct list_head *list, int *idx, struct parse_events_error *err, struct list_head *head_config) { - struct perf_evsel *evsel; + struct evsel *evsel; evsel = perf_evsel__newtp_idx(sys_name, evt_name, (*idx)++); if (IS_ERR(evsel)) { @@ -637,7 +637,7 @@ static int add_bpf_event(const char *group, const char *event, int fd, struct bp struct __add_bpf_event_param *param = _param; struct parse_events_state *parse_state = param->parse_state; struct list_head *list = param->list; - struct perf_evsel *pos; + struct evsel *pos; int err; /* * Check if we should add the event, i.e. if it is a TP but starts with a '!', @@ -656,7 +656,7 @@ static int add_bpf_event(const char *group, const char *event, int fd, struct bp event, parse_state->error, param->head_config); if (err) { - struct perf_evsel *evsel, *tmp; + struct evsel *evsel, *tmp; pr_debug("Failed to add BPF event %s:%s\n", group, event); @@ -1306,7 +1306,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state, struct perf_event_attr attr; struct perf_pmu_info info; struct perf_pmu *pmu; - struct perf_evsel *evsel; + struct evsel *evsel; struct parse_events_error *err = parse_state->error; bool use_uncore_alias; LIST_HEAD(config_terms); @@ -1453,13 +1453,13 @@ static int parse_events__set_leader_for_uncore_aliase(char *name, struct list_head *list, struct parse_events_state *parse_state) { - struct perf_evsel *evsel, *leader; + struct evsel *evsel, *leader; uintptr_t *leaders; bool is_leader = true; int i, nr_pmu = 0, total_members, ret = 0; - leader = list_first_entry(list, struct perf_evsel, node); - evsel = list_last_entry(list, struct perf_evsel, node); + leader = list_first_entry(list, struct evsel, node); + evsel = list_last_entry(list, struct evsel, node); total_members = evsel->idx - leader->idx + 1; leaders = calloc(total_members, sizeof(uintptr_t)); @@ -1521,12 +1521,12 @@ parse_events__set_leader_for_uncore_aliase(char *name, struct list_head *list, __evlist__for_each_entry(list, evsel) { if (i >= nr_pmu) i = 0; - evsel->leader = (struct perf_evsel *) leaders[i++]; + evsel->leader = (struct evsel *) leaders[i++]; } /* The number of members and group name are same for each group */ for (i = 0; i < nr_pmu; i++) { - evsel = (struct perf_evsel *) leaders[i]; + evsel = (struct evsel *) leaders[i]; evsel->nr_members = total_members / nr_pmu; evsel->group_name = name ? strdup(name) : NULL; } @@ -1544,7 +1544,7 @@ out: void parse_events__set_leader(char *name, struct list_head *list, struct parse_events_state *parse_state) { - struct perf_evsel *leader; + struct evsel *leader; if (list_empty(list)) { WARN_ONCE(true, "WARNING: failed to set leader: empty list"); @@ -1555,7 +1555,7 @@ void parse_events__set_leader(char *name, struct list_head *list, return; __perf_evlist__set_leader(list); - leader = list_entry(list->next, struct perf_evsel, node); + leader = list_entry(list->next, struct evsel, node); leader->group_name = name ? strdup(name) : NULL; } @@ -1588,7 +1588,7 @@ struct event_modifier { }; static int get_event_modifier(struct event_modifier *mod, char *str, - struct perf_evsel *evsel) + struct evsel *evsel) { int eu = evsel ? evsel->attr.exclude_user : 0; int ek = evsel ? evsel->attr.exclude_kernel : 0; @@ -1701,7 +1701,7 @@ static int check_modifier(char *str) int parse_events__modifier_event(struct list_head *list, char *str, bool add) { - struct perf_evsel *evsel; + struct evsel *evsel; struct event_modifier mod; if (str == NULL) @@ -1738,7 +1738,7 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add) int parse_events_name(struct list_head *list, char *name) { - struct perf_evsel *evsel; + struct evsel *evsel; __evlist__for_each_entry(list, evsel) { if (!evsel->name) @@ -1918,7 +1918,7 @@ int parse_events(struct perf_evlist *evlist, const char *str, ret = parse_events__scanner(str, &parse_state, PE_START_EVENTS); perf_pmu__parse_cleanup(); if (!ret) { - struct perf_evsel *last; + struct evsel *last; if (list_empty(&parse_state.list)) { WARN_ONCE(true, "WARNING: event parser found nothing\n"); @@ -2027,11 +2027,11 @@ int parse_events_option(const struct option *opt, const char *str, static int foreach_evsel_in_last_glob(struct perf_evlist *evlist, - int (*func)(struct perf_evsel *evsel, + int (*func)(struct evsel *evsel, const void *arg), const void *arg) { - struct perf_evsel *last = NULL; + struct evsel *last = NULL; int err; /* @@ -2052,13 +2052,13 @@ foreach_evsel_in_last_glob(struct perf_evlist *evlist, if (last->node.prev == &evlist->entries) return 0; - last = list_entry(last->node.prev, struct perf_evsel, node); + last = list_entry(last->node.prev, struct evsel, node); } while (!last->cmdline_group_boundary); return 0; } -static int set_filter(struct perf_evsel *evsel, const void *arg) +static int set_filter(struct evsel *evsel, const void *arg) { const char *str = arg; bool found = false; @@ -2115,7 +2115,7 @@ int parse_filter(const struct option *opt, const char *str, (const void *)str); } -static int add_exclude_perf_filter(struct perf_evsel *evsel, +static int add_exclude_perf_filter(struct evsel *evsel, const void *arg __maybe_unused) { char new_filter[64]; @@ -2307,7 +2307,7 @@ static bool is_event_supported(u8 type, unsigned config) { bool ret = true; int open_return; - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_event_attr attr = { .type = type, .config = config, diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index f7139e1a2fd3..99e206598b60 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -12,7 +12,7 @@ #include struct list_head; -struct perf_evsel; +struct evsel; struct perf_evlist; struct parse_events_error; diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 62dda70227e5..beafbd469b0c 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -93,7 +93,7 @@ PyMODINIT_FUNC PyInit_perf(void); struct pyrf_event { PyObject_HEAD - struct perf_evsel *evsel; + struct evsel *evsel; struct perf_sample sample; union perf_event event; }; @@ -383,7 +383,7 @@ static PyObject* get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name) { const char *str = _PyUnicode_AsString(PyObject_Str(attr_name)); - struct perf_evsel *evsel = pevent->evsel; + struct evsel *evsel = pevent->evsel; struct tep_format_field *field; if (!evsel->tp_format) { @@ -674,7 +674,7 @@ static int pyrf_thread_map__setup_types(void) struct pyrf_evsel { PyObject_HEAD - struct perf_evsel evsel; + struct evsel evsel; }; static int pyrf_evsel__init(struct pyrf_evsel *pevsel, @@ -795,7 +795,7 @@ static void pyrf_evsel__delete(struct pyrf_evsel *pevsel) static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel, PyObject *args, PyObject *kwargs) { - struct perf_evsel *evsel = &pevsel->evsel; + struct evsel *evsel = &pevsel->evsel; struct perf_cpu_map *cpus = NULL; struct perf_thread_map *threads = NULL; PyObject *pcpus = NULL, *pthreads = NULL; @@ -966,7 +966,7 @@ static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist, { struct perf_evlist *evlist = &pevlist->evlist; PyObject *pevsel; - struct perf_evsel *evsel; + struct evsel *evsel; if (!PyArg_ParseTuple(args, "O", &pevsel)) return NULL; @@ -1018,7 +1018,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, if (event != NULL) { PyObject *pyevent = pyrf_event__new(event); struct pyrf_event *pevent = (struct pyrf_event *)pyevent; - struct perf_evsel *evsel; + struct evsel *evsel; if (pyevent == NULL) return PyErr_NoMemory(); @@ -1118,7 +1118,7 @@ static Py_ssize_t pyrf_evlist__length(PyObject *obj) static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i) { struct pyrf_evlist *pevlist = (void *)obj; - struct perf_evsel *pos; + struct evsel *pos; if (i >= pevlist->evlist.nr_entries) return NULL; diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 051c67f82548..ef8f686729fd 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -9,12 +9,12 @@ #include "util.h" #include "cloexec.h" -typedef void (*setup_probe_fn_t)(struct perf_evsel *evsel); +typedef void (*setup_probe_fn_t)(struct evsel *evsel); static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str) { struct perf_evlist *evlist; - struct perf_evsel *evsel; + struct evsel *evsel; unsigned long flags = perf_event_open_cloexec_flag(); int err = -EAGAIN, fd; static pid_t pid = -1; @@ -78,17 +78,17 @@ static bool perf_probe_api(setup_probe_fn_t fn) return false; } -static void perf_probe_sample_identifier(struct perf_evsel *evsel) +static void perf_probe_sample_identifier(struct evsel *evsel) { evsel->attr.sample_type |= PERF_SAMPLE_IDENTIFIER; } -static void perf_probe_comm_exec(struct perf_evsel *evsel) +static void perf_probe_comm_exec(struct evsel *evsel) { evsel->attr.comm_exec = 1; } -static void perf_probe_context_switch(struct perf_evsel *evsel) +static void perf_probe_context_switch(struct evsel *evsel) { evsel->attr.context_switch = 1; } @@ -135,7 +135,7 @@ bool perf_can_record_cpu_wide(void) void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, struct callchain_param *callchain) { - struct perf_evsel *evsel; + struct evsel *evsel; bool use_sample_identifier = false; bool use_comm_exec; bool sample_id = opts->sample_id; @@ -167,7 +167,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, use_sample_identifier = perf_can_sample_identifier(); sample_id = true; } else if (evlist->nr_entries > 1) { - struct perf_evsel *first = perf_evlist__first(evlist); + struct evsel *first = perf_evlist__first(evlist); evlist__for_each_entry(evlist, evsel) { if (evsel->attr.sample_type == first->attr.sample_type) @@ -259,7 +259,7 @@ int record_opts__config(struct record_opts *opts) bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str) { struct perf_evlist *temp_evlist; - struct perf_evsel *evsel; + struct evsel *evsel; int err, fd, cpu; bool ret = false; pid_t pid = -1; diff --git a/tools/perf/util/s390-cpumsf.c b/tools/perf/util/s390-cpumsf.c index 83d2e149ef19..59d78a9fe703 100644 --- a/tools/perf/util/s390-cpumsf.c +++ b/tools/perf/util/s390-cpumsf.c @@ -918,7 +918,7 @@ s390_cpumsf_process_event(struct perf_session *session, struct s390_cpumsf, auxtrace); u64 timestamp = sample->time; - struct perf_evsel *ev_bc000; + struct evsel *ev_bc000; int err = 0; diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sample-raw.c index 6650f599ed9c..159a08220947 100644 --- a/tools/perf/util/s390-sample-raw.c +++ b/tools/perf/util/s390-sample-raw.c @@ -203,7 +203,7 @@ static void s390_cpumcfdg_dump(struct perf_sample *sample) void perf_evlist__s390_sample_raw(struct perf_evlist *evlist, union perf_event *event, struct perf_sample *sample) { - struct perf_evsel *ev_bc000; + struct evsel *ev_bc000; if (event->header.type != PERF_RECORD_SAMPLE) return; diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index 61aa7f3df915..98dcdb9a79a4 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c @@ -258,7 +258,7 @@ static void define_event_symbols(struct tep_event *event, } static SV *perl_process_callchain(struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct addr_location *al) { AV *list; @@ -336,7 +336,7 @@ exit: } static void perl_process_tracepoint(struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct addr_location *al) { struct thread *thread = al->thread; @@ -431,7 +431,7 @@ static void perl_process_tracepoint(struct perf_sample *sample, static void perl_process_event_generic(union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel) + struct evsel *evsel) { dSP; @@ -455,7 +455,7 @@ static void perl_process_event_generic(union perf_event *event, static void perl_process_event(union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct addr_location *al) { perl_process_tracepoint(sample, evsel, al); diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 0a7e662036b4..106aec31c07c 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -392,7 +392,7 @@ static const char *get_dsoname(struct map *map) } static PyObject *python_process_callchain(struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct addr_location *al) { PyObject *pylist; @@ -634,7 +634,7 @@ static PyObject *get_sample_value_as_tuple(struct sample_read_value *value) static void set_sample_read_in_dict(PyObject *dict_sample, struct perf_sample *sample, - struct perf_evsel *evsel) + struct evsel *evsel) { u64 read_format = evsel->attr.read_format; PyObject *values; @@ -705,7 +705,7 @@ static int regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size) static void set_regs_in_dict(PyObject *dict, struct perf_sample *sample, - struct perf_evsel *evsel) + struct evsel *evsel) { struct perf_event_attr *attr = &evsel->attr; char bf[512]; @@ -722,7 +722,7 @@ static void set_regs_in_dict(PyObject *dict, } static PyObject *get_perf_sample_dict(struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct addr_location *al, PyObject *callchain) { @@ -790,7 +790,7 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample, } static void python_process_tracepoint(struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct addr_location *al) { struct tep_event *event = evsel->tp_format; @@ -955,7 +955,7 @@ static int tuple_set_bytes(PyObject *t, unsigned int pos, void *bytes, return PyTuple_SetItem(t, pos, _PyBytes_FromStringAndSize(bytes, sz)); } -static int python_export_evsel(struct db_export *dbe, struct perf_evsel *evsel) +static int python_export_evsel(struct db_export *dbe, struct evsel *evsel) { struct tables *tables = container_of(dbe, struct tables, dbe); PyObject *t; @@ -1275,7 +1275,7 @@ static int python_process_call_return(struct call_return *cr, u64 *parent_db_id, } static void python_process_general_event(struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct addr_location *al) { PyObject *handler, *t, *dict, *callchain; @@ -1311,7 +1311,7 @@ static void python_process_general_event(struct perf_sample *sample, static void python_process_event(union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct addr_location *al) { struct tables *tables = &tables_global; @@ -1340,7 +1340,7 @@ static void python_process_switch(union perf_event *event, } static void get_handler_name(char *str, size_t size, - struct perf_evsel *evsel) + struct evsel *evsel) { char *p = str; @@ -1353,7 +1353,7 @@ static void get_handler_name(char *str, size_t size, } static void -process_stat(struct perf_evsel *counter, int cpu, int thread, u64 tstamp, +process_stat(struct evsel *counter, int cpu, int thread, u64 tstamp, struct perf_counts_values *count) { PyObject *handler, *t; @@ -1390,7 +1390,7 @@ process_stat(struct perf_evsel *counter, int cpu, int thread, u64 tstamp, } static void python_process_stat(struct perf_stat_config *config, - struct perf_evsel *counter, u64 tstamp) + struct evsel *counter, u64 tstamp) { struct perf_thread_map *threads = counter->threads; struct perf_cpu_map *cpus = counter->cpus; diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 69d1d158a610..e9d1cf8eb274 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -151,7 +151,7 @@ static void perf_session__destroy_kernel_maps(struct perf_session *session) static bool perf_session__has_comm_exec(struct perf_session *session) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(session->evlist, evsel) { if (evsel->attr.comm_exec) @@ -322,7 +322,7 @@ static int process_event_synth_event_update_stub(struct perf_tool *tool __maybe_ static int process_event_sample_stub(struct perf_tool *tool __maybe_unused, union perf_event *event __maybe_unused, struct perf_sample *sample __maybe_unused, - struct perf_evsel *evsel __maybe_unused, + struct evsel *evsel __maybe_unused, struct machine *machine __maybe_unused) { dump_printf(": unhandled!\n"); @@ -1033,7 +1033,7 @@ static void callchain__lbr_callstack_printf(struct perf_sample *sample) } } -static void callchain__printf(struct perf_evsel *evsel, +static void callchain__printf(struct evsel *evsel, struct perf_sample *sample) { unsigned int i; @@ -1198,7 +1198,7 @@ static void dump_event(struct perf_evlist *evlist, union perf_event *event, event->header.size, perf_event__name(event->header.type)); } -static void dump_sample(struct perf_evsel *evsel, union perf_event *event, +static void dump_sample(struct evsel *evsel, union perf_event *event, struct perf_sample *sample) { u64 sample_type; @@ -1243,7 +1243,7 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event, sample_read__printf(sample, evsel->attr.read_format); } -static void dump_read(struct perf_evsel *evsel, union perf_event *event) +static void dump_read(struct evsel *evsel, union perf_event *event) { struct read_event *read_event = &event->read; u64 read_format; @@ -1351,7 +1351,7 @@ static int struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct machine *machine) { /* We know evsel != NULL. */ @@ -1377,7 +1377,7 @@ static int machines__deliver_event(struct machines *machines, struct perf_sample *sample, struct perf_tool *tool, u64 file_offset) { - struct perf_evsel *evsel; + struct evsel *evsel; struct machine *machine; dump_event(evlist, event, file_offset, sample); @@ -1705,7 +1705,7 @@ static void perf_session__warn_order(const struct perf_session *session) { const struct ordered_events *oe = &session->ordered_events; - struct perf_evsel *evsel; + struct evsel *evsel; bool should_warn = true; evlist__for_each_entry(session->evlist, evsel) { @@ -2183,7 +2183,7 @@ int perf_session__process_events(struct perf_session *session) bool perf_session__has_traces(struct perf_session *session, const char *msg) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(session->evlist, evsel) { if (evsel->attr.type == PERF_TYPE_TRACEPOINT) @@ -2257,10 +2257,10 @@ size_t perf_session__fprintf(struct perf_session *session, FILE *fp) return machine__fprintf(&session->machines.host, fp); } -struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, +struct evsel *perf_session__find_first_evtype(struct perf_session *session, unsigned int type) { - struct perf_evsel *pos; + struct evsel *pos; evlist__for_each_entry(session->evlist, pos) { if (pos->attr.type == type) @@ -2276,7 +2276,7 @@ int perf_session__cpu_bitmap(struct perf_session *session, struct perf_cpu_map *map; for (i = 0; i < PERF_TYPE_MAX; ++i) { - struct perf_evsel *evsel; + struct evsel *evsel; evsel = perf_session__find_first_evtype(session, i); if (!evsel) @@ -2327,10 +2327,10 @@ void perf_session__fprintf_info(struct perf_session *session, FILE *fp, int __perf_session__set_tracepoints_handlers(struct perf_session *session, - const struct perf_evsel_str_handler *assocs, + const struct evsel_str_handler *assocs, size_t nr_assocs) { - struct perf_evsel *evsel; + struct evsel *evsel; size_t i; int err; @@ -2397,7 +2397,7 @@ int perf_event__synthesize_id_index(struct perf_tool *tool, struct machine *machine) { union perf_event *ev; - struct perf_evsel *evsel; + struct evsel *evsel; size_t nr = 0, i = 0, sz, max_nr, n; int err; diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 863dbad87849..2b2427c4c0b9 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -73,7 +73,7 @@ int perf_session__queue_event(struct perf_session *s, union perf_event *event, void perf_tool__fill_defaults(struct perf_tool *tool); int perf_session__resolve_callchain(struct perf_session *session, - struct perf_evsel *evsel, + struct evsel *evsel, struct thread *thread, struct ip_callchain *chain, struct symbol **parent); @@ -110,7 +110,7 @@ size_t perf_session__fprintf_dsos_buildid(struct perf_session *session, FILE *fp size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp); -struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, +struct evsel *perf_session__find_first_evtype(struct perf_session *session, unsigned int type); int perf_session__cpu_bitmap(struct perf_session *session, @@ -118,10 +118,10 @@ int perf_session__cpu_bitmap(struct perf_session *session, void perf_session__fprintf_info(struct perf_session *s, FILE *fp, bool full); -struct perf_evsel_str_handler; +struct evsel_str_handler; int __perf_session__set_tracepoints_handlers(struct perf_session *session, - const struct perf_evsel_str_handler *assocs, + const struct evsel_str_handler *assocs, size_t nr_assocs); #define perf_session__set_tracepoints_handlers(session, array) \ diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 5d2518e89fc4..133d3a45997f 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -698,7 +698,7 @@ struct sort_entry sort_time = { static char *get_trace_output(struct hist_entry *he) { struct trace_seq seq; - struct perf_evsel *evsel; + struct evsel *evsel; struct tep_record rec = { .data = he->raw_data, .size = he->raw_size, @@ -723,7 +723,7 @@ static char *get_trace_output(struct hist_entry *he) static int64_t sort__trace_cmp(struct hist_entry *left, struct hist_entry *right) { - struct perf_evsel *evsel; + struct evsel *evsel; evsel = hists_to_evsel(left->hists); if (evsel->attr.type != PERF_TYPE_TRACEPOINT) @@ -740,7 +740,7 @@ sort__trace_cmp(struct hist_entry *left, struct hist_entry *right) static int hist_entry__trace_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { - struct perf_evsel *evsel; + struct evsel *evsel; evsel = hists_to_evsel(he->hists); if (evsel->attr.type != PERF_TYPE_TRACEPOINT) @@ -1984,7 +1984,7 @@ static int __sort_dimension__add_hpp_output(struct sort_dimension *sd, struct hpp_dynamic_entry { struct perf_hpp_fmt hpp; - struct perf_evsel *evsel; + struct evsel *evsel; struct tep_format_field *field; unsigned dynamic_len; bool raw_trace; @@ -2218,7 +2218,7 @@ static void hde_free(struct perf_hpp_fmt *fmt) } static struct hpp_dynamic_entry * -__alloc_dynamic_entry(struct perf_evsel *evsel, struct tep_format_field *field, +__alloc_dynamic_entry(struct evsel *evsel, struct tep_format_field *field, int level) { struct hpp_dynamic_entry *hde; @@ -2313,10 +2313,10 @@ static int parse_field_name(char *str, char **event, char **field, char **opt) * 2. full event name (e.g. sched:sched_switch) * 3. partial event name (should not contain ':') */ -static struct perf_evsel *find_evsel(struct perf_evlist *evlist, char *event_name) +static struct evsel *find_evsel(struct perf_evlist *evlist, char *event_name) { - struct perf_evsel *evsel = NULL; - struct perf_evsel *pos; + struct evsel *evsel = NULL; + struct evsel *pos; bool full_name; /* case 1 */ @@ -2352,7 +2352,7 @@ static struct perf_evsel *find_evsel(struct perf_evlist *evlist, char *event_nam return evsel; } -static int __dynamic_dimension__add(struct perf_evsel *evsel, +static int __dynamic_dimension__add(struct evsel *evsel, struct tep_format_field *field, bool raw_trace, int level) { @@ -2368,7 +2368,7 @@ static int __dynamic_dimension__add(struct perf_evsel *evsel, return 0; } -static int add_evsel_fields(struct perf_evsel *evsel, bool raw_trace, int level) +static int add_evsel_fields(struct evsel *evsel, bool raw_trace, int level) { int ret; struct tep_format_field *field; @@ -2388,7 +2388,7 @@ static int add_all_dynamic_fields(struct perf_evlist *evlist, bool raw_trace, int level) { int ret; - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { if (evsel->attr.type != PERF_TYPE_TRACEPOINT) @@ -2405,7 +2405,7 @@ static int add_all_matching_fields(struct perf_evlist *evlist, char *field_name, bool raw_trace, int level) { int ret = -ESRCH; - struct perf_evsel *evsel; + struct evsel *evsel; struct tep_format_field *field; evlist__for_each_entry(evlist, evsel) { @@ -2427,7 +2427,7 @@ static int add_dynamic_entry(struct perf_evlist *evlist, const char *tok, int level) { char *str, *event_name, *field_name, *opt_name; - struct perf_evsel *evsel; + struct evsel *evsel; struct tep_format_field *field; bool raw_trace = symbol_conf.raw_trace; int ret = 0; @@ -2720,7 +2720,7 @@ static const char *get_default_sort_order(struct perf_evlist *evlist) default_tracepoint_sort_order, }; bool use_trace = true; - struct perf_evsel *evsel; + struct evsel *evsel; BUG_ON(sort__mode >= ARRAY_SIZE(default_sort_orders)); diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 58df6a0dbb9f..8da4ddcb2e44 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -45,7 +45,7 @@ static void print_noise_pct(struct perf_stat_config *config, } static void print_noise(struct perf_stat_config *config, - struct perf_evsel *evsel, double avg) + struct evsel *evsel, double avg) { struct perf_stat_evsel *ps; @@ -56,7 +56,7 @@ static void print_noise(struct perf_stat_config *config, print_noise_pct(config, stddev_stats(&ps->res_stats[0]), avg); } -static void print_cgroup(struct perf_stat_config *config, struct perf_evsel *evsel) +static void print_cgroup(struct perf_stat_config *config, struct evsel *evsel) { if (nr_cgroups) { const char *cgrp_name = evsel->cgrp ? evsel->cgrp->name : ""; @@ -66,7 +66,7 @@ static void print_cgroup(struct perf_stat_config *config, struct perf_evsel *evs static void aggr_printout(struct perf_stat_config *config, - struct perf_evsel *evsel, int id, int nr) + struct evsel *evsel, int id, int nr) { switch (config->aggr_mode) { case AGGR_CORE: @@ -134,7 +134,7 @@ struct outstate { const char *prefix; int nfields; int id, nr; - struct perf_evsel *evsel; + struct evsel *evsel; }; #define METRIC_LEN 35 @@ -233,7 +233,7 @@ static bool valid_only_metric(const char *unit) return true; } -static const char *fixunit(char *buf, struct perf_evsel *evsel, +static const char *fixunit(char *buf, struct evsel *evsel, const char *unit) { if (!strncmp(unit, "of all", 6)) { @@ -310,7 +310,7 @@ static void print_metric_header(struct perf_stat_config *config, } static int first_shadow_cpu(struct perf_stat_config *config, - struct perf_evsel *evsel, int id) + struct evsel *evsel, int id) { struct perf_evlist *evlist = evsel->evlist; int i; @@ -334,7 +334,7 @@ static int first_shadow_cpu(struct perf_stat_config *config, } static void abs_printout(struct perf_stat_config *config, - int id, int nr, struct perf_evsel *evsel, double avg) + int id, int nr, struct evsel *evsel, double avg) { FILE *output = config->output; double sc = evsel->scale; @@ -363,11 +363,11 @@ static void abs_printout(struct perf_stat_config *config, print_cgroup(config, evsel); } -static bool is_mixed_hw_group(struct perf_evsel *counter) +static bool is_mixed_hw_group(struct evsel *counter) { struct perf_evlist *evlist = counter->evlist; u32 pmu_type = counter->attr.type; - struct perf_evsel *pos; + struct evsel *pos; if (counter->nr_members < 2) return false; @@ -388,7 +388,7 @@ static bool is_mixed_hw_group(struct perf_evsel *counter) } static void printout(struct perf_stat_config *config, int id, int nr, - struct perf_evsel *counter, double uval, + struct evsel *counter, double uval, char *prefix, u64 run, u64 ena, double noise, struct runtime_stat *st) { @@ -493,7 +493,7 @@ static void aggr_update_shadow(struct perf_stat_config *config, { int cpu, s2, id, s; u64 val; - struct perf_evsel *counter; + struct evsel *counter; for (s = 0; s < config->aggr_map->nr; s++) { id = config->aggr_map->map[s]; @@ -512,7 +512,7 @@ static void aggr_update_shadow(struct perf_stat_config *config, } } -static void uniquify_event_name(struct perf_evsel *counter) +static void uniquify_event_name(struct evsel *counter) { char *new_name; char *config; @@ -540,13 +540,13 @@ static void uniquify_event_name(struct perf_evsel *counter) counter->uniquified_name = true; } -static void collect_all_aliases(struct perf_stat_config *config, struct perf_evsel *counter, - void (*cb)(struct perf_stat_config *config, struct perf_evsel *counter, void *data, +static void collect_all_aliases(struct perf_stat_config *config, struct evsel *counter, + void (*cb)(struct perf_stat_config *config, struct evsel *counter, void *data, bool first), void *data) { struct perf_evlist *evlist = counter->evlist; - struct perf_evsel *alias; + struct evsel *alias; alias = list_prepare_entry(counter, &(evlist->entries), node); list_for_each_entry_continue (alias, &evlist->entries, node) { @@ -562,8 +562,8 @@ static void collect_all_aliases(struct perf_stat_config *config, struct perf_evs } } -static bool collect_data(struct perf_stat_config *config, struct perf_evsel *counter, - void (*cb)(struct perf_stat_config *config, struct perf_evsel *counter, void *data, +static bool collect_data(struct perf_stat_config *config, struct evsel *counter, + void (*cb)(struct perf_stat_config *config, struct evsel *counter, void *data, bool first), void *data) { @@ -585,7 +585,7 @@ struct aggr_data { }; static void aggr_cb(struct perf_stat_config *config, - struct perf_evsel *counter, void *data, bool first) + struct evsel *counter, void *data, bool first) { struct aggr_data *ad = data; int cpu, s2; @@ -616,7 +616,7 @@ static void aggr_cb(struct perf_stat_config *config, } static void print_counter_aggrdata(struct perf_stat_config *config, - struct perf_evsel *counter, int s, + struct evsel *counter, int s, char *prefix, bool metric_only, bool *first) { @@ -656,7 +656,7 @@ static void print_aggr(struct perf_stat_config *config, { bool metric_only = config->metric_only; FILE *output = config->output; - struct perf_evsel *counter; + struct evsel *counter; int s; bool first; @@ -691,7 +691,7 @@ static int cmp_val(const void *a, const void *b) } static struct perf_aggr_thread_value *sort_aggr_thread( - struct perf_evsel *counter, + struct evsel *counter, int nthreads, int ncpus, int *ret, struct target *_target) @@ -741,7 +741,7 @@ static struct perf_aggr_thread_value *sort_aggr_thread( static void print_aggr_thread(struct perf_stat_config *config, struct target *_target, - struct perf_evsel *counter, char *prefix) + struct evsel *counter, char *prefix) { FILE *output = config->output; int nthreads = thread_map__nr(counter->threads); @@ -779,7 +779,7 @@ struct caggr_data { }; static void counter_aggr_cb(struct perf_stat_config *config __maybe_unused, - struct perf_evsel *counter, void *data, + struct evsel *counter, void *data, bool first __maybe_unused) { struct caggr_data *cd = data; @@ -795,7 +795,7 @@ static void counter_aggr_cb(struct perf_stat_config *config __maybe_unused, * aggregated counts in system-wide mode */ static void print_counter_aggr(struct perf_stat_config *config, - struct perf_evsel *counter, char *prefix) + struct evsel *counter, char *prefix) { bool metric_only = config->metric_only; FILE *output = config->output; @@ -816,7 +816,7 @@ static void print_counter_aggr(struct perf_stat_config *config, } static void counter_cb(struct perf_stat_config *config __maybe_unused, - struct perf_evsel *counter, void *data, + struct evsel *counter, void *data, bool first __maybe_unused) { struct aggr_data *ad = data; @@ -831,7 +831,7 @@ static void counter_cb(struct perf_stat_config *config __maybe_unused, * does not use aggregated count in system-wide */ static void print_counter(struct perf_stat_config *config, - struct perf_evsel *counter, char *prefix) + struct evsel *counter, char *prefix) { FILE *output = config->output; u64 ena, run, val; @@ -864,7 +864,7 @@ static void print_no_aggr_metric(struct perf_stat_config *config, { int cpu; int nrcpus = 0; - struct perf_evsel *counter; + struct evsel *counter; u64 ena, run, val; double uval; @@ -914,7 +914,7 @@ static void print_metric_headers(struct perf_stat_config *config, const char *prefix, bool no_indent) { struct perf_stat_output_ctx out; - struct perf_evsel *counter; + struct evsel *counter; struct outstate os = { .fh = config->output }; @@ -1132,7 +1132,7 @@ static void print_footer(struct perf_stat_config *config) } static void print_percore(struct perf_stat_config *config, - struct perf_evsel *counter, char *prefix) + struct evsel *counter, char *prefix) { bool metric_only = config->metric_only; FILE *output = config->output; @@ -1164,7 +1164,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist, { bool metric_only = config->metric_only; int interval = config->interval; - struct perf_evsel *counter; + struct evsel *counter; char buf[64], *prefix = NULL; if (interval) diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index accb1bf1cfd8..8c19f3149f34 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -25,7 +25,7 @@ struct stats walltime_nsecs_stats; struct saved_value { struct rb_node rb_node; - struct perf_evsel *evsel; + struct evsel *evsel; enum stat_type type; int ctx; int cpu; @@ -94,7 +94,7 @@ static void saved_value_delete(struct rblist *rblist __maybe_unused, free(v); } -static struct saved_value *saved_value_lookup(struct perf_evsel *evsel, +static struct saved_value *saved_value_lookup(struct evsel *evsel, int cpu, bool create, enum stat_type type, @@ -146,7 +146,7 @@ void perf_stat__init_shadow_stats(void) runtime_stat__init(&rt_stat); } -static int evsel_context(struct perf_evsel *evsel) +static int evsel_context(struct evsel *evsel) { int ctx = 0; @@ -207,7 +207,7 @@ static void update_runtime_stat(struct runtime_stat *st, * more semantic information such as miss/hit ratios, * instruction rates, etc: */ -void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 count, +void perf_stat__update_shadow_stats(struct evsel *counter, u64 count, int cpu, struct runtime_stat *st) { int ctx = evsel_context(counter); @@ -299,10 +299,10 @@ static const char *get_ratio_color(enum grc_type type, double ratio) return color; } -static struct perf_evsel *perf_stat__find_event(struct perf_evlist *evsel_list, +static struct evsel *perf_stat__find_event(struct perf_evlist *evsel_list, const char *name) { - struct perf_evsel *c2; + struct evsel *c2; evlist__for_each_entry (evsel_list, c2) { if (!strcasecmp(c2->name, name) && !c2->collect_stat) @@ -314,7 +314,7 @@ static struct perf_evsel *perf_stat__find_event(struct perf_evlist *evsel_list, /* Mark MetricExpr target events and link events using them to them. */ void perf_stat__collect_metric_expr(struct perf_evlist *evsel_list) { - struct perf_evsel *counter, *leader, **metric_events, *oc; + struct evsel *counter, *leader, **metric_events, *oc; bool found; const char **metric_names; int i; @@ -332,7 +332,7 @@ void perf_stat__collect_metric_expr(struct perf_evlist *evsel_list) &metric_names, &num_metric_names) < 0) continue; - metric_events = calloc(sizeof(struct perf_evsel *), + metric_events = calloc(sizeof(struct evsel *), num_metric_names + 1); if (!metric_events) return; @@ -415,7 +415,7 @@ static double runtime_stat_n(struct runtime_stat *st, static void print_stalled_cycles_frontend(struct perf_stat_config *config, int cpu, - struct perf_evsel *evsel, double avg, + struct evsel *evsel, double avg, struct perf_stat_output_ctx *out, struct runtime_stat *st) { @@ -439,7 +439,7 @@ static void print_stalled_cycles_frontend(struct perf_stat_config *config, static void print_stalled_cycles_backend(struct perf_stat_config *config, int cpu, - struct perf_evsel *evsel, double avg, + struct evsel *evsel, double avg, struct perf_stat_output_ctx *out, struct runtime_stat *st) { @@ -459,7 +459,7 @@ static void print_stalled_cycles_backend(struct perf_stat_config *config, static void print_branch_misses(struct perf_stat_config *config, int cpu, - struct perf_evsel *evsel, + struct evsel *evsel, double avg, struct perf_stat_output_ctx *out, struct runtime_stat *st) @@ -480,7 +480,7 @@ static void print_branch_misses(struct perf_stat_config *config, static void print_l1_dcache_misses(struct perf_stat_config *config, int cpu, - struct perf_evsel *evsel, + struct evsel *evsel, double avg, struct perf_stat_output_ctx *out, struct runtime_stat *st) @@ -502,7 +502,7 @@ static void print_l1_dcache_misses(struct perf_stat_config *config, static void print_l1_icache_misses(struct perf_stat_config *config, int cpu, - struct perf_evsel *evsel, + struct evsel *evsel, double avg, struct perf_stat_output_ctx *out, struct runtime_stat *st) @@ -523,7 +523,7 @@ static void print_l1_icache_misses(struct perf_stat_config *config, static void print_dtlb_cache_misses(struct perf_stat_config *config, int cpu, - struct perf_evsel *evsel, + struct evsel *evsel, double avg, struct perf_stat_output_ctx *out, struct runtime_stat *st) @@ -543,7 +543,7 @@ static void print_dtlb_cache_misses(struct perf_stat_config *config, static void print_itlb_cache_misses(struct perf_stat_config *config, int cpu, - struct perf_evsel *evsel, + struct evsel *evsel, double avg, struct perf_stat_output_ctx *out, struct runtime_stat *st) @@ -563,7 +563,7 @@ static void print_itlb_cache_misses(struct perf_stat_config *config, static void print_ll_cache_misses(struct perf_stat_config *config, int cpu, - struct perf_evsel *evsel, + struct evsel *evsel, double avg, struct perf_stat_output_ctx *out, struct runtime_stat *st) @@ -686,7 +686,7 @@ static double td_be_bound(int ctx, int cpu, struct runtime_stat *st) } static void print_smi_cost(struct perf_stat_config *config, - int cpu, struct perf_evsel *evsel, + int cpu, struct evsel *evsel, struct perf_stat_output_ctx *out, struct runtime_stat *st) { @@ -712,7 +712,7 @@ static void print_smi_cost(struct perf_stat_config *config, static void generic_metric(struct perf_stat_config *config, const char *metric_expr, - struct perf_evsel **metric_events, + struct evsel **metric_events, char *name, const char *metric_name, double avg, @@ -780,7 +780,7 @@ static void generic_metric(struct perf_stat_config *config, } void perf_stat__print_shadow_stats(struct perf_stat_config *config, - struct perf_evsel *evsel, + struct evsel *evsel, double avg, int cpu, struct perf_stat_output_ctx *out, struct rblist *metric_events, diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 62791c063f7a..7acb9a6730fe 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -68,7 +68,7 @@ double rel_stddev_stats(double stddev, double avg) return pct; } -bool __perf_evsel_stat__is(struct perf_evsel *evsel, +bool __perf_evsel_stat__is(struct evsel *evsel, enum perf_stat_evsel_id id) { struct perf_stat_evsel *ps = evsel->stats; @@ -93,7 +93,7 @@ static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = { }; #undef ID -static void perf_stat_evsel_id_init(struct perf_evsel *evsel) +static void perf_stat_evsel_id_init(struct evsel *evsel) { struct perf_stat_evsel *ps = evsel->stats; int i; @@ -108,7 +108,7 @@ static void perf_stat_evsel_id_init(struct perf_evsel *evsel) } } -static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel) +static void perf_evsel__reset_stat_priv(struct evsel *evsel) { int i; struct perf_stat_evsel *ps = evsel->stats; @@ -119,7 +119,7 @@ static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel) perf_stat_evsel_id_init(evsel); } -static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) +static int perf_evsel__alloc_stat_priv(struct evsel *evsel) { evsel->stats = zalloc(sizeof(struct perf_stat_evsel)); if (evsel->stats == NULL) @@ -128,7 +128,7 @@ static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) return 0; } -static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) +static void perf_evsel__free_stat_priv(struct evsel *evsel) { struct perf_stat_evsel *ps = evsel->stats; @@ -137,7 +137,7 @@ static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) zfree(&evsel->stats); } -static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel, +static int perf_evsel__alloc_prev_raw_counts(struct evsel *evsel, int ncpus, int nthreads) { struct perf_counts *counts; @@ -149,13 +149,13 @@ static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel, return counts ? 0 : -ENOMEM; } -static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel) +static void perf_evsel__free_prev_raw_counts(struct evsel *evsel) { perf_counts__delete(evsel->prev_raw_counts); evsel->prev_raw_counts = NULL; } -static int perf_evsel__alloc_stats(struct perf_evsel *evsel, bool alloc_raw) +static int perf_evsel__alloc_stats(struct evsel *evsel, bool alloc_raw) { int ncpus = perf_evsel__nr_cpus(evsel); int nthreads = thread_map__nr(evsel->threads); @@ -170,7 +170,7 @@ static int perf_evsel__alloc_stats(struct perf_evsel *evsel, bool alloc_raw) int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { if (perf_evsel__alloc_stats(evsel, alloc_raw)) @@ -186,7 +186,7 @@ out_free: void perf_evlist__free_stats(struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { perf_evsel__free_stat_priv(evsel); @@ -197,7 +197,7 @@ void perf_evlist__free_stats(struct perf_evlist *evlist) void perf_evlist__reset_stats(struct perf_evlist *evlist) { - struct perf_evsel *evsel; + struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { perf_evsel__reset_stat_priv(evsel); @@ -205,13 +205,13 @@ void perf_evlist__reset_stats(struct perf_evlist *evlist) } } -static void zero_per_pkg(struct perf_evsel *counter) +static void zero_per_pkg(struct evsel *counter) { if (counter->per_pkg_mask) memset(counter->per_pkg_mask, 0, MAX_NR_CPUS); } -static int check_per_pkg(struct perf_evsel *counter, +static int check_per_pkg(struct evsel *counter, struct perf_counts_values *vals, int cpu, bool *skip) { unsigned long *mask = counter->per_pkg_mask; @@ -254,7 +254,7 @@ static int check_per_pkg(struct perf_evsel *counter, } static int -process_counter_values(struct perf_stat_config *config, struct perf_evsel *evsel, +process_counter_values(struct perf_stat_config *config, struct evsel *evsel, int cpu, int thread, struct perf_counts_values *count) { @@ -306,7 +306,7 @@ process_counter_values(struct perf_stat_config *config, struct perf_evsel *evsel } static int process_counter_maps(struct perf_stat_config *config, - struct perf_evsel *counter) + struct evsel *counter) { int nthreads = thread_map__nr(counter->threads); int ncpus = perf_evsel__nr_cpus(counter); @@ -327,7 +327,7 @@ static int process_counter_maps(struct perf_stat_config *config, } int perf_stat_process_counter(struct perf_stat_config *config, - struct perf_evsel *counter) + struct evsel *counter) { struct perf_counts_values *aggr = &counter->counts->aggr; struct perf_stat_evsel *ps = counter->stats; @@ -381,7 +381,7 @@ int perf_event__process_stat_event(struct perf_session *session, { struct perf_counts_values count; struct stat_event *st = &event->stat; - struct perf_evsel *counter; + struct evsel *counter; count.val = st->val; count.ena = st->ena; @@ -437,12 +437,12 @@ size_t perf_event__fprintf_stat_config(union perf_event *event, FILE *fp) return ret; } -int create_perf_stat_counter(struct perf_evsel *evsel, +int create_perf_stat_counter(struct evsel *evsel, struct perf_stat_config *config, struct target *target) { struct perf_event_attr *attr = &evsel->attr; - struct perf_evsel *leader = evsel->leader; + struct evsel *leader = evsel->leader; attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING; diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index fa675d09febd..b64cf0177a91 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -143,11 +143,11 @@ static inline void init_stats(struct stats *stats) stats->max = 0; } -struct perf_evsel; +struct evsel; struct perf_evlist; struct perf_aggr_thread_value { - struct perf_evsel *counter; + struct evsel *counter; int id; double uval; u64 val; @@ -155,7 +155,7 @@ struct perf_aggr_thread_value { u64 ena; }; -bool __perf_evsel_stat__is(struct perf_evsel *evsel, +bool __perf_evsel_stat__is(struct evsel *evsel, enum perf_stat_evsel_id id); #define perf_stat_evsel__is(evsel, id) \ @@ -174,7 +174,7 @@ void runtime_stat__exit(struct runtime_stat *st); void perf_stat__init_shadow_stats(void); void perf_stat__reset_shadow_stats(void); void perf_stat__reset_shadow_per_stat(struct runtime_stat *st); -void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 count, +void perf_stat__update_shadow_stats(struct evsel *counter, u64 count, int cpu, struct runtime_stat *st); struct perf_stat_output_ctx { void *ctx; @@ -184,7 +184,7 @@ struct perf_stat_output_ctx { }; void perf_stat__print_shadow_stats(struct perf_stat_config *config, - struct perf_evsel *evsel, + struct evsel *evsel, double avg, int cpu, struct perf_stat_output_ctx *out, struct rblist *metric_events, @@ -196,7 +196,7 @@ void perf_evlist__free_stats(struct perf_evlist *evlist); void perf_evlist__reset_stats(struct perf_evlist *evlist); int perf_stat_process_counter(struct perf_stat_config *config, - struct perf_evsel *counter); + struct evsel *counter); struct perf_tool; union perf_event; struct perf_session; @@ -207,7 +207,7 @@ size_t perf_event__fprintf_stat(union perf_event *event, FILE *fp); size_t perf_event__fprintf_stat_round(union perf_event *event, FILE *fp); size_t perf_event__fprintf_stat_config(union perf_event *event, FILE *fp); -int create_perf_stat_counter(struct perf_evsel *evsel, +int create_perf_stat_counter(struct evsel *evsel, struct perf_stat_config *config, struct target *target); int perf_stat_synthesize_config(struct perf_stat_config *config, diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h index 9096a6e3de59..5d880a6f0a34 100644 --- a/tools/perf/util/tool.h +++ b/tools/perf/util/tool.h @@ -9,7 +9,7 @@ struct perf_session; union perf_event; struct perf_evlist; -struct perf_evsel; +struct evsel; struct perf_sample; struct perf_tool; struct machine; @@ -17,7 +17,7 @@ struct ordered_events; typedef int (*event_sample)(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, struct machine *machine); + struct evsel *evsel, struct machine *machine); typedef int (*event_op)(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine); diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c index 251bbf124fb0..9f098db76e3c 100644 --- a/tools/perf/util/top.c +++ b/tools/perf/util/top.c @@ -71,7 +71,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) } if (top->evlist->nr_entries == 1) { - struct perf_evsel *first = perf_evlist__first(top->evlist); + struct evsel *first = perf_evlist__first(top->evlist); ret += SNPRINTF(bf + ret, size - ret, "%" PRIu64 "%s ", (uint64_t)first->attr.sample_period, opts->freq ? "Hz" : ""); diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h index 19f95eaf75c8..7e0f363c0658 100644 --- a/tools/perf/util/top.h +++ b/tools/perf/util/top.h @@ -10,7 +10,7 @@ #include struct perf_evlist; -struct perf_evsel; +struct evsel; struct perf_session; struct perf_top { @@ -33,7 +33,7 @@ struct perf_top { bool vmlinux_warned; bool dump_symtab; struct hist_entry *sym_filter_entry; - struct perf_evsel *sym_evsel; + struct evsel *sym_evsel; struct perf_session *session; struct winsize winsize; int realtime_prio; diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index 4550015b9d5d..d7ae0627ac47 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c @@ -405,7 +405,7 @@ static struct tracepoint_path * get_tracepoints_path(struct list_head *pattrs) { struct tracepoint_path path, *ppath = &path; - struct perf_evsel *pos; + struct evsel *pos; int nr_tracepoints = 0; list_for_each_entry(pos, pattrs, node) { @@ -441,7 +441,7 @@ next: bool have_tracepoints(struct list_head *pattrs) { - struct perf_evsel *pos; + struct evsel *pos; list_for_each_entry(pos, pattrs, node) if (pos->attr.type == PERF_TYPE_TRACEPOINT) diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c index ba58f69777a1..dfd2640c763a 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c @@ -29,7 +29,7 @@ static int stop_script_unsupported(void) static void process_event_unsupported(union perf_event *event __maybe_unused, struct perf_sample *sample __maybe_unused, - struct perf_evsel *evsel __maybe_unused, + struct evsel *evsel __maybe_unused, struct addr_location *al __maybe_unused) { } diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index c7002fe11673..258d79071d81 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h @@ -79,13 +79,13 @@ struct scripting_ops { int (*stop_script) (void); void (*process_event) (union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, + struct evsel *evsel, struct addr_location *al); void (*process_switch)(union perf_event *event, struct perf_sample *sample, struct machine *machine); void (*process_stat)(struct perf_stat_config *config, - struct perf_evsel *evsel, u64 tstamp); + struct evsel *evsel, u64 tstamp); void (*process_stat_interval)(u64 tstamp); int (*generate_script) (struct tep_handle *pevent, const char *outfile); }; -- cgit v1.2.3-59-g8ed1b From 63503dba87acfab49280d3b05df6705a6f327e8a Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:23:52 +0200 Subject: perf evlist: Rename struct perf_evlist to struct evlist Rename struct perf_evlist to struct evlist, so we don't have a name clash when we add struct perf_evlist in libperf. Committer notes: Added fixes to build on arm64, from Jiri and from me (tools/perf/util/cs-etm.c) Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-6-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/auxtrace.c | 2 +- tools/perf/arch/arm/util/cs-etm.c | 8 +- tools/perf/arch/arm64/util/arm-spe.c | 6 +- tools/perf/arch/powerpc/util/kvm-stat.c | 6 +- tools/perf/arch/s390/util/auxtrace.c | 6 +- tools/perf/arch/x86/tests/intel-cqm.c | 2 +- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/arch/x86/util/auxtrace.c | 4 +- tools/perf/arch/x86/util/intel-bts.c | 6 +- tools/perf/arch/x86/util/intel-pt.c | 14 +- tools/perf/builtin-c2c.c | 4 +- tools/perf/builtin-diff.c | 8 +- tools/perf/builtin-ftrace.c | 2 +- tools/perf/builtin-inject.c | 8 +- tools/perf/builtin-kvm.c | 8 +- tools/perf/builtin-record.c | 14 +- tools/perf/builtin-report.c | 8 +- tools/perf/builtin-sched.c | 4 +- tools/perf/builtin-script.c | 10 +- tools/perf/builtin-stat.c | 2 +- tools/perf/builtin-top.c | 14 +- tools/perf/builtin-trace.c | 16 +-- tools/perf/tests/backward-ring-buffer.c | 6 +- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 8 +- tools/perf/tests/event-times.c | 20 +-- tools/perf/tests/event_update.c | 2 +- tools/perf/tests/evsel-roundtrip-name.c | 4 +- tools/perf/tests/hists_cumulate.c | 2 +- tools/perf/tests/hists_filter.c | 4 +- tools/perf/tests/hists_link.c | 4 +- tools/perf/tests/hists_output.c | 2 +- tools/perf/tests/keep-tracking.c | 4 +- tools/perf/tests/mmap-basic.c | 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/parse-events.c | 126 ++++++++--------- tools/perf/tests/parse-no-sample-id-all.c | 4 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 10 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/tests/time-utils-test.c | 2 +- tools/perf/ui/browsers/hists.c | 6 +- tools/perf/ui/gtk/gtk.h | 4 +- tools/perf/ui/gtk/hists.c | 2 +- tools/perf/ui/hist.c | 2 +- tools/perf/util/auxtrace.c | 10 +- tools/perf/util/auxtrace.h | 24 ++-- tools/perf/util/bpf-event.c | 2 +- tools/perf/util/bpf-event.h | 4 +- tools/perf/util/bpf-loader.c | 20 +-- tools/perf/util/bpf-loader.h | 24 ++-- tools/perf/util/cgroup.c | 10 +- tools/perf/util/cgroup.h | 6 +- tools/perf/util/cs-etm.c | 4 +- tools/perf/util/data-convert-bt.c | 4 +- tools/perf/util/evlist.c | 194 +++++++++++++-------------- tools/perf/util/evlist.h | 160 +++++++++++----------- tools/perf/util/evsel.c | 4 +- tools/perf/util/evsel.h | 4 +- tools/perf/util/header.c | 86 ++++++------ tools/perf/util/header.h | 16 +-- tools/perf/util/hist.c | 2 +- tools/perf/util/hist.h | 10 +- tools/perf/util/intel-bts.c | 2 +- tools/perf/util/intel-pt.c | 10 +- tools/perf/util/kvm-stat.h | 4 +- tools/perf/util/metricgroup.c | 6 +- tools/perf/util/mmap.c | 2 +- tools/perf/util/parse-events.c | 10 +- tools/perf/util/parse-events.h | 6 +- tools/perf/util/python.c | 16 +-- tools/perf/util/record.c | 8 +- tools/perf/util/s390-sample-raw.c | 2 +- tools/perf/util/sample-raw.c | 2 +- tools/perf/util/sample-raw.h | 6 +- tools/perf/util/session.c | 24 ++-- tools/perf/util/session.h | 4 +- tools/perf/util/sort.c | 20 +-- tools/perf/util/sort.h | 6 +- tools/perf/util/stat-display.c | 18 +-- tools/perf/util/stat-shadow.c | 4 +- tools/perf/util/stat.c | 8 +- tools/perf/util/stat.h | 14 +- tools/perf/util/tool.h | 4 +- tools/perf/util/top.h | 4 +- 86 files changed, 571 insertions(+), 571 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c index fd17dccfcb0b..306a54185438 100644 --- a/tools/perf/arch/arm/util/auxtrace.c +++ b/tools/perf/arch/arm/util/auxtrace.c @@ -50,7 +50,7 @@ static struct perf_pmu **find_all_arm_spe_pmus(int *nr_spes, int *err) } struct auxtrace_record -*auxtrace_record__init(struct perf_evlist *evlist, int *err) +*auxtrace_record__init(struct evlist *evlist, int *err) { struct perf_pmu *cs_etm_pmu; struct evsel *evsel; diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 476f845be5fe..91c64daa4487 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -32,7 +32,7 @@ struct cs_etm_recording { struct auxtrace_record itr; struct perf_pmu *cs_etm_pmu; - struct perf_evlist *evlist; + struct evlist *evlist; int wrapped_cnt; bool *wrapped; bool snapshot_mode; @@ -245,7 +245,7 @@ static int cs_etm_set_sink_attr(struct perf_pmu *pmu, } static int cs_etm_recording_options(struct auxtrace_record *itr, - struct perf_evlist *evlist, + struct evlist *evlist, struct record_opts *opts) { int ret; @@ -434,7 +434,7 @@ static u64 cs_etm_get_config(struct auxtrace_record *itr) struct cs_etm_recording *ptr = container_of(itr, struct cs_etm_recording, itr); struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu; - struct perf_evlist *evlist = ptr->evlist; + struct evlist *evlist = ptr->evlist; struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { @@ -485,7 +485,7 @@ static u64 cs_etmv4_get_config(struct auxtrace_record *itr) static size_t cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { int i; int etmv3 = 0, etmv4 = 0; diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index 103bf20ae32a..cc29b995c751 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -27,12 +27,12 @@ struct arm_spe_recording { struct auxtrace_record itr; struct perf_pmu *arm_spe_pmu; - struct perf_evlist *evlist; + struct evlist *evlist; }; static size_t arm_spe_info_priv_size(struct auxtrace_record *itr __maybe_unused, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { return ARM_SPE_AUXTRACE_PRIV_SIZE; } @@ -59,7 +59,7 @@ static int arm_spe_info_fill(struct auxtrace_record *itr, } static int arm_spe_recording_options(struct auxtrace_record *itr, - struct perf_evlist *evlist, + struct evlist *evlist, struct record_opts *opts) { struct arm_spe_recording *sper = diff --git a/tools/perf/arch/powerpc/util/kvm-stat.c b/tools/perf/arch/powerpc/util/kvm-stat.c index 557c474f0a4b..28fc0bab370f 100644 --- a/tools/perf/arch/powerpc/util/kvm-stat.c +++ b/tools/perf/arch/powerpc/util/kvm-stat.c @@ -106,7 +106,7 @@ const char * const kvm_skip_events[] = { }; -static int is_tracepoint_available(const char *str, struct perf_evlist *evlist) +static int is_tracepoint_available(const char *str, struct evlist *evlist) { struct parse_events_error err; int ret; @@ -119,7 +119,7 @@ static int is_tracepoint_available(const char *str, struct perf_evlist *evlist) } static int ppc__setup_book3s_hv(struct perf_kvm_stat *kvm, - struct perf_evlist *evlist) + struct evlist *evlist) { const char **events_ptr; int i, nr_tp = 0, err = -1; @@ -146,7 +146,7 @@ static int ppc__setup_book3s_hv(struct perf_kvm_stat *kvm, /* Wrapper to setup kvm tracepoints */ static int ppc__setup_kvm_tp(struct perf_kvm_stat *kvm) { - struct perf_evlist *evlist = perf_evlist__new(); + struct evlist *evlist = perf_evlist__new(); if (evlist == NULL) return -ENOMEM; diff --git a/tools/perf/arch/s390/util/auxtrace.c b/tools/perf/arch/s390/util/auxtrace.c index aec819b945c5..833f60fa9c5a 100644 --- a/tools/perf/arch/s390/util/auxtrace.c +++ b/tools/perf/arch/s390/util/auxtrace.c @@ -20,7 +20,7 @@ static void cpumsf_free(struct auxtrace_record *itr) } static size_t cpumsf_info_priv_size(struct auxtrace_record *itr __maybe_unused, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { return 0; } @@ -43,7 +43,7 @@ cpumsf_reference(struct auxtrace_record *itr __maybe_unused) static int cpumsf_recording_options(struct auxtrace_record *ar __maybe_unused, - struct perf_evlist *evlist __maybe_unused, + struct evlist *evlist __maybe_unused, struct record_opts *opts) { unsigned int factor = 1; @@ -82,7 +82,7 @@ cpumsf_parse_snapshot_options(struct auxtrace_record *itr __maybe_unused, * auxtrace_record__init is called when perf record * check if the event really need auxtrace */ -struct auxtrace_record *auxtrace_record__init(struct perf_evlist *evlist, +struct auxtrace_record *auxtrace_record__init(struct evlist *evlist, int *err) { struct auxtrace_record *aux; diff --git a/tools/perf/arch/x86/tests/intel-cqm.c b/tools/perf/arch/x86/tests/intel-cqm.c index b88ed71b2e3f..333b2f0d61e4 100644 --- a/tools/perf/arch/x86/tests/intel-cqm.c +++ b/tools/perf/arch/x86/tests/intel-cqm.c @@ -40,7 +40,7 @@ static pid_t spawn(void) */ int test__intel_cqm_count_nmi_context(struct test *test __maybe_unused, int subtest __maybe_unused) { - struct perf_evlist *evlist = NULL; + struct evlist *evlist = NULL; struct evsel *evsel = NULL; struct perf_event_attr pe; int i, fd[2], flag, ret; diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index 43fc7d426d93..d7092fc00e3b 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -51,7 +51,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe }; struct perf_thread_map *threads = NULL; struct perf_cpu_map *cpus = NULL; - struct perf_evlist *evlist = NULL; + struct evlist *evlist = NULL; struct evsel *evsel = NULL; int err = -1, ret, i; const char *comm1, *comm2; diff --git a/tools/perf/arch/x86/util/auxtrace.c b/tools/perf/arch/x86/util/auxtrace.c index 02f192114448..6b3ad5c826fd 100644 --- a/tools/perf/arch/x86/util/auxtrace.c +++ b/tools/perf/arch/x86/util/auxtrace.c @@ -16,7 +16,7 @@ #include "../../util/evlist.h" static -struct auxtrace_record *auxtrace_record__init_intel(struct perf_evlist *evlist, +struct auxtrace_record *auxtrace_record__init_intel(struct evlist *evlist, int *err) { struct perf_pmu *intel_pt_pmu; @@ -50,7 +50,7 @@ struct auxtrace_record *auxtrace_record__init_intel(struct perf_evlist *evlist, return NULL; } -struct auxtrace_record *auxtrace_record__init(struct perf_evlist *evlist, +struct auxtrace_record *auxtrace_record__init(struct evlist *evlist, int *err) { char buffer[64]; diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index 59685a19c3b9..c845531d383a 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -35,7 +35,7 @@ struct intel_bts_snapshot_ref { struct intel_bts_recording { struct auxtrace_record itr; struct perf_pmu *intel_bts_pmu; - struct perf_evlist *evlist; + struct evlist *evlist; bool snapshot_mode; size_t snapshot_size; int snapshot_ref_cnt; @@ -50,7 +50,7 @@ struct branch { static size_t intel_bts_info_priv_size(struct auxtrace_record *itr __maybe_unused, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { return INTEL_BTS_AUXTRACE_PRIV_SIZE; } @@ -99,7 +99,7 @@ static int intel_bts_info_fill(struct auxtrace_record *itr, } static int intel_bts_recording_options(struct auxtrace_record *itr, - struct perf_evlist *evlist, + struct evlist *evlist, struct record_opts *opts) { struct intel_bts_recording *btsr = diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index b42df73fd7ff..e4dfe8c3d5c3 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -44,7 +44,7 @@ struct intel_pt_recording { struct auxtrace_record itr; struct perf_pmu *intel_pt_pmu; int have_sched_switch; - struct perf_evlist *evlist; + struct evlist *evlist; bool snapshot_mode; bool snapshot_init_done; size_t snapshot_size; @@ -110,7 +110,7 @@ static u64 intel_pt_masked_bits(u64 mask, u64 bits) } static int intel_pt_read_config(struct perf_pmu *intel_pt_pmu, const char *str, - struct perf_evlist *evlist, u64 *res) + struct evlist *evlist, u64 *res) { struct evsel *evsel; u64 mask; @@ -132,7 +132,7 @@ static int intel_pt_read_config(struct perf_pmu *intel_pt_pmu, const char *str, } static size_t intel_pt_psb_period(struct perf_pmu *intel_pt_pmu, - struct perf_evlist *evlist) + struct evlist *evlist) { u64 val; int err, topa_multiple_entries; @@ -268,7 +268,7 @@ intel_pt_pmu_default_config(struct perf_pmu *intel_pt_pmu) return attr; } -static const char *intel_pt_find_filter(struct perf_evlist *evlist, +static const char *intel_pt_find_filter(struct evlist *evlist, struct perf_pmu *intel_pt_pmu) { struct evsel *evsel; @@ -289,7 +289,7 @@ static size_t intel_pt_filter_bytes(const char *filter) } static size_t -intel_pt_info_priv_size(struct auxtrace_record *itr, struct perf_evlist *evlist) +intel_pt_info_priv_size(struct auxtrace_record *itr, struct evlist *evlist) { struct intel_pt_recording *ptr = container_of(itr, struct intel_pt_recording, itr); @@ -398,7 +398,7 @@ static int intel_pt_info_fill(struct auxtrace_record *itr, return 0; } -static int intel_pt_track_switches(struct perf_evlist *evlist) +static int intel_pt_track_switches(struct evlist *evlist) { const char *sched_switch = "sched:sched_switch"; struct evsel *evsel; @@ -549,7 +549,7 @@ static int intel_pt_validate_config(struct perf_pmu *intel_pt_pmu, } static int intel_pt_recording_options(struct auxtrace_record *itr, - struct perf_evlist *evlist, + struct evlist *evlist, struct record_opts *opts) { struct intel_pt_recording *ptr = diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index d251a486f329..f0aae6e13a33 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -2236,7 +2236,7 @@ static void print_pareto(FILE *out) static void print_c2c_info(FILE *out, struct perf_session *session) { - struct perf_evlist *evlist = session->evlist; + struct evlist *evlist = session->evlist; struct evsel *evsel; bool first = true; @@ -2567,7 +2567,7 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset) return parse_callchain_report_opt(arg); } -static int setup_callchain(struct perf_evlist *evlist) +static int setup_callchain(struct evlist *evlist) { u64 sample_type = perf_evlist__combined_sample_type(evlist); enum perf_call_graph_mode mode = CALLCHAIN_NONE; diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index c3b4b8196e00..e91c0d798181 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -449,7 +449,7 @@ static struct perf_diff pdiff = { }; static struct evsel *evsel_match(struct evsel *evsel, - struct perf_evlist *evlist) + struct evlist *evlist) { struct evsel *e; @@ -461,7 +461,7 @@ static struct evsel *evsel_match(struct evsel *evsel, return NULL; } -static void perf_evlist__collapse_resort(struct perf_evlist *evlist) +static void perf_evlist__collapse_resort(struct evlist *evlist) { struct evsel *evsel; @@ -1009,7 +1009,7 @@ static void data__fprintf(void) static void data_process(void) { - struct perf_evlist *evlist_base = data__files[0].session->evlist; + struct evlist *evlist_base = data__files[0].session->evlist; struct evsel *evsel_base; bool first = true; @@ -1019,7 +1019,7 @@ static void data_process(void) int i; data__for_each_file_new(i, d) { - struct perf_evlist *evlist = d->session->evlist; + struct evlist *evlist = d->session->evlist; struct evsel *evsel; struct hists *hists; diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 3e81e0b6628f..1263987c291a 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -27,7 +27,7 @@ #define DEFAULT_TRACER "function_graph" struct perf_ftrace { - struct perf_evlist *evlist; + struct evlist *evlist; struct target target; const char *tracer; struct list_head filters; diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 646a1bf790fc..d2131fc863be 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -96,7 +96,7 @@ static int perf_event__repipe_op2_synth(struct perf_session *session, static int perf_event__repipe_attr(struct perf_tool *tool, union perf_event *event, - struct perf_evlist **pevlist) + struct evlist **pevlist) { struct perf_inject *inject = container_of(tool, struct perf_inject, tool); @@ -567,7 +567,7 @@ static int drop_sample(struct perf_tool *tool __maybe_unused, static void strip_init(struct perf_inject *inject) { - struct perf_evlist *evlist = inject->session->evlist; + struct evlist *evlist = inject->session->evlist; struct evsel *evsel; inject->tool.context_switch = perf_event__drop; @@ -590,7 +590,7 @@ static bool has_tracking(struct evsel *evsel) * their selected event to exist, except if there is only 1 selected event left * and it has a compatible sample type. */ -static bool ok_to_remove(struct perf_evlist *evlist, +static bool ok_to_remove(struct evlist *evlist, struct evsel *evsel_to_remove) { struct evsel *evsel; @@ -614,7 +614,7 @@ static bool ok_to_remove(struct perf_evlist *evlist, static void strip_fini(struct perf_inject *inject) { - struct perf_evlist *evlist = inject->session->evlist; + struct evlist *evlist = inject->session->evlist; struct evsel *evsel, *tmp; /* Remove non-synthesized evsels if possible */ diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index cf8f27d05296..963dddc5853d 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -743,7 +743,7 @@ static bool verify_vcpu(int vcpu) static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx, u64 *mmap_time) { - struct perf_evlist *evlist = kvm->evlist; + struct evlist *evlist = kvm->evlist; union perf_event *event; struct perf_mmap *md; u64 timestamp; @@ -1012,7 +1012,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm) { int err, rc = -1; struct evsel *pos; - struct perf_evlist *evlist = kvm->evlist; + struct evlist *evlist = kvm->evlist; char sbuf[STRERR_BUFSIZE]; perf_evlist__config(evlist, &kvm->opts, NULL); @@ -1283,9 +1283,9 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv) } #ifdef HAVE_TIMERFD_SUPPORT -static struct perf_evlist *kvm_live_event_list(void) +static struct evlist *kvm_live_event_list(void) { - struct perf_evlist *evlist; + struct evlist *evlist; char *tp, *name, *sys; int err = -1; const char * const *events_tp; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 7ba3a2c32e54..f08d1e6a1651 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -73,7 +73,7 @@ struct record { u64 bytes_written; struct perf_data data; struct auxtrace_record *itr; - struct perf_evlist *evlist; + struct evlist *evlist; struct perf_session *session; int realtime_prio; bool no_buildid; @@ -346,7 +346,7 @@ static void record__aio_set_pos(int trace_fd, off_t pos) static void record__aio_mmap_read_sync(struct record *rec) { int i; - struct perf_evlist *evlist = rec->evlist; + struct evlist *evlist = rec->evlist; struct perf_mmap *maps = evlist->mmap; if (!record__aio_enabled(rec)) @@ -672,7 +672,7 @@ static int record__auxtrace_init(struct record *rec __maybe_unused) #endif static int record__mmap_evlist(struct record *rec, - struct perf_evlist *evlist) + struct evlist *evlist) { struct record_opts *opts = &rec->opts; char msg[512]; @@ -714,7 +714,7 @@ static int record__open(struct record *rec) { char msg[BUFSIZ]; struct evsel *pos; - struct perf_evlist *evlist = rec->evlist; + struct evlist *evlist = rec->evlist; struct perf_session *session = rec->session; struct record_opts *opts = &rec->opts; int rc = 0; @@ -904,7 +904,7 @@ static size_t zstd_compress(struct perf_session *session, void *dst, size_t dst_ return compressed; } -static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evlist, +static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist, bool overwrite, bool synch) { u64 bytes_written = rec->bytes_written; @@ -1165,7 +1165,7 @@ perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused } static const struct perf_event_mmap_page * -perf_evlist__pick_pc(struct perf_evlist *evlist) +perf_evlist__pick_pc(struct evlist *evlist) { if (evlist) { if (evlist->mmap && evlist->mmap[0].base) @@ -1313,7 +1313,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) struct perf_data *data = &rec->data; struct perf_session *session; bool disabled = false, draining = false; - struct perf_evlist *sb_evlist = NULL; + struct evlist *sb_evlist = NULL; int fd; float ratio = 0; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 96a506f0d4c1..e258e988c55b 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -193,7 +193,7 @@ out: } static void setup_forced_leader(struct report *report, - struct perf_evlist *evlist) + struct evlist *evlist) { if (report->group_set) perf_evlist__force_leader(evlist); @@ -459,7 +459,7 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report return ret + fprintf(fp, "\n#\n"); } -static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, +static int perf_evlist__tty_browse_hists(struct evlist *evlist, struct report *rep, const char *help) { @@ -532,7 +532,7 @@ static void report__warn_kptr_restrict(const struct report *rep) static int report__gtk_browse_hists(struct report *rep, const char *help) { - int (*hist_browser)(struct perf_evlist *evlist, const char *help, + int (*hist_browser)(struct evlist *evlist, const char *help, struct hist_browser_timer *timer, float min_pcnt); hist_browser = dlsym(perf_gtk_handle, "perf_evlist__gtk_browse_hists"); @@ -549,7 +549,7 @@ static int report__browse_hists(struct report *rep) { int ret; struct perf_session *session = rep->session; - struct perf_evlist *evlist = session->evlist; + struct evlist *evlist = session->evlist; const char *help = perf_tip(system_path(TIPDIR)); if (help == NULL) { diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 55779f496d27..c02ecb295f23 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -2924,7 +2924,7 @@ static int perf_timehist__process_sample(struct perf_tool *tool, } static int timehist_check_attr(struct perf_sched *sched, - struct perf_evlist *evlist) + struct evlist *evlist) { struct evsel *evsel; struct evsel_runtime *er; @@ -2963,7 +2963,7 @@ static int perf_sched__timehist(struct perf_sched *sched) }; struct perf_session *session; - struct perf_evlist *evlist; + struct evlist *evlist; int err = -1; /* diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 4f9c8bb7620d..d741c0aa2750 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1636,7 +1636,7 @@ struct perf_script { int range_num; }; -static int perf_evlist__max_name_len(struct perf_evlist *evlist) +static int perf_evlist__max_name_len(struct evlist *evlist) { struct evsel *evsel; int max = 0; @@ -2018,10 +2018,10 @@ out_put: } static int process_attr(struct perf_tool *tool, union perf_event *event, - struct perf_evlist **pevlist) + struct evlist **pevlist) { struct perf_script *scr = container_of(tool, struct perf_script, tool); - struct perf_evlist *evlist; + struct evlist *evlist; struct evsel *evsel, *pos; int err; static struct evsel_script *es; @@ -2388,7 +2388,7 @@ static void sig_handler(int sig __maybe_unused) static void perf_script__fclose_per_event_dump(struct perf_script *script) { - struct perf_evlist *evlist = script->session->evlist; + struct evlist *evlist = script->session->evlist; struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { @@ -3256,7 +3256,7 @@ static int process_stat_config_event(struct perf_session *session __maybe_unused static int set_maps(struct perf_script *script) { - struct perf_evlist *evlist = script->session->evlist; + struct evlist *evlist = script->session->evlist; if (!script->cpus || !script->threads) return 0; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index e0ba97018ad7..4e61f8a1d22b 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -130,7 +130,7 @@ static const char *smi_cost_attrs = { "}" }; -static struct perf_evlist *evsel_list; +static struct evlist *evsel_list; static struct target target = { .uid = UINT_MAX, diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 2f22f313985e..c29fa1de854f 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -839,7 +839,7 @@ static u64 last_timestamp; static void perf_top__mmap_read_idx(struct perf_top *top, int idx) { struct record_opts *opts = &top->record_opts; - struct perf_evlist *evlist = top->evlist; + struct evlist *evlist = top->evlist; struct perf_mmap *md; union perf_event *event; @@ -874,7 +874,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx) static void perf_top__mmap_read(struct perf_top *top) { bool overwrite = top->record_opts.overwrite; - struct perf_evlist *evlist = top->evlist; + struct evlist *evlist = top->evlist; int i; if (overwrite) @@ -909,7 +909,7 @@ static void perf_top__mmap_read(struct perf_top *top) static int perf_top__overwrite_check(struct perf_top *top) { struct record_opts *opts = &top->record_opts; - struct perf_evlist *evlist = top->evlist; + struct evlist *evlist = top->evlist; struct perf_evsel_config_term *term; struct list_head *config_terms; struct evsel *evsel; @@ -955,7 +955,7 @@ static int perf_top_overwrite_fallback(struct perf_top *top, struct evsel *evsel) { struct record_opts *opts = &top->record_opts; - struct perf_evlist *evlist = top->evlist; + struct evlist *evlist = top->evlist; struct evsel *counter; if (!opts->overwrite) @@ -976,7 +976,7 @@ static int perf_top__start_counters(struct perf_top *top) { char msg[BUFSIZ]; struct evsel *counter; - struct perf_evlist *evlist = top->evlist; + struct evlist *evlist = top->evlist; struct record_opts *opts = &top->record_opts; if (perf_top__overwrite_check(top)) { @@ -1100,7 +1100,7 @@ static int deliver_event(struct ordered_events *qe, struct ordered_event *qevent) { struct perf_top *top = qe->data; - struct perf_evlist *evlist = top->evlist; + struct evlist *evlist = top->evlist; struct perf_session *session = top->session; union perf_event *event = qevent->event; struct perf_sample sample; @@ -1511,7 +1511,7 @@ int cmd_top(int argc, const char **argv) "Record namespaces events"), OPT_END() }; - struct perf_evlist *sb_evlist = NULL; + struct evlist *sb_evlist = NULL; const char * const top_usage[] = { "perf top []", NULL diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index fde7eff811f9..f7e7daac3cbe 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -96,7 +96,7 @@ struct trace { struct bpf_map *map; } dump; struct record_opts opts; - struct perf_evlist *evlist; + struct evlist *evlist; struct machine *host; struct thread *current; struct bpf_object *bpf_obj; @@ -1388,7 +1388,7 @@ static char *trace__machine__resolve_kernel_addr(void *vmachine, unsigned long l return machine__resolve_kernel_addr(vmachine, addrp, modp); } -static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist) +static int trace__symbols_init(struct trace *trace, struct evlist *evlist) { int err = symbol__init(NULL); @@ -2616,7 +2616,7 @@ static int trace__record(struct trace *trace, int argc, const char **argv) static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp); -static bool perf_evlist__add_vfs_getname(struct perf_evlist *evlist) +static bool perf_evlist__add_vfs_getname(struct evlist *evlist) { bool found = false; struct evsel *evsel, *tmp; @@ -2699,7 +2699,7 @@ static void trace__handle_event(struct trace *trace, union perf_event *event, st static int trace__add_syscall_newtp(struct trace *trace) { int ret = -1; - struct perf_evlist *evlist = trace->evlist; + struct evlist *evlist = trace->evlist; struct evsel *sys_enter, *sys_exit; sys_enter = perf_evsel__raw_syscall_newtp("sys_enter", trace__sys_enter); @@ -3192,7 +3192,7 @@ static int trace__set_filter_pids(struct trace *trace) static int __trace__deliver_event(struct trace *trace, union perf_event *event) { - struct perf_evlist *evlist = trace->evlist; + struct evlist *evlist = trace->evlist; struct perf_sample sample; int err; @@ -3250,7 +3250,7 @@ static int ordered_events__deliver_event(struct ordered_events *oe, static int trace__run(struct trace *trace, int argc, const char **argv) { - struct perf_evlist *evlist = trace->evlist; + struct evlist *evlist = trace->evlist; struct evsel *evsel, *pgfault_maj = NULL, *pgfault_min = NULL; int err = -1, i; unsigned long before; @@ -3843,7 +3843,7 @@ static int parse_pagefaults(const struct option *opt, const char *str, return 0; } -static void evlist__set_evsel_handler(struct perf_evlist *evlist, void *handler) +static void evlist__set_evsel_handler(struct evlist *evlist, void *handler) { struct evsel *evsel; @@ -3851,7 +3851,7 @@ static void evlist__set_evsel_handler(struct perf_evlist *evlist, void *handler) evsel->handler = handler; } -static int evlist__set_syscall_tp_fields(struct perf_evlist *evlist) +static int evlist__set_syscall_tp_fields(struct evlist *evlist) { struct evsel *evsel; diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 921af318507c..3f9c931069b0 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -25,7 +25,7 @@ static void testcase(void) } } -static int count_samples(struct perf_evlist *evlist, int *sample_count, +static int count_samples(struct evlist *evlist, int *sample_count, int *comm_count) { int i; @@ -55,7 +55,7 @@ static int count_samples(struct perf_evlist *evlist, int *sample_count, return TEST_OK; } -static int do_test(struct perf_evlist *evlist, int mmap_pages, +static int do_test(struct evlist *evlist, int mmap_pages, int *sample_count, int *comm_count) { int err; @@ -82,7 +82,7 @@ int test__backward_ring_buffer(struct test *test __maybe_unused, int subtest __m { int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0; char pid[16], sbuf[STRERR_BUFSIZE]; - struct perf_evlist *evlist; + struct evlist *evlist; struct evsel *evsel __maybe_unused; struct parse_events_error parse_error; struct record_opts opts = { diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index c9e4cdc4c9c8..95a15b51f95c 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -118,7 +118,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void), char pid[16]; char sbuf[STRERR_BUFSIZE]; - struct perf_evlist *evlist; + struct evlist *evlist; int i, ret = TEST_FAIL, err = 0, count = 0; struct parse_events_state parse_state; diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 062d23bba2df..168deb9c563e 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -362,7 +362,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, } static int process_sample_event(struct machine *machine, - struct perf_evlist *evlist, + struct evlist *evlist, union perf_event *event, struct state *state) { struct perf_sample sample; @@ -385,7 +385,7 @@ static int process_sample_event(struct machine *machine, return ret; } -static int process_event(struct machine *machine, struct perf_evlist *evlist, +static int process_event(struct machine *machine, struct evlist *evlist, union perf_event *event, struct state *state) { if (event->header.type == PERF_RECORD_SAMPLE) @@ -408,7 +408,7 @@ static int process_event(struct machine *machine, struct perf_evlist *evlist, return 0; } -static int process_events(struct machine *machine, struct perf_evlist *evlist, +static int process_events(struct machine *machine, struct evlist *evlist, struct state *state) { union perf_event *event; @@ -554,7 +554,7 @@ static int do_test_code_reading(bool try_kcore) }; struct perf_thread_map *threads = NULL; struct perf_cpu_map *cpus = NULL; - struct perf_evlist *evlist = NULL; + struct evlist *evlist = NULL; struct evsel *evsel = NULL; int err = -1, ret; pid_t pid; diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 45fe674233d7..c3545a6efcbc 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -12,7 +12,7 @@ #include "thread_map.h" #include "target.h" -static int attach__enable_on_exec(struct perf_evlist *evlist) +static int attach__enable_on_exec(struct evlist *evlist) { struct evsel *evsel = perf_evlist__last(evlist); struct target target = { @@ -48,13 +48,13 @@ static int attach__enable_on_exec(struct perf_evlist *evlist) return perf_evlist__start_workload(evlist) == 1 ? TEST_OK : TEST_FAIL; } -static int detach__enable_on_exec(struct perf_evlist *evlist) +static int detach__enable_on_exec(struct evlist *evlist) { waitpid(evlist->workload.pid, NULL, 0); return 0; } -static int attach__current_disabled(struct perf_evlist *evlist) +static int attach__current_disabled(struct evlist *evlist) { struct evsel *evsel = perf_evlist__last(evlist); struct perf_thread_map *threads; @@ -80,7 +80,7 @@ static int attach__current_disabled(struct perf_evlist *evlist) return perf_evsel__enable(evsel) == 0 ? TEST_OK : TEST_FAIL; } -static int attach__current_enabled(struct perf_evlist *evlist) +static int attach__current_enabled(struct evlist *evlist) { struct evsel *evsel = perf_evlist__last(evlist); struct perf_thread_map *threads; @@ -100,14 +100,14 @@ static int attach__current_enabled(struct perf_evlist *evlist) return err == 0 ? TEST_OK : TEST_FAIL; } -static int detach__disable(struct perf_evlist *evlist) +static int detach__disable(struct evlist *evlist) { struct evsel *evsel = perf_evlist__last(evlist); return perf_evsel__enable(evsel); } -static int attach__cpu_disabled(struct perf_evlist *evlist) +static int attach__cpu_disabled(struct evlist *evlist) { struct evsel *evsel = perf_evlist__last(evlist); struct perf_cpu_map *cpus; @@ -136,7 +136,7 @@ static int attach__cpu_disabled(struct perf_evlist *evlist) return perf_evsel__enable(evsel); } -static int attach__cpu_enabled(struct perf_evlist *evlist) +static int attach__cpu_enabled(struct evlist *evlist) { struct evsel *evsel = perf_evlist__last(evlist); struct perf_cpu_map *cpus; @@ -158,11 +158,11 @@ static int attach__cpu_enabled(struct perf_evlist *evlist) return err ? TEST_FAIL : TEST_OK; } -static int test_times(int (attach)(struct perf_evlist *), - int (detach)(struct perf_evlist *)) +static int test_times(int (attach)(struct evlist *), + int (detach)(struct evlist *)) { struct perf_counts_values count; - struct perf_evlist *evlist = NULL; + struct evlist *evlist = NULL; struct evsel *evsel; int err = -1, i; diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index 0e5a2e8195e4..eb0dd359762d 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -79,7 +79,7 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused, int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unused) { - struct perf_evlist *evlist; + struct evlist *evlist; struct evsel *evsel; struct event_name tmp; diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c index bb38489eda1e..6cc408b23026 100644 --- a/tools/perf/tests/evsel-roundtrip-name.c +++ b/tools/perf/tests/evsel-roundtrip-name.c @@ -12,7 +12,7 @@ static int perf_evsel__roundtrip_cache_name_test(void) char name[128]; int type, op, err = 0, ret = 0, i, idx; struct evsel *evsel; - struct perf_evlist *evlist = perf_evlist__new(); + struct evlist *evlist = perf_evlist__new(); if (evlist == NULL) return -ENOMEM; @@ -68,7 +68,7 @@ static int __perf_evsel__name_array_test(const char *names[], int nr_names) { int i, err; struct evsel *evsel; - struct perf_evlist *evlist = perf_evlist__new(); + struct evlist *evlist = perf_evlist__new(); if (evlist == NULL) return -ENOMEM; diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index b62bf7c3bea2..d7a6b97683d6 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -695,7 +695,7 @@ int test__hists_cumulate(struct test *test __maybe_unused, int subtest __maybe_u struct machines machines; struct machine *machine; struct evsel *evsel; - struct perf_evlist *evlist = perf_evlist__new(); + struct evlist *evlist = perf_evlist__new(); size_t i; test_fn_t testcases[] = { test1, diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index 3e679bb8da7f..9f0d6af839e9 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -47,7 +47,7 @@ static struct sample fake_samples[] = { { .pid = FAKE_PID_BASH, .ip = FAKE_IP_KERNEL_PAGE_FAULT, .socket = 3 }, }; -static int add_hist_entries(struct perf_evlist *evlist, +static int add_hist_entries(struct evlist *evlist, struct machine *machine) { struct evsel *evsel; @@ -109,7 +109,7 @@ int test__hists_filter(struct test *test __maybe_unused, int subtest __maybe_unu struct machines machines; struct machine *machine; struct evsel *evsel; - struct perf_evlist *evlist = perf_evlist__new(); + struct evlist *evlist = perf_evlist__new(); TEST_ASSERT_VAL("No memory", evlist); diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index 078ee9876980..6ab27dd3bf3f 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -62,7 +62,7 @@ static struct sample fake_samples[][5] = { }, }; -static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine) +static int add_hist_entries(struct evlist *evlist, struct machine *machine) { struct evsel *evsel; struct addr_location al; @@ -272,7 +272,7 @@ int test__hists_link(struct test *test __maybe_unused, int subtest __maybe_unuse struct machines machines; struct machine *machine = NULL; struct evsel *evsel, *first; - struct perf_evlist *evlist = perf_evlist__new(); + struct evlist *evlist = perf_evlist__new(); if (evlist == NULL) return -ENOMEM; diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index 5cd4b1baa9d1..cd36e51cdf3b 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -581,7 +581,7 @@ int test__hists_output(struct test *test __maybe_unused, int subtest __maybe_unu struct machines machines; struct machine *machine; struct evsel *evsel; - struct perf_evlist *evlist = perf_evlist__new(); + struct evlist *evlist = perf_evlist__new(); size_t i; test_fn_t testcases[] = { test1, diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 8ada3e63f1ba..e0779f2a340c 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -24,7 +24,7 @@ } \ } -static int find_comm(struct perf_evlist *evlist, const char *comm) +static int find_comm(struct evlist *evlist, const char *comm) { union perf_event *event; struct perf_mmap *md; @@ -67,7 +67,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un }; struct perf_thread_map *threads = NULL; struct perf_cpu_map *cpus = NULL; - struct perf_evlist *evlist = NULL; + struct evlist *evlist = NULL; struct evsel *evsel = NULL; int found, err = -1; const char *comm; diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 76ee42eb1355..749b580e9a92 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -29,7 +29,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse union perf_event *event; struct perf_thread_map *threads; struct perf_cpu_map *cpus; - struct perf_evlist *evlist; + struct evlist *evlist; cpu_set_t cpu_set; const char *syscall_names[] = { "getsid", "getppid", "getpgid", }; pid_t (*syscalls[])(void) = { (void *)getsid, getppid, (void*)getpgid }; diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index 2e467448e220..69bf0ec2fe5f 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -32,7 +32,7 @@ int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest }; const char *filename = "/etc/passwd"; int flags = O_RDONLY | O_DIRECTORY; - struct perf_evlist *evlist = perf_evlist__new(); + struct evlist *evlist = perf_evlist__new(); struct evsel *evsel; int err = -1, i, nr_events = 0, nr_polls = 0; char sbuf[STRERR_BUFSIZE]; diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index f55ab43d51bd..7409eed11b65 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -44,7 +44,7 @@ static bool kvm_s390_create_vm_valid(void) } #endif -static int test__checkevent_tracepoint(struct perf_evlist *evlist) +static int test__checkevent_tracepoint(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -57,7 +57,7 @@ static int test__checkevent_tracepoint(struct perf_evlist *evlist) return 0; } -static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist) +static int test__checkevent_tracepoint_multi(struct evlist *evlist) { struct evsel *evsel; @@ -75,7 +75,7 @@ static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist) return 0; } -static int test__checkevent_raw(struct perf_evlist *evlist) +static int test__checkevent_raw(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -85,7 +85,7 @@ static int test__checkevent_raw(struct perf_evlist *evlist) return 0; } -static int test__checkevent_numeric(struct perf_evlist *evlist) +static int test__checkevent_numeric(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -95,7 +95,7 @@ static int test__checkevent_numeric(struct perf_evlist *evlist) return 0; } -static int test__checkevent_symbolic_name(struct perf_evlist *evlist) +static int test__checkevent_symbolic_name(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -106,7 +106,7 @@ static int test__checkevent_symbolic_name(struct perf_evlist *evlist) return 0; } -static int test__checkevent_symbolic_name_config(struct perf_evlist *evlist) +static int test__checkevent_symbolic_name_config(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -127,7 +127,7 @@ static int test__checkevent_symbolic_name_config(struct perf_evlist *evlist) return 0; } -static int test__checkevent_symbolic_alias(struct perf_evlist *evlist) +static int test__checkevent_symbolic_alias(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -138,7 +138,7 @@ static int test__checkevent_symbolic_alias(struct perf_evlist *evlist) return 0; } -static int test__checkevent_genhw(struct perf_evlist *evlist) +static int test__checkevent_genhw(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -148,7 +148,7 @@ static int test__checkevent_genhw(struct perf_evlist *evlist) return 0; } -static int test__checkevent_breakpoint(struct perf_evlist *evlist) +static int test__checkevent_breakpoint(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -162,7 +162,7 @@ static int test__checkevent_breakpoint(struct perf_evlist *evlist) return 0; } -static int test__checkevent_breakpoint_x(struct perf_evlist *evlist) +static int test__checkevent_breakpoint_x(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -175,7 +175,7 @@ static int test__checkevent_breakpoint_x(struct perf_evlist *evlist) return 0; } -static int test__checkevent_breakpoint_r(struct perf_evlist *evlist) +static int test__checkevent_breakpoint_r(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -190,7 +190,7 @@ static int test__checkevent_breakpoint_r(struct perf_evlist *evlist) return 0; } -static int test__checkevent_breakpoint_w(struct perf_evlist *evlist) +static int test__checkevent_breakpoint_w(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -205,7 +205,7 @@ static int test__checkevent_breakpoint_w(struct perf_evlist *evlist) return 0; } -static int test__checkevent_breakpoint_rw(struct perf_evlist *evlist) +static int test__checkevent_breakpoint_rw(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -220,7 +220,7 @@ static int test__checkevent_breakpoint_rw(struct perf_evlist *evlist) return 0; } -static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist) +static int test__checkevent_tracepoint_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -233,7 +233,7 @@ static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist) } static int -test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist) +test__checkevent_tracepoint_multi_modifier(struct evlist *evlist) { struct evsel *evsel; @@ -251,7 +251,7 @@ test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist) return test__checkevent_tracepoint_multi(evlist); } -static int test__checkevent_raw_modifier(struct perf_evlist *evlist) +static int test__checkevent_raw_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -263,7 +263,7 @@ static int test__checkevent_raw_modifier(struct perf_evlist *evlist) return test__checkevent_raw(evlist); } -static int test__checkevent_numeric_modifier(struct perf_evlist *evlist) +static int test__checkevent_numeric_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -275,7 +275,7 @@ static int test__checkevent_numeric_modifier(struct perf_evlist *evlist) return test__checkevent_numeric(evlist); } -static int test__checkevent_symbolic_name_modifier(struct perf_evlist *evlist) +static int test__checkevent_symbolic_name_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -287,7 +287,7 @@ static int test__checkevent_symbolic_name_modifier(struct perf_evlist *evlist) return test__checkevent_symbolic_name(evlist); } -static int test__checkevent_exclude_host_modifier(struct perf_evlist *evlist) +static int test__checkevent_exclude_host_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -297,7 +297,7 @@ static int test__checkevent_exclude_host_modifier(struct perf_evlist *evlist) return test__checkevent_symbolic_name(evlist); } -static int test__checkevent_exclude_guest_modifier(struct perf_evlist *evlist) +static int test__checkevent_exclude_guest_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -307,7 +307,7 @@ static int test__checkevent_exclude_guest_modifier(struct perf_evlist *evlist) return test__checkevent_symbolic_name(evlist); } -static int test__checkevent_symbolic_alias_modifier(struct perf_evlist *evlist) +static int test__checkevent_symbolic_alias_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -319,7 +319,7 @@ static int test__checkevent_symbolic_alias_modifier(struct perf_evlist *evlist) return test__checkevent_symbolic_alias(evlist); } -static int test__checkevent_genhw_modifier(struct perf_evlist *evlist) +static int test__checkevent_genhw_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -331,7 +331,7 @@ static int test__checkevent_genhw_modifier(struct perf_evlist *evlist) return test__checkevent_genhw(evlist); } -static int test__checkevent_exclude_idle_modifier(struct perf_evlist *evlist) +static int test__checkevent_exclude_idle_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -346,7 +346,7 @@ static int test__checkevent_exclude_idle_modifier(struct perf_evlist *evlist) return test__checkevent_symbolic_name(evlist); } -static int test__checkevent_exclude_idle_modifier_1(struct perf_evlist *evlist) +static int test__checkevent_exclude_idle_modifier_1(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -361,7 +361,7 @@ static int test__checkevent_exclude_idle_modifier_1(struct perf_evlist *evlist) return test__checkevent_symbolic_name(evlist); } -static int test__checkevent_breakpoint_modifier(struct perf_evlist *evlist) +static int test__checkevent_breakpoint_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -376,7 +376,7 @@ static int test__checkevent_breakpoint_modifier(struct perf_evlist *evlist) return test__checkevent_breakpoint(evlist); } -static int test__checkevent_breakpoint_x_modifier(struct perf_evlist *evlist) +static int test__checkevent_breakpoint_x_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -390,7 +390,7 @@ static int test__checkevent_breakpoint_x_modifier(struct perf_evlist *evlist) return test__checkevent_breakpoint_x(evlist); } -static int test__checkevent_breakpoint_r_modifier(struct perf_evlist *evlist) +static int test__checkevent_breakpoint_r_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -404,7 +404,7 @@ static int test__checkevent_breakpoint_r_modifier(struct perf_evlist *evlist) return test__checkevent_breakpoint_r(evlist); } -static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist) +static int test__checkevent_breakpoint_w_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -418,7 +418,7 @@ static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist) return test__checkevent_breakpoint_w(evlist); } -static int test__checkevent_breakpoint_rw_modifier(struct perf_evlist *evlist) +static int test__checkevent_breakpoint_rw_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -432,7 +432,7 @@ static int test__checkevent_breakpoint_rw_modifier(struct perf_evlist *evlist) return test__checkevent_breakpoint_rw(evlist); } -static int test__checkevent_pmu(struct perf_evlist *evlist) +static int test__checkevent_pmu(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -451,7 +451,7 @@ static int test__checkevent_pmu(struct perf_evlist *evlist) return 0; } -static int test__checkevent_list(struct perf_evlist *evlist) +static int test__checkevent_list(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -490,7 +490,7 @@ static int test__checkevent_list(struct perf_evlist *evlist) return 0; } -static int test__checkevent_pmu_name(struct perf_evlist *evlist) +static int test__checkevent_pmu_name(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -511,7 +511,7 @@ static int test__checkevent_pmu_name(struct perf_evlist *evlist) return 0; } -static int test__checkevent_pmu_partial_time_callgraph(struct perf_evlist *evlist) +static int test__checkevent_pmu_partial_time_callgraph(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -544,7 +544,7 @@ static int test__checkevent_pmu_partial_time_callgraph(struct perf_evlist *evlis return 0; } -static int test__checkevent_pmu_events(struct perf_evlist *evlist) +static int test__checkevent_pmu_events(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -562,7 +562,7 @@ static int test__checkevent_pmu_events(struct perf_evlist *evlist) } -static int test__checkevent_pmu_events_mix(struct perf_evlist *evlist) +static int test__checkevent_pmu_events_mix(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -634,7 +634,7 @@ static int test__checkterms_simple(struct list_head *terms) return 0; } -static int test__group1(struct perf_evlist *evlist) +static int test__group1(struct evlist *evlist) { struct evsel *evsel, *leader; @@ -676,7 +676,7 @@ static int test__group1(struct perf_evlist *evlist) return 0; } -static int test__group2(struct perf_evlist *evlist) +static int test__group2(struct evlist *evlist) { struct evsel *evsel, *leader; @@ -731,7 +731,7 @@ static int test__group2(struct perf_evlist *evlist) return 0; } -static int test__group3(struct perf_evlist *evlist __maybe_unused) +static int test__group3(struct evlist *evlist __maybe_unused) { struct evsel *evsel, *leader; @@ -823,7 +823,7 @@ static int test__group3(struct perf_evlist *evlist __maybe_unused) return 0; } -static int test__group4(struct perf_evlist *evlist __maybe_unused) +static int test__group4(struct evlist *evlist __maybe_unused) { struct evsel *evsel, *leader; @@ -867,7 +867,7 @@ static int test__group4(struct perf_evlist *evlist __maybe_unused) return 0; } -static int test__group5(struct perf_evlist *evlist __maybe_unused) +static int test__group5(struct evlist *evlist __maybe_unused) { struct evsel *evsel, *leader; @@ -953,7 +953,7 @@ static int test__group5(struct perf_evlist *evlist __maybe_unused) return 0; } -static int test__group_gh1(struct perf_evlist *evlist) +static int test__group_gh1(struct evlist *evlist) { struct evsel *evsel, *leader; @@ -993,7 +993,7 @@ static int test__group_gh1(struct perf_evlist *evlist) return 0; } -static int test__group_gh2(struct perf_evlist *evlist) +static int test__group_gh2(struct evlist *evlist) { struct evsel *evsel, *leader; @@ -1033,7 +1033,7 @@ static int test__group_gh2(struct perf_evlist *evlist) return 0; } -static int test__group_gh3(struct perf_evlist *evlist) +static int test__group_gh3(struct evlist *evlist) { struct evsel *evsel, *leader; @@ -1073,7 +1073,7 @@ static int test__group_gh3(struct perf_evlist *evlist) return 0; } -static int test__group_gh4(struct perf_evlist *evlist) +static int test__group_gh4(struct evlist *evlist) { struct evsel *evsel, *leader; @@ -1113,7 +1113,7 @@ static int test__group_gh4(struct perf_evlist *evlist) return 0; } -static int test__leader_sample1(struct perf_evlist *evlist) +static int test__leader_sample1(struct evlist *evlist) { struct evsel *evsel, *leader; @@ -1166,7 +1166,7 @@ static int test__leader_sample1(struct perf_evlist *evlist) return 0; } -static int test__leader_sample2(struct perf_evlist *evlist __maybe_unused) +static int test__leader_sample2(struct evlist *evlist __maybe_unused) { struct evsel *evsel, *leader; @@ -1205,7 +1205,7 @@ static int test__leader_sample2(struct perf_evlist *evlist __maybe_unused) return 0; } -static int test__checkevent_pinned_modifier(struct perf_evlist *evlist) +static int test__checkevent_pinned_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -1218,7 +1218,7 @@ static int test__checkevent_pinned_modifier(struct perf_evlist *evlist) return test__checkevent_symbolic_name(evlist); } -static int test__pinned_group(struct perf_evlist *evlist) +static int test__pinned_group(struct evlist *evlist) { struct evsel *evsel, *leader; @@ -1249,7 +1249,7 @@ static int test__pinned_group(struct perf_evlist *evlist) return 0; } -static int test__checkevent_breakpoint_len(struct perf_evlist *evlist) +static int test__checkevent_breakpoint_len(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -1264,7 +1264,7 @@ static int test__checkevent_breakpoint_len(struct perf_evlist *evlist) return 0; } -static int test__checkevent_breakpoint_len_w(struct perf_evlist *evlist) +static int test__checkevent_breakpoint_len_w(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -1280,7 +1280,7 @@ static int test__checkevent_breakpoint_len_w(struct perf_evlist *evlist) } static int -test__checkevent_breakpoint_len_rw_modifier(struct perf_evlist *evlist) +test__checkevent_breakpoint_len_rw_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -1292,7 +1292,7 @@ test__checkevent_breakpoint_len_rw_modifier(struct perf_evlist *evlist) return test__checkevent_breakpoint_rw(evlist); } -static int test__checkevent_precise_max_modifier(struct perf_evlist *evlist) +static int test__checkevent_precise_max_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -1303,7 +1303,7 @@ static int test__checkevent_precise_max_modifier(struct perf_evlist *evlist) return 0; } -static int test__checkevent_config_symbol(struct perf_evlist *evlist) +static int test__checkevent_config_symbol(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -1311,7 +1311,7 @@ static int test__checkevent_config_symbol(struct perf_evlist *evlist) return 0; } -static int test__checkevent_config_raw(struct perf_evlist *evlist) +static int test__checkevent_config_raw(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -1319,7 +1319,7 @@ static int test__checkevent_config_raw(struct perf_evlist *evlist) return 0; } -static int test__checkevent_config_num(struct perf_evlist *evlist) +static int test__checkevent_config_num(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -1327,7 +1327,7 @@ static int test__checkevent_config_num(struct perf_evlist *evlist) return 0; } -static int test__checkevent_config_cache(struct perf_evlist *evlist) +static int test__checkevent_config_cache(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -1340,7 +1340,7 @@ static bool test__intel_pt_valid(void) return !!perf_pmu__find("intel_pt"); } -static int test__intel_pt(struct perf_evlist *evlist) +static int test__intel_pt(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -1348,7 +1348,7 @@ static int test__intel_pt(struct perf_evlist *evlist) return 0; } -static int test__checkevent_complex_name(struct perf_evlist *evlist) +static int test__checkevent_complex_name(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -1356,7 +1356,7 @@ static int test__checkevent_complex_name(struct perf_evlist *evlist) return 0; } -static int test__sym_event_slash(struct perf_evlist *evlist) +static int test__sym_event_slash(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -1366,7 +1366,7 @@ static int test__sym_event_slash(struct perf_evlist *evlist) return 0; } -static int test__sym_event_dc(struct perf_evlist *evlist) +static int test__sym_event_dc(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); @@ -1422,7 +1422,7 @@ static int count_tracepoints(void) return cnt; } -static int test__all_tracepoints(struct perf_evlist *evlist) +static int test__all_tracepoints(struct evlist *evlist) { TEST_ASSERT_VAL("wrong events count", count_tracepoints() == evlist->nr_entries); @@ -1435,7 +1435,7 @@ struct evlist_test { __u32 type; const int id; bool (*valid)(void); - int (*check)(struct perf_evlist *evlist); + int (*check)(struct evlist *evlist); }; static struct evlist_test test__events[] = { @@ -1769,7 +1769,7 @@ static struct terms_test test__terms[] = { static int test_event(struct evlist_test *e) { struct parse_events_error err = { .idx = 0, }; - struct perf_evlist *evlist; + struct evlist *evlist; int ret; if (e->valid && !e->valid()) { diff --git a/tools/perf/tests/parse-no-sample-id-all.c b/tools/perf/tests/parse-no-sample-id-all.c index 2196d1497c0c..fc0213246aaf 100644 --- a/tools/perf/tests/parse-no-sample-id-all.c +++ b/tools/perf/tests/parse-no-sample-id-all.c @@ -11,7 +11,7 @@ #include "util.h" #include "debug.h" -static int process_event(struct perf_evlist **pevlist, union perf_event *event) +static int process_event(struct evlist **pevlist, union perf_event *event) { struct perf_sample sample; @@ -39,7 +39,7 @@ static int process_event(struct perf_evlist **pevlist, union perf_event *event) static int process_events(union perf_event **events, size_t count) { - struct perf_evlist *evlist = NULL; + struct evlist *evlist = NULL; int err = 0; size_t i; diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 7e576c2db941..99b2d26881f9 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -50,7 +50,7 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus }; cpu_set_t cpu_mask; size_t cpu_mask_size = sizeof(cpu_mask); - struct perf_evlist *evlist = perf_evlist__new_dummy(); + struct evlist *evlist = perf_evlist__new_dummy(); struct evsel *evsel; struct perf_sample sample; const char *cmd = "sleep"; diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 620a99aad1e3..69b997eeb639 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -28,7 +28,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) char sbuf[STRERR_BUFSIZE]; union perf_event *event; struct evsel *evsel; - struct perf_evlist *evlist; + struct evlist *evlist; struct perf_event_attr attr = { .type = PERF_TYPE_SOFTWARE, .config = clock_id, diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index a946b9fa60dd..3e26ea36ec29 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -113,7 +113,7 @@ static int check_cpu(struct switch_tracking *switch_tracking, int cpu) return 0; } -static int process_sample_event(struct perf_evlist *evlist, +static int process_sample_event(struct evlist *evlist, union perf_event *event, struct switch_tracking *switch_tracking) { @@ -163,7 +163,7 @@ static int process_sample_event(struct perf_evlist *evlist, return 0; } -static int process_event(struct perf_evlist *evlist, union perf_event *event, +static int process_event(struct evlist *evlist, union perf_event *event, struct switch_tracking *switch_tracking) { if (event->header.type == PERF_RECORD_SAMPLE) @@ -203,7 +203,7 @@ struct event_node { u64 event_time; }; -static int add_event(struct perf_evlist *evlist, struct list_head *events, +static int add_event(struct evlist *evlist, struct list_head *events, union perf_event *event) { struct perf_sample sample; @@ -252,7 +252,7 @@ static int compar(const void *a, const void *b) return cmp; } -static int process_events(struct perf_evlist *evlist, +static int process_events(struct evlist *evlist, struct switch_tracking *switch_tracking) { union perf_event *event; @@ -329,7 +329,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ }; struct perf_thread_map *threads = NULL; struct perf_cpu_map *cpus = NULL; - struct perf_evlist *evlist = NULL; + struct evlist *evlist = NULL; struct evsel *evsel, *cpu_clocks_evsel, *cycles_evsel; struct evsel *switch_evsel, *tracking_evsel; const char *comm; diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index e6fb4b8d8bc2..5c2cdb0ccb96 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -38,7 +38,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused int err = -1; union perf_event *event; struct evsel *evsel; - struct perf_evlist *evlist; + struct evlist *evlist; struct target target = { .uid = UINT_MAX, .uses_mmap = true, diff --git a/tools/perf/tests/time-utils-test.c b/tools/perf/tests/time-utils-test.c index 4f53006233a1..fe57ca3b6e54 100644 --- a/tools/perf/tests/time-utils-test.c +++ b/tools/perf/tests/time-utils-test.c @@ -69,7 +69,7 @@ struct test_data { static bool test__perf_time__parse_for_ranges(struct test_data *d) { - struct perf_evlist evlist = { + struct evlist evlist = { .first_sample_time = d->first, .last_sample_time = d->last, }; diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 9bc818621eb6..b83258bece05 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -3262,7 +3262,7 @@ static int perf_evsel_menu__run(struct evsel_menu *menu, struct hist_browser_timer *hbt, bool warn_lost_event) { - struct perf_evlist *evlist = menu->b.priv; + struct evlist *evlist = menu->b.priv; struct evsel *pos; const char *title = "Available samples"; int delay_secs = hbt ? hbt->refresh : 0; @@ -3359,7 +3359,7 @@ static bool filter_group_entries(struct ui_browser *browser __maybe_unused, return false; } -static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, +static int __perf_evlist__tui_browse_hists(struct evlist *evlist, int nr_entries, const char *help, struct hist_browser_timer *hbt, float min_pcnt, @@ -3397,7 +3397,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, hbt, warn_lost_event); } -int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, +int perf_evlist__tui_browse_hists(struct evlist *evlist, const char *help, struct hist_browser_timer *hbt, float min_pcnt, struct perf_env *env, diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h index e2f5fbef3c9a..a9563932fa04 100644 --- a/tools/perf/ui/gtk/gtk.h +++ b/tools/perf/ui/gtk/gtk.h @@ -53,11 +53,11 @@ static inline GtkWidget *perf_gtk__setup_info_bar(void) #endif struct evsel; -struct perf_evlist; +struct evlist; struct hist_entry; struct hist_browser_timer; -int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help, +int perf_evlist__gtk_browse_hists(struct evlist *evlist, const char *help, struct hist_browser_timer *hbt, float min_pcnt); int hist_entry__gtk_annotate(struct hist_entry *he, diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index d5c9fe230632..1b181d8ea953 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c @@ -590,7 +590,7 @@ static void perf_gtk__show_hierarchy(GtkWidget *window, struct hists *hists, gtk_container_add(GTK_CONTAINER(window), view); } -int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, +int perf_evlist__gtk_browse_hists(struct evlist *evlist, const char *help, struct hist_browser_timer *hbt __maybe_unused, float min_pcnt) diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 214af526901b..8c7fb11edc60 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -795,7 +795,7 @@ static int add_hierarchy_fmt(struct hists *hists, struct perf_hpp_fmt *fmt) } int perf_hpp__setup_hists_formats(struct perf_hpp_list *list, - struct perf_evlist *evlist) + struct evlist *evlist) { struct evsel *evsel; struct perf_hpp_fmt *fmt; diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 98b151bc9a36..9ec2841ddec4 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -124,7 +124,7 @@ void auxtrace_mmap_params__init(struct auxtrace_mmap_params *mp, } void auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp, - struct perf_evlist *evlist, int idx, + struct evlist *evlist, int idx, bool per_cpu) { mp->idx = idx; @@ -503,7 +503,7 @@ void auxtrace_heap__pop(struct auxtrace_heap *heap) } size_t auxtrace_record__info_priv_size(struct auxtrace_record *itr, - struct perf_evlist *evlist) + struct evlist *evlist) { if (itr) return itr->info_priv_size(itr, evlist); @@ -556,7 +556,7 @@ int auxtrace_record__find_snapshot(struct auxtrace_record *itr, int idx, } int auxtrace_record__options(struct auxtrace_record *itr, - struct perf_evlist *evlist, + struct evlist *evlist, struct record_opts *opts) { if (itr) @@ -585,7 +585,7 @@ int auxtrace_parse_snapshot_options(struct auxtrace_record *itr, } struct auxtrace_record *__weak -auxtrace_record__init(struct perf_evlist *evlist __maybe_unused, int *err) +auxtrace_record__init(struct evlist *evlist __maybe_unused, int *err) { *err = 0; return NULL; @@ -2160,7 +2160,7 @@ static int perf_evsel__nr_addr_filter(struct evsel *evsel) return nr_addr_filters; } -int auxtrace_parse_filters(struct perf_evlist *evlist) +int auxtrace_parse_filters(struct evlist *evlist) { struct evsel *evsel; char *filter; diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index e9b4c5edf78b..17eb04a1da4d 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -23,7 +23,7 @@ union perf_event; struct perf_session; -struct perf_evlist; +struct evlist; struct perf_tool; struct perf_mmap; struct option; @@ -309,10 +309,10 @@ struct auxtrace_mmap_params { */ struct auxtrace_record { int (*recording_options)(struct auxtrace_record *itr, - struct perf_evlist *evlist, + struct evlist *evlist, struct record_opts *opts); size_t (*info_priv_size)(struct auxtrace_record *itr, - struct perf_evlist *evlist); + struct evlist *evlist); int (*info_fill)(struct auxtrace_record *itr, struct perf_session *session, struct auxtrace_info_event *auxtrace_info, @@ -432,7 +432,7 @@ void auxtrace_mmap_params__init(struct auxtrace_mmap_params *mp, unsigned int auxtrace_pages, bool auxtrace_overwrite); void auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp, - struct perf_evlist *evlist, int idx, + struct evlist *evlist, int idx, bool per_cpu); typedef int (*process_auxtrace_t)(struct perf_tool *tool, @@ -482,17 +482,17 @@ int auxtrace_cache__add(struct auxtrace_cache *c, u32 key, struct auxtrace_cache_entry *entry); void *auxtrace_cache__lookup(struct auxtrace_cache *c, u32 key); -struct auxtrace_record *auxtrace_record__init(struct perf_evlist *evlist, +struct auxtrace_record *auxtrace_record__init(struct evlist *evlist, int *err); int auxtrace_parse_snapshot_options(struct auxtrace_record *itr, struct record_opts *opts, const char *str); int auxtrace_record__options(struct auxtrace_record *itr, - struct perf_evlist *evlist, + struct evlist *evlist, struct record_opts *opts); size_t auxtrace_record__info_priv_size(struct auxtrace_record *itr, - struct perf_evlist *evlist); + struct evlist *evlist); int auxtrace_record__info_fill(struct auxtrace_record *itr, struct perf_session *session, struct auxtrace_info_event *auxtrace_info, @@ -540,7 +540,7 @@ void addr_filters__init(struct addr_filters *filts); void addr_filters__exit(struct addr_filters *filts); int addr_filters__parse_bare_filter(struct addr_filters *filts, const char *filter); -int auxtrace_parse_filters(struct perf_evlist *evlist); +int auxtrace_parse_filters(struct evlist *evlist); static inline int auxtrace__process_event(struct perf_session *session, union perf_event *event, @@ -613,7 +613,7 @@ void itrace_synth_opts__clear_time_range(struct itrace_synth_opts *opts) #else static inline struct auxtrace_record * -auxtrace_record__init(struct perf_evlist *evlist __maybe_unused, +auxtrace_record__init(struct evlist *evlist __maybe_unused, int *err) { *err = 0; @@ -636,7 +636,7 @@ perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr __maybe_unused, static inline int auxtrace_record__options(struct auxtrace_record *itr __maybe_unused, - struct perf_evlist *evlist __maybe_unused, + struct evlist *evlist __maybe_unused, struct record_opts *opts __maybe_unused) { return 0; @@ -733,7 +733,7 @@ void auxtrace_index__free(struct list_head *head __maybe_unused) } static inline -int auxtrace_parse_filters(struct perf_evlist *evlist __maybe_unused) +int auxtrace_parse_filters(struct evlist *evlist __maybe_unused) { return 0; } @@ -747,7 +747,7 @@ void auxtrace_mmap_params__init(struct auxtrace_mmap_params *mp, unsigned int auxtrace_pages, bool auxtrace_overwrite); void auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp, - struct perf_evlist *evlist, int idx, + struct evlist *evlist, int idx, bool per_cpu); #define ITRACE_HELP "" diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 2a4a0da35632..5a5dcc6d8f85 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -418,7 +418,7 @@ static int bpf_event__sb_cb(union perf_event *event, void *data) return 0; } -int bpf_event__add_sb_event(struct perf_evlist **evlist, +int bpf_event__add_sb_event(struct evlist **evlist, struct perf_env *env) { struct perf_event_attr attr = { diff --git a/tools/perf/util/bpf-event.h b/tools/perf/util/bpf-event.h index 04c33b3bfe28..26ab9239f986 100644 --- a/tools/perf/util/bpf-event.h +++ b/tools/perf/util/bpf-event.h @@ -37,7 +37,7 @@ int perf_event__synthesize_bpf_events(struct perf_session *session, perf_event__handler_t process, struct machine *machine, struct record_opts *opts); -int bpf_event__add_sb_event(struct perf_evlist **evlist, +int bpf_event__add_sb_event(struct evlist **evlist, struct perf_env *env); void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info, struct perf_env *env, @@ -58,7 +58,7 @@ static inline int perf_event__synthesize_bpf_events(struct perf_session *session return 0; } -static inline int bpf_event__add_sb_event(struct perf_evlist **evlist __maybe_unused, +static inline int bpf_event__add_sb_event(struct evlist **evlist __maybe_unused, struct perf_env *env __maybe_unused) { return 0; diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index 594ea279e25b..b0696726ab76 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -1043,7 +1043,7 @@ __bpf_map__config_value(struct bpf_map *map, static int bpf_map__config_value(struct bpf_map *map, struct parse_events_term *term, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { if (!term->err_val) { pr_debug("Config value not set\n"); @@ -1061,7 +1061,7 @@ bpf_map__config_value(struct bpf_map *map, static int __bpf_map__config_event(struct bpf_map *map, struct parse_events_term *term, - struct perf_evlist *evlist) + struct evlist *evlist) { struct evsel *evsel; const struct bpf_map_def *def; @@ -1103,7 +1103,7 @@ __bpf_map__config_event(struct bpf_map *map, static int bpf_map__config_event(struct bpf_map *map, struct parse_events_term *term, - struct perf_evlist *evlist) + struct evlist *evlist) { if (!term->err_val) { pr_debug("Config value not set\n"); @@ -1121,7 +1121,7 @@ bpf_map__config_event(struct bpf_map *map, struct bpf_obj_config__map_func { const char *config_opt; int (*config_func)(struct bpf_map *, struct parse_events_term *, - struct perf_evlist *); + struct evlist *); }; struct bpf_obj_config__map_func bpf_obj_config__map_funcs[] = { @@ -1169,7 +1169,7 @@ config_map_indices_range_check(struct parse_events_term *term, static int bpf__obj_config_map(struct bpf_object *obj, struct parse_events_term *term, - struct perf_evlist *evlist, + struct evlist *evlist, int *key_scan_pos) { /* key is "map:." */ @@ -1228,7 +1228,7 @@ out: int bpf__config_obj(struct bpf_object *obj, struct parse_events_term *term, - struct perf_evlist *evlist, + struct evlist *evlist, int *error_pos) { int key_scan_pos = 0; @@ -1523,7 +1523,7 @@ int bpf__apply_obj_config(void) (strcmp(name, \ bpf_map__name(pos)) == 0)) -struct evsel *bpf__setup_output_event(struct perf_evlist *evlist, const char *name) +struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name) { struct bpf_map_priv *tmpl_priv = NULL; struct bpf_object *obj, *tmp; @@ -1600,7 +1600,7 @@ struct evsel *bpf__setup_output_event(struct perf_evlist *evlist, const char *na return evsel; } -int bpf__setup_stdout(struct perf_evlist *evlist) +int bpf__setup_stdout(struct evlist *evlist) { struct evsel *evsel = bpf__setup_output_event(evlist, "__bpf_stdout__"); return PTR_ERR_OR_ZERO(evsel); @@ -1756,7 +1756,7 @@ int bpf__strerror_load(struct bpf_object *obj, int bpf__strerror_config_obj(struct bpf_object *obj __maybe_unused, struct parse_events_term *term __maybe_unused, - struct perf_evlist *evlist __maybe_unused, + struct evlist *evlist __maybe_unused, int *error_pos __maybe_unused, int err, char *buf, size_t size) { @@ -1780,7 +1780,7 @@ int bpf__strerror_apply_obj_config(int err, char *buf, size_t size) return 0; } -int bpf__strerror_setup_output_event(struct perf_evlist *evlist __maybe_unused, +int bpf__strerror_setup_output_event(struct evlist *evlist __maybe_unused, int err, char *buf, size_t size) { bpf__strerror_head(err, buf, size); diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h index e2048c978a24..25251d63164c 100644 --- a/tools/perf/util/bpf-loader.h +++ b/tools/perf/util/bpf-loader.h @@ -40,7 +40,7 @@ enum bpf_loader_errno { }; struct evsel; -struct perf_evlist; +struct evlist; struct bpf_object; struct parse_events_term; #define PERF_BPF_PROBE_GROUP "perf_bpf_probe" @@ -70,18 +70,18 @@ int bpf__foreach_event(struct bpf_object *obj, bpf_prog_iter_callback_t func, void *arg); int bpf__config_obj(struct bpf_object *obj, struct parse_events_term *term, - struct perf_evlist *evlist, int *error_pos); + struct evlist *evlist, int *error_pos); int bpf__strerror_config_obj(struct bpf_object *obj, struct parse_events_term *term, - struct perf_evlist *evlist, + struct evlist *evlist, int *error_pos, int err, char *buf, size_t size); int bpf__apply_obj_config(void); int bpf__strerror_apply_obj_config(int err, char *buf, size_t size); -int bpf__setup_stdout(struct perf_evlist *evlist); -struct evsel *bpf__setup_output_event(struct perf_evlist *evlist, const char *name); -int bpf__strerror_setup_output_event(struct perf_evlist *evlist, int err, char *buf, size_t size); +int bpf__setup_stdout(struct evlist *evlist); +struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name); +int bpf__strerror_setup_output_event(struct evlist *evlist, int err, char *buf, size_t size); #else #include #include @@ -119,7 +119,7 @@ bpf__foreach_event(struct bpf_object *obj __maybe_unused, static inline int bpf__config_obj(struct bpf_object *obj __maybe_unused, struct parse_events_term *term __maybe_unused, - struct perf_evlist *evlist __maybe_unused, + struct evlist *evlist __maybe_unused, int *error_pos __maybe_unused) { return 0; @@ -132,13 +132,13 @@ bpf__apply_obj_config(void) } static inline int -bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused) +bpf__setup_stdout(struct evlist *evlist __maybe_unused) { return 0; } static inline struct evsel * -bpf__setup_output_event(struct perf_evlist *evlist __maybe_unused, const char *name __maybe_unused) +bpf__setup_output_event(struct evlist *evlist __maybe_unused, const char *name __maybe_unused) { return NULL; } @@ -182,7 +182,7 @@ static inline int bpf__strerror_load(struct bpf_object *obj __maybe_unused, static inline int bpf__strerror_config_obj(struct bpf_object *obj __maybe_unused, struct parse_events_term *term __maybe_unused, - struct perf_evlist *evlist __maybe_unused, + struct evlist *evlist __maybe_unused, int *error_pos __maybe_unused, int err __maybe_unused, char *buf, size_t size) @@ -198,7 +198,7 @@ bpf__strerror_apply_obj_config(int err __maybe_unused, } static inline int -bpf__strerror_setup_output_event(struct perf_evlist *evlist __maybe_unused, +bpf__strerror_setup_output_event(struct evlist *evlist __maybe_unused, int err __maybe_unused, char *buf, size_t size) { return __bpf_strerror(buf, size); @@ -206,7 +206,7 @@ bpf__strerror_setup_output_event(struct perf_evlist *evlist __maybe_unused, #endif -static inline int bpf__strerror_setup_stdout(struct perf_evlist *evlist, int err, char *buf, size_t size) +static inline int bpf__strerror_setup_stdout(struct evlist *evlist, int err, char *buf, size_t size) { return bpf__strerror_setup_output_event(evlist, err, buf, size); } diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 4f5c326a9477..deb87ecd3671 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -90,7 +90,7 @@ static int open_cgroup(const char *name) return fd; } -static struct cgroup *evlist__find_cgroup(struct perf_evlist *evlist, const char *str) +static struct cgroup *evlist__find_cgroup(struct evlist *evlist, const char *str) { struct evsel *counter; /* @@ -130,14 +130,14 @@ out_err: return NULL; } -struct cgroup *evlist__findnew_cgroup(struct perf_evlist *evlist, const char *name) +struct cgroup *evlist__findnew_cgroup(struct evlist *evlist, const char *name) { struct cgroup *cgroup = evlist__find_cgroup(evlist, name); return cgroup ?: cgroup__new(name); } -static int add_cgroup(struct perf_evlist *evlist, const char *str) +static int add_cgroup(struct evlist *evlist, const char *str) { struct evsel *counter; struct cgroup *cgrp = evlist__findnew_cgroup(evlist, str); @@ -190,7 +190,7 @@ static void evsel__set_default_cgroup(struct evsel *evsel, struct cgroup *cgroup evsel->cgrp = cgroup__get(cgroup); } -void evlist__set_default_cgroup(struct perf_evlist *evlist, struct cgroup *cgroup) +void evlist__set_default_cgroup(struct evlist *evlist, struct cgroup *cgroup) { struct evsel *evsel; @@ -201,7 +201,7 @@ void evlist__set_default_cgroup(struct perf_evlist *evlist, struct cgroup *cgrou int parse_cgroups(const struct option *opt, const char *str, int unset __maybe_unused) { - struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; + struct evlist *evlist = *(struct evlist **)opt->value; struct evsel *counter; struct cgroup *cgrp = NULL; const char *p, *e, *eos = str + strlen(str); diff --git a/tools/perf/util/cgroup.h b/tools/perf/util/cgroup.h index f033a80c1b14..2ec11f01090d 100644 --- a/tools/perf/util/cgroup.h +++ b/tools/perf/util/cgroup.h @@ -18,11 +18,11 @@ extern int nr_cgroups; /* number of explicit cgroups defined */ struct cgroup *cgroup__get(struct cgroup *cgroup); void cgroup__put(struct cgroup *cgroup); -struct perf_evlist; +struct evlist; -struct cgroup *evlist__findnew_cgroup(struct perf_evlist *evlist, const char *name); +struct cgroup *evlist__findnew_cgroup(struct evlist *evlist, const char *name); -void evlist__set_default_cgroup(struct perf_evlist *evlist, struct cgroup *cgroup); +void evlist__set_default_cgroup(struct evlist *evlist, struct cgroup *cgroup); int parse_cgroups(const struct option *opt, const char *str, int unset); diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 5a9fcb60ec88..c1df366f4519 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -1222,7 +1222,7 @@ static int cs_etm__synth_event(struct perf_session *session, static int cs_etm__synth_events(struct cs_etm_auxtrace *etm, struct perf_session *session) { - struct perf_evlist *evlist = session->evlist; + struct evlist *evlist = session->evlist; struct evsel *evsel; struct perf_event_attr attr; bool found = false; @@ -2295,7 +2295,7 @@ static int cs_etm__process_auxtrace_event(struct perf_session *session, static bool cs_etm__is_timeless_decoding(struct cs_etm_auxtrace *etm) { struct evsel *evsel; - struct perf_evlist *evlist = etm->session->evlist; + struct evlist *evlist = etm->session->evlist; bool timeless_decoding = true; /* diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 042ee5b6f9f1..083101ae7b77 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -1201,7 +1201,7 @@ err: static int setup_events(struct ctf_writer *cw, struct perf_session *session) { - struct perf_evlist *evlist = session->evlist; + struct evlist *evlist = session->evlist; struct evsel *evsel; int ret; @@ -1308,7 +1308,7 @@ static int setup_non_sample_events(struct ctf_writer *cw, static void cleanup_events(struct perf_session *session) { - struct perf_evlist *evlist = session->evlist; + struct evlist *evlist = session->evlist; struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 7e6066cb525b..c234fa4ba92a 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -41,7 +41,7 @@ int sigqueue(pid_t pid, int sig, const union sigval value); #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) #define SID(e, x, y) xyarray__entry(e->sample_id, x, y) -void perf_evlist__init(struct perf_evlist *evlist, struct perf_cpu_map *cpus, +void perf_evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, struct perf_thread_map *threads) { int i; @@ -55,9 +55,9 @@ void perf_evlist__init(struct perf_evlist *evlist, struct perf_cpu_map *cpus, evlist->bkw_mmap_state = BKW_MMAP_NOTREADY; } -struct perf_evlist *perf_evlist__new(void) +struct evlist *perf_evlist__new(void) { - struct perf_evlist *evlist = zalloc(sizeof(*evlist)); + struct evlist *evlist = zalloc(sizeof(*evlist)); if (evlist != NULL) perf_evlist__init(evlist, NULL, NULL); @@ -65,9 +65,9 @@ struct perf_evlist *perf_evlist__new(void) return evlist; } -struct perf_evlist *perf_evlist__new_default(void) +struct evlist *perf_evlist__new_default(void) { - struct perf_evlist *evlist = perf_evlist__new(); + struct evlist *evlist = perf_evlist__new(); if (evlist && perf_evlist__add_default(evlist)) { perf_evlist__delete(evlist); @@ -77,9 +77,9 @@ struct perf_evlist *perf_evlist__new_default(void) return evlist; } -struct perf_evlist *perf_evlist__new_dummy(void) +struct evlist *perf_evlist__new_dummy(void) { - struct perf_evlist *evlist = perf_evlist__new(); + struct evlist *evlist = perf_evlist__new(); if (evlist && perf_evlist__add_dummy(evlist)) { perf_evlist__delete(evlist); @@ -96,7 +96,7 @@ struct perf_evlist *perf_evlist__new_dummy(void) * Events with compatible sample types all have the same id_pos * and is_pos. For convenience, put a copy on evlist. */ -void perf_evlist__set_id_pos(struct perf_evlist *evlist) +void perf_evlist__set_id_pos(struct evlist *evlist) { struct evsel *first = perf_evlist__first(evlist); @@ -104,7 +104,7 @@ void perf_evlist__set_id_pos(struct perf_evlist *evlist) evlist->is_pos = first->is_pos; } -static void perf_evlist__update_id_pos(struct perf_evlist *evlist) +static void perf_evlist__update_id_pos(struct evlist *evlist) { struct evsel *evsel; @@ -114,7 +114,7 @@ static void perf_evlist__update_id_pos(struct perf_evlist *evlist) perf_evlist__set_id_pos(evlist); } -static void perf_evlist__purge(struct perf_evlist *evlist) +static void perf_evlist__purge(struct evlist *evlist) { struct evsel *pos, *n; @@ -127,14 +127,14 @@ static void perf_evlist__purge(struct perf_evlist *evlist) evlist->nr_entries = 0; } -void perf_evlist__exit(struct perf_evlist *evlist) +void perf_evlist__exit(struct evlist *evlist) { zfree(&evlist->mmap); zfree(&evlist->overwrite_mmap); fdarray__exit(&evlist->pollfd); } -void perf_evlist__delete(struct perf_evlist *evlist) +void perf_evlist__delete(struct evlist *evlist) { if (evlist == NULL) return; @@ -150,7 +150,7 @@ void perf_evlist__delete(struct perf_evlist *evlist) free(evlist); } -static void __perf_evlist__propagate_maps(struct perf_evlist *evlist, +static void __perf_evlist__propagate_maps(struct evlist *evlist, struct evsel *evsel) { /* @@ -169,7 +169,7 @@ static void __perf_evlist__propagate_maps(struct perf_evlist *evlist, evsel->threads = thread_map__get(evlist->threads); } -static void perf_evlist__propagate_maps(struct perf_evlist *evlist) +static void perf_evlist__propagate_maps(struct evlist *evlist) { struct evsel *evsel; @@ -177,7 +177,7 @@ static void perf_evlist__propagate_maps(struct perf_evlist *evlist) __perf_evlist__propagate_maps(evlist, evsel); } -void perf_evlist__add(struct perf_evlist *evlist, struct evsel *entry) +void perf_evlist__add(struct evlist *evlist, struct evsel *entry) { entry->evlist = evlist; list_add_tail(&entry->node, &evlist->entries); @@ -190,14 +190,14 @@ void perf_evlist__add(struct perf_evlist *evlist, struct evsel *entry) __perf_evlist__propagate_maps(evlist, entry); } -void perf_evlist__remove(struct perf_evlist *evlist, struct evsel *evsel) +void perf_evlist__remove(struct evlist *evlist, struct evsel *evsel) { evsel->evlist = NULL; list_del_init(&evsel->node); evlist->nr_entries -= 1; } -void perf_evlist__splice_list_tail(struct perf_evlist *evlist, +void perf_evlist__splice_list_tail(struct evlist *evlist, struct list_head *list) { struct evsel *evsel, *temp; @@ -222,7 +222,7 @@ void __perf_evlist__set_leader(struct list_head *list) } } -void perf_evlist__set_leader(struct perf_evlist *evlist) +void perf_evlist__set_leader(struct evlist *evlist) { if (evlist->nr_entries) { evlist->nr_groups = evlist->nr_entries > 1 ? 1 : 0; @@ -230,7 +230,7 @@ void perf_evlist__set_leader(struct perf_evlist *evlist) } } -int __perf_evlist__add_default(struct perf_evlist *evlist, bool precise) +int __perf_evlist__add_default(struct evlist *evlist, bool precise) { struct evsel *evsel = perf_evsel__new_cycles(precise); @@ -241,7 +241,7 @@ int __perf_evlist__add_default(struct perf_evlist *evlist, bool precise) return 0; } -int perf_evlist__add_dummy(struct perf_evlist *evlist) +int perf_evlist__add_dummy(struct evlist *evlist) { struct perf_event_attr attr = { .type = PERF_TYPE_SOFTWARE, @@ -257,7 +257,7 @@ int perf_evlist__add_dummy(struct perf_evlist *evlist) return 0; } -static int perf_evlist__add_attrs(struct perf_evlist *evlist, +static int perf_evlist__add_attrs(struct evlist *evlist, struct perf_event_attr *attrs, size_t nr_attrs) { struct evsel *evsel, *n; @@ -281,7 +281,7 @@ out_delete_partial_list: return -1; } -int __perf_evlist__add_default_attrs(struct perf_evlist *evlist, +int __perf_evlist__add_default_attrs(struct evlist *evlist, struct perf_event_attr *attrs, size_t nr_attrs) { size_t i; @@ -293,7 +293,7 @@ int __perf_evlist__add_default_attrs(struct perf_evlist *evlist, } struct evsel * -perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id) +perf_evlist__find_tracepoint_by_id(struct evlist *evlist, int id) { struct evsel *evsel; @@ -307,7 +307,7 @@ perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id) } struct evsel * -perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist, +perf_evlist__find_tracepoint_by_name(struct evlist *evlist, const char *name) { struct evsel *evsel; @@ -321,7 +321,7 @@ perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist, return NULL; } -int perf_evlist__add_newtp(struct perf_evlist *evlist, +int perf_evlist__add_newtp(struct evlist *evlist, const char *sys, const char *name, void *handler) { struct evsel *evsel = perf_evsel__newtp(sys, name); @@ -334,7 +334,7 @@ int perf_evlist__add_newtp(struct perf_evlist *evlist, return 0; } -static int perf_evlist__nr_threads(struct perf_evlist *evlist, +static int perf_evlist__nr_threads(struct evlist *evlist, struct evsel *evsel) { if (evsel->system_wide) @@ -343,7 +343,7 @@ static int perf_evlist__nr_threads(struct perf_evlist *evlist, return thread_map__nr(evlist->threads); } -void perf_evlist__disable(struct perf_evlist *evlist) +void perf_evlist__disable(struct evlist *evlist) { struct evsel *pos; @@ -356,7 +356,7 @@ void perf_evlist__disable(struct perf_evlist *evlist) evlist->enabled = false; } -void perf_evlist__enable(struct perf_evlist *evlist) +void perf_evlist__enable(struct evlist *evlist) { struct evsel *pos; @@ -369,12 +369,12 @@ void perf_evlist__enable(struct perf_evlist *evlist) evlist->enabled = true; } -void perf_evlist__toggle_enable(struct perf_evlist *evlist) +void perf_evlist__toggle_enable(struct evlist *evlist) { (evlist->enabled ? perf_evlist__disable : perf_evlist__enable)(evlist); } -static int perf_evlist__enable_event_cpu(struct perf_evlist *evlist, +static int perf_evlist__enable_event_cpu(struct evlist *evlist, struct evsel *evsel, int cpu) { int thread; @@ -391,7 +391,7 @@ static int perf_evlist__enable_event_cpu(struct perf_evlist *evlist, return 0; } -static int perf_evlist__enable_event_thread(struct perf_evlist *evlist, +static int perf_evlist__enable_event_thread(struct evlist *evlist, struct evsel *evsel, int thread) { @@ -409,7 +409,7 @@ static int perf_evlist__enable_event_thread(struct perf_evlist *evlist, return 0; } -int perf_evlist__enable_event_idx(struct perf_evlist *evlist, +int perf_evlist__enable_event_idx(struct evlist *evlist, struct evsel *evsel, int idx) { bool per_cpu_mmaps = !cpu_map__empty(evlist->cpus); @@ -420,7 +420,7 @@ int perf_evlist__enable_event_idx(struct perf_evlist *evlist, return perf_evlist__enable_event_thread(evlist, evsel, idx); } -int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) +int perf_evlist__alloc_pollfd(struct evlist *evlist) { int nr_cpus = cpu_map__nr(evlist->cpus); int nr_threads = thread_map__nr(evlist->threads); @@ -441,7 +441,7 @@ int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) return 0; } -static int __perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, +static int __perf_evlist__add_pollfd(struct evlist *evlist, int fd, struct perf_mmap *map, short revent) { int pos = fdarray__add(&evlist->pollfd, fd, revent | POLLERR | POLLHUP); @@ -458,7 +458,7 @@ static int __perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, return pos; } -int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd) +int perf_evlist__add_pollfd(struct evlist *evlist, int fd) { return __perf_evlist__add_pollfd(evlist, fd, NULL, POLLIN); } @@ -472,18 +472,18 @@ static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd, perf_mmap__put(map); } -int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask) +int perf_evlist__filter_pollfd(struct evlist *evlist, short revents_and_mask) { return fdarray__filter(&evlist->pollfd, revents_and_mask, perf_evlist__munmap_filtered, NULL); } -int perf_evlist__poll(struct perf_evlist *evlist, int timeout) +int perf_evlist__poll(struct evlist *evlist, int timeout) { return fdarray__poll(&evlist->pollfd, timeout); } -static void perf_evlist__id_hash(struct perf_evlist *evlist, +static void perf_evlist__id_hash(struct evlist *evlist, struct evsel *evsel, int cpu, int thread, u64 id) { @@ -496,14 +496,14 @@ static void perf_evlist__id_hash(struct perf_evlist *evlist, hlist_add_head(&sid->node, &evlist->heads[hash]); } -void perf_evlist__id_add(struct perf_evlist *evlist, struct evsel *evsel, +void perf_evlist__id_add(struct evlist *evlist, struct evsel *evsel, int cpu, int thread, u64 id) { perf_evlist__id_hash(evlist, evsel, cpu, thread, id); evsel->id[evsel->ids++] = id; } -int perf_evlist__id_add_fd(struct perf_evlist *evlist, +int perf_evlist__id_add_fd(struct evlist *evlist, struct evsel *evsel, int cpu, int thread, int fd) { @@ -544,7 +544,7 @@ int perf_evlist__id_add_fd(struct perf_evlist *evlist, return 0; } -static void perf_evlist__set_sid_idx(struct perf_evlist *evlist, +static void perf_evlist__set_sid_idx(struct evlist *evlist, struct evsel *evsel, int idx, int cpu, int thread) { @@ -560,7 +560,7 @@ static void perf_evlist__set_sid_idx(struct perf_evlist *evlist, sid->tid = -1; } -struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id) +struct perf_sample_id *perf_evlist__id2sid(struct evlist *evlist, u64 id) { struct hlist_head *head; struct perf_sample_id *sid; @@ -576,7 +576,7 @@ struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id) return NULL; } -struct evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id) +struct evsel *perf_evlist__id2evsel(struct evlist *evlist, u64 id) { struct perf_sample_id *sid; @@ -593,7 +593,7 @@ struct evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id) return NULL; } -struct evsel *perf_evlist__id2evsel_strict(struct perf_evlist *evlist, +struct evsel *perf_evlist__id2evsel_strict(struct evlist *evlist, u64 id) { struct perf_sample_id *sid; @@ -608,7 +608,7 @@ struct evsel *perf_evlist__id2evsel_strict(struct perf_evlist *evlist, return NULL; } -static int perf_evlist__event2id(struct perf_evlist *evlist, +static int perf_evlist__event2id(struct evlist *evlist, union perf_event *event, u64 *id) { const u64 *array = event->sample.array; @@ -629,7 +629,7 @@ static int perf_evlist__event2id(struct perf_evlist *evlist, return 0; } -struct evsel *perf_evlist__event2evsel(struct perf_evlist *evlist, +struct evsel *perf_evlist__event2evsel(struct evlist *evlist, union perf_event *event) { struct evsel *first = perf_evlist__first(evlist); @@ -662,7 +662,7 @@ struct evsel *perf_evlist__event2evsel(struct perf_evlist *evlist, return NULL; } -static int perf_evlist__set_paused(struct perf_evlist *evlist, bool value) +static int perf_evlist__set_paused(struct evlist *evlist, bool value) { int i; @@ -682,17 +682,17 @@ static int perf_evlist__set_paused(struct perf_evlist *evlist, bool value) return 0; } -static int perf_evlist__pause(struct perf_evlist *evlist) +static int perf_evlist__pause(struct evlist *evlist) { return perf_evlist__set_paused(evlist, true); } -static int perf_evlist__resume(struct perf_evlist *evlist) +static int perf_evlist__resume(struct evlist *evlist) { return perf_evlist__set_paused(evlist, false); } -static void perf_evlist__munmap_nofree(struct perf_evlist *evlist) +static void perf_evlist__munmap_nofree(struct evlist *evlist) { int i; @@ -705,14 +705,14 @@ static void perf_evlist__munmap_nofree(struct perf_evlist *evlist) perf_mmap__munmap(&evlist->overwrite_mmap[i]); } -void perf_evlist__munmap(struct perf_evlist *evlist) +void perf_evlist__munmap(struct evlist *evlist) { perf_evlist__munmap_nofree(evlist); zfree(&evlist->mmap); zfree(&evlist->overwrite_mmap); } -static struct perf_mmap *perf_evlist__alloc_mmap(struct perf_evlist *evlist, +static struct perf_mmap *perf_evlist__alloc_mmap(struct evlist *evlist, bool overwrite) { int i; @@ -743,7 +743,7 @@ static struct perf_mmap *perf_evlist__alloc_mmap(struct perf_evlist *evlist, } static bool -perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused, +perf_evlist__should_poll(struct evlist *evlist __maybe_unused, struct evsel *evsel) { if (evsel->attr.write_backward) @@ -751,7 +751,7 @@ perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused, return true; } -static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, +static int perf_evlist__mmap_per_evsel(struct evlist *evlist, int idx, struct mmap_params *mp, int cpu_idx, int thread, int *_output, int *_output_overwrite) { @@ -829,7 +829,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, return 0; } -static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, +static int perf_evlist__mmap_per_cpu(struct evlist *evlist, struct mmap_params *mp) { int cpu, thread; @@ -858,7 +858,7 @@ out_unmap: return -1; } -static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, +static int perf_evlist__mmap_per_thread(struct evlist *evlist, struct mmap_params *mp) { int thread; @@ -1006,7 +1006,7 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, * * Return: %0 on success, negative error code otherwise. */ -int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, +int perf_evlist__mmap_ex(struct evlist *evlist, unsigned int pages, unsigned int auxtrace_pages, bool auxtrace_overwrite, int nr_cblocks, int affinity, int flush, int comp_level) @@ -1050,12 +1050,12 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, return perf_evlist__mmap_per_cpu(evlist, &mp); } -int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages) +int perf_evlist__mmap(struct evlist *evlist, unsigned int pages) { return perf_evlist__mmap_ex(evlist, pages, 0, false, 0, PERF_AFFINITY_SYS, 1, 0); } -int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) +int perf_evlist__create_maps(struct evlist *evlist, struct target *target) { bool all_threads = (target->per_thread && target->system_wide); struct perf_cpu_map *cpus; @@ -1104,7 +1104,7 @@ out_delete_threads: return -1; } -void perf_evlist__set_maps(struct perf_evlist *evlist, struct perf_cpu_map *cpus, +void perf_evlist__set_maps(struct evlist *evlist, struct perf_cpu_map *cpus, struct perf_thread_map *threads) { /* @@ -1127,7 +1127,7 @@ void perf_evlist__set_maps(struct perf_evlist *evlist, struct perf_cpu_map *cpus perf_evlist__propagate_maps(evlist); } -void __perf_evlist__set_sample_bit(struct perf_evlist *evlist, +void __perf_evlist__set_sample_bit(struct evlist *evlist, enum perf_event_sample_format bit) { struct evsel *evsel; @@ -1136,7 +1136,7 @@ void __perf_evlist__set_sample_bit(struct perf_evlist *evlist, __perf_evsel__set_sample_bit(evsel, bit); } -void __perf_evlist__reset_sample_bit(struct perf_evlist *evlist, +void __perf_evlist__reset_sample_bit(struct evlist *evlist, enum perf_event_sample_format bit) { struct evsel *evsel; @@ -1145,7 +1145,7 @@ void __perf_evlist__reset_sample_bit(struct perf_evlist *evlist, __perf_evsel__reset_sample_bit(evsel, bit); } -int perf_evlist__apply_filters(struct perf_evlist *evlist, struct evsel **err_evsel) +int perf_evlist__apply_filters(struct evlist *evlist, struct evsel **err_evsel) { struct evsel *evsel; int err = 0; @@ -1168,7 +1168,7 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist, struct evsel **err_ev return err; } -int perf_evlist__set_tp_filter(struct perf_evlist *evlist, const char *filter) +int perf_evlist__set_tp_filter(struct evlist *evlist, const char *filter) { struct evsel *evsel; int err = 0; @@ -1185,7 +1185,7 @@ int perf_evlist__set_tp_filter(struct perf_evlist *evlist, const char *filter) return err; } -int perf_evlist__set_tp_filter_pids(struct perf_evlist *evlist, size_t npids, pid_t *pids) +int perf_evlist__set_tp_filter_pids(struct evlist *evlist, size_t npids, pid_t *pids) { char *filter; int ret = -1; @@ -1212,12 +1212,12 @@ out_free: return ret; } -int perf_evlist__set_tp_filter_pid(struct perf_evlist *evlist, pid_t pid) +int perf_evlist__set_tp_filter_pid(struct evlist *evlist, pid_t pid) { return perf_evlist__set_tp_filter_pids(evlist, 1, &pid); } -bool perf_evlist__valid_sample_type(struct perf_evlist *evlist) +bool perf_evlist__valid_sample_type(struct evlist *evlist) { struct evsel *pos; @@ -1236,7 +1236,7 @@ bool perf_evlist__valid_sample_type(struct perf_evlist *evlist) return true; } -u64 __perf_evlist__combined_sample_type(struct perf_evlist *evlist) +u64 __perf_evlist__combined_sample_type(struct evlist *evlist) { struct evsel *evsel; @@ -1249,13 +1249,13 @@ u64 __perf_evlist__combined_sample_type(struct perf_evlist *evlist) return evlist->combined_sample_type; } -u64 perf_evlist__combined_sample_type(struct perf_evlist *evlist) +u64 perf_evlist__combined_sample_type(struct evlist *evlist) { evlist->combined_sample_type = 0; return __perf_evlist__combined_sample_type(evlist); } -u64 perf_evlist__combined_branch_type(struct perf_evlist *evlist) +u64 perf_evlist__combined_branch_type(struct evlist *evlist) { struct evsel *evsel; u64 branch_type = 0; @@ -1265,7 +1265,7 @@ u64 perf_evlist__combined_branch_type(struct perf_evlist *evlist) return branch_type; } -bool perf_evlist__valid_read_format(struct perf_evlist *evlist) +bool perf_evlist__valid_read_format(struct evlist *evlist) { struct evsel *first = perf_evlist__first(evlist), *pos = first; u64 read_format = first->attr.read_format; @@ -1285,13 +1285,13 @@ bool perf_evlist__valid_read_format(struct perf_evlist *evlist) return true; } -u64 perf_evlist__read_format(struct perf_evlist *evlist) +u64 perf_evlist__read_format(struct evlist *evlist) { struct evsel *first = perf_evlist__first(evlist); return first->attr.read_format; } -u16 perf_evlist__id_hdr_size(struct perf_evlist *evlist) +u16 perf_evlist__id_hdr_size(struct evlist *evlist) { struct evsel *first = perf_evlist__first(evlist); struct perf_sample *data; @@ -1324,7 +1324,7 @@ out: return size; } -bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist) +bool perf_evlist__valid_sample_id_all(struct evlist *evlist) { struct evsel *first = perf_evlist__first(evlist), *pos = first; @@ -1336,19 +1336,19 @@ bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist) return true; } -bool perf_evlist__sample_id_all(struct perf_evlist *evlist) +bool perf_evlist__sample_id_all(struct evlist *evlist) { struct evsel *first = perf_evlist__first(evlist); return first->attr.sample_id_all; } -void perf_evlist__set_selected(struct perf_evlist *evlist, +void perf_evlist__set_selected(struct evlist *evlist, struct evsel *evsel) { evlist->selected = evsel; } -void perf_evlist__close(struct perf_evlist *evlist) +void perf_evlist__close(struct evlist *evlist) { struct evsel *evsel; @@ -1356,7 +1356,7 @@ void perf_evlist__close(struct perf_evlist *evlist) perf_evsel__close(evsel); } -static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist) +static int perf_evlist__create_syswide_maps(struct evlist *evlist) { struct perf_cpu_map *cpus; struct perf_thread_map *threads; @@ -1387,7 +1387,7 @@ out_put: goto out; } -int perf_evlist__open(struct perf_evlist *evlist) +int perf_evlist__open(struct evlist *evlist) { struct evsel *evsel; int err; @@ -1417,7 +1417,7 @@ out_err: return err; } -int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *target, +int perf_evlist__prepare_workload(struct evlist *evlist, struct target *target, const char *argv[], bool pipe_output, void (*exec_error)(int signo, siginfo_t *info, void *ucontext)) { @@ -1531,7 +1531,7 @@ out_close_ready_pipe: return -1; } -int perf_evlist__start_workload(struct perf_evlist *evlist) +int perf_evlist__start_workload(struct evlist *evlist) { if (evlist->workload.cork_fd > 0) { char bf = 0; @@ -1550,7 +1550,7 @@ int perf_evlist__start_workload(struct perf_evlist *evlist) return 0; } -int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event, +int perf_evlist__parse_sample(struct evlist *evlist, union perf_event *event, struct perf_sample *sample) { struct evsel *evsel = perf_evlist__event2evsel(evlist, event); @@ -1560,7 +1560,7 @@ int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *even return perf_evsel__parse_sample(evsel, event, sample); } -int perf_evlist__parse_sample_timestamp(struct perf_evlist *evlist, +int perf_evlist__parse_sample_timestamp(struct evlist *evlist, union perf_event *event, u64 *timestamp) { @@ -1571,7 +1571,7 @@ int perf_evlist__parse_sample_timestamp(struct perf_evlist *evlist, return perf_evsel__parse_sample_timestamp(evsel, event, timestamp); } -size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp) +size_t perf_evlist__fprintf(struct evlist *evlist, FILE *fp) { struct evsel *evsel; size_t printed = 0; @@ -1584,7 +1584,7 @@ size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp) return printed + fprintf(fp, "\n"); } -int perf_evlist__strerror_open(struct perf_evlist *evlist, +int perf_evlist__strerror_open(struct evlist *evlist, int err, char *buf, size_t size) { int printed, value; @@ -1638,7 +1638,7 @@ out_default: return 0; } -int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size) +int perf_evlist__strerror_mmap(struct evlist *evlist, int err, char *buf, size_t size) { char sbuf[STRERR_BUFSIZE], *emsg = str_error_r(err, sbuf, sizeof(sbuf)); int pages_attempted = evlist->mmap_len / 1024, pages_max_per_user, printed = 0; @@ -1669,7 +1669,7 @@ int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, s return 0; } -void perf_evlist__to_front(struct perf_evlist *evlist, +void perf_evlist__to_front(struct evlist *evlist, struct evsel *move_evsel) { struct evsel *evsel, *n; @@ -1686,7 +1686,7 @@ void perf_evlist__to_front(struct perf_evlist *evlist, list_splice(&move, &evlist->entries); } -void perf_evlist__set_tracking_event(struct perf_evlist *evlist, +void perf_evlist__set_tracking_event(struct evlist *evlist, struct evsel *tracking_evsel) { struct evsel *evsel; @@ -1703,7 +1703,7 @@ void perf_evlist__set_tracking_event(struct perf_evlist *evlist, } struct evsel * -perf_evlist__find_evsel_by_str(struct perf_evlist *evlist, +perf_evlist__find_evsel_by_str(struct evlist *evlist, const char *str) { struct evsel *evsel; @@ -1718,7 +1718,7 @@ perf_evlist__find_evsel_by_str(struct perf_evlist *evlist, return NULL; } -void perf_evlist__toggle_bkw_mmap(struct perf_evlist *evlist, +void perf_evlist__toggle_bkw_mmap(struct evlist *evlist, enum bkw_mmap_state state) { enum bkw_mmap_state old_state = evlist->bkw_mmap_state; @@ -1776,7 +1776,7 @@ state_err: return; } -bool perf_evlist__exclude_kernel(struct perf_evlist *evlist) +bool perf_evlist__exclude_kernel(struct evlist *evlist) { struct evsel *evsel; @@ -1793,7 +1793,7 @@ bool perf_evlist__exclude_kernel(struct perf_evlist *evlist) * the group display. Set the artificial group and set the leader's * forced_leader flag to notify the display code. */ -void perf_evlist__force_leader(struct perf_evlist *evlist) +void perf_evlist__force_leader(struct evlist *evlist) { if (!evlist->nr_groups) { struct evsel *leader = perf_evlist__first(evlist); @@ -1803,7 +1803,7 @@ void perf_evlist__force_leader(struct perf_evlist *evlist) } } -struct evsel *perf_evlist__reset_weak_group(struct perf_evlist *evsel_list, +struct evsel *perf_evlist__reset_weak_group(struct evlist *evsel_list, struct evsel *evsel) { struct evsel *c2, *leader; @@ -1830,7 +1830,7 @@ struct evsel *perf_evlist__reset_weak_group(struct perf_evlist *evsel_list, return leader; } -int perf_evlist__add_sb_event(struct perf_evlist **evlist, +int perf_evlist__add_sb_event(struct evlist **evlist, struct perf_event_attr *attr, perf_evsel__sb_cb_t cb, void *data) @@ -1867,7 +1867,7 @@ out_err: static void *perf_evlist__poll_thread(void *arg) { - struct perf_evlist *evlist = arg; + struct evlist *evlist = arg; bool draining = false; int i, done = 0; @@ -1906,7 +1906,7 @@ static void *perf_evlist__poll_thread(void *arg) return NULL; } -int perf_evlist__start_sb_thread(struct perf_evlist *evlist, +int perf_evlist__start_sb_thread(struct evlist *evlist, struct target *target) { struct evsel *counter; @@ -1943,7 +1943,7 @@ out_delete_evlist: return -1; } -void perf_evlist__stop_sb_thread(struct perf_evlist *evlist) +void perf_evlist__stop_sb_thread(struct evlist *evlist) { if (!evlist) return; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 576d59a0d8cf..54f1c3e2b721 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -24,7 +24,7 @@ struct record_opts; #define PERF_EVLIST__HLIST_BITS 8 #define PERF_EVLIST__HLIST_SIZE (1 << PERF_EVLIST__HLIST_BITS) -struct perf_evlist { +struct evlist { struct list_head entries; struct hlist_head heads[PERF_EVLIST__HLIST_SIZE]; int nr_entries; @@ -49,7 +49,7 @@ struct perf_evlist { struct evsel *selected; struct events_stats stats; struct perf_env *env; - void (*trace_event_sample_raw)(struct perf_evlist *evlist, + void (*trace_event_sample_raw)(struct evlist *evlist, union perf_event *event, struct perf_sample *sample); u64 first_sample_time; @@ -65,46 +65,46 @@ struct evsel_str_handler { void *handler; }; -struct perf_evlist *perf_evlist__new(void); -struct perf_evlist *perf_evlist__new_default(void); -struct perf_evlist *perf_evlist__new_dummy(void); -void perf_evlist__init(struct perf_evlist *evlist, struct perf_cpu_map *cpus, +struct evlist *perf_evlist__new(void); +struct evlist *perf_evlist__new_default(void); +struct evlist *perf_evlist__new_dummy(void); +void perf_evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, struct perf_thread_map *threads); -void perf_evlist__exit(struct perf_evlist *evlist); -void perf_evlist__delete(struct perf_evlist *evlist); +void perf_evlist__exit(struct evlist *evlist); +void perf_evlist__delete(struct evlist *evlist); -void perf_evlist__add(struct perf_evlist *evlist, struct evsel *entry); -void perf_evlist__remove(struct perf_evlist *evlist, struct evsel *evsel); +void perf_evlist__add(struct evlist *evlist, struct evsel *entry); +void perf_evlist__remove(struct evlist *evlist, struct evsel *evsel); -int __perf_evlist__add_default(struct perf_evlist *evlist, bool precise); +int __perf_evlist__add_default(struct evlist *evlist, bool precise); -static inline int perf_evlist__add_default(struct perf_evlist *evlist) +static inline int perf_evlist__add_default(struct evlist *evlist) { return __perf_evlist__add_default(evlist, true); } -int __perf_evlist__add_default_attrs(struct perf_evlist *evlist, +int __perf_evlist__add_default_attrs(struct evlist *evlist, struct perf_event_attr *attrs, size_t nr_attrs); #define perf_evlist__add_default_attrs(evlist, array) \ __perf_evlist__add_default_attrs(evlist, array, ARRAY_SIZE(array)) -int perf_evlist__add_dummy(struct perf_evlist *evlist); +int perf_evlist__add_dummy(struct evlist *evlist); -int perf_evlist__add_sb_event(struct perf_evlist **evlist, +int perf_evlist__add_sb_event(struct evlist **evlist, struct perf_event_attr *attr, perf_evsel__sb_cb_t cb, void *data); -int perf_evlist__start_sb_thread(struct perf_evlist *evlist, +int perf_evlist__start_sb_thread(struct evlist *evlist, struct target *target); -void perf_evlist__stop_sb_thread(struct perf_evlist *evlist); +void perf_evlist__stop_sb_thread(struct evlist *evlist); -int perf_evlist__add_newtp(struct perf_evlist *evlist, +int perf_evlist__add_newtp(struct evlist *evlist, const char *sys, const char *name, void *handler); -void __perf_evlist__set_sample_bit(struct perf_evlist *evlist, +void __perf_evlist__set_sample_bit(struct evlist *evlist, enum perf_event_sample_format bit); -void __perf_evlist__reset_sample_bit(struct perf_evlist *evlist, +void __perf_evlist__reset_sample_bit(struct evlist *evlist, enum perf_event_sample_format bit); #define perf_evlist__set_sample_bit(evlist, bit) \ @@ -113,58 +113,58 @@ void __perf_evlist__reset_sample_bit(struct perf_evlist *evlist, #define perf_evlist__reset_sample_bit(evlist, bit) \ __perf_evlist__reset_sample_bit(evlist, PERF_SAMPLE_##bit) -int perf_evlist__set_tp_filter(struct perf_evlist *evlist, const char *filter); -int perf_evlist__set_tp_filter_pid(struct perf_evlist *evlist, pid_t pid); -int perf_evlist__set_tp_filter_pids(struct perf_evlist *evlist, size_t npids, pid_t *pids); +int perf_evlist__set_tp_filter(struct evlist *evlist, const char *filter); +int perf_evlist__set_tp_filter_pid(struct evlist *evlist, pid_t pid); +int perf_evlist__set_tp_filter_pids(struct evlist *evlist, size_t npids, pid_t *pids); struct evsel * -perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id); +perf_evlist__find_tracepoint_by_id(struct evlist *evlist, int id); struct evsel * -perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist, +perf_evlist__find_tracepoint_by_name(struct evlist *evlist, const char *name); -void perf_evlist__id_add(struct perf_evlist *evlist, struct evsel *evsel, +void perf_evlist__id_add(struct evlist *evlist, struct evsel *evsel, int cpu, int thread, u64 id); -int perf_evlist__id_add_fd(struct perf_evlist *evlist, +int perf_evlist__id_add_fd(struct evlist *evlist, struct evsel *evsel, int cpu, int thread, int fd); -int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd); -int perf_evlist__alloc_pollfd(struct perf_evlist *evlist); -int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask); +int perf_evlist__add_pollfd(struct evlist *evlist, int fd); +int perf_evlist__alloc_pollfd(struct evlist *evlist); +int perf_evlist__filter_pollfd(struct evlist *evlist, short revents_and_mask); -int perf_evlist__poll(struct perf_evlist *evlist, int timeout); +int perf_evlist__poll(struct evlist *evlist, int timeout); -struct evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id); -struct evsel *perf_evlist__id2evsel_strict(struct perf_evlist *evlist, +struct evsel *perf_evlist__id2evsel(struct evlist *evlist, u64 id); +struct evsel *perf_evlist__id2evsel_strict(struct evlist *evlist, u64 id); -struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id); +struct perf_sample_id *perf_evlist__id2sid(struct evlist *evlist, u64 id); -void perf_evlist__toggle_bkw_mmap(struct perf_evlist *evlist, enum bkw_mmap_state state); +void perf_evlist__toggle_bkw_mmap(struct evlist *evlist, enum bkw_mmap_state state); -void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx); +void perf_evlist__mmap_consume(struct evlist *evlist, int idx); -int perf_evlist__open(struct perf_evlist *evlist); -void perf_evlist__close(struct perf_evlist *evlist); +int perf_evlist__open(struct evlist *evlist); +void perf_evlist__close(struct evlist *evlist); struct callchain_param; -void perf_evlist__set_id_pos(struct perf_evlist *evlist); +void perf_evlist__set_id_pos(struct evlist *evlist); bool perf_can_sample_identifier(void); bool perf_can_record_switch_events(void); bool perf_can_record_cpu_wide(void); -void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, +void perf_evlist__config(struct evlist *evlist, struct record_opts *opts, struct callchain_param *callchain); int record_opts__config(struct record_opts *opts); -int perf_evlist__prepare_workload(struct perf_evlist *evlist, +int perf_evlist__prepare_workload(struct evlist *evlist, struct target *target, const char *argv[], bool pipe_output, void (*exec_error)(int signo, siginfo_t *info, void *ucontext)); -int perf_evlist__start_workload(struct perf_evlist *evlist); +int perf_evlist__start_workload(struct evlist *evlist); struct option; @@ -175,76 +175,76 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, unsigned long perf_event_mlock_kb_in_pages(void); -int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages, +int perf_evlist__mmap_ex(struct evlist *evlist, unsigned int pages, unsigned int auxtrace_pages, bool auxtrace_overwrite, int nr_cblocks, int affinity, int flush, int comp_level); -int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages); -void perf_evlist__munmap(struct perf_evlist *evlist); +int perf_evlist__mmap(struct evlist *evlist, unsigned int pages); +void perf_evlist__munmap(struct evlist *evlist); size_t perf_evlist__mmap_size(unsigned long pages); -void perf_evlist__disable(struct perf_evlist *evlist); -void perf_evlist__enable(struct perf_evlist *evlist); -void perf_evlist__toggle_enable(struct perf_evlist *evlist); +void perf_evlist__disable(struct evlist *evlist); +void perf_evlist__enable(struct evlist *evlist); +void perf_evlist__toggle_enable(struct evlist *evlist); -int perf_evlist__enable_event_idx(struct perf_evlist *evlist, +int perf_evlist__enable_event_idx(struct evlist *evlist, struct evsel *evsel, int idx); -void perf_evlist__set_selected(struct perf_evlist *evlist, +void perf_evlist__set_selected(struct evlist *evlist, struct evsel *evsel); -void perf_evlist__set_maps(struct perf_evlist *evlist, struct perf_cpu_map *cpus, +void perf_evlist__set_maps(struct evlist *evlist, struct perf_cpu_map *cpus, struct perf_thread_map *threads); -int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target); -int perf_evlist__apply_filters(struct perf_evlist *evlist, struct evsel **err_evsel); +int perf_evlist__create_maps(struct evlist *evlist, struct target *target); +int perf_evlist__apply_filters(struct evlist *evlist, struct evsel **err_evsel); void __perf_evlist__set_leader(struct list_head *list); -void perf_evlist__set_leader(struct perf_evlist *evlist); +void perf_evlist__set_leader(struct evlist *evlist); -u64 perf_evlist__read_format(struct perf_evlist *evlist); -u64 __perf_evlist__combined_sample_type(struct perf_evlist *evlist); -u64 perf_evlist__combined_sample_type(struct perf_evlist *evlist); -u64 perf_evlist__combined_branch_type(struct perf_evlist *evlist); -bool perf_evlist__sample_id_all(struct perf_evlist *evlist); -u16 perf_evlist__id_hdr_size(struct perf_evlist *evlist); +u64 perf_evlist__read_format(struct evlist *evlist); +u64 __perf_evlist__combined_sample_type(struct evlist *evlist); +u64 perf_evlist__combined_sample_type(struct evlist *evlist); +u64 perf_evlist__combined_branch_type(struct evlist *evlist); +bool perf_evlist__sample_id_all(struct evlist *evlist); +u16 perf_evlist__id_hdr_size(struct evlist *evlist); -int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event, +int perf_evlist__parse_sample(struct evlist *evlist, union perf_event *event, struct perf_sample *sample); -int perf_evlist__parse_sample_timestamp(struct perf_evlist *evlist, +int perf_evlist__parse_sample_timestamp(struct evlist *evlist, union perf_event *event, u64 *timestamp); -bool perf_evlist__valid_sample_type(struct perf_evlist *evlist); -bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist); -bool perf_evlist__valid_read_format(struct perf_evlist *evlist); +bool perf_evlist__valid_sample_type(struct evlist *evlist); +bool perf_evlist__valid_sample_id_all(struct evlist *evlist); +bool perf_evlist__valid_read_format(struct evlist *evlist); -void perf_evlist__splice_list_tail(struct perf_evlist *evlist, +void perf_evlist__splice_list_tail(struct evlist *evlist, struct list_head *list); -static inline bool perf_evlist__empty(struct perf_evlist *evlist) +static inline bool perf_evlist__empty(struct evlist *evlist) { return list_empty(&evlist->entries); } -static inline struct evsel *perf_evlist__first(struct perf_evlist *evlist) +static inline struct evsel *perf_evlist__first(struct evlist *evlist) { return list_entry(evlist->entries.next, struct evsel, node); } -static inline struct evsel *perf_evlist__last(struct perf_evlist *evlist) +static inline struct evsel *perf_evlist__last(struct evlist *evlist) { return list_entry(evlist->entries.prev, struct evsel, node); } -size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp); +size_t perf_evlist__fprintf(struct evlist *evlist, FILE *fp); -int perf_evlist__strerror_open(struct perf_evlist *evlist, int err, char *buf, size_t size); -int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size); +int perf_evlist__strerror_open(struct evlist *evlist, int err, char *buf, size_t size); +int perf_evlist__strerror_mmap(struct evlist *evlist, int err, char *buf, size_t size); -bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str); -void perf_evlist__to_front(struct perf_evlist *evlist, +bool perf_evlist__can_select_event(struct evlist *evlist, const char *str); +void perf_evlist__to_front(struct evlist *evlist, struct evsel *move_evsel); /** @@ -313,19 +313,19 @@ void perf_evlist__to_front(struct perf_evlist *evlist, #define evlist__for_each_entry_safe(evlist, tmp, evsel) \ __evlist__for_each_entry_safe(&(evlist)->entries, tmp, evsel) -void perf_evlist__set_tracking_event(struct perf_evlist *evlist, +void perf_evlist__set_tracking_event(struct evlist *evlist, struct evsel *tracking_evsel); struct evsel * -perf_evlist__find_evsel_by_str(struct perf_evlist *evlist, const char *str); +perf_evlist__find_evsel_by_str(struct evlist *evlist, const char *str); -struct evsel *perf_evlist__event2evsel(struct perf_evlist *evlist, +struct evsel *perf_evlist__event2evsel(struct evlist *evlist, union perf_event *event); -bool perf_evlist__exclude_kernel(struct perf_evlist *evlist); +bool perf_evlist__exclude_kernel(struct evlist *evlist); -void perf_evlist__force_leader(struct perf_evlist *evlist); +void perf_evlist__force_leader(struct evlist *evlist); -struct evsel *perf_evlist__reset_weak_group(struct perf_evlist *evlist, +struct evsel *perf_evlist__reset_weak_group(struct evlist *evlist, struct evsel *evsel); #endif /* __PERF_EVLIST_H */ diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 44421bbebd64..f7f97ca6e96d 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -3044,7 +3044,7 @@ struct perf_env *perf_evsel__env(struct evsel *evsel) return NULL; } -static int store_evsel_ids(struct evsel *evsel, struct perf_evlist *evlist) +static int store_evsel_ids(struct evsel *evsel, struct evlist *evlist) { int cpu, thread; @@ -3062,7 +3062,7 @@ static int store_evsel_ids(struct evsel *evsel, struct perf_evlist *evlist) return 0; } -int perf_evsel__store_ids(struct evsel *evsel, struct perf_evlist *evlist) +int perf_evsel__store_ids(struct evsel *evsel, struct evlist *evlist) { struct perf_cpu_map *cpus = evsel->cpus; struct perf_thread_map *threads = evsel->threads; diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 2c31c5e99524..3caabd8a4aa6 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -102,7 +102,7 @@ struct bpf_object; */ struct evsel { struct list_head node; - struct perf_evlist *evlist; + struct evlist *evlist; struct perf_event_attr attr; char *filter; struct xyarray *fd; @@ -506,5 +506,5 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr, struct perf_env *perf_evsel__env(struct evsel *evsel); -int perf_evsel__store_ids(struct evsel *evsel, struct perf_evlist *evlist); +int perf_evsel__store_ids(struct evsel *evsel, struct evlist *evlist); #endif /* __PERF_EVSEL_H */ diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 132bbc29f977..692fe8ac12ae 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -299,7 +299,7 @@ static int do_read_bitmap(struct feat_fd *ff, unsigned long **pset, u64 *psize) } static int write_tracing_data(struct feat_fd *ff, - struct perf_evlist *evlist) + struct evlist *evlist) { if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__)) return -1; @@ -308,7 +308,7 @@ static int write_tracing_data(struct feat_fd *ff, } static int write_build_id(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { struct perf_session *session; int err; @@ -332,7 +332,7 @@ static int write_build_id(struct feat_fd *ff, } static int write_hostname(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { struct utsname uts; int ret; @@ -345,7 +345,7 @@ static int write_hostname(struct feat_fd *ff, } static int write_osrelease(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { struct utsname uts; int ret; @@ -358,7 +358,7 @@ static int write_osrelease(struct feat_fd *ff, } static int write_arch(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { struct utsname uts; int ret; @@ -371,7 +371,7 @@ static int write_arch(struct feat_fd *ff, } static int write_version(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { return do_write_string(ff, perf_version_string); } @@ -432,7 +432,7 @@ done: } static int write_cpudesc(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { const char *cpuinfo_procs[] = CPUINFO_PROC; unsigned int i; @@ -448,7 +448,7 @@ static int write_cpudesc(struct feat_fd *ff, static int write_nrcpus(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { long nr; u32 nrc, nra; @@ -470,7 +470,7 @@ static int write_nrcpus(struct feat_fd *ff, } static int write_event_desc(struct feat_fd *ff, - struct perf_evlist *evlist) + struct evlist *evlist) { struct evsel *evsel; u32 nre, nri, sz; @@ -526,7 +526,7 @@ static int write_event_desc(struct feat_fd *ff, } static int write_cmdline(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { char pbuf[MAXPATHLEN], *buf; int i, ret, n; @@ -555,7 +555,7 @@ static int write_cmdline(struct feat_fd *ff, static int write_cpu_topology(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { struct cpu_topology *tp; u32 i; @@ -627,7 +627,7 @@ done: static int write_total_mem(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { char *buf = NULL; FILE *fp; @@ -656,7 +656,7 @@ static int write_total_mem(struct feat_fd *ff, } static int write_numa_topology(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { struct numa_topology *tp; int ret = -1; @@ -710,7 +710,7 @@ err: */ static int write_pmu_mappings(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { struct perf_pmu *pmu = NULL; u32 pmu_num = 0; @@ -759,7 +759,7 @@ static int write_pmu_mappings(struct feat_fd *ff, * }; */ static int write_group_desc(struct feat_fd *ff, - struct perf_evlist *evlist) + struct evlist *evlist) { u32 nr_groups = evlist->nr_groups; struct evsel *evsel; @@ -841,7 +841,7 @@ int __weak get_cpuid(char *buffer __maybe_unused, size_t sz __maybe_unused) } static int write_cpuid(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { char buffer[64]; int ret; @@ -854,13 +854,13 @@ static int write_cpuid(struct feat_fd *ff, } static int write_branch_stack(struct feat_fd *ff __maybe_unused, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { return 0; } static int write_auxtrace(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { struct perf_session *session; int err; @@ -877,14 +877,14 @@ static int write_auxtrace(struct feat_fd *ff, } static int write_clockid(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { return do_write(ff, &ff->ph->env.clockid_res_ns, sizeof(ff->ph->env.clockid_res_ns)); } static int write_dir_format(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { struct perf_session *session; struct perf_data *data; @@ -900,7 +900,7 @@ static int write_dir_format(struct feat_fd *ff, #ifdef HAVE_LIBBPF_SUPPORT static int write_bpf_prog_info(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { struct perf_env *env = &ff->ph->env; struct rb_root *root; @@ -942,14 +942,14 @@ out: } #else // HAVE_LIBBPF_SUPPORT static int write_bpf_prog_info(struct feat_fd *ff __maybe_unused, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { return 0; } #endif // HAVE_LIBBPF_SUPPORT static int write_bpf_btf(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { struct perf_env *env = &ff->ph->env; struct rb_root *root; @@ -1123,7 +1123,7 @@ static int build_caches(struct cpu_cache_level caches[], u32 size, u32 *cntp) #define MAX_CACHES (MAX_NR_CPUS * 4) static int write_cache(struct feat_fd *ff, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { struct cpu_cache_level caches[MAX_CACHES]; u32 cnt = 0, i, version = 1; @@ -1175,13 +1175,13 @@ out: } static int write_stat(struct feat_fd *ff __maybe_unused, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { return 0; } static int write_sample_time(struct feat_fd *ff, - struct perf_evlist *evlist) + struct evlist *evlist) { int ret; @@ -1315,7 +1315,7 @@ static int build_mem_topology(struct memory_node *nodes, u64 size, u64 *cntp) * 48 - bitmap | bitmap of memory indexes that belongs to node */ static int write_mem_topology(struct feat_fd *ff __maybe_unused, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { static struct memory_node nodes[MAX_MEMORY_NODES]; u64 bsize, version = 1, i, nr; @@ -1365,7 +1365,7 @@ out: } static int write_compressed(struct feat_fd *ff __maybe_unused, - struct perf_evlist *evlist __maybe_unused) + struct evlist *evlist __maybe_unused) { int ret; @@ -2090,7 +2090,7 @@ static int process_total_mem(struct feat_fd *ff, void *data __maybe_unused) } static struct evsel * -perf_evlist__find_by_index(struct perf_evlist *evlist, int idx) +perf_evlist__find_by_index(struct evlist *evlist, int idx) { struct evsel *evsel; @@ -2103,7 +2103,7 @@ perf_evlist__find_by_index(struct perf_evlist *evlist, int idx) } static void -perf_evlist__set_event_name(struct perf_evlist *evlist, +perf_evlist__set_event_name(struct evlist *evlist, struct evsel *event) { struct evsel *evsel; @@ -2801,7 +2801,7 @@ static int process_compressed(struct feat_fd *ff, } struct feature_ops { - int (*write)(struct feat_fd *ff, struct perf_evlist *evlist); + int (*write)(struct feat_fd *ff, struct evlist *evlist); void (*print)(struct feat_fd *ff, FILE *fp); int (*process)(struct feat_fd *ff, void *data); const char *name; @@ -2946,7 +2946,7 @@ int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full) static int do_write_feat(struct feat_fd *ff, int type, struct perf_file_section **p, - struct perf_evlist *evlist) + struct evlist *evlist) { int err; int ret = 0; @@ -2976,7 +2976,7 @@ static int do_write_feat(struct feat_fd *ff, int type, } static int perf_header__adds_write(struct perf_header *header, - struct perf_evlist *evlist, int fd) + struct evlist *evlist, int fd) { int nr_sections; struct feat_fd ff; @@ -3044,7 +3044,7 @@ int perf_header__write_pipe(int fd) } int perf_session__write_header(struct perf_session *session, - struct perf_evlist *evlist, + struct evlist *evlist, int fd, bool at_exit) { struct perf_file_header f_header; @@ -3511,7 +3511,7 @@ static int perf_evsel__prepare_tracepoint_event(struct evsel *evsel, return 0; } -static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist, +static int perf_evlist__prepare_tracepoint_events(struct evlist *evlist, struct tep_handle *pevent) { struct evsel *pos; @@ -3669,7 +3669,7 @@ int perf_event__synthesize_attr(struct perf_tool *tool, int perf_event__synthesize_features(struct perf_tool *tool, struct perf_session *session, - struct perf_evlist *evlist, + struct evlist *evlist, perf_event__handler_t process) { struct perf_header *header = &session->header; @@ -3921,7 +3921,7 @@ size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp) } int perf_event__synthesize_attrs(struct perf_tool *tool, - struct perf_evlist *evlist, + struct evlist *evlist, perf_event__handler_t process) { struct evsel *evsel; @@ -3950,7 +3950,7 @@ static bool has_scale(struct evsel *counter) } int perf_event__synthesize_extra_attr(struct perf_tool *tool, - struct perf_evlist *evsel_list, + struct evlist *evsel_list, perf_event__handler_t process, bool is_pipe) { @@ -4009,11 +4009,11 @@ int perf_event__synthesize_extra_attr(struct perf_tool *tool, int perf_event__process_attr(struct perf_tool *tool __maybe_unused, union perf_event *event, - struct perf_evlist **pevlist) + struct evlist **pevlist) { u32 i, ids, n_ids; struct evsel *evsel; - struct perf_evlist *evlist = *pevlist; + struct evlist *evlist = *pevlist; if (evlist == NULL) { *pevlist = evlist = perf_evlist__new(); @@ -4047,12 +4047,12 @@ int perf_event__process_attr(struct perf_tool *tool __maybe_unused, int perf_event__process_event_update(struct perf_tool *tool __maybe_unused, union perf_event *event, - struct perf_evlist **pevlist) + struct evlist **pevlist) { struct event_update_event *ev = &event->event_update; struct event_update_event_scale *ev_scale; struct event_update_event_cpus *ev_cpus; - struct perf_evlist *evlist; + struct evlist *evlist; struct evsel *evsel; struct perf_cpu_map *map; @@ -4092,7 +4092,7 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused, } int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, - struct perf_evlist *evlist, + struct evlist *evlist, perf_event__handler_t process) { union perf_event ev; diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 437d8617de27..3e48ae3c49b1 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -92,12 +92,12 @@ struct perf_header { struct perf_env env; }; -struct perf_evlist; +struct evlist; struct perf_session; int perf_session__read_header(struct perf_session *session); int perf_session__write_header(struct perf_session *session, - struct perf_evlist *evlist, + struct evlist *evlist, int fd, bool at_exit); int perf_header__write_pipe(int fd); @@ -117,11 +117,11 @@ int perf_header__fprintf_info(struct perf_session *s, FILE *fp, bool full); int perf_event__synthesize_features(struct perf_tool *tool, struct perf_session *session, - struct perf_evlist *evlist, + struct evlist *evlist, perf_event__handler_t process); int perf_event__synthesize_extra_attr(struct perf_tool *tool, - struct perf_evlist *evsel_list, + struct evlist *evsel_list, perf_event__handler_t process, bool is_pipe); @@ -132,7 +132,7 @@ int perf_event__synthesize_attr(struct perf_tool *tool, struct perf_event_attr *attr, u32 ids, u64 *id, perf_event__handler_t process); int perf_event__synthesize_attrs(struct perf_tool *tool, - struct perf_evlist *evlist, + struct evlist *evlist, perf_event__handler_t process); int perf_event__synthesize_event_update_unit(struct perf_tool *tool, struct evsel *evsel, @@ -147,14 +147,14 @@ int perf_event__synthesize_event_update_cpus(struct perf_tool *tool, struct evsel *evsel, perf_event__handler_t process); int perf_event__process_attr(struct perf_tool *tool, union perf_event *event, - struct perf_evlist **pevlist); + struct evlist **pevlist); int perf_event__process_event_update(struct perf_tool *tool, union perf_event *event, - struct perf_evlist **pevlist); + struct evlist **pevlist); size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp); int perf_event__synthesize_tracing_data(struct perf_tool *tool, - int fd, struct perf_evlist *evlist, + int fd, struct evlist *evlist, perf_event__handler_t process); int perf_event__process_tracing_data(struct perf_session *session, union perf_event *event); diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 3da49c479880..bb5437f549b6 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -2573,7 +2573,7 @@ void hist__account_cycles(struct branch_stack *bs, struct addr_location *al, } } -size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp) +size_t perf_evlist__fprintf_nr_events(struct evlist *evlist, FILE *fp) { struct evsel *pos; size_t ret = 0; diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 9bf247c638b8..83d5fc15429c 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -196,7 +196,7 @@ size_t events_stats__fprintf(struct events_stats *stats, FILE *fp); size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, int max_cols, float min_pcnt, FILE *fp, bool ignore_callchains); -size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp); +size_t perf_evlist__fprintf_nr_events(struct evlist *evlist, FILE *fp); void hists__filter_by_dso(struct hists *hists); void hists__filter_by_thread(struct hists *hists); @@ -367,7 +367,7 @@ void perf_hpp__setup_output_field(struct perf_hpp_list *list); void perf_hpp__reset_output_field(struct perf_hpp_list *list); void perf_hpp__append_sort_keys(struct perf_hpp_list *list); int perf_hpp__setup_hists_formats(struct perf_hpp_list *list, - struct perf_evlist *evlist); + struct evlist *evlist); bool perf_hpp__is_sort_entry(struct perf_hpp_fmt *format); @@ -432,7 +432,7 @@ static inline size_t perf_hpp__color_overhead(void) : 0; } -struct perf_evlist; +struct evlist; struct hist_browser_timer { void (*timer)(void *arg); @@ -461,7 +461,7 @@ int hist_entry__tui_annotate(struct hist_entry *he, struct evsel *evsel, struct hist_browser_timer *hbt, struct annotation_options *annotation_opts); -int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, +int perf_evlist__tui_browse_hists(struct evlist *evlist, const char *help, struct hist_browser_timer *hbt, float min_pcnt, struct perf_env *env, @@ -476,7 +476,7 @@ int res_sample_browse(struct res_sample *res_samples, int num_res, void res_sample_init(void); #else static inline -int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused, +int perf_evlist__tui_browse_hists(struct evlist *evlist __maybe_unused, const char *help __maybe_unused, struct hist_browser_timer *hbt __maybe_unused, float min_pcnt __maybe_unused, diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index 8fd46d5f4b39..849a5b713b04 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c @@ -760,7 +760,7 @@ static int intel_bts_synth_event(struct perf_session *session, static int intel_bts_synth_events(struct intel_bts *bts, struct perf_session *session) { - struct perf_evlist *evlist = session->evlist; + struct evlist *evlist = session->evlist; struct evsel *evsel; struct perf_event_attr attr; bool found = false; diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index f1595b86d7c7..c88e3d1ee9c7 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -2713,7 +2713,7 @@ static int intel_pt_synth_event(struct perf_session *session, const char *name, return err; } -static void intel_pt_set_event_name(struct perf_evlist *evlist, u64 id, +static void intel_pt_set_event_name(struct evlist *evlist, u64 id, const char *name) { struct evsel *evsel; @@ -2729,7 +2729,7 @@ static void intel_pt_set_event_name(struct perf_evlist *evlist, u64 id, } static struct evsel *intel_pt_evsel(struct intel_pt *pt, - struct perf_evlist *evlist) + struct evlist *evlist) { struct evsel *evsel; @@ -2744,7 +2744,7 @@ static struct evsel *intel_pt_evsel(struct intel_pt *pt, static int intel_pt_synth_events(struct intel_pt *pt, struct perf_session *session) { - struct perf_evlist *evlist = session->evlist; + struct evlist *evlist = session->evlist; struct evsel *evsel = intel_pt_evsel(pt, evlist); struct perf_event_attr attr; u64 id; @@ -2894,7 +2894,7 @@ static int intel_pt_synth_events(struct intel_pt *pt, return 0; } -static struct evsel *intel_pt_find_sched_switch(struct perf_evlist *evlist) +static struct evsel *intel_pt_find_sched_switch(struct evlist *evlist) { struct evsel *evsel; @@ -2908,7 +2908,7 @@ static struct evsel *intel_pt_find_sched_switch(struct perf_evlist *evlist) return NULL; } -static bool intel_pt_find_switch(struct perf_evlist *evlist) +static bool intel_pt_find_switch(struct evlist *evlist) { struct evsel *evsel; diff --git a/tools/perf/util/kvm-stat.h b/tools/perf/util/kvm-stat.h index 299edd32d3d4..a09c495f866b 100644 --- a/tools/perf/util/kvm-stat.h +++ b/tools/perf/util/kvm-stat.h @@ -7,7 +7,7 @@ #include "stat.h" struct evsel; -struct perf_evlist; +struct evlist; struct perf_session; struct event_key { @@ -74,7 +74,7 @@ struct exit_reasons_table { struct perf_kvm_stat { struct perf_tool tool; struct record_opts opts; - struct perf_evlist *evlist; + struct evlist *evlist; struct perf_session *session; const char *file_name; diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 14c423974d63..fdb0d1c5c5cf 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -101,7 +101,7 @@ static bool record_evsel(int *ind, struct evsel **start, return false; } -static struct evsel *find_evsel_group(struct perf_evlist *perf_evlist, +static struct evsel *find_evsel_group(struct evlist *perf_evlist, const char **ids, int idnum, struct evsel **metric_events) @@ -140,7 +140,7 @@ static struct evsel *find_evsel_group(struct perf_evlist *perf_evlist, } static int metricgroup__setup_events(struct list_head *groups, - struct perf_evlist *perf_evlist, + struct evlist *perf_evlist, struct rblist *metric_events_list) { struct metric_event *me; @@ -502,7 +502,7 @@ int metricgroup__parse_groups(const struct option *opt, struct rblist *metric_events) { struct parse_events_error parse_error; - struct perf_evlist *perf_evlist = *(struct perf_evlist **)opt->value; + struct evlist *perf_evlist = *(struct evlist **)opt->value; struct strbuf extra_events; LIST_HEAD(group_list); int ret; diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 177c41fc9842..42a5971146ae 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -150,7 +150,7 @@ void __weak auxtrace_mmap_params__init(struct auxtrace_mmap_params *mp __maybe_u } void __weak auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp __maybe_unused, - struct perf_evlist *evlist __maybe_unused, + struct evlist *evlist __maybe_unused, int idx __maybe_unused, bool per_cpu __maybe_unused) { diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index dfde9cb31562..d341b11fb141 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1904,7 +1904,7 @@ int parse_events_terms(struct list_head *terms, const char *str) return ret; } -int parse_events(struct perf_evlist *evlist, const char *str, +int parse_events(struct evlist *evlist, const char *str, struct parse_events_error *err) { struct parse_events_state parse_state = { @@ -2013,7 +2013,7 @@ void parse_events_print_error(struct parse_events_error *err, int parse_events_option(const struct option *opt, const char *str, int unset __maybe_unused) { - struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; + struct evlist *evlist = *(struct evlist **)opt->value; struct parse_events_error err = { .idx = 0, }; int ret = parse_events(evlist, str, &err); @@ -2026,7 +2026,7 @@ int parse_events_option(const struct option *opt, const char *str, } static int -foreach_evsel_in_last_glob(struct perf_evlist *evlist, +foreach_evsel_in_last_glob(struct evlist *evlist, int (*func)(struct evsel *evsel, const void *arg), const void *arg) @@ -2109,7 +2109,7 @@ static int set_filter(struct evsel *evsel, const void *arg) int parse_filter(const struct option *opt, const char *str, int unset __maybe_unused) { - struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; + struct evlist *evlist = *(struct evlist **)opt->value; return foreach_evsel_in_last_glob(evlist, set_filter, (const void *)str); @@ -2141,7 +2141,7 @@ int exclude_perf(const struct option *opt, const char *arg __maybe_unused, int unset __maybe_unused) { - struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; + struct evlist *evlist = *(struct evlist **)opt->value; return foreach_evsel_in_last_glob(evlist, add_exclude_perf_filter, NULL); diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 99e206598b60..48111b8fc232 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -13,7 +13,7 @@ struct list_head; struct evsel; -struct perf_evlist; +struct evlist; struct parse_events_error; struct option; @@ -31,7 +31,7 @@ bool have_tracepoints(struct list_head *evlist); const char *event_type(int type); int parse_events_option(const struct option *opt, const char *str, int unset); -int parse_events(struct perf_evlist *evlist, const char *str, +int parse_events(struct evlist *evlist, const char *str, struct parse_events_error *error); int parse_events_terms(struct list_head *terms, const char *str); int parse_filter(const struct option *opt, const char *str, int unset); @@ -119,7 +119,7 @@ struct parse_events_state { int idx; int nr_groups; struct parse_events_error *error; - struct perf_evlist *evlist; + struct evlist *evlist; struct list_head *terms; }; diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index beafbd469b0c..ed57b6b5ed91 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -858,7 +858,7 @@ static int pyrf_evsel__setup_types(void) struct pyrf_evlist { PyObject_HEAD - struct perf_evlist evlist; + struct evlist evlist; }; static int pyrf_evlist__init(struct pyrf_evlist *pevlist, @@ -886,7 +886,7 @@ static void pyrf_evlist__delete(struct pyrf_evlist *pevlist) static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs) { - struct perf_evlist *evlist = &pevlist->evlist; + struct evlist *evlist = &pevlist->evlist; static char *kwlist[] = { "pages", "overwrite", NULL }; int pages = 128, overwrite = false; @@ -906,7 +906,7 @@ static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist, static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs) { - struct perf_evlist *evlist = &pevlist->evlist; + struct evlist *evlist = &pevlist->evlist; static char *kwlist[] = { "timeout", NULL }; int timeout = -1, n; @@ -926,7 +926,7 @@ static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist, PyObject *args __maybe_unused, PyObject *kwargs __maybe_unused) { - struct perf_evlist *evlist = &pevlist->evlist; + struct evlist *evlist = &pevlist->evlist; PyObject *list = PyList_New(0); int i; @@ -964,7 +964,7 @@ static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs __maybe_unused) { - struct perf_evlist *evlist = &pevlist->evlist; + struct evlist *evlist = &pevlist->evlist; PyObject *pevsel; struct evsel *evsel; @@ -979,7 +979,7 @@ static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist, return Py_BuildValue("i", evlist->nr_entries); } -static struct perf_mmap *get_md(struct perf_evlist *evlist, int cpu) +static struct perf_mmap *get_md(struct evlist *evlist, int cpu) { int i; @@ -996,7 +996,7 @@ static struct perf_mmap *get_md(struct perf_evlist *evlist, int cpu) static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs) { - struct perf_evlist *evlist = &pevlist->evlist; + struct evlist *evlist = &pevlist->evlist; union perf_event *event; int sample_id_all = 1, cpu; static char *kwlist[] = { "cpu", "sample_id_all", NULL }; @@ -1049,7 +1049,7 @@ end: static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs) { - struct perf_evlist *evlist = &pevlist->evlist; + struct evlist *evlist = &pevlist->evlist; int group = 0; static char *kwlist[] = { "group", NULL }; diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index ef8f686729fd..a550d78a0b4d 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -13,7 +13,7 @@ typedef void (*setup_probe_fn_t)(struct evsel *evsel); static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str) { - struct perf_evlist *evlist; + struct evlist *evlist; struct evsel *evsel; unsigned long flags = perf_event_open_cloexec_flag(); int err = -EAGAIN, fd; @@ -132,7 +132,7 @@ bool perf_can_record_cpu_wide(void) return true; } -void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, +void perf_evlist__config(struct evlist *evlist, struct record_opts *opts, struct callchain_param *callchain) { struct evsel *evsel; @@ -256,9 +256,9 @@ int record_opts__config(struct record_opts *opts) return record_opts__config_freq(opts); } -bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str) +bool perf_evlist__can_select_event(struct evlist *evlist, const char *str) { - struct perf_evlist *temp_evlist; + struct evlist *temp_evlist; struct evsel *evsel; int err, fd, cpu; bool ret = false; diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sample-raw.c index 159a08220947..6c709647cd8e 100644 --- a/tools/perf/util/s390-sample-raw.c +++ b/tools/perf/util/s390-sample-raw.c @@ -200,7 +200,7 @@ static void s390_cpumcfdg_dump(struct perf_sample *sample) * its raw data. * The function is only invoked when the dump flag -D is set. */ -void perf_evlist__s390_sample_raw(struct perf_evlist *evlist, union perf_event *event, +void perf_evlist__s390_sample_raw(struct evlist *evlist, union perf_event *event, struct perf_sample *sample) { struct evsel *ev_bc000; diff --git a/tools/perf/util/sample-raw.c b/tools/perf/util/sample-raw.c index c21e1311fb0f..e84bbe0e441a 100644 --- a/tools/perf/util/sample-raw.c +++ b/tools/perf/util/sample-raw.c @@ -9,7 +9,7 @@ * Check platform the perf data file was created on and perform platform * specific interpretation. */ -void perf_evlist__init_trace_event_sample_raw(struct perf_evlist *evlist) +void perf_evlist__init_trace_event_sample_raw(struct evlist *evlist) { const char *arch_pf = perf_env__arch(evlist->env); diff --git a/tools/perf/util/sample-raw.h b/tools/perf/util/sample-raw.h index 95d445c87e93..afe1491a117e 100644 --- a/tools/perf/util/sample-raw.h +++ b/tools/perf/util/sample-raw.h @@ -2,13 +2,13 @@ #ifndef __SAMPLE_RAW_H #define __SAMPLE_RAW_H 1 -struct perf_evlist; +struct evlist; union perf_event; struct perf_sample; -void perf_evlist__s390_sample_raw(struct perf_evlist *evlist, +void perf_evlist__s390_sample_raw(struct evlist *evlist, union perf_event *event, struct perf_sample *sample); -void perf_evlist__init_trace_event_sample_raw(struct perf_evlist *evlist); +void perf_evlist__init_trace_event_sample_raw(struct evlist *evlist); #endif /* __PERF_EVLIST_H */ diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index e9d1cf8eb274..c191dc152175 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -300,7 +300,7 @@ static int process_event_synth_tracing_data_stub(struct perf_session *session static int process_event_synth_attr_stub(struct perf_tool *tool __maybe_unused, union perf_event *event __maybe_unused, - struct perf_evlist **pevlist + struct evlist **pevlist __maybe_unused) { dump_printf(": unhandled!\n"); @@ -309,7 +309,7 @@ static int process_event_synth_attr_stub(struct perf_tool *tool __maybe_unused, static int process_event_synth_event_update_stub(struct perf_tool *tool __maybe_unused, union perf_event *event __maybe_unused, - struct perf_evlist **pevlist + struct evlist **pevlist __maybe_unused) { if (dump_trace) @@ -1129,7 +1129,7 @@ static void stack_user__printf(struct stack_dump *dump) dump->size, dump->offset); } -static void perf_evlist__print_tstamp(struct perf_evlist *evlist, +static void perf_evlist__print_tstamp(struct evlist *evlist, union perf_event *event, struct perf_sample *sample) { @@ -1178,7 +1178,7 @@ static void sample_read__printf(struct perf_sample *sample, u64 read_format) sample->read.one.id, sample->read.one.value); } -static void dump_event(struct perf_evlist *evlist, union perf_event *event, +static void dump_event(struct evlist *evlist, union perf_event *event, u64 file_offset, struct perf_sample *sample) { if (!dump_trace) @@ -1296,7 +1296,7 @@ static struct machine *machines__find_for_cpumode(struct machines *machines, return &machines->host; } -static int deliver_sample_value(struct perf_evlist *evlist, +static int deliver_sample_value(struct evlist *evlist, struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, @@ -1326,7 +1326,7 @@ static int deliver_sample_value(struct perf_evlist *evlist, return tool->sample(tool, event, sample, sid->evsel, machine); } -static int deliver_sample_group(struct perf_evlist *evlist, +static int deliver_sample_group(struct evlist *evlist, struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, @@ -1347,7 +1347,7 @@ static int deliver_sample_group(struct perf_evlist *evlist, } static int - perf_evlist__deliver_sample(struct perf_evlist *evlist, + perf_evlist__deliver_sample(struct evlist *evlist, struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, @@ -1372,7 +1372,7 @@ static int } static int machines__deliver_event(struct machines *machines, - struct perf_evlist *evlist, + struct evlist *evlist, union perf_event *event, struct perf_sample *sample, struct perf_tool *tool, u64 file_offset) @@ -1553,7 +1553,7 @@ int perf_session__deliver_synth_event(struct perf_session *session, union perf_event *event, struct perf_sample *sample) { - struct perf_evlist *evlist = session->evlist; + struct evlist *evlist = session->evlist; struct perf_tool *tool = session->tool; events_stats__inc(&evlist->stats, event->header.type); @@ -1631,7 +1631,7 @@ out_parse_sample: static s64 perf_session__process_event(struct perf_session *session, union perf_event *event, u64 file_offset) { - struct perf_evlist *evlist = session->evlist; + struct evlist *evlist = session->evlist; struct perf_tool *tool = session->tool; int ret; @@ -2357,7 +2357,7 @@ out: int perf_event__process_id_index(struct perf_session *session, union perf_event *event) { - struct perf_evlist *evlist = session->evlist; + struct evlist *evlist = session->evlist; struct id_index_event *ie = &event->id_index; size_t i, nr, max_nr; @@ -2393,7 +2393,7 @@ int perf_event__process_id_index(struct perf_session *session, int perf_event__synthesize_id_index(struct perf_tool *tool, perf_event__handler_t process, - struct perf_evlist *evlist, + struct evlist *evlist, struct machine *machine) { union perf_event *ev; diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 2b2427c4c0b9..79e97d17ea04 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -23,7 +23,7 @@ struct itrace_synth_opts; struct perf_session { struct perf_header header; struct machines machines; - struct perf_evlist *evlist; + struct evlist *evlist; struct auxtrace *auxtrace; struct itrace_synth_opts *itrace_synth_opts; struct list_head auxtrace_index; @@ -140,7 +140,7 @@ int perf_event__process_id_index(struct perf_session *session, int perf_event__synthesize_id_index(struct perf_tool *tool, perf_event__handler_t process, - struct perf_evlist *evlist, + struct evlist *evlist, struct machine *machine); #endif /* __PERF_SESSION_H */ diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 133d3a45997f..d8e4392d6e18 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -2313,7 +2313,7 @@ static int parse_field_name(char *str, char **event, char **field, char **opt) * 2. full event name (e.g. sched:sched_switch) * 3. partial event name (should not contain ':') */ -static struct evsel *find_evsel(struct perf_evlist *evlist, char *event_name) +static struct evsel *find_evsel(struct evlist *evlist, char *event_name) { struct evsel *evsel = NULL; struct evsel *pos; @@ -2384,7 +2384,7 @@ static int add_evsel_fields(struct evsel *evsel, bool raw_trace, int level) return 0; } -static int add_all_dynamic_fields(struct perf_evlist *evlist, bool raw_trace, +static int add_all_dynamic_fields(struct evlist *evlist, bool raw_trace, int level) { int ret; @@ -2401,7 +2401,7 @@ static int add_all_dynamic_fields(struct perf_evlist *evlist, bool raw_trace, return 0; } -static int add_all_matching_fields(struct perf_evlist *evlist, +static int add_all_matching_fields(struct evlist *evlist, char *field_name, bool raw_trace, int level) { int ret = -ESRCH; @@ -2423,7 +2423,7 @@ static int add_all_matching_fields(struct perf_evlist *evlist, return ret; } -static int add_dynamic_entry(struct perf_evlist *evlist, const char *tok, +static int add_dynamic_entry(struct evlist *evlist, const char *tok, int level) { char *str, *event_name, *field_name, *opt_name; @@ -2567,7 +2567,7 @@ int hpp_dimension__add_output(unsigned col) } int sort_dimension__add(struct perf_hpp_list *list, const char *tok, - struct perf_evlist *evlist, + struct evlist *evlist, int level) { unsigned int i; @@ -2663,7 +2663,7 @@ int sort_dimension__add(struct perf_hpp_list *list, const char *tok, } static int setup_sort_list(struct perf_hpp_list *list, char *str, - struct perf_evlist *evlist) + struct evlist *evlist) { char *tmp, *tok; int ret = 0; @@ -2709,7 +2709,7 @@ static int setup_sort_list(struct perf_hpp_list *list, char *str, return ret; } -static const char *get_default_sort_order(struct perf_evlist *evlist) +static const char *get_default_sort_order(struct evlist *evlist) { const char *default_sort_orders[] = { default_sort_order, @@ -2743,7 +2743,7 @@ out_no_evlist: return default_sort_orders[sort__mode]; } -static int setup_sort_order(struct perf_evlist *evlist) +static int setup_sort_order(struct evlist *evlist) { char *new_sort_order; @@ -2804,7 +2804,7 @@ static char *setup_overhead(char *keys) return keys; } -static int __setup_sorting(struct perf_evlist *evlist) +static int __setup_sorting(struct evlist *evlist) { char *str; const char *sort_keys; @@ -3057,7 +3057,7 @@ out: return ret; } -int setup_sorting(struct perf_evlist *evlist) +int setup_sorting(struct evlist *evlist) { int err; diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index a0f232151d6f..5e34676a98e8 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -301,9 +301,9 @@ struct block_hist { extern struct sort_entry sort_thread; extern struct list_head hist_entry__sort_list; -struct perf_evlist; +struct evlist; struct tep_handle; -int setup_sorting(struct perf_evlist *evlist); +int setup_sorting(struct evlist *evlist); int setup_output_field(void); void reset_output_field(void); void sort__setup_elide(FILE *fp); @@ -318,7 +318,7 @@ bool is_strict_order(const char *order); int hpp_dimension__add_output(unsigned col); void reset_dimensions(void); int sort_dimension__add(struct perf_hpp_list *list, const char *tok, - struct perf_evlist *evlist, + struct evlist *evlist, int level); int output_field_add(struct perf_hpp_list *list, char *tok); int64_t diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 8da4ddcb2e44..cdfceb5b4d72 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -312,7 +312,7 @@ static void print_metric_header(struct perf_stat_config *config, static int first_shadow_cpu(struct perf_stat_config *config, struct evsel *evsel, int id) { - struct perf_evlist *evlist = evsel->evlist; + struct evlist *evlist = evsel->evlist; int i; if (!config->aggr_get_id) @@ -365,7 +365,7 @@ static void abs_printout(struct perf_stat_config *config, static bool is_mixed_hw_group(struct evsel *counter) { - struct perf_evlist *evlist = counter->evlist; + struct evlist *evlist = counter->evlist; u32 pmu_type = counter->attr.type; struct evsel *pos; @@ -489,7 +489,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, } static void aggr_update_shadow(struct perf_stat_config *config, - struct perf_evlist *evlist) + struct evlist *evlist) { int cpu, s2, id, s; u64 val; @@ -545,7 +545,7 @@ static void collect_all_aliases(struct perf_stat_config *config, struct evsel *c bool first), void *data) { - struct perf_evlist *evlist = counter->evlist; + struct evlist *evlist = counter->evlist; struct evsel *alias; alias = list_prepare_entry(counter, &(evlist->entries), node); @@ -651,7 +651,7 @@ static void print_counter_aggrdata(struct perf_stat_config *config, } static void print_aggr(struct perf_stat_config *config, - struct perf_evlist *evlist, + struct evlist *evlist, char *prefix) { bool metric_only = config->metric_only; @@ -859,7 +859,7 @@ static void print_counter(struct perf_stat_config *config, } static void print_no_aggr_metric(struct perf_stat_config *config, - struct perf_evlist *evlist, + struct evlist *evlist, char *prefix) { int cpu; @@ -910,7 +910,7 @@ static const char *aggr_header_csv[] = { }; static void print_metric_headers(struct perf_stat_config *config, - struct perf_evlist *evlist, + struct evlist *evlist, const char *prefix, bool no_indent) { struct perf_stat_output_ctx out; @@ -949,7 +949,7 @@ static void print_metric_headers(struct perf_stat_config *config, } static void print_interval(struct perf_stat_config *config, - struct perf_evlist *evlist, + struct evlist *evlist, char *prefix, struct timespec *ts) { bool metric_only = config->metric_only; @@ -1156,7 +1156,7 @@ static void print_percore(struct perf_stat_config *config, } void -perf_evlist__print_counters(struct perf_evlist *evlist, +perf_evlist__print_counters(struct evlist *evlist, struct perf_stat_config *config, struct target *_target, struct timespec *ts, diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index 8c19f3149f34..d81bcab2e64c 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -299,7 +299,7 @@ static const char *get_ratio_color(enum grc_type type, double ratio) return color; } -static struct evsel *perf_stat__find_event(struct perf_evlist *evsel_list, +static struct evsel *perf_stat__find_event(struct evlist *evsel_list, const char *name) { struct evsel *c2; @@ -312,7 +312,7 @@ static struct evsel *perf_stat__find_event(struct perf_evlist *evsel_list, } /* Mark MetricExpr target events and link events using them to them. */ -void perf_stat__collect_metric_expr(struct perf_evlist *evsel_list) +void perf_stat__collect_metric_expr(struct evlist *evsel_list) { struct evsel *counter, *leader, **metric_events, *oc; bool found; diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 7acb9a6730fe..efd934ec02c3 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -168,7 +168,7 @@ static int perf_evsel__alloc_stats(struct evsel *evsel, bool alloc_raw) return 0; } -int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw) +int perf_evlist__alloc_stats(struct evlist *evlist, bool alloc_raw) { struct evsel *evsel; @@ -184,7 +184,7 @@ out_free: return -1; } -void perf_evlist__free_stats(struct perf_evlist *evlist) +void perf_evlist__free_stats(struct evlist *evlist) { struct evsel *evsel; @@ -195,7 +195,7 @@ void perf_evlist__free_stats(struct perf_evlist *evlist) } } -void perf_evlist__reset_stats(struct perf_evlist *evlist) +void perf_evlist__reset_stats(struct evlist *evlist) { struct evsel *evsel; @@ -490,7 +490,7 @@ int create_perf_stat_counter(struct evsel *evsel, int perf_stat_synthesize_config(struct perf_stat_config *config, struct perf_tool *tool, - struct perf_evlist *evlist, + struct evlist *evlist, perf_event__handler_t process, bool attrs) { diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index b64cf0177a91..95b4de7a9d51 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -144,7 +144,7 @@ static inline void init_stats(struct stats *stats) } struct evsel; -struct perf_evlist; +struct evlist; struct perf_aggr_thread_value { struct evsel *counter; @@ -189,11 +189,11 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config, struct perf_stat_output_ctx *out, struct rblist *metric_events, struct runtime_stat *st); -void perf_stat__collect_metric_expr(struct perf_evlist *); +void perf_stat__collect_metric_expr(struct evlist *); -int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw); -void perf_evlist__free_stats(struct perf_evlist *evlist); -void perf_evlist__reset_stats(struct perf_evlist *evlist); +int perf_evlist__alloc_stats(struct evlist *evlist, bool alloc_raw); +void perf_evlist__free_stats(struct evlist *evlist); +void perf_evlist__reset_stats(struct evlist *evlist); int perf_stat_process_counter(struct perf_stat_config *config, struct evsel *counter); @@ -212,11 +212,11 @@ int create_perf_stat_counter(struct evsel *evsel, struct target *target); int perf_stat_synthesize_config(struct perf_stat_config *config, struct perf_tool *tool, - struct perf_evlist *evlist, + struct evlist *evlist, perf_event__handler_t process, bool attrs); void -perf_evlist__print_counters(struct perf_evlist *evlist, +perf_evlist__print_counters(struct evlist *evlist, struct perf_stat_config *config, struct target *_target, struct timespec *ts, diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h index 5d880a6f0a34..7f95dd1d6883 100644 --- a/tools/perf/util/tool.h +++ b/tools/perf/util/tool.h @@ -8,7 +8,7 @@ struct perf_session; union perf_event; -struct perf_evlist; +struct evlist; struct evsel; struct perf_sample; struct perf_tool; @@ -24,7 +24,7 @@ typedef int (*event_op)(struct perf_tool *tool, union perf_event *event, typedef int (*event_attr_op)(struct perf_tool *tool, union perf_event *event, - struct perf_evlist **pevlist); + struct evlist **pevlist); typedef int (*event_op2)(struct perf_session *session, union perf_event *event); typedef s64 (*event_op3)(struct perf_session *session, union perf_event *event); diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h index 7e0f363c0658..2023e0bf6165 100644 --- a/tools/perf/util/top.h +++ b/tools/perf/util/top.h @@ -9,13 +9,13 @@ #include #include -struct perf_evlist; +struct evlist; struct evsel; struct perf_session; struct perf_top { struct perf_tool tool; - struct perf_evlist *evlist; + struct evlist *evlist; struct record_opts record_opts; struct annotation_options annotation_opts; /* -- cgit v1.2.3-59-g8ed1b From b4b62ee688eb39151c9d8182c3e2f12c9d34602d Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:23:53 +0200 Subject: perf evsel: Rename perf_evsel__init() to evsel__init() Rename perf_evsel__init() to evsel__init(), so we don't have a name clash when we add perf_evsel__init() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-7-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 8 ++++---- tools/perf/util/evsel.h | 3 +-- tools/perf/util/python.c | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index f7f97ca6e96d..97bee83f0f98 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -223,8 +223,8 @@ bool perf_evsel__is_function_event(struct evsel *evsel) #undef FUNCTION_EVENT } -void perf_evsel__init(struct evsel *evsel, - struct perf_event_attr *attr, int idx) +void evsel__init(struct evsel *evsel, + struct perf_event_attr *attr, int idx) { evsel->idx = idx; evsel->tracking = !idx; @@ -255,7 +255,7 @@ struct evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) if (!evsel) return NULL; - perf_evsel__init(evsel, attr, idx); + evsel__init(evsel, attr, idx); if (perf_evsel__is_bpf_output(evsel)) { evsel->attr.sample_type |= (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | @@ -350,7 +350,7 @@ struct evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx) event_attr_init(&attr); attr.config = evsel->tp_format->id; attr.sample_period = 1; - perf_evsel__init(evsel, &attr, idx); + evsel__init(evsel, &attr, idx); } return evsel; diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 3caabd8a4aa6..af230d92fbef 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -238,8 +238,7 @@ struct evsel *perf_evsel__new_cycles(bool precise); struct tep_event *event_format__new(const char *sys, const char *name); -void perf_evsel__init(struct evsel *evsel, - struct perf_event_attr *attr, int idx); +void evsel__init(struct evsel *evsel, struct perf_event_attr *attr, int idx); void perf_evsel__exit(struct evsel *evsel); void perf_evsel__delete(struct evsel *evsel); diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index ed57b6b5ed91..f6fe3c90828f 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -782,7 +782,7 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel, attr.sample_id_all = sample_id_all; attr.size = sizeof(attr); - perf_evsel__init(&pevsel->evsel, &attr, idx); + evsel__init(&pevsel->evsel, &attr, idx); return 0; } -- cgit v1.2.3-59-g8ed1b From 52c86bca94b42239563b1510d5fc6329b0ec1a86 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:23:54 +0200 Subject: perf evlist: Rename perf_evlist__init() to evlist__init() Rename perf_evlist__init() to evlist__init(), so we don't have a name clash when we add perf_evlist__init() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-8-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 6 +++--- tools/perf/util/evlist.h | 4 ++-- tools/perf/util/python.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index c234fa4ba92a..4fcd55c8a8d5 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -41,8 +41,8 @@ int sigqueue(pid_t pid, int sig, const union sigval value); #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) #define SID(e, x, y) xyarray__entry(e->sample_id, x, y) -void perf_evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, - struct perf_thread_map *threads) +void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, + struct perf_thread_map *threads) { int i; @@ -60,7 +60,7 @@ struct evlist *perf_evlist__new(void) struct evlist *evlist = zalloc(sizeof(*evlist)); if (evlist != NULL) - perf_evlist__init(evlist, NULL, NULL); + evlist__init(evlist, NULL, NULL); return evlist; } diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 54f1c3e2b721..d6a3fa461566 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -68,8 +68,8 @@ struct evsel_str_handler { struct evlist *perf_evlist__new(void); struct evlist *perf_evlist__new_default(void); struct evlist *perf_evlist__new_dummy(void); -void perf_evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, - struct perf_thread_map *threads); +void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, + struct perf_thread_map *threads); void perf_evlist__exit(struct evlist *evlist); void perf_evlist__delete(struct evlist *evlist); diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index f6fe3c90828f..ade4e85c6d81 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -873,7 +873,7 @@ static int pyrf_evlist__init(struct pyrf_evlist *pevlist, threads = ((struct pyrf_thread_map *)pthreads)->threads; cpus = ((struct pyrf_cpu_map *)pcpus)->cpus; - perf_evlist__init(&pevlist->evlist, cpus, threads); + evlist__init(&pevlist->evlist, cpus, threads); return 0; } -- cgit v1.2.3-59-g8ed1b From 0f98b11c616f240b54ee85629ff4d3650c7ccc7d Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:23:55 +0200 Subject: perf evlist: Rename perf_evlist__new() to evlist__new() Rename perf_evlist__new() to evlist__new(), so we don't have a name clash when we add perf_evlist__new() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-9-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/powerpc/util/kvm-stat.c | 2 +- tools/perf/arch/x86/tests/intel-cqm.c | 2 +- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-ftrace.c | 2 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-stat.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/event-times.c | 2 +- tools/perf/tests/evsel-roundtrip-name.c | 4 ++-- tools/perf/tests/hists_cumulate.c | 2 +- tools/perf/tests/hists_filter.c | 2 +- tools/perf/tests/hists_link.c | 2 +- tools/perf/tests/hists_output.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c | 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/parse-events.c | 2 +- tools/perf/tests/sw-clock.c | 4 ++-- tools/perf/tests/switch-tracking.c | 4 ++-- tools/perf/util/evlist.c | 8 ++++---- tools/perf/util/evlist.h | 2 +- tools/perf/util/header.c | 4 ++-- tools/perf/util/record.c | 4 ++-- 28 files changed, 36 insertions(+), 36 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/powerpc/util/kvm-stat.c b/tools/perf/arch/powerpc/util/kvm-stat.c index 28fc0bab370f..f0dbf7b075c8 100644 --- a/tools/perf/arch/powerpc/util/kvm-stat.c +++ b/tools/perf/arch/powerpc/util/kvm-stat.c @@ -146,7 +146,7 @@ static int ppc__setup_book3s_hv(struct perf_kvm_stat *kvm, /* Wrapper to setup kvm tracepoints */ static int ppc__setup_kvm_tp(struct perf_kvm_stat *kvm) { - struct evlist *evlist = perf_evlist__new(); + struct evlist *evlist = evlist__new(); if (evlist == NULL) return -ENOMEM; diff --git a/tools/perf/arch/x86/tests/intel-cqm.c b/tools/perf/arch/x86/tests/intel-cqm.c index 333b2f0d61e4..8089a33c6c16 100644 --- a/tools/perf/arch/x86/tests/intel-cqm.c +++ b/tools/perf/arch/x86/tests/intel-cqm.c @@ -51,7 +51,7 @@ int test__intel_cqm_count_nmi_context(struct test *test __maybe_unused, int subt flag = perf_event_open_cloexec_flag(); - evlist = perf_evlist__new(); + evlist = evlist__new(); if (!evlist) { pr_debug("perf_evlist__new failed\n"); return TEST_FAIL; diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index d7092fc00e3b..da9a3302d8e6 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -68,7 +68,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe cpus = cpu_map__new(NULL); CHECK_NOT_NULL__(cpus); - evlist = perf_evlist__new(); + evlist = evlist__new(); CHECK_NOT_NULL__(evlist); perf_evlist__set_maps(evlist, cpus, threads); diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 1263987c291a..b8bdc593e5b8 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -495,7 +495,7 @@ int cmd_ftrace(int argc, const char **argv) goto out_delete_filters; } - ftrace.evlist = perf_evlist__new(); + ftrace.evlist = evlist__new(); if (ftrace.evlist == NULL) { ret = -ENOMEM; goto out_delete_filters; diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 963dddc5853d..ee896b8a9fe8 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1290,7 +1290,7 @@ static struct evlist *kvm_live_event_list(void) int err = -1; const char * const *events_tp; - evlist = perf_evlist__new(); + evlist = evlist__new(); if (evlist == NULL) return NULL; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index f08d1e6a1651..e8aa8a078dff 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -2265,7 +2265,7 @@ int cmd_record(int argc, const char **argv) CPU_ZERO(&rec->affinity_mask); rec->opts.affinity = PERF_AFFINITY_SYS; - rec->evlist = perf_evlist__new(); + rec->evlist = evlist__new(); if (rec->evlist == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 4e61f8a1d22b..ee0dc8088ac0 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1702,7 +1702,7 @@ int cmd_stat(int argc, const char **argv) setlocale(LC_ALL, ""); - evsel_list = perf_evlist__new(); + evsel_list = evlist__new(); if (evsel_list == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index c29fa1de854f..e4b7146cd666 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1524,7 +1524,7 @@ int cmd_top(int argc, const char **argv) top.annotation_opts.min_pcnt = 5; top.annotation_opts.context = 4; - top.evlist = perf_evlist__new(); + top.evlist = evlist__new(); if (top.evlist == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index f7e7daac3cbe..767b04eaaf45 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -4169,7 +4169,7 @@ int cmd_trace(int argc, const char **argv) signal(SIGSEGV, sighandler_dump_stack); signal(SIGFPE, sighandler_dump_stack); - trace.evlist = perf_evlist__new(); + trace.evlist = evlist__new(); trace.sctbl = syscalltbl__new(); if (trace.evlist == NULL || trace.sctbl == NULL) { diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 3f9c931069b0..3883b315b25b 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -99,7 +99,7 @@ int test__backward_ring_buffer(struct test *test __maybe_unused, int subtest __m pid[sizeof(pid) - 1] = '\0'; opts.target.tid = opts.target.pid = pid; - evlist = perf_evlist__new(); + evlist = evlist__new(); if (!evlist) { pr_debug("Not enough memory to create evlist\n"); return TEST_FAIL; diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 95a15b51f95c..d15f62dc4261 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -140,7 +140,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void), opts.target.tid = opts.target.pid = pid; /* Instead of perf_evlist__new_default, don't add default events */ - evlist = perf_evlist__new(); + evlist = evlist__new(); if (!evlist) { pr_debug("Not enough memory to create evlist\n"); return TEST_FAIL; diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 168deb9c563e..dd0325eabc25 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -622,7 +622,7 @@ static int do_test_code_reading(bool try_kcore) while (1) { const char *str; - evlist = perf_evlist__new(); + evlist = evlist__new(); if (!evlist) { pr_debug("perf_evlist__new failed\n"); goto out_put; diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index c3545a6efcbc..8d3cf9792d9e 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -166,7 +166,7 @@ static int test_times(int (attach)(struct evlist *), struct evsel *evsel; int err = -1, i; - evlist = perf_evlist__new(); + evlist = evlist__new(); if (!evlist) { pr_debug("failed to create event list\n"); goto out_err; diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c index 6cc408b23026..74e79d6b7e96 100644 --- a/tools/perf/tests/evsel-roundtrip-name.c +++ b/tools/perf/tests/evsel-roundtrip-name.c @@ -12,7 +12,7 @@ static int perf_evsel__roundtrip_cache_name_test(void) char name[128]; int type, op, err = 0, ret = 0, i, idx; struct evsel *evsel; - struct evlist *evlist = perf_evlist__new(); + struct evlist *evlist = evlist__new(); if (evlist == NULL) return -ENOMEM; @@ -68,7 +68,7 @@ static int __perf_evsel__name_array_test(const char *names[], int nr_names) { int i, err; struct evsel *evsel; - struct evlist *evlist = perf_evlist__new(); + struct evlist *evlist = evlist__new(); if (evlist == NULL) return -ENOMEM; diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index d7a6b97683d6..897e74b5ed1f 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -695,7 +695,7 @@ int test__hists_cumulate(struct test *test __maybe_unused, int subtest __maybe_u struct machines machines; struct machine *machine; struct evsel *evsel; - struct evlist *evlist = perf_evlist__new(); + struct evlist *evlist = evlist__new(); size_t i; test_fn_t testcases[] = { test1, diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index 9f0d6af839e9..b0468db74ca3 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -109,7 +109,7 @@ int test__hists_filter(struct test *test __maybe_unused, int subtest __maybe_unu struct machines machines; struct machine *machine; struct evsel *evsel; - struct evlist *evlist = perf_evlist__new(); + struct evlist *evlist = evlist__new(); TEST_ASSERT_VAL("No memory", evlist); diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index 6ab27dd3bf3f..878cb5bfbe78 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -272,7 +272,7 @@ int test__hists_link(struct test *test __maybe_unused, int subtest __maybe_unuse struct machines machines; struct machine *machine = NULL; struct evsel *evsel, *first; - struct evlist *evlist = perf_evlist__new(); + struct evlist *evlist = evlist__new(); if (evlist == NULL) return -ENOMEM; diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index cd36e51cdf3b..87a05e7afb7e 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -581,7 +581,7 @@ int test__hists_output(struct test *test __maybe_unused, int subtest __maybe_unu struct machines machines; struct machine *machine; struct evsel *evsel; - struct evlist *evlist = perf_evlist__new(); + struct evlist *evlist = evlist__new(); size_t i; test_fn_t testcases[] = { test1, diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index e0779f2a340c..4c73377bfccb 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -78,7 +78,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un cpus = cpu_map__new(NULL); CHECK_NOT_NULL__(cpus); - evlist = perf_evlist__new(); + evlist = evlist__new(); CHECK_NOT_NULL__(evlist); perf_evlist__set_maps(evlist, cpus, threads); diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 749b580e9a92..8d1be34fd951 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -61,7 +61,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse goto out_free_cpus; } - evlist = perf_evlist__new(); + evlist = evlist__new(); if (evlist == NULL) { pr_debug("perf_evlist__new\n"); goto out_free_cpus; diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index 69bf0ec2fe5f..141592437520 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -32,7 +32,7 @@ int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest }; const char *filename = "/etc/passwd"; int flags = O_RDONLY | O_DIRECTORY; - struct evlist *evlist = perf_evlist__new(); + struct evlist *evlist = evlist__new(); struct evsel *evsel; int err = -1, i, nr_events = 0, nr_polls = 0; char sbuf[STRERR_BUFSIZE]; diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 7409eed11b65..6e81a930b224 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -1777,7 +1777,7 @@ static int test_event(struct evlist_test *e) return 0; } - evlist = perf_evlist__new(); + evlist = evlist__new(); if (evlist == NULL) return -ENOMEM; diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 69b997eeb639..88a75cbae230 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -43,9 +43,9 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) attr.sample_freq = 500; - evlist = perf_evlist__new(); + evlist = evlist__new(); if (evlist == NULL) { - pr_debug("perf_evlist__new\n"); + pr_debug("evlist__new\n"); return -1; } diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 3e26ea36ec29..89bc20b2178a 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -347,9 +347,9 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ goto out_err; } - evlist = perf_evlist__new(); + evlist = evlist__new(); if (!evlist) { - pr_debug("perf_evlist__new failed!\n"); + pr_debug("evlist__new failed!\n"); goto out_err; } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4fcd55c8a8d5..317b2d64ba6d 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -55,7 +55,7 @@ void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, evlist->bkw_mmap_state = BKW_MMAP_NOTREADY; } -struct evlist *perf_evlist__new(void) +struct evlist *evlist__new(void) { struct evlist *evlist = zalloc(sizeof(*evlist)); @@ -67,7 +67,7 @@ struct evlist *perf_evlist__new(void) struct evlist *perf_evlist__new_default(void) { - struct evlist *evlist = perf_evlist__new(); + struct evlist *evlist = evlist__new(); if (evlist && perf_evlist__add_default(evlist)) { perf_evlist__delete(evlist); @@ -79,7 +79,7 @@ struct evlist *perf_evlist__new_default(void) struct evlist *perf_evlist__new_dummy(void) { - struct evlist *evlist = perf_evlist__new(); + struct evlist *evlist = evlist__new(); if (evlist && perf_evlist__add_dummy(evlist)) { perf_evlist__delete(evlist); @@ -1839,7 +1839,7 @@ int perf_evlist__add_sb_event(struct evlist **evlist, bool new_evlist = (*evlist) == NULL; if (*evlist == NULL) - *evlist = perf_evlist__new(); + *evlist = evlist__new(); if (*evlist == NULL) return -1; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index d6a3fa461566..60e1c9268e9e 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -65,7 +65,7 @@ struct evsel_str_handler { void *handler; }; -struct evlist *perf_evlist__new(void); +struct evlist *evlist__new(void); struct evlist *perf_evlist__new_default(void); struct evlist *perf_evlist__new_dummy(void); void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 692fe8ac12ae..5b90786a8436 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -3535,7 +3535,7 @@ int perf_session__read_header(struct perf_session *session) int nr_attrs, nr_ids, i, j; int fd = perf_data__fd(data); - session->evlist = perf_evlist__new(); + session->evlist = evlist__new(); if (session->evlist == NULL) return -ENOMEM; @@ -4016,7 +4016,7 @@ int perf_event__process_attr(struct perf_tool *tool __maybe_unused, struct evlist *evlist = *pevlist; if (evlist == NULL) { - *pevlist = evlist = perf_evlist__new(); + *pevlist = evlist = evlist__new(); if (evlist == NULL) return -ENOMEM; } diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index a550d78a0b4d..a23c69137dfc 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -19,7 +19,7 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str) int err = -EAGAIN, fd; static pid_t pid = -1; - evlist = perf_evlist__new(); + evlist = evlist__new(); if (!evlist) return -ENOMEM; @@ -264,7 +264,7 @@ bool perf_evlist__can_select_event(struct evlist *evlist, const char *str) bool ret = false; pid_t pid = -1; - temp_evlist = perf_evlist__new(); + temp_evlist = evlist__new(); if (!temp_evlist) return false; -- cgit v1.2.3-59-g8ed1b From c12995a55474e1cefac52da38c7fc47c024de067 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:23:56 +0200 Subject: perf evlist: Rename perf_evlist__delete() to evlist__delete() Rename perf_evlist__delete() to evlist__delete(), so we don't have a name clash when we add perf_evlist__delete() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-10-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/tests/intel-cqm.c | 2 +- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-ftrace.c | 2 +- tools/perf/builtin-kvm.c | 4 ++-- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-stat.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 4 ++-- tools/perf/tests/event-times.c | 2 +- tools/perf/tests/evsel-roundtrip-name.c | 4 ++-- tools/perf/tests/hists_cumulate.c | 2 +- tools/perf/tests/hists_filter.c | 2 +- tools/perf/tests/hists_link.c | 2 +- tools/perf/tests/hists_output.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c | 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/parse-events.c | 2 +- tools/perf/tests/parse-no-sample-id-all.c | 2 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/util/data-convert-bt.c | 2 +- tools/perf/util/evlist.c | 12 ++++++------ tools/perf/util/evlist.h | 2 +- tools/perf/util/header.c | 4 ++-- tools/perf/util/parse-events.c | 2 +- tools/perf/util/record.c | 4 ++-- 32 files changed, 42 insertions(+), 42 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/x86/tests/intel-cqm.c b/tools/perf/arch/x86/tests/intel-cqm.c index 8089a33c6c16..2a105e3b2ad1 100644 --- a/tools/perf/arch/x86/tests/intel-cqm.c +++ b/tools/perf/arch/x86/tests/intel-cqm.c @@ -124,6 +124,6 @@ int test__intel_cqm_count_nmi_context(struct test *test __maybe_unused, int subt kill(pid, SIGKILL); wait(NULL); out: - perf_evlist__delete(evlist); + evlist__delete(evlist); return err; } diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index da9a3302d8e6..09b6cef76f5b 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -163,6 +163,6 @@ next_event: err = 0; out_err: - perf_evlist__delete(evlist); + evlist__delete(evlist); return err; } diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index b8bdc593e5b8..105ef2a17a9c 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -508,7 +508,7 @@ int cmd_ftrace(int argc, const char **argv) ret = __cmd_ftrace(&ftrace, argc, argv); out_delete_evlist: - perf_evlist__delete(ftrace.evlist); + evlist__delete(ftrace.evlist); out_delete_filters: delete_filter_func(&ftrace.filters); diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index ee896b8a9fe8..8f54bdfb5743 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1325,7 +1325,7 @@ static struct evlist *kvm_live_event_list(void) out: if (err) { - perf_evlist__delete(evlist); + evlist__delete(evlist); evlist = NULL; } @@ -1460,7 +1460,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, out: perf_session__delete(kvm->session); kvm->session = NULL; - perf_evlist__delete(kvm->evlist); + evlist__delete(kvm->evlist); return err; } diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index e8aa8a078dff..06966a2c2cdd 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -2449,7 +2449,7 @@ int cmd_record(int argc, const char **argv) err = __cmd_record(&record, argc, argv); out: - perf_evlist__delete(rec->evlist); + evlist__delete(rec->evlist); symbol__exit(); auxtrace_record__free(rec->itr); return err; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index ee0dc8088ac0..d28d4d71d9b7 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -2015,7 +2015,7 @@ out: if (smi_cost && smi_reset) sysfs__write_int(FREEZE_ON_SMI_PATH, 0); - perf_evlist__delete(evsel_list); + evlist__delete(evsel_list); runtime_stat_delete(&stat_config); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index e4b7146cd666..6c0c2b78093a 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1661,7 +1661,7 @@ int cmd_top(int argc, const char **argv) perf_evlist__stop_sb_thread(sb_evlist); out_delete_evlist: - perf_evlist__delete(top.evlist); + evlist__delete(top.evlist); perf_session__delete(top.session); return status; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 767b04eaaf45..e133204b3bb9 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3498,7 +3498,7 @@ out_disable: out_delete_evlist: trace__symbols__exit(trace); - perf_evlist__delete(evlist); + evlist__delete(evlist); cgroup__put(trace->cgroup); trace->evlist = NULL; trace->live = false; diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 3883b315b25b..ef3c6db2fae4 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -150,6 +150,6 @@ int test__backward_ring_buffer(struct test *test __maybe_unused, int subtest __m ret = TEST_OK; out_delete_evlist: - perf_evlist__delete(evlist); + evlist__delete(evlist); return ret; } diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index d15f62dc4261..313ff1aadd9c 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -200,7 +200,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void), ret = TEST_OK; out_delete_evlist: - perf_evlist__delete(evlist); + evlist__delete(evlist); return ret; } diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index dd0325eabc25..1c7f092a7388 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -658,7 +658,7 @@ static int do_test_code_reading(bool try_kcore) cpu_map__get(cpus); thread_map__get(threads); perf_evlist__set_maps(evlist, NULL, NULL); - perf_evlist__delete(evlist); + evlist__delete(evlist); evlist = NULL; continue; } @@ -703,7 +703,7 @@ out_put: out_err: if (evlist) { - perf_evlist__delete(evlist); + evlist__delete(evlist); } else { cpu_map__put(cpus); thread_map__put(threads); diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 8d3cf9792d9e..0f74ca103c41 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -204,7 +204,7 @@ static int test_times(int (attach)(struct evlist *), count.ena, count.run); out_err: - perf_evlist__delete(evlist); + evlist__delete(evlist); return !err ? TEST_OK : TEST_FAIL; } diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c index 74e79d6b7e96..5330f106a6ee 100644 --- a/tools/perf/tests/evsel-roundtrip-name.c +++ b/tools/perf/tests/evsel-roundtrip-name.c @@ -60,7 +60,7 @@ static int perf_evsel__roundtrip_cache_name_test(void) } } - perf_evlist__delete(evlist); + evlist__delete(evlist); return ret; } @@ -91,7 +91,7 @@ static int __perf_evsel__name_array_test(const char *names[], int nr_names) } out_delete_evlist: - perf_evlist__delete(evlist); + evlist__delete(evlist); return err; } diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index 897e74b5ed1f..1f3de85ae18b 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -731,7 +731,7 @@ int test__hists_cumulate(struct test *test __maybe_unused, int subtest __maybe_u out: /* tear down everything */ - perf_evlist__delete(evlist); + evlist__delete(evlist); machines__exit(&machines); return err; diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index b0468db74ca3..a274716fc438 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -321,7 +321,7 @@ int test__hists_filter(struct test *test __maybe_unused, int subtest __maybe_unu out: /* tear down everything */ - perf_evlist__delete(evlist); + evlist__delete(evlist); reset_output_field(); machines__exit(&machines); diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index 878cb5bfbe78..b25383aa2e6e 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -334,7 +334,7 @@ int test__hists_link(struct test *test __maybe_unused, int subtest __maybe_unuse out: /* tear down everything */ - perf_evlist__delete(evlist); + evlist__delete(evlist); reset_output_field(); machines__exit(&machines); diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index 87a05e7afb7e..009888adf4b3 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -618,7 +618,7 @@ int test__hists_output(struct test *test __maybe_unused, int subtest __maybe_unu out: /* tear down everything */ - perf_evlist__delete(evlist); + evlist__delete(evlist); machines__exit(&machines); return err; diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 4c73377bfccb..cdc19bcc7523 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -147,7 +147,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un out_err: if (evlist) { perf_evlist__disable(evlist); - perf_evlist__delete(evlist); + evlist__delete(evlist); } else { cpu_map__put(cpus); thread_map__put(threads); diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 8d1be34fd951..7f96bb72f7e5 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -151,7 +151,7 @@ out_init: } out_delete_evlist: - perf_evlist__delete(evlist); + evlist__delete(evlist); cpus = NULL; threads = NULL; out_free_cpus: diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index 141592437520..0263420f4495 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -134,7 +134,7 @@ int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest out_ok: err = 0; out_delete_evlist: - perf_evlist__delete(evlist); + evlist__delete(evlist); out: return err; } diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 6e81a930b224..2365dd655c88 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -1790,7 +1790,7 @@ static int test_event(struct evlist_test *e) ret = e->check(evlist); } - perf_evlist__delete(evlist); + evlist__delete(evlist); return ret; } diff --git a/tools/perf/tests/parse-no-sample-id-all.c b/tools/perf/tests/parse-no-sample-id-all.c index fc0213246aaf..396e40d68922 100644 --- a/tools/perf/tests/parse-no-sample-id-all.c +++ b/tools/perf/tests/parse-no-sample-id-all.c @@ -46,7 +46,7 @@ static int process_events(union perf_event **events, size_t count) for (i = 0; i < count && !err; i++) err = process_event(&evlist, events[i]); - perf_evlist__delete(evlist); + evlist__delete(evlist); return err; } diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 99b2d26881f9..779d5996428b 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -325,7 +325,7 @@ found_exit: ++errs; } out_delete_evlist: - perf_evlist__delete(evlist); + evlist__delete(evlist); out: return (err < 0 || errs > 0) ? -1 : 0; } diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 88a75cbae230..1c7d8adb43d0 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -128,7 +128,7 @@ out_free_maps: cpu_map__put(cpus); thread_map__put(threads); out_delete_evlist: - perf_evlist__delete(evlist); + evlist__delete(evlist); return err; } diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 89bc20b2178a..ac5da4fd222f 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -567,7 +567,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ out: if (evlist) { perf_evlist__disable(evlist); - perf_evlist__delete(evlist); + evlist__delete(evlist); } else { cpu_map__put(cpus); thread_map__put(threads); diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 5c2cdb0ccb96..698ee5369c02 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -138,6 +138,6 @@ out_free_maps: cpu_map__put(cpus); thread_map__put(threads); out_delete_evlist: - perf_evlist__delete(evlist); + evlist__delete(evlist); return err; } diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 083101ae7b77..ca30bb25b3c5 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -1319,7 +1319,7 @@ static void cleanup_events(struct perf_session *session) zfree(&evsel->priv); } - perf_evlist__delete(evlist); + evlist__delete(evlist); session->evlist = NULL; } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 317b2d64ba6d..9fa3663068b4 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -70,7 +70,7 @@ struct evlist *perf_evlist__new_default(void) struct evlist *evlist = evlist__new(); if (evlist && perf_evlist__add_default(evlist)) { - perf_evlist__delete(evlist); + evlist__delete(evlist); evlist = NULL; } @@ -82,7 +82,7 @@ struct evlist *perf_evlist__new_dummy(void) struct evlist *evlist = evlist__new(); if (evlist && perf_evlist__add_dummy(evlist)) { - perf_evlist__delete(evlist); + evlist__delete(evlist); evlist = NULL; } @@ -134,7 +134,7 @@ void perf_evlist__exit(struct evlist *evlist) fdarray__exit(&evlist->pollfd); } -void perf_evlist__delete(struct evlist *evlist) +void evlist__delete(struct evlist *evlist) { if (evlist == NULL) return; @@ -1859,7 +1859,7 @@ int perf_evlist__add_sb_event(struct evlist **evlist, out_err: if (new_evlist) { - perf_evlist__delete(*evlist); + evlist__delete(*evlist); *evlist = NULL; } return -1; @@ -1938,7 +1938,7 @@ int perf_evlist__start_sb_thread(struct evlist *evlist, return 0; out_delete_evlist: - perf_evlist__delete(evlist); + evlist__delete(evlist); evlist = NULL; return -1; } @@ -1949,5 +1949,5 @@ void perf_evlist__stop_sb_thread(struct evlist *evlist) return; evlist->thread.done = 1; pthread_join(evlist->thread.th, NULL); - perf_evlist__delete(evlist); + evlist__delete(evlist); } diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 60e1c9268e9e..12a5fd6972df 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -71,7 +71,7 @@ struct evlist *perf_evlist__new_dummy(void); void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, struct perf_thread_map *threads); void perf_evlist__exit(struct evlist *evlist); -void perf_evlist__delete(struct evlist *evlist); +void evlist__delete(struct evlist *evlist); void perf_evlist__add(struct evlist *evlist, struct evsel *entry); void perf_evlist__remove(struct evlist *evlist, struct evsel *evsel); diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 5b90786a8436..29bbfd699226 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -3591,7 +3591,7 @@ int perf_session__read_header(struct perf_session *session) evsel->needs_swap = header->needs_swap; /* * Do it before so that if perf_evsel__alloc_id fails, this - * entry gets purged too at perf_evlist__delete(). + * entry gets purged too at evlist__delete(). */ perf_evlist__add(session->evlist, evsel); @@ -3628,7 +3628,7 @@ out_errno: return -errno; out_delete_evlist: - perf_evlist__delete(session->evlist); + evlist__delete(session->evlist); session->evlist = NULL; return -ENOMEM; } diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index d341b11fb141..6a4bfc7ab0c1 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1935,7 +1935,7 @@ int parse_events(struct evlist *evlist, const char *str, /* * There are 2 users - builtin-record and builtin-test objects. - * Both call perf_evlist__delete in case of error, so we dont + * Both call evlist__delete in case of error, so we dont * need to bother. */ return ret; diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index a23c69137dfc..9f8841548539 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -53,7 +53,7 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str) err = 0; out_delete: - perf_evlist__delete(evlist); + evlist__delete(evlist); return err; } @@ -299,7 +299,7 @@ bool perf_evlist__can_select_event(struct evlist *evlist, const char *str) ret = true; out_delete: - perf_evlist__delete(temp_evlist); + evlist__delete(temp_evlist); return ret; } -- cgit v1.2.3-59-g8ed1b From 5eb2dd2ade8354dcbe4cef54cd1719622af8f2dc Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:23:57 +0200 Subject: perf evsel: Rename perf_evsel__delete() to evsel__delete() Remame perf_evsel__delete() to evsel__delete(), so we don't have a name clash when we add perf_evsel__delete() in libperf. Also renaming perf_evsel__delete_priv() to evsel__delete_priv(). Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-11-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 4 ++-- tools/perf/builtin-trace.c | 12 ++++++------ tools/perf/tests/evsel-tp-sched.c | 4 ++-- tools/perf/tests/openat-syscall-all-cpus.c | 2 +- tools/perf/tests/openat-syscall.c | 2 +- tools/perf/util/evlist.c | 4 ++-- tools/perf/util/evsel.c | 4 ++-- tools/perf/util/evsel.h | 2 +- tools/perf/util/parse-events.c | 4 ++-- 9 files changed, 19 insertions(+), 19 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index d2131fc863be..917c8fb4baa5 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -623,7 +623,7 @@ static void strip_fini(struct perf_inject *inject) ok_to_remove(evlist, evsel)) { pr_debug("Deleting %s\n", perf_evsel__name(evsel)); perf_evlist__remove(evlist, evsel); - perf_evsel__delete(evsel); + evsel__delete(evsel); } } } @@ -725,7 +725,7 @@ static int __cmd_inject(struct perf_inject *inject) pr_debug("Deleting %s\n", perf_evsel__name(evsel)); perf_evlist__remove(session->evlist, evsel); - perf_evsel__delete(evsel); + evsel__delete(evsel); } if (inject->strip) strip_fini(inject); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index e133204b3bb9..0f7d1859a2d1 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -274,10 +274,10 @@ static int perf_evsel__init_tp_ptr_field(struct evsel *evsel, ({ struct syscall_tp *sc = evsel->priv;\ perf_evsel__init_tp_ptr_field(evsel, &sc->name, #name); }) -static void perf_evsel__delete_priv(struct evsel *evsel) +static void evsel__delete_priv(struct evsel *evsel) { zfree(&evsel->priv); - perf_evsel__delete(evsel); + evsel__delete(evsel); } static int perf_evsel__init_syscall_tp(struct evsel *evsel) @@ -368,7 +368,7 @@ static struct evsel *perf_evsel__raw_syscall_newtp(const char *direction, void * return evsel; out_delete: - perf_evsel__delete_priv(evsel); + evsel__delete_priv(evsel); return NULL; } @@ -2638,7 +2638,7 @@ static bool perf_evlist__add_vfs_getname(struct evlist *evlist) list_del_init(&evsel->node); evsel->evlist = NULL; - perf_evsel__delete(evsel); + evsel__delete(evsel); } return found; @@ -2739,9 +2739,9 @@ out: return ret; out_delete_sys_exit: - perf_evsel__delete_priv(sys_exit); + evsel__delete_priv(sys_exit); out_delete_sys_enter: - perf_evsel__delete_priv(sys_enter); + evsel__delete_priv(sys_enter); goto out; } diff --git a/tools/perf/tests/evsel-tp-sched.c b/tools/perf/tests/evsel-tp-sched.c index 0170e9d2e329..261e6eaaee99 100644 --- a/tools/perf/tests/evsel-tp-sched.c +++ b/tools/perf/tests/evsel-tp-sched.c @@ -64,7 +64,7 @@ int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, int subtes if (perf_evsel__test_field(evsel, "next_prio", 4, true)) ret = -1; - perf_evsel__delete(evsel); + evsel__delete(evsel); evsel = perf_evsel__newtp("sched", "sched_wakeup"); @@ -85,6 +85,6 @@ int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, int subtes if (perf_evsel__test_field(evsel, "target_cpu", 4, true)) ret = -1; - perf_evsel__delete(evsel); + evsel__delete(evsel); return ret; } diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index 4bf73896695a..001a0e8e6998 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -118,7 +118,7 @@ int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int out_close_fd: perf_evsel__close_fd(evsel); out_evsel_delete: - perf_evsel__delete(evsel); + evsel__delete(evsel); out_cpu_map_delete: cpu_map__put(cpus); out_thread_map_delete: diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c index f3efadd05863..20e353fbfdd0 100644 --- a/tools/perf/tests/openat-syscall.c +++ b/tools/perf/tests/openat-syscall.c @@ -59,7 +59,7 @@ int test__openat_syscall_event(struct test *test __maybe_unused, int subtest __m out_close_fd: perf_evsel__close_fd(evsel); out_evsel_delete: - perf_evsel__delete(evsel); + evsel__delete(evsel); out_thread_map_delete: thread_map__put(threads); return err; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 9fa3663068b4..986d20c15778 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -121,7 +121,7 @@ static void perf_evlist__purge(struct evlist *evlist) evlist__for_each_entry_safe(evlist, n, pos) { list_del_init(&pos->node); pos->evlist = NULL; - perf_evsel__delete(pos); + evsel__delete(pos); } evlist->nr_entries = 0; @@ -277,7 +277,7 @@ static int perf_evlist__add_attrs(struct evlist *evlist, out_delete_partial_list: __evlist__for_each_entry_safe(&head, n, evsel) - perf_evsel__delete(evsel); + evsel__delete(evsel); return -1; } diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 97bee83f0f98..de379b63f1ce 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -316,7 +316,7 @@ new_event: out: return evsel; error_free: - perf_evsel__delete(evsel); + evsel__delete(evsel); evsel = NULL; goto out; } @@ -1333,7 +1333,7 @@ void perf_evsel__exit(struct evsel *evsel) perf_evsel__object.fini(evsel); } -void perf_evsel__delete(struct evsel *evsel) +void evsel__delete(struct evsel *evsel) { perf_evsel__exit(evsel); free(evsel); diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index af230d92fbef..20b4e31b63a9 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -240,7 +240,7 @@ struct tep_event *event_format__new(const char *sys, const char *name); void evsel__init(struct evsel *evsel, struct perf_event_attr *attr, int idx); void perf_evsel__exit(struct evsel *evsel); -void perf_evsel__delete(struct evsel *evsel); +void evsel__delete(struct evsel *evsel); struct callchain_param; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 6a4bfc7ab0c1..cc63367f6e45 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -662,7 +662,7 @@ static int add_bpf_event(const char *group, const char *event, int fd, struct bp group, event); list_for_each_entry_safe(evsel, tmp, &new_evsels, node) { list_del_init(&evsel->node); - perf_evsel__delete(evsel); + evsel__delete(evsel); } return err; } @@ -2334,7 +2334,7 @@ static bool is_event_supported(u8 type, unsigned config) evsel->attr.exclude_kernel = 1; ret = perf_evsel__open(evsel, NULL, tmap) >= 0; } - perf_evsel__delete(evsel); + evsel__delete(evsel); } thread_map__put(tmap); -- cgit v1.2.3-59-g8ed1b From 365c3ae7452ca95e0a8f1e4716dd806550ade706 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:23:58 +0200 Subject: perf evsel: Rename perf_evsel__new() to evsel__new() Rename perf_evsel__new() to evsel__new(), so we don't have a name clash when we add perf_evsel__new() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-12-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/util/evsel.c | 2 +- tools/perf/util/evsel.h | 2 +- tools/perf/util/header.c | 4 ++-- tools/perf/util/parse-events.c | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 0f7d1859a2d1..c5eb47f4e42e 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2657,7 +2657,7 @@ static struct evsel *perf_evsel__new_pgfault(u64 config) event_attr_init(&attr); - evsel = perf_evsel__new(&attr); + evsel = evsel__new(&attr); if (evsel) evsel->handler = trace__pgfault; diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 1c7d8adb43d0..247d3734686e 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -49,7 +49,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) return -1; } - evsel = perf_evsel__new(&attr); + evsel = evsel__new(&attr); if (evsel == NULL) { pr_debug("perf_evsel__new\n"); goto out_delete_evlist; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index de379b63f1ce..c9723c2d57c9 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -301,7 +301,7 @@ struct evsel *perf_evsel__new_cycles(bool precise) * to kick in when we return and before perf_evsel__open() is called. */ new_event: - evsel = perf_evsel__new(&attr); + evsel = evsel__new(&attr); if (evsel == NULL) goto out; diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 20b4e31b63a9..ecea51a918e0 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -219,7 +219,7 @@ int perf_evsel__object_config(size_t object_size, struct evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx); -static inline struct evsel *perf_evsel__new(struct perf_event_attr *attr) +static inline struct evsel *evsel__new(struct perf_event_attr *attr) { return perf_evsel__new_idx(attr, 0); } diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 29bbfd699226..7760ddc4bc18 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -3583,7 +3583,7 @@ int perf_session__read_header(struct perf_session *session) } tmp = lseek(fd, 0, SEEK_CUR); - evsel = perf_evsel__new(&f_attr.attr); + evsel = evsel__new(&f_attr.attr); if (evsel == NULL) goto out_delete_evlist; @@ -4021,7 +4021,7 @@ int perf_event__process_attr(struct perf_tool *tool __maybe_unused, return -ENOMEM; } - evsel = perf_evsel__new(&event->attr.attr); + evsel = evsel__new(&event->attr.attr); if (evsel == NULL) return -ENOMEM; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index cc63367f6e45..40087cf74dd1 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -2318,7 +2318,7 @@ static bool is_event_supported(u8 type, unsigned config) if (tmap == NULL) return false; - evsel = perf_evsel__new(&attr); + evsel = evsel__new(&attr); if (evsel) { open_return = perf_evsel__open(evsel, NULL, tmap); ret = open_return >= 0; -- cgit v1.2.3-59-g8ed1b From a1cf3a75d3317ed893d453c222d220ca4d5f4c4e Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:23:59 +0200 Subject: perf evlist: Rename perf_evlist__add() to evlist__add() Rename perf_evlist__add() to evlist__add(), so we don't have a name clash when we add perf_evlist__add() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-13-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 12 ++++++------ tools/perf/tests/mmap-basic.c | 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/util/evlist.c | 16 ++++++++-------- tools/perf/util/evlist.h | 2 +- tools/perf/util/header.c | 4 ++-- tools/perf/util/python.c | 2 +- 8 files changed, 21 insertions(+), 21 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index c5eb47f4e42e..89ae4737ef74 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2616,7 +2616,7 @@ static int trace__record(struct trace *trace, int argc, const char **argv) static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp); -static bool perf_evlist__add_vfs_getname(struct evlist *evlist) +static bool evlist__add_vfs_getname(struct evlist *evlist) { bool found = false; struct evsel *evsel, *tmp; @@ -2719,8 +2719,8 @@ static int trace__add_syscall_newtp(struct trace *trace) perf_evsel__config_callchain(sys_enter, &trace->opts, &callchain_param); perf_evsel__config_callchain(sys_exit, &trace->opts, &callchain_param); - perf_evlist__add(evlist, sys_enter); - perf_evlist__add(evlist, sys_exit); + evlist__add(evlist, sys_enter); + evlist__add(evlist, sys_exit); if (callchain_param.enabled && !trace->kernel_syscallchains) { /* @@ -3264,7 +3264,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) goto out_error_raw_syscalls; if (trace->trace_syscalls) - trace->vfs_getname = perf_evlist__add_vfs_getname(evlist); + trace->vfs_getname = evlist__add_vfs_getname(evlist); } if ((trace->trace_pgfaults & TRACE_PFMAJ)) { @@ -3272,7 +3272,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (pgfault_maj == NULL) goto out_error_mem; perf_evsel__config_callchain(pgfault_maj, &trace->opts, &callchain_param); - perf_evlist__add(evlist, pgfault_maj); + evlist__add(evlist, pgfault_maj); } if ((trace->trace_pgfaults & TRACE_PFMIN)) { @@ -3280,7 +3280,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (pgfault_min == NULL) goto out_error_mem; perf_evsel__config_callchain(pgfault_min, &trace->opts, &callchain_param); - perf_evlist__add(evlist, pgfault_min); + evlist__add(evlist, pgfault_min); } if (trace->sched && diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 7f96bb72f7e5..16b8a4e5de8f 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -82,7 +82,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse evsels[i]->attr.wakeup_events = 1; perf_evsel__set_sample_id(evsels[i], false); - perf_evlist__add(evlist, evsels[i]); + evlist__add(evlist, evsels[i]); if (perf_evsel__open(evsels[i], cpus, threads) < 0) { pr_debug("failed to open counter: %s, " diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index 0263420f4495..f822c3c181f3 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -48,7 +48,7 @@ int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest goto out_delete_evlist; } - perf_evlist__add(evlist, evsel); + evlist__add(evlist, evsel); err = perf_evlist__create_maps(evlist, &opts.target); if (err < 0) { diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 247d3734686e..3ab11291174c 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -54,7 +54,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) pr_debug("perf_evsel__new\n"); goto out_delete_evlist; } - perf_evlist__add(evlist, evsel); + evlist__add(evlist, evsel); cpus = cpu_map__dummy_new(); threads = thread_map__new_by_tid(getpid()); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 986d20c15778..7741e12bdcb0 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -177,7 +177,7 @@ static void perf_evlist__propagate_maps(struct evlist *evlist) __perf_evlist__propagate_maps(evlist, evsel); } -void perf_evlist__add(struct evlist *evlist, struct evsel *entry) +void evlist__add(struct evlist *evlist, struct evsel *entry) { entry->evlist = evlist; list_add_tail(&entry->node, &evlist->entries); @@ -204,7 +204,7 @@ void perf_evlist__splice_list_tail(struct evlist *evlist, __evlist__for_each_entry_safe(list, temp, evsel) { list_del_init(&evsel->node); - perf_evlist__add(evlist, evsel); + evlist__add(evlist, evsel); } } @@ -237,7 +237,7 @@ int __perf_evlist__add_default(struct evlist *evlist, bool precise) if (evsel == NULL) return -ENOMEM; - perf_evlist__add(evlist, evsel); + evlist__add(evlist, evsel); return 0; } @@ -253,11 +253,11 @@ int perf_evlist__add_dummy(struct evlist *evlist) if (evsel == NULL) return -ENOMEM; - perf_evlist__add(evlist, evsel); + evlist__add(evlist, evsel); return 0; } -static int perf_evlist__add_attrs(struct evlist *evlist, +static int evlist__add_attrs(struct evlist *evlist, struct perf_event_attr *attrs, size_t nr_attrs) { struct evsel *evsel, *n; @@ -289,7 +289,7 @@ int __perf_evlist__add_default_attrs(struct evlist *evlist, for (i = 0; i < nr_attrs; i++) event_attr_init(attrs + i); - return perf_evlist__add_attrs(evlist, attrs, nr_attrs); + return evlist__add_attrs(evlist, attrs, nr_attrs); } struct evsel * @@ -330,7 +330,7 @@ int perf_evlist__add_newtp(struct evlist *evlist, return -1; evsel->handler = handler; - perf_evlist__add(evlist, evsel); + evlist__add(evlist, evsel); return 0; } @@ -1854,7 +1854,7 @@ int perf_evlist__add_sb_event(struct evlist **evlist, evsel->side_band.cb = cb; evsel->side_band.data = data; - perf_evlist__add(*evlist, evsel); + evlist__add(*evlist, evsel); return 0; out_err: diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 12a5fd6972df..d52b29a1d852 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -73,7 +73,7 @@ void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, void perf_evlist__exit(struct evlist *evlist); void evlist__delete(struct evlist *evlist); -void perf_evlist__add(struct evlist *evlist, struct evsel *entry); +void evlist__add(struct evlist *evlist, struct evsel *entry); void perf_evlist__remove(struct evlist *evlist, struct evsel *evsel); int __perf_evlist__add_default(struct evlist *evlist, bool precise); diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 7760ddc4bc18..5e0093251f26 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -3593,7 +3593,7 @@ int perf_session__read_header(struct perf_session *session) * Do it before so that if perf_evsel__alloc_id fails, this * entry gets purged too at evlist__delete(). */ - perf_evlist__add(session->evlist, evsel); + evlist__add(session->evlist, evsel); nr_ids = f_attr.ids.size / sizeof(u64); /* @@ -4025,7 +4025,7 @@ int perf_event__process_attr(struct perf_tool *tool __maybe_unused, if (evsel == NULL) return -ENOMEM; - perf_evlist__add(evlist, evsel); + evlist__add(evlist, evsel); ids = event->header.size; ids -= (void *)&event->attr.id - (void *)event; diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index ade4e85c6d81..48c951a4a76b 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -974,7 +974,7 @@ static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist, Py_INCREF(pevsel); evsel = &((struct pyrf_evsel *)pevsel)->evsel; evsel->idx = evlist->nr_entries; - perf_evlist__add(evlist, evsel); + evlist__add(evlist, evsel); return Py_BuildValue("i", evlist->nr_entries); } -- cgit v1.2.3-59-g8ed1b From 1625102764a578b11fb407b8194cb0521129d919 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:00 +0200 Subject: perf evlist: Rename perf_evlist__remove() to evlist__remove() Rename perf_evlist__remove() to evlist__remove(), so we don't have a name clash when we add perf_evlist__remove() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-14-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 4 ++-- tools/perf/util/evlist.c | 2 +- tools/perf/util/evlist.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 917c8fb4baa5..4e56e399bbc8 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -622,7 +622,7 @@ static void strip_fini(struct perf_inject *inject) if (evsel->handler == drop_sample && ok_to_remove(evlist, evsel)) { pr_debug("Deleting %s\n", perf_evsel__name(evsel)); - perf_evlist__remove(evlist, evsel); + evlist__remove(evlist, evsel); evsel__delete(evsel); } } @@ -724,7 +724,7 @@ static int __cmd_inject(struct perf_inject *inject) if (evsel) { pr_debug("Deleting %s\n", perf_evsel__name(evsel)); - perf_evlist__remove(session->evlist, evsel); + evlist__remove(session->evlist, evsel); evsel__delete(evsel); } if (inject->strip) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 7741e12bdcb0..47516db62424 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -190,7 +190,7 @@ void evlist__add(struct evlist *evlist, struct evsel *entry) __perf_evlist__propagate_maps(evlist, entry); } -void perf_evlist__remove(struct evlist *evlist, struct evsel *evsel) +void evlist__remove(struct evlist *evlist, struct evsel *evsel) { evsel->evlist = NULL; list_del_init(&evsel->node); diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index d52b29a1d852..b3a44e2eed08 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -74,7 +74,7 @@ void perf_evlist__exit(struct evlist *evlist); void evlist__delete(struct evlist *evlist); void evlist__add(struct evlist *evlist, struct evsel *entry); -void perf_evlist__remove(struct evlist *evlist, struct evsel *evsel); +void evlist__remove(struct evlist *evlist, struct evsel *evsel); int __perf_evlist__add_default(struct evlist *evlist, bool precise); -- cgit v1.2.3-59-g8ed1b From 5972d1e07bd95c7458e2d7f484391d69008affc7 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:01 +0200 Subject: perf evsel: Rename perf_evsel__open() to evsel__open() Rename perf_evsel__open() to evsel__open(), so we don't have a name clash when we add perf_evsel__open() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-15-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/tests/mmap-basic.c | 2 +- tools/perf/tests/openat-syscall-all-cpus.c | 2 +- tools/perf/util/evlist.c | 4 ++-- tools/perf/util/evsel.c | 8 ++++---- tools/perf/util/evsel.h | 4 ++-- tools/perf/util/parse-events.c | 4 ++-- tools/perf/util/python.c | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 06966a2c2cdd..7f933997b6d0 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -739,7 +739,7 @@ static int record__open(struct record *rec) evlist__for_each_entry(evlist, pos) { try_again: - if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) { + if (evsel__open(pos, pos->cpus, pos->threads) < 0) { if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) { if (verbose > 0) ui__warning("%s\n", msg); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 6c0c2b78093a..5886389f6a40 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -989,7 +989,7 @@ static int perf_top__start_counters(struct perf_top *top) evlist__for_each_entry(evlist, counter) { try_again: - if (perf_evsel__open(counter, top->evlist->cpus, + if (evsel__open(counter, top->evlist->cpus, top->evlist->threads) < 0) { /* diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 16b8a4e5de8f..40511025208f 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -84,7 +84,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse evlist__add(evlist, evsels[i]); - if (perf_evsel__open(evsels[i], cpus, threads) < 0) { + if (evsel__open(evsels[i], cpus, threads) < 0) { pr_debug("failed to open counter: %s, " "tweak /proc/sys/kernel/perf_event_paranoid?\n", str_error_r(errno, sbuf, sizeof(sbuf))); diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index 001a0e8e6998..f96cbd304024 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -48,7 +48,7 @@ int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int goto out_cpu_map_delete; } - if (perf_evsel__open(evsel, cpus, threads) < 0) { + if (evsel__open(evsel, cpus, threads) < 0) { pr_debug("failed to open counter: %s, " "tweak /proc/sys/kernel/perf_event_paranoid?\n", str_error_r(errno, sbuf, sizeof(sbuf))); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 47516db62424..4627cc47de3e 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1405,7 +1405,7 @@ int perf_evlist__open(struct evlist *evlist) perf_evlist__update_id_pos(evlist); evlist__for_each_entry(evlist, evsel) { - err = perf_evsel__open(evsel, evsel->cpus, evsel->threads); + err = evsel__open(evsel, evsel->cpus, evsel->threads); if (err < 0) goto out_err; } @@ -1918,7 +1918,7 @@ int perf_evlist__start_sb_thread(struct evlist *evlist, goto out_delete_evlist; evlist__for_each_entry(evlist, counter) { - if (perf_evsel__open(counter, evlist->cpus, + if (evsel__open(counter, evlist->cpus, evlist->threads) < 0) goto out_delete_evlist; } diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index c9723c2d57c9..f365d0685268 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1825,8 +1825,8 @@ static int perf_event_open(struct evsel *evsel, return fd; } -int perf_evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus, - struct perf_thread_map *threads) +int evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus, + struct perf_thread_map *threads) { int cpu, thread, nthreads; unsigned long flags = PERF_FLAG_FD_CLOEXEC; @@ -2086,13 +2086,13 @@ void perf_evsel__close(struct evsel *evsel) int perf_evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus) { - return perf_evsel__open(evsel, cpus, NULL); + return evsel__open(evsel, cpus, NULL); } int perf_evsel__open_per_thread(struct evsel *evsel, struct perf_thread_map *threads) { - return perf_evsel__open(evsel, NULL, threads); + return evsel__open(evsel, NULL, threads); } static int perf_evsel__parse_id_sample(const struct evsel *evsel, diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index ecea51a918e0..d43409bb07c5 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -302,8 +302,8 @@ int perf_evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus); int perf_evsel__open_per_thread(struct evsel *evsel, struct perf_thread_map *threads); -int perf_evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus, - struct perf_thread_map *threads); +int evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus, + struct perf_thread_map *threads); void perf_evsel__close(struct evsel *evsel); struct perf_sample; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 40087cf74dd1..decb66d243ca 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -2320,7 +2320,7 @@ static bool is_event_supported(u8 type, unsigned config) evsel = evsel__new(&attr); if (evsel) { - open_return = perf_evsel__open(evsel, NULL, tmap); + open_return = evsel__open(evsel, NULL, tmap); ret = open_return >= 0; if (open_return == -EACCES) { @@ -2332,7 +2332,7 @@ static bool is_event_supported(u8 type, unsigned config) * */ evsel->attr.exclude_kernel = 1; - ret = perf_evsel__open(evsel, NULL, tmap) >= 0; + ret = evsel__open(evsel, NULL, tmap) >= 0; } evsel__delete(evsel); } diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 48c951a4a76b..3eb7348d29f8 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -817,7 +817,7 @@ static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel, * This will group just the fds for this single evsel, to group * multiple events, use evlist.open(). */ - if (perf_evsel__open(evsel, cpus, threads) < 0) { + if (evsel__open(evsel, cpus, threads) < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } -- cgit v1.2.3-59-g8ed1b From ec7f24ef44fc5a4eb5cb71658c33db538ed66003 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:02 +0200 Subject: perf evsel: Rename perf_evsel__enable() to evsel__enable() Rename perf_evsel__enable() to evsel__enable(), so we don't have a name clash when we add perf_evsel__enable() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-16-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 2 +- tools/perf/arch/x86/util/intel-bts.c | 2 +- tools/perf/arch/x86/util/intel-pt.c | 2 +- tools/perf/tests/event-times.c | 6 +++--- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/util/evlist.c | 4 ++-- tools/perf/util/evsel.c | 2 +- tools/perf/util/evsel.h | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 91c64daa4487..4b70b9504603 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -834,7 +834,7 @@ static int cs_etm_snapshot_finish(struct auxtrace_record *itr) evlist__for_each_entry(ptr->evlist, evsel) { if (evsel->attr.type == ptr->cs_etm_pmu->type) - return perf_evsel__enable(evsel); + return evsel__enable(evsel); } return -EINVAL; } diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index c845531d383a..d27832fcb34c 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -330,7 +330,7 @@ static int intel_bts_snapshot_finish(struct auxtrace_record *itr) evlist__for_each_entry(btsr->evlist, evsel) { if (evsel->attr.type == btsr->intel_bts_pmu->type) - return perf_evsel__enable(evsel); + return evsel__enable(evsel); } return -EINVAL; } diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index e4dfe8c3d5c3..e3dacb2bf01b 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -801,7 +801,7 @@ static int intel_pt_snapshot_finish(struct auxtrace_record *itr) evlist__for_each_entry(ptr->evlist, evsel) { if (evsel->attr.type == ptr->intel_pt_pmu->type) - return perf_evsel__enable(evsel); + return evsel__enable(evsel); } return -EINVAL; } diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 0f74ca103c41..6f9995df2c27 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -77,7 +77,7 @@ static int attach__current_disabled(struct evlist *evlist) } thread_map__put(threads); - return perf_evsel__enable(evsel) == 0 ? TEST_OK : TEST_FAIL; + return evsel__enable(evsel) == 0 ? TEST_OK : TEST_FAIL; } static int attach__current_enabled(struct evlist *evlist) @@ -104,7 +104,7 @@ static int detach__disable(struct evlist *evlist) { struct evsel *evsel = perf_evlist__last(evlist); - return perf_evsel__enable(evsel); + return evsel__enable(evsel); } static int attach__cpu_disabled(struct evlist *evlist) @@ -133,7 +133,7 @@ static int attach__cpu_disabled(struct evlist *evlist) } cpu_map__put(cpus); - return perf_evsel__enable(evsel); + return evsel__enable(evsel); } static int attach__cpu_enabled(struct evlist *evlist) diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index ac5da4fd222f..acc4b5ff0cea 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -509,7 +509,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ goto out_err; } - err = perf_evsel__enable(cycles_evsel); + err = evsel__enable(cycles_evsel); if (err) { pr_debug("perf_evlist__disable_event failed!\n"); goto out_err; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4627cc47de3e..e87c43e339d0 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -363,7 +363,7 @@ void perf_evlist__enable(struct evlist *evlist) evlist__for_each_entry(evlist, pos) { if (!perf_evsel__is_group_leader(pos) || !pos->fd) continue; - perf_evsel__enable(pos); + evsel__enable(pos); } evlist->enabled = true; @@ -1927,7 +1927,7 @@ int perf_evlist__start_sb_thread(struct evlist *evlist, goto out_delete_evlist; evlist__for_each_entry(evlist, counter) { - if (perf_evsel__enable(counter)) + if (evsel__enable(counter)) goto out_delete_evlist; } diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index f365d0685268..7adae1736191 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1234,7 +1234,7 @@ int perf_evsel__append_addr_filter(struct evsel *evsel, const char *filter) return perf_evsel__append_filter(evsel, "%s,%s", filter); } -int perf_evsel__enable(struct evsel *evsel) +int evsel__enable(struct evsel *evsel) { int err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, 0); diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index d43409bb07c5..fa26c583a606 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -295,7 +295,7 @@ int perf_evsel__append_tp_filter(struct evsel *evsel, const char *filter); int perf_evsel__append_addr_filter(struct evsel *evsel, const char *filter); int perf_evsel__apply_filter(struct evsel *evsel, const char *filter); -int perf_evsel__enable(struct evsel *evsel); +int evsel__enable(struct evsel *evsel); int perf_evsel__disable(struct evsel *evsel); int perf_evsel__open_per_cpu(struct evsel *evsel, -- cgit v1.2.3-59-g8ed1b From 9a10bb22897ae9c2aa0ac9c2071f539f406ef942 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:03 +0200 Subject: perf evsel: Rename perf_evsel__disable() to evsel__disable() Renaming perf_evsel__disable() to evsel__disable(), so we don't have a name clash when we add perf_evsel__disable() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-17-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 2 +- tools/perf/arch/x86/util/intel-bts.c | 2 +- tools/perf/arch/x86/util/intel-pt.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/switch-tracking.c | 4 ++-- tools/perf/util/evlist.c | 2 +- tools/perf/util/evsel.c | 2 +- tools/perf/util/evsel.h | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 4b70b9504603..268fcb31cd53 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -821,7 +821,7 @@ static int cs_etm_snapshot_start(struct auxtrace_record *itr) evlist__for_each_entry(ptr->evlist, evsel) { if (evsel->attr.type == ptr->cs_etm_pmu->type) - return perf_evsel__disable(evsel); + return evsel__disable(evsel); } return -EINVAL; } diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index d27832fcb34c..8b0a53d748c9 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -317,7 +317,7 @@ static int intel_bts_snapshot_start(struct auxtrace_record *itr) evlist__for_each_entry(btsr->evlist, evsel) { if (evsel->attr.type == btsr->intel_bts_pmu->type) - return perf_evsel__disable(evsel); + return evsel__disable(evsel); } return -EINVAL; } diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index e3dacb2bf01b..4ce157a4e5e2 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -788,7 +788,7 @@ static int intel_pt_snapshot_start(struct auxtrace_record *itr) evlist__for_each_entry(ptr->evlist, evsel) { if (evsel->attr.type == ptr->intel_pt_pmu->type) - return perf_evsel__disable(evsel); + return evsel__disable(evsel); } return -EINVAL; } diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 89ae4737ef74..95ecefa9ff7e 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2400,7 +2400,7 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel, ++trace->nr_events_printed; if (evsel->max_events != ULONG_MAX && ++evsel->nr_events_printed == evsel->max_events) { - perf_evsel__disable(evsel); + evsel__disable(evsel); perf_evsel__close(evsel); } } diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index cdc19bcc7523..1976ccb3c812 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -129,7 +129,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un evsel = perf_evlist__last(evlist); - CHECK__(perf_evsel__disable(evsel)); + CHECK__(evsel__disable(evsel)); comm = "Test COMM 2"; CHECK__(prctl(PR_SET_NAME, (unsigned long)comm, 0, 0, 0)); diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index acc4b5ff0cea..5662dc1c6bd3 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -464,7 +464,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ perf_evlist__enable(evlist); - err = perf_evsel__disable(cpu_clocks_evsel); + err = evsel__disable(cpu_clocks_evsel); if (err) { pr_debug("perf_evlist__disable_event failed!\n"); goto out_err; @@ -483,7 +483,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ goto out_err; } - err = perf_evsel__disable(cycles_evsel); + err = evsel__disable(cycles_evsel); if (err) { pr_debug("perf_evlist__disable_event failed!\n"); goto out_err; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index e87c43e339d0..9461583c53d9 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -350,7 +350,7 @@ void perf_evlist__disable(struct evlist *evlist) evlist__for_each_entry(evlist, pos) { if (pos->disabled || !perf_evsel__is_group_leader(pos) || !pos->fd) continue; - perf_evsel__disable(pos); + evsel__disable(pos); } evlist->enabled = false; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 7adae1736191..855d286298eb 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1244,7 +1244,7 @@ int evsel__enable(struct evsel *evsel) return err; } -int perf_evsel__disable(struct evsel *evsel) +int evsel__disable(struct evsel *evsel) { int err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_DISABLE, 0); /* diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index fa26c583a606..c338ce14e8aa 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -296,7 +296,7 @@ int perf_evsel__append_addr_filter(struct evsel *evsel, const char *filter); int perf_evsel__apply_filter(struct evsel *evsel, const char *filter); int evsel__enable(struct evsel *evsel); -int perf_evsel__disable(struct evsel *evsel); +int evsel__disable(struct evsel *evsel); int perf_evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus); -- cgit v1.2.3-59-g8ed1b From 24e376b24582648d363df4e0a6bcc2ffcecd211e Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:04 +0200 Subject: perf evsel: Rename perf_evsel__apply_filter() to evsel__apply_filter() Rename perf_evsel__apply_filter() to evsel__apply_filter(), so we don't have a name clash when we add perf_evsel__apply_filter() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-18-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 2 +- tools/perf/util/evsel.c | 2 +- tools/perf/util/evsel.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 9461583c53d9..e71c3cc93924 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1158,7 +1158,7 @@ int perf_evlist__apply_filters(struct evlist *evlist, struct evsel **err_evsel) * filters only work for tracepoint event, which doesn't have cpu limit. * So evlist and evsel should always be same. */ - err = perf_evsel__apply_filter(evsel, evsel->filter); + err = evsel__apply_filter(evsel, evsel->filter); if (err) { *err_evsel = evsel; break; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 855d286298eb..5aeb7260c8e1 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1187,7 +1187,7 @@ static int perf_evsel__run_ioctl(struct evsel *evsel, return 0; } -int perf_evsel__apply_filter(struct evsel *evsel, const char *filter) +int evsel__apply_filter(struct evsel *evsel, const char *filter) { return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_SET_FILTER, diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index c338ce14e8aa..35f7e7ff3c5e 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -294,7 +294,7 @@ int perf_evsel__set_filter(struct evsel *evsel, const char *filter); int perf_evsel__append_tp_filter(struct evsel *evsel, const char *filter); int perf_evsel__append_addr_filter(struct evsel *evsel, const char *filter); -int perf_evsel__apply_filter(struct evsel *evsel, const char *filter); +int evsel__apply_filter(struct evsel *evsel, const char *filter); int evsel__enable(struct evsel *evsel); int evsel__disable(struct evsel *evsel); -- cgit v1.2.3-59-g8ed1b From b49aca3e9ce60d00e5bf0694b2ff4c2cd40809e5 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:05 +0200 Subject: perf evsel: Rename perf_evsel__cpus() to evsel__cpus() Rename perf_evsel__cpus() to evsel__cpus(), so we don't have a name clash when we add perf_evsel__cpus() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-19-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.h | 4 ++-- tools/perf/util/stat-display.c | 6 +++--- tools/perf/util/stat.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 35f7e7ff3c5e..5fec1ca64f58 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -197,14 +197,14 @@ struct target; struct thread_map; struct record_opts; -static inline struct perf_cpu_map *perf_evsel__cpus(struct evsel *evsel) +static inline struct perf_cpu_map *evsel__cpus(struct evsel *evsel) { return evsel->cpus; } static inline int perf_evsel__nr_cpus(struct evsel *evsel) { - return perf_evsel__cpus(evsel)->nr; + return evsel__cpus(evsel)->nr; } void perf_counts_values__scale(struct perf_counts_values *count, diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index cdfceb5b4d72..f7666d2e6e0c 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -109,7 +109,7 @@ static void aggr_printout(struct perf_stat_config *config, } else { fprintf(config->output, "CPU%*d%s ", config->csv_output ? 0 : -5, - perf_evsel__cpus(evsel)->map[id], + evsel__cpus(evsel)->map[id], config->csv_sep); } break; @@ -325,7 +325,7 @@ static int first_shadow_cpu(struct perf_stat_config *config, return 0; for (i = 0; i < perf_evsel__nr_cpus(evsel); i++) { - int cpu2 = perf_evsel__cpus(evsel)->map[i]; + int cpu2 = evsel__cpus(evsel)->map[i]; if (config->aggr_get_id(config, evlist->cpus, cpu2) == id) return cpu2; @@ -593,7 +593,7 @@ static void aggr_cb(struct perf_stat_config *config, for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { struct perf_counts_values *counts; - s2 = config->aggr_get_id(config, perf_evsel__cpus(counter), cpu); + s2 = config->aggr_get_id(config, evsel__cpus(counter), cpu); if (s2 != ad->id) continue; if (first) diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index efd934ec02c3..63f7815ceb4f 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -215,7 +215,7 @@ static int check_per_pkg(struct evsel *counter, struct perf_counts_values *vals, int cpu, bool *skip) { unsigned long *mask = counter->per_pkg_mask; - struct perf_cpu_map *cpus = perf_evsel__cpus(counter); + struct perf_cpu_map *cpus = evsel__cpus(counter); int s; *skip = false; @@ -483,7 +483,7 @@ int create_perf_stat_counter(struct evsel *evsel, } if (target__has_cpu(target) && !target__has_per_thread(target)) - return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel)); + return perf_evsel__open_per_cpu(evsel, evsel__cpus(evsel)); return perf_evsel__open_per_thread(evsel, evsel->threads); } -- cgit v1.2.3-59-g8ed1b From 474ddc4c46025a615d0ea791d37ce9038fa20229 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:06 +0200 Subject: perf evlist: Rename perf_evlist__open() to evlist__open() Rename perf_evlist__open() to evlist__open(), so we don't have a name clash when we add perf_evlist__open() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-20-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/event-times.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/util/evlist.c | 2 +- tools/perf/util/evlist.h | 2 +- tools/perf/util/python.c | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index 09b6cef76f5b..ea4cf1d367a6 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -83,7 +83,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe evsel->attr.disabled = 1; evsel->attr.enable_on_exec = 0; - CHECK__(perf_evlist__open(evlist)); + CHECK__(evlist__open(evlist)); CHECK__(perf_evlist__mmap(evlist, UINT_MAX)); diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 8f54bdfb5743..85604d117558 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1048,7 +1048,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm) attr->disabled = 1; } - err = perf_evlist__open(evlist); + err = evlist__open(evlist); if (err < 0) { printf("Couldn't create the events: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 95ecefa9ff7e..e508fdb77099 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3342,7 +3342,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) } } - err = perf_evlist__open(evlist); + err = evlist__open(evlist); if (err < 0) goto out_error_open; diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index ef3c6db2fae4..8de2d6ad93ce 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -125,7 +125,7 @@ int test__backward_ring_buffer(struct test *test __maybe_unused, int subtest __m perf_evlist__config(evlist, &opts, NULL); - err = perf_evlist__open(evlist); + err = evlist__open(evlist); if (err < 0) { pr_debug("perf_evlist__open: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 313ff1aadd9c..b41c41482283 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -157,7 +157,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void), perf_evlist__config(evlist, &opts, NULL); - err = perf_evlist__open(evlist); + err = evlist__open(evlist); if (err < 0) { pr_debug("perf_evlist__open: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 1c7f092a7388..23abc775a69c 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -646,7 +646,7 @@ static int do_test_code_reading(bool try_kcore) evsel->attr.disabled = 1; evsel->attr.enable_on_exec = 0; - ret = perf_evlist__open(evlist); + ret = evlist__open(evlist); if (ret < 0) { if (!excl_kernel) { excl_kernel = true; diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 6f9995df2c27..bf00d3d792fb 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -38,7 +38,7 @@ static int attach__enable_on_exec(struct evlist *evlist) evsel->attr.enable_on_exec = 1; - err = perf_evlist__open(evlist); + err = evlist__open(evlist); if (err < 0) { pr_debug("perf_evlist__open: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 1976ccb3c812..c55bc062e200 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -94,7 +94,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un evsel->attr.disabled = 1; evsel->attr.enable_on_exec = 0; - if (perf_evlist__open(evlist) < 0) { + if (evlist__open(evlist) < 0) { pr_debug("Unable to open dummy and cycles event\n"); err = TEST_SKIP; goto out_err; diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index f822c3c181f3..233447af9d03 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -60,7 +60,7 @@ int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest thread_map__set_pid(evlist->threads, 0, getpid()); - err = perf_evlist__open(evlist); + err = evlist__open(evlist); if (err < 0) { pr_debug("perf_evlist__open: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 779d5996428b..f5d1e7f1b58b 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -130,7 +130,7 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus * Call sys_perf_event_open on all the fds on all the evsels, * grouping them if asked to. */ - err = perf_evlist__open(evlist); + err = evlist__open(evlist); if (err < 0) { pr_debug("perf_evlist__open: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 3ab11291174c..528a2dff06e0 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -69,7 +69,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) cpus = NULL; threads = NULL; - if (perf_evlist__open(evlist)) { + if (evlist__open(evlist)) { const char *knob = "/proc/sys/kernel/perf_event_max_sample_rate"; err = -errno; diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 5662dc1c6bd3..47f9895ba807 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -450,7 +450,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ } } - if (perf_evlist__open(evlist) < 0) { + if (evlist__open(evlist) < 0) { pr_debug("Not supported\n"); err = 0; goto out; diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 698ee5369c02..d17effdd55c8 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -95,7 +95,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused evsel->attr.wakeup_events = 1; evsel->attr.exclude_kernel = 1; - err = perf_evlist__open(evlist); + err = evlist__open(evlist); if (err < 0) { pr_debug("Couldn't open the evlist: %s\n", str_error_r(-err, sbuf, sizeof(sbuf))); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index e71c3cc93924..7d44e05dfaa4 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1387,7 +1387,7 @@ out_put: goto out; } -int perf_evlist__open(struct evlist *evlist) +int evlist__open(struct evlist *evlist) { struct evsel *evsel; int err; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index b3a44e2eed08..f4b3152c879e 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -146,7 +146,7 @@ void perf_evlist__toggle_bkw_mmap(struct evlist *evlist, enum bkw_mmap_state sta void perf_evlist__mmap_consume(struct evlist *evlist, int idx); -int perf_evlist__open(struct evlist *evlist); +int evlist__open(struct evlist *evlist); void perf_evlist__close(struct evlist *evlist); struct callchain_param; diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 3eb7348d29f8..cc4af99ab190 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -1059,7 +1059,7 @@ static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist, if (group) perf_evlist__set_leader(evlist); - if (perf_evlist__open(evlist) < 0) { + if (evlist__open(evlist) < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } -- cgit v1.2.3-59-g8ed1b From 750b4edeb0527414fb17b0ee2a76d2dbbd9a199d Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:07 +0200 Subject: perf evlist: Rename perf_evlist__close() to evlist__close() Rename perf_evlist__close() to evlist__close(), so we don't have a name clash when we add perf_evlist__close() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-21-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-stat.c | 4 ++-- tools/perf/util/evlist.c | 6 +++--- tools/perf/util/evlist.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 85604d117558..6a0573a9c16b 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1058,7 +1058,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm) if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages) < 0) { ui__error("Failed to mmap the events: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); - perf_evlist__close(evlist); + evlist__close(evlist); goto out; } diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index d28d4d71d9b7..bdfe138f7aed 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -613,7 +613,7 @@ try_again: * later the evsel_list will be closed after. */ if (!STAT_RECORD) - perf_evlist__close(evsel_list); + evlist__close(evsel_list); return WEXITSTATUS(status); } @@ -2003,7 +2003,7 @@ int cmd_stat(int argc, const char **argv) perf_session__write_header(perf_stat.session, evsel_list, fd, true); } - perf_evlist__close(evsel_list); + evlist__close(evsel_list); perf_session__delete(perf_stat.session); } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 7d44e05dfaa4..67c288f467f6 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -140,7 +140,7 @@ void evlist__delete(struct evlist *evlist) return; perf_evlist__munmap(evlist); - perf_evlist__close(evlist); + evlist__close(evlist); cpu_map__put(evlist->cpus); thread_map__put(evlist->threads); evlist->cpus = NULL; @@ -1348,7 +1348,7 @@ void perf_evlist__set_selected(struct evlist *evlist, evlist->selected = evsel; } -void perf_evlist__close(struct evlist *evlist) +void evlist__close(struct evlist *evlist) { struct evsel *evsel; @@ -1412,7 +1412,7 @@ int evlist__open(struct evlist *evlist) return 0; out_err: - perf_evlist__close(evlist); + evlist__close(evlist); errno = -err; return err; } diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index f4b3152c879e..47e9d26b6774 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -147,7 +147,7 @@ void perf_evlist__toggle_bkw_mmap(struct evlist *evlist, enum bkw_mmap_state sta void perf_evlist__mmap_consume(struct evlist *evlist, int idx); int evlist__open(struct evlist *evlist); -void perf_evlist__close(struct evlist *evlist); +void evlist__close(struct evlist *evlist); struct callchain_param; -- cgit v1.2.3-59-g8ed1b From 1c87f1654cc315fbeae0238a8dbf5bf3c498f3af Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:08 +0200 Subject: perf evlist: Rename perf_evlist__enable() to evlist__enable() Rename perf_evlist__enable() to evlist__enable(), so we don't have a name clash when we add perf_evlist__enable() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-22-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-record.c | 4 ++-- tools/perf/builtin-stat.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 4 ++-- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/keep-tracking.c | 4 ++-- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/util/evlist.c | 4 ++-- tools/perf/util/evlist.h | 2 +- 16 files changed, 20 insertions(+), 20 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index ea4cf1d367a6..aa5a5c972ce5 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -97,7 +97,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe goto out_err; } - perf_evlist__enable(evlist); + evlist__enable(evlist); comm1 = "Test COMM 1"; CHECK__(prctl(PR_SET_NAME, (unsigned long)comm1, 0, 0, 0)); diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 6a0573a9c16b..9207bd49583e 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -972,7 +972,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm) goto out; /* everything is good - enable the events and process */ - perf_evlist__enable(kvm->evlist); + evlist__enable(kvm->evlist); while (!done) { struct fdarray *fda = &kvm->evlist->pollfd; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 7f933997b6d0..8e20ead0ddbe 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1453,7 +1453,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) * so don't spoil it by prematurely enabling them. */ if (!target__none(&opts->target) && !opts->initial_delay) - perf_evlist__enable(rec->evlist); + evlist__enable(rec->evlist); /* * Let the child rip @@ -1506,7 +1506,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) if (opts->initial_delay) { usleep(opts->initial_delay * USEC_PER_MSEC); - perf_evlist__enable(rec->evlist); + evlist__enable(rec->evlist); } trigger_ready(&auxtrace_snapshot_trigger); diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index bdfe138f7aed..c0e9d94b6dd5 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -362,7 +362,7 @@ static void enable_counters(void) * - we have initial delay configured */ if (!target__none(&target) || stat_config.initial_delay) - perf_evlist__enable(evsel_list); + evlist__enable(evsel_list); } static void disable_counters(void) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 5886389f6a40..b103f1ba01cb 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1255,7 +1255,7 @@ static int __cmd_top(struct perf_top *top) * so leave the check here. */ if (!target__none(&opts->target)) - perf_evlist__enable(top->evlist); + evlist__enable(top->evlist); ret = -1; if (pthread_create(&thread_process, NULL, process_thread, top)) { diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index e508fdb77099..46fab1ff92dc 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3402,14 +3402,14 @@ static int trace__run(struct trace *trace, int argc, const char **argv) goto out_error_mmap; if (!target__none(&trace->opts.target) && !trace->opts.initial_delay) - perf_evlist__enable(evlist); + evlist__enable(evlist); if (forks) perf_evlist__start_workload(evlist); if (trace->opts.initial_delay) { usleep(trace->opts.initial_delay * 1000); - perf_evlist__enable(evlist); + evlist__enable(evlist); } trace->multiple_threads = thread_map__pid(evlist->threads, 0) == -1 || diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 8de2d6ad93ce..f4b45702821d 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -68,7 +68,7 @@ static int do_test(struct evlist *evlist, int mmap_pages, return TEST_FAIL; } - perf_evlist__enable(evlist); + evlist__enable(evlist); testcase(); perf_evlist__disable(evlist); diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index b41c41482283..92fed94f4b6c 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -171,7 +171,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void), goto out_delete_evlist; } - perf_evlist__enable(evlist); + evlist__enable(evlist); (*func)(); perf_evlist__disable(evlist); diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 23abc775a69c..8d38e001160d 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -680,7 +680,7 @@ static int do_test_code_reading(bool try_kcore) goto out_put; } - perf_evlist__enable(evlist); + evlist__enable(evlist); do_something(); diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index c55bc062e200..c333b9c765e8 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -107,7 +107,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un * enabled. */ - perf_evlist__enable(evlist); + evlist__enable(evlist); comm = "Test COMM 1"; CHECK__(prctl(PR_SET_NAME, (unsigned long)comm, 0, 0, 0)); @@ -125,7 +125,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un * disabled with the dummy event still enabled. */ - perf_evlist__enable(evlist); + evlist__enable(evlist); evsel = perf_evlist__last(evlist); diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index 233447af9d03..c7182b7840e5 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -74,7 +74,7 @@ int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest goto out_delete_evlist; } - perf_evlist__enable(evlist); + evlist__enable(evlist); /* * Generate the event: diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index f5d1e7f1b58b..67b388e92cba 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -153,7 +153,7 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus * Now that all is properly set up, enable the events, they will * count just on workload.pid, which will start... */ - perf_evlist__enable(evlist); + evlist__enable(evlist); /* * Now! diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 528a2dff06e0..4ab316c04ce7 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -86,7 +86,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) goto out_delete_evlist; } - perf_evlist__enable(evlist); + evlist__enable(evlist); /* collect samples */ for (i = 0; i < NR_LOOPS; i++) diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 47f9895ba807..ea214313f22b 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -462,7 +462,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ goto out_err; } - perf_evlist__enable(evlist); + evlist__enable(evlist); err = evsel__disable(cpu_clocks_evsel); if (err) { diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 67c288f467f6..94825c37a35f 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -356,7 +356,7 @@ void perf_evlist__disable(struct evlist *evlist) evlist->enabled = false; } -void perf_evlist__enable(struct evlist *evlist) +void evlist__enable(struct evlist *evlist) { struct evsel *pos; @@ -371,7 +371,7 @@ void perf_evlist__enable(struct evlist *evlist) void perf_evlist__toggle_enable(struct evlist *evlist) { - (evlist->enabled ? perf_evlist__disable : perf_evlist__enable)(evlist); + (evlist->enabled ? perf_evlist__disable : evlist__enable)(evlist); } static int perf_evlist__enable_event_cpu(struct evlist *evlist, diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 47e9d26b6774..ab48bbfbca41 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -185,7 +185,7 @@ void perf_evlist__munmap(struct evlist *evlist); size_t perf_evlist__mmap_size(unsigned long pages); void perf_evlist__disable(struct evlist *evlist); -void perf_evlist__enable(struct evlist *evlist); +void evlist__enable(struct evlist *evlist); void perf_evlist__toggle_enable(struct evlist *evlist); int perf_evlist__enable_event_idx(struct evlist *evlist, -- cgit v1.2.3-59-g8ed1b From e74676debaae7dcce20a34817ef145478887ba95 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:09 +0200 Subject: perf evlist: Rename perf_evlist__disable() to evlist__disable() Rename perf_evlist__disable() to evlist__disable(), so we don't have a name clash when we add perf_evlist__disable() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-23-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-stat.c | 2 +- tools/perf/builtin-trace.c | 4 ++-- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/keep-tracking.c | 6 +++--- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 4 ++-- tools/perf/util/evlist.c | 4 ++-- tools/perf/util/evlist.h | 2 +- 13 files changed, 18 insertions(+), 18 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index aa5a5c972ce5..8b70e9ee341a 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -107,7 +107,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe comm2 = "Test COMM 2"; CHECK__(prctl(PR_SET_NAME, (unsigned long)comm2, 0, 0, 0)); - perf_evlist__disable(evlist); + evlist__disable(evlist); for (i = 0; i < evlist->nr_mmaps; i++) { md = &evlist->mmap[i]; diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 9207bd49583e..3370eba0d3f3 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -993,7 +993,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm) err = fdarray__poll(fda, 100); } - perf_evlist__disable(kvm->evlist); + evlist__disable(kvm->evlist); if (err == 0) { sort_result(kvm); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 8e20ead0ddbe..c0962ddfad04 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1605,7 +1605,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) */ if (done && !disabled && !target__none(&opts->target)) { trigger_off(&auxtrace_snapshot_trigger); - perf_evlist__disable(rec->evlist); + evlist__disable(rec->evlist); disabled = true; } } diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index c0e9d94b6dd5..36e66a4f3c57 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -373,7 +373,7 @@ static void disable_counters(void) * from counting before reading their constituent counters. */ if (!target__none(&target)) - perf_evlist__disable(evsel_list); + evlist__disable(evsel_list); } static volatile int workload_exec_errno; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 46fab1ff92dc..51d142594a12 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3451,7 +3451,7 @@ again: goto out_disable; if (done && !draining) { - perf_evlist__disable(evlist); + evlist__disable(evlist); draining = true; } } @@ -3477,7 +3477,7 @@ again: out_disable: thread__zput(trace->current); - perf_evlist__disable(evlist); + evlist__disable(evlist); if (trace->sort_events) ordered_events__flush(&trace->oe.data, OE_FLUSH__FINAL); diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index f4b45702821d..9bdf66139099 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -70,7 +70,7 @@ static int do_test(struct evlist *evlist, int mmap_pages, evlist__enable(evlist); testcase(); - perf_evlist__disable(evlist); + evlist__disable(evlist); err = count_samples(evlist, sample_count, comm_count); perf_evlist__munmap(evlist); diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 92fed94f4b6c..e16f927f38b6 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -173,7 +173,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void), evlist__enable(evlist); (*func)(); - perf_evlist__disable(evlist); + evlist__disable(evlist); for (i = 0; i < evlist->nr_mmaps; i++) { union perf_event *event; diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 8d38e001160d..ec4b0bf28270 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -684,7 +684,7 @@ static int do_test_code_reading(bool try_kcore) do_something(); - perf_evlist__disable(evlist); + evlist__disable(evlist); ret = process_events(machine, evlist, &state); if (ret < 0) diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index c333b9c765e8..7bfc859971e5 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -112,7 +112,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un comm = "Test COMM 1"; CHECK__(prctl(PR_SET_NAME, (unsigned long)comm, 0, 0, 0)); - perf_evlist__disable(evlist); + evlist__disable(evlist); found = find_comm(evlist, comm); if (found != 1) { @@ -134,7 +134,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un comm = "Test COMM 2"; CHECK__(prctl(PR_SET_NAME, (unsigned long)comm, 0, 0, 0)); - perf_evlist__disable(evlist); + evlist__disable(evlist); found = find_comm(evlist, comm); if (found != 1) { @@ -146,7 +146,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un out_err: if (evlist) { - perf_evlist__disable(evlist); + evlist__disable(evlist); evlist__delete(evlist); } else { cpu_map__put(cpus); diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 4ab316c04ce7..ba033a6e6c0f 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -92,7 +92,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) for (i = 0; i < NR_LOOPS; i++) tmp++; - perf_evlist__disable(evlist); + evlist__disable(evlist); md = &evlist->mmap[0]; if (perf_mmap__read_init(md) < 0) diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index ea214313f22b..d5537edb47db 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -528,7 +528,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ goto out_err; } - perf_evlist__disable(evlist); + evlist__disable(evlist); switch_tracking.switch_evsel = switch_evsel; switch_tracking.cycles_evsel = cycles_evsel; @@ -566,7 +566,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ } out: if (evlist) { - perf_evlist__disable(evlist); + evlist__disable(evlist); evlist__delete(evlist); } else { cpu_map__put(cpus); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 94825c37a35f..1bedec28e58f 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -343,7 +343,7 @@ static int perf_evlist__nr_threads(struct evlist *evlist, return thread_map__nr(evlist->threads); } -void perf_evlist__disable(struct evlist *evlist) +void evlist__disable(struct evlist *evlist) { struct evsel *pos; @@ -371,7 +371,7 @@ void evlist__enable(struct evlist *evlist) void perf_evlist__toggle_enable(struct evlist *evlist) { - (evlist->enabled ? perf_evlist__disable : evlist__enable)(evlist); + (evlist->enabled ? evlist__disable : evlist__enable)(evlist); } static int perf_evlist__enable_event_cpu(struct evlist *evlist, diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index ab48bbfbca41..99621c056d09 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -184,7 +184,7 @@ void perf_evlist__munmap(struct evlist *evlist); size_t perf_evlist__mmap_size(unsigned long pages); -void perf_evlist__disable(struct evlist *evlist); +void evlist__disable(struct evlist *evlist); void evlist__enable(struct evlist *evlist); void perf_evlist__toggle_enable(struct evlist *evlist); -- cgit v1.2.3-59-g8ed1b From 3143504918105156d03e8f927e127f7b9ea260d2 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:10 +0200 Subject: libperf: Make libperf.a part of the perf build Add an empty libperf.a under tools/perf/lib and link it with perf. It can also be built separately with: $ cd tools/perf/lib && make CC core.o LD libperf-in.o AR libperf.a LINK libperf.so Committer testing: $ make O=/tmp/build/perf -C tools/perf/lib/ make: Entering directory '/home/acme/git/perf/tools/perf/lib' LINK /tmp/build/perf/libperf.so make: Leaving directory '/home/acme/git/perf/tools/perf/lib' $ ls -la /tmp/build/perf/libperf.so -rwxrwxr-x. 1 acme acme 16232 Jul 22 15:30 /tmp/build/perf/libperf.so $ file /tmp/build/perf/libperf.so /tmp/build/perf/libperf.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=7a51d227d871b381ddb686dcf94145c4dd908221, not stripped $ git status tools/perf On branch perf/core nothing to commit, working tree clean $ $ ls -lart tools/perf/lib/ total 16 drwxrwxr-x. 16 acme acme 4096 Jul 22 15:29 .. -rw-rw-r--. 1 acme acme 1633 Jul 22 15:29 Makefile -rw-rw-r--. 1 acme acme 0 Jul 22 15:29 core.c -rw-rw-r--. 1 acme acme 20 Jul 22 15:29 Build drwxrwxr-x. 2 acme acme 4096 Jul 22 15:29 . $ Committer notes: Need to add -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi to tools/perf/lib/Makefile's INCLUDE variable to pick up the latest versions of kernel headers, even in older systems, this is in line with what is in tools/lib/bpf/Makefile. Signed-off-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-24-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.config | 1 + tools/perf/Makefile.perf | 30 ++++++++++--------- tools/perf/lib/Build | 1 + tools/perf/lib/Makefile | 74 ++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/lib/core.c | 0 5 files changed, 92 insertions(+), 14 deletions(-) create mode 100644 tools/perf/lib/Build create mode 100644 tools/perf/lib/Makefile create mode 100644 tools/perf/lib/core.c (limited to 'tools') diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 89ac5a1f1550..e4988f49ea79 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -277,6 +277,7 @@ ifeq ($(DEBUG),0) endif endif +INC_FLAGS += -I$(src-perf)/lib/include INC_FLAGS += -I$(src-perf)/util/include INC_FLAGS += -I$(src-perf)/arch/$(SRCARCH)/include INC_FLAGS += -I$(srctree)/tools/include/uapi diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 0fffd2bb6cd9..6e7e7d44ffac 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -224,6 +224,7 @@ LIB_DIR = $(srctree)/tools/lib/api/ TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/ BPF_DIR = $(srctree)/tools/lib/bpf/ SUBCMD_DIR = $(srctree)/tools/lib/subcmd/ +LIBPERF_DIR = $(srctree)/tools/perf/lib/ # Set FEATURE_TESTS to 'all' so all possible feature checkers are executed. # Without this setting the output feature dump file misses some features, for @@ -272,6 +273,7 @@ ifneq ($(OUTPUT),) TE_PATH=$(OUTPUT) BPF_PATH=$(OUTPUT) SUBCMD_PATH=$(OUTPUT) + LIBPERF_PATH=$(OUTPUT) ifneq ($(subdir),) API_PATH=$(OUTPUT)/../lib/api/ else @@ -282,6 +284,7 @@ else API_PATH=$(LIB_DIR) BPF_PATH=$(BPF_DIR) SUBCMD_PATH=$(SUBCMD_DIR) + LIBPERF_PATH=$(LIBPERF_DIR) endif LIBTRACEEVENT = $(TE_PATH)libtraceevent.a @@ -303,6 +306,8 @@ LIBBPF = $(BPF_PATH)libbpf.a LIBSUBCMD = $(SUBCMD_PATH)libsubcmd.a +LIBPERF = $(LIBPERF_PATH)libperf.a + # python extension build directories PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/ PYTHON_EXTBUILD_LIB := $(PYTHON_EXTBUILD)lib/ @@ -348,9 +353,7 @@ endif export PERL_PATH -LIBPERF_A=$(OUTPUT)libperf.a - -PERFLIBS = $(LIBAPI) $(LIBTRACEEVENT) $(LIBSUBCMD) +PERFLIBS = $(LIBAPI) $(LIBTRACEEVENT) $(LIBSUBCMD) $(LIBPERF) ifndef NO_LIBBPF PERFLIBS += $(LIBBPF) endif @@ -583,8 +586,6 @@ JEVENTS_IN := $(OUTPUT)pmu-events/jevents-in.o PMU_EVENTS_IN := $(OUTPUT)pmu-events/pmu-events-in.o -LIBPERF_IN := $(OUTPUT)libperf-in.o - export JEVENTS build := -f $(srctree)/tools/build/Makefile.build dir=. obj @@ -601,12 +602,9 @@ $(JEVENTS): $(JEVENTS_IN) $(PMU_EVENTS_IN): $(JEVENTS) FORCE $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=pmu-events obj=pmu-events -$(LIBPERF_IN): prepare FORCE - $(Q)$(MAKE) $(build)=libperf - -$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(PMU_EVENTS_IN) $(LIBPERF_IN) $(LIBTRACEEVENT_DYNAMIC_LIST) +$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(PMU_EVENTS_IN) $(LIBTRACEEVENT_DYNAMIC_LIST) $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS) \ - $(PERF_IN) $(PMU_EVENTS_IN) $(LIBPERF_IN) $(LIBS) -o $@ + $(PERF_IN) $(PMU_EVENTS_IN) $(LIBS) -o $@ $(GTK_IN): FORCE $(Q)$(MAKE) $(build)=gtk @@ -727,9 +725,6 @@ endif $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h) -$(LIBPERF_A): $(LIBPERF_IN) - $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIBPERF_IN) $(LIB_OBJS) - LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ) 'EXTRA_CFLAGS=$(EXTRA_CFLAGS)' 'LDFLAGS=$(LDFLAGS)' $(LIBTRACEEVENT): FORCE @@ -762,6 +757,13 @@ $(LIBBPF)-clean: $(call QUIET_CLEAN, libbpf) $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) clean >/dev/null +$(LIBPERF): FORCE + $(Q)$(MAKE) -C $(LIBPERF_DIR) O=$(OUTPUT) $(OUTPUT)libperf.a + +$(LIBPERF)-clean: + $(call QUIET_CLEAN, libperf) + $(Q)$(MAKE) -C $(LIBPERF_DIR) O=$(OUTPUT) clean >/dev/null + $(LIBSUBCMD): FORCE $(Q)$(MAKE) -C $(SUBCMD_DIR) O=$(OUTPUT) $(OUTPUT)libsubcmd.a @@ -948,7 +950,7 @@ config-clean: python-clean: $(python-clean) -clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean config-clean fixdep-clean python-clean +clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean config-clean fixdep-clean python-clean $(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS) $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete $(Q)$(RM) $(OUTPUT).config-detected diff --git a/tools/perf/lib/Build b/tools/perf/lib/Build new file mode 100644 index 000000000000..5196958cec01 --- /dev/null +++ b/tools/perf/lib/Build @@ -0,0 +1 @@ +libperf-y += core.o diff --git a/tools/perf/lib/Makefile b/tools/perf/lib/Makefile new file mode 100644 index 000000000000..33046e7c6a2a --- /dev/null +++ b/tools/perf/lib/Makefile @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) +# Most of this file is copied from tools/lib/bpf/Makefile + +MAKEFLAGS += --no-print-directory + +ifeq ($(srctree),) +srctree := $(patsubst %/,%,$(dir $(CURDIR))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +#$(info Determined 'srctree' to be $(srctree)) +endif + +include $(srctree)/tools/scripts/Makefile.include +include $(srctree)/tools/scripts/Makefile.arch + +ifeq ("$(origin V)", "command line") + VERBOSE = $(V) +endif +ifndef VERBOSE + VERBOSE = 0 +endif + +ifeq ($(VERBOSE),1) + Q = +else + Q = @ +endif + +# Set compile option CFLAGS +ifdef EXTRA_CFLAGS + CFLAGS := $(EXTRA_CFLAGS) +else + CFLAGS := -g -Wall +endif + +INCLUDES = -I$(srctree)/tools/perf/lib/include -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/ -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi + +# Append required CFLAGS +override CFLAGS += $(EXTRA_WARNINGS) +override CFLAGS += -Werror -Wall +override CFLAGS += -fPIC +override CFLAGS += $(INCLUDES) +override CFLAGS += -fvisibility=hidden + +all: + +export srctree OUTPUT CC LD CFLAGS V +include $(srctree)/tools/build/Makefile.include + +LIBPERF_SO := $(OUTPUT)libperf.so +LIBPERF_A := $(OUTPUT)libperf.a +LIBPERF_IN := $(OUTPUT)libperf-in.o + +$(LIBPERF_IN): FORCE + $(Q)$(MAKE) $(build)=libperf + +$(LIBPERF_A): $(LIBPERF_IN) + $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIBPERF_IN) + +$(LIBPERF_SO): $(LIBPERF_IN) + $(QUIET_LINK)$(CC) --shared -Wl,-soname,libperf.so $^ -o $@ + +libs: $(LIBPERF_A) $(LIBPERF_SO) + +all: fixdep + $(Q)$(MAKE) libs + +clean: + $(call QUIET_CLEAN, libperf) $(RM) $(LIBPERF_A) \ + *.o *~ *.a *.so .*.d .*.cmd LIBPERF-CFLAGS + +FORCE: + +.PHONY: all install clean FORCE diff --git a/tools/perf/lib/core.c b/tools/perf/lib/core.c new file mode 100644 index 000000000000..e69de29bb2d1 -- cgit v1.2.3-59-g8ed1b From 47f9bccc79cb067103ad5e9790e0d01c94839429 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:11 +0200 Subject: libperf: Add build version support Add a shared library version, generating the following files: $ ll tools/perf/lib/libperf.so* libperf.so -> libperf.so.0.0.1 libperf.so.0 -> libperf.so.0.0.1 libperf.so.0.0.1 Committer testing: One has to build just libbperf to get this, building perf so far doesn't trigger this, i.e. I tried: $ make O=/tmp/build/perf -C tools/perf And the files above were not created, so one has to do: $ make O=/tmp/build/perf -C tools/perf/lib/ make: Entering directory '/home/acme/git/perf/tools/perf/lib' LINK /tmp/build/perf/libperf.so.0.0.1 make: Leaving directory '/home/acme/git/perf/tools/perf/lib' $ ls -la /tmp/build/perf/*.so.* lrwxrwxrwx. 1 acme acme 16 Jul 22 15:37 /tmp/build/perf/libperf.so.0 -> libperf.so.0.0.1 -rwxrwxr-x. 1 acme acme 16368 Jul 22 15:37 /tmp/build/perf/libperf.so.0.0.1 $ Signed-off-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-25-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/Makefile | 20 +++++++++++++++++--- tools/perf/lib/libperf.map | 4 ++++ 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 tools/perf/lib/libperf.map (limited to 'tools') diff --git a/tools/perf/lib/Makefile b/tools/perf/lib/Makefile index 33046e7c6a2a..cd571ec648ad 100644 --- a/tools/perf/lib/Makefile +++ b/tools/perf/lib/Makefile @@ -1,6 +1,10 @@ # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) # Most of this file is copied from tools/lib/bpf/Makefile +LIBPERF_VERSION = 0 +LIBPERF_PATCHLEVEL = 0 +LIBPERF_EXTRAVERSION = 1 + MAKEFLAGS += --no-print-directory ifeq ($(srctree),) @@ -47,7 +51,13 @@ all: export srctree OUTPUT CC LD CFLAGS V include $(srctree)/tools/build/Makefile.include -LIBPERF_SO := $(OUTPUT)libperf.so +VERSION_SCRIPT := libperf.map + +PATCHLEVEL = $(LIBPERF_PATCHLEVEL) +EXTRAVERSION = $(LIBPERF_EXTRAVERSION) +VERSION = $(LIBPERF_VERSION).$(LIBPERF_PATCHLEVEL).$(LIBPERF_EXTRAVERSION) + +LIBPERF_SO := $(OUTPUT)libperf.so.$(VERSION) LIBPERF_A := $(OUTPUT)libperf.a LIBPERF_IN := $(OUTPUT)libperf-in.o @@ -58,7 +68,11 @@ $(LIBPERF_A): $(LIBPERF_IN) $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIBPERF_IN) $(LIBPERF_SO): $(LIBPERF_IN) - $(QUIET_LINK)$(CC) --shared -Wl,-soname,libperf.so $^ -o $@ + $(QUIET_LINK)$(CC) --shared -Wl,-soname,libperf.so \ + -Wl,--version-script=$(VERSION_SCRIPT) $^ -o $@ + @ln -sf $(@F) $(OUTPUT)libperf.so + @ln -sf $(@F) $(OUTPUT)libperf.so.$(LIBPERF_VERSION) + libs: $(LIBPERF_A) $(LIBPERF_SO) @@ -67,7 +81,7 @@ all: fixdep clean: $(call QUIET_CLEAN, libperf) $(RM) $(LIBPERF_A) \ - *.o *~ *.a *.so .*.d .*.cmd LIBPERF-CFLAGS + *.o *~ *.a *.so *.so.$(VERSION) *.so.$(LIBPERF_VERSION) .*.d .*.cmd LIBPERF-CFLAGS FORCE: diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map new file mode 100644 index 000000000000..a8e913988edf --- /dev/null +++ b/tools/perf/lib/libperf.map @@ -0,0 +1,4 @@ +LIBPERF_0.0.1 { + local: + *; +}; -- cgit v1.2.3-59-g8ed1b From a429dcb8feb60b8500fed81e2275c1944e3091fc Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:12 +0200 Subject: libperf: Add libperf to the python.so build Link libperf.a with python.so. Committer testing: Continues to work: # perf test python 18: 'import perf' in python : Ok # Signed-off-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-26-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 1 + tools/perf/util/setup.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 6e7e7d44ffac..67512a12276b 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -307,6 +307,7 @@ LIBBPF = $(BPF_PATH)libbpf.a LIBSUBCMD = $(SUBCMD_PATH)libsubcmd.a LIBPERF = $(LIBPERF_PATH)libperf.a +export LIBPERF # python extension build directories PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/ diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py index a1a68a2fa917..d48f9cd58964 100644 --- a/tools/perf/util/setup.py +++ b/tools/perf/util/setup.py @@ -48,6 +48,7 @@ build_lib = getenv('PYTHON_EXTBUILD_LIB') build_tmp = getenv('PYTHON_EXTBUILD_TMP') libtraceevent = getenv('LIBTRACEEVENT') libapikfs = getenv('LIBAPI') +libperf = getenv('LIBPERF') ext_sources = [f.strip() for f in open('util/python-ext-sources') if len(f.strip()) > 0 and f[0] != '#'] @@ -64,7 +65,7 @@ perf = Extension('perf', include_dirs = ['util/include'], libraries = extra_libraries, extra_compile_args = cflags, - extra_objects = [libtraceevent, libapikfs], + extra_objects = [libtraceevent, libapikfs, libperf], ) setup(name='perf', -- cgit v1.2.3-59-g8ed1b From 5b7f445d684fc287a2101e29d42d1fee19ae14ff Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:13 +0200 Subject: libperf: Add perf/core.h header Add perf/core.h header to be used in header files coming in the following patches. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-27-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/core.h | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 tools/perf/lib/include/perf/core.h (limited to 'tools') diff --git a/tools/perf/lib/include/perf/core.h b/tools/perf/lib/include/perf/core.h new file mode 100644 index 000000000000..e2e4b43c9131 --- /dev/null +++ b/tools/perf/lib/include/perf/core.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LIBPERF_CORE_H +#define __LIBPERF_CORE_H + +#ifndef LIBPERF_API +#define LIBPERF_API __attribute__((visibility("default"))) +#endif + +#endif /* __LIBPERF_CORE_H */ -- cgit v1.2.3-59-g8ed1b From a1556f8479ed58b8d5a33aef54578bad0165c7e7 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:14 +0200 Subject: libperf: Add debug output support Add the perf_set_print() function to allow setting an output function for warn/info/debug messages. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-28-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/core.c | 34 ++++++++++++++++++++++++++++++++++ tools/perf/lib/include/perf/core.h | 13 +++++++++++++ tools/perf/lib/internal.h | 18 ++++++++++++++++++ tools/perf/lib/libperf.map | 2 ++ 4 files changed, 67 insertions(+) create mode 100644 tools/perf/lib/internal.h (limited to 'tools') diff --git a/tools/perf/lib/core.c b/tools/perf/lib/core.c index e69de29bb2d1..29d5e3348718 100644 --- a/tools/perf/lib/core.c +++ b/tools/perf/lib/core.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#define __printf(a, b) __attribute__((format(printf, a, b))) + +#include +#include +#include +#include "internal.h" + +static int __base_pr(enum libperf_print_level level, const char *format, + va_list args) +{ + return vfprintf(stderr, format, args); +} + +static libperf_print_fn_t __libperf_pr = __base_pr; + +void libperf_set_print(libperf_print_fn_t fn) +{ + __libperf_pr = fn; +} + +__printf(2, 3) +void libperf_print(enum libperf_print_level level, const char *format, ...) +{ + va_list args; + + if (!__libperf_pr) + return; + + va_start(args, format); + __libperf_pr(level, format, args); + va_end(args); +} diff --git a/tools/perf/lib/include/perf/core.h b/tools/perf/lib/include/perf/core.h index e2e4b43c9131..c341a7b2c874 100644 --- a/tools/perf/lib/include/perf/core.h +++ b/tools/perf/lib/include/perf/core.h @@ -2,8 +2,21 @@ #ifndef __LIBPERF_CORE_H #define __LIBPERF_CORE_H +#include + #ifndef LIBPERF_API #define LIBPERF_API __attribute__((visibility("default"))) #endif +enum libperf_print_level { + LIBPERF_WARN, + LIBPERF_INFO, + LIBPERF_DEBUG, +}; + +typedef int (*libperf_print_fn_t)(enum libperf_print_level level, + const char *, va_list ap); + +LIBPERF_API void libperf_set_print(libperf_print_fn_t fn); + #endif /* __LIBPERF_CORE_H */ diff --git a/tools/perf/lib/internal.h b/tools/perf/lib/internal.h new file mode 100644 index 000000000000..dc92f241732e --- /dev/null +++ b/tools/perf/lib/internal.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LIBPERF_INTERNAL_H +#define __LIBPERF_INTERNAL_H + +void libperf_print(enum libperf_print_level level, + const char *format, ...) + __attribute__((format(printf, 2, 3))); + +#define __pr(level, fmt, ...) \ +do { \ + libperf_print(level, "libperf: " fmt, ##__VA_ARGS__); \ +} while (0) + +#define pr_warning(fmt, ...) __pr(LIBPERF_WARN, fmt, ##__VA_ARGS__) +#define pr_info(fmt, ...) __pr(LIBPERF_INFO, fmt, ##__VA_ARGS__) +#define pr_debug(fmt, ...) __pr(LIBPERF_DEBUG, fmt, ##__VA_ARGS__) + +#endif /* __LIBPERF_INTERNAL_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index a8e913988edf..3536242c545c 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -1,4 +1,6 @@ LIBPERF_0.0.1 { + global: + libperf_set_print; local: *; }; -- cgit v1.2.3-59-g8ed1b From 959b83c769389b24d64759f60e64c4c62620ff02 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:15 +0200 Subject: libperf: Add perf_cpu_map struct Add perf_cpu_map struct to libperf. It's added as a declaration into: include/perf/cpumap.h which will be included by users. The perf_cpu_map struct definition is added into: include/internal/cpumap.h which is not to be included by users, but shared within perf and libperf. We tried the total separation of the perf_cpu_map struct in libperf, but it lead to complications and much bigger changes in perf code, so we decided to share the declaration. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-29-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/Build | 1 + tools/perf/lib/cpumap.c | 5 +++++ tools/perf/lib/include/internal/cpumap.h | 13 +++++++++++++ tools/perf/lib/include/perf/cpumap.h | 7 +++++++ tools/perf/util/cpumap.h | 7 +------ 5 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 tools/perf/lib/cpumap.c create mode 100644 tools/perf/lib/include/internal/cpumap.h create mode 100644 tools/perf/lib/include/perf/cpumap.h (limited to 'tools') diff --git a/tools/perf/lib/Build b/tools/perf/lib/Build index 5196958cec01..195b274db49a 100644 --- a/tools/perf/lib/Build +++ b/tools/perf/lib/Build @@ -1 +1,2 @@ libperf-y += core.o +libperf-y += cpumap.o diff --git a/tools/perf/lib/cpumap.c b/tools/perf/lib/cpumap.c new file mode 100644 index 000000000000..86a199c26f20 --- /dev/null +++ b/tools/perf/lib/cpumap.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include +#include diff --git a/tools/perf/lib/include/internal/cpumap.h b/tools/perf/lib/include/internal/cpumap.h new file mode 100644 index 000000000000..53ce95374b05 --- /dev/null +++ b/tools/perf/lib/include/internal/cpumap.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LIBPERF_INTERNAL_CPUMAP_H +#define __LIBPERF_INTERNAL_CPUMAP_H + +#include + +struct perf_cpu_map { + refcount_t refcnt; + int nr; + int map[]; +}; + +#endif /* __LIBPERF_INTERNAL_CPUMAP_H */ diff --git a/tools/perf/lib/include/perf/cpumap.h b/tools/perf/lib/include/perf/cpumap.h new file mode 100644 index 000000000000..8355d3ce7d0c --- /dev/null +++ b/tools/perf/lib/include/perf/cpumap.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LIBPERF_CPUMAP_H +#define __LIBPERF_CPUMAP_H + +struct perf_cpu_map; + +#endif /* __LIBPERF_CPUMAP_H */ diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index 22729beae959..c2ba9ae195f7 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -5,16 +5,11 @@ #include #include #include +#include #include "perf.h" #include "util/debug.h" -struct perf_cpu_map { - refcount_t refcnt; - int nr; - int map[]; -}; - struct perf_cpu_map *cpu_map__new(const char *cpu_list); struct perf_cpu_map *cpu_map__empty_new(int nr); struct perf_cpu_map *cpu_map__dummy_new(void); -- cgit v1.2.3-59-g8ed1b From 397721e06e52d017cfdd403f63284ed0995d4caf Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:16 +0200 Subject: libperf: Add perf_cpu_map__dummy_new() function Move cpu_map__dummy_new() to libperf as perf_cpu_map__dummy_new() function. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-30-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/cpumap.c | 13 +++++++++++++ tools/perf/lib/include/perf/cpumap.h | 4 ++++ tools/perf/lib/libperf.map | 1 + tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/util/cpumap.c | 15 +-------------- tools/perf/util/cpumap.h | 2 +- tools/perf/util/evlist.c | 2 +- tools/perf/util/evsel.c | 2 +- 9 files changed, 24 insertions(+), 19 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/cpumap.c b/tools/perf/lib/cpumap.c index 86a199c26f20..80d587ab95aa 100644 --- a/tools/perf/lib/cpumap.c +++ b/tools/perf/lib/cpumap.c @@ -3,3 +3,16 @@ #include #include #include + +struct perf_cpu_map *perf_cpu_map__dummy_new(void) +{ + struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + sizeof(int)); + + if (cpus != NULL) { + cpus->nr = 1; + cpus->map[0] = -1; + refcount_set(&cpus->refcnt, 1); + } + + return cpus; +} diff --git a/tools/perf/lib/include/perf/cpumap.h b/tools/perf/lib/include/perf/cpumap.h index 8355d3ce7d0c..fa1e5aa9d662 100644 --- a/tools/perf/lib/include/perf/cpumap.h +++ b/tools/perf/lib/include/perf/cpumap.h @@ -2,6 +2,10 @@ #ifndef __LIBPERF_CPUMAP_H #define __LIBPERF_CPUMAP_H +#include + struct perf_cpu_map; +LIBPERF_API struct perf_cpu_map *perf_cpu_map__dummy_new(void); + #endif /* __LIBPERF_CPUMAP_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 3536242c545c..65201c6cbe7e 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -1,6 +1,7 @@ LIBPERF_0.0.1 { global: libperf_set_print; + perf_cpu_map__dummy_new; local: *; }; diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index ba033a6e6c0f..c6d3f4488b73 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -56,7 +56,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) } evlist__add(evlist, evsel); - cpus = cpu_map__dummy_new(); + cpus = perf_cpu_map__dummy_new(); threads = thread_map__new_by_tid(getpid()); if (!cpus || !threads) { err = -ENOMEM; diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index d17effdd55c8..c094fb8cc877 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -63,7 +63,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused * perf_evlist__prepare_workload we'll fill in the only thread * we're monitoring, the one forked there. */ - cpus = cpu_map__dummy_new(); + cpus = perf_cpu_map__dummy_new(); threads = thread_map__new_by_tid(-1); if (!cpus || !threads) { err = -ENOMEM; diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 5eb4e1fbb877..acda9bfb4002 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -189,7 +189,7 @@ struct perf_cpu_map *cpu_map__new(const char *cpu_list) else if (*cpu_list != '\0') cpus = cpu_map__default_new(); else - cpus = cpu_map__dummy_new(); + cpus = perf_cpu_map__dummy_new(); invalid: free(tmp_cpus); out: @@ -256,19 +256,6 @@ size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp) #undef BUFSIZE } -struct perf_cpu_map *cpu_map__dummy_new(void) -{ - struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + sizeof(int)); - - if (cpus != NULL) { - cpus->nr = 1; - cpus->map[0] = -1; - refcount_set(&cpus->refcnt, 1); - } - - return cpus; -} - struct perf_cpu_map *cpu_map__empty_new(int nr) { struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + sizeof(int) * nr); diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index c2ba9ae195f7..0ce3f6bd9449 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -6,13 +6,13 @@ #include #include #include +#include #include "perf.h" #include "util/debug.h" struct perf_cpu_map *cpu_map__new(const char *cpu_list); struct perf_cpu_map *cpu_map__empty_new(int nr); -struct perf_cpu_map *cpu_map__dummy_new(void); struct perf_cpu_map *cpu_map__new_data(struct cpu_map_data *data); struct perf_cpu_map *cpu_map__read(FILE *file); size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 1bedec28e58f..461c1e68e9e7 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1086,7 +1086,7 @@ int perf_evlist__create_maps(struct evlist *evlist, struct target *target) return -1; if (target__uses_dummy_map(target)) - cpus = cpu_map__dummy_new(); + cpus = perf_cpu_map__dummy_new(); else cpus = cpu_map__new(target->cpu_list); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 5aeb7260c8e1..a389752840a9 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1840,7 +1840,7 @@ int evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus, static struct perf_cpu_map *empty_cpu_map; if (empty_cpu_map == NULL) { - empty_cpu_map = cpu_map__dummy_new(); + empty_cpu_map = perf_cpu_map__dummy_new(); if (empty_cpu_map == NULL) return -ENOMEM; } -- cgit v1.2.3-59-g8ed1b From 38f01d8da1d8d28678ea16a0a484f4d3eded34b2 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:17 +0200 Subject: libperf: Add perf_cpu_map__get()/perf_cpu_map__put() Moving the following functions: cpu_map__get() cpu_map__put() to libperf with following names: perf_cpu_map__get() perf_cpu_map__put() Committer notes: Added fixes for arm/arm64 Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-31-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 6 +++--- tools/perf/arch/arm64/util/header.c | 4 ++-- tools/perf/builtin-ftrace.c | 2 +- tools/perf/builtin-stat.c | 4 ++-- tools/perf/lib/cpumap.c | 24 ++++++++++++++++++++++++ tools/perf/lib/include/perf/cpumap.h | 2 ++ tools/perf/lib/libperf.map | 2 ++ tools/perf/tests/bitmap.c | 2 +- tools/perf/tests/code-reading.c | 4 ++-- tools/perf/tests/cpumap.c | 8 ++++---- tools/perf/tests/event-times.c | 4 ++-- tools/perf/tests/event_update.c | 4 ++-- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mem2node.c | 2 +- tools/perf/tests/mmap-basic.c | 2 +- tools/perf/tests/openat-syscall-all-cpus.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/tests/topology.c | 2 +- tools/perf/util/cpumap.c | 22 ---------------------- tools/perf/util/cpumap.h | 3 --- tools/perf/util/cputopo.c | 4 ++-- tools/perf/util/env.c | 2 +- tools/perf/util/event.c | 2 +- tools/perf/util/evlist.c | 16 ++++++++-------- tools/perf/util/evsel.c | 4 ++-- tools/perf/util/parse-events.c | 4 ++-- tools/perf/util/pmu.c | 2 +- tools/perf/util/python.c | 2 +- tools/perf/util/record.c | 6 +++--- tools/perf/util/session.c | 2 +- tools/perf/util/svghelper.c | 2 +- 33 files changed, 78 insertions(+), 75 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 268fcb31cd53..3a78b38e43ca 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -181,7 +181,7 @@ static int cs_etm_set_option(struct auxtrace_record *itr, err = 0; out: - cpu_map__put(online_cpus); + perf_cpu_map__put(online_cpus); return err; } @@ -517,7 +517,7 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused, } } - cpu_map__put(online_cpus); + perf_cpu_map__put(online_cpus); return (CS_ETM_HEADER_SIZE + (etmv4 * CS_ETMV4_PRIV_SIZE) + @@ -679,7 +679,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr, if (cpu_map__has(cpu_map, i)) cs_etm_get_metadata(i, &offset, itr, info); - cpu_map__put(online_cpus); + perf_cpu_map__put(online_cpus); return 0; } diff --git a/tools/perf/arch/arm64/util/header.c b/tools/perf/arch/arm64/util/header.c index b3e73a413f5a..602caf550e7f 100644 --- a/tools/perf/arch/arm64/util/header.c +++ b/tools/perf/arch/arm64/util/header.c @@ -27,7 +27,7 @@ char *get_cpuid_str(struct perf_pmu *pmu) return NULL; /* read midr from list of cpus mapped to this pmu */ - cpus = cpu_map__get(pmu->cpus); + cpus = perf_cpu_map__get(pmu->cpus); for (cpu = 0; cpu < cpus->nr; cpu++) { scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d"MIDR, sysfs, cpus->map[cpu]); @@ -60,6 +60,6 @@ char *get_cpuid_str(struct perf_pmu *pmu) buf = NULL; } - cpu_map__put(cpus); + perf_cpu_map__put(cpus); return buf; } diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 105ef2a17a9c..6943352b8d94 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -206,7 +206,7 @@ static int reset_tracing_cpu(void) int ret; ret = set_tracing_cpumask(cpumap); - cpu_map__put(cpumap); + perf_cpu_map__put(cpumap); return ret; } diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 36e66a4f3c57..39bd73d0e06e 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -933,8 +933,8 @@ static int perf_stat_init_aggr_mode(void) static void perf_stat__exit_aggr_mode(void) { - cpu_map__put(stat_config.aggr_map); - cpu_map__put(stat_config.cpus_aggr_map); + perf_cpu_map__put(stat_config.aggr_map); + perf_cpu_map__put(stat_config.cpus_aggr_map); stat_config.aggr_map = NULL; stat_config.cpus_aggr_map = NULL; } diff --git a/tools/perf/lib/cpumap.c b/tools/perf/lib/cpumap.c index 80d587ab95aa..f3cfb4c71106 100644 --- a/tools/perf/lib/cpumap.c +++ b/tools/perf/lib/cpumap.c @@ -3,6 +3,8 @@ #include #include #include +#include +#include struct perf_cpu_map *perf_cpu_map__dummy_new(void) { @@ -16,3 +18,25 @@ struct perf_cpu_map *perf_cpu_map__dummy_new(void) return cpus; } + +static void cpu_map__delete(struct perf_cpu_map *map) +{ + if (map) { + WARN_ONCE(refcount_read(&map->refcnt) != 0, + "cpu_map refcnt unbalanced\n"); + free(map); + } +} + +struct perf_cpu_map *perf_cpu_map__get(struct perf_cpu_map *map) +{ + if (map) + refcount_inc(&map->refcnt); + return map; +} + +void perf_cpu_map__put(struct perf_cpu_map *map) +{ + if (map && refcount_dec_and_test(&map->refcnt)) + cpu_map__delete(map); +} diff --git a/tools/perf/lib/include/perf/cpumap.h b/tools/perf/lib/include/perf/cpumap.h index fa1e5aa9d662..e16c2515a499 100644 --- a/tools/perf/lib/include/perf/cpumap.h +++ b/tools/perf/lib/include/perf/cpumap.h @@ -7,5 +7,7 @@ struct perf_cpu_map; LIBPERF_API struct perf_cpu_map *perf_cpu_map__dummy_new(void); +LIBPERF_API struct perf_cpu_map *perf_cpu_map__get(struct perf_cpu_map *map); +LIBPERF_API void perf_cpu_map__put(struct perf_cpu_map *map); #endif /* __LIBPERF_CPUMAP_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 65201c6cbe7e..76ce3bc59dd8 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -2,6 +2,8 @@ LIBPERF_0.0.1 { global: libperf_set_print; perf_cpu_map__dummy_new; + perf_cpu_map__get; + perf_cpu_map__put; local: *; }; diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c index 74d0cd32a5c4..95304d29092e 100644 --- a/tools/perf/tests/bitmap.c +++ b/tools/perf/tests/bitmap.c @@ -21,7 +21,7 @@ static unsigned long *get_bitmap(const char *str, int nbits) } if (map) - cpu_map__put(map); + perf_cpu_map__put(map); return bm; } diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index ec4b0bf28270..ce2d3266286a 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -655,7 +655,7 @@ static int do_test_code_reading(bool try_kcore) * and will be freed by following perf_evlist__set_maps * call. Getting refference to keep them alive. */ - cpu_map__get(cpus); + perf_cpu_map__get(cpus); thread_map__get(threads); perf_evlist__set_maps(evlist, NULL, NULL); evlist__delete(evlist); @@ -705,7 +705,7 @@ out_err: if (evlist) { evlist__delete(evlist); } else { - cpu_map__put(cpus); + perf_cpu_map__put(cpus); thread_map__put(threads); } machine__delete_threads(machine); diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index 10da4400493d..6c921087b0fe 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -39,7 +39,7 @@ static int process_event_mask(struct perf_tool *tool __maybe_unused, TEST_ASSERT_VAL("wrong cpu", map->map[i] == i); } - cpu_map__put(map); + perf_cpu_map__put(map); return 0; } @@ -68,7 +68,7 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused, TEST_ASSERT_VAL("wrong cpu", map->map[0] == 1); TEST_ASSERT_VAL("wrong cpu", map->map[1] == 256); TEST_ASSERT_VAL("wrong refcnt", refcount_read(&map->refcnt) == 1); - cpu_map__put(map); + perf_cpu_map__put(map); return 0; } @@ -83,7 +83,7 @@ int test__cpu_map_synthesize(struct test *test __maybe_unused, int subtest __may TEST_ASSERT_VAL("failed to synthesize map", !perf_event__synthesize_cpu_map(NULL, cpus, process_event_mask, NULL)); - cpu_map__put(cpus); + perf_cpu_map__put(cpus); /* This one is better stores in cpu values. */ cpus = cpu_map__new("1,256"); @@ -91,7 +91,7 @@ int test__cpu_map_synthesize(struct test *test __maybe_unused, int subtest __may TEST_ASSERT_VAL("failed to synthesize map", !perf_event__synthesize_cpu_map(NULL, cpus, process_event_cpus, NULL)); - cpu_map__put(cpus); + perf_cpu_map__put(cpus); return 0; } diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index bf00d3d792fb..dcfff4b20c92 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -132,7 +132,7 @@ static int attach__cpu_disabled(struct evlist *evlist) return err; } - cpu_map__put(cpus); + perf_cpu_map__put(cpus); return evsel__enable(evsel); } @@ -154,7 +154,7 @@ static int attach__cpu_enabled(struct evlist *evlist) if (err == -EACCES) return TEST_SKIP; - cpu_map__put(cpus); + perf_cpu_map__put(cpus); return err ? TEST_FAIL : TEST_OK; } diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index eb0dd359762d..415d12e96834 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -73,7 +73,7 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused, TEST_ASSERT_VAL("wrong cpus", map->map[0] == 1); TEST_ASSERT_VAL("wrong cpus", map->map[1] == 2); TEST_ASSERT_VAL("wrong cpus", map->map[2] == 3); - cpu_map__put(map); + perf_cpu_map__put(map); return 0; } @@ -113,6 +113,6 @@ int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unu TEST_ASSERT_VAL("failed to synthesize attr update cpus", !perf_event__synthesize_event_update_cpus(&tmp.tool, evsel, process_event_cpus)); - cpu_map__put(evsel->own_cpus); + perf_cpu_map__put(evsel->own_cpus); return 0; } diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 7bfc859971e5..43e55fe98f8c 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -149,7 +149,7 @@ out_err: evlist__disable(evlist); evlist__delete(evlist); } else { - cpu_map__put(cpus); + perf_cpu_map__put(cpus); thread_map__put(threads); } diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c index e12eedfba781..6fe2c1e7918b 100644 --- a/tools/perf/tests/mem2node.c +++ b/tools/perf/tests/mem2node.c @@ -32,7 +32,7 @@ static unsigned long *get_bitmap(const char *str, int nbits) } if (map) - cpu_map__put(map); + perf_cpu_map__put(map); else free(bm); diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 40511025208f..d15282174b2e 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -155,7 +155,7 @@ out_delete_evlist: cpus = NULL; threads = NULL; out_free_cpus: - cpu_map__put(cpus); + perf_cpu_map__put(cpus); out_free_threads: thread_map__put(threads); return err; diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index f96cbd304024..611f6ea9b702 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -120,7 +120,7 @@ out_close_fd: out_evsel_delete: evsel__delete(evsel); out_cpu_map_delete: - cpu_map__put(cpus); + perf_cpu_map__put(cpus); out_thread_map_delete: thread_map__put(threads); return err; diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index c6d3f4488b73..c464e301ade9 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -125,7 +125,7 @@ out_init: } out_free_maps: - cpu_map__put(cpus); + perf_cpu_map__put(cpus); thread_map__put(threads); out_delete_evlist: evlist__delete(evlist); diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index d5537edb47db..27af7b7109a3 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -569,7 +569,7 @@ out: evlist__disable(evlist); evlist__delete(evlist); } else { - cpu_map__put(cpus); + perf_cpu_map__put(cpus); thread_map__put(threads); } diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index c094fb8cc877..f026759a05d7 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -135,7 +135,7 @@ out_init: } out_free_maps: - cpu_map__put(cpus); + perf_cpu_map__put(cpus); thread_map__put(threads); out_delete_evlist: evlist__delete(evlist); diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index 443d0272ebbd..1b57ded58d59 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -133,7 +133,7 @@ int test__session_topology(struct test *test __maybe_unused, int subtest __maybe } ret = check_cpu_topology(path, map); - cpu_map__put(map); + perf_cpu_map__put(map); free_path: unlink(path); diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index acda9bfb4002..44082e5eabde 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -273,28 +273,6 @@ struct perf_cpu_map *cpu_map__empty_new(int nr) return cpus; } -static void cpu_map__delete(struct perf_cpu_map *map) -{ - if (map) { - WARN_ONCE(refcount_read(&map->refcnt) != 0, - "cpu_map refcnt unbalanced\n"); - free(map); - } -} - -struct perf_cpu_map *cpu_map__get(struct perf_cpu_map *map) -{ - if (map) - refcount_inc(&map->refcnt); - return map; -} - -void cpu_map__put(struct perf_cpu_map *map) -{ - if (map && refcount_dec_and_test(&map->refcnt)) - cpu_map__delete(map); -} - static int cpu__get_topology_int(int cpu, const char *name, int *value) { char path[PATH_MAX]; diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index 0ce3f6bd9449..b7af2cb68c19 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -29,9 +29,6 @@ int cpu_map__build_die_map(struct perf_cpu_map *cpus, struct perf_cpu_map **diep int cpu_map__build_core_map(struct perf_cpu_map *cpus, struct perf_cpu_map **corep); const struct perf_cpu_map *cpu_map__online(void); /* thread unsafe */ -struct perf_cpu_map *cpu_map__get(struct perf_cpu_map *map); -void cpu_map__put(struct perf_cpu_map *map); - static inline int cpu_map__socket(struct perf_cpu_map *sock, int s) { if (!sock || s > sock->nr || s < 0) diff --git a/tools/perf/util/cputopo.c b/tools/perf/util/cputopo.c index 157b0988435e..0cd99c460cd4 100644 --- a/tools/perf/util/cputopo.c +++ b/tools/perf/util/cputopo.c @@ -219,7 +219,7 @@ struct cpu_topology *cpu_topology__new(void) } out_free: - cpu_map__put(map); + perf_cpu_map__put(map); if (ret) { cpu_topology__delete(tp); tp = NULL; @@ -335,7 +335,7 @@ struct numa_topology *numa_topology__new(void) out: free(buf); fclose(fp); - cpu_map__put(node_map); + perf_cpu_map__put(node_map); return tp; } diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c index 9909ec40c6d2..d77912b2b5e7 100644 --- a/tools/perf/util/env.c +++ b/tools/perf/util/env.c @@ -179,7 +179,7 @@ void perf_env__exit(struct perf_env *env) zfree(&env->cpu); for (i = 0; i < env->nr_numa_nodes; i++) - cpu_map__put(env->numa_nodes[i].map); + perf_cpu_map__put(env->numa_nodes[i].map); zfree(&env->numa_nodes); for (i = 0; i < env->caches_cnt; i++) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index f78837788b14..1a3db35f9f7d 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1403,7 +1403,7 @@ size_t perf_event__fprintf_cpu_map(union perf_event *event, FILE *fp) else ret += fprintf(fp, "failed to get cpumap from event\n"); - cpu_map__put(cpus); + perf_cpu_map__put(cpus); return ret; } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 461c1e68e9e7..35020d50f51e 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -141,7 +141,7 @@ void evlist__delete(struct evlist *evlist) perf_evlist__munmap(evlist); evlist__close(evlist); - cpu_map__put(evlist->cpus); + perf_cpu_map__put(evlist->cpus); thread_map__put(evlist->threads); evlist->cpus = NULL; evlist->threads = NULL; @@ -158,11 +158,11 @@ static void __perf_evlist__propagate_maps(struct evlist *evlist, * keep it, if there's no target cpu list defined. */ if (!evsel->own_cpus || evlist->has_user_cpus) { - cpu_map__put(evsel->cpus); - evsel->cpus = cpu_map__get(evlist->cpus); + perf_cpu_map__put(evsel->cpus); + evsel->cpus = perf_cpu_map__get(evlist->cpus); } else if (evsel->cpus != evsel->own_cpus) { - cpu_map__put(evsel->cpus); - evsel->cpus = cpu_map__get(evsel->own_cpus); + perf_cpu_map__put(evsel->cpus); + evsel->cpus = perf_cpu_map__get(evsel->own_cpus); } thread_map__put(evsel->threads); @@ -1115,8 +1115,8 @@ void perf_evlist__set_maps(struct evlist *evlist, struct perf_cpu_map *cpus, * the caller to increase the reference count. */ if (cpus != evlist->cpus) { - cpu_map__put(evlist->cpus); - evlist->cpus = cpu_map__get(cpus); + perf_cpu_map__put(evlist->cpus); + evlist->cpus = perf_cpu_map__get(cpus); } if (threads != evlist->threads) { @@ -1383,7 +1383,7 @@ static int perf_evlist__create_syswide_maps(struct evlist *evlist) out: return err; out_put: - cpu_map__put(cpus); + perf_cpu_map__put(cpus); goto out; } diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index a389752840a9..72c0e6948e83 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1325,8 +1325,8 @@ void perf_evsel__exit(struct evsel *evsel) perf_evsel__free_id(evsel); perf_evsel__free_config_terms(evsel); cgroup__put(evsel->cgrp); - cpu_map__put(evsel->cpus); - cpu_map__put(evsel->own_cpus); + perf_cpu_map__put(evsel->cpus); + perf_cpu_map__put(evsel->own_cpus); thread_map__put(evsel->threads); zfree(&evsel->group_name); zfree(&evsel->name); diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index decb66d243ca..8c9928feb38a 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -332,8 +332,8 @@ __add_event(struct list_head *list, int *idx, return NULL; (*idx)++; - evsel->cpus = cpu_map__get(cpus); - evsel->own_cpus = cpu_map__get(cpus); + evsel->cpus = perf_cpu_map__get(cpus); + evsel->own_cpus = perf_cpu_map__get(cpus); evsel->system_wide = pmu ? pmu->is_uncore : false; evsel->auto_merge_stats = auto_merge_stats; diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 4929a50c0973..d355f9506a1c 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -626,7 +626,7 @@ static bool pmu_is_uncore(const char *name) snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name); cpus = __pmu_cpumask(path); - cpu_map__put(cpus); + perf_cpu_map__put(cpus); return !!cpus; } diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index cc4af99ab190..677c93f91c6c 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -557,7 +557,7 @@ static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus, static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus) { - cpu_map__put(pcpus->cpus); + perf_cpu_map__put(pcpus->cpus); Py_TYPE(pcpus)->tp_free((PyObject*)pcpus); } diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 9f8841548539..fecccfd71aa1 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -67,7 +67,7 @@ static bool perf_probe_api(setup_probe_fn_t fn) if (!cpus) return false; cpu = cpus->map[0]; - cpu_map__put(cpus); + perf_cpu_map__put(cpus); do { ret = perf_do_probe_api(fn, cpu, try[i++]); @@ -122,7 +122,7 @@ bool perf_can_record_cpu_wide(void) if (!cpus) return false; cpu = cpus->map[0]; - cpu_map__put(cpus); + perf_cpu_map__put(cpus); fd = sys_perf_event_open(&attr, -1, cpu, -1, 0); if (fd < 0) @@ -278,7 +278,7 @@ bool perf_evlist__can_select_event(struct evlist *evlist, const char *str) struct perf_cpu_map *cpus = cpu_map__new(NULL); cpu = cpus ? cpus->map[0] : 0; - cpu_map__put(cpus); + perf_cpu_map__put(cpus); } else { cpu = evlist->cpus->map[0]; } diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index c191dc152175..62d37440cbee 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -2310,7 +2310,7 @@ int perf_session__cpu_bitmap(struct perf_session *session, err = 0; out_delete_map: - cpu_map__put(map); + perf_cpu_map__put(map); return err; } diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index 99132c6a30a6..a9ca5c4fffee 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c @@ -745,7 +745,7 @@ static int str_to_bitmap(char *s, cpumask_t *b) set_bit(c, cpumask_bits(b)); } - cpu_map__put(m); + perf_cpu_map__put(m); return ret; } -- cgit v1.2.3-59-g8ed1b From 07acd22677ac6bb2db404d1d258e8c7d06ca7706 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:18 +0200 Subject: libperf: Add perf_thread_map struct Add perf_thread_map struct to libperf. It's added as a declaration into into: include/perf/threadmap.h which will be included by users. The perf_thread_map struct definition is added into: include/internal/threadmap.h which is not to be included by users, but shared within perf and libperf. We tried the total separation of the perf_thread_map struct in libperf, but it lead to complications and much bigger changes in perf code, so we decided to share the declaration. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-32-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/Build | 1 + tools/perf/lib/include/internal/threadmap.h | 21 +++++++++++++++++++++ tools/perf/lib/include/perf/threadmap.h | 7 +++++++ tools/perf/lib/threadmap.c | 5 +++++ tools/perf/util/thread_map.h | 13 +------------ 5 files changed, 35 insertions(+), 12 deletions(-) create mode 100644 tools/perf/lib/include/internal/threadmap.h create mode 100644 tools/perf/lib/include/perf/threadmap.h create mode 100644 tools/perf/lib/threadmap.c (limited to 'tools') diff --git a/tools/perf/lib/Build b/tools/perf/lib/Build index 195b274db49a..9beadfc81a71 100644 --- a/tools/perf/lib/Build +++ b/tools/perf/lib/Build @@ -1,2 +1,3 @@ libperf-y += core.o libperf-y += cpumap.o +libperf-y += threadmap.o diff --git a/tools/perf/lib/include/internal/threadmap.h b/tools/perf/lib/include/internal/threadmap.h new file mode 100644 index 000000000000..c8088005a9ab --- /dev/null +++ b/tools/perf/lib/include/internal/threadmap.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LIBPERF_INTERNAL_THREADMAP_H +#define __LIBPERF_INTERNAL_THREADMAP_H + +#include +#include +#include + +struct thread_map_data { + pid_t pid; + char *comm; +}; + +struct perf_thread_map { + refcount_t refcnt; + int nr; + int err_thread; + struct thread_map_data map[]; +}; + +#endif /* __LIBPERF_INTERNAL_THREADMAP_H */ diff --git a/tools/perf/lib/include/perf/threadmap.h b/tools/perf/lib/include/perf/threadmap.h new file mode 100644 index 000000000000..dc3a3837b56f --- /dev/null +++ b/tools/perf/lib/include/perf/threadmap.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LIBPERF_THREADMAP_H +#define __LIBPERF_THREADMAP_H + +struct perf_thread_map; + +#endif /* __LIBPERF_THREADMAP_H */ diff --git a/tools/perf/lib/threadmap.c b/tools/perf/lib/threadmap.c new file mode 100644 index 000000000000..163dc609b909 --- /dev/null +++ b/tools/perf/lib/threadmap.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h index 9358b1b6e657..5a7be6f8934f 100644 --- a/tools/perf/util/thread_map.h +++ b/tools/perf/util/thread_map.h @@ -5,18 +5,7 @@ #include #include #include - -struct thread_map_data { - pid_t pid; - char *comm; -}; - -struct perf_thread_map { - refcount_t refcnt; - int nr; - int err_thread; - struct thread_map_data map[]; -}; +#include struct thread_map_event; -- cgit v1.2.3-59-g8ed1b From 4b49cce25e719587e934b745fe9bbb5bc8c4ba29 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:19 +0200 Subject: libperf: Add perf_thread_map__new_dummy() function Moving the following functions: thread_map__new_dummy() thread_map__realloc() thread_map__set_pid() to libperf with the following names: perf_thread_map__new_dummy() perf_thread_map__realloc() perf_thread_map__set_pid() the other 2 functions are dependencies of the perf_thread_map__new_dummy() function. The perf_thread_map__realloc() function is not exported. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-33-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/internal/threadmap.h | 2 + tools/perf/lib/include/perf/threadmap.h | 7 ++++ tools/perf/lib/libperf.map | 2 + tools/perf/lib/threadmap.c | 43 +++++++++++++++++++++ tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/thread-map.c | 2 +- tools/perf/util/evlist.c | 4 +- tools/perf/util/thread_map.c | 59 ++++++----------------------- tools/perf/util/thread_map.h | 7 +--- 9 files changed, 71 insertions(+), 57 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/internal/threadmap.h b/tools/perf/lib/include/internal/threadmap.h index c8088005a9ab..df748baf9eda 100644 --- a/tools/perf/lib/include/internal/threadmap.h +++ b/tools/perf/lib/include/internal/threadmap.h @@ -18,4 +18,6 @@ struct perf_thread_map { struct thread_map_data map[]; }; +struct perf_thread_map *perf_thread_map__realloc(struct perf_thread_map *map, int nr); + #endif /* __LIBPERF_INTERNAL_THREADMAP_H */ diff --git a/tools/perf/lib/include/perf/threadmap.h b/tools/perf/lib/include/perf/threadmap.h index dc3a3837b56f..34ed7f587101 100644 --- a/tools/perf/lib/include/perf/threadmap.h +++ b/tools/perf/lib/include/perf/threadmap.h @@ -2,6 +2,13 @@ #ifndef __LIBPERF_THREADMAP_H #define __LIBPERF_THREADMAP_H +#include +#include + struct perf_thread_map; +LIBPERF_API struct perf_thread_map *perf_thread_map__new_dummy(void); + +LIBPERF_API void perf_thread_map__set_pid(struct perf_thread_map *map, int thread, pid_t pid); + #endif /* __LIBPERF_THREADMAP_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 76ce3bc59dd8..6b4ec1c4d3f3 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -4,6 +4,8 @@ LIBPERF_0.0.1 { perf_cpu_map__dummy_new; perf_cpu_map__get; perf_cpu_map__put; + perf_thread_map__new_dummy; + perf_thread_map__set_pid; local: *; }; diff --git a/tools/perf/lib/threadmap.c b/tools/perf/lib/threadmap.c index 163dc609b909..23e628a1437a 100644 --- a/tools/perf/lib/threadmap.c +++ b/tools/perf/lib/threadmap.c @@ -3,3 +3,46 @@ #include #include #include +#include + +static void perf_thread_map__reset(struct perf_thread_map *map, int start, int nr) +{ + size_t size = (nr - start) * sizeof(map->map[0]); + + memset(&map->map[start], 0, size); + map->err_thread = -1; +} + +struct perf_thread_map *perf_thread_map__realloc(struct perf_thread_map *map, int nr) +{ + size_t size = sizeof(*map) + sizeof(map->map[0]) * nr; + int start = map ? map->nr : 0; + + map = realloc(map, size); + /* + * We only realloc to add more items, let's reset new items. + */ + if (map) + perf_thread_map__reset(map, start, nr); + + return map; +} + +#define thread_map__alloc(__nr) perf_thread_map__realloc(NULL, __nr) + +void perf_thread_map__set_pid(struct perf_thread_map *map, int thread, pid_t pid) +{ + map->map[thread].pid = pid; +} + +struct perf_thread_map *perf_thread_map__new_dummy(void) +{ + struct perf_thread_map *threads = thread_map__alloc(1); + + if (threads != NULL) { + perf_thread_map__set_pid(threads, 0, -1); + threads->nr = 1; + refcount_set(&threads->refcnt, 1); + } + return threads; +} diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index c7182b7840e5..1de79208e690 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -58,7 +58,7 @@ int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest perf_evsel__config(evsel, &opts, NULL); - thread_map__set_pid(evlist->threads, 0, getpid()); + perf_thread_map__set_pid(evlist->threads, 0, getpid()); err = evlist__open(evlist); if (err < 0) { diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c index 367dfe708e4c..73bc404ed390 100644 --- a/tools/perf/tests/thread-map.c +++ b/tools/perf/tests/thread-map.c @@ -35,7 +35,7 @@ int test__thread_map(struct test *test __maybe_unused, int subtest __maybe_unuse thread_map__put(map); /* test dummy pid */ - map = thread_map__new_dummy(); + map = perf_thread_map__new_dummy(); TEST_ASSERT_VAL("failed to alloc map", map); thread_map__read_comms(map); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 35020d50f51e..88d131769df4 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1375,7 +1375,7 @@ static int perf_evlist__create_syswide_maps(struct evlist *evlist) if (!cpus) goto out; - threads = thread_map__new_dummy(); + threads = perf_thread_map__new_dummy(); if (!threads) goto out_put; @@ -1504,7 +1504,7 @@ int perf_evlist__prepare_workload(struct evlist *evlist, struct target *target, __func__, __LINE__); goto out_close_pipes; } - thread_map__set_pid(evlist->threads, 0, evlist->workload.pid); + perf_thread_map__set_pid(evlist->threads, 0, evlist->workload.pid); } close(child_ready_pipe[1]); diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index e89496c39d58..06dd9f2e4ce5 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c @@ -28,30 +28,7 @@ static int filter(const struct dirent *dir) return 1; } -static void thread_map__reset(struct perf_thread_map *map, int start, int nr) -{ - size_t size = (nr - start) * sizeof(map->map[0]); - - memset(&map->map[start], 0, size); - map->err_thread = -1; -} - -static struct perf_thread_map *thread_map__realloc(struct perf_thread_map *map, int nr) -{ - size_t size = sizeof(*map) + sizeof(map->map[0]) * nr; - int start = map ? map->nr : 0; - - map = realloc(map, size); - /* - * We only realloc to add more items, let's reset new items. - */ - if (map) - thread_map__reset(map, start, nr); - - return map; -} - -#define thread_map__alloc(__nr) thread_map__realloc(NULL, __nr) +#define thread_map__alloc(__nr) perf_thread_map__realloc(NULL, __nr) struct perf_thread_map *thread_map__new_by_pid(pid_t pid) { @@ -69,7 +46,7 @@ struct perf_thread_map *thread_map__new_by_pid(pid_t pid) threads = thread_map__alloc(items); if (threads != NULL) { for (i = 0; i < items; i++) - thread_map__set_pid(threads, i, atoi(namelist[i]->d_name)); + perf_thread_map__set_pid(threads, i, atoi(namelist[i]->d_name)); threads->nr = items; refcount_set(&threads->refcnt, 1); } @@ -86,7 +63,7 @@ struct perf_thread_map *thread_map__new_by_tid(pid_t tid) struct perf_thread_map *threads = thread_map__alloc(1); if (threads != NULL) { - thread_map__set_pid(threads, 0, tid); + perf_thread_map__set_pid(threads, 0, tid); threads->nr = 1; refcount_set(&threads->refcnt, 1); } @@ -142,7 +119,7 @@ static struct perf_thread_map *__thread_map__new_all_cpus(uid_t uid) if (grow) { struct perf_thread_map *tmp; - tmp = thread_map__realloc(threads, max_threads); + tmp = perf_thread_map__realloc(threads, max_threads); if (tmp == NULL) goto out_free_namelist; @@ -150,8 +127,8 @@ static struct perf_thread_map *__thread_map__new_all_cpus(uid_t uid) } for (i = 0; i < items; i++) { - thread_map__set_pid(threads, threads->nr + i, - atoi(namelist[i]->d_name)); + perf_thread_map__set_pid(threads, threads->nr + i, + atoi(namelist[i]->d_name)); } for (i = 0; i < items; i++) @@ -233,14 +210,14 @@ static struct perf_thread_map *thread_map__new_by_pid_str(const char *pid_str) goto out_free_threads; total_tasks += items; - nt = thread_map__realloc(threads, total_tasks); + nt = perf_thread_map__realloc(threads, total_tasks); if (nt == NULL) goto out_free_namelist; threads = nt; for (i = 0; i < items; i++) { - thread_map__set_pid(threads, j++, atoi(namelist[i]->d_name)); + perf_thread_map__set_pid(threads, j++, atoi(namelist[i]->d_name)); zfree(&namelist[i]); } threads->nr = total_tasks; @@ -263,18 +240,6 @@ out_free_threads: goto out; } -struct perf_thread_map *thread_map__new_dummy(void) -{ - struct perf_thread_map *threads = thread_map__alloc(1); - - if (threads != NULL) { - thread_map__set_pid(threads, 0, -1); - threads->nr = 1; - refcount_set(&threads->refcnt, 1); - } - return threads; -} - struct perf_thread_map *thread_map__new_by_tid_str(const char *tid_str) { struct perf_thread_map *threads = NULL, *nt; @@ -287,7 +252,7 @@ struct perf_thread_map *thread_map__new_by_tid_str(const char *tid_str) /* perf-stat expects threads to be generated even if tid not given */ if (!tid_str) - return thread_map__new_dummy(); + return perf_thread_map__new_dummy(); slist = strlist__new(tid_str, &slist_config); if (!slist) @@ -304,13 +269,13 @@ struct perf_thread_map *thread_map__new_by_tid_str(const char *tid_str) continue; ntasks++; - nt = thread_map__realloc(threads, ntasks); + nt = perf_thread_map__realloc(threads, ntasks); if (nt == NULL) goto out_free_threads; threads = nt; - thread_map__set_pid(threads, ntasks - 1, tid); + perf_thread_map__set_pid(threads, ntasks - 1, tid); threads->nr = ntasks; } out: @@ -437,7 +402,7 @@ static void thread_map__copy_event(struct perf_thread_map *threads, threads->nr = (int) event->nr; for (i = 0; i < event->nr; i++) { - thread_map__set_pid(threads, i, (pid_t) event->entries[i].pid); + perf_thread_map__set_pid(threads, i, (pid_t) event->entries[i].pid); threads->map[i].comm = strndup(event->entries[i].comm, 16); } diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h index 5a7be6f8934f..94a1f9565f5e 100644 --- a/tools/perf/util/thread_map.h +++ b/tools/perf/util/thread_map.h @@ -6,6 +6,7 @@ #include #include #include +#include struct thread_map_event; @@ -37,12 +38,6 @@ static inline pid_t thread_map__pid(struct perf_thread_map *map, int thread) return map->map[thread].pid; } -static inline void -thread_map__set_pid(struct perf_thread_map *map, int thread, pid_t pid) -{ - map->map[thread].pid = pid; -} - static inline char *thread_map__comm(struct perf_thread_map *map, int thread) { return map->map[thread].comm; -- cgit v1.2.3-59-g8ed1b From 7836e52e518b5e3fd695850f1d4081f756f58406 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:20 +0200 Subject: libperf: Add perf_thread_map__get()/perf_thread_map__put() Move the following functions: thread_map__get() thread_map__put() thread_map__comm() to libperf with the following names: perf_thread_map__get() perf_thread_map__put() perf_thread_map__comm() Add the perf_thread_map__comm() function for it to work/compile. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-34-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 2 +- tools/perf/lib/include/perf/threadmap.h | 4 ++++ tools/perf/lib/libperf.map | 3 +++ tools/perf/lib/threadmap.c | 33 ++++++++++++++++++++++++++++++ tools/perf/tests/code-reading.c | 4 ++-- tools/perf/tests/event-times.c | 4 ++-- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c | 2 +- tools/perf/tests/mmap-thread-lookup.c | 2 +- tools/perf/tests/openat-syscall-all-cpus.c | 2 +- tools/perf/tests/openat-syscall.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/tests/thread-map.c | 18 ++++++++-------- tools/perf/util/event.c | 4 ++-- tools/perf/util/evlist.c | 12 +++++------ tools/perf/util/evsel.c | 2 +- tools/perf/util/parse-events.c | 2 +- tools/perf/util/python.c | 2 +- tools/perf/util/stat-display.c | 2 +- tools/perf/util/thread_map.c | 26 ----------------------- tools/perf/util/thread_map.h | 8 -------- 23 files changed, 74 insertions(+), 68 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index c0962ddfad04..03fbe4600ca0 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1060,7 +1060,7 @@ static int record__synthesize_workload(struct record *rec, bool tail) process_synthesized_event, &rec->session->machines.host, rec->opts.sample_address); - thread_map__put(thread_map); + perf_thread_map__put(thread_map); return err; } diff --git a/tools/perf/lib/include/perf/threadmap.h b/tools/perf/lib/include/perf/threadmap.h index 34ed7f587101..456295273daa 100644 --- a/tools/perf/lib/include/perf/threadmap.h +++ b/tools/perf/lib/include/perf/threadmap.h @@ -10,5 +10,9 @@ struct perf_thread_map; LIBPERF_API struct perf_thread_map *perf_thread_map__new_dummy(void); LIBPERF_API void perf_thread_map__set_pid(struct perf_thread_map *map, int thread, pid_t pid); +LIBPERF_API char *perf_thread_map__comm(struct perf_thread_map *map, int thread); + +LIBPERF_API struct perf_thread_map *perf_thread_map__get(struct perf_thread_map *map); +LIBPERF_API void perf_thread_map__put(struct perf_thread_map *map); #endif /* __LIBPERF_THREADMAP_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 6b4ec1c4d3f3..c4f611010ccc 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -6,6 +6,9 @@ LIBPERF_0.0.1 { perf_cpu_map__put; perf_thread_map__new_dummy; perf_thread_map__set_pid; + perf_thread_map__comm; + perf_thread_map__get; + perf_thread_map__put; local: *; }; diff --git a/tools/perf/lib/threadmap.c b/tools/perf/lib/threadmap.c index 23e628a1437a..4865b73e2586 100644 --- a/tools/perf/lib/threadmap.c +++ b/tools/perf/lib/threadmap.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include static void perf_thread_map__reset(struct perf_thread_map *map, int start, int nr) { @@ -35,6 +37,11 @@ void perf_thread_map__set_pid(struct perf_thread_map *map, int thread, pid_t pid map->map[thread].pid = pid; } +char *perf_thread_map__comm(struct perf_thread_map *map, int thread) +{ + return map->map[thread].comm; +} + struct perf_thread_map *perf_thread_map__new_dummy(void) { struct perf_thread_map *threads = thread_map__alloc(1); @@ -46,3 +53,29 @@ struct perf_thread_map *perf_thread_map__new_dummy(void) } return threads; } + +static void perf_thread_map__delete(struct perf_thread_map *threads) +{ + if (threads) { + int i; + + WARN_ONCE(refcount_read(&threads->refcnt) != 0, + "thread map refcnt unbalanced\n"); + for (i = 0; i < threads->nr; i++) + free(perf_thread_map__comm(threads, i)); + free(threads); + } +} + +struct perf_thread_map *perf_thread_map__get(struct perf_thread_map *map) +{ + if (map) + refcount_inc(&map->refcnt); + return map; +} + +void perf_thread_map__put(struct perf_thread_map *map) +{ + if (map && refcount_dec_and_test(&map->refcnt)) + perf_thread_map__delete(map); +} diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index ce2d3266286a..7b26be1dfb47 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -656,7 +656,7 @@ static int do_test_code_reading(bool try_kcore) * call. Getting refference to keep them alive. */ perf_cpu_map__get(cpus); - thread_map__get(threads); + perf_thread_map__get(threads); perf_evlist__set_maps(evlist, NULL, NULL); evlist__delete(evlist); evlist = NULL; @@ -706,7 +706,7 @@ out_err: evlist__delete(evlist); } else { perf_cpu_map__put(cpus); - thread_map__put(threads); + perf_thread_map__put(threads); } machine__delete_threads(machine); machine__delete(machine); diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index dcfff4b20c92..9238180416b0 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -76,7 +76,7 @@ static int attach__current_disabled(struct evlist *evlist) return err; } - thread_map__put(threads); + perf_thread_map__put(threads); return evsel__enable(evsel) == 0 ? TEST_OK : TEST_FAIL; } @@ -96,7 +96,7 @@ static int attach__current_enabled(struct evlist *evlist) err = perf_evsel__open_per_thread(evsel, threads); - thread_map__put(threads); + perf_thread_map__put(threads); return err == 0 ? TEST_OK : TEST_FAIL; } diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 43e55fe98f8c..830fb3d7ea2e 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -150,7 +150,7 @@ out_err: evlist__delete(evlist); } else { perf_cpu_map__put(cpus); - thread_map__put(threads); + perf_thread_map__put(threads); } return err; diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index d15282174b2e..72fbf55f4fc3 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -157,6 +157,6 @@ out_delete_evlist: out_free_cpus: perf_cpu_map__put(cpus); out_free_threads: - thread_map__put(threads); + perf_thread_map__put(threads); return err; } diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c index ad6ca943e568..360d70deb855 100644 --- a/tools/perf/tests/mmap-thread-lookup.c +++ b/tools/perf/tests/mmap-thread-lookup.c @@ -147,7 +147,7 @@ static int synth_process(struct machine *machine) perf_event__process, machine, 0); - thread_map__put(map); + perf_thread_map__put(map); return err; } diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index 611f6ea9b702..674b0fa035ec 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -122,6 +122,6 @@ out_evsel_delete: out_cpu_map_delete: perf_cpu_map__put(cpus); out_thread_map_delete: - thread_map__put(threads); + perf_thread_map__put(threads); return err; } diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c index 20e353fbfdd0..87c212545767 100644 --- a/tools/perf/tests/openat-syscall.c +++ b/tools/perf/tests/openat-syscall.c @@ -61,6 +61,6 @@ out_close_fd: out_evsel_delete: evsel__delete(evsel); out_thread_map_delete: - thread_map__put(threads); + perf_thread_map__put(threads); return err; } diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index c464e301ade9..2decda2d4c17 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -126,7 +126,7 @@ out_init: out_free_maps: perf_cpu_map__put(cpus); - thread_map__put(threads); + perf_thread_map__put(threads); out_delete_evlist: evlist__delete(evlist); return err; diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 27af7b7109a3..0935a5a1ecaa 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -570,7 +570,7 @@ out: evlist__delete(evlist); } else { perf_cpu_map__put(cpus); - thread_map__put(threads); + perf_thread_map__put(threads); } return err; diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index f026759a05d7..24257285844b 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -136,7 +136,7 @@ out_init: out_free_maps: perf_cpu_map__put(cpus); - thread_map__put(threads); + perf_thread_map__put(threads); out_delete_evlist: evlist__delete(evlist); return err; diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c index 73bc404ed390..d61773cacf0b 100644 --- a/tools/perf/tests/thread-map.c +++ b/tools/perf/tests/thread-map.c @@ -28,11 +28,11 @@ int test__thread_map(struct test *test __maybe_unused, int subtest __maybe_unuse TEST_ASSERT_VAL("wrong pid", thread_map__pid(map, 0) == getpid()); TEST_ASSERT_VAL("wrong comm", - thread_map__comm(map, 0) && - !strcmp(thread_map__comm(map, 0), NAME)); + perf_thread_map__comm(map, 0) && + !strcmp(perf_thread_map__comm(map, 0), NAME)); TEST_ASSERT_VAL("wrong refcnt", refcount_read(&map->refcnt) == 1); - thread_map__put(map); + perf_thread_map__put(map); /* test dummy pid */ map = perf_thread_map__new_dummy(); @@ -43,11 +43,11 @@ int test__thread_map(struct test *test __maybe_unused, int subtest __maybe_unuse TEST_ASSERT_VAL("wrong nr", map->nr == 1); TEST_ASSERT_VAL("wrong pid", thread_map__pid(map, 0) == -1); TEST_ASSERT_VAL("wrong comm", - thread_map__comm(map, 0) && - !strcmp(thread_map__comm(map, 0), "dummy")); + perf_thread_map__comm(map, 0) && + !strcmp(perf_thread_map__comm(map, 0), "dummy")); TEST_ASSERT_VAL("wrong refcnt", refcount_read(&map->refcnt) == 1); - thread_map__put(map); + perf_thread_map__put(map); return 0; } @@ -70,11 +70,11 @@ static int process_event(struct perf_tool *tool __maybe_unused, TEST_ASSERT_VAL("wrong pid", thread_map__pid(threads, 0) == getpid()); TEST_ASSERT_VAL("wrong comm", - thread_map__comm(threads, 0) && - !strcmp(thread_map__comm(threads, 0), NAME)); + perf_thread_map__comm(threads, 0) && + !strcmp(perf_thread_map__comm(threads, 0), NAME)); TEST_ASSERT_VAL("wrong refcnt", refcount_read(&threads->refcnt) == 1); - thread_map__put(threads); + perf_thread_map__put(threads); return 0; } diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 1a3db35f9f7d..f440fdc3e953 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -992,7 +992,7 @@ int perf_event__synthesize_thread_map2(struct perf_tool *tool, for (i = 0; i < threads->nr; i++) { struct thread_map_event_entry *entry = &event->thread_map.entries[i]; - char *comm = thread_map__comm(threads, i); + char *comm = perf_thread_map__comm(threads, i); if (!comm) comm = (char *) ""; @@ -1387,7 +1387,7 @@ size_t perf_event__fprintf_thread_map(union perf_event *event, FILE *fp) else ret += fprintf(fp, "failed to get threads from event\n"); - thread_map__put(threads); + perf_thread_map__put(threads); return ret; } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 88d131769df4..38a3c6d16b4b 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -142,7 +142,7 @@ void evlist__delete(struct evlist *evlist) perf_evlist__munmap(evlist); evlist__close(evlist); perf_cpu_map__put(evlist->cpus); - thread_map__put(evlist->threads); + perf_thread_map__put(evlist->threads); evlist->cpus = NULL; evlist->threads = NULL; perf_evlist__purge(evlist); @@ -165,8 +165,8 @@ static void __perf_evlist__propagate_maps(struct evlist *evlist, evsel->cpus = perf_cpu_map__get(evsel->own_cpus); } - thread_map__put(evsel->threads); - evsel->threads = thread_map__get(evlist->threads); + perf_thread_map__put(evsel->threads); + evsel->threads = perf_thread_map__get(evlist->threads); } static void perf_evlist__propagate_maps(struct evlist *evlist) @@ -1100,7 +1100,7 @@ int perf_evlist__create_maps(struct evlist *evlist, struct target *target) return 0; out_delete_threads: - thread_map__put(threads); + perf_thread_map__put(threads); return -1; } @@ -1120,8 +1120,8 @@ void perf_evlist__set_maps(struct evlist *evlist, struct perf_cpu_map *cpus, } if (threads != evlist->threads) { - thread_map__put(evlist->threads); - evlist->threads = thread_map__get(threads); + perf_thread_map__put(evlist->threads); + evlist->threads = perf_thread_map__get(threads); } perf_evlist__propagate_maps(evlist); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 72c0e6948e83..652e53279b28 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1327,7 +1327,7 @@ void perf_evsel__exit(struct evsel *evsel) cgroup__put(evsel->cgrp); perf_cpu_map__put(evsel->cpus); perf_cpu_map__put(evsel->own_cpus); - thread_map__put(evsel->threads); + perf_thread_map__put(evsel->threads); zfree(&evsel->group_name); zfree(&evsel->name); perf_evsel__object.fini(evsel); diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 8c9928feb38a..38eeca6fa1fc 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -2337,7 +2337,7 @@ static bool is_event_supported(u8 type, unsigned config) evsel__delete(evsel); } - thread_map__put(tmap); + perf_thread_map__put(tmap); return ret; } diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 677c93f91c6c..19d2feee91d5 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -626,7 +626,7 @@ static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads, static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads) { - thread_map__put(pthreads->threads); + perf_thread_map__put(pthreads->threads); Py_TYPE(pthreads)->tp_free((PyObject*)pthreads); } diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index f7666d2e6e0c..1f099823a1f9 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -116,7 +116,7 @@ static void aggr_printout(struct perf_stat_config *config, case AGGR_THREAD: fprintf(config->output, "%*s-%*d%s", config->csv_output ? 0 : 16, - thread_map__comm(evsel->threads, id), + perf_thread_map__comm(evsel->threads, id), config->csv_output ? 0 : -8, thread_map__pid(evsel->threads, id), config->csv_sep); diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index 06dd9f2e4ce5..c58385ea05be 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c @@ -304,32 +304,6 @@ struct perf_thread_map *thread_map__new_str(const char *pid, const char *tid, return thread_map__new_by_tid_str(tid); } -static void thread_map__delete(struct perf_thread_map *threads) -{ - if (threads) { - int i; - - WARN_ONCE(refcount_read(&threads->refcnt) != 0, - "thread map refcnt unbalanced\n"); - for (i = 0; i < threads->nr; i++) - free(thread_map__comm(threads, i)); - free(threads); - } -} - -struct perf_thread_map *thread_map__get(struct perf_thread_map *map) -{ - if (map) - refcount_inc(&map->refcnt); - return map; -} - -void thread_map__put(struct perf_thread_map *map) -{ - if (map && refcount_dec_and_test(&map->refcnt)) - thread_map__delete(map); -} - size_t thread_map__fprintf(struct perf_thread_map *threads, FILE *fp) { int i; diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h index 94a1f9565f5e..ba45c760be72 100644 --- a/tools/perf/util/thread_map.h +++ b/tools/perf/util/thread_map.h @@ -18,9 +18,6 @@ struct perf_thread_map *thread_map__new_all_cpus(void); struct perf_thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid); struct perf_thread_map *thread_map__new_event(struct thread_map_event *event); -struct perf_thread_map *thread_map__get(struct perf_thread_map *map); -void thread_map__put(struct perf_thread_map *map); - struct perf_thread_map *thread_map__new_str(const char *pid, const char *tid, uid_t uid, bool all_threads); @@ -38,11 +35,6 @@ static inline pid_t thread_map__pid(struct perf_thread_map *map, int thread) return map->map[thread].pid; } -static inline char *thread_map__comm(struct perf_thread_map *map, int thread) -{ - return map->map[thread].comm; -} - void thread_map__read_comms(struct perf_thread_map *threads); bool thread_map__has(struct perf_thread_map *threads, pid_t pid); int thread_map__remove(struct perf_thread_map *threads, int idx); -- cgit v1.2.3-59-g8ed1b From 285a30c36d1e18e7e2afa24dae50ba5596be45e7 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:21 +0200 Subject: libperf: Add perf_evlist and perf_evsel structs Add the perf_evlist and perf_evsel structs to libperf. It's added as a declarations into: include/perf/evlist.h include/perf/evsel.h which will be included by users. The definitions are added into: include/internal/evlist.h include/internal/evsel.h which is not to be included by users, but shared within perf and libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-35-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/Build | 2 ++ tools/perf/lib/evlist.c | 4 ++++ tools/perf/lib/evsel.c | 4 ++++ tools/perf/lib/include/internal/evlist.h | 9 +++++++++ tools/perf/lib/include/internal/evsel.h | 9 +++++++++ tools/perf/lib/include/perf/evlist.h | 7 +++++++ tools/perf/lib/include/perf/evsel.h | 7 +++++++ 7 files changed, 42 insertions(+) create mode 100644 tools/perf/lib/evlist.c create mode 100644 tools/perf/lib/evsel.c create mode 100644 tools/perf/lib/include/internal/evlist.h create mode 100644 tools/perf/lib/include/internal/evsel.h create mode 100644 tools/perf/lib/include/perf/evlist.h create mode 100644 tools/perf/lib/include/perf/evsel.h (limited to 'tools') diff --git a/tools/perf/lib/Build b/tools/perf/lib/Build index 9beadfc81a71..b27c1543b046 100644 --- a/tools/perf/lib/Build +++ b/tools/perf/lib/Build @@ -1,3 +1,5 @@ libperf-y += core.o libperf-y += cpumap.o libperf-y += threadmap.o +libperf-y += evsel.o +libperf-y += evlist.o diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c new file mode 100644 index 000000000000..646bdd518793 --- /dev/null +++ b/tools/perf/lib/evlist.c @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include diff --git a/tools/perf/lib/evsel.c b/tools/perf/lib/evsel.c new file mode 100644 index 000000000000..12e86de1994b --- /dev/null +++ b/tools/perf/lib/evsel.c @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h new file mode 100644 index 000000000000..7fbfe5716652 --- /dev/null +++ b/tools/perf/lib/include/internal/evlist.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LIBPERF_INTERNAL_EVLIST_H +#define __LIBPERF_INTERNAL_EVLIST_H + +struct perf_evlist { + struct list_head entries; +}; + +#endif /* __LIBPERF_INTERNAL_EVLIST_H */ diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h new file mode 100644 index 000000000000..690943d0408a --- /dev/null +++ b/tools/perf/lib/include/internal/evsel.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LIBPERF_INTERNAL_EVSEL_H +#define __LIBPERF_INTERNAL_EVSEL_H + +struct perf_evsel { + struct list_head node; +}; + +#endif /* __LIBPERF_INTERNAL_EVSEL_H */ diff --git a/tools/perf/lib/include/perf/evlist.h b/tools/perf/lib/include/perf/evlist.h new file mode 100644 index 000000000000..92b0eb39caec --- /dev/null +++ b/tools/perf/lib/include/perf/evlist.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LIBPERF_EVLIST_H +#define __LIBPERF_EVLIST_H + +struct perf_evlist; + +#endif /* __LIBPERF_EVLIST_H */ diff --git a/tools/perf/lib/include/perf/evsel.h b/tools/perf/lib/include/perf/evsel.h new file mode 100644 index 000000000000..162bffd43409 --- /dev/null +++ b/tools/perf/lib/include/perf/evsel.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LIBPERF_EVSEL_H +#define __LIBPERF_EVSEL_H + +struct perf_evsel; + +#endif /* __LIBPERF_EVSEL_H */ -- cgit v1.2.3-59-g8ed1b From b27c4ece725a7f2225f76ad05dc6f3f5463fe893 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:22 +0200 Subject: libperf: Include perf_evsel in evsel object Including perf_evsel in evsel object, will continue to move other generic things into libperf's perf_evsel struct. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-36-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-sched.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/ui/browsers/hists.c | 8 ++++---- tools/perf/util/evlist.c | 16 ++++++++-------- tools/perf/util/evlist.h | 12 ++++++------ tools/perf/util/evsel.c | 4 ++-- tools/perf/util/evsel.h | 16 ++++++++-------- tools/perf/util/parse-events.c | 20 ++++++++++---------- tools/perf/util/stat-display.c | 4 ++-- tools/perf/util/trace-event-info.c | 4 ++-- 10 files changed, 44 insertions(+), 44 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index c02ecb295f23..70247f1b23da 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -2929,7 +2929,7 @@ static int timehist_check_attr(struct perf_sched *sched, struct evsel *evsel; struct evsel_runtime *er; - list_for_each_entry(evsel, &evlist->entries, node) { + list_for_each_entry(evsel, &evlist->entries, core.node) { er = perf_evsel__get_runtime(evsel); if (er == NULL) { pr_err("Failed to allocate memory for evsel runtime data\n"); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 51d142594a12..29dbf99f6081 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2636,7 +2636,7 @@ static bool evlist__add_vfs_getname(struct evlist *evlist) continue; } - list_del_init(&evsel->node); + list_del_init(&evsel->core.node); evsel->evlist = NULL; evsel__delete(evsel); } diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index b83258bece05..280347499c50 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -3212,7 +3212,7 @@ static void perf_evsel_menu__write(struct ui_browser *browser, { struct evsel_menu *menu = container_of(browser, struct evsel_menu, b); - struct evsel *evsel = list_entry(entry, struct evsel, node); + struct evsel *evsel = list_entry(entry, struct evsel, core.node); struct hists *hists = evsel__hists(evsel); bool current_entry = ui_browser__is_current_entry(browser, row); unsigned long nr_events = hists->stats.nr_events[PERF_RECORD_SAMPLE]; @@ -3309,13 +3309,13 @@ browse_hists: ui_browser__show_title(&menu->b, title); switch (key) { case K_TAB: - if (pos->node.next == &evlist->entries) + if (pos->core.node.next == &evlist->entries) pos = perf_evlist__first(evlist); else pos = perf_evsel__next(pos); goto browse_hists; case K_UNTAB: - if (pos->node.prev == &evlist->entries) + if (pos->core.node.prev == &evlist->entries) pos = perf_evlist__last(evlist); else pos = perf_evsel__prev(pos); @@ -3351,7 +3351,7 @@ out: static bool filter_group_entries(struct ui_browser *browser __maybe_unused, void *entry) { - struct evsel *evsel = list_entry(entry, struct evsel, node); + struct evsel *evsel = list_entry(entry, struct evsel, core.node); if (symbol_conf.event_group && !perf_evsel__is_group_leader(evsel)) return true; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 38a3c6d16b4b..227576bf16c0 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -119,7 +119,7 @@ static void perf_evlist__purge(struct evlist *evlist) struct evsel *pos, *n; evlist__for_each_entry_safe(evlist, n, pos) { - list_del_init(&pos->node); + list_del_init(&pos->core.node); pos->evlist = NULL; evsel__delete(pos); } @@ -180,7 +180,7 @@ static void perf_evlist__propagate_maps(struct evlist *evlist) void evlist__add(struct evlist *evlist, struct evsel *entry) { entry->evlist = evlist; - list_add_tail(&entry->node, &evlist->entries); + list_add_tail(&entry->core.node, &evlist->entries); entry->idx = evlist->nr_entries; entry->tracking = !entry->idx; @@ -193,7 +193,7 @@ void evlist__add(struct evlist *evlist, struct evsel *entry) void evlist__remove(struct evlist *evlist, struct evsel *evsel) { evsel->evlist = NULL; - list_del_init(&evsel->node); + list_del_init(&evsel->core.node); evlist->nr_entries -= 1; } @@ -203,7 +203,7 @@ void perf_evlist__splice_list_tail(struct evlist *evlist, struct evsel *evsel, *temp; __evlist__for_each_entry_safe(list, temp, evsel) { - list_del_init(&evsel->node); + list_del_init(&evsel->core.node); evlist__add(evlist, evsel); } } @@ -212,8 +212,8 @@ void __perf_evlist__set_leader(struct list_head *list) { struct evsel *evsel, *leader; - leader = list_entry(list->next, struct evsel, node); - evsel = list_entry(list->prev, struct evsel, node); + leader = list_entry(list->next, struct evsel, core.node); + evsel = list_entry(list->prev, struct evsel, core.node); leader->nr_members = evsel->idx - leader->idx + 1; @@ -268,7 +268,7 @@ static int evlist__add_attrs(struct evlist *evlist, evsel = perf_evsel__new_idx(attrs + i, evlist->nr_entries + i); if (evsel == NULL) goto out_delete_partial_list; - list_add_tail(&evsel->node, &head); + list_add_tail(&evsel->core.node, &head); } perf_evlist__splice_list_tail(evlist, &head); @@ -1680,7 +1680,7 @@ void perf_evlist__to_front(struct evlist *evlist, evlist__for_each_entry_safe(evlist, n, evsel) { if (evsel->leader == move_evsel->leader) - list_move_tail(&evsel->node, &move); + list_move_tail(&evsel->core.node, &move); } list_splice(&move, &evlist->entries); diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 99621c056d09..1315e64ad69e 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -230,12 +230,12 @@ static inline bool perf_evlist__empty(struct evlist *evlist) static inline struct evsel *perf_evlist__first(struct evlist *evlist) { - return list_entry(evlist->entries.next, struct evsel, node); + return list_entry(evlist->entries.next, struct evsel, core.node); } static inline struct evsel *perf_evlist__last(struct evlist *evlist) { - return list_entry(evlist->entries.prev, struct evsel, node); + return list_entry(evlist->entries.prev, struct evsel, core.node); } size_t perf_evlist__fprintf(struct evlist *evlist, FILE *fp); @@ -253,7 +253,7 @@ void perf_evlist__to_front(struct evlist *evlist, * @evsel: struct evsel iterator */ #define __evlist__for_each_entry(list, evsel) \ - list_for_each_entry(evsel, list, node) + list_for_each_entry(evsel, list, core.node) /** * evlist__for_each_entry - iterate thru all the evsels @@ -269,7 +269,7 @@ void perf_evlist__to_front(struct evlist *evlist, * @evsel: struct evsel iterator */ #define __evlist__for_each_entry_continue(list, evsel) \ - list_for_each_entry_continue(evsel, list, node) + list_for_each_entry_continue(evsel, list, core.node) /** * evlist__for_each_entry_continue - continue iteration thru all the evsels @@ -285,7 +285,7 @@ void perf_evlist__to_front(struct evlist *evlist, * @evsel: struct evsel iterator */ #define __evlist__for_each_entry_reverse(list, evsel) \ - list_for_each_entry_reverse(evsel, list, node) + list_for_each_entry_reverse(evsel, list, core.node) /** * evlist__for_each_entry_reverse - iterate thru all the evsels in reverse order @@ -302,7 +302,7 @@ void perf_evlist__to_front(struct evlist *evlist, * @evsel: struct evsel iterator */ #define __evlist__for_each_entry_safe(list, tmp, evsel) \ - list_for_each_entry_safe(evsel, tmp, list, node) + list_for_each_entry_safe(evsel, tmp, list, core.node) /** * evlist__for_each_entry_safe - safely iterate thru all the evsels diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 652e53279b28..8fed22d889a4 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -236,7 +236,7 @@ void evsel__init(struct evsel *evsel, evsel->evlist = NULL; evsel->bpf_obj = NULL; evsel->bpf_fd = -1; - INIT_LIST_HEAD(&evsel->node); + INIT_LIST_HEAD(&evsel->core.node); INIT_LIST_HEAD(&evsel->config_terms); perf_evsel__object.init(evsel); evsel->sample_size = __perf_evsel__sample_size(attr->sample_type); @@ -1318,7 +1318,7 @@ void perf_evsel__close_fd(struct evsel *evsel) void perf_evsel__exit(struct evsel *evsel) { - assert(list_empty(&evsel->node)); + assert(list_empty(&evsel->core.node)); assert(evsel->evlist == NULL); perf_evsel__free_counts(evsel); perf_evsel__free_fd(evsel); diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 5fec1ca64f58..d74cac6fe306 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "xyarray.h" #include "symbol_conf.h" #include "cpumap.h" @@ -87,8 +88,7 @@ struct bpf_object; /** struct evsel - event selector * * @evlist - evlist this evsel is in, if it is in one. - * @node - To insert it into evlist->entries or in other list_heads, say in - * the event parsing routines. + * @core - libperf evsel object * @name - Can be set to retain the original event name passed by the user, * so that when showing results in tools such as 'perf stat', we * show the name used, not some alias. @@ -101,7 +101,7 @@ struct bpf_object; * @priv: And what is in its containing unnamed union are tool specific */ struct evsel { - struct list_head node; + struct perf_evsel core; struct evlist *evlist; struct perf_event_attr attr; char *filter; @@ -386,12 +386,12 @@ int perf_evsel__parse_sample_timestamp(struct evsel *evsel, static inline struct evsel *perf_evsel__next(struct evsel *evsel) { - return list_entry(evsel->node.next, struct evsel, node); + return list_entry(evsel->core.node.next, struct evsel, core.node); } static inline struct evsel *perf_evsel__prev(struct evsel *evsel) { - return list_entry(evsel->node.prev, struct evsel, node); + return list_entry(evsel->core.node.prev, struct evsel, core.node); } /** @@ -478,15 +478,15 @@ static inline int perf_evsel__group_idx(struct evsel *evsel) /* Iterates group WITHOUT the leader. */ #define for_each_group_member(_evsel, _leader) \ -for ((_evsel) = list_entry((_leader)->node.next, struct evsel, node); \ +for ((_evsel) = list_entry((_leader)->core.node.next, struct evsel, core.node); \ (_evsel) && (_evsel)->leader == (_leader); \ - (_evsel) = list_entry((_evsel)->node.next, struct evsel, node)) + (_evsel) = list_entry((_evsel)->core.node.next, struct evsel, core.node)) /* Iterates group WITH the leader. */ #define for_each_group_evsel(_evsel, _leader) \ for ((_evsel) = _leader; \ (_evsel) && (_evsel)->leader == (_leader); \ - (_evsel) = list_entry((_evsel)->node.next, struct evsel, node)) + (_evsel) = list_entry((_evsel)->core.node.next, struct evsel, core.node)) static inline bool perf_evsel__has_branch_callstack(const struct evsel *evsel) { diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 38eeca6fa1fc..e111c0e0a5ac 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -343,7 +343,7 @@ __add_event(struct list_head *list, int *idx, if (config_terms) list_splice(config_terms, &evsel->config_terms); - list_add_tail(&evsel->node, list); + list_add_tail(&evsel->core.node, list); return evsel; } @@ -526,7 +526,7 @@ static int add_tracepoint(struct list_head *list, int *idx, list_splice(&config_terms, &evsel->config_terms); } - list_add_tail(&evsel->node, list); + list_add_tail(&evsel->core.node, list); return 0; } @@ -660,15 +660,15 @@ static int add_bpf_event(const char *group, const char *event, int fd, struct bp pr_debug("Failed to add BPF event %s:%s\n", group, event); - list_for_each_entry_safe(evsel, tmp, &new_evsels, node) { - list_del_init(&evsel->node); + list_for_each_entry_safe(evsel, tmp, &new_evsels, core.node) { + list_del_init(&evsel->core.node); evsel__delete(evsel); } return err; } pr_debug("adding %s:%s\n", group, event); - list_for_each_entry(pos, &new_evsels, node) { + list_for_each_entry(pos, &new_evsels, core.node) { pr_debug("adding %s:%s to %p\n", group, event, pos); pos->bpf_fd = fd; @@ -1458,8 +1458,8 @@ parse_events__set_leader_for_uncore_aliase(char *name, struct list_head *list, bool is_leader = true; int i, nr_pmu = 0, total_members, ret = 0; - leader = list_first_entry(list, struct evsel, node); - evsel = list_last_entry(list, struct evsel, node); + leader = list_first_entry(list, struct evsel, core.node); + evsel = list_last_entry(list, struct evsel, core.node); total_members = evsel->idx - leader->idx + 1; leaders = calloc(total_members, sizeof(uintptr_t)); @@ -1555,7 +1555,7 @@ void parse_events__set_leader(char *name, struct list_head *list, return; __perf_evlist__set_leader(list); - leader = list_entry(list->next, struct evsel, node); + leader = list_entry(list->next, struct evsel, core.node); leader->group_name = name ? strdup(name) : NULL; } @@ -2050,9 +2050,9 @@ foreach_evsel_in_last_glob(struct evlist *evlist, if (!last) return 0; - if (last->node.prev == &evlist->entries) + if (last->core.node.prev == &evlist->entries) return 0; - last = list_entry(last->node.prev, struct evsel, node); + last = list_entry(last->core.node.prev, struct evsel, core.node); } while (!last->cmdline_group_boundary); return 0; diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 1f099823a1f9..17b7d3b55b5f 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -548,8 +548,8 @@ static void collect_all_aliases(struct perf_stat_config *config, struct evsel *c struct evlist *evlist = counter->evlist; struct evsel *alias; - alias = list_prepare_entry(counter, &(evlist->entries), node); - list_for_each_entry_continue (alias, &evlist->entries, node) { + alias = list_prepare_entry(counter, &(evlist->entries), core.node); + list_for_each_entry_continue (alias, &evlist->entries, core.node) { if (strcmp(perf_evsel__name(alias), perf_evsel__name(counter)) || alias->scale != counter->scale || alias->cgrp != counter->cgrp || diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index d7ae0627ac47..7efdbb182ea1 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c @@ -408,7 +408,7 @@ get_tracepoints_path(struct list_head *pattrs) struct evsel *pos; int nr_tracepoints = 0; - list_for_each_entry(pos, pattrs, node) { + list_for_each_entry(pos, pattrs, core.node) { if (pos->attr.type != PERF_TYPE_TRACEPOINT) continue; ++nr_tracepoints; @@ -443,7 +443,7 @@ bool have_tracepoints(struct list_head *pattrs) { struct evsel *pos; - list_for_each_entry(pos, pattrs, node) + list_for_each_entry(pos, pattrs, core.node) if (pos->attr.type == PERF_TYPE_TRACEPOINT) return true; -- cgit v1.2.3-59-g8ed1b From ce9036a6e3bdfac6c7ccf8221aec9bcf9c2d355e Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:23 +0200 Subject: libperf: Include perf_evlist in evlist object Include perf_evlist in the evlist object, will continue to move other generic things into libperf's perf_evlist. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-37-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 4 ++-- tools/perf/builtin-sched.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/ui/browsers/hists.c | 6 +++--- tools/perf/util/cgroup.c | 2 +- tools/perf/util/evlist.c | 8 ++++---- tools/perf/util/evlist.h | 17 +++++++++-------- tools/perf/util/header.c | 4 ++-- tools/perf/util/parse-events.c | 2 +- tools/perf/util/stat-display.c | 4 ++-- 10 files changed, 26 insertions(+), 25 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 03fbe4600ca0..17bb0a536da3 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1002,7 +1002,7 @@ static void record__init_features(struct record *rec) if (rec->no_buildid) perf_header__clear_feat(&session->header, HEADER_BUILD_ID); - if (!have_tracepoints(&rec->evlist->entries)) + if (!have_tracepoints(&rec->evlist->core.entries)) perf_header__clear_feat(&session->header, HEADER_TRACING_DATA); if (!rec->opts.branch_stack) @@ -1218,7 +1218,7 @@ static int record__synthesize(struct record *rec, bool tail) return err; } - if (have_tracepoints(&rec->evlist->entries)) { + if (have_tracepoints(&rec->evlist->core.entries)) { /* * FIXME err <= 0 here actually means that * there were no tracepoints so its not really diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 70247f1b23da..897d11c8ca2e 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -2929,7 +2929,7 @@ static int timehist_check_attr(struct perf_sched *sched, struct evsel *evsel; struct evsel_runtime *er; - list_for_each_entry(evsel, &evlist->entries, core.node) { + list_for_each_entry(evsel, &evlist->core.entries, core.node) { er = perf_evsel__get_runtime(evsel); if (er == NULL) { pr_err("Failed to allocate memory for evsel runtime data\n"); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 29dbf99f6081..bcd033e91de4 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3980,7 +3980,7 @@ static int trace__parse_cgroups(const struct option *opt, const char *str, int u { struct trace *trace = opt->value; - if (!list_empty(&trace->evlist->entries)) + if (!list_empty(&trace->evlist->core.entries)) return parse_cgroups(opt, str, unset); trace->cgroup = evlist__findnew_cgroup(trace->evlist, str); diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 280347499c50..ed5406ff9fe4 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -3309,13 +3309,13 @@ browse_hists: ui_browser__show_title(&menu->b, title); switch (key) { case K_TAB: - if (pos->core.node.next == &evlist->entries) + if (pos->core.node.next == &evlist->core.entries) pos = perf_evlist__first(evlist); else pos = perf_evsel__next(pos); goto browse_hists; case K_UNTAB: - if (pos->core.node.prev == &evlist->entries) + if (pos->core.node.prev == &evlist->core.entries) pos = perf_evlist__last(evlist); else pos = perf_evsel__prev(pos); @@ -3370,7 +3370,7 @@ static int __perf_evlist__tui_browse_hists(struct evlist *evlist, struct evsel *pos; struct evsel_menu menu = { .b = { - .entries = &evlist->entries, + .entries = &evlist->core.entries, .refresh = ui_browser__list_head_refresh, .seek = ui_browser__list_head_seek, .write = perf_evsel_menu__write, diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index deb87ecd3671..f73599f271ff 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -208,7 +208,7 @@ int parse_cgroups(const struct option *opt, const char *str, char *s; int ret, i; - if (list_empty(&evlist->entries)) { + if (list_empty(&evlist->core.entries)) { fprintf(stderr, "must define events before cgroups\n"); return -1; } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 227576bf16c0..faf3ffd81d4c 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -48,7 +48,7 @@ void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i) INIT_HLIST_HEAD(&evlist->heads[i]); - INIT_LIST_HEAD(&evlist->entries); + INIT_LIST_HEAD(&evlist->core.entries); perf_evlist__set_maps(evlist, cpus, threads); fdarray__init(&evlist->pollfd, 64); evlist->workload.pid = -1; @@ -180,7 +180,7 @@ static void perf_evlist__propagate_maps(struct evlist *evlist) void evlist__add(struct evlist *evlist, struct evsel *entry) { entry->evlist = evlist; - list_add_tail(&entry->core.node, &evlist->entries); + list_add_tail(&entry->core.node, &evlist->core.entries); entry->idx = evlist->nr_entries; entry->tracking = !entry->idx; @@ -226,7 +226,7 @@ void perf_evlist__set_leader(struct evlist *evlist) { if (evlist->nr_entries) { evlist->nr_groups = evlist->nr_entries > 1 ? 1 : 0; - __perf_evlist__set_leader(&evlist->entries); + __perf_evlist__set_leader(&evlist->core.entries); } } @@ -1683,7 +1683,7 @@ void perf_evlist__to_front(struct evlist *evlist, list_move_tail(&evsel->core.node, &move); } - list_splice(&move, &evlist->entries); + list_splice(&move, &evlist->core.entries); } void perf_evlist__set_tracking_event(struct evlist *evlist, diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 1315e64ad69e..7117378a08e3 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "../perf.h" #include "event.h" #include "evsel.h" @@ -25,7 +26,7 @@ struct record_opts; #define PERF_EVLIST__HLIST_SIZE (1 << PERF_EVLIST__HLIST_BITS) struct evlist { - struct list_head entries; + struct perf_evlist core; struct hlist_head heads[PERF_EVLIST__HLIST_SIZE]; int nr_entries; int nr_groups; @@ -225,17 +226,17 @@ void perf_evlist__splice_list_tail(struct evlist *evlist, static inline bool perf_evlist__empty(struct evlist *evlist) { - return list_empty(&evlist->entries); + return list_empty(&evlist->core.entries); } static inline struct evsel *perf_evlist__first(struct evlist *evlist) { - return list_entry(evlist->entries.next, struct evsel, core.node); + return list_entry(evlist->core.entries.next, struct evsel, core.node); } static inline struct evsel *perf_evlist__last(struct evlist *evlist) { - return list_entry(evlist->entries.prev, struct evsel, core.node); + return list_entry(evlist->core.entries.prev, struct evsel, core.node); } size_t perf_evlist__fprintf(struct evlist *evlist, FILE *fp); @@ -261,7 +262,7 @@ void perf_evlist__to_front(struct evlist *evlist, * @evsel: struct evsel iterator */ #define evlist__for_each_entry(evlist, evsel) \ - __evlist__for_each_entry(&(evlist)->entries, evsel) + __evlist__for_each_entry(&(evlist)->core.entries, evsel) /** * __evlist__for_each_entry_continue - continue iteration thru all the evsels @@ -277,7 +278,7 @@ void perf_evlist__to_front(struct evlist *evlist, * @evsel: struct evsel iterator */ #define evlist__for_each_entry_continue(evlist, evsel) \ - __evlist__for_each_entry_continue(&(evlist)->entries, evsel) + __evlist__for_each_entry_continue(&(evlist)->core.entries, evsel) /** * __evlist__for_each_entry_reverse - iterate thru all the evsels in reverse order @@ -293,7 +294,7 @@ void perf_evlist__to_front(struct evlist *evlist, * @evsel: struct evsel iterator */ #define evlist__for_each_entry_reverse(evlist, evsel) \ - __evlist__for_each_entry_reverse(&(evlist)->entries, evsel) + __evlist__for_each_entry_reverse(&(evlist)->core.entries, evsel) /** * __evlist__for_each_entry_safe - safely iterate thru all the evsels @@ -311,7 +312,7 @@ void perf_evlist__to_front(struct evlist *evlist, * @tmp: struct evsel temp iterator */ #define evlist__for_each_entry_safe(evlist, tmp, evsel) \ - __evlist__for_each_entry_safe(&(evlist)->entries, tmp, evsel) + __evlist__for_each_entry_safe(&(evlist)->core.entries, tmp, evsel) void perf_evlist__set_tracking_event(struct evlist *evlist, struct evsel *tracking_evsel); diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 5e0093251f26..70ab6b8c715b 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -304,7 +304,7 @@ static int write_tracing_data(struct feat_fd *ff, if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__)) return -1; - return read_tracing_data(ff->fd, &evlist->entries); + return read_tracing_data(ff->fd, &evlist->core.entries); } static int write_build_id(struct feat_fd *ff, @@ -4112,7 +4112,7 @@ int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, * - write the tracing data from the temp file * to the pipe */ - tdata = tracing_data_get(&evlist->entries, fd, true); + tdata = tracing_data_get(&evlist->core.entries, fd, true); if (!tdata) return -1; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index e111c0e0a5ac..a0b7d68d2f8e 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -2050,7 +2050,7 @@ foreach_evsel_in_last_glob(struct evlist *evlist, if (!last) return 0; - if (last->core.node.prev == &evlist->entries) + if (last->core.node.prev == &evlist->core.entries) return 0; last = list_entry(last->core.node.prev, struct evsel, core.node); } while (!last->cmdline_group_boundary); diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 17b7d3b55b5f..b1a2571f7c8f 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -548,8 +548,8 @@ static void collect_all_aliases(struct perf_stat_config *config, struct evsel *c struct evlist *evlist = counter->evlist; struct evsel *alias; - alias = list_prepare_entry(counter, &(evlist->entries), core.node); - list_for_each_entry_continue (alias, &evlist->entries, core.node) { + alias = list_prepare_entry(counter, &(evlist->core.entries), core.node); + list_for_each_entry_continue (alias, &evlist->core.entries, core.node) { if (strcmp(perf_evsel__name(alias), perf_evsel__name(counter)) || alias->scale != counter->scale || alias->cgrp != counter->cgrp || -- cgit v1.2.3-59-g8ed1b From b04c597af761ccfd32f40ee3629843b6f3674fce Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:24 +0200 Subject: libperf: Add perf_evsel__init function Add the perf_evsel__init() function to initialize perf_evsel struct. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-38-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evsel.c | 5 +++++ tools/perf/lib/include/perf/evsel.h | 4 ++++ tools/perf/lib/libperf.map | 1 + tools/perf/util/evsel.c | 3 ++- 4 files changed, 12 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/lib/evsel.c b/tools/perf/lib/evsel.c index 12e86de1994b..9a87e867a7ec 100644 --- a/tools/perf/lib/evsel.c +++ b/tools/perf/lib/evsel.c @@ -2,3 +2,8 @@ #include #include #include + +void perf_evsel__init(struct perf_evsel *evsel) +{ + INIT_LIST_HEAD(&evsel->node); +} diff --git a/tools/perf/lib/include/perf/evsel.h b/tools/perf/lib/include/perf/evsel.h index 162bffd43409..b4d074a3684b 100644 --- a/tools/perf/lib/include/perf/evsel.h +++ b/tools/perf/lib/include/perf/evsel.h @@ -2,6 +2,10 @@ #ifndef __LIBPERF_EVSEL_H #define __LIBPERF_EVSEL_H +#include + struct perf_evsel; +LIBPERF_API void perf_evsel__init(struct perf_evsel *evsel); + #endif /* __LIBPERF_EVSEL_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index c4f611010ccc..54f8503c6d82 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -9,6 +9,7 @@ LIBPERF_0.0.1 { perf_thread_map__comm; perf_thread_map__get; perf_thread_map__put; + perf_evsel__init; local: *; }; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 8fed22d889a4..172bcc2e198f 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "asm/bug.h" #include "callchain.h" #include "cgroup.h" @@ -226,6 +227,7 @@ bool perf_evsel__is_function_event(struct evsel *evsel) void evsel__init(struct evsel *evsel, struct perf_event_attr *attr, int idx) { + perf_evsel__init(&evsel->core); evsel->idx = idx; evsel->tracking = !idx; evsel->attr = *attr; @@ -236,7 +238,6 @@ void evsel__init(struct evsel *evsel, evsel->evlist = NULL; evsel->bpf_obj = NULL; evsel->bpf_fd = -1; - INIT_LIST_HEAD(&evsel->core.node); INIT_LIST_HEAD(&evsel->config_terms); perf_evsel__object.init(evsel); evsel->sample_size = __perf_evsel__sample_size(attr->sample_type); -- cgit v1.2.3-59-g8ed1b From 4562a7393996bb28bf629277903a561bfefea177 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:25 +0200 Subject: libperf: Add perf_evlist__init() function Add the perf_evlist__init() function to initialize a perf_evlist struct. Committer testing: Fix a change in init ordering that was causing this backtrace: (gdb) run stat sleep 1 Starting program: /root/bin/perf stat sleep 1 Program received signal SIGSEGV, Segmentation fault. 0x00000000004f6b55 in __perf_evlist__propagate_maps (evlist=0xbb34c0, evsel=0x0) at util/evlist.c:161 161 if (!evsel->own_cpus || evlist->has_user_cpus) { Missing separate debuginfos, use: dnf debuginfo-install bzip2-libs-1.0.6-29.fc30.x86_64 elfutils-libelf-0.176-3.fc30.x86_64 elfutils-libs-0.176-3.fc30.x86_64 glib2-2.60.4-1.fc30.x86_64 libbabeltrace-1.5.6-2.fc30.x86_64 libgcc-9.1.1-1.fc30.x86_64 libunwind-1.3.1-2.fc30.x86_64 libuuid-2.33.2-1.fc30.x86_64 libxcrypt-4.4.6-2.fc30.x86_64 libzstd-1.4.0-1.fc30.x86_64 numactl-libs-2.0.12-2.fc30.x86_64 pcre-8.43-2.fc30.x86_64 perl-libs-5.28.2-436.fc30.x86_64 popt-1.16-17.fc30.x86_64 python2-libs-2.7.16-2.fc30.x86_64 slang-2.3.2-5.fc30.x86_64 xz-libs-5.2.4-5.fc30.x86_64 zlib-1.2.11-15.fc30.x86_64 (gdb) bt #0 0x00000000004f6b55 in __perf_evlist__propagate_maps (evlist=0xbb34c0, evsel=0x0) at util/evlist.c:161 #1 0x00000000004f6c7a in perf_evlist__propagate_maps (evlist=0xbb34c0) at util/evlist.c:178 #2 0x00000000004f955e in perf_evlist__set_maps (evlist=0xbb34c0, cpus=0x0, threads=0x0) at util/evlist.c:1128 #3 0x00000000004f66f8 in evlist__init (evlist=0xbb34c0, cpus=0x0, threads=0x0) at util/evlist.c:52 #4 0x00000000004f6790 in evlist__new () at util/evlist.c:64 #5 0x0000000000456071 in cmd_stat (argc=3, argv=0x7fffffffd670) at builtin-stat.c:1705 #6 0x00000000004dd0fa in run_builtin (p=0xa21e00 , argc=3, argv=0x7fffffffd670) at perf.c:304 #7 0x00000000004dd367 in handle_internal_command (argc=3, argv=0x7fffffffd670) at perf.c:356 #8 0x00000000004dd4ae in run_argv (argcp=0x7fffffffd4cc, argv=0x7fffffffd4c0) at perf.c:400 #9 0x00000000004dd81a in main (argc=3, argv=0x7fffffffd670) at perf.c:522 (gdb) bt So move the initialization of the core evlist (calling perf_evlist__init()) to before perf_evlist__set_maps() in evlist__init(). Signed-off-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-39-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evlist.c | 5 +++++ tools/perf/lib/include/perf/evlist.h | 4 ++++ tools/perf/lib/libperf.map | 1 + tools/perf/util/evlist.c | 3 ++- 4 files changed, 12 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c index 646bdd518793..fdc8c1894b37 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/perf/lib/evlist.c @@ -2,3 +2,8 @@ #include #include #include + +void perf_evlist__init(struct perf_evlist *evlist) +{ + INIT_LIST_HEAD(&evlist->entries); +} diff --git a/tools/perf/lib/include/perf/evlist.h b/tools/perf/lib/include/perf/evlist.h index 92b0eb39caec..1ddfcca0bd01 100644 --- a/tools/perf/lib/include/perf/evlist.h +++ b/tools/perf/lib/include/perf/evlist.h @@ -2,6 +2,10 @@ #ifndef __LIBPERF_EVLIST_H #define __LIBPERF_EVLIST_H +#include + struct perf_evlist; +LIBPERF_API void perf_evlist__init(struct perf_evlist *evlist); + #endif /* __LIBPERF_EVLIST_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 54f8503c6d82..5ca6ff6fcdfa 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -10,6 +10,7 @@ LIBPERF_0.0.1 { perf_thread_map__get; perf_thread_map__put; perf_evsel__init; + perf_evlist__init; local: *; }; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index faf3ffd81d4c..f4aa6cf80559 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef LACKS_SIGQUEUE_PROTOTYPE int sigqueue(pid_t pid, int sig, const union sigval value); @@ -48,7 +49,7 @@ void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i) INIT_HLIST_HEAD(&evlist->heads[i]); - INIT_LIST_HEAD(&evlist->core.entries); + perf_evlist__init(&evlist->core); perf_evlist__set_maps(evlist, cpus, threads); fdarray__init(&evlist->pollfd, 64); evlist->workload.pid = -1; -- cgit v1.2.3-59-g8ed1b From 9a5edde6d3a6fb26101406534f7a5d09a9fcd362 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:26 +0200 Subject: libperf: Add perf_evlist__add() function Add the perf_evlist__add() function to add a perf_evsel in a perf_evlist struct. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-40-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evlist.c | 7 +++++++ tools/perf/lib/include/perf/evlist.h | 3 +++ tools/perf/lib/libperf.map | 1 + tools/perf/util/evlist.c | 2 +- 4 files changed, 12 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c index fdc8c1894b37..e5f187fa4e57 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/perf/lib/evlist.c @@ -2,8 +2,15 @@ #include #include #include +#include void perf_evlist__init(struct perf_evlist *evlist) { INIT_LIST_HEAD(&evlist->entries); } + +void perf_evlist__add(struct perf_evlist *evlist, + struct perf_evsel *evsel) +{ + list_add_tail(&evsel->node, &evlist->entries); +} diff --git a/tools/perf/lib/include/perf/evlist.h b/tools/perf/lib/include/perf/evlist.h index 1ddfcca0bd01..6992568b14a0 100644 --- a/tools/perf/lib/include/perf/evlist.h +++ b/tools/perf/lib/include/perf/evlist.h @@ -5,7 +5,10 @@ #include struct perf_evlist; +struct perf_evsel; LIBPERF_API void perf_evlist__init(struct perf_evlist *evlist); +LIBPERF_API void perf_evlist__add(struct perf_evlist *evlist, + struct perf_evsel *evsel); #endif /* __LIBPERF_EVLIST_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 5ca6ff6fcdfa..06ccf31eb24d 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -11,6 +11,7 @@ LIBPERF_0.0.1 { perf_thread_map__put; perf_evsel__init; perf_evlist__init; + perf_evlist__add; local: *; }; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index f4aa6cf80559..f2b86f49ab8d 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -180,8 +180,8 @@ static void perf_evlist__propagate_maps(struct evlist *evlist) void evlist__add(struct evlist *evlist, struct evsel *entry) { + perf_evlist__add(&evlist->core, &entry->core); entry->evlist = evlist; - list_add_tail(&entry->core.node, &evlist->core.entries); entry->idx = evlist->nr_entries; entry->tracking = !entry->idx; -- cgit v1.2.3-59-g8ed1b From 52e22fb8af779e1a26b1cbde1db2f82f78b3ae68 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:27 +0200 Subject: libperf: Add perf_evlist__remove() function Adding perf_evlist__remove() function to remove a perf_evsel from a perf_evlist struct. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-41-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evlist.c | 6 ++++++ tools/perf/lib/include/perf/evlist.h | 2 ++ tools/perf/lib/libperf.map | 1 + tools/perf/util/evlist.c | 2 +- 4 files changed, 10 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c index e5f187fa4e57..023fe4b44131 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/perf/lib/evlist.c @@ -14,3 +14,9 @@ void perf_evlist__add(struct perf_evlist *evlist, { list_add_tail(&evsel->node, &evlist->entries); } + +void perf_evlist__remove(struct perf_evlist *evlist, + struct perf_evsel *evsel) +{ + list_del_init(&evsel->node); +} diff --git a/tools/perf/lib/include/perf/evlist.h b/tools/perf/lib/include/perf/evlist.h index 6992568b14a0..e0c87995c6ff 100644 --- a/tools/perf/lib/include/perf/evlist.h +++ b/tools/perf/lib/include/perf/evlist.h @@ -10,5 +10,7 @@ struct perf_evsel; LIBPERF_API void perf_evlist__init(struct perf_evlist *evlist); LIBPERF_API void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *evsel); +LIBPERF_API void perf_evlist__remove(struct perf_evlist *evlist, + struct perf_evsel *evsel); #endif /* __LIBPERF_EVLIST_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 06ccf31eb24d..168339f89a2e 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -12,6 +12,7 @@ LIBPERF_0.0.1 { perf_evsel__init; perf_evlist__init; perf_evlist__add; + perf_evlist__remove; local: *; }; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index f2b86f49ab8d..9b0108c23010 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -194,7 +194,7 @@ void evlist__add(struct evlist *evlist, struct evsel *entry) void evlist__remove(struct evlist *evlist, struct evsel *evsel) { evsel->evlist = NULL; - list_del_init(&evsel->core.node); + perf_evlist__remove(&evlist->core, &evsel->core); evlist->nr_entries -= 1; } -- cgit v1.2.3-59-g8ed1b From 6484d2f9dc3ecbf13f07100f7f771d1d779eda04 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:28 +0200 Subject: libperf: Add nr_entries to struct perf_evlist Move nr_entries count from 'struct perf' to into perf_evlist struct. Committer notes: Fix tools/perf/arch/s390/util/auxtrace.c case. And also the comment in tools/perf/util/annotate.h. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-42-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/s390/util/auxtrace.c | 2 +- tools/perf/builtin-record.c | 4 +- tools/perf/builtin-stat.c | 4 +- tools/perf/builtin-top.c | 12 ++--- tools/perf/builtin-trace.c | 4 +- tools/perf/lib/evlist.c | 3 ++ tools/perf/lib/include/internal/evlist.h | 1 + tools/perf/tests/parse-events.c | 76 ++++++++++++++++---------------- tools/perf/ui/browsers/annotate.c | 2 +- tools/perf/ui/browsers/hists.c | 2 +- tools/perf/util/annotate.c | 2 +- tools/perf/util/annotate.h | 2 +- tools/perf/util/evlist.c | 26 +++++------ tools/perf/util/evlist.h | 1 - tools/perf/util/header.c | 4 +- tools/perf/util/parse-events.c | 4 +- tools/perf/util/python.c | 8 ++-- tools/perf/util/record.c | 2 +- tools/perf/util/sort.c | 2 +- tools/perf/util/top.c | 2 +- 20 files changed, 83 insertions(+), 80 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/s390/util/auxtrace.c b/tools/perf/arch/s390/util/auxtrace.c index 833f60fa9c5a..480ada281bdb 100644 --- a/tools/perf/arch/s390/util/auxtrace.c +++ b/tools/perf/arch/s390/util/auxtrace.c @@ -90,7 +90,7 @@ struct auxtrace_record *auxtrace_record__init(struct evlist *evlist, int diagnose = 0; *err = 0; - if (evlist->nr_entries == 0) + if (evlist->core.nr_entries == 0) return NULL; evlist__for_each_entry(evlist, pos) { diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 17bb0a536da3..778e46417f6b 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1375,7 +1375,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) * because we synthesize event name through the pipe * and need the id for that. */ - if (data->is_pipe && rec->evlist->nr_entries == 1) + if (data->is_pipe && rec->evlist->core.nr_entries == 1) rec->opts.sample_id = true; if (record__open(rec) != 0) { @@ -2386,7 +2386,7 @@ int cmd_record(int argc, const char **argv) if (record.opts.overwrite) record.opts.tail_synthesize = true; - if (rec->evlist->nr_entries == 0 && + if (rec->evlist->core.nr_entries == 0 && __perf_evlist__add_default(rec->evlist, !record.opts.no_samples) < 0) { pr_err("Not enough memory for event selector list\n"); goto out; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 39bd73d0e06e..3ba184f2e64f 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1366,7 +1366,7 @@ static int add_default_attributes(void) free(str); } - if (!evsel_list->nr_entries) { + if (!evsel_list->core.nr_entries) { if (target__has_cpu(&target)) default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK; @@ -1683,7 +1683,7 @@ static void setup_system_wide(int forks) return; } - if (evsel_list->nr_entries) + if (evsel_list->core.nr_entries) target.system_wide = true; } } diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index b103f1ba01cb..3291eff13e28 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -129,7 +129,7 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) notes = symbol__annotation(sym); pthread_mutex_lock(¬es->lock); - if (!symbol__hists(sym, top->evlist->nr_entries)) { + if (!symbol__hists(sym, top->evlist->core.nr_entries)) { pthread_mutex_unlock(¬es->lock); pr_err("Not enough memory for annotating '%s' symbol!\n", sym->name); @@ -404,7 +404,7 @@ static void perf_top__print_mapped_keys(struct perf_top *top) fprintf(stdout, "\t[d] display refresh delay. \t(%d)\n", top->delay_secs); fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", top->print_entries); - if (top->evlist->nr_entries > 1) + if (top->evlist->core.nr_entries > 1) fprintf(stdout, "\t[E] active event counter. \t(%s)\n", perf_evsel__name(top->sym_evsel)); fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", top->count_filter); @@ -439,7 +439,7 @@ static int perf_top__key_mapped(struct perf_top *top, int c) case 'S': return 1; case 'E': - return top->evlist->nr_entries > 1 ? 1 : 0; + return top->evlist->core.nr_entries > 1 ? 1 : 0; default: break; } @@ -485,7 +485,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c) } break; case 'E': - if (top->evlist->nr_entries > 1) { + if (top->evlist->core.nr_entries > 1) { /* Select 0 as the default event: */ int counter = 0; @@ -496,7 +496,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c) prompt_integer(&counter, "Enter details event counter"); - if (counter >= top->evlist->nr_entries) { + if (counter >= top->evlist->core.nr_entries) { top->sym_evsel = perf_evlist__first(top->evlist); fprintf(stderr, "Sorry, no such event, using %s.\n", perf_evsel__name(top->sym_evsel)); sleep(1); @@ -1536,7 +1536,7 @@ int cmd_top(int argc, const char **argv) if (argc) usage_with_options(top_usage, options); - if (!top.evlist->nr_entries && + if (!top.evlist->core.nr_entries && perf_evlist__add_default(top.evlist) < 0) { pr_err("Not enough memory for event selector list\n"); goto out_delete_evlist; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index bcd033e91de4..06fcd8b1f160 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -4270,7 +4270,7 @@ int cmd_trace(int argc, const char **argv) symbol_conf.use_callchain = true; } - if (trace.evlist->nr_entries > 0) { + if (trace.evlist->core.nr_entries > 0) { evlist__set_evsel_handler(trace.evlist, trace__event_handler); if (evlist__set_syscall_tp_fields(trace.evlist)) { perror("failed to set syscalls:* tracepoint fields"); @@ -4368,7 +4368,7 @@ init_augmented_syscall_tp: trace.summary = trace.summary_only; if (!trace.trace_syscalls && !trace.trace_pgfaults && - trace.evlist->nr_entries == 0 /* Was --events used? */) { + trace.evlist->core.nr_entries == 0 /* Was --events used? */) { trace.trace_syscalls = true; } diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c index 023fe4b44131..1b27fd2de9b9 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/perf/lib/evlist.c @@ -7,16 +7,19 @@ void perf_evlist__init(struct perf_evlist *evlist) { INIT_LIST_HEAD(&evlist->entries); + evlist->nr_entries = 0; } void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *evsel) { list_add_tail(&evsel->node, &evlist->entries); + evlist->nr_entries += 1; } void perf_evlist__remove(struct perf_evlist *evlist, struct perf_evsel *evsel) { list_del_init(&evsel->node); + evlist->nr_entries -= 1; } diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h index 7fbfe5716652..a12c712a9197 100644 --- a/tools/perf/lib/include/internal/evlist.h +++ b/tools/perf/lib/include/internal/evlist.h @@ -4,6 +4,7 @@ struct perf_evlist { struct list_head entries; + int nr_entries; }; #endif /* __LIBPERF_INTERNAL_EVLIST_H */ diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 2365dd655c88..878140501edf 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -48,7 +48,7 @@ static int test__checkevent_tracepoint(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong number of groups", 0 == evlist->nr_groups); TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); TEST_ASSERT_VAL("wrong sample_type", @@ -61,7 +61,7 @@ static int test__checkevent_tracepoint_multi(struct evlist *evlist) { struct evsel *evsel; - TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); + TEST_ASSERT_VAL("wrong number of entries", evlist->core.nr_entries > 1); TEST_ASSERT_VAL("wrong number of groups", 0 == evlist->nr_groups); evlist__for_each_entry(evlist, evsel) { @@ -79,7 +79,7 @@ static int test__checkevent_raw(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 0x1a == evsel->attr.config); return 0; @@ -89,7 +89,7 @@ static int test__checkevent_numeric(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); return 0; @@ -99,7 +99,7 @@ static int test__checkevent_symbolic_name(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); TEST_ASSERT_VAL("wrong config", PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); @@ -110,7 +110,7 @@ static int test__checkevent_symbolic_name_config(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); TEST_ASSERT_VAL("wrong config", PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); @@ -131,7 +131,7 @@ static int test__checkevent_symbolic_alias(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type); TEST_ASSERT_VAL("wrong config", PERF_COUNT_SW_PAGE_FAULTS == evsel->attr.config); @@ -142,7 +142,7 @@ static int test__checkevent_genhw(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->attr.type); TEST_ASSERT_VAL("wrong config", (1 << 16) == evsel->attr.config); return 0; @@ -152,7 +152,7 @@ static int test__checkevent_breakpoint(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); TEST_ASSERT_VAL("wrong bp_type", (HW_BREAKPOINT_R | HW_BREAKPOINT_W) == @@ -166,7 +166,7 @@ static int test__checkevent_breakpoint_x(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); TEST_ASSERT_VAL("wrong bp_type", @@ -179,7 +179,7 @@ static int test__checkevent_breakpoint_r(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); @@ -194,7 +194,7 @@ static int test__checkevent_breakpoint_w(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); @@ -209,7 +209,7 @@ static int test__checkevent_breakpoint_rw(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); @@ -237,7 +237,7 @@ test__checkevent_tracepoint_multi_modifier(struct evlist *evlist) { struct evsel *evsel; - TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); + TEST_ASSERT_VAL("wrong number of entries", evlist->core.nr_entries > 1); evlist__for_each_entry(evlist, evsel) { TEST_ASSERT_VAL("wrong exclude_user", @@ -437,7 +437,7 @@ static int test__checkevent_pmu(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 10 == evsel->attr.config); TEST_ASSERT_VAL("wrong config1", 1 == evsel->attr.config1); @@ -455,7 +455,7 @@ static int test__checkevent_list(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->core.nr_entries); /* r1 */ TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); @@ -495,14 +495,14 @@ static int test__checkevent_pmu_name(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); /* cpu/config=1,name=krava/u */ - TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "krava")); /* cpu/config=2/u" */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 2 == evsel->attr.config); TEST_ASSERT_VAL("wrong name", @@ -516,7 +516,7 @@ static int test__checkevent_pmu_partial_time_callgraph(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); /* cpu/config=1,call-graph=fp,time,period=100000/ */ - TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); /* @@ -548,7 +548,7 @@ static int test__checkevent_pmu_events(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); @@ -567,7 +567,7 @@ static int test__checkevent_pmu_events_mix(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); /* pmu-event:u */ - TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", @@ -578,7 +578,7 @@ static int test__checkevent_pmu_events_mix(struct evlist *evlist) /* cpu/pmu-event/u*/ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); @@ -638,7 +638,7 @@ static int test__group1(struct evlist *evlist) { struct evsel *evsel, *leader; - TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); /* instructions:k */ @@ -680,7 +680,7 @@ static int test__group2(struct evlist *evlist) { struct evsel *evsel, *leader; - TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); /* faults + :ku modifier */ @@ -735,7 +735,7 @@ static int test__group3(struct evlist *evlist __maybe_unused) { struct evsel *evsel, *leader; - TEST_ASSERT_VAL("wrong number of entries", 5 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 5 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong number of groups", 2 == evlist->nr_groups); /* group1 syscalls:sys_enter_openat:H */ @@ -827,7 +827,7 @@ static int test__group4(struct evlist *evlist __maybe_unused) { struct evsel *evsel, *leader; - TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); /* cycles:u + p */ @@ -871,7 +871,7 @@ static int test__group5(struct evlist *evlist __maybe_unused) { struct evsel *evsel, *leader; - TEST_ASSERT_VAL("wrong number of entries", 5 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 5 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong number of groups", 2 == evlist->nr_groups); /* cycles + G */ @@ -957,7 +957,7 @@ static int test__group_gh1(struct evlist *evlist) { struct evsel *evsel, *leader; - TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); /* cycles + :H group modifier */ @@ -997,7 +997,7 @@ static int test__group_gh2(struct evlist *evlist) { struct evsel *evsel, *leader; - TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); /* cycles + :G group modifier */ @@ -1037,7 +1037,7 @@ static int test__group_gh3(struct evlist *evlist) { struct evsel *evsel, *leader; - TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); /* cycles:G + :u group modifier */ @@ -1077,7 +1077,7 @@ static int test__group_gh4(struct evlist *evlist) { struct evsel *evsel, *leader; - TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); /* cycles:G + :uG group modifier */ @@ -1117,7 +1117,7 @@ static int test__leader_sample1(struct evlist *evlist) { struct evsel *evsel, *leader; - TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->core.nr_entries); /* cycles - sampling group leader */ evsel = leader = perf_evlist__first(evlist); @@ -1170,7 +1170,7 @@ static int test__leader_sample2(struct evlist *evlist __maybe_unused) { struct evsel *evsel, *leader; - TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); /* instructions - sampling group leader */ evsel = leader = perf_evlist__first(evlist); @@ -1222,7 +1222,7 @@ static int test__pinned_group(struct evlist *evlist) { struct evsel *evsel, *leader; - TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->core.nr_entries); /* cycles - group leader */ evsel = leader = perf_evlist__first(evlist); @@ -1253,7 +1253,7 @@ static int test__checkevent_breakpoint_len(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); TEST_ASSERT_VAL("wrong bp_type", (HW_BREAKPOINT_R | HW_BREAKPOINT_W) == @@ -1268,7 +1268,7 @@ static int test__checkevent_breakpoint_len_w(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); TEST_ASSERT_VAL("wrong bp_type", HW_BREAKPOINT_W == @@ -1296,7 +1296,7 @@ static int test__checkevent_precise_max_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type); TEST_ASSERT_VAL("wrong config", PERF_COUNT_SW_TASK_CLOCK == evsel->attr.config); @@ -1425,7 +1425,7 @@ static int count_tracepoints(void) static int test__all_tracepoints(struct evlist *evlist) { TEST_ASSERT_VAL("wrong events count", - count_tracepoints() == evlist->nr_entries); + count_tracepoints() == evlist->core.nr_entries); return test__checkevent_tracepoint_multi(evlist); } diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 64cc650c4543..e633eb42550d 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -422,7 +422,7 @@ static bool annotate_browser__callq(struct annotate_browser *browser, notes = symbol__annotation(dl->ops.target.sym); pthread_mutex_lock(¬es->lock); - if (!symbol__hists(dl->ops.target.sym, evsel->evlist->nr_entries)) { + if (!symbol__hists(dl->ops.target.sym, evsel->evlist->core.nr_entries)) { pthread_mutex_unlock(¬es->lock); ui__warning("Not enough memory for annotating '%s' symbol!\n", dl->ops.target.sym->name); diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index ed5406ff9fe4..b195b1ba625b 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -3404,7 +3404,7 @@ int perf_evlist__tui_browse_hists(struct evlist *evlist, const char *help, bool warn_lost_event, struct annotation_options *annotation_opts) { - int nr_entries = evlist->nr_entries; + int nr_entries = evlist->core.nr_entries; single_entry: if (nr_entries == 1) { diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 6ea5d678a81c..d46f2ae2c695 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -936,7 +936,7 @@ static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, if (sym == NULL) return 0; - src = symbol__hists(sym, evsel->evlist->nr_entries); + src = symbol__hists(sym, evsel->evlist->core.nr_entries); return (src) ? __symbol__inc_addr_samples(sym, map, src, evsel->idx, addr, sample) : 0; } diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 7c42f320efa2..d94be9140e31 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -245,7 +245,7 @@ struct cyc_hist { /** struct annotated_source - symbols with hits have this attached as in sannotation * * @histograms: Array of addr hit histograms per event being monitored - * nr_histograms: This may not be the same as evsel->evlist->nr_entries if + * nr_histograms: This may not be the same as evsel->evlist->core.nr_entries if * we have more than a group in a evlist, where we will want * to see each group separately, that is why symbol__annotate2() * sets src->nr_histograms to evsel->nr_members. diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 9b0108c23010..ce9f52215d60 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -125,7 +125,7 @@ static void perf_evlist__purge(struct evlist *evlist) evsel__delete(pos); } - evlist->nr_entries = 0; + evlist->core.nr_entries = 0; } void perf_evlist__exit(struct evlist *evlist) @@ -180,12 +180,13 @@ static void perf_evlist__propagate_maps(struct evlist *evlist) void evlist__add(struct evlist *evlist, struct evsel *entry) { - perf_evlist__add(&evlist->core, &entry->core); entry->evlist = evlist; - entry->idx = evlist->nr_entries; + entry->idx = evlist->core.nr_entries; entry->tracking = !entry->idx; - if (!evlist->nr_entries++) + perf_evlist__add(&evlist->core, &entry->core); + + if (evlist->core.nr_entries == 1) perf_evlist__set_id_pos(evlist); __perf_evlist__propagate_maps(evlist, entry); @@ -195,7 +196,6 @@ void evlist__remove(struct evlist *evlist, struct evsel *evsel) { evsel->evlist = NULL; perf_evlist__remove(&evlist->core, &evsel->core); - evlist->nr_entries -= 1; } void perf_evlist__splice_list_tail(struct evlist *evlist, @@ -225,8 +225,8 @@ void __perf_evlist__set_leader(struct list_head *list) void perf_evlist__set_leader(struct evlist *evlist) { - if (evlist->nr_entries) { - evlist->nr_groups = evlist->nr_entries > 1 ? 1 : 0; + if (evlist->core.nr_entries) { + evlist->nr_groups = evlist->core.nr_entries > 1 ? 1 : 0; __perf_evlist__set_leader(&evlist->core.entries); } } @@ -249,7 +249,7 @@ int perf_evlist__add_dummy(struct evlist *evlist) .config = PERF_COUNT_SW_DUMMY, .size = sizeof(attr), /* to capture ABI version */ }; - struct evsel *evsel = perf_evsel__new_idx(&attr, evlist->nr_entries); + struct evsel *evsel = perf_evsel__new_idx(&attr, evlist->core.nr_entries); if (evsel == NULL) return -ENOMEM; @@ -266,7 +266,7 @@ static int evlist__add_attrs(struct evlist *evlist, size_t i; for (i = 0; i < nr_attrs; i++) { - evsel = perf_evsel__new_idx(attrs + i, evlist->nr_entries + i); + evsel = perf_evsel__new_idx(attrs + i, evlist->core.nr_entries + i); if (evsel == NULL) goto out_delete_partial_list; list_add_tail(&evsel->core.node, &head); @@ -581,7 +581,7 @@ struct evsel *perf_evlist__id2evsel(struct evlist *evlist, u64 id) { struct perf_sample_id *sid; - if (evlist->nr_entries == 1 || !id) + if (evlist->core.nr_entries == 1 || !id) return perf_evlist__first(evlist); sid = perf_evlist__id2sid(evlist, id); @@ -639,7 +639,7 @@ struct evsel *perf_evlist__event2evsel(struct evlist *evlist, int hash; u64 id; - if (evlist->nr_entries == 1) + if (evlist->core.nr_entries == 1) return first; if (!first->attr.sample_id_all && @@ -1222,7 +1222,7 @@ bool perf_evlist__valid_sample_type(struct evlist *evlist) { struct evsel *pos; - if (evlist->nr_entries == 1) + if (evlist->core.nr_entries == 1) return true; if (evlist->id_pos < 0 || evlist->is_pos < 0) @@ -1849,7 +1849,7 @@ int perf_evlist__add_sb_event(struct evlist **evlist, attr->sample_id_all = 1; } - evsel = perf_evsel__new_idx(attr, (*evlist)->nr_entries); + evsel = perf_evsel__new_idx(attr, (*evlist)->core.nr_entries); if (!evsel) goto out_err; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 7117378a08e3..17dd83021a79 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -28,7 +28,6 @@ struct record_opts; struct evlist { struct perf_evlist core; struct hlist_head heads[PERF_EVLIST__HLIST_SIZE]; - int nr_entries; int nr_groups; int nr_mmaps; bool enabled; diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 70ab6b8c715b..141de4425100 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -476,7 +476,7 @@ static int write_event_desc(struct feat_fd *ff, u32 nre, nri, sz; int ret; - nre = evlist->nr_entries; + nre = evlist->core.nr_entries; /* * write number of events @@ -3100,7 +3100,7 @@ int perf_session__write_header(struct perf_session *session, .attr_size = sizeof(f_attr), .attrs = { .offset = attr_offset, - .size = evlist->nr_entries * sizeof(f_attr), + .size = evlist->core.nr_entries * sizeof(f_attr), }, .data = { .offset = header->data_offset, diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index a0b7d68d2f8e..10efc33c56a1 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1909,7 +1909,7 @@ int parse_events(struct evlist *evlist, const char *str, { struct parse_events_state parse_state = { .list = LIST_HEAD_INIT(parse_state.list), - .idx = evlist->nr_entries, + .idx = evlist->core.nr_entries, .error = err, .evlist = evlist, }; @@ -2040,7 +2040,7 @@ foreach_evsel_in_last_glob(struct evlist *evlist, * * So no need to WARN here, let *func do this. */ - if (evlist->nr_entries > 0) + if (evlist->core.nr_entries > 0) last = perf_evlist__last(evlist); do { diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 19d2feee91d5..cf0a18d49018 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -973,10 +973,10 @@ static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist, Py_INCREF(pevsel); evsel = &((struct pyrf_evsel *)pevsel)->evsel; - evsel->idx = evlist->nr_entries; + evsel->idx = evlist->core.nr_entries; evlist__add(evlist, evsel); - return Py_BuildValue("i", evlist->nr_entries); + return Py_BuildValue("i", evlist->core.nr_entries); } static struct perf_mmap *get_md(struct evlist *evlist, int cpu) @@ -1112,7 +1112,7 @@ static Py_ssize_t pyrf_evlist__length(PyObject *obj) { struct pyrf_evlist *pevlist = (void *)obj; - return pevlist->evlist.nr_entries; + return pevlist->evlist.core.nr_entries; } static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i) @@ -1120,7 +1120,7 @@ static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i) struct pyrf_evlist *pevlist = (void *)obj; struct evsel *pos; - if (i >= pevlist->evlist.nr_entries) + if (i >= pevlist->evlist.core.nr_entries) return NULL; evlist__for_each_entry(&pevlist->evlist, pos) { diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index fecccfd71aa1..3d3d732498e1 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -166,7 +166,7 @@ void perf_evlist__config(struct evlist *evlist, struct record_opts *opts, */ use_sample_identifier = perf_can_sample_identifier(); sample_id = true; - } else if (evlist->nr_entries > 1) { + } else if (evlist->core.nr_entries > 1) { struct evsel *first = perf_evlist__first(evlist); evlist__for_each_entry(evlist, evsel) { diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index d8e4392d6e18..fa3cc2112b82 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -2323,7 +2323,7 @@ static struct evsel *find_evsel(struct evlist *evlist, char *event_name) if (event_name[0] == '%') { int nr = strtol(event_name+1, NULL, 0); - if (nr > evlist->nr_entries) + if (nr > evlist->core.nr_entries) return NULL; evsel = perf_evlist__first(evlist); diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c index 9f098db76e3c..3bbbdac2c550 100644 --- a/tools/perf/util/top.c +++ b/tools/perf/util/top.c @@ -70,7 +70,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) esamples_percent); } - if (top->evlist->nr_entries == 1) { + if (top->evlist->core.nr_entries == 1) { struct evsel *first = perf_evlist__first(top->evlist); ret += SNPRINTF(bf + ret, size - ret, "%" PRIu64 "%s ", (uint64_t)first->attr.sample_period, -- cgit v1.2.3-59-g8ed1b From 1fc632cef4ea137bc45fd0fc4cb902e374064163 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:29 +0200 Subject: libperf: Move perf_event_attr field from perf's evsel to libperf's perf_evsel Move the perf_event_attr struct fron 'struct evsel' to 'struct perf_evsel'. Committer notes: Fixed up these: tools/perf/arch/arm/util/auxtrace.c tools/perf/arch/arm/util/cs-etm.c tools/perf/arch/arm64/util/arm-spe.c tools/perf/arch/s390/util/auxtrace.c tools/perf/util/cs-etm.c Also cc1: warnings being treated as errors tests/sample-parsing.c: In function 'do_test': tests/sample-parsing.c:162: error: missing initializer tests/sample-parsing.c:162: error: (near initialization for 'evsel.core.cpus') struct evsel evsel = { .needs_swap = false, - .core.attr = { - .sample_type = sample_type, - .read_format = read_format, + .core = { + . attr = { + .sample_type = sample_type, + .read_format = read_format, + }, [perfbuilder@a70e4eeb5549 /]$ gcc --version |& head -1 gcc (GCC) 4.4.7 Also we don't need to include perf_event.h in tools/perf/lib/include/perf/evsel.h, forward declaring 'struct perf_event_attr' is enough. And this even fixes the build in some systems where things are used somewhere down the include path from perf_event.h without defining __always_inline. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-43-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/auxtrace.c | 4 +- tools/perf/arch/arm/util/cs-etm.c | 28 +- tools/perf/arch/arm64/util/arm-spe.c | 12 +- tools/perf/arch/s390/util/auxtrace.c | 2 +- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 6 +- tools/perf/arch/x86/util/auxtrace.c | 4 +- tools/perf/arch/x86/util/intel-bts.c | 16 +- tools/perf/arch/x86/util/intel-pt.c | 40 +- tools/perf/builtin-evlist.c | 2 +- tools/perf/builtin-inject.c | 14 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-script.c | 52 +- tools/perf/builtin-stat.c | 2 +- tools/perf/builtin-timechart.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 32 +- tools/perf/lib/evsel.c | 3 +- tools/perf/lib/include/internal/evsel.h | 4 + tools/perf/lib/include/perf/evsel.h | 4 +- tools/perf/tests/code-reading.c | 6 +- tools/perf/tests/event-times.c | 8 +- tools/perf/tests/keep-tracking.c | 6 +- tools/perf/tests/mmap-basic.c | 2 +- tools/perf/tests/parse-events.c | 872 ++++++++++----------- tools/perf/tests/sample-parsing.c | 12 +- tools/perf/tests/switch-tracking.c | 8 +- tools/perf/tests/task-exit.c | 14 +- tools/perf/ui/browsers/res_sample.c | 2 +- tools/perf/ui/browsers/scripts.c | 2 +- tools/perf/util/auxtrace.c | 2 +- tools/perf/util/bpf-loader.c | 2 +- tools/perf/util/cs-etm.c | 20 +- tools/perf/util/data-convert-bt.c | 14 +- tools/perf/util/db-export.c | 4 +- tools/perf/util/evlist.c | 50 +- tools/perf/util/evsel.c | 167 ++-- tools/perf/util/evsel.h | 17 +- tools/perf/util/evsel_fprintf.c | 8 +- tools/perf/util/header.c | 28 +- tools/perf/util/hist.c | 2 +- tools/perf/util/intel-bts.c | 18 +- tools/perf/util/intel-pt.c | 50 +- tools/perf/util/jitdump.c | 4 +- tools/perf/util/machine.c | 4 +- tools/perf/util/parse-events.c | 40 +- tools/perf/util/python.c | 6 +- tools/perf/util/record.c | 16 +- tools/perf/util/s390-cpumsf.c | 2 +- tools/perf/util/s390-sample-raw.c | 2 +- .../perf/util/scripting-engines/trace-event-perl.c | 6 +- .../util/scripting-engines/trace-event-python.c | 14 +- tools/perf/util/session.c | 20 +- tools/perf/util/sort.c | 12 +- tools/perf/util/stat-display.c | 8 +- tools/perf/util/stat-shadow.c | 30 +- tools/perf/util/stat.c | 2 +- tools/perf/util/top.c | 2 +- tools/perf/util/trace-event-info.c | 6 +- 59 files changed, 864 insertions(+), 857 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c index 306a54185438..41b78f74599f 100644 --- a/tools/perf/arch/arm/util/auxtrace.c +++ b/tools/perf/arch/arm/util/auxtrace.c @@ -70,14 +70,14 @@ struct auxtrace_record evlist__for_each_entry(evlist, evsel) { if (cs_etm_pmu && - evsel->attr.type == cs_etm_pmu->type) + evsel->core.attr.type == cs_etm_pmu->type) found_etm = true; if (!nr_spes) continue; for (i = 0; i < nr_spes; i++) { - if (evsel->attr.type == arm_spe_pmus[i]->type) { + if (evsel->core.attr.type == arm_spe_pmus[i]->type) { found_spe = true; break; } diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 3a78b38e43ca..f5aafdec7f50 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -95,7 +95,7 @@ static int cs_etm_set_context_id(struct auxtrace_record *itr, } /* All good, let the kernel know */ - evsel->attr.config |= (1 << ETM_OPT_CTXTID); + evsel->core.attr.config |= (1 << ETM_OPT_CTXTID); err = 0; out: @@ -144,7 +144,7 @@ static int cs_etm_set_timestamp(struct auxtrace_record *itr, } /* All good, let the kernel know */ - evsel->attr.config |= (1 << ETM_OPT_TS); + evsel->core.attr.config |= (1 << ETM_OPT_TS); err = 0; out: @@ -215,7 +215,7 @@ static int cs_etm_set_sink_attr(struct perf_pmu *pmu, int ret = -EINVAL; u32 hash; - if (evsel->attr.config2 & GENMASK(31, 0)) + if (evsel->core.attr.config2 & GENMASK(31, 0)) return 0; list_for_each_entry(term, &evsel->config_terms, list) { @@ -233,7 +233,7 @@ static int cs_etm_set_sink_attr(struct perf_pmu *pmu, return ret; } - evsel->attr.config2 |= hash; + evsel->core.attr.config2 |= hash; return 0; } @@ -264,14 +264,14 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, opts->record_switch_events = true; evlist__for_each_entry(evlist, evsel) { - if (evsel->attr.type == cs_etm_pmu->type) { + if (evsel->core.attr.type == cs_etm_pmu->type) { if (cs_etm_evsel) { pr_err("There may be only one %s event\n", CORESIGHT_ETM_PMU_NAME); return -EINVAL; } - evsel->attr.freq = 0; - evsel->attr.sample_period = 1; + evsel->core.attr.freq = 0; + evsel->core.attr.sample_period = 1; cs_etm_evsel = evsel; opts->full_auxtrace = true; } @@ -416,8 +416,8 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, tracking_evsel = perf_evlist__last(evlist); perf_evlist__set_tracking_event(evlist, tracking_evsel); - tracking_evsel->attr.freq = 0; - tracking_evsel->attr.sample_period = 1; + tracking_evsel->core.attr.freq = 0; + tracking_evsel->core.attr.sample_period = 1; /* In per-cpu case, always need the time of mmap events etc */ if (!cpu_map__empty(cpus)) @@ -438,7 +438,7 @@ static u64 cs_etm_get_config(struct auxtrace_record *itr) struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { - if (evsel->attr.type == cs_etm_pmu->type) { + if (evsel->core.attr.type == cs_etm_pmu->type) { /* * Variable perf_event_attr::config is assigned to * ETMv3/PTM. The bit fields have been made to match @@ -447,7 +447,7 @@ static u64 cs_etm_get_config(struct auxtrace_record *itr) * drivers/hwtracing/coresight/coresight-perf.c for * details. */ - config = evsel->attr.config; + config = evsel->core.attr.config; break; } } @@ -820,7 +820,7 @@ static int cs_etm_snapshot_start(struct auxtrace_record *itr) struct evsel *evsel; evlist__for_each_entry(ptr->evlist, evsel) { - if (evsel->attr.type == ptr->cs_etm_pmu->type) + if (evsel->core.attr.type == ptr->cs_etm_pmu->type) return evsel__disable(evsel); } return -EINVAL; @@ -833,7 +833,7 @@ static int cs_etm_snapshot_finish(struct auxtrace_record *itr) struct evsel *evsel; evlist__for_each_entry(ptr->evlist, evsel) { - if (evsel->attr.type == ptr->cs_etm_pmu->type) + if (evsel->core.attr.type == ptr->cs_etm_pmu->type) return evsel__enable(evsel); } return -EINVAL; @@ -861,7 +861,7 @@ static int cs_etm_read_finish(struct auxtrace_record *itr, int idx) struct evsel *evsel; evlist__for_each_entry(ptr->evlist, evsel) { - if (evsel->attr.type == ptr->cs_etm_pmu->type) + if (evsel->core.attr.type == ptr->cs_etm_pmu->type) return perf_evlist__enable_event_idx(ptr->evlist, evsel, idx); } diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index cc29b995c751..00915b8fd05b 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -73,13 +73,13 @@ static int arm_spe_recording_options(struct auxtrace_record *itr, sper->evlist = evlist; evlist__for_each_entry(evlist, evsel) { - if (evsel->attr.type == arm_spe_pmu->type) { + if (evsel->core.attr.type == arm_spe_pmu->type) { if (arm_spe_evsel) { pr_err("There may be only one " ARM_SPE_PMU_NAME "x event\n"); return -EINVAL; } - evsel->attr.freq = 0; - evsel->attr.sample_period = 1; + evsel->core.attr.freq = 0; + evsel->core.attr.sample_period = 1; arm_spe_evsel = evsel; opts->full_auxtrace = true; } @@ -130,8 +130,8 @@ static int arm_spe_recording_options(struct auxtrace_record *itr, tracking_evsel = perf_evlist__last(evlist); perf_evlist__set_tracking_event(evlist, tracking_evsel); - tracking_evsel->attr.freq = 0; - tracking_evsel->attr.sample_period = 1; + tracking_evsel->core.attr.freq = 0; + tracking_evsel->core.attr.sample_period = 1; perf_evsel__set_sample_bit(tracking_evsel, TIME); perf_evsel__set_sample_bit(tracking_evsel, CPU); perf_evsel__reset_sample_bit(tracking_evsel, BRANCH_STACK); @@ -163,7 +163,7 @@ static int arm_spe_read_finish(struct auxtrace_record *itr, int idx) struct evsel *evsel; evlist__for_each_entry(sper->evlist, evsel) { - if (evsel->attr.type == sper->arm_spe_pmu->type) + if (evsel->core.attr.type == sper->arm_spe_pmu->type) return perf_evlist__enable_event_idx(sper->evlist, evsel, idx); } diff --git a/tools/perf/arch/s390/util/auxtrace.c b/tools/perf/arch/s390/util/auxtrace.c index 480ada281bdb..cab46f517b83 100644 --- a/tools/perf/arch/s390/util/auxtrace.c +++ b/tools/perf/arch/s390/util/auxtrace.c @@ -94,7 +94,7 @@ struct auxtrace_record *auxtrace_record__init(struct evlist *evlist, return NULL; evlist__for_each_entry(evlist, pos) { - if (pos->attr.config == PERF_EVENT_CPUM_SF_DIAG) { + if (pos->core.attr.config == PERF_EVENT_CPUM_SF_DIAG) { diagnose = 1; break; } diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index 8b70e9ee341a..07129e007eb0 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -79,9 +79,9 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe evsel = perf_evlist__first(evlist); - evsel->attr.comm = 1; - evsel->attr.disabled = 1; - evsel->attr.enable_on_exec = 0; + evsel->core.attr.comm = 1; + evsel->core.attr.disabled = 1; + evsel->core.attr.enable_on_exec = 0; CHECK__(evlist__open(evlist)); diff --git a/tools/perf/arch/x86/util/auxtrace.c b/tools/perf/arch/x86/util/auxtrace.c index 6b3ad5c826fd..96f4a2c11893 100644 --- a/tools/perf/arch/x86/util/auxtrace.c +++ b/tools/perf/arch/x86/util/auxtrace.c @@ -29,9 +29,9 @@ struct auxtrace_record *auxtrace_record__init_intel(struct evlist *evlist, intel_bts_pmu = perf_pmu__find(INTEL_BTS_PMU_NAME); evlist__for_each_entry(evlist, evsel) { - if (intel_pt_pmu && evsel->attr.type == intel_pt_pmu->type) + if (intel_pt_pmu && evsel->core.attr.type == intel_pt_pmu->type) found_pt = true; - if (intel_bts_pmu && evsel->attr.type == intel_bts_pmu->type) + if (intel_bts_pmu && evsel->core.attr.type == intel_bts_pmu->type) found_bts = true; } diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index 8b0a53d748c9..d8a091266185 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -113,13 +113,13 @@ static int intel_bts_recording_options(struct auxtrace_record *itr, btsr->snapshot_mode = opts->auxtrace_snapshot_mode; evlist__for_each_entry(evlist, evsel) { - if (evsel->attr.type == intel_bts_pmu->type) { + if (evsel->core.attr.type == intel_bts_pmu->type) { if (intel_bts_evsel) { pr_err("There may be only one " INTEL_BTS_PMU_NAME " event\n"); return -EINVAL; } - evsel->attr.freq = 0; - evsel->attr.sample_period = 1; + evsel->core.attr.freq = 0; + evsel->core.attr.sample_period = 1; intel_bts_evsel = evsel; opts->full_auxtrace = true; } @@ -231,8 +231,8 @@ static int intel_bts_recording_options(struct auxtrace_record *itr, perf_evlist__set_tracking_event(evlist, tracking_evsel); - tracking_evsel->attr.freq = 0; - tracking_evsel->attr.sample_period = 1; + tracking_evsel->core.attr.freq = 0; + tracking_evsel->core.attr.sample_period = 1; } return 0; @@ -316,7 +316,7 @@ static int intel_bts_snapshot_start(struct auxtrace_record *itr) struct evsel *evsel; evlist__for_each_entry(btsr->evlist, evsel) { - if (evsel->attr.type == btsr->intel_bts_pmu->type) + if (evsel->core.attr.type == btsr->intel_bts_pmu->type) return evsel__disable(evsel); } return -EINVAL; @@ -329,7 +329,7 @@ static int intel_bts_snapshot_finish(struct auxtrace_record *itr) struct evsel *evsel; evlist__for_each_entry(btsr->evlist, evsel) { - if (evsel->attr.type == btsr->intel_bts_pmu->type) + if (evsel->core.attr.type == btsr->intel_bts_pmu->type) return evsel__enable(evsel); } return -EINVAL; @@ -411,7 +411,7 @@ static int intel_bts_read_finish(struct auxtrace_record *itr, int idx) struct evsel *evsel; evlist__for_each_entry(btsr->evlist, evsel) { - if (evsel->attr.type == btsr->intel_bts_pmu->type) + if (evsel->core.attr.type == btsr->intel_bts_pmu->type) return perf_evlist__enable_event_idx(btsr->evlist, evsel, idx); } diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 4ce157a4e5e2..aada6a2c456a 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -122,8 +122,8 @@ static int intel_pt_read_config(struct perf_pmu *intel_pt_pmu, const char *str, return -EINVAL; evlist__for_each_entry(evlist, evsel) { - if (evsel->attr.type == intel_pt_pmu->type) { - *res = intel_pt_masked_bits(mask, evsel->attr.config); + if (evsel->core.attr.type == intel_pt_pmu->type) { + *res = intel_pt_masked_bits(mask, evsel->core.attr.config); return 0; } } @@ -274,7 +274,7 @@ static const char *intel_pt_find_filter(struct evlist *evlist, struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { - if (evsel->attr.type == intel_pt_pmu->type) + if (evsel->core.attr.type == intel_pt_pmu->type) return evsel->filter; } @@ -526,26 +526,26 @@ static int intel_pt_validate_config(struct perf_pmu *intel_pt_pmu, * sets pt=0, which avoids senseless kernel errors. */ if (perf_pmu__scan_file(intel_pt_pmu, "format/pt", "%c", &c) == 1 && - !(evsel->attr.config & 1)) { + !(evsel->core.attr.config & 1)) { pr_warning("pt=0 doesn't make sense, forcing pt=1\n"); - evsel->attr.config |= 1; + evsel->core.attr.config |= 1; } err = intel_pt_val_config_term(intel_pt_pmu, "caps/cycle_thresholds", "cyc_thresh", "caps/psb_cyc", - evsel->attr.config); + evsel->core.attr.config); if (err) return err; err = intel_pt_val_config_term(intel_pt_pmu, "caps/mtc_periods", "mtc_period", "caps/mtc", - evsel->attr.config); + evsel->core.attr.config); if (err) return err; return intel_pt_val_config_term(intel_pt_pmu, "caps/psb_periods", "psb_period", "caps/psb_cyc", - evsel->attr.config); + evsel->core.attr.config); } static int intel_pt_recording_options(struct auxtrace_record *itr, @@ -566,13 +566,13 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, ptr->snapshot_mode = opts->auxtrace_snapshot_mode; evlist__for_each_entry(evlist, evsel) { - if (evsel->attr.type == intel_pt_pmu->type) { + if (evsel->core.attr.type == intel_pt_pmu->type) { if (intel_pt_evsel) { pr_err("There may be only one " INTEL_PT_PMU_NAME " event\n"); return -EINVAL; } - evsel->attr.freq = 0; - evsel->attr.sample_period = 1; + evsel->core.attr.freq = 0; + evsel->core.attr.sample_period = 1; intel_pt_evsel = evsel; opts->full_auxtrace = true; } @@ -670,7 +670,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, intel_pt_parse_terms(&intel_pt_pmu->format, "tsc", &tsc_bit); - if (opts->full_auxtrace && (intel_pt_evsel->attr.config & tsc_bit)) + if (opts->full_auxtrace && (intel_pt_evsel->core.attr.config & tsc_bit)) have_timing_info = true; else have_timing_info = false; @@ -693,9 +693,9 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, switch_evsel = perf_evlist__last(evlist); - switch_evsel->attr.freq = 0; - switch_evsel->attr.sample_period = 1; - switch_evsel->attr.context_switch = 1; + switch_evsel->core.attr.freq = 0; + switch_evsel->core.attr.sample_period = 1; + switch_evsel->core.attr.context_switch = 1; switch_evsel->system_wide = true; switch_evsel->no_aux_samples = true; @@ -753,8 +753,8 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, perf_evlist__set_tracking_event(evlist, tracking_evsel); - tracking_evsel->attr.freq = 0; - tracking_evsel->attr.sample_period = 1; + tracking_evsel->core.attr.freq = 0; + tracking_evsel->core.attr.sample_period = 1; tracking_evsel->no_aux_samples = true; if (need_immediate) @@ -787,7 +787,7 @@ static int intel_pt_snapshot_start(struct auxtrace_record *itr) struct evsel *evsel; evlist__for_each_entry(ptr->evlist, evsel) { - if (evsel->attr.type == ptr->intel_pt_pmu->type) + if (evsel->core.attr.type == ptr->intel_pt_pmu->type) return evsel__disable(evsel); } return -EINVAL; @@ -800,7 +800,7 @@ static int intel_pt_snapshot_finish(struct auxtrace_record *itr) struct evsel *evsel; evlist__for_each_entry(ptr->evlist, evsel) { - if (evsel->attr.type == ptr->intel_pt_pmu->type) + if (evsel->core.attr.type == ptr->intel_pt_pmu->type) return evsel__enable(evsel); } return -EINVAL; @@ -1073,7 +1073,7 @@ static int intel_pt_read_finish(struct auxtrace_record *itr, int idx) struct evsel *evsel; evlist__for_each_entry(ptr->evlist, evsel) { - if (evsel->attr.type == ptr->intel_pt_pmu->type) + if (evsel->core.attr.type == ptr->intel_pt_pmu->type) return perf_evlist__enable_event_idx(ptr->evlist, evsel, idx); } diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c index e4cb61dc6315..238fa3876805 100644 --- a/tools/perf/builtin-evlist.c +++ b/tools/perf/builtin-evlist.c @@ -36,7 +36,7 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details evlist__for_each_entry(session->evlist, pos) { perf_evsel__fprintf(pos, details, stdout); - if (pos->attr.type == PERF_TYPE_TRACEPOINT) + if (pos->core.attr.type == PERF_TYPE_TRACEPOINT) has_tracepoint = true; } diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 4e56e399bbc8..040142581d20 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -530,8 +530,8 @@ found: sample_sw.period = sample->period; sample_sw.time = sample->time; - perf_event__synthesize_sample(event_sw, evsel->attr.sample_type, - evsel->attr.read_format, &sample_sw); + perf_event__synthesize_sample(event_sw, evsel->core.attr.sample_type, + evsel->core.attr.read_format, &sample_sw); build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine); return perf_event__repipe(tool, event_sw, &sample_sw, machine); } @@ -544,7 +544,7 @@ static void sig_handler(int sig __maybe_unused) static int perf_evsel__check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg) { - struct perf_event_attr *attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->core.attr; const char *name = perf_evsel__name(evsel); if (!(attr->sample_type & sample_type)) { @@ -578,8 +578,8 @@ static void strip_init(struct perf_inject *inject) static bool has_tracking(struct evsel *evsel) { - return evsel->attr.mmap || evsel->attr.mmap2 || evsel->attr.comm || - evsel->attr.task; + return evsel->core.attr.mmap || evsel->core.attr.mmap2 || evsel->core.attr.comm || + evsel->core.attr.task; } #define COMPAT_MASK (PERF_SAMPLE_ID | PERF_SAMPLE_TID | PERF_SAMPLE_TIME | \ @@ -603,8 +603,8 @@ static bool ok_to_remove(struct evlist *evlist, evlist__for_each_entry(evlist, evsel) { if (evsel->handler != drop_sample) { cnt += 1; - if ((evsel->attr.sample_type & COMPAT_MASK) == - (evsel_to_remove->attr.sample_type & COMPAT_MASK)) + if ((evsel->core.attr.sample_type & COMPAT_MASK) == + (evsel_to_remove->core.attr.sample_type & COMPAT_MASK)) ok = true; } } diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 3370eba0d3f3..b9c58a5c1ba6 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1022,7 +1022,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm) * This command processes KVM tracepoints from host only */ evlist__for_each_entry(evlist, pos) { - struct perf_event_attr *attr = &pos->attr; + struct perf_event_attr *attr = &pos->core.attr; /* make sure these *are* set */ perf_evsel__set_sample_bit(pos, TID); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 778e46417f6b..b7d2c27c4164 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -732,7 +732,7 @@ static int record__open(struct record *rec) pos->tracking = 0; pos = perf_evlist__last(evlist); pos->tracking = 1; - pos->attr.enable_on_exec = 1; + pos->core.attr.enable_on_exec = 1; } perf_evlist__config(evlist, opts, &callchain_param); diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index d741c0aa2750..69133b35bbc1 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -345,7 +345,7 @@ static int perf_evsel__do_check_stype(struct evsel *evsel, enum perf_output_field field, bool allow_user_set) { - struct perf_event_attr *attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->core.attr; int type = output_type(attr->type); const char *evname; @@ -383,7 +383,7 @@ static int perf_evsel__check_stype(struct evsel *evsel, static int perf_evsel__check_attr(struct evsel *evsel, struct perf_session *session) { - struct perf_event_attr *attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->core.attr; bool allow_user_set; if (perf_header__has_feat(&session->header, HEADER_STAT)) @@ -418,7 +418,7 @@ static int perf_evsel__check_attr(struct evsel *evsel, return -EINVAL; if (PRINT_FIELD(SYM) && - !(evsel->attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) { + !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) { pr_err("Display of symbols requested but neither sample IP nor " "sample address\navailable. Hence, no addresses to convert " "to symbols.\n"); @@ -430,7 +430,7 @@ static int perf_evsel__check_attr(struct evsel *evsel, return -EINVAL; } if (PRINT_FIELD(DSO) && - !(evsel->attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) { + !(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) { pr_err("Display of DSO requested but no address to convert.\n"); return -EINVAL; } @@ -531,7 +531,7 @@ static int perf_session__check_output_opt(struct perf_session *session) if (evsel == NULL) continue; - set_print_ip_opts(&evsel->attr); + set_print_ip_opts(&evsel->core.attr); } if (!no_callchain) { @@ -558,7 +558,7 @@ static int perf_session__check_output_opt(struct perf_session *session) j = PERF_TYPE_TRACEPOINT; evlist__for_each_entry(session->evlist, evsel) { - if (evsel->attr.type != j) + if (evsel->core.attr.type != j) continue; if (evsel__has_callchain(evsel)) { @@ -566,7 +566,7 @@ static int perf_session__check_output_opt(struct perf_session *session) output[j].fields |= PERF_OUTPUT_SYM; output[j].fields |= PERF_OUTPUT_SYMOFFSET; output[j].fields |= PERF_OUTPUT_DSO; - set_print_ip_opts(&evsel->attr); + set_print_ip_opts(&evsel->core.attr); goto out; } } @@ -617,7 +617,7 @@ static int perf_sample__fprintf_start(struct perf_sample *sample, struct evsel *evsel, u32 type, FILE *fp) { - struct perf_event_attr *attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->core.attr; unsigned long secs; unsigned long long nsecs; int printed = 0; @@ -1168,7 +1168,7 @@ static const char *resolve_branch_sym(struct perf_sample *sample, u64 *ip) { struct addr_location addr_al; - struct perf_event_attr *attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->core.attr; const char *name = NULL; if (sample->flags & (PERF_IP_FLAG_CALL | PERF_IP_FLAG_TRACE_BEGIN)) { @@ -1195,7 +1195,7 @@ static int perf_sample__fprintf_callindent(struct perf_sample *sample, struct thread *thread, struct addr_location *al, FILE *fp) { - struct perf_event_attr *attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->core.attr; size_t depth = thread_stack__depth(thread, sample->cpu); const char *name = NULL; static int spacing; @@ -1290,7 +1290,7 @@ static int perf_sample__fprintf_bts(struct perf_sample *sample, struct addr_location *al, struct machine *machine, FILE *fp) { - struct perf_event_attr *attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->core.attr; unsigned int type = output_type(attr->type); bool print_srcline_last = false; int printed = 0; @@ -1322,7 +1322,7 @@ static int perf_sample__fprintf_bts(struct perf_sample *sample, /* print branch_to information */ if (PRINT_FIELD(ADDR) || - ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && + ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) && !output[type].user_set)) { printed += fprintf(fp, " => "); printed += perf_sample__fprintf_addr(sample, thread, attr, fp); @@ -1595,7 +1595,7 @@ static int perf_sample__fprintf_synth_cbr(struct perf_sample *sample, FILE *fp) static int perf_sample__fprintf_synth(struct perf_sample *sample, struct evsel *evsel, FILE *fp) { - switch (evsel->attr.config) { + switch (evsel->core.attr.config) { case PERF_SYNTH_INTEL_PTWRITE: return perf_sample__fprintf_synth_ptwrite(sample, fp); case PERF_SYNTH_INTEL_MWAIT: @@ -1793,7 +1793,7 @@ static void process_event(struct perf_script *script, struct machine *machine) { struct thread *thread = al->thread; - struct perf_event_attr *attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->core.attr; unsigned int type = output_type(attr->type); struct evsel_script *es = evsel->priv; FILE *fp = es->fp; @@ -2046,18 +2046,18 @@ static int process_attr(struct perf_tool *tool, union perf_event *event, } } - if (evsel->attr.type >= PERF_TYPE_MAX && - evsel->attr.type != PERF_TYPE_SYNTH) + if (evsel->core.attr.type >= PERF_TYPE_MAX && + evsel->core.attr.type != PERF_TYPE_SYNTH) return 0; evlist__for_each_entry(evlist, pos) { - if (pos->attr.type == evsel->attr.type && pos != evsel) + if (pos->core.attr.type == evsel->core.attr.type && pos != evsel) return 0; } - set_print_ip_opts(&evsel->attr); + set_print_ip_opts(&evsel->core.attr); - if (evsel->attr.sample_type) + if (evsel->core.attr.sample_type) err = perf_evsel__check_attr(evsel, scr->session); return err; @@ -2083,7 +2083,7 @@ static int process_comm_event(struct perf_tool *tool, if (perf_event__process_comm(tool, event, sample, machine) < 0) goto out; - if (!evsel->attr.sample_id_all) { + if (!evsel->core.attr.sample_id_all) { sample->cpu = 0; sample->time = 0; sample->tid = event->comm.tid; @@ -2121,7 +2121,7 @@ static int process_namespaces_event(struct perf_tool *tool, if (perf_event__process_namespaces(tool, event, sample, machine) < 0) goto out; - if (!evsel->attr.sample_id_all) { + if (!evsel->core.attr.sample_id_all) { sample->cpu = 0; sample->time = 0; sample->tid = event->namespaces.tid; @@ -2157,7 +2157,7 @@ static int process_fork_event(struct perf_tool *tool, return -1; } - if (!evsel->attr.sample_id_all) { + if (!evsel->core.attr.sample_id_all) { sample->cpu = 0; sample->time = event->fork.time; sample->tid = event->fork.tid; @@ -2189,7 +2189,7 @@ static int process_exit_event(struct perf_tool *tool, return -1; } - if (!evsel->attr.sample_id_all) { + if (!evsel->core.attr.sample_id_all) { sample->cpu = 0; sample->time = 0; sample->tid = event->fork.tid; @@ -2227,7 +2227,7 @@ static int process_mmap_event(struct perf_tool *tool, return -1; } - if (!evsel->attr.sample_id_all) { + if (!evsel->core.attr.sample_id_all) { sample->cpu = 0; sample->time = 0; sample->tid = event->mmap.tid; @@ -2261,7 +2261,7 @@ static int process_mmap2_event(struct perf_tool *tool, return -1; } - if (!evsel->attr.sample_id_all) { + if (!evsel->core.attr.sample_id_all) { sample->cpu = 0; sample->time = 0; sample->tid = event->mmap2.tid; @@ -2360,7 +2360,7 @@ process_bpf_events(struct perf_tool *tool __maybe_unused, if (machine__process_ksymbol(machine, event, sample) < 0) return -1; - if (!evsel->attr.sample_id_all) { + if (!evsel->core.attr.sample_id_all) { perf_event__fprintf(event, stdout); return 0; } diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 3ba184f2e64f..8ad3643d61f9 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -391,7 +391,7 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *inf static bool perf_evsel__should_store_id(struct evsel *counter) { - return STAT_RECORD || counter->attr.read_format & PERF_FORMAT_ID; + return STAT_RECORD || counter->core.attr.read_format & PERF_FORMAT_ID; } static bool is_target_alive(struct target *_target, diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index f5f70c83d304..7d6a6ecf4e02 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -557,7 +557,7 @@ static int process_sample_event(struct perf_tool *tool, { struct timechart *tchart = container_of(tool, struct timechart, tool); - if (evsel->attr.sample_type & PERF_SAMPLE_TIME) { + if (evsel->core.attr.sample_type & PERF_SAMPLE_TIME) { if (!tchart->first_time || tchart->first_time > sample->time) tchart->first_time = sample->time; if (tchart->last_time < sample->time) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 3291eff13e28..54d06d271bfd 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -966,7 +966,7 @@ static int perf_top_overwrite_fallback(struct perf_top *top, return 0; evlist__for_each_entry(evlist, counter) - counter->attr.write_backward = false; + counter->core.attr.write_backward = false; opts->overwrite = false; pr_debug2("fall back to non-overwrite mode\n"); return 1; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 06fcd8b1f160..abfd22ff1730 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2046,8 +2046,8 @@ static int trace__resolve_callchain(struct trace *trace, struct evsel *evsel, struct callchain_cursor *cursor) { struct addr_location al; - int max_stack = evsel->attr.sample_max_stack ? - evsel->attr.sample_max_stack : + int max_stack = evsel->core.attr.sample_max_stack ? + evsel->core.attr.sample_max_stack : trace->max_stack; int err; @@ -2462,7 +2462,7 @@ static int trace__pgfault(struct trace *trace, if (ttrace == NULL) goto out_put; - if (evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ) + if (evsel->core.attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ) ttrace->pfmaj++; else ttrace->pfmin++; @@ -2475,7 +2475,7 @@ static int trace__pgfault(struct trace *trace, trace__fprintf_entry_head(trace, thread, 0, true, sample->time, trace->output); fprintf(trace->output, "%sfault [", - evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ ? + evsel->core.attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ ? "maj" : "min"); print_location(trace->output, sample, &al, false, true); @@ -2523,7 +2523,7 @@ static void trace__set_base_time(struct trace *trace, * appears in our event stream (vfs_getname comes to mind). */ if (trace->base_time == 0 && !trace->full_time && - (evsel->attr.sample_type & PERF_SAMPLE_TIME)) + (evsel->core.attr.sample_type & PERF_SAMPLE_TIME)) trace->base_time = sample->time; } @@ -2682,7 +2682,7 @@ static void trace__handle_event(struct trace *trace, union perf_event *event, st trace__set_base_time(trace, evsel, sample); - if (evsel->attr.type == PERF_TYPE_TRACEPOINT && + if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT && sample->raw_data == NULL) { fprintf(trace->output, "%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n", perf_evsel__name(evsel), sample->tid, @@ -2728,7 +2728,7 @@ static int trace__add_syscall_newtp(struct trace *trace) * leading to the syscall, allow overriding that for * debugging reasons using --kernel_syscall_callchains */ - sys_exit->attr.exclude_callchain_kernel = 1; + sys_exit->core.attr.exclude_callchain_kernel = 1; } trace->syscalls.events.sys_enter = sys_enter; @@ -3414,18 +3414,18 @@ static int trace__run(struct trace *trace, int argc, const char **argv) trace->multiple_threads = thread_map__pid(evlist->threads, 0) == -1 || evlist->threads->nr > 1 || - perf_evlist__first(evlist)->attr.inherit; + perf_evlist__first(evlist)->core.attr.inherit; /* - * Now that we already used evsel->attr to ask the kernel to setup the - * events, lets reuse evsel->attr.sample_max_stack as the limit in + * Now that we already used evsel->core.attr to ask the kernel to setup the + * events, lets reuse evsel->core.attr.sample_max_stack as the limit in * trace__resolve_callchain(), allowing per-event max-stack settings * to override an explicitly set --max-stack global setting. */ evlist__for_each_entry(evlist, evsel) { if (evsel__has_callchain(evsel) && - evsel->attr.sample_max_stack == 0) - evsel->attr.sample_max_stack = trace->max_stack; + evsel->core.attr.sample_max_stack == 0) + evsel->core.attr.sample_max_stack = trace->max_stack; } again: before = trace->nr_events; @@ -3618,10 +3618,10 @@ static int trace__replay(struct trace *trace) } evlist__for_each_entry(session->evlist, evsel) { - if (evsel->attr.type == PERF_TYPE_SOFTWARE && - (evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ || - evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MIN || - evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS)) + if (evsel->core.attr.type == PERF_TYPE_SOFTWARE && + (evsel->core.attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ || + evsel->core.attr.config == PERF_COUNT_SW_PAGE_FAULTS_MIN || + evsel->core.attr.config == PERF_COUNT_SW_PAGE_FAULTS)) evsel->handler = trace__pgfault; } diff --git a/tools/perf/lib/evsel.c b/tools/perf/lib/evsel.c index 9a87e867a7ec..17cba35becc7 100644 --- a/tools/perf/lib/evsel.c +++ b/tools/perf/lib/evsel.c @@ -3,7 +3,8 @@ #include #include -void perf_evsel__init(struct perf_evsel *evsel) +void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr) { INIT_LIST_HEAD(&evsel->node); + evsel->attr = *attr; } diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h index 690943d0408a..c2e0bd104c94 100644 --- a/tools/perf/lib/include/internal/evsel.h +++ b/tools/perf/lib/include/internal/evsel.h @@ -2,8 +2,12 @@ #ifndef __LIBPERF_INTERNAL_EVSEL_H #define __LIBPERF_INTERNAL_EVSEL_H +#include +#include + struct perf_evsel { struct list_head node; + struct perf_event_attr attr; }; #endif /* __LIBPERF_INTERNAL_EVSEL_H */ diff --git a/tools/perf/lib/include/perf/evsel.h b/tools/perf/lib/include/perf/evsel.h index b4d074a3684b..295583b89f46 100644 --- a/tools/perf/lib/include/perf/evsel.h +++ b/tools/perf/lib/include/perf/evsel.h @@ -5,7 +5,9 @@ #include struct perf_evsel; +struct perf_event_attr; -LIBPERF_API void perf_evsel__init(struct perf_evsel *evsel); +LIBPERF_API void perf_evsel__init(struct perf_evsel *evsel, + struct perf_event_attr *attr); #endif /* __LIBPERF_EVSEL_H */ diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 7b26be1dfb47..131bbeec62d2 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -642,9 +642,9 @@ static int do_test_code_reading(bool try_kcore) evsel = perf_evlist__first(evlist); - evsel->attr.comm = 1; - evsel->attr.disabled = 1; - evsel->attr.enable_on_exec = 0; + evsel->core.attr.comm = 1; + evsel->core.attr.disabled = 1; + evsel->core.attr.enable_on_exec = 0; ret = evlist__open(evlist); if (ret < 0) { diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 9238180416b0..165534f62036 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -36,7 +36,7 @@ static int attach__enable_on_exec(struct evlist *evlist) return err; } - evsel->attr.enable_on_exec = 1; + evsel->core.attr.enable_on_exec = 1; err = evlist__open(evlist); if (err < 0) { @@ -68,7 +68,7 @@ static int attach__current_disabled(struct evlist *evlist) return -1; } - evsel->attr.disabled = 1; + evsel->core.attr.disabled = 1; err = perf_evsel__open_per_thread(evsel, threads); if (err) { @@ -121,7 +121,7 @@ static int attach__cpu_disabled(struct evlist *evlist) return -1; } - evsel->attr.disabled = 1; + evsel->core.attr.disabled = 1; err = perf_evsel__open_per_cpu(evsel, cpus); if (err) { @@ -179,7 +179,7 @@ static int test_times(int (attach)(struct evlist *), } evsel = perf_evlist__last(evlist); - evsel->attr.read_format |= + evsel->core.attr.read_format |= PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING; diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 830fb3d7ea2e..4fc7b3b4e153 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -90,9 +90,9 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un evsel = perf_evlist__first(evlist); - evsel->attr.comm = 1; - evsel->attr.disabled = 1; - evsel->attr.enable_on_exec = 0; + evsel->core.attr.comm = 1; + evsel->core.attr.disabled = 1; + evsel->core.attr.enable_on_exec = 0; if (evlist__open(evlist) < 0) { pr_debug("Unable to open dummy and cycles event\n"); diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 72fbf55f4fc3..9d8eb43b12cb 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -79,7 +79,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse goto out_delete_evlist; } - evsels[i]->attr.wakeup_events = 1; + evsels[i]->core.attr.wakeup_events = 1; perf_evsel__set_sample_id(evsels[i], false); evlist__add(evlist, evsels[i]); diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 878140501edf..5b4a5a3dac50 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -50,10 +50,10 @@ static int test__checkevent_tracepoint(struct evlist *evlist) TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong number of groups", 0 == evlist->nr_groups); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->core.attr.type); TEST_ASSERT_VAL("wrong sample_type", - PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); - TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); + PERF_TP_SAMPLE_TYPE == evsel->core.attr.sample_type); + TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->core.attr.sample_period); return 0; } @@ -66,11 +66,11 @@ static int test__checkevent_tracepoint_multi(struct evlist *evlist) evlist__for_each_entry(evlist, evsel) { TEST_ASSERT_VAL("wrong type", - PERF_TYPE_TRACEPOINT == evsel->attr.type); + PERF_TYPE_TRACEPOINT == evsel->core.attr.type); TEST_ASSERT_VAL("wrong sample_type", - PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); + PERF_TP_SAMPLE_TYPE == evsel->core.attr.sample_type); TEST_ASSERT_VAL("wrong sample_period", - 1 == evsel->attr.sample_period); + 1 == evsel->core.attr.sample_period); } return 0; } @@ -80,8 +80,8 @@ static int test__checkevent_raw(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 0x1a == evsel->attr.config); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", 0x1a == evsel->core.attr.config); return 0; } @@ -90,8 +90,8 @@ static int test__checkevent_numeric(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); - TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); + TEST_ASSERT_VAL("wrong type", 1 == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", 1 == evsel->core.attr.config); return 0; } @@ -100,9 +100,9 @@ static int test__checkevent_symbolic_name(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); + PERF_COUNT_HW_INSTRUCTIONS == evsel->core.attr.config); return 0; } @@ -111,19 +111,19 @@ static int test__checkevent_symbolic_name_config(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); + PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); /* * The period value gets configured within perf_evlist__config, * while this test executes only parse events method. */ TEST_ASSERT_VAL("wrong period", - 0 == evsel->attr.sample_period); + 0 == evsel->core.attr.sample_period); TEST_ASSERT_VAL("wrong config1", - 0 == evsel->attr.config1); + 0 == evsel->core.attr.config1); TEST_ASSERT_VAL("wrong config2", - 1 == evsel->attr.config2); + 1 == evsel->core.attr.config2); return 0; } @@ -132,9 +132,9 @@ static int test__checkevent_symbolic_alias(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_SW_PAGE_FAULTS == evsel->attr.config); + PERF_COUNT_SW_PAGE_FAULTS == evsel->core.attr.config); return 0; } @@ -143,8 +143,8 @@ static int test__checkevent_genhw(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", (1 << 16) == evsel->attr.config); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", (1 << 16) == evsel->core.attr.config); return 0; } @@ -153,12 +153,12 @@ static int test__checkevent_breakpoint(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", 0 == evsel->core.attr.config); TEST_ASSERT_VAL("wrong bp_type", (HW_BREAKPOINT_R | HW_BREAKPOINT_W) == - evsel->attr.bp_type); + evsel->core.attr.bp_type); TEST_ASSERT_VAL("wrong bp_len", HW_BREAKPOINT_LEN_4 == - evsel->attr.bp_len); + evsel->core.attr.bp_len); return 0; } @@ -167,11 +167,11 @@ static int test__checkevent_breakpoint_x(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", 0 == evsel->core.attr.config); TEST_ASSERT_VAL("wrong bp_type", - HW_BREAKPOINT_X == evsel->attr.bp_type); - TEST_ASSERT_VAL("wrong bp_len", sizeof(long) == evsel->attr.bp_len); + HW_BREAKPOINT_X == evsel->core.attr.bp_type); + TEST_ASSERT_VAL("wrong bp_len", sizeof(long) == evsel->core.attr.bp_len); return 0; } @@ -181,12 +181,12 @@ static int test__checkevent_breakpoint_r(struct evlist *evlist) TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", - PERF_TYPE_BREAKPOINT == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); + PERF_TYPE_BREAKPOINT == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", 0 == evsel->core.attr.config); TEST_ASSERT_VAL("wrong bp_type", - HW_BREAKPOINT_R == evsel->attr.bp_type); + HW_BREAKPOINT_R == evsel->core.attr.bp_type); TEST_ASSERT_VAL("wrong bp_len", - HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); + HW_BREAKPOINT_LEN_4 == evsel->core.attr.bp_len); return 0; } @@ -196,12 +196,12 @@ static int test__checkevent_breakpoint_w(struct evlist *evlist) TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", - PERF_TYPE_BREAKPOINT == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); + PERF_TYPE_BREAKPOINT == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", 0 == evsel->core.attr.config); TEST_ASSERT_VAL("wrong bp_type", - HW_BREAKPOINT_W == evsel->attr.bp_type); + HW_BREAKPOINT_W == evsel->core.attr.bp_type); TEST_ASSERT_VAL("wrong bp_len", - HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); + HW_BREAKPOINT_LEN_4 == evsel->core.attr.bp_len); return 0; } @@ -211,12 +211,12 @@ static int test__checkevent_breakpoint_rw(struct evlist *evlist) TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", - PERF_TYPE_BREAKPOINT == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); + PERF_TYPE_BREAKPOINT == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", 0 == evsel->core.attr.config); TEST_ASSERT_VAL("wrong bp_type", - (HW_BREAKPOINT_R|HW_BREAKPOINT_W) == evsel->attr.bp_type); + (HW_BREAKPOINT_R|HW_BREAKPOINT_W) == evsel->core.attr.bp_type); TEST_ASSERT_VAL("wrong bp_len", - HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); + HW_BREAKPOINT_LEN_4 == evsel->core.attr.bp_len); return 0; } @@ -224,10 +224,10 @@ static int test__checkevent_tracepoint_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); return test__checkevent_tracepoint(evlist); } @@ -241,11 +241,11 @@ test__checkevent_tracepoint_multi_modifier(struct evlist *evlist) evlist__for_each_entry(evlist, evsel) { TEST_ASSERT_VAL("wrong exclude_user", - !evsel->attr.exclude_user); + !evsel->core.attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", - evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); } return test__checkevent_tracepoint_multi(evlist); @@ -255,10 +255,10 @@ static int test__checkevent_raw_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip); return test__checkevent_raw(evlist); } @@ -267,10 +267,10 @@ static int test__checkevent_numeric_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip); return test__checkevent_numeric(evlist); } @@ -279,10 +279,10 @@ static int test__checkevent_symbolic_name_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); return test__checkevent_symbolic_name(evlist); } @@ -291,8 +291,8 @@ static int test__checkevent_exclude_host_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host); return test__checkevent_symbolic_name(evlist); } @@ -301,8 +301,8 @@ static int test__checkevent_exclude_guest_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); return test__checkevent_symbolic_name(evlist); } @@ -311,10 +311,10 @@ static int test__checkevent_symbolic_alias_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); return test__checkevent_symbolic_alias(evlist); } @@ -323,10 +323,10 @@ static int test__checkevent_genhw_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip); return test__checkevent_genhw(evlist); } @@ -335,13 +335,13 @@ static int test__checkevent_exclude_idle_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong exclude idle", evsel->attr.exclude_idle); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong exclude idle", evsel->core.attr.exclude_idle); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); return test__checkevent_symbolic_name(evlist); } @@ -350,13 +350,13 @@ static int test__checkevent_exclude_idle_modifier_1(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong exclude idle", evsel->attr.exclude_idle); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong exclude idle", evsel->core.attr.exclude_idle); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); return test__checkevent_symbolic_name(evlist); } @@ -366,10 +366,10 @@ static int test__checkevent_breakpoint_modifier(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "mem:0:u")); @@ -380,10 +380,10 @@ static int test__checkevent_breakpoint_x_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "mem:0:x:k")); @@ -394,10 +394,10 @@ static int test__checkevent_breakpoint_r_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "mem:0:r:hp")); @@ -408,10 +408,10 @@ static int test__checkevent_breakpoint_w_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "mem:0:w:up")); @@ -422,10 +422,10 @@ static int test__checkevent_breakpoint_rw_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "mem:0:rw:kp")); @@ -438,15 +438,15 @@ static int test__checkevent_pmu(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 10 == evsel->attr.config); - TEST_ASSERT_VAL("wrong config1", 1 == evsel->attr.config1); - TEST_ASSERT_VAL("wrong config2", 3 == evsel->attr.config2); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", 10 == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong config1", 1 == evsel->core.attr.config1); + TEST_ASSERT_VAL("wrong config2", 3 == evsel->core.attr.config2); /* * The period value gets configured within perf_evlist__config, * while this test executes only parse events method. */ - TEST_ASSERT_VAL("wrong period", 0 == evsel->attr.sample_period); + TEST_ASSERT_VAL("wrong period", 0 == evsel->core.attr.sample_period); return 0; } @@ -458,34 +458,34 @@ static int test__checkevent_list(struct evlist *evlist) TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->core.nr_entries); /* r1 */ - TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); - TEST_ASSERT_VAL("wrong config1", 0 == evsel->attr.config1); - TEST_ASSERT_VAL("wrong config2", 0 == evsel->attr.config2); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", 1 == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong config1", 0 == evsel->core.attr.config1); + TEST_ASSERT_VAL("wrong config2", 0 == evsel->core.attr.config2); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); /* syscalls:sys_enter_openat:k */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->core.attr.type); TEST_ASSERT_VAL("wrong sample_type", - PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); - TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_TP_SAMPLE_TYPE == evsel->core.attr.sample_type); + TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->core.attr.sample_period); + TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); /* 1:1:hp */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong type", 1 == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", 1 == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip); return 0; } @@ -496,15 +496,15 @@ static int test__checkevent_pmu_name(struct evlist *evlist) /* cpu/config=1,name=krava/u */ TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", 1 == evsel->core.attr.config); TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "krava")); /* cpu/config=2/u" */ evsel = perf_evsel__next(evsel); TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 2 == evsel->attr.config); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", 2 == evsel->core.attr.config); TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "cpu/config=2/u")); @@ -517,29 +517,29 @@ static int test__checkevent_pmu_partial_time_callgraph(struct evlist *evlist) /* cpu/config=1,call-graph=fp,time,period=100000/ */ TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", 1 == evsel->core.attr.config); /* * The period, time and callgraph value gets configured * within perf_evlist__config, * while this test executes only parse events method. */ - TEST_ASSERT_VAL("wrong period", 0 == evsel->attr.sample_period); + TEST_ASSERT_VAL("wrong period", 0 == evsel->core.attr.sample_period); TEST_ASSERT_VAL("wrong callgraph", !evsel__has_callchain(evsel)); - TEST_ASSERT_VAL("wrong time", !(PERF_SAMPLE_TIME & evsel->attr.sample_type)); + TEST_ASSERT_VAL("wrong time", !(PERF_SAMPLE_TIME & evsel->core.attr.sample_type)); /* cpu/config=2,call-graph=no,time=0,period=2000/ */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 2 == evsel->attr.config); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", 2 == evsel->core.attr.config); /* * The period, time and callgraph value gets configured * within perf_evlist__config, * while this test executes only parse events method. */ - TEST_ASSERT_VAL("wrong period", 0 == evsel->attr.sample_period); + TEST_ASSERT_VAL("wrong period", 0 == evsel->core.attr.sample_period); TEST_ASSERT_VAL("wrong callgraph", !evsel__has_callchain(evsel)); - TEST_ASSERT_VAL("wrong time", !(PERF_SAMPLE_TIME & evsel->attr.sample_type)); + TEST_ASSERT_VAL("wrong time", !(PERF_SAMPLE_TIME & evsel->core.attr.sample_type)); return 0; } @@ -549,14 +549,14 @@ static int test__checkevent_pmu_events(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type); TEST_ASSERT_VAL("wrong exclude_user", - !evsel->attr.exclude_user); + !evsel->core.attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", - evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong pinned", !evsel->attr.pinned); + evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); + TEST_ASSERT_VAL("wrong pinned", !evsel->core.attr.pinned); return 0; } @@ -569,24 +569,24 @@ static int test__checkevent_pmu_events_mix(struct evlist *evlist) /* pmu-event:u */ TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong exclude_user", - !evsel->attr.exclude_user); + !evsel->core.attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", - evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong pinned", !evsel->attr.pinned); + evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); + TEST_ASSERT_VAL("wrong pinned", !evsel->core.attr.pinned); /* cpu/pmu-event/u*/ evsel = perf_evsel__next(evsel); TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type); TEST_ASSERT_VAL("wrong exclude_user", - !evsel->attr.exclude_user); + !evsel->core.attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", - evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong pinned", !evsel->attr.pinned); + evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); + TEST_ASSERT_VAL("wrong pinned", !evsel->core.attr.pinned); return 0; } @@ -643,15 +643,15 @@ static int test__group1(struct evlist *evlist) /* instructions:k */ evsel = leader = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_INSTRUCTIONS == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0); @@ -659,16 +659,16 @@ static int test__group1(struct evlist *evlist) /* cycles:upp */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); /* use of precise requires exclude_guest */ - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2); + TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip == 2); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1); TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read); @@ -685,15 +685,15 @@ static int test__group2(struct evlist *evlist) /* faults + :ku modifier */ evsel = leader = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_SW_PAGE_FAULTS == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_SW_PAGE_FAULTS == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0); @@ -701,30 +701,30 @@ static int test__group2(struct evlist *evlist) /* cache-references + :u modifier */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CACHE_REFERENCES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_CACHE_REFERENCES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1); TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read); /* cycles:k */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read); @@ -740,16 +740,16 @@ static int test__group3(struct evlist *evlist __maybe_unused) /* group1 syscalls:sys_enter_openat:H */ evsel = leader = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->core.attr.type); TEST_ASSERT_VAL("wrong sample_type", - PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); - TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_TP_SAMPLE_TYPE == evsel->core.attr.sample_type); + TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->core.attr.sample_period); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); TEST_ASSERT_VAL("wrong group name", !strcmp(leader->group_name, "group1")); @@ -759,16 +759,16 @@ static int test__group3(struct evlist *evlist __maybe_unused) /* group1 cycles:kppp */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); /* use of precise requires exclude_guest */ - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 3); + TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip == 3); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1); @@ -776,15 +776,15 @@ static int test__group3(struct evlist *evlist __maybe_unused) /* group2 cycles + G modifier */ evsel = leader = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); TEST_ASSERT_VAL("wrong group name", !strcmp(leader->group_name, "group2")); @@ -794,29 +794,29 @@ static int test__group3(struct evlist *evlist __maybe_unused) /* group2 1:3 + G modifier */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 3 == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong type", 1 == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", 3 == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1); TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read); /* instructions:u */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_INSTRUCTIONS == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read); @@ -832,16 +832,16 @@ static int test__group4(struct evlist *evlist __maybe_unused) /* cycles:u + p */ evsel = leader = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); /* use of precise requires exclude_guest */ - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 1); + TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip == 1); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); @@ -850,16 +850,16 @@ static int test__group4(struct evlist *evlist __maybe_unused) /* instructions:kp + p */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + PERF_COUNT_HW_INSTRUCTIONS == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); /* use of precise requires exclude_guest */ - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2); + TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip == 2); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1); TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read); @@ -876,15 +876,15 @@ static int test__group5(struct evlist *evlist __maybe_unused) /* cycles + G */ evsel = leader = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); @@ -893,30 +893,30 @@ static int test__group5(struct evlist *evlist __maybe_unused) /* instructions + G */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_INSTRUCTIONS == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1); TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read); /* cycles:G */ evsel = leader = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); @@ -925,29 +925,29 @@ static int test__group5(struct evlist *evlist __maybe_unused) /* instructions:G */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_INSTRUCTIONS == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1); /* cycles */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); return 0; @@ -962,15 +962,15 @@ static int test__group_gh1(struct evlist *evlist) /* cycles + :H group modifier */ evsel = leader = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); @@ -978,15 +978,15 @@ static int test__group_gh1(struct evlist *evlist) /* cache-misses:G + :H group modifier */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CACHE_MISSES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_CACHE_MISSES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1); @@ -1002,15 +1002,15 @@ static int test__group_gh2(struct evlist *evlist) /* cycles + :G group modifier */ evsel = leader = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); @@ -1018,15 +1018,15 @@ static int test__group_gh2(struct evlist *evlist) /* cache-misses:H + :G group modifier */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CACHE_MISSES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_CACHE_MISSES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1); @@ -1042,15 +1042,15 @@ static int test__group_gh3(struct evlist *evlist) /* cycles:G + :u group modifier */ evsel = leader = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); @@ -1058,15 +1058,15 @@ static int test__group_gh3(struct evlist *evlist) /* cache-misses:H + :u group modifier */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CACHE_MISSES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_CACHE_MISSES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1); @@ -1082,15 +1082,15 @@ static int test__group_gh4(struct evlist *evlist) /* cycles:G + :uG group modifier */ evsel = leader = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); @@ -1098,15 +1098,15 @@ static int test__group_gh4(struct evlist *evlist) /* cache-misses:H + :uG group modifier */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CACHE_MISSES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_CACHE_MISSES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1); @@ -1121,44 +1121,44 @@ static int test__leader_sample1(struct evlist *evlist) /* cycles - sampling group leader */ evsel = leader = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); TEST_ASSERT_VAL("wrong sample_read", evsel->sample_read); /* cache-misses - not sampling */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CACHE_MISSES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_CACHE_MISSES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); TEST_ASSERT_VAL("wrong sample_read", evsel->sample_read); /* branch-misses - not sampling */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_BRANCH_MISSES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_BRANCH_MISSES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); TEST_ASSERT_VAL("wrong sample_read", evsel->sample_read); @@ -1174,30 +1174,30 @@ static int test__leader_sample2(struct evlist *evlist __maybe_unused) /* instructions - sampling group leader */ evsel = leader = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_INSTRUCTIONS == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); TEST_ASSERT_VAL("wrong sample_read", evsel->sample_read); /* branch-misses - not sampling */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_BRANCH_MISSES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + PERF_COUNT_HW_BRANCH_MISSES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); TEST_ASSERT_VAL("wrong sample_read", evsel->sample_read); @@ -1209,11 +1209,11 @@ static int test__checkevent_pinned_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong pinned", evsel->attr.pinned); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip); + TEST_ASSERT_VAL("wrong pinned", evsel->core.attr.pinned); return test__checkevent_symbolic_name(evlist); } @@ -1226,25 +1226,25 @@ static int test__pinned_group(struct evlist *evlist) /* cycles - group leader */ evsel = leader = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); + PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); - TEST_ASSERT_VAL("wrong pinned", evsel->attr.pinned); + TEST_ASSERT_VAL("wrong pinned", evsel->core.attr.pinned); /* cache-misses - can not be pinned, but will go on with the leader */ evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CACHE_MISSES == evsel->attr.config); - TEST_ASSERT_VAL("wrong pinned", !evsel->attr.pinned); + PERF_COUNT_HW_CACHE_MISSES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong pinned", !evsel->core.attr.pinned); /* branch-misses - ditto */ evsel = perf_evsel__next(evsel); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_BRANCH_MISSES == evsel->attr.config); - TEST_ASSERT_VAL("wrong pinned", !evsel->attr.pinned); + PERF_COUNT_HW_BRANCH_MISSES == evsel->core.attr.config); + TEST_ASSERT_VAL("wrong pinned", !evsel->core.attr.pinned); return 0; } @@ -1254,12 +1254,12 @@ static int test__checkevent_breakpoint_len(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", 0 == evsel->core.attr.config); TEST_ASSERT_VAL("wrong bp_type", (HW_BREAKPOINT_R | HW_BREAKPOINT_W) == - evsel->attr.bp_type); + evsel->core.attr.bp_type); TEST_ASSERT_VAL("wrong bp_len", HW_BREAKPOINT_LEN_1 == - evsel->attr.bp_len); + evsel->core.attr.bp_len); return 0; } @@ -1269,12 +1269,12 @@ static int test__checkevent_breakpoint_len_w(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->core.attr.type); + TEST_ASSERT_VAL("wrong config", 0 == evsel->core.attr.config); TEST_ASSERT_VAL("wrong bp_type", HW_BREAKPOINT_W == - evsel->attr.bp_type); + evsel->core.attr.bp_type); TEST_ASSERT_VAL("wrong bp_len", HW_BREAKPOINT_LEN_2 == - evsel->attr.bp_len); + evsel->core.attr.bp_len); return 0; } @@ -1284,10 +1284,10 @@ test__checkevent_breakpoint_len_rw_modifier(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); return test__checkevent_breakpoint_rw(evlist); } @@ -1297,9 +1297,9 @@ static int test__checkevent_precise_max_modifier(struct evlist *evlist) struct evsel *evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", - PERF_COUNT_SW_TASK_CLOCK == evsel->attr.config); + PERF_COUNT_SW_TASK_CLOCK == evsel->core.attr.config); return 0; } @@ -1360,9 +1360,9 @@ static int test__sym_event_slash(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", evsel->attr.type == PERF_TYPE_HARDWARE); - TEST_ASSERT_VAL("wrong config", evsel->attr.config == PERF_COUNT_HW_CPU_CYCLES); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong type", evsel->core.attr.type == PERF_TYPE_HARDWARE); + TEST_ASSERT_VAL("wrong config", evsel->core.attr.config == PERF_COUNT_HW_CPU_CYCLES); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); return 0; } @@ -1370,9 +1370,9 @@ static int test__sym_event_dc(struct evlist *evlist) { struct evsel *evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", evsel->attr.type == PERF_TYPE_HARDWARE); - TEST_ASSERT_VAL("wrong config", evsel->attr.config == PERF_COUNT_HW_CPU_CYCLES); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong type", evsel->core.attr.type == PERF_TYPE_HARDWARE); + TEST_ASSERT_VAL("wrong config", evsel->core.attr.config == PERF_COUNT_HW_CPU_CYCLES); + TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); return 0; } diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c index a8cd3ed3c116..a8ca29fe172b 100644 --- a/tools/perf/tests/sample-parsing.c +++ b/tools/perf/tests/sample-parsing.c @@ -155,9 +155,11 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format) { struct evsel evsel = { .needs_swap = false, - .attr = { - .sample_type = sample_type, - .read_format = read_format, + .core = { + . attr = { + .sample_type = sample_type, + .read_format = read_format, + }, }, }; union perf_event *event; @@ -221,10 +223,10 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format) int err, ret = -1; if (sample_type & PERF_SAMPLE_REGS_USER) - evsel.attr.sample_regs_user = sample_regs; + evsel.core.attr.sample_regs_user = sample_regs; if (sample_type & PERF_SAMPLE_REGS_INTR) - evsel.attr.sample_regs_intr = sample_regs; + evsel.core.attr.sample_regs_intr = sample_regs; for (i = 0; i < sizeof(regs); i++) *(i + (u8 *)regs) = i & 0xfe; diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 0935a5a1ecaa..dd07acced4af 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -420,8 +420,8 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ perf_evlist__set_tracking_event(evlist, tracking_evsel); - tracking_evsel->attr.freq = 0; - tracking_evsel->attr.sample_period = 1; + tracking_evsel->core.attr.freq = 0; + tracking_evsel->core.attr.sample_period = 1; perf_evsel__set_sample_bit(tracking_evsel, TIME); @@ -435,7 +435,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ } /* Check tracking event is tracking */ - if (!tracking_evsel->attr.mmap || !tracking_evsel->attr.comm) { + if (!tracking_evsel->core.attr.mmap || !tracking_evsel->core.attr.comm) { pr_debug("Tracking event not tracking\n"); goto out_err; } @@ -443,7 +443,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ /* Check non-tracking events are not tracking */ evlist__for_each_entry(evlist, evsel) { if (evsel != tracking_evsel) { - if (evsel->attr.mmap || evsel->attr.comm) { + if (evsel->core.attr.mmap || evsel->core.attr.comm) { pr_debug("Non-tracking event is tracking\n"); goto out_err; } diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 24257285844b..b0192ea636a7 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -84,16 +84,16 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused } evsel = perf_evlist__first(evlist); - evsel->attr.task = 1; + evsel->core.attr.task = 1; #ifdef __s390x__ - evsel->attr.sample_freq = 1000000; + evsel->core.attr.sample_freq = 1000000; #else - evsel->attr.sample_freq = 1; + evsel->core.attr.sample_freq = 1; #endif - evsel->attr.inherit = 0; - evsel->attr.watermark = 0; - evsel->attr.wakeup_events = 1; - evsel->attr.exclude_kernel = 1; + evsel->core.attr.inherit = 0; + evsel->core.attr.watermark = 0; + evsel->core.attr.wakeup_events = 1; + evsel->core.attr.exclude_kernel = 1; err = evlist__open(evlist); if (err < 0) { diff --git a/tools/perf/ui/browsers/res_sample.c b/tools/perf/ui/browsers/res_sample.c index 7f3576deafd7..08897bd5eb0f 100644 --- a/tools/perf/ui/browsers/res_sample.c +++ b/tools/perf/ui/browsers/res_sample.c @@ -66,7 +66,7 @@ int res_sample_browse(struct res_sample *res_samples, int num_res, timestamp__scnprintf_nsec(r->time, tsample, sizeof tsample); - attr_to_script(extra_format, &evsel->attr); + attr_to_script(extra_format, &evsel->core.attr); if (asprintf(&cmd, "%s script %s%s --time %s %s%s %s%s --ns %s %s %s %s %s | less +/%s", perf, diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c index c0462457e9f9..04f9aff5621e 100644 --- a/tools/perf/ui/browsers/scripts.c +++ b/tools/perf/ui/browsers/scripts.c @@ -100,7 +100,7 @@ static int list_scripts(char *script_name, bool *custom, return -1; if (evsel) - attr_to_script(scriptc.extra_format, &evsel->attr); + attr_to_script(scriptc.extra_format, &evsel->core.attr); add_script_option("Show individual samples", "", &scriptc); add_script_option("Show individual samples with assembler", "-F +insn --xed", &scriptc); diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 9ec2841ddec4..843959f85d6f 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -2140,7 +2140,7 @@ static struct perf_pmu *perf_evsel__find_pmu(struct evsel *evsel) struct perf_pmu *pmu = NULL; while ((pmu = perf_pmu__scan(pmu)) != NULL) { - if (pmu->type == evsel->attr.type) + if (pmu->type == evsel->core.attr.type) break; } diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index b0696726ab76..4df8bdea14ac 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -1421,7 +1421,7 @@ apply_config_evsel_for_key(const char *name, int map_fd, void *pkey, return -BPF_LOADER_ERRNO__OBJCONF_MAP_EVTDIM; } - attr = &evsel->attr; + attr = &evsel->core.attr; if (attr->inherit) { pr_debug("ERROR: Can't put inherit event into map %s\n", name); return -BPF_LOADER_ERRNO__OBJCONF_MAP_EVTINH; diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index c1df366f4519..ed6f7fd5b90b 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -1230,7 +1230,7 @@ static int cs_etm__synth_events(struct cs_etm_auxtrace *etm, int err; evlist__for_each_entry(evlist, evsel) { - if (evsel->attr.type == etm->pmu_type) { + if (evsel->core.attr.type == etm->pmu_type) { found = true; break; } @@ -1244,7 +1244,7 @@ static int cs_etm__synth_events(struct cs_etm_auxtrace *etm, memset(&attr, 0, sizeof(struct perf_event_attr)); attr.size = sizeof(struct perf_event_attr); attr.type = PERF_TYPE_HARDWARE; - attr.sample_type = evsel->attr.sample_type & PERF_SAMPLE_MASK; + attr.sample_type = evsel->core.attr.sample_type & PERF_SAMPLE_MASK; attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_PERIOD; if (etm->timeless_decoding) @@ -1252,13 +1252,13 @@ static int cs_etm__synth_events(struct cs_etm_auxtrace *etm, else attr.sample_type |= PERF_SAMPLE_TIME; - attr.exclude_user = evsel->attr.exclude_user; - attr.exclude_kernel = evsel->attr.exclude_kernel; - attr.exclude_hv = evsel->attr.exclude_hv; - attr.exclude_host = evsel->attr.exclude_host; - attr.exclude_guest = evsel->attr.exclude_guest; - attr.sample_id_all = evsel->attr.sample_id_all; - attr.read_format = evsel->attr.read_format; + attr.exclude_user = evsel->core.attr.exclude_user; + attr.exclude_kernel = evsel->core.attr.exclude_kernel; + attr.exclude_hv = evsel->core.attr.exclude_hv; + attr.exclude_host = evsel->core.attr.exclude_host; + attr.exclude_guest = evsel->core.attr.exclude_guest; + attr.sample_id_all = evsel->core.attr.sample_id_all; + attr.read_format = evsel->core.attr.read_format; /* create new id val to be a fixed offset from evsel id */ id = evsel->id[0] + 1000000000; @@ -2303,7 +2303,7 @@ static bool cs_etm__is_timeless_decoding(struct cs_etm_auxtrace *etm) * with the time bit set. */ evlist__for_each_entry(evlist, evsel) { - if ((evsel->attr.sample_type & PERF_SAMPLE_TIME)) + if ((evsel->core.attr.sample_type & PERF_SAMPLE_TIME)) timeless_decoding = false; } diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index ca30bb25b3c5..0c268449959c 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -587,7 +587,7 @@ static int add_generic_values(struct ctf_writer *cw, struct evsel *evsel, struct perf_sample *sample) { - u64 type = evsel->attr.sample_type; + u64 type = evsel->core.attr.sample_type; int ret; /* @@ -757,7 +757,7 @@ static int get_sample_cpu(struct ctf_writer *cw, struct perf_sample *sample, { int cpu = 0; - if (evsel->attr.sample_type & PERF_SAMPLE_CPU) + if (evsel->core.attr.sample_type & PERF_SAMPLE_CPU) cpu = sample->cpu; if (cpu > cw->stream_cnt) { @@ -795,7 +795,7 @@ static int process_sample_event(struct perf_tool *tool, struct bt_ctf_event_class *event_class; struct bt_ctf_event *event; int ret; - unsigned long type = evsel->attr.sample_type; + unsigned long type = evsel->core.attr.sample_type; if (WARN_ONCE(!priv, "Failed to setup all events.\n")) return 0; @@ -820,7 +820,7 @@ static int process_sample_event(struct perf_tool *tool, if (ret) return -1; - if (evsel->attr.type == PERF_TYPE_TRACEPOINT) { + if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) { ret = add_tracepoint_values(cw, event_class, event, evsel, sample); if (ret) @@ -1087,7 +1087,7 @@ static int add_bpf_output_types(struct ctf_writer *cw, static int add_generic_types(struct ctf_writer *cw, struct evsel *evsel, struct bt_ctf_event_class *event_class) { - u64 type = evsel->attr.sample_type; + u64 type = evsel->core.attr.sample_type; /* * missing: @@ -1157,7 +1157,7 @@ static int add_event(struct ctf_writer *cw, struct evsel *evsel) const char *name = perf_evsel__name(evsel); int ret; - pr("Adding event '%s' (type %d)\n", name, evsel->attr.type); + pr("Adding event '%s' (type %d)\n", name, evsel->core.attr.type); event_class = bt_ctf_event_class_create(name); if (!event_class) @@ -1167,7 +1167,7 @@ static int add_event(struct ctf_writer *cw, struct evsel *evsel) if (ret) goto err; - if (evsel->attr.type == PERF_TYPE_TRACEPOINT) { + if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) { ret = add_tracepoint_types(cw, evsel, event_class); if (ret) goto err; diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c index dc2d4de772e3..701e9f814313 100644 --- a/tools/perf/util/db-export.c +++ b/tools/perf/util/db-export.c @@ -388,8 +388,8 @@ int db_export__sample(struct db_export *dbe, union perf_event *event, } } - if ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && - sample_addr_correlates_sym(&evsel->attr)) { + if ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) && + sample_addr_correlates_sym(&evsel->core.attr)) { struct addr_location addr_al; thread__resolve(thread, &addr_al, sample); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index ce9f52215d60..ae75777a0ba4 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -299,8 +299,8 @@ perf_evlist__find_tracepoint_by_id(struct evlist *evlist, int id) struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { - if (evsel->attr.type == PERF_TYPE_TRACEPOINT && - (int)evsel->attr.config == id) + if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT && + (int)evsel->core.attr.config == id) return evsel; } @@ -314,7 +314,7 @@ perf_evlist__find_tracepoint_by_name(struct evlist *evlist, struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { - if ((evsel->attr.type == PERF_TYPE_TRACEPOINT) && + if ((evsel->core.attr.type == PERF_TYPE_TRACEPOINT) && (strcmp(evsel->name, name) == 0)) return evsel; } @@ -529,13 +529,13 @@ int perf_evlist__id_add_fd(struct evlist *evlist, if (perf_evlist__read_format(evlist) & PERF_FORMAT_GROUP) return -1; - if (!(evsel->attr.read_format & PERF_FORMAT_ID) || + if (!(evsel->core.attr.read_format & PERF_FORMAT_ID) || read(fd, &read_data, sizeof(read_data)) == -1) return -1; - if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) + if (evsel->core.attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) ++id_idx; - if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) + if (evsel->core.attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) ++id_idx; id = read_data[id_idx]; @@ -642,7 +642,7 @@ struct evsel *perf_evlist__event2evsel(struct evlist *evlist, if (evlist->core.nr_entries == 1) return first; - if (!first->attr.sample_id_all && + if (!first->core.attr.sample_id_all && event->header.type != PERF_RECORD_SAMPLE) return first; @@ -747,7 +747,7 @@ static bool perf_evlist__should_poll(struct evlist *evlist __maybe_unused, struct evsel *evsel) { - if (evsel->attr.write_backward) + if (evsel->core.attr.write_backward) return false; return true; } @@ -767,7 +767,7 @@ static int perf_evlist__mmap_per_evsel(struct evlist *evlist, int idx, int cpu; mp->prot = PROT_READ | PROT_WRITE; - if (evsel->attr.write_backward) { + if (evsel->core.attr.write_backward) { output = _output_overwrite; maps = evlist->overwrite_mmap; @@ -818,7 +818,7 @@ static int perf_evlist__mmap_per_evsel(struct evlist *evlist, int idx, return -1; } - if (evsel->attr.read_format & PERF_FORMAT_ID) { + if (evsel->core.attr.read_format & PERF_FORMAT_ID) { if (perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0) return -1; @@ -1039,7 +1039,7 @@ int perf_evlist__mmap_ex(struct evlist *evlist, unsigned int pages, auxtrace_pages, auxtrace_overwrite); evlist__for_each_entry(evlist, evsel) { - if ((evsel->attr.read_format & PERF_FORMAT_ID) && + if ((evsel->core.attr.read_format & PERF_FORMAT_ID) && evsel->sample_id == NULL && perf_evsel__alloc_id(evsel, cpu_map__nr(cpus), threads->nr) < 0) return -ENOMEM; @@ -1175,7 +1175,7 @@ int perf_evlist__set_tp_filter(struct evlist *evlist, const char *filter) int err = 0; evlist__for_each_entry(evlist, evsel) { - if (evsel->attr.type != PERF_TYPE_TRACEPOINT) + if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) continue; err = perf_evsel__set_filter(evsel, filter); @@ -1245,7 +1245,7 @@ u64 __perf_evlist__combined_sample_type(struct evlist *evlist) return evlist->combined_sample_type; evlist__for_each_entry(evlist, evsel) - evlist->combined_sample_type |= evsel->attr.sample_type; + evlist->combined_sample_type |= evsel->core.attr.sample_type; return evlist->combined_sample_type; } @@ -1262,18 +1262,18 @@ u64 perf_evlist__combined_branch_type(struct evlist *evlist) u64 branch_type = 0; evlist__for_each_entry(evlist, evsel) - branch_type |= evsel->attr.branch_sample_type; + branch_type |= evsel->core.attr.branch_sample_type; return branch_type; } bool perf_evlist__valid_read_format(struct evlist *evlist) { struct evsel *first = perf_evlist__first(evlist), *pos = first; - u64 read_format = first->attr.read_format; - u64 sample_type = first->attr.sample_type; + u64 read_format = first->core.attr.read_format; + u64 sample_type = first->core.attr.sample_type; evlist__for_each_entry(evlist, pos) { - if (read_format != pos->attr.read_format) + if (read_format != pos->core.attr.read_format) return false; } @@ -1289,7 +1289,7 @@ bool perf_evlist__valid_read_format(struct evlist *evlist) u64 perf_evlist__read_format(struct evlist *evlist) { struct evsel *first = perf_evlist__first(evlist); - return first->attr.read_format; + return first->core.attr.read_format; } u16 perf_evlist__id_hdr_size(struct evlist *evlist) @@ -1299,10 +1299,10 @@ u16 perf_evlist__id_hdr_size(struct evlist *evlist) u64 sample_type; u16 size = 0; - if (!first->attr.sample_id_all) + if (!first->core.attr.sample_id_all) goto out; - sample_type = first->attr.sample_type; + sample_type = first->core.attr.sample_type; if (sample_type & PERF_SAMPLE_TID) size += sizeof(data->tid) * 2; @@ -1330,7 +1330,7 @@ bool perf_evlist__valid_sample_id_all(struct evlist *evlist) struct evsel *first = perf_evlist__first(evlist), *pos = first; evlist__for_each_entry_continue(evlist, pos) { - if (first->attr.sample_id_all != pos->attr.sample_id_all) + if (first->core.attr.sample_id_all != pos->core.attr.sample_id_all) return false; } @@ -1340,7 +1340,7 @@ bool perf_evlist__valid_sample_id_all(struct evlist *evlist) bool perf_evlist__sample_id_all(struct evlist *evlist) { struct evsel *first = perf_evlist__first(evlist); - return first->attr.sample_id_all; + return first->core.attr.sample_id_all; } void perf_evlist__set_selected(struct evlist *evlist, @@ -1620,14 +1620,14 @@ int perf_evlist__strerror_open(struct evlist *evlist, if (sysctl__read_int("kernel/perf_event_max_sample_rate", &max_freq) < 0) goto out_default; - if (first->attr.sample_freq < (u64)max_freq) + if (first->core.attr.sample_freq < (u64)max_freq) goto out_default; printed = scnprintf(buf, size, "Error:\t%s.\n" "Hint:\tCheck /proc/sys/kernel/perf_event_max_sample_rate.\n" "Hint:\tThe current value is %d and %" PRIu64 " is being requested.", - emsg, max_freq, first->attr.sample_freq); + emsg, max_freq, first->core.attr.sample_freq); break; } default: @@ -1782,7 +1782,7 @@ bool perf_evlist__exclude_kernel(struct evlist *evlist) struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { - if (!evsel->attr.exclude_kernel) + if (!evsel->core.attr.exclude_kernel) return false; } diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 172bcc2e198f..089582e644d7 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -170,15 +170,15 @@ static int __perf_evsel__calc_is_pos(u64 sample_type) void perf_evsel__calc_id_pos(struct evsel *evsel) { - evsel->id_pos = __perf_evsel__calc_id_pos(evsel->attr.sample_type); - evsel->is_pos = __perf_evsel__calc_is_pos(evsel->attr.sample_type); + evsel->id_pos = __perf_evsel__calc_id_pos(evsel->core.attr.sample_type); + evsel->is_pos = __perf_evsel__calc_is_pos(evsel->core.attr.sample_type); } void __perf_evsel__set_sample_bit(struct evsel *evsel, enum perf_event_sample_format bit) { - if (!(evsel->attr.sample_type & bit)) { - evsel->attr.sample_type |= bit; + if (!(evsel->core.attr.sample_type & bit)) { + evsel->core.attr.sample_type |= bit; evsel->sample_size += sizeof(u64); perf_evsel__calc_id_pos(evsel); } @@ -187,8 +187,8 @@ void __perf_evsel__set_sample_bit(struct evsel *evsel, void __perf_evsel__reset_sample_bit(struct evsel *evsel, enum perf_event_sample_format bit) { - if (evsel->attr.sample_type & bit) { - evsel->attr.sample_type &= ~bit; + if (evsel->core.attr.sample_type & bit) { + evsel->core.attr.sample_type &= ~bit; evsel->sample_size -= sizeof(u64); perf_evsel__calc_id_pos(evsel); } @@ -203,7 +203,7 @@ void perf_evsel__set_sample_id(struct evsel *evsel, } else { perf_evsel__set_sample_bit(evsel, ID); } - evsel->attr.read_format |= PERF_FORMAT_ID; + evsel->core.attr.read_format |= PERF_FORMAT_ID; } /** @@ -227,10 +227,9 @@ bool perf_evsel__is_function_event(struct evsel *evsel) void evsel__init(struct evsel *evsel, struct perf_event_attr *attr, int idx) { - perf_evsel__init(&evsel->core); + perf_evsel__init(&evsel->core, attr); evsel->idx = idx; evsel->tracking = !idx; - evsel->attr = *attr; evsel->leader = evsel; evsel->unit = ""; evsel->scale = 1.0; @@ -259,9 +258,9 @@ struct evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) evsel__init(evsel, attr, idx); if (perf_evsel__is_bpf_output(evsel)) { - evsel->attr.sample_type |= (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | + evsel->core.attr.sample_type |= (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD), - evsel->attr.sample_period = 1; + evsel->core.attr.sample_period = 1; } if (perf_evsel__is_clock(evsel)) { @@ -387,7 +386,7 @@ static const char *__perf_evsel__hw_name(u64 config) static int perf_evsel__add_modifiers(struct evsel *evsel, char *bf, size_t size) { int colon = 0, r = 0; - struct perf_event_attr *attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->core.attr; bool exclude_guest_default = false; #define MOD_PRINT(context, mod) do { \ @@ -422,7 +421,7 @@ static int perf_evsel__add_modifiers(struct evsel *evsel, char *bf, size_t size) static int perf_evsel__hw_name(struct evsel *evsel, char *bf, size_t size) { - int r = scnprintf(bf, size, "%s", __perf_evsel__hw_name(evsel->attr.config)); + int r = scnprintf(bf, size, "%s", __perf_evsel__hw_name(evsel->core.attr.config)); return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); } @@ -448,7 +447,7 @@ static const char *__perf_evsel__sw_name(u64 config) static int perf_evsel__sw_name(struct evsel *evsel, char *bf, size_t size) { - int r = scnprintf(bf, size, "%s", __perf_evsel__sw_name(evsel->attr.config)); + int r = scnprintf(bf, size, "%s", __perf_evsel__sw_name(evsel->core.attr.config)); return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); } @@ -472,7 +471,7 @@ static int __perf_evsel__bp_name(char *bf, size_t size, u64 addr, u64 type) static int perf_evsel__bp_name(struct evsel *evsel, char *bf, size_t size) { - struct perf_event_attr *attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->core.attr; int r = __perf_evsel__bp_name(bf, size, attr->bp_addr, attr->bp_type); return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); } @@ -572,13 +571,13 @@ out_err: static int perf_evsel__hw_cache_name(struct evsel *evsel, char *bf, size_t size) { - int ret = __perf_evsel__hw_cache_name(evsel->attr.config, bf, size); + int ret = __perf_evsel__hw_cache_name(evsel->core.attr.config, bf, size); return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret); } static int perf_evsel__raw_name(struct evsel *evsel, char *bf, size_t size) { - int ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->attr.config); + int ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->core.attr.config); return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret); } @@ -598,7 +597,7 @@ const char *perf_evsel__name(struct evsel *evsel) if (evsel->name) return evsel->name; - switch (evsel->attr.type) { + switch (evsel->core.attr.type) { case PERF_TYPE_RAW: perf_evsel__raw_name(evsel, bf, sizeof(bf)); break; @@ -628,7 +627,7 @@ const char *perf_evsel__name(struct evsel *evsel) default: scnprintf(bf, sizeof(bf), "unknown attr type: %d", - evsel->attr.type); + evsel->core.attr.type); break; } @@ -682,7 +681,7 @@ static void __perf_evsel__config_callchain(struct evsel *evsel, struct callchain_param *param) { bool function = perf_evsel__is_function_event(evsel); - struct perf_event_attr *attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->core.attr; perf_evsel__set_sample_bit(evsel, CALLCHAIN); @@ -748,7 +747,7 @@ static void perf_evsel__reset_callgraph(struct evsel *evsel, struct callchain_param *param) { - struct perf_event_attr *attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->core.attr; perf_evsel__reset_sample_bit(evsel, CALLCHAIN); if (param->record_mode == CALLCHAIN_LBR) { @@ -767,7 +766,7 @@ static void apply_config_terms(struct evsel *evsel, { struct perf_evsel_config_term *term; struct list_head *config_terms = &evsel->config_terms; - struct perf_event_attr *attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->core.attr; /* callgraph default */ struct callchain_param param = { .record_mode = callchain_param.record_mode, @@ -880,7 +879,7 @@ static void apply_config_terms(struct evsel *evsel, if (sample_address) { perf_evsel__set_sample_bit(evsel, ADDR); perf_evsel__set_sample_bit(evsel, DATA_SRC); - evsel->attr.mmap_data = track; + evsel->core.attr.mmap_data = track; } perf_evsel__config_callchain(evsel, opts, ¶m); } @@ -889,8 +888,8 @@ static void apply_config_terms(struct evsel *evsel, static bool is_dummy_event(struct evsel *evsel) { - return (evsel->attr.type == PERF_TYPE_SOFTWARE) && - (evsel->attr.config == PERF_COUNT_SW_DUMMY); + return (evsel->core.attr.type == PERF_TYPE_SOFTWARE) && + (evsel->core.attr.config == PERF_COUNT_SW_DUMMY); } /* @@ -925,7 +924,7 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts, struct callchain_param *callchain) { struct evsel *leader = evsel->leader; - struct perf_event_attr *attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->core.attr; int track = evsel->tracking; bool per_cpu = opts->target.default_per_cpu && !opts->target.per_thread; @@ -986,14 +985,14 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts, * event to follow the master sample_type to ease up * report. */ - attr->sample_type = leader->attr.sample_type; + attr->sample_type = leader->core.attr.sample_type; } if (opts->no_samples) attr->sample_freq = 0; if (opts->inherit_stat) { - evsel->attr.read_format |= + evsel->core.attr.read_format |= PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING | PERF_FORMAT_ID; @@ -1011,7 +1010,7 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts, * fault handler and its overall trickiness nature. */ if (perf_evsel__is_function_event(evsel)) - evsel->attr.exclude_callchain_user = 1; + evsel->core.attr.exclude_callchain_user = 1; if (callchain && callchain->enabled && !evsel->no_aux_samples) perf_evsel__config_callchain(evsel, opts, callchain); @@ -1080,7 +1079,7 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts, perf_evsel__set_sample_bit(evsel, TRANSACTION); if (opts->running_time) { - evsel->attr.read_format |= + evsel->core.attr.read_format |= PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING; } @@ -1127,7 +1126,7 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts, } if (evsel->own_cpus || evsel->unit) - evsel->attr.read_format |= PERF_FORMAT_ID; + evsel->core.attr.read_format |= PERF_FORMAT_ID; /* * Apply event specific term settings, @@ -1382,7 +1381,7 @@ void perf_counts_values__scale(struct perf_counts_values *count, static int perf_evsel__read_size(struct evsel *evsel) { - u64 read_format = evsel->attr.read_format; + u64 read_format = evsel->core.attr.read_format; int entry = sizeof(u64); /* value */ int size = 0; int nr = 1; @@ -1448,7 +1447,7 @@ static int perf_evsel__process_group_data(struct evsel *leader, int cpu, int thread, u64 *data) { - u64 read_format = leader->attr.read_format; + u64 read_format = leader->core.attr.read_format; struct sample_read_value *v; u64 nr, ena = 0, run = 0, i; @@ -1486,7 +1485,7 @@ static int perf_evsel__read_group(struct evsel *leader, int cpu, int thread) { struct perf_stat_evsel *ps = leader->stats; - u64 read_format = leader->attr.read_format; + u64 read_format = leader->core.attr.read_format; int size = perf_evsel__read_size(leader); u64 *data = ps->group_data; @@ -1515,7 +1514,7 @@ perf_evsel__read_group(struct evsel *leader, int cpu, int thread) int perf_evsel__read_counter(struct evsel *evsel, int cpu, int thread) { - u64 read_format = evsel->attr.read_format; + u64 read_format = evsel->core.attr.read_format; if (read_format & PERF_FORMAT_GROUP) return perf_evsel__read_group(evsel, cpu, thread); @@ -1793,14 +1792,14 @@ static int perf_event_open(struct evsel *evsel, pid_t pid, int cpu, int group_fd, unsigned long flags) { - int precise_ip = evsel->attr.precise_ip; + int precise_ip = evsel->core.attr.precise_ip; int fd; while (1) { pr_debug2("sys_perf_event_open: pid %d cpu %d group_fd %d flags %#lx", pid, cpu, group_fd, flags); - fd = sys_perf_event_open(&evsel->attr, pid, cpu, group_fd, flags); + fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, group_fd, flags); if (fd >= 0) break; @@ -1812,15 +1811,15 @@ static int perf_event_open(struct evsel *evsel, * We tried all the precise_ip values, and it's * still failing, so leave it to standard fallback. */ - if (!evsel->attr.precise_ip) { - evsel->attr.precise_ip = precise_ip; + if (!evsel->core.attr.precise_ip) { + evsel->core.attr.precise_ip = precise_ip; break; } pr_debug2("\nsys_perf_event_open failed, error %d\n", -ENOTSUP); - evsel->attr.precise_ip--; - pr_debug2("decreasing precise_ip by one (%d)\n", evsel->attr.precise_ip); - display_attr(&evsel->attr); + evsel->core.attr.precise_ip--; + pr_debug2("decreasing precise_ip by one (%d)\n", evsel->core.attr.precise_ip); + display_attr(&evsel->core.attr); } return fd; @@ -1834,7 +1833,7 @@ int evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus, int pid = -1, err; enum { NO_CHANGE, SET_TO_MAX, INCREASED_MAX } set_rlimit = NO_CHANGE; - if (perf_missing_features.write_backward && evsel->attr.write_backward) + if (perf_missing_features.write_backward && evsel->core.attr.write_backward) return -EINVAL; if (cpus == NULL) { @@ -1877,31 +1876,31 @@ int evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus, fallback_missing_features: if (perf_missing_features.clockid_wrong) - evsel->attr.clockid = CLOCK_MONOTONIC; /* should always work */ + evsel->core.attr.clockid = CLOCK_MONOTONIC; /* should always work */ if (perf_missing_features.clockid) { - evsel->attr.use_clockid = 0; - evsel->attr.clockid = 0; + evsel->core.attr.use_clockid = 0; + evsel->core.attr.clockid = 0; } if (perf_missing_features.cloexec) flags &= ~(unsigned long)PERF_FLAG_FD_CLOEXEC; if (perf_missing_features.mmap2) - evsel->attr.mmap2 = 0; + evsel->core.attr.mmap2 = 0; if (perf_missing_features.exclude_guest) - evsel->attr.exclude_guest = evsel->attr.exclude_host = 0; + evsel->core.attr.exclude_guest = evsel->core.attr.exclude_host = 0; if (perf_missing_features.lbr_flags) - evsel->attr.branch_sample_type &= ~(PERF_SAMPLE_BRANCH_NO_FLAGS | + evsel->core.attr.branch_sample_type &= ~(PERF_SAMPLE_BRANCH_NO_FLAGS | PERF_SAMPLE_BRANCH_NO_CYCLES); - if (perf_missing_features.group_read && evsel->attr.inherit) - evsel->attr.read_format &= ~(PERF_FORMAT_GROUP|PERF_FORMAT_ID); + if (perf_missing_features.group_read && evsel->core.attr.inherit) + evsel->core.attr.read_format &= ~(PERF_FORMAT_GROUP|PERF_FORMAT_ID); if (perf_missing_features.ksymbol) - evsel->attr.ksymbol = 0; + evsel->core.attr.ksymbol = 0; if (perf_missing_features.bpf_event) - evsel->attr.bpf_event = 0; + evsel->core.attr.bpf_event = 0; retry_sample_id: if (perf_missing_features.sample_id_all) - evsel->attr.sample_id_all = 0; + evsel->core.attr.sample_id_all = 0; - display_attr(&evsel->attr); + display_attr(&evsel->core.attr); for (cpu = 0; cpu < cpus->nr; cpu++) { @@ -2008,23 +2007,23 @@ try_fallback: * Must probe features in the order they were added to the * perf_event_attr interface. */ - if (!perf_missing_features.bpf_event && evsel->attr.bpf_event) { + if (!perf_missing_features.bpf_event && evsel->core.attr.bpf_event) { perf_missing_features.bpf_event = true; pr_debug2("switching off bpf_event\n"); goto fallback_missing_features; - } else if (!perf_missing_features.ksymbol && evsel->attr.ksymbol) { + } else if (!perf_missing_features.ksymbol && evsel->core.attr.ksymbol) { perf_missing_features.ksymbol = true; pr_debug2("switching off ksymbol\n"); goto fallback_missing_features; - } else if (!perf_missing_features.write_backward && evsel->attr.write_backward) { + } else if (!perf_missing_features.write_backward && evsel->core.attr.write_backward) { perf_missing_features.write_backward = true; pr_debug2("switching off write_backward\n"); goto out_close; - } else if (!perf_missing_features.clockid_wrong && evsel->attr.use_clockid) { + } else if (!perf_missing_features.clockid_wrong && evsel->core.attr.use_clockid) { perf_missing_features.clockid_wrong = true; pr_debug2("switching off clockid\n"); goto fallback_missing_features; - } else if (!perf_missing_features.clockid && evsel->attr.use_clockid) { + } else if (!perf_missing_features.clockid && evsel->core.attr.use_clockid) { perf_missing_features.clockid = true; pr_debug2("switching off use_clockid\n"); goto fallback_missing_features; @@ -2032,12 +2031,12 @@ try_fallback: perf_missing_features.cloexec = true; pr_debug2("switching off cloexec flag\n"); goto fallback_missing_features; - } else if (!perf_missing_features.mmap2 && evsel->attr.mmap2) { + } else if (!perf_missing_features.mmap2 && evsel->core.attr.mmap2) { perf_missing_features.mmap2 = true; pr_debug2("switching off mmap2\n"); goto fallback_missing_features; } else if (!perf_missing_features.exclude_guest && - (evsel->attr.exclude_guest || evsel->attr.exclude_host)) { + (evsel->core.attr.exclude_guest || evsel->core.attr.exclude_host)) { perf_missing_features.exclude_guest = true; pr_debug2("switching off exclude_guest, exclude_host\n"); goto fallback_missing_features; @@ -2046,15 +2045,15 @@ try_fallback: pr_debug2("switching off sample_id_all\n"); goto retry_sample_id; } else if (!perf_missing_features.lbr_flags && - (evsel->attr.branch_sample_type & + (evsel->core.attr.branch_sample_type & (PERF_SAMPLE_BRANCH_NO_CYCLES | PERF_SAMPLE_BRANCH_NO_FLAGS))) { perf_missing_features.lbr_flags = true; pr_debug2("switching off branch sample type no (cycles/flags)\n"); goto fallback_missing_features; } else if (!perf_missing_features.group_read && - evsel->attr.inherit && - (evsel->attr.read_format & PERF_FORMAT_GROUP) && + evsel->core.attr.inherit && + (evsel->core.attr.read_format & PERF_FORMAT_GROUP) && perf_evsel__is_group_leader(evsel)) { perf_missing_features.group_read = true; pr_debug2("switching off group read\n"); @@ -2100,7 +2099,7 @@ static int perf_evsel__parse_id_sample(const struct evsel *evsel, const union perf_event *event, struct perf_sample *sample) { - u64 type = evsel->attr.sample_type; + u64 type = evsel->core.attr.sample_type; const u64 *array = event->sample.array; bool swapped = evsel->needs_swap; union u64_swap u; @@ -2189,7 +2188,7 @@ perf_event__check_size(union perf_event *event, unsigned int sample_size) int perf_evsel__parse_sample(struct evsel *evsel, union perf_event *event, struct perf_sample *data) { - u64 type = evsel->attr.sample_type; + u64 type = evsel->core.attr.sample_type; bool swapped = evsel->needs_swap; const u64 *array; u16 max_size = event->header.size; @@ -2205,14 +2204,14 @@ int perf_evsel__parse_sample(struct evsel *evsel, union perf_event *event, memset(data, 0, sizeof(*data)); data->cpu = data->pid = data->tid = -1; data->stream_id = data->id = data->time = -1ULL; - data->period = evsel->attr.sample_period; + data->period = evsel->core.attr.sample_period; data->cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; data->misc = event->header.misc; data->id = -1ULL; data->data_src = PERF_MEM_DATA_SRC_NONE; if (event->header.type != PERF_RECORD_SAMPLE) { - if (!evsel->attr.sample_id_all) + if (!evsel->core.attr.sample_id_all) return 0; return perf_evsel__parse_id_sample(evsel, event, data); } @@ -2285,7 +2284,7 @@ int perf_evsel__parse_sample(struct evsel *evsel, union perf_event *event, } if (type & PERF_SAMPLE_READ) { - u64 read_format = evsel->attr.read_format; + u64 read_format = evsel->core.attr.read_format; OVERFLOW_CHECK_u64(array); if (read_format & PERF_FORMAT_GROUP) @@ -2390,7 +2389,7 @@ int perf_evsel__parse_sample(struct evsel *evsel, union perf_event *event, array++; if (data->user_regs.abi) { - u64 mask = evsel->attr.sample_regs_user; + u64 mask = evsel->core.attr.sample_regs_user; sz = hweight64(mask) * sizeof(u64); OVERFLOW_CHECK(array, sz, max_size); @@ -2446,7 +2445,7 @@ int perf_evsel__parse_sample(struct evsel *evsel, union perf_event *event, array++; if (data->intr_regs.abi != PERF_SAMPLE_REGS_ABI_NONE) { - u64 mask = evsel->attr.sample_regs_intr; + u64 mask = evsel->core.attr.sample_regs_intr; sz = hweight64(mask) * sizeof(u64); OVERFLOW_CHECK(array, sz, max_size); @@ -2469,7 +2468,7 @@ int perf_evsel__parse_sample_timestamp(struct evsel *evsel, union perf_event *event, u64 *timestamp) { - u64 type = evsel->attr.sample_type; + u64 type = evsel->core.attr.sample_type; const u64 *array; if (!(type & PERF_SAMPLE_TIME)) @@ -2480,7 +2479,7 @@ int perf_evsel__parse_sample_timestamp(struct evsel *evsel, .time = -1ULL, }; - if (!evsel->attr.sample_id_all) + if (!evsel->core.attr.sample_id_all) return -1; if (perf_evsel__parse_id_sample(evsel, event, &data)) return -1; @@ -2866,8 +2865,8 @@ bool perf_evsel__fallback(struct evsel *evsel, int err, int paranoid; if ((err == ENOENT || err == ENXIO || err == ENODEV) && - evsel->attr.type == PERF_TYPE_HARDWARE && - evsel->attr.config == PERF_COUNT_HW_CPU_CYCLES) { + evsel->core.attr.type == PERF_TYPE_HARDWARE && + evsel->core.attr.config == PERF_COUNT_HW_CPU_CYCLES) { /* * If it's cycles then fall back to hrtimer based * cpu-clock-tick sw counter, which is always available even if @@ -2879,12 +2878,12 @@ bool perf_evsel__fallback(struct evsel *evsel, int err, scnprintf(msg, msgsize, "%s", "The cycles event is not supported, trying to fall back to cpu-clock-ticks"); - evsel->attr.type = PERF_TYPE_SOFTWARE; - evsel->attr.config = PERF_COUNT_SW_CPU_CLOCK; + evsel->core.attr.type = PERF_TYPE_SOFTWARE; + evsel->core.attr.config = PERF_COUNT_SW_CPU_CLOCK; zfree(&evsel->name); return true; - } else if (err == EACCES && !evsel->attr.exclude_kernel && + } else if (err == EACCES && !evsel->core.attr.exclude_kernel && (paranoid = perf_event_paranoid()) > 1) { const char *name = perf_evsel__name(evsel); char *new_name; @@ -2903,7 +2902,7 @@ bool perf_evsel__fallback(struct evsel *evsel, int err, evsel->name = new_name; scnprintf(msg, msgsize, "kernel.perf_event_paranoid=%d, trying to fall back to excluding kernel samples", paranoid); - evsel->attr.exclude_kernel = 1; + evsel->core.attr.exclude_kernel = 1; return true; } @@ -3000,15 +2999,15 @@ int perf_evsel__open_strerror(struct evsel *evsel, struct target *target, "No such device - did you specify an out-of-range profile CPU?"); break; case EOPNOTSUPP: - if (evsel->attr.sample_period != 0) + if (evsel->core.attr.sample_period != 0) return scnprintf(msg, size, "%s: PMU Hardware doesn't support sampling/overflow-interrupts. Try 'perf stat'", perf_evsel__name(evsel)); - if (evsel->attr.precise_ip) + if (evsel->core.attr.precise_ip) return scnprintf(msg, size, "%s", "\'precise\' request may not be supported. Try removing 'p' modifier."); #if defined(__i386__) || defined(__x86_64__) - if (evsel->attr.type == PERF_TYPE_HARDWARE) + if (evsel->core.attr.type == PERF_TYPE_HARDWARE) return scnprintf(msg, size, "%s", "No hardware sampling interrupt available.\n"); #endif @@ -3020,7 +3019,7 @@ int perf_evsel__open_strerror(struct evsel *evsel, struct target *target, "We found oprofile daemon running, please stop it and try again."); break; case EINVAL: - if (evsel->attr.write_backward && perf_missing_features.write_backward) + if (evsel->core.attr.write_backward && perf_missing_features.write_backward) return scnprintf(msg, size, "Reading from overwrite event is not supported by this kernel."); if (perf_missing_features.clockid) return scnprintf(msg, size, "clockid feature not supported."); diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index d74cac6fe306..43f66158de3b 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -103,7 +103,6 @@ struct bpf_object; struct evsel { struct perf_evsel core; struct evlist *evlist; - struct perf_event_attr attr; char *filter; struct xyarray *fd; struct xyarray *sample_id; @@ -327,21 +326,21 @@ u64 format_field__intval(struct tep_format_field *field, struct perf_sample *sam struct tep_format_field *perf_evsel__field(struct evsel *evsel, const char *name); #define perf_evsel__match(evsel, t, c) \ - (evsel->attr.type == PERF_TYPE_##t && \ - evsel->attr.config == PERF_COUNT_##c) + (evsel->core.attr.type == PERF_TYPE_##t && \ + evsel->core.attr.config == PERF_COUNT_##c) static inline bool perf_evsel__match2(struct evsel *e1, struct evsel *e2) { - return (e1->attr.type == e2->attr.type) && - (e1->attr.config == e2->attr.config); + return (e1->core.attr.type == e2->core.attr.type) && + (e1->core.attr.config == e2->core.attr.config); } #define perf_evsel__cmp(a, b) \ ((a) && \ (b) && \ - (a)->attr.type == (b)->attr.type && \ - (a)->attr.config == (b)->attr.config) + (a)->core.attr.type == (b)->core.attr.type && \ + (a)->core.attr.config == (b)->core.attr.config) int perf_evsel__read(struct evsel *evsel, int cpu, int thread, struct perf_counts_values *count); @@ -490,12 +489,12 @@ for ((_evsel) = _leader; \ static inline bool perf_evsel__has_branch_callstack(const struct evsel *evsel) { - return evsel->attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK; + return evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK; } static inline bool evsel__has_callchain(const struct evsel *evsel) { - return (evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) != 0; + return (evsel->core.attr.sample_type & PERF_SAMPLE_CALLCHAIN) != 0; } typedef int (*attr__fprintf_f)(FILE *, const char *, const char *, void *); diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c index 1fddb7da4b51..3466eca34a00 100644 --- a/tools/perf/util/evsel_fprintf.c +++ b/tools/perf/util/evsel_fprintf.c @@ -60,22 +60,22 @@ int perf_evsel__fprintf(struct evsel *evsel, printed += fprintf(fp, "%s", perf_evsel__name(evsel)); if (details->verbose) { - printed += perf_event_attr__fprintf(fp, &evsel->attr, + printed += perf_event_attr__fprintf(fp, &evsel->core.attr, __print_attr__fprintf, &first); } else if (details->freq) { const char *term = "sample_freq"; - if (!evsel->attr.freq) + if (!evsel->core.attr.freq) term = "sample_period"; printed += comma_fprintf(fp, &first, " %s=%" PRIu64, - term, (u64)evsel->attr.sample_freq); + term, (u64)evsel->core.attr.sample_freq); } if (details->trace_fields) { struct tep_format_field *field; - if (evsel->attr.type != PERF_TYPE_TRACEPOINT) { + if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) { printed += comma_fprintf(fp, &first, " (not a tracepoint)"); goto out; } diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 141de4425100..d81afe56392c 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -488,13 +488,13 @@ static int write_event_desc(struct feat_fd *ff, /* * size of perf_event_attr struct */ - sz = (u32)sizeof(evsel->attr); + sz = (u32)sizeof(evsel->core.attr); ret = do_write(ff, &sz, sizeof(sz)); if (ret < 0) return ret; evlist__for_each_entry(evlist, evsel) { - ret = do_write(ff, &evsel->attr, sz); + ret = do_write(ff, &evsel->core.attr, sz); if (ret < 0) return ret; /* @@ -1575,7 +1575,7 @@ static void free_event_desc(struct evsel *events) if (!events) return; - for (evsel = events; evsel->attr.size; evsel++) { + for (evsel = events; evsel->core.attr.size; evsel++) { zfree(&evsel->name); zfree(&evsel->id); } @@ -1603,12 +1603,12 @@ static struct evsel *read_event_desc(struct feat_fd *ff) if (!buf) goto error; - /* the last event terminates with evsel->attr.size == 0: */ + /* the last event terminates with evsel->core.attr.size == 0: */ events = calloc(nre + 1, sizeof(*events)); if (!events) goto error; - msz = sizeof(evsel->attr); + msz = sizeof(evsel->core.attr); if (sz < msz) msz = sz; @@ -1625,7 +1625,7 @@ static struct evsel *read_event_desc(struct feat_fd *ff) if (ff->ph->needs_swap) perf_event__attr_swap(buf); - memcpy(&evsel->attr, buf, msz); + memcpy(&evsel->core.attr, buf, msz); if (do_read_u32(ff, &nr)) goto error; @@ -1683,7 +1683,7 @@ static void print_event_desc(struct feat_fd *ff, FILE *fp) return; } - for (evsel = events; evsel->attr.size; evsel++) { + for (evsel = events; evsel->core.attr.size; evsel++) { fprintf(fp, "# event : name = %s, ", evsel->name); if (evsel->ids) { @@ -1696,7 +1696,7 @@ static void print_event_desc(struct feat_fd *ff, FILE *fp) fprintf(fp, " }"); } - perf_event_attr__fprintf(fp, &evsel->attr, __desc_attr__fprintf, NULL); + perf_event_attr__fprintf(fp, &evsel->core.attr, __desc_attr__fprintf, NULL); fputc('\n', fp); } @@ -2138,7 +2138,7 @@ process_event_desc(struct feat_fd *ff, void *data __maybe_unused) ff->events = events; } - for (evsel = events; evsel->attr.size; evsel++) + for (evsel = events; evsel->core.attr.size; evsel++) perf_evlist__set_event_name(session->evlist, evsel); if (!session->data->is_pipe) @@ -3071,7 +3071,7 @@ int perf_session__write_header(struct perf_session *session, evlist__for_each_entry(evlist, evsel) { f_attr = (struct perf_file_attr){ - .attr = evsel->attr, + .attr = evsel->core.attr, .ids = { .offset = evsel->id_offset, .size = evsel->ids * sizeof(u64), @@ -3494,9 +3494,9 @@ static int perf_evsel__prepare_tracepoint_event(struct evsel *evsel, return -1; } - event = tep_find_event(pevent, evsel->attr.config); + event = tep_find_event(pevent, evsel->core.attr.config); if (event == NULL) { - pr_debug("cannot find event format for %d\n", (int)evsel->attr.config); + pr_debug("cannot find event format for %d\n", (int)evsel->core.attr.config); return -1; } @@ -3517,7 +3517,7 @@ static int perf_evlist__prepare_tracepoint_events(struct evlist *evlist, struct evsel *pos; evlist__for_each_entry(evlist, pos) { - if (pos->attr.type == PERF_TYPE_TRACEPOINT && + if (pos->core.attr.type == PERF_TYPE_TRACEPOINT && perf_evsel__prepare_tracepoint_event(pos, pevent)) return -1; } @@ -3928,7 +3928,7 @@ int perf_event__synthesize_attrs(struct perf_tool *tool, int err = 0; evlist__for_each_entry(evlist, evsel) { - err = perf_event__synthesize_attr(tool, &evsel->attr, evsel->ids, + err = perf_event__synthesize_attr(tool, &evsel->core.attr, evsel->ids, evsel->id, process); if (err) { pr_debug("failed to create perf header attribute\n"); diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index bb5437f549b6..821e0fe6cf26 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -2638,7 +2638,7 @@ int __hists__scnprintf_title(struct hists *hists, char *bf, size_t size, bool sh enable_ref = true; if (show_freq) - scnprintf(sample_freq_str, sizeof(sample_freq_str), " %d Hz,", evsel->attr.sample_freq); + scnprintf(sample_freq_str, sizeof(sample_freq_str), " %d Hz,", evsel->core.attr.sample_freq); nr_samples = convert_unit(nr_samples, &unit); printed = scnprintf(bf, size, diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index 849a5b713b04..7eb9e6dc27dd 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c @@ -768,7 +768,7 @@ static int intel_bts_synth_events(struct intel_bts *bts, int err; evlist__for_each_entry(evlist, evsel) { - if (evsel->attr.type == bts->pmu_type && evsel->ids) { + if (evsel->core.attr.type == bts->pmu_type && evsel->ids) { found = true; break; } @@ -782,18 +782,18 @@ static int intel_bts_synth_events(struct intel_bts *bts, memset(&attr, 0, sizeof(struct perf_event_attr)); attr.size = sizeof(struct perf_event_attr); attr.type = PERF_TYPE_HARDWARE; - attr.sample_type = evsel->attr.sample_type & PERF_SAMPLE_MASK; + attr.sample_type = evsel->core.attr.sample_type & PERF_SAMPLE_MASK; attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_PERIOD; attr.sample_type &= ~(u64)PERF_SAMPLE_TIME; attr.sample_type &= ~(u64)PERF_SAMPLE_CPU; - attr.exclude_user = evsel->attr.exclude_user; - attr.exclude_kernel = evsel->attr.exclude_kernel; - attr.exclude_hv = evsel->attr.exclude_hv; - attr.exclude_host = evsel->attr.exclude_host; - attr.exclude_guest = evsel->attr.exclude_guest; - attr.sample_id_all = evsel->attr.sample_id_all; - attr.read_format = evsel->attr.read_format; + attr.exclude_user = evsel->core.attr.exclude_user; + attr.exclude_kernel = evsel->core.attr.exclude_kernel; + attr.exclude_hv = evsel->core.attr.exclude_hv; + attr.exclude_host = evsel->core.attr.exclude_host; + attr.exclude_guest = evsel->core.attr.exclude_guest; + attr.sample_id_all = evsel->core.attr.sample_id_all; + attr.read_format = evsel->core.attr.read_format; id = evsel->id[0] + 1000000000; if (!id) diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index c88e3d1ee9c7..4c52204868d8 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -726,8 +726,8 @@ static bool intel_pt_exclude_kernel(struct intel_pt *pt) struct evsel *evsel; evlist__for_each_entry(pt->session->evlist, evsel) { - if (intel_pt_get_config(pt, &evsel->attr, NULL) && - !evsel->attr.exclude_kernel) + if (intel_pt_get_config(pt, &evsel->core.attr, NULL) && + !evsel->core.attr.exclude_kernel) return false; } return true; @@ -742,7 +742,7 @@ static bool intel_pt_return_compression(struct intel_pt *pt) return true; evlist__for_each_entry(pt->session->evlist, evsel) { - if (intel_pt_get_config(pt, &evsel->attr, &config) && + if (intel_pt_get_config(pt, &evsel->core.attr, &config) && (config & pt->noretcomp_bit)) return false; } @@ -755,7 +755,7 @@ static bool intel_pt_branch_enable(struct intel_pt *pt) u64 config; evlist__for_each_entry(pt->session->evlist, evsel) { - if (intel_pt_get_config(pt, &evsel->attr, &config) && + if (intel_pt_get_config(pt, &evsel->core.attr, &config) && (config & 1) && !(config & 0x2000)) return false; } @@ -775,7 +775,7 @@ static unsigned int intel_pt_mtc_period(struct intel_pt *pt) config >>= 1; evlist__for_each_entry(pt->session->evlist, evsel) { - if (intel_pt_get_config(pt, &evsel->attr, &config)) + if (intel_pt_get_config(pt, &evsel->core.attr, &config)) return (config & pt->mtc_freq_bits) >> shift; } return 0; @@ -791,9 +791,9 @@ static bool intel_pt_timeless_decoding(struct intel_pt *pt) return true; evlist__for_each_entry(pt->session->evlist, evsel) { - if (!(evsel->attr.sample_type & PERF_SAMPLE_TIME)) + if (!(evsel->core.attr.sample_type & PERF_SAMPLE_TIME)) return true; - if (intel_pt_get_config(pt, &evsel->attr, &config)) { + if (intel_pt_get_config(pt, &evsel->core.attr, &config)) { if (config & pt->tsc_bit) timeless_decoding = false; else @@ -808,8 +808,8 @@ static bool intel_pt_tracing_kernel(struct intel_pt *pt) struct evsel *evsel; evlist__for_each_entry(pt->session->evlist, evsel) { - if (intel_pt_get_config(pt, &evsel->attr, NULL) && - !evsel->attr.exclude_kernel) + if (intel_pt_get_config(pt, &evsel->core.attr, NULL) && + !evsel->core.attr.exclude_kernel) return true; } return false; @@ -825,7 +825,7 @@ static bool intel_pt_have_tsc(struct intel_pt *pt) return false; evlist__for_each_entry(pt->session->evlist, evsel) { - if (intel_pt_get_config(pt, &evsel->attr, &config)) { + if (intel_pt_get_config(pt, &evsel->core.attr, &config)) { if (config & pt->tsc_bit) have_tsc = true; else @@ -1703,7 +1703,7 @@ static int intel_pt_synth_pebs_sample(struct intel_pt_queue *ptq) union perf_event *event = ptq->event_buf; struct intel_pt *pt = ptq->pt; struct evsel *evsel = pt->pebs_evsel; - u64 sample_type = evsel->attr.sample_type; + u64 sample_type = evsel->core.attr.sample_type; u64 id = evsel->id[0]; u8 cpumode; @@ -1715,8 +1715,8 @@ static int intel_pt_synth_pebs_sample(struct intel_pt_queue *ptq) sample.id = id; sample.stream_id = id; - if (!evsel->attr.freq) - sample.period = evsel->attr.sample_period; + if (!evsel->core.attr.freq) + sample.period = evsel->core.attr.sample_period; /* No support for non-zero CS base */ if (items->has_ip) @@ -1757,7 +1757,7 @@ static int intel_pt_synth_pebs_sample(struct intel_pt_queue *ptq) if (sample_type & PERF_SAMPLE_REGS_INTR && items->mask[INTEL_PT_GP_REGS_POS]) { u64 regs[sizeof(sample.intr_regs.mask)]; - u64 regs_mask = evsel->attr.sample_regs_intr; + u64 regs_mask = evsel->core.attr.sample_regs_intr; u64 *pos; sample.intr_regs.abi = items->is_32_bit ? @@ -2734,7 +2734,7 @@ static struct evsel *intel_pt_evsel(struct intel_pt *pt, struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { - if (evsel->attr.type == pt->pmu_type && evsel->ids) + if (evsel->core.attr.type == pt->pmu_type && evsel->ids) return evsel; } @@ -2758,7 +2758,7 @@ static int intel_pt_synth_events(struct intel_pt *pt, memset(&attr, 0, sizeof(struct perf_event_attr)); attr.size = sizeof(struct perf_event_attr); attr.type = PERF_TYPE_HARDWARE; - attr.sample_type = evsel->attr.sample_type & PERF_SAMPLE_MASK; + attr.sample_type = evsel->core.attr.sample_type & PERF_SAMPLE_MASK; attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_PERIOD; if (pt->timeless_decoding) @@ -2767,13 +2767,13 @@ static int intel_pt_synth_events(struct intel_pt *pt, attr.sample_type |= PERF_SAMPLE_TIME; if (!pt->per_cpu_mmaps) attr.sample_type &= ~(u64)PERF_SAMPLE_CPU; - attr.exclude_user = evsel->attr.exclude_user; - attr.exclude_kernel = evsel->attr.exclude_kernel; - attr.exclude_hv = evsel->attr.exclude_hv; - attr.exclude_host = evsel->attr.exclude_host; - attr.exclude_guest = evsel->attr.exclude_guest; - attr.sample_id_all = evsel->attr.sample_id_all; - attr.read_format = evsel->attr.read_format; + attr.exclude_user = evsel->core.attr.exclude_user; + attr.exclude_kernel = evsel->core.attr.exclude_kernel; + attr.exclude_hv = evsel->core.attr.exclude_hv; + attr.exclude_host = evsel->core.attr.exclude_host; + attr.exclude_guest = evsel->core.attr.exclude_guest; + attr.sample_id_all = evsel->core.attr.sample_id_all; + attr.read_format = evsel->core.attr.read_format; id = evsel->id[0] + 1000000000; if (!id) @@ -2857,7 +2857,7 @@ static int intel_pt_synth_events(struct intel_pt *pt, id += 1; } - if (pt->synth_opts.pwr_events && (evsel->attr.config & 0x10)) { + if (pt->synth_opts.pwr_events && (evsel->core.attr.config & 0x10)) { attr.config = PERF_SYNTH_INTEL_MWAIT; err = intel_pt_synth_event(session, "mwait", &attr, id); if (err) @@ -2913,7 +2913,7 @@ static bool intel_pt_find_switch(struct evlist *evlist) struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { - if (evsel->attr.context_switch) + if (evsel->core.attr.context_switch) return true; } diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c index 8df60703411a..bbeac4f66402 100644 --- a/tools/perf/util/jitdump.c +++ b/tools/perf/util/jitdump.c @@ -124,7 +124,7 @@ jit_validate_events(struct perf_session *session) * check that all events use CLOCK_MONOTONIC */ evlist__for_each_entry(session->evlist, evsel) { - if (evsel->attr.use_clockid == 0 || evsel->attr.clockid != CLOCK_MONOTONIC) + if (evsel->core.attr.use_clockid == 0 || evsel->core.attr.clockid != CLOCK_MONOTONIC) return -1; } return 0; @@ -779,7 +779,7 @@ jit_process(struct perf_session *session, * perf sets the same sample type to all events as of now */ first = perf_evlist__first(session->evlist); - jd.sample_type = first->attr.sample_type; + jd.sample_type = first->core.attr.sample_type; *nbytes = 0; diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index ec0675b0caa8..f6ee7fbad3e4 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -2498,8 +2498,8 @@ static int thread__resolve_callchain_unwind(struct thread *thread, int max_stack) { /* Can we do dwarf post unwind? */ - if (!((evsel->attr.sample_type & PERF_SAMPLE_REGS_USER) && - (evsel->attr.sample_type & PERF_SAMPLE_STACK_USER))) + if (!((evsel->core.attr.sample_type & PERF_SAMPLE_REGS_USER) && + (evsel->core.attr.sample_type & PERF_SAMPLE_STACK_USER))) return 0; /* Bail out if nothing was captured. */ diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 10efc33c56a1..ec7ce18b999a 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1590,16 +1590,16 @@ struct event_modifier { static int get_event_modifier(struct event_modifier *mod, char *str, struct evsel *evsel) { - int eu = evsel ? evsel->attr.exclude_user : 0; - int ek = evsel ? evsel->attr.exclude_kernel : 0; - int eh = evsel ? evsel->attr.exclude_hv : 0; - int eH = evsel ? evsel->attr.exclude_host : 0; - int eG = evsel ? evsel->attr.exclude_guest : 0; - int eI = evsel ? evsel->attr.exclude_idle : 0; - int precise = evsel ? evsel->attr.precise_ip : 0; + int eu = evsel ? evsel->core.attr.exclude_user : 0; + int ek = evsel ? evsel->core.attr.exclude_kernel : 0; + int eh = evsel ? evsel->core.attr.exclude_hv : 0; + int eH = evsel ? evsel->core.attr.exclude_host : 0; + int eG = evsel ? evsel->core.attr.exclude_guest : 0; + int eI = evsel ? evsel->core.attr.exclude_idle : 0; + int precise = evsel ? evsel->core.attr.precise_ip : 0; int precise_max = 0; int sample_read = 0; - int pinned = evsel ? evsel->attr.pinned : 0; + int pinned = evsel ? evsel->core.attr.pinned : 0; int exclude = eu | ek | eh; int exclude_GH = evsel ? evsel->exclude_GH : 0; @@ -1717,20 +1717,20 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add) if (add && get_event_modifier(&mod, str, evsel)) return -EINVAL; - evsel->attr.exclude_user = mod.eu; - evsel->attr.exclude_kernel = mod.ek; - evsel->attr.exclude_hv = mod.eh; - evsel->attr.precise_ip = mod.precise; - evsel->attr.exclude_host = mod.eH; - evsel->attr.exclude_guest = mod.eG; - evsel->attr.exclude_idle = mod.eI; + evsel->core.attr.exclude_user = mod.eu; + evsel->core.attr.exclude_kernel = mod.ek; + evsel->core.attr.exclude_hv = mod.eh; + evsel->core.attr.precise_ip = mod.precise; + evsel->core.attr.exclude_host = mod.eH; + evsel->core.attr.exclude_guest = mod.eG; + evsel->core.attr.exclude_idle = mod.eI; evsel->exclude_GH = mod.exclude_GH; evsel->sample_read = mod.sample_read; evsel->precise_max = mod.precise_max; evsel->weak_group = mod.weak; if (perf_evsel__is_group_leader(evsel)) - evsel->attr.pinned = mod.pinned; + evsel->core.attr.pinned = mod.pinned; } return 0; @@ -2071,7 +2071,7 @@ static int set_filter(struct evsel *evsel, const void *arg) return -1; } - if (evsel->attr.type == PERF_TYPE_TRACEPOINT) { + if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) { if (perf_evsel__append_tp_filter(evsel, str) < 0) { fprintf(stderr, "not enough memory to hold filter string\n"); @@ -2082,7 +2082,7 @@ static int set_filter(struct evsel *evsel, const void *arg) } while ((pmu = perf_pmu__scan(pmu)) != NULL) - if (pmu->type == evsel->attr.type) { + if (pmu->type == evsel->core.attr.type) { found = true; break; } @@ -2120,7 +2120,7 @@ static int add_exclude_perf_filter(struct evsel *evsel, { char new_filter[64]; - if (evsel == NULL || evsel->attr.type != PERF_TYPE_TRACEPOINT) { + if (evsel == NULL || evsel->core.attr.type != PERF_TYPE_TRACEPOINT) { fprintf(stderr, "--exclude-perf option should follow a -e tracepoint option\n"); return -1; @@ -2331,7 +2331,7 @@ static bool is_event_supported(u8 type, unsigned config) * by default as some ARM machines do not support it. * */ - evsel->attr.exclude_kernel = 1; + evsel->core.attr.exclude_kernel = 1; ret = evsel__open(evsel, NULL, tmap) >= 0; } evsel__delete(evsel); diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index cf0a18d49018..23a4fa13b92d 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -337,7 +337,7 @@ static PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent) static bool is_tracepoint(struct pyrf_event *pevent) { - return pevent->evsel->attr.type == PERF_TYPE_TRACEPOINT; + return pevent->evsel->core.attr.type == PERF_TYPE_TRACEPOINT; } static PyObject* @@ -389,7 +389,7 @@ get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name) if (!evsel->tp_format) { struct tep_event *tp_format; - tp_format = trace_event__tp_format_id(evsel->attr.config); + tp_format = trace_event__tp_format_id(evsel->core.attr.config); if (!tp_format) return NULL; @@ -812,7 +812,7 @@ static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel, if (pcpus != NULL) cpus = ((struct pyrf_cpu_map *)pcpus)->cpus; - evsel->attr.inherit = inherit; + evsel->core.attr.inherit = inherit; /* * This will group just the fds for this single evsel, to group * multiple events, use evlist.open(). diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 3d3d732498e1..445788819969 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -29,7 +29,7 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str) evsel = perf_evlist__first(evlist); while (1) { - fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1, flags); + fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, flags); if (fd < 0) { if (pid == -1 && errno == EACCES) { pid = 0; @@ -43,7 +43,7 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str) fn(evsel); - fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1, flags); + fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, flags); if (fd < 0) { if (errno == EINVAL) err = -EINVAL; @@ -80,17 +80,17 @@ static bool perf_probe_api(setup_probe_fn_t fn) static void perf_probe_sample_identifier(struct evsel *evsel) { - evsel->attr.sample_type |= PERF_SAMPLE_IDENTIFIER; + evsel->core.attr.sample_type |= PERF_SAMPLE_IDENTIFIER; } static void perf_probe_comm_exec(struct evsel *evsel) { - evsel->attr.comm_exec = 1; + evsel->core.attr.comm_exec = 1; } static void perf_probe_context_switch(struct evsel *evsel) { - evsel->attr.context_switch = 1; + evsel->core.attr.context_switch = 1; } bool perf_can_sample_identifier(void) @@ -155,7 +155,7 @@ void perf_evlist__config(struct evlist *evlist, struct record_opts *opts, evlist__for_each_entry(evlist, evsel) { perf_evsel__config(evsel, opts, callchain); if (evsel->tracking && use_comm_exec) - evsel->attr.comm_exec = 1; + evsel->core.attr.comm_exec = 1; } if (opts->full_auxtrace) { @@ -170,7 +170,7 @@ void perf_evlist__config(struct evlist *evlist, struct record_opts *opts, struct evsel *first = perf_evlist__first(evlist); evlist__for_each_entry(evlist, evsel) { - if (evsel->attr.sample_type == first->attr.sample_type) + if (evsel->core.attr.sample_type == first->core.attr.sample_type) continue; use_sample_identifier = perf_can_sample_identifier(); break; @@ -284,7 +284,7 @@ bool perf_evlist__can_select_event(struct evlist *evlist, const char *str) } while (1) { - fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1, + fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, perf_event_open_cloexec_flag()); if (fd < 0) { if (pid == -1 && errno == EACCES) { diff --git a/tools/perf/util/s390-cpumsf.c b/tools/perf/util/s390-cpumsf.c index 59d78a9fe703..d078ae8353c8 100644 --- a/tools/perf/util/s390-cpumsf.c +++ b/tools/perf/util/s390-cpumsf.c @@ -935,7 +935,7 @@ s390_cpumsf_process_event(struct perf_session *session, /* Handle event with raw data */ ev_bc000 = perf_evlist__event2evsel(session->evlist, event); if (ev_bc000 && - ev_bc000->attr.config == PERF_EVENT_CPUM_CF_DIAG) + ev_bc000->core.attr.config == PERF_EVENT_CPUM_CF_DIAG) err = s390_cpumcf_dumpctr(sf, sample); return err; } diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sample-raw.c index 6c709647cd8e..d311c81464e5 100644 --- a/tools/perf/util/s390-sample-raw.c +++ b/tools/perf/util/s390-sample-raw.c @@ -210,7 +210,7 @@ void perf_evlist__s390_sample_raw(struct evlist *evlist, union perf_event *event ev_bc000 = perf_evlist__event2evsel(evlist, event); if (ev_bc000 == NULL || - ev_bc000->attr.config != PERF_EVENT_CPUM_CF_DIAG) + ev_bc000->core.attr.config != PERF_EVENT_CPUM_CF_DIAG) return; /* Display raw data on screen */ diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index 98dcdb9a79a4..01ebf10b8bf4 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c @@ -353,11 +353,11 @@ static void perl_process_tracepoint(struct perf_sample *sample, dSP; - if (evsel->attr.type != PERF_TYPE_TRACEPOINT) + if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) return; if (!event) { - pr_debug("ug! no event found for type %" PRIu64, (u64)evsel->attr.config); + pr_debug("ug! no event found for type %" PRIu64, (u64)evsel->core.attr.config); return; } @@ -442,7 +442,7 @@ static void perl_process_event_generic(union perf_event *event, SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpvn((const char *)event, event->header.size))); - XPUSHs(sv_2mortal(newSVpvn((const char *)&evsel->attr, sizeof(evsel->attr)))); + XPUSHs(sv_2mortal(newSVpvn((const char *)&evsel->core.attr, sizeof(evsel->core.attr)))); XPUSHs(sv_2mortal(newSVpvn((const char *)sample, sizeof(*sample)))); XPUSHs(sv_2mortal(newSVpvn((const char *)sample->raw_data, sample->raw_size))); PUTBACK; diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 106aec31c07c..78b40c1d688e 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -636,7 +636,7 @@ static void set_sample_read_in_dict(PyObject *dict_sample, struct perf_sample *sample, struct evsel *evsel) { - u64 read_format = evsel->attr.read_format; + u64 read_format = evsel->core.attr.read_format; PyObject *values; unsigned int i; @@ -707,7 +707,7 @@ static void set_regs_in_dict(PyObject *dict, struct perf_sample *sample, struct evsel *evsel) { - struct perf_event_attr *attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->core.attr; char bf[512]; regs_map(&sample->intr_regs, attr->sample_regs_intr, bf, sizeof(bf)); @@ -737,7 +737,7 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample, Py_FatalError("couldn't create Python dictionary"); pydict_set_item_string_decref(dict, "ev_name", _PyUnicode_FromString(perf_evsel__name(evsel))); - pydict_set_item_string_decref(dict, "attr", _PyBytes_FromStringAndSize((const char *)&evsel->attr, sizeof(evsel->attr))); + pydict_set_item_string_decref(dict, "attr", _PyBytes_FromStringAndSize((const char *)&evsel->core.attr, sizeof(evsel->core.attr))); pydict_set_item_string_decref(dict_sample, "pid", _PyLong_FromLong(sample->pid)); @@ -809,7 +809,7 @@ static void python_process_tracepoint(struct perf_sample *sample, if (!event) { snprintf(handler_name, sizeof(handler_name), - "ug! no event found for type %" PRIu64, (u64)evsel->attr.config); + "ug! no event found for type %" PRIu64, (u64)evsel->core.attr.config); Py_FatalError(handler_name); } @@ -1163,7 +1163,7 @@ static void python_export_synth(struct db_export *dbe, struct export_sample *es) t = tuple_new(3); tuple_set_u64(t, 0, es->db_id); - tuple_set_u64(t, 1, es->evsel->attr.config); + tuple_set_u64(t, 1, es->evsel->core.attr.config); tuple_set_bytes(t, 2, es->sample->raw_data, es->sample->raw_size); call_object(tables->synth_handler, t, "synth_data"); @@ -1178,7 +1178,7 @@ static int python_export_sample(struct db_export *dbe, python_export_sample_table(dbe, es); - if (es->evsel->attr.type == PERF_TYPE_SYNTH && tables->synth_handler) + if (es->evsel->core.attr.type == PERF_TYPE_SYNTH && tables->synth_handler) python_export_synth(dbe, es); return 0; @@ -1316,7 +1316,7 @@ static void python_process_event(union perf_event *event, { struct tables *tables = &tables_global; - switch (evsel->attr.type) { + switch (evsel->core.attr.type) { case PERF_TYPE_TRACEPOINT: python_process_tracepoint(sample, evsel, al); break; diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 62d37440cbee..1f3dc7a8cee6 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -154,7 +154,7 @@ static bool perf_session__has_comm_exec(struct perf_session *session) struct evsel *evsel; evlist__for_each_entry(session->evlist, evsel) { - if (evsel->attr.comm_exec) + if (evsel->core.attr.comm_exec) return true; } @@ -1210,7 +1210,7 @@ static void dump_sample(struct evsel *evsel, union perf_event *event, event->header.misc, sample->pid, sample->tid, sample->ip, sample->period, sample->addr); - sample_type = evsel->attr.sample_type; + sample_type = evsel->core.attr.sample_type; if (evsel__has_callchain(evsel)) callchain__printf(evsel, sample); @@ -1240,7 +1240,7 @@ static void dump_sample(struct evsel *evsel, union perf_event *event, printf("... transaction: %" PRIx64 "\n", sample->transaction); if (sample_type & PERF_SAMPLE_READ) - sample_read__printf(sample, evsel->attr.read_format); + sample_read__printf(sample, evsel->core.attr.read_format); } static void dump_read(struct evsel *evsel, union perf_event *event) @@ -1258,7 +1258,7 @@ static void dump_read(struct evsel *evsel, union perf_event *event) if (!evsel) return; - read_format = evsel->attr.read_format; + read_format = evsel->core.attr.read_format; if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) printf("... time enabled : %" PRIu64 "\n", read_event->time_enabled); @@ -1355,8 +1355,8 @@ static int struct machine *machine) { /* We know evsel != NULL. */ - u64 sample_type = evsel->attr.sample_type; - u64 read_format = evsel->attr.read_format; + u64 sample_type = evsel->core.attr.sample_type; + u64 read_format = evsel->core.attr.read_format; /* Standard sample delivery. */ if (!(sample_type & PERF_SAMPLE_READ)) @@ -1709,7 +1709,7 @@ perf_session__warn_order(const struct perf_session *session) bool should_warn = true; evlist__for_each_entry(session->evlist, evsel) { - if (evsel->attr.write_backward) + if (evsel->core.attr.write_backward) should_warn = false; } @@ -2186,7 +2186,7 @@ bool perf_session__has_traces(struct perf_session *session, const char *msg) struct evsel *evsel; evlist__for_each_entry(session->evlist, evsel) { - if (evsel->attr.type == PERF_TYPE_TRACEPOINT) + if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) return true; } @@ -2263,7 +2263,7 @@ struct evsel *perf_session__find_first_evtype(struct perf_session *session, struct evsel *pos; evlist__for_each_entry(session->evlist, pos) { - if (pos->attr.type == type) + if (pos->core.attr.type == type) return pos; } return NULL; @@ -2282,7 +2282,7 @@ int perf_session__cpu_bitmap(struct perf_session *session, if (!evsel) continue; - if (!(evsel->attr.sample_type & PERF_SAMPLE_CPU)) { + if (!(evsel->core.attr.sample_type & PERF_SAMPLE_CPU)) { pr_err("File does not contain CPU events. " "Remove -C option to proceed.\n"); return -1; diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index fa3cc2112b82..f9a38a1dd4d1 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -726,7 +726,7 @@ sort__trace_cmp(struct hist_entry *left, struct hist_entry *right) struct evsel *evsel; evsel = hists_to_evsel(left->hists); - if (evsel->attr.type != PERF_TYPE_TRACEPOINT) + if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) return 0; if (left->trace_output == NULL) @@ -743,7 +743,7 @@ static int hist_entry__trace_snprintf(struct hist_entry *he, char *bf, struct evsel *evsel; evsel = hists_to_evsel(he->hists); - if (evsel->attr.type != PERF_TYPE_TRACEPOINT) + if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) return scnprintf(bf, size, "%-.*s", width, "N/A"); if (he->trace_output == NULL) @@ -2391,7 +2391,7 @@ static int add_all_dynamic_fields(struct evlist *evlist, bool raw_trace, struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { - if (evsel->attr.type != PERF_TYPE_TRACEPOINT) + if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) continue; ret = add_evsel_fields(evsel, raw_trace, level); @@ -2409,7 +2409,7 @@ static int add_all_matching_fields(struct evlist *evlist, struct tep_format_field *field; evlist__for_each_entry(evlist, evsel) { - if (evsel->attr.type != PERF_TYPE_TRACEPOINT) + if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) continue; field = tep_find_any_field(evsel->tp_format, field_name); @@ -2470,7 +2470,7 @@ static int add_dynamic_entry(struct evlist *evlist, const char *tok, goto out; } - if (evsel->attr.type != PERF_TYPE_TRACEPOINT) { + if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) { pr_debug("%s is not a tracepoint event\n", event_name); ret = -EINVAL; goto out; @@ -2728,7 +2728,7 @@ static const char *get_default_sort_order(struct evlist *evlist) goto out_no_evlist; evlist__for_each_entry(evlist, evsel) { - if (evsel->attr.type != PERF_TYPE_TRACEPOINT) { + if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) { use_trace = false; break; } diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index b1a2571f7c8f..99bda99a1b2d 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -366,7 +366,7 @@ static void abs_printout(struct perf_stat_config *config, static bool is_mixed_hw_group(struct evsel *counter) { struct evlist *evlist = counter->evlist; - u32 pmu_type = counter->attr.type; + u32 pmu_type = counter->core.attr.type; struct evsel *pos; if (counter->nr_members < 2) @@ -374,13 +374,13 @@ static bool is_mixed_hw_group(struct evsel *counter) evlist__for_each_entry(evlist, pos) { /* software events can be part of any hardware group */ - if (pos->attr.type == PERF_TYPE_SOFTWARE) + if (pos->core.attr.type == PERF_TYPE_SOFTWARE) continue; if (pmu_type == PERF_TYPE_SOFTWARE) { - pmu_type = pos->attr.type; + pmu_type = pos->core.attr.type; continue; } - if (pmu_type != pos->attr.type) + if (pmu_type != pos->core.attr.type) return true; } diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index d81bcab2e64c..2ed5e0066c70 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -150,15 +150,15 @@ static int evsel_context(struct evsel *evsel) { int ctx = 0; - if (evsel->attr.exclude_kernel) + if (evsel->core.attr.exclude_kernel) ctx |= CTX_BIT_KERNEL; - if (evsel->attr.exclude_user) + if (evsel->core.attr.exclude_user) ctx |= CTX_BIT_USER; - if (evsel->attr.exclude_hv) + if (evsel->core.attr.exclude_hv) ctx |= CTX_BIT_HV; - if (evsel->attr.exclude_host) + if (evsel->core.attr.exclude_host) ctx |= CTX_BIT_HOST; - if (evsel->attr.exclude_idle) + if (evsel->core.attr.exclude_idle) ctx |= CTX_BIT_IDLE; return ctx; @@ -829,8 +829,8 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config, else print_metric(config, ctxp, NULL, NULL, "of all branches", 0); } else if ( - evsel->attr.type == PERF_TYPE_HW_CACHE && - evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1D | + evsel->core.attr.type == PERF_TYPE_HW_CACHE && + evsel->core.attr.config == ( PERF_COUNT_HW_CACHE_L1D | ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) { @@ -839,8 +839,8 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config, else print_metric(config, ctxp, NULL, NULL, "of all L1-dcache hits", 0); } else if ( - evsel->attr.type == PERF_TYPE_HW_CACHE && - evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1I | + evsel->core.attr.type == PERF_TYPE_HW_CACHE && + evsel->core.attr.config == ( PERF_COUNT_HW_CACHE_L1I | ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) { @@ -849,8 +849,8 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config, else print_metric(config, ctxp, NULL, NULL, "of all L1-icache hits", 0); } else if ( - evsel->attr.type == PERF_TYPE_HW_CACHE && - evsel->attr.config == ( PERF_COUNT_HW_CACHE_DTLB | + evsel->core.attr.type == PERF_TYPE_HW_CACHE && + evsel->core.attr.config == ( PERF_COUNT_HW_CACHE_DTLB | ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) { @@ -859,8 +859,8 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config, else print_metric(config, ctxp, NULL, NULL, "of all dTLB cache hits", 0); } else if ( - evsel->attr.type == PERF_TYPE_HW_CACHE && - evsel->attr.config == ( PERF_COUNT_HW_CACHE_ITLB | + evsel->core.attr.type == PERF_TYPE_HW_CACHE && + evsel->core.attr.config == ( PERF_COUNT_HW_CACHE_ITLB | ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) { @@ -869,8 +869,8 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config, else print_metric(config, ctxp, NULL, NULL, "of all iTLB cache hits", 0); } else if ( - evsel->attr.type == PERF_TYPE_HW_CACHE && - evsel->attr.config == ( PERF_COUNT_HW_CACHE_LL | + evsel->core.attr.type == PERF_TYPE_HW_CACHE && + evsel->core.attr.config == ( PERF_COUNT_HW_CACHE_LL | ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) { diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 63f7815ceb4f..632bf72cf780 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -441,7 +441,7 @@ int create_perf_stat_counter(struct evsel *evsel, struct perf_stat_config *config, struct target *target) { - struct perf_event_attr *attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->core.attr; struct evsel *leader = evsel->leader; attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c index 3bbbdac2c550..f533f1aac045 100644 --- a/tools/perf/util/top.c +++ b/tools/perf/util/top.c @@ -73,7 +73,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) if (top->evlist->core.nr_entries == 1) { struct evsel *first = perf_evlist__first(top->evlist); ret += SNPRINTF(bf + ret, size - ret, "%" PRIu64 "%s ", - (uint64_t)first->attr.sample_period, + (uint64_t)first->core.attr.sample_period, opts->freq ? "Hz" : ""); } diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index 7efdbb182ea1..2f8a0601a546 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c @@ -409,7 +409,7 @@ get_tracepoints_path(struct list_head *pattrs) int nr_tracepoints = 0; list_for_each_entry(pos, pattrs, core.node) { - if (pos->attr.type != PERF_TYPE_TRACEPOINT) + if (pos->core.attr.type != PERF_TYPE_TRACEPOINT) continue; ++nr_tracepoints; @@ -425,7 +425,7 @@ get_tracepoints_path(struct list_head *pattrs) } try_id: - ppath->next = tracepoint_id_to_path(pos->attr.config); + ppath->next = tracepoint_id_to_path(pos->core.attr.config); if (!ppath->next) { error: pr_debug("No memory to alloc tracepoints list\n"); @@ -444,7 +444,7 @@ bool have_tracepoints(struct list_head *pattrs) struct evsel *pos; list_for_each_entry(pos, pattrs, core.node) - if (pos->attr.type == PERF_TYPE_TRACEPOINT) + if (pos->core.attr.type == PERF_TYPE_TRACEPOINT) return true; return false; -- cgit v1.2.3-59-g8ed1b From 9c3516d1b850ea938b074df33e4c86d721c77720 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:30 +0200 Subject: libperf: Add perf_cpu_map__new()/perf_cpu_map__read() functions Moving the following functions from tools/perf: cpu_map__new() cpu_map__read() to libperf with the following names: perf_cpu_map__new() perf_cpu_map__read() Committer notes: Fixed up this one: tools/perf/arch/arm/util/cs-etm.c Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-44-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 6 +- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 3 +- tools/perf/bench/epoll-ctl.c | 3 +- tools/perf/bench/epoll-wait.c | 3 +- tools/perf/bench/futex-hash.c | 3 +- tools/perf/bench/futex-lock-pi.c | 3 +- tools/perf/bench/futex-requeue.c | 3 +- tools/perf/bench/futex-wake-parallel.c | 2 +- tools/perf/bench/futex-wake.c | 3 +- tools/perf/builtin-ftrace.c | 2 +- tools/perf/builtin-sched.c | 4 +- tools/perf/lib/cpumap.c | 184 +++++++++++++++++++++++++++ tools/perf/lib/include/internal/cpumap.h | 4 + tools/perf/lib/include/perf/cpumap.h | 3 + tools/perf/lib/libperf.map | 2 + tools/perf/tests/bitmap.c | 3 +- tools/perf/tests/code-reading.c | 5 +- tools/perf/tests/cpumap.c | 7 +- tools/perf/tests/event-times.c | 9 +- tools/perf/tests/event_update.c | 3 +- tools/perf/tests/keep-tracking.c | 3 +- tools/perf/tests/mem2node.c | 3 +- tools/perf/tests/mmap-basic.c | 3 +- tools/perf/tests/openat-syscall-all-cpus.c | 2 +- tools/perf/tests/switch-tracking.c | 5 +- tools/perf/tests/topology.c | 3 +- tools/perf/util/cpumap.c | 181 +------------------------- tools/perf/util/cpumap.h | 2 - tools/perf/util/cputopo.c | 5 +- tools/perf/util/evlist.c | 5 +- tools/perf/util/header.c | 3 +- tools/perf/util/parse-events.c | 3 +- tools/perf/util/pmu.c | 3 +- tools/perf/util/python.c | 3 +- tools/perf/util/record.c | 7 +- tools/perf/util/session.c | 3 +- tools/perf/util/svghelper.c | 3 +- 37 files changed, 265 insertions(+), 227 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index f5aafdec7f50..c25bc1528b96 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -156,7 +156,7 @@ static int cs_etm_set_option(struct auxtrace_record *itr, { int i, err = -EINVAL; struct perf_cpu_map *event_cpus = evsel->evlist->cpus; - struct perf_cpu_map *online_cpus = cpu_map__new(NULL); + struct perf_cpu_map *online_cpus = perf_cpu_map__new(NULL); /* Set option of each CPU we have */ for (i = 0; i < cpu__max_cpu(); i++) { @@ -490,7 +490,7 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused, int i; int etmv3 = 0, etmv4 = 0; struct perf_cpu_map *event_cpus = evlist->cpus; - struct perf_cpu_map *online_cpus = cpu_map__new(NULL); + struct perf_cpu_map *online_cpus = perf_cpu_map__new(NULL); /* cpu map is not empty, we have specific CPUs to work with */ if (!cpu_map__empty(event_cpus)) { @@ -637,7 +637,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr, u64 nr_cpu, type; struct perf_cpu_map *cpu_map; struct perf_cpu_map *event_cpus = session->evlist->cpus; - struct perf_cpu_map *online_cpus = cpu_map__new(NULL); + struct perf_cpu_map *online_cpus = perf_cpu_map__new(NULL); struct cs_etm_recording *ptr = container_of(itr, struct cs_etm_recording, itr); struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu; diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index 07129e007eb0..261bdd680651 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "parse-events.h" #include "evlist.h" @@ -65,7 +66,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe threads = thread_map__new(-1, getpid(), UINT_MAX); CHECK_NOT_NULL__(threads); - cpus = cpu_map__new(NULL); + cpus = perf_cpu_map__new(NULL); CHECK_NOT_NULL__(cpus); evlist = evlist__new(); diff --git a/tools/perf/bench/epoll-ctl.c b/tools/perf/bench/epoll-ctl.c index 1fd724f1d48b..84658d45f349 100644 --- a/tools/perf/bench/epoll-ctl.c +++ b/tools/perf/bench/epoll-ctl.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "../util/stat.h" #include @@ -315,7 +316,7 @@ int bench_epoll_ctl(int argc, const char **argv) act.sa_sigaction = toggle_done; sigaction(SIGINT, &act, NULL); - cpu = cpu_map__new(NULL); + cpu = perf_cpu_map__new(NULL); if (!cpu) goto errmem; diff --git a/tools/perf/bench/epoll-wait.c b/tools/perf/bench/epoll-wait.c index 79a254fff2d1..c27a65639cfb 100644 --- a/tools/perf/bench/epoll-wait.c +++ b/tools/perf/bench/epoll-wait.c @@ -75,6 +75,7 @@ #include #include #include +#include #include "../util/stat.h" #include @@ -429,7 +430,7 @@ int bench_epoll_wait(int argc, const char **argv) act.sa_sigaction = toggle_done; sigaction(SIGINT, &act, NULL); - cpu = cpu_map__new(NULL); + cpu = perf_cpu_map__new(NULL); if (!cpu) goto errmem; diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c index b4fea8e3a368..80e138904c66 100644 --- a/tools/perf/bench/futex-hash.c +++ b/tools/perf/bench/futex-hash.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "../util/stat.h" #include @@ -132,7 +133,7 @@ int bench_futex_hash(int argc, const char **argv) exit(EXIT_FAILURE); } - cpu = cpu_map__new(NULL); + cpu = perf_cpu_map__new(NULL); if (!cpu) goto errmem; diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c index 596769924709..c5d6d0abbaa9 100644 --- a/tools/perf/bench/futex-lock-pi.c +++ b/tools/perf/bench/futex-lock-pi.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "bench.h" #include "futex.h" #include "cpumap.h" @@ -156,7 +157,7 @@ int bench_futex_lock_pi(int argc, const char **argv) if (argc) goto err; - cpu = cpu_map__new(NULL); + cpu = perf_cpu_map__new(NULL); if (!cpu) err(EXIT_FAILURE, "calloc"); diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index 1fd32a4f9c14..75d3418c1a88 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "bench.h" #include "futex.h" #include "cpumap.h" @@ -123,7 +124,7 @@ int bench_futex_requeue(int argc, const char **argv) if (argc) goto err; - cpu = cpu_map__new(NULL); + cpu = perf_cpu_map__new(NULL); if (!cpu) err(EXIT_FAILURE, "cpu_map__new"); diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c index 884c73e5bd1b..163fe16c275a 100644 --- a/tools/perf/bench/futex-wake-parallel.c +++ b/tools/perf/bench/futex-wake-parallel.c @@ -237,7 +237,7 @@ int bench_futex_wake_parallel(int argc, const char **argv) act.sa_sigaction = toggle_done; sigaction(SIGINT, &act, NULL); - cpu = cpu_map__new(NULL); + cpu = perf_cpu_map__new(NULL); if (!cpu) err(EXIT_FAILURE, "calloc"); diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c index 2288fa8412ff..77dcdc13618a 100644 --- a/tools/perf/bench/futex-wake.c +++ b/tools/perf/bench/futex-wake.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "bench.h" #include "futex.h" #include "cpumap.h" @@ -131,7 +132,7 @@ int bench_futex_wake(int argc, const char **argv) exit(EXIT_FAILURE); } - cpu = cpu_map__new(NULL); + cpu = perf_cpu_map__new(NULL); if (!cpu) err(EXIT_FAILURE, "calloc"); diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 6943352b8d94..77989254fdd8 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -202,7 +202,7 @@ static int set_tracing_cpu(struct perf_ftrace *ftrace) static int reset_tracing_cpu(void) { - struct perf_cpu_map *cpumap = cpu_map__new(NULL); + struct perf_cpu_map *cpumap = perf_cpu_map__new(NULL); int ret; ret = set_tracing_cpumask(cpumap); diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 897d11c8ca2e..0d6b4c3b1a51 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -3183,7 +3183,7 @@ static int setup_map_cpus(struct perf_sched *sched) if (!sched->map.cpus_str) return 0; - map = cpu_map__new(sched->map.cpus_str); + map = perf_cpu_map__new(sched->map.cpus_str); if (!map) { pr_err("failed to get cpus map from %s\n", sched->map.cpus_str); return -1; @@ -3217,7 +3217,7 @@ static int setup_color_cpus(struct perf_sched *sched) if (!sched->map.color_cpus_str) return 0; - map = cpu_map__new(sched->map.color_cpus_str); + map = perf_cpu_map__new(sched->map.color_cpus_str); if (!map) { pr_err("failed to get thread map from %s\n", sched->map.color_cpus_str); return -1; diff --git a/tools/perf/lib/cpumap.c b/tools/perf/lib/cpumap.c index f3cfb4c71106..a5d4f7ff7174 100644 --- a/tools/perf/lib/cpumap.c +++ b/tools/perf/lib/cpumap.c @@ -5,6 +5,10 @@ #include #include #include +#include +#include +#include +#include struct perf_cpu_map *perf_cpu_map__dummy_new(void) { @@ -40,3 +44,183 @@ void perf_cpu_map__put(struct perf_cpu_map *map) if (map && refcount_dec_and_test(&map->refcnt)) cpu_map__delete(map); } + +static struct perf_cpu_map *cpu_map__default_new(void) +{ + struct perf_cpu_map *cpus; + int nr_cpus; + + nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); + if (nr_cpus < 0) + return NULL; + + cpus = malloc(sizeof(*cpus) + nr_cpus * sizeof(int)); + if (cpus != NULL) { + int i; + + for (i = 0; i < nr_cpus; ++i) + cpus->map[i] = i; + + cpus->nr = nr_cpus; + refcount_set(&cpus->refcnt, 1); + } + + return cpus; +} + +static struct perf_cpu_map *cpu_map__trim_new(int nr_cpus, int *tmp_cpus) +{ + size_t payload_size = nr_cpus * sizeof(int); + struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + payload_size); + + if (cpus != NULL) { + cpus->nr = nr_cpus; + memcpy(cpus->map, tmp_cpus, payload_size); + refcount_set(&cpus->refcnt, 1); + } + + return cpus; +} + +struct perf_cpu_map *perf_cpu_map__read(FILE *file) +{ + struct perf_cpu_map *cpus = NULL; + int nr_cpus = 0; + int *tmp_cpus = NULL, *tmp; + int max_entries = 0; + int n, cpu, prev; + char sep; + + sep = 0; + prev = -1; + for (;;) { + n = fscanf(file, "%u%c", &cpu, &sep); + if (n <= 0) + break; + if (prev >= 0) { + int new_max = nr_cpus + cpu - prev - 1; + + if (new_max >= max_entries) { + max_entries = new_max + MAX_NR_CPUS / 2; + tmp = realloc(tmp_cpus, max_entries * sizeof(int)); + if (tmp == NULL) + goto out_free_tmp; + tmp_cpus = tmp; + } + + while (++prev < cpu) + tmp_cpus[nr_cpus++] = prev; + } + if (nr_cpus == max_entries) { + max_entries += MAX_NR_CPUS; + tmp = realloc(tmp_cpus, max_entries * sizeof(int)); + if (tmp == NULL) + goto out_free_tmp; + tmp_cpus = tmp; + } + + tmp_cpus[nr_cpus++] = cpu; + if (n == 2 && sep == '-') + prev = cpu; + else + prev = -1; + if (n == 1 || sep == '\n') + break; + } + + if (nr_cpus > 0) + cpus = cpu_map__trim_new(nr_cpus, tmp_cpus); + else + cpus = cpu_map__default_new(); +out_free_tmp: + free(tmp_cpus); + return cpus; +} + +static struct perf_cpu_map *cpu_map__read_all_cpu_map(void) +{ + struct perf_cpu_map *cpus = NULL; + FILE *onlnf; + + onlnf = fopen("/sys/devices/system/cpu/online", "r"); + if (!onlnf) + return cpu_map__default_new(); + + cpus = perf_cpu_map__read(onlnf); + fclose(onlnf); + return cpus; +} + +struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list) +{ + struct perf_cpu_map *cpus = NULL; + unsigned long start_cpu, end_cpu = 0; + char *p = NULL; + int i, nr_cpus = 0; + int *tmp_cpus = NULL, *tmp; + int max_entries = 0; + + if (!cpu_list) + return cpu_map__read_all_cpu_map(); + + /* + * must handle the case of empty cpumap to cover + * TOPOLOGY header for NUMA nodes with no CPU + * ( e.g., because of CPU hotplug) + */ + if (!isdigit(*cpu_list) && *cpu_list != '\0') + goto out; + + while (isdigit(*cpu_list)) { + p = NULL; + start_cpu = strtoul(cpu_list, &p, 0); + if (start_cpu >= INT_MAX + || (*p != '\0' && *p != ',' && *p != '-')) + goto invalid; + + if (*p == '-') { + cpu_list = ++p; + p = NULL; + end_cpu = strtoul(cpu_list, &p, 0); + + if (end_cpu >= INT_MAX || (*p != '\0' && *p != ',')) + goto invalid; + + if (end_cpu < start_cpu) + goto invalid; + } else { + end_cpu = start_cpu; + } + + for (; start_cpu <= end_cpu; start_cpu++) { + /* check for duplicates */ + for (i = 0; i < nr_cpus; i++) + if (tmp_cpus[i] == (int)start_cpu) + goto invalid; + + if (nr_cpus == max_entries) { + max_entries += MAX_NR_CPUS; + tmp = realloc(tmp_cpus, max_entries * sizeof(int)); + if (tmp == NULL) + goto invalid; + tmp_cpus = tmp; + } + tmp_cpus[nr_cpus++] = (int)start_cpu; + } + if (*p) + ++p; + + cpu_list = p; + } + + if (nr_cpus > 0) + cpus = cpu_map__trim_new(nr_cpus, tmp_cpus); + else if (*cpu_list != '\0') + cpus = cpu_map__default_new(); + else + cpus = perf_cpu_map__dummy_new(); +invalid: + free(tmp_cpus); +out: + return cpus; +} diff --git a/tools/perf/lib/include/internal/cpumap.h b/tools/perf/lib/include/internal/cpumap.h index 53ce95374b05..3306319f7df8 100644 --- a/tools/perf/lib/include/internal/cpumap.h +++ b/tools/perf/lib/include/internal/cpumap.h @@ -10,4 +10,8 @@ struct perf_cpu_map { int map[]; }; +#ifndef MAX_NR_CPUS +#define MAX_NR_CPUS 2048 +#endif + #endif /* __LIBPERF_INTERNAL_CPUMAP_H */ diff --git a/tools/perf/lib/include/perf/cpumap.h b/tools/perf/lib/include/perf/cpumap.h index e16c2515a499..b4a9283a5dfa 100644 --- a/tools/perf/lib/include/perf/cpumap.h +++ b/tools/perf/lib/include/perf/cpumap.h @@ -3,10 +3,13 @@ #define __LIBPERF_CPUMAP_H #include +#include struct perf_cpu_map; LIBPERF_API struct perf_cpu_map *perf_cpu_map__dummy_new(void); +LIBPERF_API struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list); +LIBPERF_API struct perf_cpu_map *perf_cpu_map__read(FILE *file); LIBPERF_API struct perf_cpu_map *perf_cpu_map__get(struct perf_cpu_map *map); LIBPERF_API void perf_cpu_map__put(struct perf_cpu_map *map); diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 168339f89a2e..e38473a8f32f 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -4,6 +4,8 @@ LIBPERF_0.0.1 { perf_cpu_map__dummy_new; perf_cpu_map__get; perf_cpu_map__put; + perf_cpu_map__new; + perf_cpu_map__read; perf_thread_map__new_dummy; perf_thread_map__set_pid; perf_thread_map__comm; diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c index 95304d29092e..db2aadff3708 100644 --- a/tools/perf/tests/bitmap.c +++ b/tools/perf/tests/bitmap.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include "tests.h" #include "cpumap.h" #include "debug.h" @@ -9,7 +10,7 @@ static unsigned long *get_bitmap(const char *str, int nbits) { - struct perf_cpu_map *map = cpu_map__new(str); + struct perf_cpu_map *map = perf_cpu_map__new(str); unsigned long *bm = NULL; int i; diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 131bbeec62d2..bfaf22c2023c 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "parse-events.h" #include "evlist.h" @@ -613,9 +614,9 @@ static int do_test_code_reading(bool try_kcore) goto out_put; } - cpus = cpu_map__new(NULL); + cpus = perf_cpu_map__new(NULL); if (!cpus) { - pr_debug("cpu_map__new failed\n"); + pr_debug("perf_cpu_map__new failed\n"); goto out_put; } diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index 6c921087b0fe..b71fe09a8087 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -5,6 +5,7 @@ #include "event.h" #include #include +#include #include "debug.h" struct machine; @@ -78,7 +79,7 @@ int test__cpu_map_synthesize(struct test *test __maybe_unused, int subtest __may struct perf_cpu_map *cpus; /* This one is better stores in mask. */ - cpus = cpu_map__new("0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19"); + cpus = perf_cpu_map__new("0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19"); TEST_ASSERT_VAL("failed to synthesize map", !perf_event__synthesize_cpu_map(NULL, cpus, process_event_mask, NULL)); @@ -86,7 +87,7 @@ int test__cpu_map_synthesize(struct test *test __maybe_unused, int subtest __may perf_cpu_map__put(cpus); /* This one is better stores in cpu values. */ - cpus = cpu_map__new("1,256"); + cpus = perf_cpu_map__new("1,256"); TEST_ASSERT_VAL("failed to synthesize map", !perf_event__synthesize_cpu_map(NULL, cpus, process_event_cpus, NULL)); @@ -97,7 +98,7 @@ int test__cpu_map_synthesize(struct test *test __maybe_unused, int subtest __may static int cpu_map_print(const char *str) { - struct perf_cpu_map *map = cpu_map__new(str); + struct perf_cpu_map *map = perf_cpu_map__new(str); char buf[100]; if (!map) diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 165534f62036..00adba86403b 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "tests.h" #include "evlist.h" #include "evsel.h" @@ -115,9 +116,9 @@ static int attach__cpu_disabled(struct evlist *evlist) pr_debug("attaching to CPU 0 as enabled\n"); - cpus = cpu_map__new("0"); + cpus = perf_cpu_map__new("0"); if (cpus == NULL) { - pr_debug("failed to call cpu_map__new\n"); + pr_debug("failed to call perf_cpu_map__new\n"); return -1; } @@ -144,9 +145,9 @@ static int attach__cpu_enabled(struct evlist *evlist) pr_debug("attaching to CPU 0 as enabled\n"); - cpus = cpu_map__new("0"); + cpus = perf_cpu_map__new("0"); if (cpus == NULL) { - pr_debug("failed to call cpu_map__new\n"); + pr_debug("failed to call perf_cpu_map__new\n"); return -1; } diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index 415d12e96834..2bc5145284c0 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include "evlist.h" #include "evsel.h" #include "machine.h" @@ -108,7 +109,7 @@ int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unu TEST_ASSERT_VAL("failed to synthesize attr update name", !perf_event__synthesize_event_update_name(&tmp.tool, evsel, process_event_name)); - evsel->own_cpus = cpu_map__new("1,2,3"); + evsel->own_cpus = perf_cpu_map__new("1,2,3"); TEST_ASSERT_VAL("failed to synthesize attr update cpus", !perf_event__synthesize_event_update_cpus(&tmp.tool, evsel, process_event_cpus)); diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 4fc7b3b4e153..46478ba1ed16 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "parse-events.h" #include "evlist.h" @@ -75,7 +76,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un threads = thread_map__new(-1, getpid(), UINT_MAX); CHECK_NOT_NULL__(threads); - cpus = cpu_map__new(NULL); + cpus = perf_cpu_map__new(NULL); CHECK_NOT_NULL__(cpus); evlist = evlist__new(); diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c index 6fe2c1e7918b..5ec193f7968d 100644 --- a/tools/perf/tests/mem2node.c +++ b/tools/perf/tests/mem2node.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "cpumap.h" #include "mem2node.h" #include "tests.h" @@ -19,7 +20,7 @@ static struct node { static unsigned long *get_bitmap(const char *str, int nbits) { - struct perf_cpu_map *map = cpu_map__new(str); + struct perf_cpu_map *map = perf_cpu_map__new(str); unsigned long *bm = NULL; int i; diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 9d8eb43b12cb..aa792aebd7f0 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -3,6 +3,7 @@ #include /* For the CLR_() macros */ #include +#include #include "evlist.h" #include "evsel.h" @@ -46,7 +47,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse return -1; } - cpus = cpu_map__new(NULL); + cpus = perf_cpu_map__new(NULL); if (cpus == NULL) { pr_debug("cpu_map__new\n"); goto out_free_threads; diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index 674b0fa035ec..d161b1a78703 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -33,7 +33,7 @@ int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int return -1; } - cpus = cpu_map__new(NULL); + cpus = perf_cpu_map__new(NULL); if (cpus == NULL) { pr_debug("cpu_map__new\n"); goto out_thread_map_delete; diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index dd07acced4af..9e0bbea15005 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "parse-events.h" #include "evlist.h" @@ -341,9 +342,9 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ goto out_err; } - cpus = cpu_map__new(NULL); + cpus = perf_cpu_map__new(NULL); if (!cpus) { - pr_debug("cpu_map__new failed!\n"); + pr_debug("perf_cpu_map__new failed!\n"); goto out_err; } diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index 1b57ded58d59..a4f9f5182b47 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "tests.h" #include "util.h" #include "session.h" @@ -126,7 +127,7 @@ int test__session_topology(struct test *test __maybe_unused, int subtest __maybe if (session_write_header(path)) goto free_path; - map = cpu_map__new(NULL); + map = perf_cpu_map__new(NULL); if (map == NULL) { pr_debug("failed to get system cpumap\n"); goto free_path; diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 44082e5eabde..71d4d7b35a57 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -17,185 +17,6 @@ static int max_present_cpu_num; static int max_node_num; static int *cpunode_map; -static struct perf_cpu_map *cpu_map__default_new(void) -{ - struct perf_cpu_map *cpus; - int nr_cpus; - - nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); - if (nr_cpus < 0) - return NULL; - - cpus = malloc(sizeof(*cpus) + nr_cpus * sizeof(int)); - if (cpus != NULL) { - int i; - for (i = 0; i < nr_cpus; ++i) - cpus->map[i] = i; - - cpus->nr = nr_cpus; - refcount_set(&cpus->refcnt, 1); - } - - return cpus; -} - -static struct perf_cpu_map *cpu_map__trim_new(int nr_cpus, int *tmp_cpus) -{ - size_t payload_size = nr_cpus * sizeof(int); - struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + payload_size); - - if (cpus != NULL) { - cpus->nr = nr_cpus; - memcpy(cpus->map, tmp_cpus, payload_size); - refcount_set(&cpus->refcnt, 1); - } - - return cpus; -} - -struct perf_cpu_map *cpu_map__read(FILE *file) -{ - struct perf_cpu_map *cpus = NULL; - int nr_cpus = 0; - int *tmp_cpus = NULL, *tmp; - int max_entries = 0; - int n, cpu, prev; - char sep; - - sep = 0; - prev = -1; - for (;;) { - n = fscanf(file, "%u%c", &cpu, &sep); - if (n <= 0) - break; - if (prev >= 0) { - int new_max = nr_cpus + cpu - prev - 1; - - if (new_max >= max_entries) { - max_entries = new_max + MAX_NR_CPUS / 2; - tmp = realloc(tmp_cpus, max_entries * sizeof(int)); - if (tmp == NULL) - goto out_free_tmp; - tmp_cpus = tmp; - } - - while (++prev < cpu) - tmp_cpus[nr_cpus++] = prev; - } - if (nr_cpus == max_entries) { - max_entries += MAX_NR_CPUS; - tmp = realloc(tmp_cpus, max_entries * sizeof(int)); - if (tmp == NULL) - goto out_free_tmp; - tmp_cpus = tmp; - } - - tmp_cpus[nr_cpus++] = cpu; - if (n == 2 && sep == '-') - prev = cpu; - else - prev = -1; - if (n == 1 || sep == '\n') - break; - } - - if (nr_cpus > 0) - cpus = cpu_map__trim_new(nr_cpus, tmp_cpus); - else - cpus = cpu_map__default_new(); -out_free_tmp: - free(tmp_cpus); - return cpus; -} - -static struct perf_cpu_map *cpu_map__read_all_cpu_map(void) -{ - struct perf_cpu_map *cpus = NULL; - FILE *onlnf; - - onlnf = fopen("/sys/devices/system/cpu/online", "r"); - if (!onlnf) - return cpu_map__default_new(); - - cpus = cpu_map__read(onlnf); - fclose(onlnf); - return cpus; -} - -struct perf_cpu_map *cpu_map__new(const char *cpu_list) -{ - struct perf_cpu_map *cpus = NULL; - unsigned long start_cpu, end_cpu = 0; - char *p = NULL; - int i, nr_cpus = 0; - int *tmp_cpus = NULL, *tmp; - int max_entries = 0; - - if (!cpu_list) - return cpu_map__read_all_cpu_map(); - - /* - * must handle the case of empty cpumap to cover - * TOPOLOGY header for NUMA nodes with no CPU - * ( e.g., because of CPU hotplug) - */ - if (!isdigit(*cpu_list) && *cpu_list != '\0') - goto out; - - while (isdigit(*cpu_list)) { - p = NULL; - start_cpu = strtoul(cpu_list, &p, 0); - if (start_cpu >= INT_MAX - || (*p != '\0' && *p != ',' && *p != '-')) - goto invalid; - - if (*p == '-') { - cpu_list = ++p; - p = NULL; - end_cpu = strtoul(cpu_list, &p, 0); - - if (end_cpu >= INT_MAX || (*p != '\0' && *p != ',')) - goto invalid; - - if (end_cpu < start_cpu) - goto invalid; - } else { - end_cpu = start_cpu; - } - - for (; start_cpu <= end_cpu; start_cpu++) { - /* check for duplicates */ - for (i = 0; i < nr_cpus; i++) - if (tmp_cpus[i] == (int)start_cpu) - goto invalid; - - if (nr_cpus == max_entries) { - max_entries += MAX_NR_CPUS; - tmp = realloc(tmp_cpus, max_entries * sizeof(int)); - if (tmp == NULL) - goto invalid; - tmp_cpus = tmp; - } - tmp_cpus[nr_cpus++] = (int)start_cpu; - } - if (*p) - ++p; - - cpu_list = p; - } - - if (nr_cpus > 0) - cpus = cpu_map__trim_new(nr_cpus, tmp_cpus); - else if (*cpu_list != '\0') - cpus = cpu_map__default_new(); - else - cpus = perf_cpu_map__dummy_new(); -invalid: - free(tmp_cpus); -out: - return cpus; -} - static struct perf_cpu_map *cpu_map__from_entries(struct cpu_map_entries *cpus) { struct perf_cpu_map *map; @@ -751,7 +572,7 @@ const struct perf_cpu_map *cpu_map__online(void) /* thread unsafe */ static const struct perf_cpu_map *online = NULL; if (!online) - online = cpu_map__new(NULL); /* from /sys/devices/system/cpu/online */ + online = perf_cpu_map__new(NULL); /* from /sys/devices/system/cpu/online */ return online; } diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index b7af2cb68c19..a3d27f4131be 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -11,10 +11,8 @@ #include "perf.h" #include "util/debug.h" -struct perf_cpu_map *cpu_map__new(const char *cpu_list); struct perf_cpu_map *cpu_map__empty_new(int nr); struct perf_cpu_map *cpu_map__new_data(struct cpu_map_data *data); -struct perf_cpu_map *cpu_map__read(FILE *file); size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size); size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size); size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp); diff --git a/tools/perf/util/cputopo.c b/tools/perf/util/cputopo.c index 0cd99c460cd4..4f70155eaf83 100644 --- a/tools/perf/util/cputopo.c +++ b/tools/perf/util/cputopo.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "cputopo.h" #include "cpumap.h" @@ -182,7 +183,7 @@ struct cpu_topology *cpu_topology__new(void) ncpus = cpu__max_present_cpu(); /* build online CPU map */ - map = cpu_map__new(NULL); + map = perf_cpu_map__new(NULL); if (map == NULL) { pr_debug("failed to get system cpumap\n"); return NULL; @@ -312,7 +313,7 @@ struct numa_topology *numa_topology__new(void) if (c) *c = '\0'; - node_map = cpu_map__new(buf); + node_map = perf_cpu_map__new(buf); if (!node_map) goto out; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index ae75777a0ba4..67c67e9a38cd 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -34,6 +34,7 @@ #include #include #include +#include #ifdef LACKS_SIGQUEUE_PROTOTYPE int sigqueue(pid_t pid, int sig, const union sigval value); @@ -1089,7 +1090,7 @@ int perf_evlist__create_maps(struct evlist *evlist, struct target *target) if (target__uses_dummy_map(target)) cpus = perf_cpu_map__dummy_new(); else - cpus = cpu_map__new(target->cpu_list); + cpus = perf_cpu_map__new(target->cpu_list); if (!cpus) goto out_delete_threads; @@ -1372,7 +1373,7 @@ static int perf_evlist__create_syswide_maps(struct evlist *evlist) * error, and we may not want to do that fallback to a * default cpu identity map :-\ */ - cpus = cpu_map__new(NULL); + cpus = perf_cpu_map__new(NULL); if (!cpus) goto out; diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index d81afe56392c..fa914ba8cd56 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "evlist.h" #include "evsel.h" @@ -2348,7 +2349,7 @@ static int process_numa_topology(struct feat_fd *ff, void *data __maybe_unused) if (!str) goto error; - n->map = cpu_map__new(str); + n->map = perf_cpu_map__new(str); if (!n->map) goto error; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index ec7ce18b999a..db2460d6b625 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -24,6 +24,7 @@ #include "bpf-loader.h" #include "debug.h" #include +#include #include "parse-events-bison.h" #define YY_EXTRA_TYPE int #include "parse-events-flex.h" @@ -323,7 +324,7 @@ __add_event(struct list_head *list, int *idx, { struct evsel *evsel; struct perf_cpu_map *cpus = pmu ? pmu->cpus : - cpu_list ? cpu_map__new(cpu_list) : NULL; + cpu_list ? perf_cpu_map__new(cpu_list) : NULL; event_attr_init(attr); diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index d355f9506a1c..b7da21a7d627 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "pmu.h" #include "parse-events.h" #include "cpumap.h" @@ -581,7 +582,7 @@ static struct perf_cpu_map *__pmu_cpumask(const char *path) if (!file) return NULL; - cpus = cpu_map__read(file); + cpus = perf_cpu_map__read(file); fclose(file); return cpus; } diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 23a4fa13b92d..75ecc32a4427 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "evlist.h" #include "callchain.h" #include "evsel.h" @@ -549,7 +550,7 @@ static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus, kwlist, &cpustr)) return -1; - pcpus->cpus = cpu_map__new(cpustr); + pcpus->cpus = perf_cpu_map__new(cpustr); if (pcpus->cpus == NULL) return -1; return 0; diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 445788819969..03dcdb3f33a7 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "util.h" #include "cloexec.h" @@ -63,7 +64,7 @@ static bool perf_probe_api(setup_probe_fn_t fn) struct perf_cpu_map *cpus; int cpu, ret, i = 0; - cpus = cpu_map__new(NULL); + cpus = perf_cpu_map__new(NULL); if (!cpus) return false; cpu = cpus->map[0]; @@ -118,7 +119,7 @@ bool perf_can_record_cpu_wide(void) struct perf_cpu_map *cpus; int cpu, fd; - cpus = cpu_map__new(NULL); + cpus = perf_cpu_map__new(NULL); if (!cpus) return false; cpu = cpus->map[0]; @@ -275,7 +276,7 @@ bool perf_evlist__can_select_event(struct evlist *evlist, const char *str) evsel = perf_evlist__last(temp_evlist); if (!evlist || cpu_map__empty(evlist->cpus)) { - struct perf_cpu_map *cpus = cpu_map__new(NULL); + struct perf_cpu_map *cpus = perf_cpu_map__new(NULL); cpu = cpus ? cpus->map[0] : 0; perf_cpu_map__put(cpus); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 1f3dc7a8cee6..11e6093c941b 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "evlist.h" #include "evsel.h" @@ -2289,7 +2290,7 @@ int perf_session__cpu_bitmap(struct perf_session *session, } } - map = cpu_map__new(cpu_list); + map = perf_cpu_map__new(cpu_list); if (map == NULL) { pr_err("Invalid cpu_list\n"); return -1; diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index a9ca5c4fffee..ae6a534a7a80 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "perf.h" #include "svghelper.h" @@ -731,7 +732,7 @@ static int str_to_bitmap(char *s, cpumask_t *b) struct perf_cpu_map *m; int c; - m = cpu_map__new(s); + m = perf_cpu_map__new(s); if (!m) return -1; -- cgit v1.2.3-59-g8ed1b From 93bce7e5bfcd570e9250c974b5c2c91d6b8332ef Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:31 +0200 Subject: libperf: Move zalloc.o into libperf We need it in both perf and libperf, thus moving it to libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-45-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/Build | 5 +++++ tools/perf/util/Build | 5 ----- tools/perf/util/python-ext-sources | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/Build b/tools/perf/lib/Build index b27c1543b046..faf64db13e37 100644 --- a/tools/perf/lib/Build +++ b/tools/perf/lib/Build @@ -3,3 +3,8 @@ libperf-y += cpumap.o libperf-y += threadmap.o libperf-y += evsel.o libperf-y += evlist.o +libperf-y += zalloc.o + +$(OUTPUT)zalloc.o: ../../lib/zalloc.c FORCE + $(call rule_mkdir) + $(call if_changed_dep,cc_o_c) diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 14f812bb07a7..08f670d21615 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -26,7 +26,6 @@ perf-y += rbtree.o perf-y += libstring.o perf-y += bitmap.o perf-y += hweight.o -perf-y += zalloc.o perf-y += smt.o perf-y += strbuf.o perf-y += string.o @@ -243,7 +242,3 @@ $(OUTPUT)util/hweight.o: ../lib/hweight.c FORCE $(OUTPUT)util/vsprintf.o: ../lib/vsprintf.c FORCE $(call rule_mkdir) $(call if_changed_dep,cc_o_c) - -$(OUTPUT)util/zalloc.o: ../lib/zalloc.c FORCE - $(call rule_mkdir) - $(call if_changed_dep,cc_o_c) diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index ceb8afdf9a89..2237bac9fadb 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources @@ -18,7 +18,6 @@ util/namespaces.c ../lib/hweight.c ../lib/string.c ../lib/vsprintf.c -../lib/zalloc.c util/thread_map.c util/util.c util/xyarray.c -- cgit v1.2.3-59-g8ed1b From 634912d61ccc6bfeebb87716c276fbea20f63bdc Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:32 +0200 Subject: libperf: Add perf_evlist__new() function Add perf_evlist__new() function to create and init a perf_evlist struct dynamicaly. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-46-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evlist.c | 11 +++++++++++ tools/perf/lib/include/perf/evlist.h | 1 + tools/perf/lib/libperf.map | 1 + 3 files changed, 13 insertions(+) (limited to 'tools') diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c index 1b27fd2de9b9..0517deb4cb1c 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/perf/lib/evlist.c @@ -3,6 +3,7 @@ #include #include #include +#include void perf_evlist__init(struct perf_evlist *evlist) { @@ -23,3 +24,13 @@ void perf_evlist__remove(struct perf_evlist *evlist, list_del_init(&evsel->node); evlist->nr_entries -= 1; } + +struct perf_evlist *perf_evlist__new(void) +{ + struct perf_evlist *evlist = zalloc(sizeof(*evlist)); + + if (evlist != NULL) + perf_evlist__init(evlist); + + return evlist; +} diff --git a/tools/perf/lib/include/perf/evlist.h b/tools/perf/lib/include/perf/evlist.h index e0c87995c6ff..7255a60869a1 100644 --- a/tools/perf/lib/include/perf/evlist.h +++ b/tools/perf/lib/include/perf/evlist.h @@ -12,5 +12,6 @@ LIBPERF_API void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *evsel); LIBPERF_API void perf_evlist__remove(struct perf_evlist *evlist, struct perf_evsel *evsel); +LIBPERF_API struct perf_evlist *perf_evlist__new(void); #endif /* __LIBPERF_EVLIST_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index e38473a8f32f..5e685d6c7a95 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -12,6 +12,7 @@ LIBPERF_0.0.1 { perf_thread_map__get; perf_thread_map__put; perf_evsel__init; + perf_evlist__new; perf_evlist__init; perf_evlist__add; perf_evlist__remove; -- cgit v1.2.3-59-g8ed1b From 63bd5dfa69658c459d08a6ee6bfebbd4a91cf24d Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:33 +0200 Subject: libperf: Add perf_evsel__new() function Add a perf_evsel__new() function to create and init a perf_evsel struct dynamicaly. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-47-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evsel.c | 11 +++++++++++ tools/perf/lib/include/perf/evsel.h | 1 + tools/perf/lib/libperf.map | 1 + 3 files changed, 13 insertions(+) (limited to 'tools') diff --git a/tools/perf/lib/evsel.c b/tools/perf/lib/evsel.c index 17cba35becc7..8e91738c5c38 100644 --- a/tools/perf/lib/evsel.c +++ b/tools/perf/lib/evsel.c @@ -2,9 +2,20 @@ #include #include #include +#include void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr) { INIT_LIST_HEAD(&evsel->node); evsel->attr = *attr; } + +struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr) +{ + struct perf_evsel *evsel = zalloc(sizeof(*evsel)); + + if (evsel != NULL) + perf_evsel__init(evsel, attr); + + return evsel; +} diff --git a/tools/perf/lib/include/perf/evsel.h b/tools/perf/lib/include/perf/evsel.h index 295583b89f46..21b66fc1937f 100644 --- a/tools/perf/lib/include/perf/evsel.h +++ b/tools/perf/lib/include/perf/evsel.h @@ -9,5 +9,6 @@ struct perf_event_attr; LIBPERF_API void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr); +LIBPERF_API struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr); #endif /* __LIBPERF_EVSEL_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 5e685d6c7a95..e3eac9b60726 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -11,6 +11,7 @@ LIBPERF_0.0.1 { perf_thread_map__comm; perf_thread_map__get; perf_thread_map__put; + perf_evsel__new; perf_evsel__init; perf_evlist__new; perf_evlist__init; -- cgit v1.2.3-59-g8ed1b From 651bf38ce10a65ef8efb901fc33187127c023e97 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:34 +0200 Subject: libperf: Add perf_evlist__for_each_evsel() iterator Add a perf_evlist__for_each_evsel() macro to iterate perf_evsel objects in evlist. Introduce the perf_evlist__next() function to do that without exposing 'struct perf_evlist' internals. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-48-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evlist.c | 20 ++++++++++++++++++++ tools/perf/lib/include/perf/evlist.h | 7 +++++++ tools/perf/lib/libperf.map | 1 + 3 files changed, 28 insertions(+) (limited to 'tools') diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c index 0517deb4cb1c..979ee423490f 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/perf/lib/evlist.c @@ -34,3 +34,23 @@ struct perf_evlist *perf_evlist__new(void) return evlist; } + +struct perf_evsel * +perf_evlist__next(struct perf_evlist *evlist, struct perf_evsel *prev) +{ + struct perf_evsel *next; + + if (!prev) { + next = list_first_entry(&evlist->entries, + struct perf_evsel, + node); + } else { + next = list_next_entry(prev, node); + } + + /* Empty list is noticed here so don't need checking on entry. */ + if (&next->node == &evlist->entries) + return NULL; + + return next; +} diff --git a/tools/perf/lib/include/perf/evlist.h b/tools/perf/lib/include/perf/evlist.h index 7255a60869a1..5092b622935b 100644 --- a/tools/perf/lib/include/perf/evlist.h +++ b/tools/perf/lib/include/perf/evlist.h @@ -13,5 +13,12 @@ LIBPERF_API void perf_evlist__add(struct perf_evlist *evlist, LIBPERF_API void perf_evlist__remove(struct perf_evlist *evlist, struct perf_evsel *evsel); LIBPERF_API struct perf_evlist *perf_evlist__new(void); +LIBPERF_API struct perf_evsel* perf_evlist__next(struct perf_evlist *evlist, + struct perf_evsel *evsel); + +#define perf_evlist__for_each_evsel(evlist, pos) \ + for ((pos) = perf_evlist__next((evlist), NULL); \ + (pos) != NULL; \ + (pos) = perf_evlist__next((evlist), (pos))) #endif /* __LIBPERF_EVLIST_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index e3eac9b60726..c0968226f7b6 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -17,6 +17,7 @@ LIBPERF_0.0.1 { perf_evlist__init; perf_evlist__add; perf_evlist__remove; + perf_evlist__next; local: *; }; -- cgit v1.2.3-59-g8ed1b From 57f0c3b6e13ae822ba02dd37563c8e6956a47141 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:35 +0200 Subject: libperf: Add perf_evlist__delete() function Add the perf_evlist__delete() function to delete a perf_evlist instance. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-49-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evlist.c | 6 ++++++ tools/perf/lib/include/perf/evlist.h | 1 + tools/perf/lib/libperf.map | 1 + 3 files changed, 8 insertions(+) (limited to 'tools') diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c index 979ee423490f..087ef76ea8fd 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/perf/lib/evlist.c @@ -4,6 +4,7 @@ #include #include #include +#include void perf_evlist__init(struct perf_evlist *evlist) { @@ -54,3 +55,8 @@ perf_evlist__next(struct perf_evlist *evlist, struct perf_evsel *prev) return next; } + +void perf_evlist__delete(struct perf_evlist *evlist) +{ + free(evlist); +} diff --git a/tools/perf/lib/include/perf/evlist.h b/tools/perf/lib/include/perf/evlist.h index 5092b622935b..9a126fd0773c 100644 --- a/tools/perf/lib/include/perf/evlist.h +++ b/tools/perf/lib/include/perf/evlist.h @@ -13,6 +13,7 @@ LIBPERF_API void perf_evlist__add(struct perf_evlist *evlist, LIBPERF_API void perf_evlist__remove(struct perf_evlist *evlist, struct perf_evsel *evsel); LIBPERF_API struct perf_evlist *perf_evlist__new(void); +LIBPERF_API void perf_evlist__delete(struct perf_evlist *evlist); LIBPERF_API struct perf_evsel* perf_evlist__next(struct perf_evlist *evlist, struct perf_evsel *evsel); diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index c0968226f7b6..153e77cd6739 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -14,6 +14,7 @@ LIBPERF_0.0.1 { perf_evsel__new; perf_evsel__init; perf_evlist__new; + perf_evlist__delete; perf_evlist__init; perf_evlist__add; perf_evlist__remove; -- cgit v1.2.3-59-g8ed1b From b9358ee95ec65fe7e2c4dc12e4d3da4aeee0d8fc Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:36 +0200 Subject: libperf: Add perf_evsel__delete() function Add the perf_evsel__delete() function to delete a perf_evsel instance. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-50-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evsel.c | 6 ++++++ tools/perf/lib/include/perf/evsel.h | 1 + tools/perf/lib/libperf.map | 1 + 3 files changed, 8 insertions(+) (limited to 'tools') diff --git a/tools/perf/lib/evsel.c b/tools/perf/lib/evsel.c index 8e91738c5c38..ddc3ad447bfb 100644 --- a/tools/perf/lib/evsel.c +++ b/tools/perf/lib/evsel.c @@ -3,6 +3,7 @@ #include #include #include +#include void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr) { @@ -19,3 +20,8 @@ struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr) return evsel; } + +void perf_evsel__delete(struct perf_evsel *evsel) +{ + free(evsel); +} diff --git a/tools/perf/lib/include/perf/evsel.h b/tools/perf/lib/include/perf/evsel.h index 21b66fc1937f..a57efc0f5c8b 100644 --- a/tools/perf/lib/include/perf/evsel.h +++ b/tools/perf/lib/include/perf/evsel.h @@ -10,5 +10,6 @@ struct perf_event_attr; LIBPERF_API void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr); LIBPERF_API struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr); +LIBPERF_API void perf_evsel__delete(struct perf_evsel *evsel); #endif /* __LIBPERF_EVSEL_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 153e77cd6739..28ed04cbd223 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -12,6 +12,7 @@ LIBPERF_0.0.1 { perf_thread_map__get; perf_thread_map__put; perf_evsel__new; + perf_evsel__delete; perf_evsel__init; perf_evlist__new; perf_evlist__delete; -- cgit v1.2.3-59-g8ed1b From d400bd3abf2cc68df2df32047d3533faf690f404 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:37 +0200 Subject: libperf: Add cpus to struct perf_evsel Mov the 'cpus' field from tools/perf's evsel to libperf's perf_evsel. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-51-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-script.c | 2 +- tools/perf/lib/include/internal/evsel.h | 7 +++++-- tools/perf/util/evlist.c | 14 +++++++------- tools/perf/util/evsel.c | 4 ++-- tools/perf/util/evsel.h | 3 +-- tools/perf/util/parse-events.c | 2 +- tools/perf/util/scripting-engines/trace-event-python.c | 2 +- tools/perf/util/stat-display.c | 2 +- 9 files changed, 20 insertions(+), 18 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index b7d2c27c4164..090aaa2cf4b3 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -739,7 +739,7 @@ static int record__open(struct record *rec) evlist__for_each_entry(evlist, pos) { try_again: - if (evsel__open(pos, pos->cpus, pos->threads) < 0) { + if (evsel__open(pos, pos->core.cpus, pos->threads) < 0) { if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) { if (verbose > 0) ui__warning("%s\n", msg); diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 69133b35bbc1..35f07dde5ad4 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1920,7 +1920,7 @@ static void __process_stat(struct evsel *counter, u64 tstamp) counts = perf_counts(counter->counts, cpu, thread); printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n", - counter->cpus->map[cpu], + counter->core.cpus->map[cpu], thread_map__pid(counter->threads, thread), counts->val, counts->ena, diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h index c2e0bd104c94..b2c76e1a6244 100644 --- a/tools/perf/lib/include/internal/evsel.h +++ b/tools/perf/lib/include/internal/evsel.h @@ -5,9 +5,12 @@ #include #include +struct perf_cpu_map; + struct perf_evsel { - struct list_head node; - struct perf_event_attr attr; + struct list_head node; + struct perf_event_attr attr; + struct perf_cpu_map *cpus; }; #endif /* __LIBPERF_INTERNAL_EVSEL_H */ diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 67c67e9a38cd..713968130d1d 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -160,11 +160,11 @@ static void __perf_evlist__propagate_maps(struct evlist *evlist, * keep it, if there's no target cpu list defined. */ if (!evsel->own_cpus || evlist->has_user_cpus) { - perf_cpu_map__put(evsel->cpus); - evsel->cpus = perf_cpu_map__get(evlist->cpus); - } else if (evsel->cpus != evsel->own_cpus) { - perf_cpu_map__put(evsel->cpus); - evsel->cpus = perf_cpu_map__get(evsel->own_cpus); + perf_cpu_map__put(evsel->core.cpus); + evsel->core.cpus = perf_cpu_map__get(evlist->cpus); + } else if (evsel->core.cpus != evsel->own_cpus) { + perf_cpu_map__put(evsel->core.cpus); + evsel->core.cpus = perf_cpu_map__get(evsel->own_cpus); } perf_thread_map__put(evsel->threads); @@ -786,7 +786,7 @@ static int perf_evlist__mmap_per_evsel(struct evlist *evlist, int idx, if (evsel->system_wide && thread) continue; - cpu = cpu_map__idx(evsel->cpus, evlist_cpu); + cpu = cpu_map__idx(evsel->core.cpus, evlist_cpu); if (cpu == -1) continue; @@ -1407,7 +1407,7 @@ int evlist__open(struct evlist *evlist) perf_evlist__update_id_pos(evlist); evlist__for_each_entry(evlist, evsel) { - err = evsel__open(evsel, evsel->cpus, evsel->threads); + err = evsel__open(evsel, evsel->core.cpus, evsel->threads); if (err < 0) goto out_err; } diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 089582e644d7..651f66ee902e 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1325,7 +1325,7 @@ void perf_evsel__exit(struct evsel *evsel) perf_evsel__free_id(evsel); perf_evsel__free_config_terms(evsel); cgroup__put(evsel->cgrp); - perf_cpu_map__put(evsel->cpus); + perf_cpu_map__put(evsel->core.cpus); perf_cpu_map__put(evsel->own_cpus); perf_thread_map__put(evsel->threads); zfree(&evsel->group_name); @@ -3064,7 +3064,7 @@ static int store_evsel_ids(struct evsel *evsel, struct evlist *evlist) int perf_evsel__store_ids(struct evsel *evsel, struct evlist *evlist) { - struct perf_cpu_map *cpus = evsel->cpus; + struct perf_cpu_map *cpus = evsel->core.cpus; struct perf_thread_map *threads = evsel->threads; if (perf_evsel__alloc_id(evsel, cpus->nr, threads->nr)) diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 43f66158de3b..8ece5edf65ac 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -123,7 +123,6 @@ struct evsel { u64 db_id; struct cgroup *cgrp; void *handler; - struct perf_cpu_map *cpus; struct perf_cpu_map *own_cpus; struct perf_thread_map *threads; unsigned int sample_size; @@ -198,7 +197,7 @@ struct record_opts; static inline struct perf_cpu_map *evsel__cpus(struct evsel *evsel) { - return evsel->cpus; + return evsel->core.cpus; } static inline int perf_evsel__nr_cpus(struct evsel *evsel) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index db2460d6b625..a27771eca9c2 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -333,7 +333,7 @@ __add_event(struct list_head *list, int *idx, return NULL; (*idx)++; - evsel->cpus = perf_cpu_map__get(cpus); + evsel->core.cpus = perf_cpu_map__get(cpus); evsel->own_cpus = perf_cpu_map__get(cpus); evsel->system_wide = pmu ? pmu->is_uncore : false; evsel->auto_merge_stats = auto_merge_stats; diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 78b40c1d688e..c5f520e0885b 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -1393,7 +1393,7 @@ static void python_process_stat(struct perf_stat_config *config, struct evsel *counter, u64 tstamp) { struct perf_thread_map *threads = counter->threads; - struct perf_cpu_map *cpus = counter->cpus; + struct perf_cpu_map *cpus = counter->core.cpus; int cpu, thread; if (config->aggr_mode == AGGR_GLOBAL) { diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 99bda99a1b2d..e84f8063c2db 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -745,7 +745,7 @@ static void print_aggr_thread(struct perf_stat_config *config, { FILE *output = config->output; int nthreads = thread_map__nr(counter->threads); - int ncpus = cpu_map__nr(counter->cpus); + int ncpus = cpu_map__nr(counter->core.cpus); int thread, sorted_threads, id; struct perf_aggr_thread_value *buf; -- cgit v1.2.3-59-g8ed1b From fe1f61b37ffada9fc7ec2c9d4ca5376b5a797dbc Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:38 +0200 Subject: libperf: Add own_cpus to struct perf_evsel Move own_cpus from tools/perf's evsel to libbpf's perf_evsel. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-52-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/internal/evsel.h | 1 + tools/perf/tests/event_update.c | 4 ++-- tools/perf/util/evlist.c | 6 +++--- tools/perf/util/evsel.c | 4 ++-- tools/perf/util/evsel.h | 1 - tools/perf/util/header.c | 10 +++++----- tools/perf/util/parse-events.c | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h index b2c76e1a6244..d15d8ccfa3dc 100644 --- a/tools/perf/lib/include/internal/evsel.h +++ b/tools/perf/lib/include/internal/evsel.h @@ -11,6 +11,7 @@ struct perf_evsel { struct list_head node; struct perf_event_attr attr; struct perf_cpu_map *cpus; + struct perf_cpu_map *own_cpus; }; #endif /* __LIBPERF_INTERNAL_EVSEL_H */ diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index 2bc5145284c0..c37ff49c07c7 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -109,11 +109,11 @@ int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unu TEST_ASSERT_VAL("failed to synthesize attr update name", !perf_event__synthesize_event_update_name(&tmp.tool, evsel, process_event_name)); - evsel->own_cpus = perf_cpu_map__new("1,2,3"); + evsel->core.own_cpus = perf_cpu_map__new("1,2,3"); TEST_ASSERT_VAL("failed to synthesize attr update cpus", !perf_event__synthesize_event_update_cpus(&tmp.tool, evsel, process_event_cpus)); - perf_cpu_map__put(evsel->own_cpus); + perf_cpu_map__put(evsel->core.own_cpus); return 0; } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 713968130d1d..d203305ac187 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -159,12 +159,12 @@ static void __perf_evlist__propagate_maps(struct evlist *evlist, * We already have cpus for evsel (via PMU sysfs) so * keep it, if there's no target cpu list defined. */ - if (!evsel->own_cpus || evlist->has_user_cpus) { + if (!evsel->core.own_cpus || evlist->has_user_cpus) { perf_cpu_map__put(evsel->core.cpus); evsel->core.cpus = perf_cpu_map__get(evlist->cpus); - } else if (evsel->core.cpus != evsel->own_cpus) { + } else if (evsel->core.cpus != evsel->core.own_cpus) { perf_cpu_map__put(evsel->core.cpus); - evsel->core.cpus = perf_cpu_map__get(evsel->own_cpus); + evsel->core.cpus = perf_cpu_map__get(evsel->core.own_cpus); } perf_thread_map__put(evsel->threads); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 651f66ee902e..c5f6ee6d5f3b 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1125,7 +1125,7 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts, attr->exclude_user = 1; } - if (evsel->own_cpus || evsel->unit) + if (evsel->core.own_cpus || evsel->unit) evsel->core.attr.read_format |= PERF_FORMAT_ID; /* @@ -1326,7 +1326,7 @@ void perf_evsel__exit(struct evsel *evsel) perf_evsel__free_config_terms(evsel); cgroup__put(evsel->cgrp); perf_cpu_map__put(evsel->core.cpus); - perf_cpu_map__put(evsel->own_cpus); + perf_cpu_map__put(evsel->core.own_cpus); perf_thread_map__put(evsel->threads); zfree(&evsel->group_name); zfree(&evsel->name); diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 8ece5edf65ac..2eff837f10bd 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -123,7 +123,6 @@ struct evsel { u64 db_id; struct cgroup *cgrp; void *handler; - struct perf_cpu_map *own_cpus; struct perf_thread_map *threads; unsigned int sample_size; int id_pos; diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index fa914ba8cd56..f97df418d661 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -3861,10 +3861,10 @@ perf_event__synthesize_event_update_cpus(struct perf_tool *tool, int max, err; u16 type; - if (!evsel->own_cpus) + if (!evsel->core.own_cpus) return 0; - ev = cpu_map_data__alloc(evsel->own_cpus, &size, &type, &max); + ev = cpu_map_data__alloc(evsel->core.own_cpus, &size, &type, &max); if (!ev) return -ENOMEM; @@ -3874,7 +3874,7 @@ perf_event__synthesize_event_update_cpus(struct perf_tool *tool, ev->id = evsel->id[0]; cpu_map_data__synthesize((struct cpu_map_data *) ev->data, - evsel->own_cpus, + evsel->core.own_cpus, type, max); err = process(tool, (union perf_event*) ev, NULL, NULL); @@ -3985,7 +3985,7 @@ int perf_event__synthesize_extra_attr(struct perf_tool *tool, } } - if (counter->own_cpus) { + if (counter->core.own_cpus) { err = perf_event__synthesize_event_update_cpus(tool, counter, process); if (err < 0) { pr_err("Couldn't synthesize evsel cpus.\n"); @@ -4082,7 +4082,7 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused, map = cpu_map__new_data(&ev_cpus->cpus); if (map) - evsel->own_cpus = map; + evsel->core.own_cpus = map; else pr_err("failed to get event_update cpus\n"); default: diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index a27771eca9c2..8182b1e66ec6 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -334,7 +334,7 @@ __add_event(struct list_head *list, int *idx, (*idx)++; evsel->core.cpus = perf_cpu_map__get(cpus); - evsel->own_cpus = perf_cpu_map__get(cpus); + evsel->core.own_cpus = perf_cpu_map__get(cpus); evsel->system_wide = pmu ? pmu->is_uncore : false; evsel->auto_merge_stats = auto_merge_stats; -- cgit v1.2.3-59-g8ed1b From af663bd01beaff8d9514199fcc1b239902a77de5 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:39 +0200 Subject: libperf: Add threads to struct perf_evsel Move 'threads' from tools/perf's evsel to libperf's perf_evsel struct. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-53-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-script.c | 4 ++-- tools/perf/lib/include/internal/evsel.h | 2 ++ tools/perf/util/evlist.c | 6 +++--- tools/perf/util/evsel.c | 4 ++-- tools/perf/util/evsel.h | 1 - tools/perf/util/scripting-engines/trace-event-python.c | 2 +- tools/perf/util/stat-display.c | 6 +++--- tools/perf/util/stat.c | 6 +++--- 9 files changed, 17 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 090aaa2cf4b3..27ff899bed88 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -739,7 +739,7 @@ static int record__open(struct record *rec) evlist__for_each_entry(evlist, pos) { try_again: - if (evsel__open(pos, pos->core.cpus, pos->threads) < 0) { + if (evsel__open(pos, pos->core.cpus, pos->core.threads) < 0) { if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) { if (verbose > 0) ui__warning("%s\n", msg); diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 35f07dde5ad4..a787c5cb1331 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1899,7 +1899,7 @@ static struct scripting_ops *scripting_ops; static void __process_stat(struct evsel *counter, u64 tstamp) { - int nthreads = thread_map__nr(counter->threads); + int nthreads = thread_map__nr(counter->core.threads); int ncpus = perf_evsel__nr_cpus(counter); int cpu, thread; static int header_printed; @@ -1921,7 +1921,7 @@ static void __process_stat(struct evsel *counter, u64 tstamp) printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n", counter->core.cpus->map[cpu], - thread_map__pid(counter->threads, thread), + thread_map__pid(counter->core.threads, thread), counts->val, counts->ena, counts->run, diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h index d15d8ccfa3dc..8340fd883a3d 100644 --- a/tools/perf/lib/include/internal/evsel.h +++ b/tools/perf/lib/include/internal/evsel.h @@ -6,12 +6,14 @@ #include struct perf_cpu_map; +struct perf_thread_map; struct perf_evsel { struct list_head node; struct perf_event_attr attr; struct perf_cpu_map *cpus; struct perf_cpu_map *own_cpus; + struct perf_thread_map *threads; }; #endif /* __LIBPERF_INTERNAL_EVSEL_H */ diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index d203305ac187..5ce8fc730453 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -167,8 +167,8 @@ static void __perf_evlist__propagate_maps(struct evlist *evlist, evsel->core.cpus = perf_cpu_map__get(evsel->core.own_cpus); } - perf_thread_map__put(evsel->threads); - evsel->threads = perf_thread_map__get(evlist->threads); + perf_thread_map__put(evsel->core.threads); + evsel->core.threads = perf_thread_map__get(evlist->threads); } static void perf_evlist__propagate_maps(struct evlist *evlist) @@ -1407,7 +1407,7 @@ int evlist__open(struct evlist *evlist) perf_evlist__update_id_pos(evlist); evlist__for_each_entry(evlist, evsel) { - err = evsel__open(evsel, evsel->core.cpus, evsel->threads); + err = evsel__open(evsel, evsel->core.cpus, evsel->core.threads); if (err < 0) goto out_err; } diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index c5f6ee6d5f3b..f7758ce0dd5c 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1327,7 +1327,7 @@ void perf_evsel__exit(struct evsel *evsel) cgroup__put(evsel->cgrp); perf_cpu_map__put(evsel->core.cpus); perf_cpu_map__put(evsel->core.own_cpus); - perf_thread_map__put(evsel->threads); + perf_thread_map__put(evsel->core.threads); zfree(&evsel->group_name); zfree(&evsel->name); perf_evsel__object.fini(evsel); @@ -3065,7 +3065,7 @@ static int store_evsel_ids(struct evsel *evsel, struct evlist *evlist) int perf_evsel__store_ids(struct evsel *evsel, struct evlist *evlist) { struct perf_cpu_map *cpus = evsel->core.cpus; - struct perf_thread_map *threads = evsel->threads; + struct perf_thread_map *threads = evsel->core.threads; if (perf_evsel__alloc_id(evsel, cpus->nr, threads->nr)) return -ENOMEM; diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 2eff837f10bd..57b5523b480c 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -123,7 +123,6 @@ struct evsel { u64 db_id; struct cgroup *cgrp; void *handler; - struct perf_thread_map *threads; unsigned int sample_size; int id_pos; int is_pos; diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index c5f520e0885b..32c17a727450 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -1392,7 +1392,7 @@ process_stat(struct evsel *counter, int cpu, int thread, u64 tstamp, static void python_process_stat(struct perf_stat_config *config, struct evsel *counter, u64 tstamp) { - struct perf_thread_map *threads = counter->threads; + struct perf_thread_map *threads = counter->core.threads; struct perf_cpu_map *cpus = counter->core.cpus; int cpu, thread; diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index e84f8063c2db..7c938135398b 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -116,9 +116,9 @@ static void aggr_printout(struct perf_stat_config *config, case AGGR_THREAD: fprintf(config->output, "%*s-%*d%s", config->csv_output ? 0 : 16, - perf_thread_map__comm(evsel->threads, id), + perf_thread_map__comm(evsel->core.threads, id), config->csv_output ? 0 : -8, - thread_map__pid(evsel->threads, id), + thread_map__pid(evsel->core.threads, id), config->csv_sep); break; case AGGR_GLOBAL: @@ -744,7 +744,7 @@ static void print_aggr_thread(struct perf_stat_config *config, struct evsel *counter, char *prefix) { FILE *output = config->output; - int nthreads = thread_map__nr(counter->threads); + int nthreads = thread_map__nr(counter->core.threads); int ncpus = cpu_map__nr(counter->core.cpus); int thread, sorted_threads, id; struct perf_aggr_thread_value *buf; diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 632bf72cf780..1e351462ca49 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -158,7 +158,7 @@ static void perf_evsel__free_prev_raw_counts(struct evsel *evsel) static int perf_evsel__alloc_stats(struct evsel *evsel, bool alloc_raw) { int ncpus = perf_evsel__nr_cpus(evsel); - int nthreads = thread_map__nr(evsel->threads); + int nthreads = thread_map__nr(evsel->core.threads); if (perf_evsel__alloc_stat_priv(evsel) < 0 || perf_evsel__alloc_counts(evsel, ncpus, nthreads) < 0 || @@ -308,7 +308,7 @@ process_counter_values(struct perf_stat_config *config, struct evsel *evsel, static int process_counter_maps(struct perf_stat_config *config, struct evsel *counter) { - int nthreads = thread_map__nr(counter->threads); + int nthreads = thread_map__nr(counter->core.threads); int ncpus = perf_evsel__nr_cpus(counter); int cpu, thread; @@ -485,7 +485,7 @@ int create_perf_stat_counter(struct evsel *evsel, if (target__has_cpu(target) && !target__has_per_thread(target)) return perf_evsel__open_per_cpu(evsel, evsel__cpus(evsel)); - return perf_evsel__open_per_thread(evsel, evsel->threads); + return perf_evsel__open_per_thread(evsel, evsel->core.threads); } int perf_stat_synthesize_config(struct perf_stat_config *config, -- cgit v1.2.3-59-g8ed1b From ec903f264f0184a0aba62b42d7717c61f1893450 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:40 +0200 Subject: libperf: Add has_user_cpus to struct perf_evlist Move has_user_cpus from tools/perf's evlist to libbperf's perf_evlist struct. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-54-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/internal/evlist.h | 1 + tools/perf/util/evlist.c | 4 ++-- tools/perf/util/evlist.h | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h index a12c712a9197..9964e4a9456e 100644 --- a/tools/perf/lib/include/internal/evlist.h +++ b/tools/perf/lib/include/internal/evlist.h @@ -5,6 +5,7 @@ struct perf_evlist { struct list_head entries; int nr_entries; + bool has_user_cpus; }; #endif /* __LIBPERF_INTERNAL_EVLIST_H */ diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 5ce8fc730453..23a8ead4512f 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -159,7 +159,7 @@ static void __perf_evlist__propagate_maps(struct evlist *evlist, * We already have cpus for evsel (via PMU sysfs) so * keep it, if there's no target cpu list defined. */ - if (!evsel->core.own_cpus || evlist->has_user_cpus) { + if (!evsel->core.own_cpus || evlist->core.has_user_cpus) { perf_cpu_map__put(evsel->core.cpus); evsel->core.cpus = perf_cpu_map__get(evlist->cpus); } else if (evsel->core.cpus != evsel->core.own_cpus) { @@ -1095,7 +1095,7 @@ int perf_evlist__create_maps(struct evlist *evlist, struct target *target) if (!cpus) goto out_delete_threads; - evlist->has_user_cpus = !!target->cpu_list; + evlist->core.has_user_cpus = !!target->cpu_list; perf_evlist__set_maps(evlist, cpus, threads); diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 17dd83021a79..35cca0242631 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -31,7 +31,6 @@ struct evlist { int nr_groups; int nr_mmaps; bool enabled; - bool has_user_cpus; size_t mmap_len; int id_pos; int is_pos; -- cgit v1.2.3-59-g8ed1b From f72f901d90b00aaf2a6c1335b41311687b3f2dec Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:41 +0200 Subject: libperf: Add cpus to struct perf_evlist Move cpus from tools/perf's evlist to libperf's perf_evlist struct. Committer notes: Fixed up this one: tools/perf/arch/arm/util/cs-etm.c Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-55-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 8 +++---- tools/perf/arch/x86/util/intel-bts.c | 2 +- tools/perf/arch/x86/util/intel-pt.c | 4 ++-- tools/perf/builtin-ftrace.c | 2 +- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-stat.c | 16 +++++++------- tools/perf/builtin-top.c | 2 +- tools/perf/lib/include/internal/evlist.h | 9 +++++--- tools/perf/util/auxtrace.c | 2 +- tools/perf/util/evlist.c | 36 ++++++++++++++++---------------- tools/perf/util/evlist.h | 1 - tools/perf/util/record.c | 6 +++--- tools/perf/util/stat-display.c | 6 +++--- tools/perf/util/stat.c | 2 +- tools/perf/util/top.c | 6 +++--- 15 files changed, 53 insertions(+), 51 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index c25bc1528b96..5cb07e8cb296 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -155,7 +155,7 @@ static int cs_etm_set_option(struct auxtrace_record *itr, struct evsel *evsel, u32 option) { int i, err = -EINVAL; - struct perf_cpu_map *event_cpus = evsel->evlist->cpus; + struct perf_cpu_map *event_cpus = evsel->evlist->core.cpus; struct perf_cpu_map *online_cpus = perf_cpu_map__new(NULL); /* Set option of each CPU we have */ @@ -253,7 +253,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, container_of(itr, struct cs_etm_recording, itr); struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu; struct evsel *evsel, *cs_etm_evsel = NULL; - struct perf_cpu_map *cpus = evlist->cpus; + struct perf_cpu_map *cpus = evlist->core.cpus; bool privileged = (geteuid() == 0 || perf_event_paranoid() < 0); int err = 0; @@ -489,7 +489,7 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused, { int i; int etmv3 = 0, etmv4 = 0; - struct perf_cpu_map *event_cpus = evlist->cpus; + struct perf_cpu_map *event_cpus = evlist->core.cpus; struct perf_cpu_map *online_cpus = perf_cpu_map__new(NULL); /* cpu map is not empty, we have specific CPUs to work with */ @@ -636,7 +636,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr, u32 offset; u64 nr_cpu, type; struct perf_cpu_map *cpu_map; - struct perf_cpu_map *event_cpus = session->evlist->cpus; + struct perf_cpu_map *event_cpus = session->evlist->core.cpus; struct perf_cpu_map *online_cpus = perf_cpu_map__new(NULL); struct cs_etm_recording *ptr = container_of(itr, struct cs_etm_recording, itr); diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index d8a091266185..7b23318ebd7b 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -106,7 +106,7 @@ static int intel_bts_recording_options(struct auxtrace_record *itr, container_of(itr, struct intel_bts_recording, itr); struct perf_pmu *intel_bts_pmu = btsr->intel_bts_pmu; struct evsel *evsel, *intel_bts_evsel = NULL; - const struct perf_cpu_map *cpus = evlist->cpus; + const struct perf_cpu_map *cpus = evlist->core.cpus; bool privileged = geteuid() == 0 || perf_event_paranoid() < 0; btsr->evlist = evlist; diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index aada6a2c456a..218a4e694618 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -365,7 +365,7 @@ static int intel_pt_info_fill(struct auxtrace_record *itr, ui__warning("Intel Processor Trace: TSC not available\n"); } - per_cpu_mmaps = !cpu_map__empty(session->evlist->cpus); + per_cpu_mmaps = !cpu_map__empty(session->evlist->core.cpus); auxtrace_info->type = PERF_AUXTRACE_INTEL_PT; auxtrace_info->priv[INTEL_PT_PMU_TYPE] = intel_pt_pmu->type; @@ -557,7 +557,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, struct perf_pmu *intel_pt_pmu = ptr->intel_pt_pmu; bool have_timing_info, need_immediate = false; struct evsel *evsel, *intel_pt_evsel = NULL; - const struct perf_cpu_map *cpus = evlist->cpus; + const struct perf_cpu_map *cpus = evlist->core.cpus; bool privileged = geteuid() == 0 || perf_event_paranoid() < 0; u64 tsc_bit; int err; diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 77989254fdd8..f481a870e728 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -192,7 +192,7 @@ static int set_tracing_cpumask(struct perf_cpu_map *cpumap) static int set_tracing_cpu(struct perf_ftrace *ftrace) { - struct perf_cpu_map *cpumap = ftrace->evlist->cpus; + struct perf_cpu_map *cpumap = ftrace->evlist->core.cpus; if (!target__has_cpu(&ftrace->target)) return 0; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 27ff899bed88..d4f0430c2f49 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1283,7 +1283,7 @@ static int record__synthesize(struct record *rec, bool tail) return err; } - err = perf_event__synthesize_cpu_map(&rec->tool, rec->evlist->cpus, + err = perf_event__synthesize_cpu_map(&rec->tool, rec->evlist->core.cpus, process_synthesized_event, NULL); if (err < 0) { pr_err("Couldn't synthesize cpu map.\n"); diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 8ad3643d61f9..d81b0b1ef514 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -884,21 +884,21 @@ static int perf_stat_init_aggr_mode(void) switch (stat_config.aggr_mode) { case AGGR_SOCKET: - if (cpu_map__build_socket_map(evsel_list->cpus, &stat_config.aggr_map)) { + if (cpu_map__build_socket_map(evsel_list->core.cpus, &stat_config.aggr_map)) { perror("cannot build socket map"); return -1; } stat_config.aggr_get_id = perf_stat__get_socket_cached; break; case AGGR_DIE: - if (cpu_map__build_die_map(evsel_list->cpus, &stat_config.aggr_map)) { + if (cpu_map__build_die_map(evsel_list->core.cpus, &stat_config.aggr_map)) { perror("cannot build die map"); return -1; } stat_config.aggr_get_id = perf_stat__get_die_cached; break; case AGGR_CORE: - if (cpu_map__build_core_map(evsel_list->cpus, &stat_config.aggr_map)) { + if (cpu_map__build_core_map(evsel_list->core.cpus, &stat_config.aggr_map)) { perror("cannot build core map"); return -1; } @@ -906,7 +906,7 @@ static int perf_stat_init_aggr_mode(void) break; case AGGR_NONE: if (term_percore_set()) { - if (cpu_map__build_core_map(evsel_list->cpus, + if (cpu_map__build_core_map(evsel_list->core.cpus, &stat_config.aggr_map)) { perror("cannot build core map"); return -1; @@ -926,7 +926,7 @@ static int perf_stat_init_aggr_mode(void) * taking the highest cpu number to be the size of * the aggregation translate cpumap. */ - nr = cpu_map__get_max(evsel_list->cpus); + nr = cpu_map__get_max(evsel_list->core.cpus); stat_config.cpus_aggr_map = cpu_map__empty_new(nr + 1); return stat_config.cpus_aggr_map ? 0 : -ENOMEM; } @@ -1057,21 +1057,21 @@ static int perf_stat_init_aggr_mode_file(struct perf_stat *st) switch (stat_config.aggr_mode) { case AGGR_SOCKET: - if (perf_env__build_socket_map(env, evsel_list->cpus, &stat_config.aggr_map)) { + if (perf_env__build_socket_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) { perror("cannot build socket map"); return -1; } stat_config.aggr_get_id = perf_stat__get_socket_file; break; case AGGR_DIE: - if (perf_env__build_die_map(env, evsel_list->cpus, &stat_config.aggr_map)) { + if (perf_env__build_die_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) { perror("cannot build die map"); return -1; } stat_config.aggr_get_id = perf_stat__get_die_file; break; case AGGR_CORE: - if (perf_env__build_core_map(env, evsel_list->cpus, &stat_config.aggr_map)) { + if (perf_env__build_core_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) { perror("cannot build core map"); return -1; } diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 54d06d271bfd..947f83e53272 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -989,7 +989,7 @@ static int perf_top__start_counters(struct perf_top *top) evlist__for_each_entry(evlist, counter) { try_again: - if (evsel__open(counter, top->evlist->cpus, + if (evsel__open(counter, top->evlist->core.cpus, top->evlist->threads) < 0) { /* diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h index 9964e4a9456e..f9caab1fe3c3 100644 --- a/tools/perf/lib/include/internal/evlist.h +++ b/tools/perf/lib/include/internal/evlist.h @@ -2,10 +2,13 @@ #ifndef __LIBPERF_INTERNAL_EVLIST_H #define __LIBPERF_INTERNAL_EVLIST_H +struct perf_cpu_map; + struct perf_evlist { - struct list_head entries; - int nr_entries; - bool has_user_cpus; + struct list_head entries; + int nr_entries; + bool has_user_cpus; + struct perf_cpu_map *cpus; }; #endif /* __LIBPERF_INTERNAL_EVLIST_H */ diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 843959f85d6f..67a2afc5d964 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -130,7 +130,7 @@ void auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp, mp->idx = idx; if (per_cpu) { - mp->cpu = evlist->cpus->map[idx]; + mp->cpu = evlist->core.cpus->map[idx]; if (evlist->threads) mp->tid = thread_map__pid(evlist->threads, 0); else diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 23a8ead4512f..977b9291fb0d 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -143,9 +143,9 @@ void evlist__delete(struct evlist *evlist) perf_evlist__munmap(evlist); evlist__close(evlist); - perf_cpu_map__put(evlist->cpus); + perf_cpu_map__put(evlist->core.cpus); perf_thread_map__put(evlist->threads); - evlist->cpus = NULL; + evlist->core.cpus = NULL; evlist->threads = NULL; perf_evlist__purge(evlist); perf_evlist__exit(evlist); @@ -161,7 +161,7 @@ static void __perf_evlist__propagate_maps(struct evlist *evlist, */ if (!evsel->core.own_cpus || evlist->core.has_user_cpus) { perf_cpu_map__put(evsel->core.cpus); - evsel->core.cpus = perf_cpu_map__get(evlist->cpus); + evsel->core.cpus = perf_cpu_map__get(evlist->core.cpus); } else if (evsel->core.cpus != evsel->core.own_cpus) { perf_cpu_map__put(evsel->core.cpus); evsel->core.cpus = perf_cpu_map__get(evsel->core.own_cpus); @@ -398,7 +398,7 @@ static int perf_evlist__enable_event_thread(struct evlist *evlist, int thread) { int cpu; - int nr_cpus = cpu_map__nr(evlist->cpus); + int nr_cpus = cpu_map__nr(evlist->core.cpus); if (!evsel->fd) return -EINVAL; @@ -414,7 +414,7 @@ static int perf_evlist__enable_event_thread(struct evlist *evlist, int perf_evlist__enable_event_idx(struct evlist *evlist, struct evsel *evsel, int idx) { - bool per_cpu_mmaps = !cpu_map__empty(evlist->cpus); + bool per_cpu_mmaps = !cpu_map__empty(evlist->core.cpus); if (per_cpu_mmaps) return perf_evlist__enable_event_cpu(evlist, evsel, idx); @@ -424,7 +424,7 @@ int perf_evlist__enable_event_idx(struct evlist *evlist, int perf_evlist__alloc_pollfd(struct evlist *evlist) { - int nr_cpus = cpu_map__nr(evlist->cpus); + int nr_cpus = cpu_map__nr(evlist->core.cpus); int nr_threads = thread_map__nr(evlist->threads); int nfds = 0; struct evsel *evsel; @@ -552,8 +552,8 @@ static void perf_evlist__set_sid_idx(struct evlist *evlist, { struct perf_sample_id *sid = SID(evsel, cpu, thread); sid->idx = idx; - if (evlist->cpus && cpu >= 0) - sid->cpu = evlist->cpus->map[cpu]; + if (evlist->core.cpus && cpu >= 0) + sid->cpu = evlist->core.cpus->map[cpu]; else sid->cpu = -1; if (!evsel->system_wide && evlist->threads && thread >= 0) @@ -720,8 +720,8 @@ static struct perf_mmap *perf_evlist__alloc_mmap(struct evlist *evlist, int i; struct perf_mmap *map; - evlist->nr_mmaps = cpu_map__nr(evlist->cpus); - if (cpu_map__empty(evlist->cpus)) + evlist->nr_mmaps = cpu_map__nr(evlist->core.cpus); + if (cpu_map__empty(evlist->core.cpus)) evlist->nr_mmaps = thread_map__nr(evlist->threads); map = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap)); if (!map) @@ -759,7 +759,7 @@ static int perf_evlist__mmap_per_evsel(struct evlist *evlist, int idx, { struct evsel *evsel; int revent; - int evlist_cpu = cpu_map__cpu(evlist->cpus, cpu_idx); + int evlist_cpu = cpu_map__cpu(evlist->core.cpus, cpu_idx); evlist__for_each_entry(evlist, evsel) { struct perf_mmap *maps = evlist->mmap; @@ -835,7 +835,7 @@ static int perf_evlist__mmap_per_cpu(struct evlist *evlist, struct mmap_params *mp) { int cpu, thread; - int nr_cpus = cpu_map__nr(evlist->cpus); + int nr_cpus = cpu_map__nr(evlist->core.cpus); int nr_threads = thread_map__nr(evlist->threads); pr_debug2("perf event ring buffer mmapped per cpu\n"); @@ -1014,7 +1014,7 @@ int perf_evlist__mmap_ex(struct evlist *evlist, unsigned int pages, int comp_level) { struct evsel *evsel; - const struct perf_cpu_map *cpus = evlist->cpus; + const struct perf_cpu_map *cpus = evlist->core.cpus; const struct perf_thread_map *threads = evlist->threads; /* * Delay setting mp.prot: set it before calling perf_mmap__mmap. @@ -1116,9 +1116,9 @@ void perf_evlist__set_maps(struct evlist *evlist, struct perf_cpu_map *cpus, * original reference count of 1. If that is not the case it is up to * the caller to increase the reference count. */ - if (cpus != evlist->cpus) { - perf_cpu_map__put(evlist->cpus); - evlist->cpus = perf_cpu_map__get(cpus); + if (cpus != evlist->core.cpus) { + perf_cpu_map__put(evlist->core.cpus); + evlist->core.cpus = perf_cpu_map__get(cpus); } if (threads != evlist->threads) { @@ -1398,7 +1398,7 @@ int evlist__open(struct evlist *evlist) * Default: one fd per CPU, all threads, aka systemwide * as sys_perf_event_open(cpu = -1, thread = -1) is EINVAL */ - if (evlist->threads == NULL && evlist->cpus == NULL) { + if (evlist->threads == NULL && evlist->core.cpus == NULL) { err = perf_evlist__create_syswide_maps(evlist); if (err < 0) goto out_err; @@ -1920,7 +1920,7 @@ int perf_evlist__start_sb_thread(struct evlist *evlist, goto out_delete_evlist; evlist__for_each_entry(evlist, counter) { - if (evsel__open(counter, evlist->cpus, + if (evsel__open(counter, evlist->core.cpus, evlist->threads) < 0) goto out_delete_evlist; } diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 35cca0242631..fdd8f83eac2d 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -44,7 +44,6 @@ struct evlist { struct perf_mmap *mmap; struct perf_mmap *overwrite_mmap; struct perf_thread_map *threads; - struct perf_cpu_map *cpus; struct evsel *selected; struct events_stats stats; struct perf_env *env; diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 03dcdb3f33a7..e59382d99196 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -148,7 +148,7 @@ void perf_evlist__config(struct evlist *evlist, struct record_opts *opts, if (opts->group) perf_evlist__set_leader(evlist); - if (evlist->cpus->map[0] < 0) + if (evlist->core.cpus->map[0] < 0) opts->no_inherit = true; use_comm_exec = perf_can_comm_exec(); @@ -275,13 +275,13 @@ bool perf_evlist__can_select_event(struct evlist *evlist, const char *str) evsel = perf_evlist__last(temp_evlist); - if (!evlist || cpu_map__empty(evlist->cpus)) { + if (!evlist || cpu_map__empty(evlist->core.cpus)) { struct perf_cpu_map *cpus = perf_cpu_map__new(NULL); cpu = cpus ? cpus->map[0] : 0; perf_cpu_map__put(cpus); } else { - cpu = evlist->cpus->map[0]; + cpu = evlist->core.cpus->map[0]; } while (1) { diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 7c938135398b..4a162858583f 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -327,7 +327,7 @@ static int first_shadow_cpu(struct perf_stat_config *config, for (i = 0; i < perf_evsel__nr_cpus(evsel); i++) { int cpu2 = evsel__cpus(evsel)->map[i]; - if (config->aggr_get_id(config, evlist->cpus, cpu2) == id) + if (config->aggr_get_id(config, evlist->core.cpus, cpu2) == id) return cpu2; } return 0; @@ -500,7 +500,7 @@ static void aggr_update_shadow(struct perf_stat_config *config, evlist__for_each_entry(evlist, counter) { val = 0; for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { - s2 = config->aggr_get_id(config, evlist->cpus, cpu); + s2 = config->aggr_get_id(config, evlist->core.cpus, cpu); if (s2 != id) continue; val += perf_counts(counter->counts, cpu, 0)->val; @@ -868,7 +868,7 @@ static void print_no_aggr_metric(struct perf_stat_config *config, u64 ena, run, val; double uval; - nrcpus = evlist->cpus->nr; + nrcpus = evlist->core.cpus->nr; for (cpu = 0; cpu < nrcpus; cpu++) { bool first = true; diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 1e351462ca49..24c9c3015983 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -514,7 +514,7 @@ int perf_stat_synthesize_config(struct perf_stat_config *config, return err; } - err = perf_event__synthesize_cpu_map(tool, evlist->cpus, + err = perf_event__synthesize_cpu_map(tool, evlist->core.cpus, process, NULL); if (err < 0) { pr_err("Couldn't synthesize thread map.\n"); diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c index f533f1aac045..e5b690cf2898 100644 --- a/tools/perf/util/top.c +++ b/tools/perf/util/top.c @@ -95,15 +95,15 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) if (target->cpu_list) ret += SNPRINTF(bf + ret, size - ret, ", CPU%s: %s)", - top->evlist->cpus->nr > 1 ? "s" : "", + top->evlist->core.cpus->nr > 1 ? "s" : "", target->cpu_list); else { if (target->tid) ret += SNPRINTF(bf + ret, size - ret, ")"); else ret += SNPRINTF(bf + ret, size - ret, ", %d CPU%s)", - top->evlist->cpus->nr, - top->evlist->cpus->nr > 1 ? "s" : ""); + top->evlist->core.cpus->nr, + top->evlist->core.cpus->nr > 1 ? "s" : ""); } perf_top__reset_sample_counters(top); -- cgit v1.2.3-59-g8ed1b From 03617c22e31f32cbf0e4797e216db898fb898d90 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:42 +0200 Subject: libperf: Add threads to struct perf_evlist Move threads from tools/perf's evlist to libperf's perf_evlist struct. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-56-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-ftrace.c | 4 ++-- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-record.c | 4 ++-- tools/perf/builtin-stat.c | 18 +++++++-------- tools/perf/builtin-top.c | 4 ++-- tools/perf/builtin-trace.c | 8 +++---- tools/perf/lib/include/internal/evlist.h | 2 ++ tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/util/auxtrace.c | 6 ++--- tools/perf/util/evlist.c | 36 ++++++++++++++--------------- tools/perf/util/evlist.h | 1 - tools/perf/util/stat.c | 2 +- 12 files changed, 45 insertions(+), 44 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index f481a870e728..ae1466aa3b26 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -156,9 +156,9 @@ static int set_tracing_pid(struct perf_ftrace *ftrace) if (target__has_cpu(&ftrace->target)) return 0; - for (i = 0; i < thread_map__nr(ftrace->evlist->threads); i++) { + for (i = 0; i < thread_map__nr(ftrace->evlist->core.threads); i++) { scnprintf(buf, sizeof(buf), "%d", - ftrace->evlist->threads->map[i]); + ftrace->evlist->core.threads->map[i]); if (append_tracing_file("set_ftrace_pid", buf) < 0) return -1; } diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index b9c58a5c1ba6..69d16ac852c3 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1450,7 +1450,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, perf_session__set_id_hdr_size(kvm->session); ordered_events__set_copy_on_queue(&kvm->session->ordered_events, true); machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target, - kvm->evlist->threads, false, 1); + kvm->evlist->core.threads, false, 1); err = kvm_live_open_events(kvm); if (err) goto out; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index d4f0430c2f49..d31d7a5a1be3 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1275,7 +1275,7 @@ static int record__synthesize(struct record *rec, bool tail) if (err) goto out; - err = perf_event__synthesize_thread_map2(&rec->tool, rec->evlist->threads, + err = perf_event__synthesize_thread_map2(&rec->tool, rec->evlist->core.threads, process_synthesized_event, NULL); if (err < 0) { @@ -1295,7 +1295,7 @@ static int record__synthesize(struct record *rec, bool tail) if (err < 0) pr_warning("Couldn't synthesize bpf events.\n"); - err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads, + err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->core.threads, process_synthesized_event, opts->sample_address, 1); out: diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index d81b0b1ef514..4a94ca131d56 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -263,7 +263,7 @@ static int read_single_counter(struct evsel *counter, int cpu, */ static int read_counter(struct evsel *counter, struct timespec *rs) { - int nthreads = thread_map__nr(evsel_list->threads); + int nthreads = thread_map__nr(evsel_list->core.threads); int ncpus, cpu, thread; if (target__has_cpu(&target) && !target__has_per_thread(&target)) @@ -485,15 +485,15 @@ try_again: ui__warning("%s\n", msg); goto try_again; } else if (target__has_per_thread(&target) && - evsel_list->threads && - evsel_list->threads->err_thread != -1) { + evsel_list->core.threads && + evsel_list->core.threads->err_thread != -1) { /* * For global --per-thread case, skip current * error thread. */ - if (!thread_map__remove(evsel_list->threads, - evsel_list->threads->err_thread)) { - evsel_list->threads->err_thread = -1; + if (!thread_map__remove(evsel_list->core.threads, + evsel_list->core.threads->err_thread)) { + evsel_list->core.threads->err_thread = -1; goto try_again; } } @@ -579,7 +579,7 @@ try_again: enable_counters(); while (!done) { nanosleep(&ts, NULL); - if (!is_target_alive(&target, evsel_list->threads)) + if (!is_target_alive(&target, evsel_list->core.threads)) break; if (timeout) break; @@ -1889,10 +1889,10 @@ int cmd_stat(int argc, const char **argv) * so we could print it out on output. */ if (stat_config.aggr_mode == AGGR_THREAD) { - thread_map__read_comms(evsel_list->threads); + thread_map__read_comms(evsel_list->core.threads); if (target.system_wide) { if (runtime_stat_new(&stat_config, - thread_map__nr(evsel_list->threads))) { + thread_map__nr(evsel_list->core.threads))) { goto out; } } diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 947f83e53272..c69ddc67c672 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -990,7 +990,7 @@ static int perf_top__start_counters(struct perf_top *top) evlist__for_each_entry(evlist, counter) { try_again: if (evsel__open(counter, top->evlist->core.cpus, - top->evlist->threads) < 0) { + top->evlist->core.threads) < 0) { /* * Specially handle overwrite fall back. @@ -1222,7 +1222,7 @@ static int __cmd_top(struct perf_top *top) pr_debug("Couldn't synthesize BPF events: Pre-existing BPF programs won't have symbols resolved.\n"); machine__synthesize_threads(&top->session->machines.host, &opts->target, - top->evlist->threads, false, + top->evlist->core.threads, false, top->nr_threads_synthesize); if (top->nr_threads_synthesize > 1) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index abfd22ff1730..35f3684f5327 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1404,7 +1404,7 @@ static int trace__symbols_init(struct trace *trace, struct evlist *evlist) goto out; err = __machine__synthesize_threads(trace->host, &trace->tool, &trace->opts.target, - evlist->threads, trace__tool_process, false, + evlist->core.threads, trace__tool_process, false, 1); out: if (err) @@ -3183,7 +3183,7 @@ static int trace__set_filter_pids(struct trace *trace) err = bpf_map__set_filter_pids(trace->filter_pids.map, trace->filter_pids.nr, trace->filter_pids.entries); } - } else if (thread_map__pid(trace->evlist->threads, 0) == -1) { + } else if (thread_map__pid(trace->evlist->core.threads, 0) == -1) { err = trace__set_filter_loop_pids(trace); } @@ -3412,8 +3412,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv) evlist__enable(evlist); } - trace->multiple_threads = thread_map__pid(evlist->threads, 0) == -1 || - evlist->threads->nr > 1 || + trace->multiple_threads = thread_map__pid(evlist->core.threads, 0) == -1 || + evlist->core.threads->nr > 1 || perf_evlist__first(evlist)->core.attr.inherit; /* diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h index f9caab1fe3c3..b7b43dbc9b82 100644 --- a/tools/perf/lib/include/internal/evlist.h +++ b/tools/perf/lib/include/internal/evlist.h @@ -3,12 +3,14 @@ #define __LIBPERF_INTERNAL_EVLIST_H struct perf_cpu_map; +struct perf_thread_map; struct perf_evlist { struct list_head entries; int nr_entries; bool has_user_cpus; struct perf_cpu_map *cpus; + struct perf_thread_map *threads; }; #endif /* __LIBPERF_INTERNAL_EVLIST_H */ diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index 1de79208e690..9c06130d37be 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -58,7 +58,7 @@ int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest perf_evsel__config(evsel, &opts, NULL); - perf_thread_map__set_pid(evlist->threads, 0, getpid()); + perf_thread_map__set_pid(evlist->core.threads, 0, getpid()); err = evlist__open(evlist); if (err < 0) { diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 67a2afc5d964..65728cdeefb6 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -131,13 +131,13 @@ void auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp, if (per_cpu) { mp->cpu = evlist->core.cpus->map[idx]; - if (evlist->threads) - mp->tid = thread_map__pid(evlist->threads, 0); + if (evlist->core.threads) + mp->tid = thread_map__pid(evlist->core.threads, 0); else mp->tid = -1; } else { mp->cpu = -1; - mp->tid = thread_map__pid(evlist->threads, idx); + mp->tid = thread_map__pid(evlist->core.threads, idx); } } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 977b9291fb0d..1a6f877ebb03 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -144,9 +144,9 @@ void evlist__delete(struct evlist *evlist) perf_evlist__munmap(evlist); evlist__close(evlist); perf_cpu_map__put(evlist->core.cpus); - perf_thread_map__put(evlist->threads); + perf_thread_map__put(evlist->core.threads); evlist->core.cpus = NULL; - evlist->threads = NULL; + evlist->core.threads = NULL; perf_evlist__purge(evlist); perf_evlist__exit(evlist); free(evlist); @@ -168,7 +168,7 @@ static void __perf_evlist__propagate_maps(struct evlist *evlist, } perf_thread_map__put(evsel->core.threads); - evsel->core.threads = perf_thread_map__get(evlist->threads); + evsel->core.threads = perf_thread_map__get(evlist->core.threads); } static void perf_evlist__propagate_maps(struct evlist *evlist) @@ -342,7 +342,7 @@ static int perf_evlist__nr_threads(struct evlist *evlist, if (evsel->system_wide) return 1; else - return thread_map__nr(evlist->threads); + return thread_map__nr(evlist->core.threads); } void evlist__disable(struct evlist *evlist) @@ -425,7 +425,7 @@ int perf_evlist__enable_event_idx(struct evlist *evlist, int perf_evlist__alloc_pollfd(struct evlist *evlist) { int nr_cpus = cpu_map__nr(evlist->core.cpus); - int nr_threads = thread_map__nr(evlist->threads); + int nr_threads = thread_map__nr(evlist->core.threads); int nfds = 0; struct evsel *evsel; @@ -556,8 +556,8 @@ static void perf_evlist__set_sid_idx(struct evlist *evlist, sid->cpu = evlist->core.cpus->map[cpu]; else sid->cpu = -1; - if (!evsel->system_wide && evlist->threads && thread >= 0) - sid->tid = thread_map__pid(evlist->threads, thread); + if (!evsel->system_wide && evlist->core.threads && thread >= 0) + sid->tid = thread_map__pid(evlist->core.threads, thread); else sid->tid = -1; } @@ -722,7 +722,7 @@ static struct perf_mmap *perf_evlist__alloc_mmap(struct evlist *evlist, evlist->nr_mmaps = cpu_map__nr(evlist->core.cpus); if (cpu_map__empty(evlist->core.cpus)) - evlist->nr_mmaps = thread_map__nr(evlist->threads); + evlist->nr_mmaps = thread_map__nr(evlist->core.threads); map = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap)); if (!map) return NULL; @@ -836,7 +836,7 @@ static int perf_evlist__mmap_per_cpu(struct evlist *evlist, { int cpu, thread; int nr_cpus = cpu_map__nr(evlist->core.cpus); - int nr_threads = thread_map__nr(evlist->threads); + int nr_threads = thread_map__nr(evlist->core.threads); pr_debug2("perf event ring buffer mmapped per cpu\n"); for (cpu = 0; cpu < nr_cpus; cpu++) { @@ -864,7 +864,7 @@ static int perf_evlist__mmap_per_thread(struct evlist *evlist, struct mmap_params *mp) { int thread; - int nr_threads = thread_map__nr(evlist->threads); + int nr_threads = thread_map__nr(evlist->core.threads); pr_debug2("perf event ring buffer mmapped per thread\n"); for (thread = 0; thread < nr_threads; thread++) { @@ -1015,7 +1015,7 @@ int perf_evlist__mmap_ex(struct evlist *evlist, unsigned int pages, { struct evsel *evsel; const struct perf_cpu_map *cpus = evlist->core.cpus; - const struct perf_thread_map *threads = evlist->threads; + const struct perf_thread_map *threads = evlist->core.threads; /* * Delay setting mp.prot: set it before calling perf_mmap__mmap. * Its value is decided by evsel's write_backward. @@ -1121,9 +1121,9 @@ void perf_evlist__set_maps(struct evlist *evlist, struct perf_cpu_map *cpus, evlist->core.cpus = perf_cpu_map__get(cpus); } - if (threads != evlist->threads) { - perf_thread_map__put(evlist->threads); - evlist->threads = perf_thread_map__get(threads); + if (threads != evlist->core.threads) { + perf_thread_map__put(evlist->core.threads); + evlist->core.threads = perf_thread_map__get(threads); } perf_evlist__propagate_maps(evlist); @@ -1398,7 +1398,7 @@ int evlist__open(struct evlist *evlist) * Default: one fd per CPU, all threads, aka systemwide * as sys_perf_event_open(cpu = -1, thread = -1) is EINVAL */ - if (evlist->threads == NULL && evlist->core.cpus == NULL) { + if (evlist->core.threads == NULL && evlist->core.cpus == NULL) { err = perf_evlist__create_syswide_maps(evlist); if (err < 0) goto out_err; @@ -1501,12 +1501,12 @@ int perf_evlist__prepare_workload(struct evlist *evlist, struct target *target, } if (target__none(target)) { - if (evlist->threads == NULL) { + if (evlist->core.threads == NULL) { fprintf(stderr, "FATAL: evlist->threads need to be set at this point (%s:%d).\n", __func__, __LINE__); goto out_close_pipes; } - perf_thread_map__set_pid(evlist->threads, 0, evlist->workload.pid); + perf_thread_map__set_pid(evlist->core.threads, 0, evlist->workload.pid); } close(child_ready_pipe[1]); @@ -1921,7 +1921,7 @@ int perf_evlist__start_sb_thread(struct evlist *evlist, evlist__for_each_entry(evlist, counter) { if (evsel__open(counter, evlist->core.cpus, - evlist->threads) < 0) + evlist->core.threads) < 0) goto out_delete_evlist; } diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index fdd8f83eac2d..de2025d198d4 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -43,7 +43,6 @@ struct evlist { struct fdarray pollfd; struct perf_mmap *mmap; struct perf_mmap *overwrite_mmap; - struct perf_thread_map *threads; struct evsel *selected; struct events_stats stats; struct perf_env *env; diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 24c9c3015983..799f3c0a9050 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -507,7 +507,7 @@ int perf_stat_synthesize_config(struct perf_stat_config *config, err = perf_event__synthesize_extra_attr(tool, evlist, process, attrs); - err = perf_event__synthesize_thread_map2(tool, evlist->threads, + err = perf_event__synthesize_thread_map2(tool, evlist->core.threads, process, NULL); if (err < 0) { pr_err("Couldn't synthesize thread map.\n"); -- cgit v1.2.3-59-g8ed1b From 453fa03090a64c0e0a561f10dfd5e8747796949c Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:43 +0200 Subject: libperf: Add perf_evlist__set_maps() function Move the evlist__set_maps() function from tools/perf to libperf. Committer notes: Fix up reject due to earlier inversion in calling perf_evlist__init(). Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-57-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 3 +- tools/perf/builtin-script.c | 3 +- tools/perf/builtin-stat.c | 3 +- tools/perf/lib/evlist.c | 54 ++++++++++++++++++++++++++ tools/perf/lib/include/perf/evlist.h | 6 +++ tools/perf/lib/libperf.map | 1 + tools/perf/tests/code-reading.c | 5 ++- tools/perf/tests/keep-tracking.c | 3 +- tools/perf/tests/mmap-basic.c | 3 +- tools/perf/tests/sw-clock.c | 3 +- tools/perf/tests/switch-tracking.c | 3 +- tools/perf/tests/task-exit.c | 3 +- tools/perf/util/evlist.c | 58 ++-------------------------- tools/perf/util/evlist.h | 2 - 14 files changed, 83 insertions(+), 67 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index 261bdd680651..582182d98a7f 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "parse-events.h" #include "evlist.h" @@ -72,7 +73,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe evlist = evlist__new(); CHECK_NOT_NULL__(evlist); - perf_evlist__set_maps(evlist, cpus, threads); + perf_evlist__set_maps(&evlist->core, cpus, threads); CHECK__(parse_events(evlist, "cycles:u", NULL)); diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index a787c5cb1331..46fadbbe1c3e 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -48,6 +48,7 @@ #include #include #include +#include #include @@ -3264,7 +3265,7 @@ static int set_maps(struct perf_script *script) if (WARN_ONCE(script->allocated, "stats double allocation\n")) return -EINVAL; - perf_evlist__set_maps(evlist, script->cpus, script->threads); + perf_evlist__set_maps(&evlist->core, script->cpus, script->threads); if (perf_evlist__alloc_stats(evlist, true)) return -ENOMEM; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 4a94ca131d56..14e4c970d16a 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -83,6 +83,7 @@ #include #include +#include #define DEFAULT_SEPARATOR " " #define FREEZE_ON_SMI_PATH "devices/cpu/freeze_on_smi" @@ -1517,7 +1518,7 @@ static int set_maps(struct perf_stat *st) if (WARN_ONCE(st->maps_allocated, "stats double allocation\n")) return -EINVAL; - perf_evlist__set_maps(evsel_list, st->cpus, st->threads); + perf_evlist__set_maps(&evsel_list->core, st->cpus, st->threads); if (perf_evlist__alloc_stats(evsel_list, true)) return -ENOMEM; diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c index 087ef76ea8fd..6a2308ef9868 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/perf/lib/evlist.c @@ -5,6 +5,8 @@ #include #include #include +#include +#include void perf_evlist__init(struct perf_evlist *evlist) { @@ -12,11 +14,39 @@ void perf_evlist__init(struct perf_evlist *evlist) evlist->nr_entries = 0; } +static void __perf_evlist__propagate_maps(struct perf_evlist *evlist, + struct perf_evsel *evsel) +{ + /* + * We already have cpus for evsel (via PMU sysfs) so + * keep it, if there's no target cpu list defined. + */ + if (!evsel->own_cpus || evlist->has_user_cpus) { + perf_cpu_map__put(evsel->cpus); + evsel->cpus = perf_cpu_map__get(evlist->cpus); + } else if (evsel->cpus != evsel->own_cpus) { + perf_cpu_map__put(evsel->cpus); + evsel->cpus = perf_cpu_map__get(evsel->own_cpus); + } + + perf_thread_map__put(evsel->threads); + evsel->threads = perf_thread_map__get(evlist->threads); +} + +static void perf_evlist__propagate_maps(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel; + + perf_evlist__for_each_evsel(evlist, evsel) + __perf_evlist__propagate_maps(evlist, evsel); +} + void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *evsel) { list_add_tail(&evsel->node, &evlist->entries); evlist->nr_entries += 1; + __perf_evlist__propagate_maps(evlist, evsel); } void perf_evlist__remove(struct perf_evlist *evlist, @@ -60,3 +90,27 @@ void perf_evlist__delete(struct perf_evlist *evlist) { free(evlist); } + +void perf_evlist__set_maps(struct perf_evlist *evlist, + struct perf_cpu_map *cpus, + struct perf_thread_map *threads) +{ + /* + * Allow for the possibility that one or another of the maps isn't being + * changed i.e. don't put it. Note we are assuming the maps that are + * being applied are brand new and evlist is taking ownership of the + * original reference count of 1. If that is not the case it is up to + * the caller to increase the reference count. + */ + if (cpus != evlist->cpus) { + perf_cpu_map__put(evlist->cpus); + evlist->cpus = perf_cpu_map__get(cpus); + } + + if (threads != evlist->threads) { + perf_thread_map__put(evlist->threads); + evlist->threads = perf_thread_map__get(threads); + } + + perf_evlist__propagate_maps(evlist); +} diff --git a/tools/perf/lib/include/perf/evlist.h b/tools/perf/lib/include/perf/evlist.h index 9a126fd0773c..b1d8dee018d6 100644 --- a/tools/perf/lib/include/perf/evlist.h +++ b/tools/perf/lib/include/perf/evlist.h @@ -6,6 +6,8 @@ struct perf_evlist; struct perf_evsel; +struct perf_cpu_map; +struct perf_thread_map; LIBPERF_API void perf_evlist__init(struct perf_evlist *evlist); LIBPERF_API void perf_evlist__add(struct perf_evlist *evlist, @@ -22,4 +24,8 @@ LIBPERF_API struct perf_evsel* perf_evlist__next(struct perf_evlist *evlist, (pos) != NULL; \ (pos) = perf_evlist__next((evlist), (pos))) +LIBPERF_API void perf_evlist__set_maps(struct perf_evlist *evlist, + struct perf_cpu_map *cpus, + struct perf_thread_map *threads); + #endif /* __LIBPERF_EVLIST_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 28ed04cbd223..9b6e8f165014 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -20,6 +20,7 @@ LIBPERF_0.0.1 { perf_evlist__add; perf_evlist__remove; perf_evlist__next; + perf_evlist__set_maps; local: *; }; diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index bfaf22c2023c..e45df0736261 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "parse-events.h" #include "evlist.h" @@ -629,7 +630,7 @@ static int do_test_code_reading(bool try_kcore) goto out_put; } - perf_evlist__set_maps(evlist, cpus, threads); + perf_evlist__set_maps(&evlist->core, cpus, threads); str = do_determine_event(excl_kernel); pr_debug("Parsing event '%s'\n", str); @@ -658,7 +659,7 @@ static int do_test_code_reading(bool try_kcore) */ perf_cpu_map__get(cpus); perf_thread_map__get(threads); - perf_evlist__set_maps(evlist, NULL, NULL); + perf_evlist__set_maps(&evlist->core, NULL, NULL); evlist__delete(evlist); evlist = NULL; continue; diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 46478ba1ed16..0ce5ce33bac4 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "parse-events.h" #include "evlist.h" @@ -82,7 +83,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un evlist = evlist__new(); CHECK_NOT_NULL__(evlist); - perf_evlist__set_maps(evlist, cpus, threads); + perf_evlist__set_maps(&evlist->core, cpus, threads); CHECK__(parse_events(evlist, "dummy:u", NULL)); CHECK__(parse_events(evlist, "cycles:u", NULL)); diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index aa792aebd7f0..7327694fbde0 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -12,6 +12,7 @@ #include "tests.h" #include #include +#include /* * This test will generate random numbers of calls to some getpid syscalls, @@ -68,7 +69,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse goto out_free_cpus; } - perf_evlist__set_maps(evlist, cpus, threads); + perf_evlist__set_maps(&evlist->core, cpus, threads); for (i = 0; i < nsyscalls; ++i) { char name[64]; diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 2decda2d4c17..c5f1a9f83380 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -11,6 +11,7 @@ #include "util/evlist.h" #include "util/cpumap.h" #include "util/thread_map.h" +#include #define NR_LOOPS 10000000 @@ -64,7 +65,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) goto out_free_maps; } - perf_evlist__set_maps(evlist, cpus, threads); + perf_evlist__set_maps(&evlist->core, cpus, threads); cpus = NULL; threads = NULL; diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 9e0bbea15005..e3cee69f6ea2 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "parse-events.h" #include "evlist.h" @@ -354,7 +355,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ goto out_err; } - perf_evlist__set_maps(evlist, cpus, threads); + perf_evlist__set_maps(&evlist->core, cpus, threads); /* First event */ err = parse_events(evlist, "cpu-clock:u", NULL); diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index b0192ea636a7..4ca38fd0379a 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -7,6 +7,7 @@ #include #include +#include static int exited; static int nr_exit; @@ -71,7 +72,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused goto out_free_maps; } - perf_evlist__set_maps(evlist, cpus, threads); + perf_evlist__set_maps(&evlist->core, cpus, threads); cpus = NULL; threads = NULL; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 1a6f877ebb03..4433b656cfb7 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -51,7 +51,7 @@ void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i) INIT_HLIST_HEAD(&evlist->heads[i]); perf_evlist__init(&evlist->core); - perf_evlist__set_maps(evlist, cpus, threads); + perf_evlist__set_maps(&evlist->core, cpus, threads); fdarray__init(&evlist->pollfd, 64); evlist->workload.pid = -1; evlist->bkw_mmap_state = BKW_MMAP_NOTREADY; @@ -152,33 +152,6 @@ void evlist__delete(struct evlist *evlist) free(evlist); } -static void __perf_evlist__propagate_maps(struct evlist *evlist, - struct evsel *evsel) -{ - /* - * We already have cpus for evsel (via PMU sysfs) so - * keep it, if there's no target cpu list defined. - */ - if (!evsel->core.own_cpus || evlist->core.has_user_cpus) { - perf_cpu_map__put(evsel->core.cpus); - evsel->core.cpus = perf_cpu_map__get(evlist->core.cpus); - } else if (evsel->core.cpus != evsel->core.own_cpus) { - perf_cpu_map__put(evsel->core.cpus); - evsel->core.cpus = perf_cpu_map__get(evsel->core.own_cpus); - } - - perf_thread_map__put(evsel->core.threads); - evsel->core.threads = perf_thread_map__get(evlist->core.threads); -} - -static void perf_evlist__propagate_maps(struct evlist *evlist) -{ - struct evsel *evsel; - - evlist__for_each_entry(evlist, evsel) - __perf_evlist__propagate_maps(evlist, evsel); -} - void evlist__add(struct evlist *evlist, struct evsel *entry) { entry->evlist = evlist; @@ -189,8 +162,6 @@ void evlist__add(struct evlist *evlist, struct evsel *entry) if (evlist->core.nr_entries == 1) perf_evlist__set_id_pos(evlist); - - __perf_evlist__propagate_maps(evlist, entry); } void evlist__remove(struct evlist *evlist, struct evsel *evsel) @@ -1097,7 +1068,7 @@ int perf_evlist__create_maps(struct evlist *evlist, struct target *target) evlist->core.has_user_cpus = !!target->cpu_list; - perf_evlist__set_maps(evlist, cpus, threads); + perf_evlist__set_maps(&evlist->core, cpus, threads); return 0; @@ -1106,29 +1077,6 @@ out_delete_threads: return -1; } -void perf_evlist__set_maps(struct evlist *evlist, struct perf_cpu_map *cpus, - struct perf_thread_map *threads) -{ - /* - * Allow for the possibility that one or another of the maps isn't being - * changed i.e. don't put it. Note we are assuming the maps that are - * being applied are brand new and evlist is taking ownership of the - * original reference count of 1. If that is not the case it is up to - * the caller to increase the reference count. - */ - if (cpus != evlist->core.cpus) { - perf_cpu_map__put(evlist->core.cpus); - evlist->core.cpus = perf_cpu_map__get(cpus); - } - - if (threads != evlist->core.threads) { - perf_thread_map__put(evlist->core.threads); - evlist->core.threads = perf_thread_map__get(threads); - } - - perf_evlist__propagate_maps(evlist); -} - void __perf_evlist__set_sample_bit(struct evlist *evlist, enum perf_event_sample_format bit) { @@ -1381,7 +1329,7 @@ static int perf_evlist__create_syswide_maps(struct evlist *evlist) if (!threads) goto out_put; - perf_evlist__set_maps(evlist, cpus, threads); + perf_evlist__set_maps(&evlist->core, cpus, threads); out: return err; out_put: diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index de2025d198d4..e31ddcc058f2 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -191,8 +191,6 @@ int perf_evlist__enable_event_idx(struct evlist *evlist, void perf_evlist__set_selected(struct evlist *evlist, struct evsel *evsel); -void perf_evlist__set_maps(struct evlist *evlist, struct perf_cpu_map *cpus, - struct perf_thread_map *threads); int perf_evlist__create_maps(struct evlist *evlist, struct target *target); int perf_evlist__apply_filters(struct evlist *evlist, struct evsel **err_evsel); -- cgit v1.2.3-59-g8ed1b From 4b247fa7314ce48282f3da400a9ffb7f3fd3f863 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:44 +0200 Subject: libperf: Adopt xyarray class from perf Move the xyarray class from perf to libperf, because it's going to be used in both. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-58-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 1 - tools/perf/lib/Build | 1 + tools/perf/lib/include/internal/xyarray.h | 35 +++++++++++++++++++++++++++++++ tools/perf/lib/xyarray.c | 33 +++++++++++++++++++++++++++++ tools/perf/util/Build | 1 - tools/perf/util/counts.h | 2 +- tools/perf/util/evsel.h | 2 +- tools/perf/util/python-ext-sources | 1 - tools/perf/util/stat.h | 1 - tools/perf/util/xyarray.h | 35 ------------------------------- 10 files changed, 71 insertions(+), 41 deletions(-) create mode 100644 tools/perf/lib/include/internal/xyarray.h create mode 100644 tools/perf/lib/xyarray.c delete mode 100644 tools/perf/util/xyarray.h (limited to 'tools') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index c69ddc67c672..1a4615a5f6c9 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -38,7 +38,6 @@ #include #include "util/parse-events.h" #include "util/cpumap.h" -#include "util/xyarray.h" #include "util/sort.h" #include "util/string2.h" #include "util/term.h" diff --git a/tools/perf/lib/Build b/tools/perf/lib/Build index faf64db13e37..4f78ec0b4e10 100644 --- a/tools/perf/lib/Build +++ b/tools/perf/lib/Build @@ -4,6 +4,7 @@ libperf-y += threadmap.o libperf-y += evsel.o libperf-y += evlist.o libperf-y += zalloc.o +libperf-y += xyarray.o $(OUTPUT)zalloc.o: ../../lib/zalloc.c FORCE $(call rule_mkdir) diff --git a/tools/perf/lib/include/internal/xyarray.h b/tools/perf/lib/include/internal/xyarray.h new file mode 100644 index 000000000000..3bf70e4d474c --- /dev/null +++ b/tools/perf/lib/include/internal/xyarray.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LIBPERF_INTERNAL_XYARRAY_H +#define __LIBPERF_INTERNAL_XYARRAY_H + +#include + +struct xyarray { + size_t row_size; + size_t entry_size; + size_t entries; + size_t max_x; + size_t max_y; + char contents[]; +}; + +struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size); +void xyarray__delete(struct xyarray *xy); +void xyarray__reset(struct xyarray *xy); + +static inline void *xyarray__entry(struct xyarray *xy, int x, int y) +{ + return &xy->contents[x * xy->row_size + y * xy->entry_size]; +} + +static inline int xyarray__max_y(struct xyarray *xy) +{ + return xy->max_y; +} + +static inline int xyarray__max_x(struct xyarray *xy) +{ + return xy->max_x; +} + +#endif /* __LIBPERF_INTERNAL_XYARRAY_H */ diff --git a/tools/perf/lib/xyarray.c b/tools/perf/lib/xyarray.c new file mode 100644 index 000000000000..dcd901d154bb --- /dev/null +++ b/tools/perf/lib/xyarray.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include + +struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size) +{ + size_t row_size = ylen * entry_size; + struct xyarray *xy = zalloc(sizeof(*xy) + xlen * row_size); + + if (xy != NULL) { + xy->entry_size = entry_size; + xy->row_size = row_size; + xy->entries = xlen * ylen; + xy->max_x = xlen; + xy->max_y = ylen; + } + + return xy; +} + +void xyarray__reset(struct xyarray *xy) +{ + size_t n = xy->entries * xy->entry_size; + + memset(xy->contents, 0, n); +} + +void xyarray__delete(struct xyarray *xy) +{ + free(xy); +} diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 08f670d21615..7abf05131889 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -69,7 +69,6 @@ perf-y += svghelper.o perf-y += sort.o perf-y += hist.o perf-y += util.o -perf-y += xyarray.o perf-y += cpumap.o perf-y += cputopo.o perf-y += cgroup.o diff --git a/tools/perf/util/counts.h b/tools/perf/util/counts.h index 0f0cb2d8f70d..bbfac9ecf642 100644 --- a/tools/perf/util/counts.h +++ b/tools/perf/util/counts.h @@ -2,7 +2,7 @@ #ifndef __PERF_COUNTS_H #define __PERF_COUNTS_H -#include "xyarray.h" +#include struct perf_counts_values { union { diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 57b5523b480c..1f9f66fe43f4 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -8,7 +8,7 @@ #include #include #include -#include "xyarray.h" +#include #include "symbol_conf.h" #include "cpumap.h" #include "counts.h" diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index 2237bac9fadb..235bd9803390 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources @@ -20,7 +20,6 @@ util/namespaces.c ../lib/vsprintf.c util/thread_map.c util/util.c -util/xyarray.c util/cgroup.c util/parse-branch-options.c util/rblist.c diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 95b4de7a9d51..bcb376e1b3a7 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -8,7 +8,6 @@ #include #include #include -#include "xyarray.h" #include "rblist.h" #include "perf.h" #include "event.h" diff --git a/tools/perf/util/xyarray.h b/tools/perf/util/xyarray.h deleted file mode 100644 index 7ffe562e7ae7..000000000000 --- a/tools/perf/util/xyarray.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _PERF_XYARRAY_H_ -#define _PERF_XYARRAY_H_ 1 - -#include - -struct xyarray { - size_t row_size; - size_t entry_size; - size_t entries; - size_t max_x; - size_t max_y; - char contents[]; -}; - -struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size); -void xyarray__delete(struct xyarray *xy); -void xyarray__reset(struct xyarray *xy); - -static inline void *xyarray__entry(struct xyarray *xy, int x, int y) -{ - return &xy->contents[x * xy->row_size + y * xy->entry_size]; -} - -static inline int xyarray__max_y(struct xyarray *xy) -{ - return xy->max_y; -} - -static inline int xyarray__max_x(struct xyarray *xy) -{ - return xy->max_x; -} - -#endif /* _PERF_XYARRAY_H_ */ -- cgit v1.2.3-59-g8ed1b From 9dfcb7599084382884fec6d0fd9ca33945fa7578 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:45 +0200 Subject: libperf: Move fd array from perf's evsel to lobperf's perf_evsel class Move the fd array from perf's evsel to libperf's perf_evsel class. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-59-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/internal/evsel.h | 1 + tools/perf/util/bpf-loader.c | 2 +- tools/perf/util/evlist.c | 10 +++++----- tools/perf/util/evsel.c | 30 +++++++++++++++--------------- tools/perf/util/evsel.h | 1 - 5 files changed, 22 insertions(+), 22 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h index 8340fd883a3d..df4078194e9a 100644 --- a/tools/perf/lib/include/internal/evsel.h +++ b/tools/perf/lib/include/internal/evsel.h @@ -14,6 +14,7 @@ struct perf_evsel { struct perf_cpu_map *cpus; struct perf_cpu_map *own_cpus; struct perf_thread_map *threads; + struct xyarray *fd; }; #endif /* __LIBPERF_INTERNAL_EVSEL_H */ diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index 4df8bdea14ac..9c219d413e57 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -1403,7 +1403,7 @@ static int apply_config_evsel_for_key(const char *name, int map_fd, void *pkey, struct evsel *evsel) { - struct xyarray *xy = evsel->fd; + struct xyarray *xy = evsel->core.fd; struct perf_event_attr *attr; unsigned int key, events; bool check_pass = false; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4433b656cfb7..e4b1a9914ea4 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -40,7 +40,7 @@ int sigqueue(pid_t pid, int sig, const union sigval value); #endif -#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) +#define FD(e, x, y) (*(int *)xyarray__entry(e->core.fd, x, y)) #define SID(e, x, y) xyarray__entry(e->sample_id, x, y) void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, @@ -321,7 +321,7 @@ void evlist__disable(struct evlist *evlist) struct evsel *pos; evlist__for_each_entry(evlist, pos) { - if (pos->disabled || !perf_evsel__is_group_leader(pos) || !pos->fd) + if (pos->disabled || !perf_evsel__is_group_leader(pos) || !pos->core.fd) continue; evsel__disable(pos); } @@ -334,7 +334,7 @@ void evlist__enable(struct evlist *evlist) struct evsel *pos; evlist__for_each_entry(evlist, pos) { - if (!perf_evsel__is_group_leader(pos) || !pos->fd) + if (!perf_evsel__is_group_leader(pos) || !pos->core.fd) continue; evsel__enable(pos); } @@ -353,7 +353,7 @@ static int perf_evlist__enable_event_cpu(struct evlist *evlist, int thread; int nr_threads = perf_evlist__nr_threads(evlist, evsel); - if (!evsel->fd) + if (!evsel->core.fd) return -EINVAL; for (thread = 0; thread < nr_threads; thread++) { @@ -371,7 +371,7 @@ static int perf_evlist__enable_event_thread(struct evlist *evlist, int cpu; int nr_cpus = cpu_map__nr(evlist->core.cpus); - if (!evsel->fd) + if (!evsel->core.fd) return -EINVAL; for (cpu = 0; cpu < nr_cpus; cpu++) { diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index f7758ce0dd5c..8d087d0e55f1 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -90,7 +90,7 @@ set_methods: return 0; } -#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) +#define FD(e, x, y) (*(int *)xyarray__entry(e->core.fd, x, y)) int __perf_evsel__sample_size(u64 sample_type) { @@ -1155,9 +1155,9 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts, static int perf_evsel__alloc_fd(struct evsel *evsel, int ncpus, int nthreads) { - evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int)); + evsel->core.fd = xyarray__new(ncpus, nthreads, sizeof(int)); - if (evsel->fd) { + if (evsel->core.fd) { int cpu, thread; for (cpu = 0; cpu < ncpus; cpu++) { for (thread = 0; thread < nthreads; thread++) { @@ -1166,7 +1166,7 @@ static int perf_evsel__alloc_fd(struct evsel *evsel, int ncpus, int nthreads) } } - return evsel->fd != NULL ? 0 : -ENOMEM; + return evsel->core.fd != NULL ? 0 : -ENOMEM; } static int perf_evsel__run_ioctl(struct evsel *evsel, @@ -1174,8 +1174,8 @@ static int perf_evsel__run_ioctl(struct evsel *evsel, { int cpu, thread; - for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) { - for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) { + for (cpu = 0; cpu < xyarray__max_x(evsel->core.fd); cpu++) { + for (thread = 0; thread < xyarray__max_y(evsel->core.fd); thread++) { int fd = FD(evsel, cpu, thread), err = ioctl(fd, ioc, arg); @@ -1283,8 +1283,8 @@ int perf_evsel__alloc_id(struct evsel *evsel, int ncpus, int nthreads) static void perf_evsel__free_fd(struct evsel *evsel) { - xyarray__delete(evsel->fd); - evsel->fd = NULL; + xyarray__delete(evsel->core.fd); + evsel->core.fd = NULL; } static void perf_evsel__free_id(struct evsel *evsel) @@ -1309,8 +1309,8 @@ void perf_evsel__close_fd(struct evsel *evsel) { int cpu, thread; - for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) - for (thread = 0; thread < xyarray__max_y(evsel->fd); ++thread) { + for (cpu = 0; cpu < xyarray__max_x(evsel->core.fd); cpu++) + for (thread = 0; thread < xyarray__max_y(evsel->core.fd); ++thread) { close(FD(evsel, cpu, thread)); FD(evsel, cpu, thread) = -1; } @@ -1555,7 +1555,7 @@ static int get_group_fd(struct evsel *evsel, int cpu, int thread) * Leader must be already processed/open, * if not it's a bug. */ - BUG_ON(!leader->fd); + BUG_ON(!leader->core.fd); fd = FD(leader, cpu, thread); BUG_ON(fd == -1); @@ -1865,7 +1865,7 @@ int evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus, else nthreads = threads->nr; - if (evsel->fd == NULL && + if (evsel->core.fd == NULL && perf_evsel__alloc_fd(evsel, cpus->nr, nthreads) < 0) return -ENOMEM; @@ -2075,7 +2075,7 @@ out_close: void perf_evsel__close(struct evsel *evsel) { - if (evsel->fd == NULL) + if (evsel->core.fd == NULL) return; perf_evsel__close_fd(evsel); @@ -3048,8 +3048,8 @@ static int store_evsel_ids(struct evsel *evsel, struct evlist *evlist) { int cpu, thread; - for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) { - for (thread = 0; thread < xyarray__max_y(evsel->fd); + for (cpu = 0; cpu < xyarray__max_x(evsel->core.fd); cpu++) { + for (thread = 0; thread < xyarray__max_y(evsel->core.fd); thread++) { int fd = FD(evsel, cpu, thread); diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 1f9f66fe43f4..6056ce64bfdf 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -104,7 +104,6 @@ struct evsel { struct perf_evsel core; struct evlist *evlist; char *filter; - struct xyarray *fd; struct xyarray *sample_id; u64 *id; struct perf_counts *counts; -- cgit v1.2.3-59-g8ed1b From 5643b1a59e581ac3f66d36caba8124313cc446c0 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:46 +0200 Subject: libperf: Move nr_members from perf's evsel to libperf's perf_evsel Move the nr_members member from perf's evsel to libperf's perf_evsel. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-60-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-report.c | 2 +- tools/perf/builtin-script.c | 2 +- tools/perf/builtin-stat.c | 2 +- tools/perf/lib/include/internal/evsel.h | 3 +++ tools/perf/tests/parse-events.c | 22 +++++++++++----------- tools/perf/ui/gtk/annotate.c | 2 +- tools/perf/ui/gtk/hists.c | 2 +- tools/perf/ui/hist.c | 6 +++--- tools/perf/util/annotate.c | 8 ++++---- tools/perf/util/evlist.c | 6 +++--- tools/perf/util/evsel.c | 6 +++--- tools/perf/util/evsel.h | 3 +-- tools/perf/util/evsel_fprintf.c | 4 ++-- tools/perf/util/header.c | 12 ++++++------ tools/perf/util/hist.c | 2 +- tools/perf/util/parse-events.c | 2 +- tools/perf/util/stat-display.c | 2 +- tools/perf/util/stat.c | 2 +- 18 files changed, 45 insertions(+), 43 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index e258e988c55b..d4288dcce156 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -436,7 +436,7 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report ret = fprintf(fp, "# Samples: %lu%c", nr_samples, unit); if (evname != NULL) { ret += fprintf(fp, " of event%s '%s'", - evsel->nr_members > 1 ? "s" : "", evname); + evsel->core.nr_members > 1 ? "s" : "", evname); } if (rep->time_str) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 46fadbbe1c3e..31a529ec139f 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1734,7 +1734,7 @@ static void perf_sample__fprint_metric(struct perf_script *script, sample->cpu, &rt_stat); evsel_script(evsel)->val = val; - if (evsel_script(evsel->leader)->gnum == evsel->leader->nr_members) { + if (evsel_script(evsel->leader)->gnum == evsel->leader->core.nr_members) { for_each_group_member (ev2, evsel->leader) { perf_stat__print_shadow_stats(&stat_config, ev2, evsel_script(ev2)->val, diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 14e4c970d16a..b19df671111e 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -479,7 +479,7 @@ try_again: counter->supported = false; if ((counter->leader != counter) || - !(counter->leader->nr_members > 1)) + !(counter->leader->core.nr_members > 1)) continue; } else if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) { if (verbose > 0) diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h index df4078194e9a..29eca9576546 100644 --- a/tools/perf/lib/include/internal/evsel.h +++ b/tools/perf/lib/include/internal/evsel.h @@ -15,6 +15,9 @@ struct perf_evsel { struct perf_cpu_map *own_cpus; struct perf_thread_map *threads; struct xyarray *fd; + + /* parse modifier helper */ + int nr_members; }; #endif /* __LIBPERF_INTERNAL_EVSEL_H */ diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 5b4a5a3dac50..49f52e4de41b 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -653,7 +653,7 @@ static int test__group1(struct evlist *evlist) TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); - TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); + TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0); TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read); @@ -695,7 +695,7 @@ static int test__group2(struct evlist *evlist) TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); - TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); + TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0); TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read); @@ -753,7 +753,7 @@ static int test__group3(struct evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); TEST_ASSERT_VAL("wrong group name", !strcmp(leader->group_name, "group1")); - TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); + TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0); TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read); @@ -788,7 +788,7 @@ static int test__group3(struct evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); TEST_ASSERT_VAL("wrong group name", !strcmp(leader->group_name, "group2")); - TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); + TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0); TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read); @@ -844,7 +844,7 @@ static int test__group4(struct evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip == 1); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); - TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); + TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0); TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read); @@ -887,7 +887,7 @@ static int test__group5(struct evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); - TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); + TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0); TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read); @@ -919,7 +919,7 @@ static int test__group5(struct evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); - TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); + TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0); TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read); @@ -973,7 +973,7 @@ static int test__group_gh1(struct evlist *evlist) TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); - TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); + TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0); /* cache-misses:G + :H group modifier */ @@ -1013,7 +1013,7 @@ static int test__group_gh2(struct evlist *evlist) TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); - TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); + TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0); /* cache-misses:H + :G group modifier */ @@ -1053,7 +1053,7 @@ static int test__group_gh3(struct evlist *evlist) TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); - TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); + TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0); /* cache-misses:H + :u group modifier */ @@ -1093,7 +1093,7 @@ static int test__group_gh4(struct evlist *evlist) TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel)); - TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2); + TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2); TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0); /* cache-misses:H + :uG group modifier */ diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c index 40e263a730e4..d7f984436dec 100644 --- a/tools/perf/ui/gtk/annotate.c +++ b/tools/perf/ui/gtk/annotate.c @@ -129,7 +129,7 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym, gtk_list_store_append(store, &iter); if (perf_evsel__is_group_event(evsel)) { - for (i = 0; i < evsel->nr_members; i++) { + for (i = 0; i < evsel->core.nr_members; i++) { ret += perf_gtk__get_percent(s + ret, sizeof(s) - ret, sym, pos, diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index 1b181d8ea953..0efdb226d1a7 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c @@ -645,7 +645,7 @@ int perf_evlist__gtk_browse_hists(struct evlist *evlist, if (!perf_evsel__is_group_leader(pos)) continue; - if (pos->nr_members > 1) { + if (pos->core.nr_members > 1) { perf_evsel__group_desc(pos, buf, size); evname = buf; } diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 8c7fb11edc60..e5fb64347b2c 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -43,7 +43,7 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, if (perf_evsel__is_group_event(evsel)) { int prev_idx, idx_delta; struct hist_entry *pair; - int nr_members = evsel->nr_members; + int nr_members = evsel->core.nr_members; prev_idx = perf_evsel__group_idx(evsel); @@ -165,7 +165,7 @@ static int __hpp__sort(struct hist_entry *a, struct hist_entry *b, if (!perf_evsel__is_group_event(evsel)) return ret; - nr_members = evsel->nr_members; + nr_members = evsel->core.nr_members; fields_a = calloc(nr_members, sizeof(*fields_a)); fields_b = calloc(nr_members, sizeof(*fields_b)); @@ -226,7 +226,7 @@ static int hpp__width_fn(struct perf_hpp_fmt *fmt, struct evsel *evsel = hists_to_evsel(hists); if (symbol_conf.event_group) - len = max(len, evsel->nr_members * fmt->len); + len = max(len, evsel->core.nr_members * fmt->len); if (len < (int)strlen(fmt->name)) len = strlen(fmt->name); diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index d46f2ae2c695..91d4fc3e78cf 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1170,7 +1170,7 @@ annotation_line__new(struct annotate_args *args, size_t privsize) int nr = 1; if (perf_evsel__is_group_event(evsel)) - nr = evsel->nr_members; + nr = evsel->core.nr_members; size += sizeof(al->data[0]) * nr; @@ -1448,7 +1448,7 @@ annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start return -1; if (perf_evsel__is_group_event(evsel)) - width *= evsel->nr_members; + width *= evsel->core.nr_members; if (!*al->line) printf(" %*s:\n", width, " "); @@ -2272,7 +2272,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, len = symbol__size(sym); if (perf_evsel__is_group_event(evsel)) { - width *= evsel->nr_members; + width *= evsel->core.nr_members; perf_evsel__group_desc(evsel, buf, sizeof(buf)); evsel_name = buf; } @@ -2968,7 +2968,7 @@ int symbol__annotate2(struct symbol *sym, struct map *map, struct evsel *evsel, return -1; if (perf_evsel__is_group_event(evsel)) - nr_pcnt = evsel->nr_members; + nr_pcnt = evsel->core.nr_members; err = symbol__annotate(sym, map, evsel, 0, options, parch); if (err) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index e4b1a9914ea4..eac4d634b9c7 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -188,7 +188,7 @@ void __perf_evlist__set_leader(struct list_head *list) leader = list_entry(list->next, struct evsel, core.node); evsel = list_entry(list->prev, struct evsel, core.node); - leader->nr_members = evsel->idx - leader->idx + 1; + leader->core.nr_members = evsel->idx - leader->idx + 1; __evlist__for_each_entry(list, evsel) { evsel->leader = leader; @@ -1761,7 +1761,7 @@ struct evsel *perf_evlist__reset_weak_group(struct evlist *evsel_list, leader = evsel->leader; pr_debug("Weak group for %s/%d failed\n", - leader->name, leader->nr_members); + leader->name, leader->core.nr_members); /* * for_each_group_member doesn't work here because it doesn't @@ -1774,7 +1774,7 @@ struct evsel *perf_evlist__reset_weak_group(struct evlist *evsel_list, if (is_open) perf_evsel__close(c2); c2->leader = c2; - c2->nr_members = 0; + c2->core.nr_members = 0; } } return leader; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 8d087d0e55f1..8b9a00598677 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -948,7 +948,7 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts, * Apply group format only if we belong to group * with more than one members. */ - if (leader->nr_members > 1) { + if (leader->core.nr_members > 1) { attr->read_format |= PERF_FORMAT_GROUP; attr->inherit = 0; } @@ -1396,7 +1396,7 @@ static int perf_evsel__read_size(struct evsel *evsel) entry += sizeof(u64); if (read_format & PERF_FORMAT_GROUP) { - nr = evsel->nr_members; + nr = evsel->core.nr_members; size += sizeof(u64); } @@ -1453,7 +1453,7 @@ perf_evsel__process_group_data(struct evsel *leader, nr = *data++; - if (nr != (u64) leader->nr_members) + if (nr != (u64) leader->core.nr_members) return -EINVAL; if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 6056ce64bfdf..afd3a5b7bcc3 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -142,7 +142,6 @@ struct evsel { bool use_uncore_alias; /* parse modifier helper */ int exclude_GH; - int nr_members; int sample_read; unsigned long *per_pkg_mask; struct evsel *leader; @@ -414,7 +413,7 @@ static inline bool perf_evsel__is_group_event(struct evsel *evsel) if (!symbol_conf.event_group) return false; - return perf_evsel__is_group_leader(evsel) && evsel->nr_members > 1; + return perf_evsel__is_group_leader(evsel) && evsel->core.nr_members > 1; } bool perf_evsel__is_function_event(struct evsel *evsel); diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c index 3466eca34a00..496fec01f5d1 100644 --- a/tools/perf/util/evsel_fprintf.c +++ b/tools/perf/util/evsel_fprintf.c @@ -45,14 +45,14 @@ int perf_evsel__fprintf(struct evsel *evsel, if (!perf_evsel__is_group_leader(evsel)) return 0; - if (evsel->nr_members > 1) + if (evsel->core.nr_members > 1) printed += fprintf(fp, "%s{", evsel->group_name ?: ""); printed += fprintf(fp, "%s", perf_evsel__name(evsel)); for_each_group_member(pos, evsel) printed += fprintf(fp, ",%s", perf_evsel__name(pos)); - if (evsel->nr_members > 1) + if (evsel->core.nr_members > 1) printed += fprintf(fp, "}"); goto out; } diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index f97df418d661..b04c2b6b28b3 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -772,10 +772,10 @@ static int write_group_desc(struct feat_fd *ff, evlist__for_each_entry(evlist, evsel) { if (perf_evsel__is_group_leader(evsel) && - evsel->nr_members > 1) { + evsel->core.nr_members > 1) { const char *name = evsel->group_name ?: "{anon_group}"; u32 leader_idx = evsel->idx; - u32 nr_members = evsel->nr_members; + u32 nr_members = evsel->core.nr_members; ret = do_write_string(ff, name); if (ret < 0) @@ -1812,11 +1812,11 @@ static void print_group_desc(struct feat_fd *ff, FILE *fp) evlist__for_each_entry(session->evlist, evsel) { if (perf_evsel__is_group_leader(evsel) && - evsel->nr_members > 1) { + evsel->core.nr_members > 1) { fprintf(fp, "# group: %s{%s", evsel->group_name ?: "", perf_evsel__name(evsel)); - nr = evsel->nr_members - 1; + nr = evsel->core.nr_members - 1; } else if (nr) { fprintf(fp, ",%s", perf_evsel__name(evsel)); @@ -2463,7 +2463,7 @@ static int process_group_desc(struct feat_fd *ff, void *data __maybe_unused) evsel->group_name = desc[i].name; desc[i].name = NULL; } - evsel->nr_members = desc[i].nr_members; + evsel->core.nr_members = desc[i].nr_members; if (i >= nr_groups || nr > 0) { pr_debug("invalid group desc\n"); @@ -2471,7 +2471,7 @@ static int process_group_desc(struct feat_fd *ff, void *data __maybe_unused) } leader = evsel; - nr = evsel->nr_members - 1; + nr = evsel->core.nr_members - 1; i++; } else if (nr) { /* This is a group member */ diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 821e0fe6cf26..4297f56b1e05 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -2643,7 +2643,7 @@ int __hists__scnprintf_title(struct hists *hists, char *bf, size_t size, bool sh nr_samples = convert_unit(nr_samples, &unit); printed = scnprintf(bf, size, "Samples: %lu%c of event%s '%s',%s%sEvent count (approx.): %" PRIu64, - nr_samples, unit, evsel->nr_members > 1 ? "s" : "", + nr_samples, unit, evsel->core.nr_members > 1 ? "s" : "", ev_name, sample_freq_str, enable_ref ? ref : " ", nr_events); diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 8182b1e66ec6..2cfec3b7a982 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1528,7 +1528,7 @@ parse_events__set_leader_for_uncore_aliase(char *name, struct list_head *list, /* The number of members and group name are same for each group */ for (i = 0; i < nr_pmu; i++) { evsel = (struct evsel *) leaders[i]; - evsel->nr_members = total_members / nr_pmu; + evsel->core.nr_members = total_members / nr_pmu; evsel->group_name = name ? strdup(name) : NULL; } diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 4a162858583f..f7b39f4bc51e 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -369,7 +369,7 @@ static bool is_mixed_hw_group(struct evsel *counter) u32 pmu_type = counter->core.attr.type; struct evsel *pos; - if (counter->nr_members < 2) + if (counter->core.nr_members < 2) return false; evlist__for_each_entry(evlist, pos) { diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 799f3c0a9050..e4e4e3bf8b2b 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -452,7 +452,7 @@ int create_perf_stat_counter(struct evsel *evsel, * the group read (for leader) and ID retrieval for all * members. */ - if (leader->nr_members > 1) + if (leader->core.nr_members > 1) attr->read_format |= PERF_FORMAT_ID|PERF_FORMAT_GROUP; attr->inherit = !config->no_inherit; -- cgit v1.2.3-59-g8ed1b From c03538b1f1a7e0e996a8d6feb20cf001d4b14939 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:47 +0200 Subject: libperf: Adopt the readn()/writen() functions from tools/perf Move the readn()/writen() functions into libperf. Keep those non-namespaced names because they will be shared only between perf and libperf. Again, these are not exported functions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-61-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/Build | 1 + tools/perf/lib/include/internal/lib.h | 10 ++++++++ tools/perf/lib/lib.c | 46 +++++++++++++++++++++++++++++++++++ tools/perf/util/util.c | 40 ------------------------------ tools/perf/util/util.h | 4 +-- 5 files changed, 58 insertions(+), 43 deletions(-) create mode 100644 tools/perf/lib/include/internal/lib.h create mode 100644 tools/perf/lib/lib.c (limited to 'tools') diff --git a/tools/perf/lib/Build b/tools/perf/lib/Build index 4f78ec0b4e10..c31f1c111f8f 100644 --- a/tools/perf/lib/Build +++ b/tools/perf/lib/Build @@ -5,6 +5,7 @@ libperf-y += evsel.o libperf-y += evlist.o libperf-y += zalloc.o libperf-y += xyarray.o +libperf-y += lib.o $(OUTPUT)zalloc.o: ../../lib/zalloc.c FORCE $(call rule_mkdir) diff --git a/tools/perf/lib/include/internal/lib.h b/tools/perf/lib/include/internal/lib.h new file mode 100644 index 000000000000..0b56f1201dc9 --- /dev/null +++ b/tools/perf/lib/include/internal/lib.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LIBPERF_INTERNAL_LIB_H +#define __LIBPERF_INTERNAL_LIB_H + +#include + +ssize_t readn(int fd, void *buf, size_t n); +ssize_t writen(int fd, const void *buf, size_t n); + +#endif /* __LIBPERF_INTERNAL_CPUMAP_H */ diff --git a/tools/perf/lib/lib.c b/tools/perf/lib/lib.c new file mode 100644 index 000000000000..2a81819c3b8c --- /dev/null +++ b/tools/perf/lib/lib.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include + +static ssize_t ion(bool is_read, int fd, void *buf, size_t n) +{ + void *buf_start = buf; + size_t left = n; + + while (left) { + /* buf must be treated as const if !is_read. */ + ssize_t ret = is_read ? read(fd, buf, left) : + write(fd, buf, left); + + if (ret < 0 && errno == EINTR) + continue; + if (ret <= 0) + return ret; + + left -= ret; + buf += ret; + } + + BUG_ON((size_t)(buf - buf_start) != n); + return n; +} + +/* + * Read exactly 'n' bytes or return an error. + */ +ssize_t readn(int fd, void *buf, size_t n) +{ + return ion(true, fd, buf, n); +} + +/* + * Write exactly 'n' bytes or return an error. + */ +ssize_t writen(int fd, const void *buf, size_t n) +{ + /* ion does not modify buf. */ + return ion(false, fd, (void *)buf, n); +} diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index a61535cf1bca..9c3c97697387 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -384,46 +384,6 @@ int copyfile(const char *from, const char *to) return copyfile_mode(from, to, 0755); } -static ssize_t ion(bool is_read, int fd, void *buf, size_t n) -{ - void *buf_start = buf; - size_t left = n; - - while (left) { - /* buf must be treated as const if !is_read. */ - ssize_t ret = is_read ? read(fd, buf, left) : - write(fd, buf, left); - - if (ret < 0 && errno == EINTR) - continue; - if (ret <= 0) - return ret; - - left -= ret; - buf += ret; - } - - BUG_ON((size_t)(buf - buf_start) != n); - return n; -} - -/* - * Read exactly 'n' bytes or return an error. - */ -ssize_t readn(int fd, void *buf, size_t n) -{ - return ion(true, fd, buf, n); -} - -/* - * Write exactly 'n' bytes or return an error. - */ -ssize_t writen(int fd, const void *buf, size_t n) -{ - /* ion does not modify buf. */ - return ion(false, fd, (void *)buf, n); -} - size_t hex_width(u64 v) { size_t n = 1; diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index dc7a469921e9..0dab140c6517 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -11,6 +11,7 @@ #include #include #include +#include /* General helper functions */ void usage(const char *err) __noreturn; @@ -30,9 +31,6 @@ int copyfile_mode(const char *from, const char *to, mode_t mode); int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi); int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size); -ssize_t readn(int fd, void *buf, size_t n); -ssize_t writen(int fd, const void *buf, size_t n); - size_t hex_width(u64 v); extern unsigned int page_size; -- cgit v1.2.3-59-g8ed1b From b8eca4d761c57fcf691a8063cd562f205645d11f Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:48 +0200 Subject: libperf: Adopt perf_evsel__alloc_fd() function from tools/perf Move the perf_evsel__alloc_fd() function from perf to libperf. It's not exported. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-62-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evsel.c | 21 +++++++++++++++++++++ tools/perf/lib/include/internal/evsel.h | 2 ++ tools/perf/util/evsel.c | 18 +----------------- 3 files changed, 24 insertions(+), 17 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/evsel.c b/tools/perf/lib/evsel.c index ddc3ad447bfb..027f1edb4e8e 100644 --- a/tools/perf/lib/evsel.c +++ b/tools/perf/lib/evsel.c @@ -1,9 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include #include #include #include #include +#include +#include void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr) { @@ -25,3 +28,21 @@ void perf_evsel__delete(struct perf_evsel *evsel) { free(evsel); } + +#define FD(e, x, y) (*(int *) xyarray__entry(e->fd, x, y)) + +int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) +{ + evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int)); + + if (evsel->fd) { + int cpu, thread; + for (cpu = 0; cpu < ncpus; cpu++) { + for (thread = 0; thread < nthreads; thread++) { + FD(evsel, cpu, thread) = -1; + } + } + } + + return evsel->fd != NULL ? 0 : -ENOMEM; +} diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h index 29eca9576546..3cb9a0f5f32e 100644 --- a/tools/perf/lib/include/internal/evsel.h +++ b/tools/perf/lib/include/internal/evsel.h @@ -20,4 +20,6 @@ struct perf_evsel { int nr_members; }; +int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); + #endif /* __LIBPERF_INTERNAL_EVSEL_H */ diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 8b9a00598677..d3c8488f7069 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1153,22 +1153,6 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts, perf_evsel__reset_sample_bit(evsel, BRANCH_STACK); } -static int perf_evsel__alloc_fd(struct evsel *evsel, int ncpus, int nthreads) -{ - evsel->core.fd = xyarray__new(ncpus, nthreads, sizeof(int)); - - if (evsel->core.fd) { - int cpu, thread; - for (cpu = 0; cpu < ncpus; cpu++) { - for (thread = 0; thread < nthreads; thread++) { - FD(evsel, cpu, thread) = -1; - } - } - } - - return evsel->core.fd != NULL ? 0 : -ENOMEM; -} - static int perf_evsel__run_ioctl(struct evsel *evsel, int ioc, void *arg) { @@ -1866,7 +1850,7 @@ int evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus, nthreads = threads->nr; if (evsel->core.fd == NULL && - perf_evsel__alloc_fd(evsel, cpus->nr, nthreads) < 0) + perf_evsel__alloc_fd(&evsel->core, cpus->nr, nthreads) < 0) return -ENOMEM; if (evsel->cgrp) { -- cgit v1.2.3-59-g8ed1b From 50a4e6fa450c4e5b688814a7ec8236d0de6e38bf Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:49 +0200 Subject: libperf: Adopt simplified perf_evsel__open() function from tools/perf Add a perf_evsel__open() function to libperf. It's a simplified version of evsel__open() without the fallback mechanism. We can try to merge it in the future to libperf, but it has many details, lets start simple, requiring the latest kernel, perf should continue using its evsel__open() version, continuing to support running on older kernels when possible. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-63-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evsel.c | 65 +++++++++++++++++++++++++++++++++++++ tools/perf/lib/include/perf/evsel.h | 4 +++ tools/perf/lib/libperf.map | 1 + 3 files changed, 70 insertions(+) (limited to 'tools') diff --git a/tools/perf/lib/evsel.c b/tools/perf/lib/evsel.c index 027f1edb4e8e..7027dacb50f6 100644 --- a/tools/perf/lib/evsel.c +++ b/tools/perf/lib/evsel.c @@ -1,11 +1,17 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include +#include #include +#include +#include #include #include #include #include #include +#include +#include #include void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr) @@ -46,3 +52,62 @@ int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) return evsel->fd != NULL ? 0 : -ENOMEM; } + +static int +sys_perf_event_open(struct perf_event_attr *attr, + pid_t pid, int cpu, int group_fd, + unsigned long flags) +{ + return syscall(__NR_perf_event_open, attr, pid, cpu, group_fd, flags); +} + +int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus, + struct perf_thread_map *threads) +{ + int cpu, thread, err = 0; + + if (cpus == NULL) { + static struct perf_cpu_map *empty_cpu_map; + + if (empty_cpu_map == NULL) { + empty_cpu_map = perf_cpu_map__dummy_new(); + if (empty_cpu_map == NULL) + return -ENOMEM; + } + + cpus = empty_cpu_map; + } + + if (threads == NULL) { + static struct perf_thread_map *empty_thread_map; + + if (empty_thread_map == NULL) { + empty_thread_map = perf_thread_map__new_dummy(); + if (empty_thread_map == NULL) + return -ENOMEM; + } + + threads = empty_thread_map; + } + + if (evsel->fd == NULL && + perf_evsel__alloc_fd(evsel, cpus->nr, threads->nr) < 0) + return -ENOMEM; + + for (cpu = 0; cpu < cpus->nr; cpu++) { + for (thread = 0; thread < threads->nr; thread++) { + int fd; + + fd = sys_perf_event_open(&evsel->attr, + threads->map[thread].pid, + cpus->map[cpu], -1, 0); + + if (fd < 0) + return -errno; + + FD(evsel, cpu, thread) = fd; + } + } + + return err; +} diff --git a/tools/perf/lib/include/perf/evsel.h b/tools/perf/lib/include/perf/evsel.h index a57efc0f5c8b..e9fbaa8fb51a 100644 --- a/tools/perf/lib/include/perf/evsel.h +++ b/tools/perf/lib/include/perf/evsel.h @@ -6,10 +6,14 @@ struct perf_evsel; struct perf_event_attr; +struct perf_cpu_map; +struct perf_thread_map; LIBPERF_API void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr); LIBPERF_API struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr); LIBPERF_API void perf_evsel__delete(struct perf_evsel *evsel); +LIBPERF_API int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus, + struct perf_thread_map *threads); #endif /* __LIBPERF_EVSEL_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 9b6e8f165014..7594d3d89c5f 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -14,6 +14,7 @@ LIBPERF_0.0.1 { perf_evsel__new; perf_evsel__delete; perf_evsel__init; + perf_evsel__open; perf_evlist__new; perf_evlist__delete; perf_evlist__init; -- cgit v1.2.3-59-g8ed1b From 88761fa1f1e3fb2df86727ac99f88abf2ac7e00b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:50 +0200 Subject: libperf: Adopt simplified perf_evsel__close() function from tools/perf Add perf_evsel__close() function to libperf while keeping a tools/perf specific evsel__close() to free ids. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-64-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 2 +- tools/perf/lib/evsel.c | 26 ++++++++++++++++++++++++++ tools/perf/lib/include/internal/evsel.h | 2 ++ tools/perf/lib/include/perf/evsel.h | 1 + tools/perf/lib/libperf.map | 1 + tools/perf/tests/openat-syscall-all-cpus.c | 2 +- tools/perf/tests/openat-syscall.c | 2 +- tools/perf/util/evlist.c | 5 +++-- tools/perf/util/evsel.c | 27 +++------------------------ tools/perf/util/evsel.h | 3 +-- 10 files changed, 40 insertions(+), 31 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 35f3684f5327..75eb3811e942 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2401,7 +2401,7 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel, if (evsel->max_events != ULONG_MAX && ++evsel->nr_events_printed == evsel->max_events) { evsel__disable(evsel); - perf_evsel__close(evsel); + evsel__close(evsel); } } } diff --git a/tools/perf/lib/evsel.c b/tools/perf/lib/evsel.c index 7027dacb50f6..50f09e939229 100644 --- a/tools/perf/lib/evsel.c +++ b/tools/perf/lib/evsel.c @@ -111,3 +111,29 @@ int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus, return err; } + +void perf_evsel__close_fd(struct perf_evsel *evsel) +{ + int cpu, thread; + + for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) + for (thread = 0; thread < xyarray__max_y(evsel->fd); ++thread) { + close(FD(evsel, cpu, thread)); + FD(evsel, cpu, thread) = -1; + } +} + +void perf_evsel__free_fd(struct perf_evsel *evsel) +{ + xyarray__delete(evsel->fd); + evsel->fd = NULL; +} + +void perf_evsel__close(struct perf_evsel *evsel) +{ + if (evsel->fd == NULL) + return; + + perf_evsel__close_fd(evsel); + perf_evsel__free_fd(evsel); +} diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h index 3cb9a0f5f32e..878e2cf41ffc 100644 --- a/tools/perf/lib/include/internal/evsel.h +++ b/tools/perf/lib/include/internal/evsel.h @@ -21,5 +21,7 @@ struct perf_evsel { }; int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); +void perf_evsel__close_fd(struct perf_evsel *evsel); +void perf_evsel__free_fd(struct perf_evsel *evsel); #endif /* __LIBPERF_INTERNAL_EVSEL_H */ diff --git a/tools/perf/lib/include/perf/evsel.h b/tools/perf/lib/include/perf/evsel.h index e9fbaa8fb51a..aa5c48f822d2 100644 --- a/tools/perf/lib/include/perf/evsel.h +++ b/tools/perf/lib/include/perf/evsel.h @@ -15,5 +15,6 @@ LIBPERF_API struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr); LIBPERF_API void perf_evsel__delete(struct perf_evsel *evsel); LIBPERF_API int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus, struct perf_thread_map *threads); +LIBPERF_API void perf_evsel__close(struct perf_evsel *evsel); #endif /* __LIBPERF_EVSEL_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 7594d3d89c5f..0b90999dcdcb 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -15,6 +15,7 @@ LIBPERF_0.0.1 { perf_evsel__delete; perf_evsel__init; perf_evsel__open; + perf_evsel__close; perf_evlist__new; perf_evlist__delete; perf_evlist__init; diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index d161b1a78703..8322b6aa4047 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -116,7 +116,7 @@ int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int perf_evsel__free_counts(evsel); out_close_fd: - perf_evsel__close_fd(evsel); + perf_evsel__close_fd(&evsel->core); out_evsel_delete: evsel__delete(evsel); out_cpu_map_delete: diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c index 87c212545767..f217972977e0 100644 --- a/tools/perf/tests/openat-syscall.c +++ b/tools/perf/tests/openat-syscall.c @@ -57,7 +57,7 @@ int test__openat_syscall_event(struct test *test __maybe_unused, int subtest __m err = 0; out_close_fd: - perf_evsel__close_fd(evsel); + perf_evsel__close_fd(&evsel->core); out_evsel_delete: evsel__delete(evsel); out_thread_map_delete: diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index eac4d634b9c7..c6b4883b2d49 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #ifdef LACKS_SIGQUEUE_PROTOTYPE @@ -1303,7 +1304,7 @@ void evlist__close(struct evlist *evlist) struct evsel *evsel; evlist__for_each_entry_reverse(evlist, evsel) - perf_evsel__close(evsel); + evsel__close(evsel); } static int perf_evlist__create_syswide_maps(struct evlist *evlist) @@ -1772,7 +1773,7 @@ struct evsel *perf_evlist__reset_weak_group(struct evlist *evsel_list, is_open = false; if (c2->leader == leader) { if (is_open) - perf_evsel__close(c2); + evsel__close(c2); c2->leader = c2; c2->core.nr_members = 0; } diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index d3c8488f7069..8d8ed36377f5 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1265,12 +1265,6 @@ int perf_evsel__alloc_id(struct evsel *evsel, int ncpus, int nthreads) return 0; } -static void perf_evsel__free_fd(struct evsel *evsel) -{ - xyarray__delete(evsel->core.fd); - evsel->core.fd = NULL; -} - static void perf_evsel__free_id(struct evsel *evsel) { xyarray__delete(evsel->sample_id); @@ -1289,23 +1283,12 @@ static void perf_evsel__free_config_terms(struct evsel *evsel) } } -void perf_evsel__close_fd(struct evsel *evsel) -{ - int cpu, thread; - - for (cpu = 0; cpu < xyarray__max_x(evsel->core.fd); cpu++) - for (thread = 0; thread < xyarray__max_y(evsel->core.fd); ++thread) { - close(FD(evsel, cpu, thread)); - FD(evsel, cpu, thread) = -1; - } -} - void perf_evsel__exit(struct evsel *evsel) { assert(list_empty(&evsel->core.node)); assert(evsel->evlist == NULL); perf_evsel__free_counts(evsel); - perf_evsel__free_fd(evsel); + perf_evsel__free_fd(&evsel->core); perf_evsel__free_id(evsel); perf_evsel__free_config_terms(evsel); cgroup__put(evsel->cgrp); @@ -2057,13 +2040,9 @@ out_close: return err; } -void perf_evsel__close(struct evsel *evsel) +void evsel__close(struct evsel *evsel) { - if (evsel->core.fd == NULL) - return; - - perf_evsel__close_fd(evsel); - perf_evsel__free_fd(evsel); + perf_evsel__close(&evsel->core); perf_evsel__free_id(evsel); } diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index afd3a5b7bcc3..03fc8edad492 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -268,7 +268,6 @@ const char *perf_evsel__group_name(struct evsel *evsel); int perf_evsel__group_desc(struct evsel *evsel, char *buf, size_t size); int perf_evsel__alloc_id(struct evsel *evsel, int ncpus, int nthreads); -void perf_evsel__close_fd(struct evsel *evsel); void __perf_evsel__set_sample_bit(struct evsel *evsel, enum perf_event_sample_format bit); @@ -298,7 +297,7 @@ int perf_evsel__open_per_thread(struct evsel *evsel, struct perf_thread_map *threads); int evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus, struct perf_thread_map *threads); -void perf_evsel__close(struct evsel *evsel); +void evsel__close(struct evsel *evsel); struct perf_sample; -- cgit v1.2.3-59-g8ed1b From 5c30af92f2b1e9d844e1ae3243e4adcd7753d4c1 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:51 +0200 Subject: libperf: Adopt perf_evsel__read() function from tools/perf Move the perf_evsel__read() function to libperf as a public interface together with struct perf_counts_values for returning counter values. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-65-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evsel.c | 42 ++++++++++++++++++++++++++++++ tools/perf/lib/include/internal/evsel.h | 1 + tools/perf/lib/include/perf/evsel.h | 14 ++++++++++ tools/perf/lib/libperf.map | 1 + tools/perf/tests/event-times.c | 2 +- tools/perf/util/counts.h | 12 +-------- tools/perf/util/evsel.c | 45 ++------------------------------- tools/perf/util/evsel.h | 3 --- 8 files changed, 62 insertions(+), 58 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/evsel.c b/tools/perf/lib/evsel.c index 50f09e939229..390fcf9107c1 100644 --- a/tools/perf/lib/evsel.c +++ b/tools/perf/lib/evsel.c @@ -12,6 +12,7 @@ #include #include #include +#include #include void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr) @@ -137,3 +138,44 @@ void perf_evsel__close(struct perf_evsel *evsel) perf_evsel__close_fd(evsel); perf_evsel__free_fd(evsel); } + +int perf_evsel__read_size(struct perf_evsel *evsel) +{ + u64 read_format = evsel->attr.read_format; + int entry = sizeof(u64); /* value */ + int size = 0; + int nr = 1; + + if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) + size += sizeof(u64); + + if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) + size += sizeof(u64); + + if (read_format & PERF_FORMAT_ID) + entry += sizeof(u64); + + if (read_format & PERF_FORMAT_GROUP) { + nr = evsel->nr_members; + size += sizeof(u64); + } + + size += entry * nr; + return size; +} + +int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread, + struct perf_counts_values *count) +{ + size_t size = perf_evsel__read_size(evsel); + + memset(count, 0, sizeof(*count)); + + if (FD(evsel, cpu, thread) < 0) + return -EINVAL; + + if (readn(FD(evsel, cpu, thread), count->values, size) <= 0) + return -errno; + + return 0; +} diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h index 878e2cf41ffc..89bae3720d67 100644 --- a/tools/perf/lib/include/internal/evsel.h +++ b/tools/perf/lib/include/internal/evsel.h @@ -23,5 +23,6 @@ struct perf_evsel { int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); void perf_evsel__close_fd(struct perf_evsel *evsel); void perf_evsel__free_fd(struct perf_evsel *evsel); +int perf_evsel__read_size(struct perf_evsel *evsel); #endif /* __LIBPERF_INTERNAL_EVSEL_H */ diff --git a/tools/perf/lib/include/perf/evsel.h b/tools/perf/lib/include/perf/evsel.h index aa5c48f822d2..16ae3f873280 100644 --- a/tools/perf/lib/include/perf/evsel.h +++ b/tools/perf/lib/include/perf/evsel.h @@ -2,6 +2,7 @@ #ifndef __LIBPERF_EVSEL_H #define __LIBPERF_EVSEL_H +#include #include struct perf_evsel; @@ -9,6 +10,17 @@ struct perf_event_attr; struct perf_cpu_map; struct perf_thread_map; +struct perf_counts_values { + union { + struct { + uint64_t val; + uint64_t ena; + uint64_t run; + }; + uint64_t values[3]; + }; +}; + LIBPERF_API void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr); LIBPERF_API struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr); @@ -16,5 +28,7 @@ LIBPERF_API void perf_evsel__delete(struct perf_evsel *evsel); LIBPERF_API int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus, struct perf_thread_map *threads); LIBPERF_API void perf_evsel__close(struct perf_evsel *evsel); +LIBPERF_API int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread, + struct perf_counts_values *count); #endif /* __LIBPERF_EVSEL_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 0b90999dcdcb..2e23cf420cce 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -16,6 +16,7 @@ LIBPERF_0.0.1 { perf_evsel__init; perf_evsel__open; perf_evsel__close; + perf_evsel__read; perf_evlist__new; perf_evlist__delete; perf_evlist__init; diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 00adba86403b..714e3611352c 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -196,7 +196,7 @@ static int test_times(int (attach)(struct evlist *), TEST_ASSERT_VAL("failed to detach", !detach(evlist)); - perf_evsel__read(evsel, 0, 0, &count); + perf_evsel__read(&evsel->core, 0, 0, &count); err = !(count.ena == count.run); diff --git a/tools/perf/util/counts.h b/tools/perf/util/counts.h index bbfac9ecf642..13430f353c19 100644 --- a/tools/perf/util/counts.h +++ b/tools/perf/util/counts.h @@ -3,17 +3,7 @@ #define __PERF_COUNTS_H #include - -struct perf_counts_values { - union { - struct { - u64 val; - u64 ena; - u64 run; - }; - u64 values[3]; - }; -}; +#include struct perf_counts { s8 scaled; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 8d8ed36377f5..0957ec24f518 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1346,53 +1346,12 @@ void perf_counts_values__scale(struct perf_counts_values *count, *pscaled = scaled; } -static int perf_evsel__read_size(struct evsel *evsel) -{ - u64 read_format = evsel->core.attr.read_format; - int entry = sizeof(u64); /* value */ - int size = 0; - int nr = 1; - - if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) - size += sizeof(u64); - - if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) - size += sizeof(u64); - - if (read_format & PERF_FORMAT_ID) - entry += sizeof(u64); - - if (read_format & PERF_FORMAT_GROUP) { - nr = evsel->core.nr_members; - size += sizeof(u64); - } - - size += entry * nr; - return size; -} - -int perf_evsel__read(struct evsel *evsel, int cpu, int thread, - struct perf_counts_values *count) -{ - size_t size = perf_evsel__read_size(evsel); - - memset(count, 0, sizeof(*count)); - - if (FD(evsel, cpu, thread) < 0) - return -EINVAL; - - if (readn(FD(evsel, cpu, thread), count->values, size) <= 0) - return -errno; - - return 0; -} - static int perf_evsel__read_one(struct evsel *evsel, int cpu, int thread) { struct perf_counts_values *count = perf_counts(evsel->counts, cpu, thread); - return perf_evsel__read(evsel, cpu, thread, count); + return perf_evsel__read(&evsel->core, cpu, thread, count); } static void @@ -1453,7 +1412,7 @@ perf_evsel__read_group(struct evsel *leader, int cpu, int thread) { struct perf_stat_evsel *ps = leader->stats; u64 read_format = leader->core.attr.read_format; - int size = perf_evsel__read_size(leader); + int size = perf_evsel__read_size(&leader->core); u64 *data = ps->group_data; if (!(read_format & PERF_FORMAT_ID)) diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 03fc8edad492..57e315d8158e 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -336,9 +336,6 @@ static inline bool perf_evsel__match2(struct evsel *e1, (a)->core.attr.type == (b)->core.attr.type && \ (a)->core.attr.config == (b)->core.attr.config) -int perf_evsel__read(struct evsel *evsel, int cpu, int thread, - struct perf_counts_values *count); - int perf_evsel__read_counter(struct evsel *evsel, int cpu, int thread); int __perf_evsel__read_on_cpu(struct evsel *evsel, -- cgit v1.2.3-59-g8ed1b From a00571fda6091b5268d05e87d0797efe2db1920a Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:52 +0200 Subject: libperf: Adopt perf_evsel__enable()/disable()/apply_filter() functions Move the following functions: evsel__enable() evsel__disable() evsel__apply_filter() to libperf with the following names: perf_evsel__enable() perf_evsel__disable() perf_evsel__apply_filter() Export only perf_evsel__enable()/disable(), keeping the perf_evsel__apply_filter() one private for the moment. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-66-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evsel.c | 36 +++++++++++++++++++++++++++++++++ tools/perf/lib/include/internal/evsel.h | 1 + tools/perf/lib/include/perf/evsel.h | 2 ++ tools/perf/lib/libperf.map | 2 ++ tools/perf/util/evlist.c | 2 +- tools/perf/util/evsel.c | 29 ++------------------------ tools/perf/util/evsel.h | 1 - 7 files changed, 44 insertions(+), 29 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/evsel.c b/tools/perf/lib/evsel.c index 390fcf9107c1..c3f3722e9f91 100644 --- a/tools/perf/lib/evsel.c +++ b/tools/perf/lib/evsel.c @@ -14,6 +14,7 @@ #include #include #include +#include void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr) { @@ -179,3 +180,38 @@ int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread, return 0; } + +static int perf_evsel__run_ioctl(struct perf_evsel *evsel, + int ioc, void *arg) +{ + int cpu, thread; + + for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) { + for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) { + int fd = FD(evsel, cpu, thread), + err = ioctl(fd, ioc, arg); + + if (err) + return err; + } + } + + return 0; +} + +int perf_evsel__enable(struct perf_evsel *evsel) +{ + return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, 0); +} + +int perf_evsel__disable(struct perf_evsel *evsel) +{ + return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_DISABLE, 0); +} + +int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter) +{ + return perf_evsel__run_ioctl(evsel, + PERF_EVENT_IOC_SET_FILTER, + (void *)filter); +} diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h index 89bae3720d67..8b854d1c9b45 100644 --- a/tools/perf/lib/include/internal/evsel.h +++ b/tools/perf/lib/include/internal/evsel.h @@ -24,5 +24,6 @@ int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); void perf_evsel__close_fd(struct perf_evsel *evsel); void perf_evsel__free_fd(struct perf_evsel *evsel); int perf_evsel__read_size(struct perf_evsel *evsel); +int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter); #endif /* __LIBPERF_INTERNAL_EVSEL_H */ diff --git a/tools/perf/lib/include/perf/evsel.h b/tools/perf/lib/include/perf/evsel.h index 16ae3f873280..0db18dfabdb8 100644 --- a/tools/perf/lib/include/perf/evsel.h +++ b/tools/perf/lib/include/perf/evsel.h @@ -30,5 +30,7 @@ LIBPERF_API int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map * LIBPERF_API void perf_evsel__close(struct perf_evsel *evsel); LIBPERF_API int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread, struct perf_counts_values *count); +LIBPERF_API int perf_evsel__enable(struct perf_evsel *evsel); +LIBPERF_API int perf_evsel__disable(struct perf_evsel *evsel); #endif /* __LIBPERF_EVSEL_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 2e23cf420cce..5bd491ac1762 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -13,6 +13,8 @@ LIBPERF_0.0.1 { perf_thread_map__put; perf_evsel__new; perf_evsel__delete; + perf_evsel__enable; + perf_evsel__disable; perf_evsel__init; perf_evsel__open; perf_evsel__close; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index c6b4883b2d49..c4489a1ad6bc 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1109,7 +1109,7 @@ int perf_evlist__apply_filters(struct evlist *evlist, struct evsel **err_evsel) * filters only work for tracepoint event, which doesn't have cpu limit. * So evlist and evsel should always be same. */ - err = evsel__apply_filter(evsel, evsel->filter); + err = perf_evsel__apply_filter(&evsel->core, evsel->filter); if (err) { *err_evsel = evsel; break; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 0957ec24f518..64bc32ed6dfa 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1153,31 +1153,6 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts, perf_evsel__reset_sample_bit(evsel, BRANCH_STACK); } -static int perf_evsel__run_ioctl(struct evsel *evsel, - int ioc, void *arg) -{ - int cpu, thread; - - for (cpu = 0; cpu < xyarray__max_x(evsel->core.fd); cpu++) { - for (thread = 0; thread < xyarray__max_y(evsel->core.fd); thread++) { - int fd = FD(evsel, cpu, thread), - err = ioctl(fd, ioc, arg); - - if (err) - return err; - } - } - - return 0; -} - -int evsel__apply_filter(struct evsel *evsel, const char *filter) -{ - return perf_evsel__run_ioctl(evsel, - PERF_EVENT_IOC_SET_FILTER, - (void *)filter); -} - int perf_evsel__set_filter(struct evsel *evsel, const char *filter) { char *new_filter = strdup(filter); @@ -1220,7 +1195,7 @@ int perf_evsel__append_addr_filter(struct evsel *evsel, const char *filter) int evsel__enable(struct evsel *evsel) { - int err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, 0); + int err = perf_evsel__enable(&evsel->core); if (!err) evsel->disabled = false; @@ -1230,7 +1205,7 @@ int evsel__enable(struct evsel *evsel) int evsel__disable(struct evsel *evsel) { - int err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_DISABLE, 0); + int err = perf_evsel__disable(&evsel->core); /* * We mark it disabled here so that tools that disable a event can * ignore events after they disable it. I.e. the ring buffer may have diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 57e315d8158e..0989fb2eb1ec 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -287,7 +287,6 @@ int perf_evsel__set_filter(struct evsel *evsel, const char *filter); int perf_evsel__append_tp_filter(struct evsel *evsel, const char *filter); int perf_evsel__append_addr_filter(struct evsel *evsel, const char *filter); -int evsel__apply_filter(struct evsel *evsel, const char *filter); int evsel__enable(struct evsel *evsel); int evsel__disable(struct evsel *evsel); -- cgit v1.2.3-59-g8ed1b From 09145d26b608e886415396e9277ae08f0617d21b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:53 +0200 Subject: libperf: Add perf_cpu_map__for_each_cpu() macro Add the following macro to libperf: perf_cpu_map__for_each_cpu() And its related functions: perf_cpu_map__cpu() perf_cpu_map__nr() That will allow hiding how it is implemented. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-67-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/cpumap.c | 13 +++++++++++++ tools/perf/lib/include/perf/cpumap.h | 7 +++++++ tools/perf/lib/libperf.map | 2 ++ 3 files changed, 22 insertions(+) (limited to 'tools') diff --git a/tools/perf/lib/cpumap.c b/tools/perf/lib/cpumap.c index a5d4f7ff7174..1ddb69e796e5 100644 --- a/tools/perf/lib/cpumap.c +++ b/tools/perf/lib/cpumap.c @@ -224,3 +224,16 @@ invalid: out: return cpus; } + +int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx) +{ + if (idx < cpus->nr) + return cpus->map[idx]; + + return -1; +} + +int perf_cpu_map__nr(const struct perf_cpu_map *cpus) +{ + return cpus ? cpus->nr : 1; +} diff --git a/tools/perf/lib/include/perf/cpumap.h b/tools/perf/lib/include/perf/cpumap.h index b4a9283a5dfa..1b6e7db3fa2b 100644 --- a/tools/perf/lib/include/perf/cpumap.h +++ b/tools/perf/lib/include/perf/cpumap.h @@ -12,5 +12,12 @@ LIBPERF_API struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list); LIBPERF_API struct perf_cpu_map *perf_cpu_map__read(FILE *file); LIBPERF_API struct perf_cpu_map *perf_cpu_map__get(struct perf_cpu_map *map); LIBPERF_API void perf_cpu_map__put(struct perf_cpu_map *map); +LIBPERF_API int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx); +LIBPERF_API int perf_cpu_map__nr(const struct perf_cpu_map *cpus); + +#define perf_cpu_map__for_each_cpu(cpu, idx, cpus) \ + for ((idx) = 0, (cpu) = perf_cpu_map__cpu(cpus, idx); \ + (idx) < perf_cpu_map__nr(cpus); \ + (idx)++, (cpu) = perf_cpu_map__cpu(cpus, idx)) #endif /* __LIBPERF_CPUMAP_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 5bd491ac1762..d4d34bea0b40 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -6,6 +6,8 @@ LIBPERF_0.0.1 { perf_cpu_map__put; perf_cpu_map__new; perf_cpu_map__read; + perf_cpu_map__nr; + perf_cpu_map__cpu; perf_thread_map__new_dummy; perf_thread_map__set_pid; perf_thread_map__comm; -- cgit v1.2.3-59-g8ed1b From 0ff1a0fdf52cffa998eee4303e02780d39b2b09c Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:54 +0200 Subject: libperf: Add perf_evsel__cpus()/threads() functions Add the following functions: perf_evsel__cpus() perf_evsel__threads() to access the evsel's cpus and threads objects. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-68-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evsel.c | 10 ++++++++++ tools/perf/lib/include/perf/evsel.h | 2 ++ tools/perf/lib/libperf.map | 2 ++ tools/perf/util/evsel.h | 2 +- 4 files changed, 15 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/lib/evsel.c b/tools/perf/lib/evsel.c index c3f3722e9f91..8dbe0e841b8f 100644 --- a/tools/perf/lib/evsel.c +++ b/tools/perf/lib/evsel.c @@ -215,3 +215,13 @@ int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter) PERF_EVENT_IOC_SET_FILTER, (void *)filter); } + +struct perf_cpu_map *perf_evsel__cpus(struct perf_evsel *evsel) +{ + return evsel->cpus; +} + +struct perf_thread_map *perf_evsel__threads(struct perf_evsel *evsel) +{ + return evsel->threads; +} diff --git a/tools/perf/lib/include/perf/evsel.h b/tools/perf/lib/include/perf/evsel.h index 0db18dfabdb8..ae9f7eeb53a2 100644 --- a/tools/perf/lib/include/perf/evsel.h +++ b/tools/perf/lib/include/perf/evsel.h @@ -32,5 +32,7 @@ LIBPERF_API int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread, struct perf_counts_values *count); LIBPERF_API int perf_evsel__enable(struct perf_evsel *evsel); LIBPERF_API int perf_evsel__disable(struct perf_evsel *evsel); +LIBPERF_API struct perf_cpu_map *perf_evsel__cpus(struct perf_evsel *evsel); +LIBPERF_API struct perf_thread_map *perf_evsel__threads(struct perf_evsel *evsel); #endif /* __LIBPERF_EVSEL_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index d4d34bea0b40..9f43b5cda031 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -21,6 +21,8 @@ LIBPERF_0.0.1 { perf_evsel__open; perf_evsel__close; perf_evsel__read; + perf_evsel__cpus; + perf_evsel__threads; perf_evlist__new; perf_evlist__delete; perf_evlist__init; diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 0989fb2eb1ec..3cf35aa782b9 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -193,7 +193,7 @@ struct record_opts; static inline struct perf_cpu_map *evsel__cpus(struct evsel *evsel) { - return evsel->core.cpus; + return perf_evsel__cpus(&evsel->core); } static inline int perf_evsel__nr_cpus(struct evsel *evsel) -- cgit v1.2.3-59-g8ed1b From 80dc2b3e257cbd62e1cd5b18a6581f231c828c81 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:55 +0200 Subject: libperf: Adopt simplified perf_evlist__open()/close() functions from tools/perf Add the following functions: perf_evlist__open() perf_evlist__close() It's a simplified version of perf's evlist__open() without the sampling id index calculations. We can try to merge it in the future when we need it in some new libperf user. Also adopt some helper evlist traversing macros. In the future we can remove them from util/evlist.h, but that requires also some other changes. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-69-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evlist.c | 27 +++++++++++++++++++++++++ tools/perf/lib/include/internal/evlist.h | 34 ++++++++++++++++++++++++++++++++ tools/perf/lib/include/perf/evlist.h | 2 ++ tools/perf/lib/libperf.map | 2 ++ 4 files changed, 65 insertions(+) (limited to 'tools') diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c index 6a2308ef9868..5dda96b1d4da 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/perf/lib/evlist.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include #include @@ -114,3 +115,29 @@ void perf_evlist__set_maps(struct perf_evlist *evlist, perf_evlist__propagate_maps(evlist); } + +int perf_evlist__open(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel; + int err; + + perf_evlist__for_each_entry(evlist, evsel) { + err = perf_evsel__open(evsel, evsel->cpus, evsel->threads); + if (err < 0) + goto out_err; + } + + return 0; + +out_err: + perf_evlist__close(evlist); + return err; +} + +void perf_evlist__close(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel; + + perf_evlist__for_each_entry_reverse(evlist, evsel) + perf_evsel__close(evsel); +} diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h index b7b43dbc9b82..448891f06e3e 100644 --- a/tools/perf/lib/include/internal/evlist.h +++ b/tools/perf/lib/include/internal/evlist.h @@ -2,6 +2,8 @@ #ifndef __LIBPERF_INTERNAL_EVLIST_H #define __LIBPERF_INTERNAL_EVLIST_H +#include + struct perf_cpu_map; struct perf_thread_map; @@ -13,4 +15,36 @@ struct perf_evlist { struct perf_thread_map *threads; }; +/** + * __perf_evlist__for_each_entry - iterate thru all the evsels + * @list: list_head instance to iterate + * @evsel: struct perf_evsel iterator + */ +#define __perf_evlist__for_each_entry(list, evsel) \ + list_for_each_entry(evsel, list, node) + +/** + * evlist__for_each_entry - iterate thru all the evsels + * @evlist: perf_evlist instance to iterate + * @evsel: struct perf_evsel iterator + */ +#define perf_evlist__for_each_entry(evlist, evsel) \ + __perf_evlist__for_each_entry(&(evlist)->entries, evsel) + +/** + * __perf_evlist__for_each_entry_reverse - iterate thru all the evsels in reverse order + * @list: list_head instance to iterate + * @evsel: struct evsel iterator + */ +#define __perf_evlist__for_each_entry_reverse(list, evsel) \ + list_for_each_entry_reverse(evsel, list, node) + +/** + * perf_evlist__for_each_entry_reverse - iterate thru all the evsels in reverse order + * @evlist: evlist instance to iterate + * @evsel: struct evsel iterator + */ +#define perf_evlist__for_each_entry_reverse(evlist, evsel) \ + __perf_evlist__for_each_entry_reverse(&(evlist)->entries, evsel) + #endif /* __LIBPERF_INTERNAL_EVLIST_H */ diff --git a/tools/perf/lib/include/perf/evlist.h b/tools/perf/lib/include/perf/evlist.h index b1d8dee018d6..6d3dda743541 100644 --- a/tools/perf/lib/include/perf/evlist.h +++ b/tools/perf/lib/include/perf/evlist.h @@ -18,6 +18,8 @@ LIBPERF_API struct perf_evlist *perf_evlist__new(void); LIBPERF_API void perf_evlist__delete(struct perf_evlist *evlist); LIBPERF_API struct perf_evsel* perf_evlist__next(struct perf_evlist *evlist, struct perf_evsel *evsel); +LIBPERF_API int perf_evlist__open(struct perf_evlist *evlist); +LIBPERF_API void perf_evlist__close(struct perf_evlist *evlist); #define perf_evlist__for_each_evsel(evlist, pos) \ for ((pos) = perf_evlist__next((evlist), NULL); \ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 9f43b5cda031..4f966ddd5e53 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -25,6 +25,8 @@ LIBPERF_0.0.1 { perf_evsel__threads; perf_evlist__new; perf_evlist__delete; + perf_evlist__open; + perf_evlist__close; perf_evlist__init; perf_evlist__add; perf_evlist__remove; -- cgit v1.2.3-59-g8ed1b From fcc97c3e7a9d6fd3fda7674f52fb005f4e8453e7 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:56 +0200 Subject: libperf: Adopt perf_evlist__enable()/disable() functions from perf Adopt the following functions from tools/perf: perf_evlist__enable() perf_evlist__disable() Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-70-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evlist.c | 16 ++++++++++++++++ tools/perf/lib/include/perf/evlist.h | 2 ++ tools/perf/lib/libperf.map | 2 ++ 3 files changed, 20 insertions(+) (limited to 'tools') diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c index 5dda96b1d4da..f4dc9a208332 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/perf/lib/evlist.c @@ -141,3 +141,19 @@ void perf_evlist__close(struct perf_evlist *evlist) perf_evlist__for_each_entry_reverse(evlist, evsel) perf_evsel__close(evsel); } + +void perf_evlist__enable(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel; + + perf_evlist__for_each_entry(evlist, evsel) + perf_evsel__enable(evsel); +} + +void perf_evlist__disable(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel; + + perf_evlist__for_each_entry(evlist, evsel) + perf_evsel__disable(evsel); +} diff --git a/tools/perf/lib/include/perf/evlist.h b/tools/perf/lib/include/perf/evlist.h index 6d3dda743541..38365f8f3fba 100644 --- a/tools/perf/lib/include/perf/evlist.h +++ b/tools/perf/lib/include/perf/evlist.h @@ -20,6 +20,8 @@ LIBPERF_API struct perf_evsel* perf_evlist__next(struct perf_evlist *evlist, struct perf_evsel *evsel); LIBPERF_API int perf_evlist__open(struct perf_evlist *evlist); LIBPERF_API void perf_evlist__close(struct perf_evlist *evlist); +LIBPERF_API void perf_evlist__enable(struct perf_evlist *evlist); +LIBPERF_API void perf_evlist__disable(struct perf_evlist *evlist); #define perf_evlist__for_each_evsel(evlist, pos) \ for ((pos) = perf_evlist__next((evlist), NULL); \ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 4f966ddd5e53..2068e3d52227 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -27,6 +27,8 @@ LIBPERF_0.0.1 { perf_evlist__delete; perf_evlist__open; perf_evlist__close; + perf_evlist__enable; + perf_evlist__disable; perf_evlist__init; perf_evlist__add; perf_evlist__remove; -- cgit v1.2.3-59-g8ed1b From 384c4ad192a01fe235c7ac9e9fd8605d12a807e8 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:57 +0200 Subject: libperf: Add perf_evsel__attr() function Add a perf_evsel__attr() function to get attr pointer from a perf_evsel instance. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-71-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evsel.c | 5 +++++ tools/perf/lib/include/perf/evsel.h | 1 + tools/perf/lib/libperf.map | 1 + 3 files changed, 7 insertions(+) (limited to 'tools') diff --git a/tools/perf/lib/evsel.c b/tools/perf/lib/evsel.c index 8dbe0e841b8f..24abc80dd767 100644 --- a/tools/perf/lib/evsel.c +++ b/tools/perf/lib/evsel.c @@ -225,3 +225,8 @@ struct perf_thread_map *perf_evsel__threads(struct perf_evsel *evsel) { return evsel->threads; } + +struct perf_event_attr *perf_evsel__attr(struct perf_evsel *evsel) +{ + return &evsel->attr; +} diff --git a/tools/perf/lib/include/perf/evsel.h b/tools/perf/lib/include/perf/evsel.h index ae9f7eeb53a2..4388667f265c 100644 --- a/tools/perf/lib/include/perf/evsel.h +++ b/tools/perf/lib/include/perf/evsel.h @@ -34,5 +34,6 @@ LIBPERF_API int perf_evsel__enable(struct perf_evsel *evsel); LIBPERF_API int perf_evsel__disable(struct perf_evsel *evsel); LIBPERF_API struct perf_cpu_map *perf_evsel__cpus(struct perf_evsel *evsel); LIBPERF_API struct perf_thread_map *perf_evsel__threads(struct perf_evsel *evsel); +LIBPERF_API struct perf_event_attr *perf_evsel__attr(struct perf_evsel *evsel); #endif /* __LIBPERF_EVSEL_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 2068e3d52227..e24d3cec01c1 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -23,6 +23,7 @@ LIBPERF_0.0.1 { perf_evsel__read; perf_evsel__cpus; perf_evsel__threads; + perf_evsel__attr; perf_evlist__new; perf_evlist__delete; perf_evlist__open; -- cgit v1.2.3-59-g8ed1b From 0a64d7091efde161a7d0fa385ed5c3bdb72ecdf9 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:58 +0200 Subject: libperf: Add install targets Add install targets (mostly copied from tools/lib/bpf), it's now possible to install libperf with: $ make DESTDIR=/tmp/krava install INSTALL libperf.a INSTALL libperf.so INSTALL libperf.so.0 INSTALL libperf.so.0.0.1 INSTALL headers INSTALL libperf.pc $ find /tmp/krava/ /tmp/krava/ /tmp/krava/include /tmp/krava/include/perf /tmp/krava/include/perf/evsel.h /tmp/krava/include/perf/evlist.h /tmp/krava/include/perf/threadmap.h /tmp/krava/include/perf/cpumap.h /tmp/krava/include/perf/core.h /tmp/krava/lib64 /tmp/krava/lib64/pkgconfig /tmp/krava/lib64/pkgconfig/libperf.pc /tmp/krava/lib64/libperf.so.0.0.1 /tmp/krava/lib64/libperf.so.0 /tmp/krava/lib64/libperf.so /tmp/krava/lib64/libperf.a Signed-off-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-72-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/Makefile | 69 ++++++++++++++++++++++++++++++++++++-- tools/perf/lib/libperf.pc.template | 11 ++++++ 2 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 tools/perf/lib/libperf.pc.template (limited to 'tools') diff --git a/tools/perf/lib/Makefile b/tools/perf/lib/Makefile index cd571ec648ad..f1b3d4c6d5f0 100644 --- a/tools/perf/lib/Makefile +++ b/tools/perf/lib/Makefile @@ -14,9 +14,31 @@ srctree := $(patsubst %/,%,$(dir $(srctree))) #$(info Determined 'srctree' to be $(srctree)) endif +INSTALL = install + +# Use DESTDIR for installing into a different root directory. +# This is useful for building a package. The program will be +# installed in this directory as if it was the root directory. +# Then the build tool can move it later. +DESTDIR ?= +DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' + include $(srctree)/tools/scripts/Makefile.include include $(srctree)/tools/scripts/Makefile.arch +ifeq ($(LP64), 1) + libdir_relative = lib64 +else + libdir_relative = lib +endif + +prefix ?= +libdir = $(prefix)/$(libdir_relative) + +# Shell quotes +libdir_SQ = $(subst ','\'',$(libdir)) +libdir_relative_SQ = $(subst ','\'',$(libdir_relative)) + ifeq ("$(origin V)", "command line") VERBOSE = $(V) endif @@ -49,6 +71,8 @@ override CFLAGS += -fvisibility=hidden all: export srctree OUTPUT CC LD CFLAGS V +export DESTDIR DESTDIR_SQ + include $(srctree)/tools/build/Makefile.include VERSION_SCRIPT := libperf.map @@ -60,6 +84,9 @@ VERSION = $(LIBPERF_VERSION).$(LIBPERF_PATCHLEVEL).$(LIBPERF_EXTRAVERSION) LIBPERF_SO := $(OUTPUT)libperf.so.$(VERSION) LIBPERF_A := $(OUTPUT)libperf.a LIBPERF_IN := $(OUTPUT)libperf-in.o +LIBPERF_PC := $(OUTPUT)libperf.pc + +LIBPERF_ALL := $(LIBPERF_A) $(OUTPUT)libperf.so* $(LIBPERF_IN): FORCE $(Q)$(MAKE) $(build)=libperf @@ -74,14 +101,52 @@ $(LIBPERF_SO): $(LIBPERF_IN) @ln -sf $(@F) $(OUTPUT)libperf.so.$(LIBPERF_VERSION) -libs: $(LIBPERF_A) $(LIBPERF_SO) +libs: $(LIBPERF_A) $(LIBPERF_SO) $(LIBPERF_PC) all: fixdep $(Q)$(MAKE) libs clean: $(call QUIET_CLEAN, libperf) $(RM) $(LIBPERF_A) \ - *.o *~ *.a *.so *.so.$(VERSION) *.so.$(LIBPERF_VERSION) .*.d .*.cmd LIBPERF-CFLAGS + *.o *~ *.a *.so *.so.$(VERSION) *.so.$(LIBPERF_VERSION) .*.d .*.cmd LIBPERF-CFLAGS $(LIBPERF_PC) + +$(LIBPERF_PC): + $(QUIET_GEN)sed -e "s|@PREFIX@|$(prefix)|" \ + -e "s|@LIBDIR@|$(libdir_SQ)|" \ + -e "s|@VERSION@|$(VERSION)|" \ + < libperf.pc.template > $@ + +define do_install_mkdir + if [ ! -d '$(DESTDIR_SQ)$1' ]; then \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$1'; \ + fi +endef + +define do_install + if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ + fi; \ + $(INSTALL) $1 $(if $3,-m $3,) '$(DESTDIR_SQ)$2' +endef + +install_lib: libs + $(call QUIET_INSTALL, $(LIBPERF_ALL)) \ + $(call do_install_mkdir,$(libdir_SQ)); \ + cp -fpR $(LIBPERF_ALL) $(DESTDIR)$(libdir_SQ) + +install_headers: + $(call QUIET_INSTALL, headers) \ + $(call do_install,include/perf/core.h,$(prefix)/include/perf,644); \ + $(call do_install,include/perf/cpumap.h,$(prefix)/include/perf,644); \ + $(call do_install,include/perf/threadmap.h,$(prefix)/include/perf,644); \ + $(call do_install,include/perf/evlist.h,$(prefix)/include/perf,644); \ + $(call do_install,include/perf/evsel.h,$(prefix)/include/perf,644); + +install_pkgconfig: $(LIBPERF_PC) + $(call QUIET_INSTALL, $(LIBPERF_PC)) \ + $(call do_install,$(LIBPERF_PC),$(libdir_SQ)/pkgconfig,644) + +install: install_lib install_headers install_pkgconfig FORCE: diff --git a/tools/perf/lib/libperf.pc.template b/tools/perf/lib/libperf.pc.template new file mode 100644 index 000000000000..117e4a237b55 --- /dev/null +++ b/tools/perf/lib/libperf.pc.template @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) + +prefix=@PREFIX@ +libdir=@LIBDIR@ +includedir=${prefix}/include + +Name: libperf +Description: perf library +Version: @VERSION@ +Libs: -L${libdir} -lperf +Cflags: -I${includedir} -- cgit v1.2.3-59-g8ed1b From 6a94b52a71b7d3ca3ec47c194f7916b306cb26ef Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:24:59 +0200 Subject: libperf: Add tests support Adding simple test framework, now empty. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-73-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/Makefile | 7 +++++- tools/perf/lib/include/internal/tests.h | 19 +++++++++++++++++ tools/perf/lib/tests/Makefile | 38 +++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 tools/perf/lib/include/internal/tests.h create mode 100644 tools/perf/lib/tests/Makefile (limited to 'tools') diff --git a/tools/perf/lib/Makefile b/tools/perf/lib/Makefile index f1b3d4c6d5f0..8a9ae50818e4 100644 --- a/tools/perf/lib/Makefile +++ b/tools/perf/lib/Makefile @@ -109,6 +109,11 @@ all: fixdep clean: $(call QUIET_CLEAN, libperf) $(RM) $(LIBPERF_A) \ *.o *~ *.a *.so *.so.$(VERSION) *.so.$(LIBPERF_VERSION) .*.d .*.cmd LIBPERF-CFLAGS $(LIBPERF_PC) + $(Q)$(MAKE) -C tests clean + +tests: + $(Q)$(MAKE) -C tests + $(Q)$(MAKE) -C tests run $(LIBPERF_PC): $(QUIET_GEN)sed -e "s|@PREFIX@|$(prefix)|" \ @@ -150,4 +155,4 @@ install: install_lib install_headers install_pkgconfig FORCE: -.PHONY: all install clean FORCE +.PHONY: all install clean tests FORCE diff --git a/tools/perf/lib/include/internal/tests.h b/tools/perf/lib/include/internal/tests.h new file mode 100644 index 000000000000..b7a20cd24ee1 --- /dev/null +++ b/tools/perf/lib/include/internal/tests.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LIBPERF_INTERNAL_TESTS_H +#define __LIBPERF_INTERNAL_TESTS_H + +#include + +#define __T_START fprintf(stdout, "- running %s...", __FILE__) +#define __T_OK fprintf(stdout, "OK\n") +#define __T_FAIL fprintf(stdout, "FAIL\n") + +#define __T(text, cond) \ +do { \ + if (!(cond)) { \ + fprintf(stderr, "FAILED %s:%d %s\n", __FILE__, __LINE__, text); \ + return -1; \ + } \ +} while (0) + +#endif /* __LIBPERF_INTERNAL_TESTS_H */ diff --git a/tools/perf/lib/tests/Makefile b/tools/perf/lib/tests/Makefile new file mode 100644 index 000000000000..de951ae38dea --- /dev/null +++ b/tools/perf/lib/tests/Makefile @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) + +TESTS = + +TESTS_SO := $(addsuffix -so,$(TESTS)) +TESTS_A := $(addsuffix -a,$(TESTS)) + +# Set compile option CFLAGS +ifdef EXTRA_CFLAGS + CFLAGS := $(EXTRA_CFLAGS) +else + CFLAGS := -g -Wall +endif + +all: + +include $(srctree)/tools/scripts/Makefile.include + +INCLUDE = -I$(srctree)/tools/perf/lib/include -I$(srctree)/tools/include + +$(TESTS_A): FORCE + $(QUIET_LINK)$(CC) $(INCLUDE) $(CFLAGS) -o $@ $(subst -a,.c,$@) ../libperf.a + +$(TESTS_SO): FORCE + $(QUIET_LINK)$(CC) $(INCLUDE) $(CFLAGS) -L.. -o $@ $(subst -so,.c,$@) -lperf + +all: $(TESTS_A) $(TESTS_SO) + +run: + @echo "running static:" + @for i in $(TESTS_A); do ./$$i; done + @echo "running dynamic:" + @for i in $(TESTS_SO); do LD_LIBRARY_PATH=../ ./$$i; done + +clean: + $(call QUIET_CLEAN, tests)$(RM) $(TESTS_A) $(TESTS_SO) + +.PHONY: all clean FORCE -- cgit v1.2.3-59-g8ed1b From c0e730456ae8a864701f5ca4f6c2e23010e4b04a Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:25:00 +0200 Subject: libperf: Add perf_cpu_map test Add simple perf_cpu_map tests. Committer testing: One has to build it in the source tree, a limitation that should be fixed in followup patches: $ make O=/tmp/build/perf -C tools/perf/lib make: Entering directory '/home/acme/git/perf/tools/perf/lib' LINK /tmp/build/perf/libperf.so.0.0.1 GEN /tmp/build/perf/libperf.pc make: Leaving directory '/home/acme/git/perf/tools/perf/lib' $ make O=/tmp/build/perf -C tools/perf/lib tests make: Entering directory '/home/acme/git/perf/tools/perf/lib' LINK test-cpumap-a gcc: error: ../libperf.a: No such file or directory make[1]: *** [Makefile:22: test-cpumap-a] Error 1 make: *** [Makefile:115: tests] Error 2 make: Leaving directory '/home/acme/git/perf/tools/perf/lib' [acme@quaco perf]$ make -C tools/perf/lib make: Entering directory '/home/acme/git/perf/tools/perf/lib' HOSTCC fixdep.o HOSTLD fixdep-in.o LINK fixdep CC core.o CC cpumap.o CC threadmap.o CC evsel.o CC evlist.o CC zalloc.o CC xyarray.o CC lib.o LD libperf-in.o AR libperf.a LINK libperf.so.0.0.1 GEN libperf.pc make: Leaving directory '/home/acme/git/perf/tools/perf/lib' $ make O=/tmp/build/perf -C tools/perf/lib tests make: Entering directory '/home/acme/git/perf/tools/perf/lib' LINK test-cpumap-a LINK test-cpumap-so running static: - running test-cpumap.c...OK running dynamic: - running test-cpumap.c...OK make: Leaving directory '/home/acme/git/perf/tools/perf/lib' $ Signed-off-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-74-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/tests/Makefile | 2 +- tools/perf/lib/tests/test-cpumap.c | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tools/perf/lib/tests/test-cpumap.c (limited to 'tools') diff --git a/tools/perf/lib/tests/Makefile b/tools/perf/lib/tests/Makefile index de951ae38dea..b72c8c47df61 100644 --- a/tools/perf/lib/tests/Makefile +++ b/tools/perf/lib/tests/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) -TESTS = +TESTS = test-cpumap TESTS_SO := $(addsuffix -so,$(TESTS)) TESTS_A := $(addsuffix -a,$(TESTS)) diff --git a/tools/perf/lib/tests/test-cpumap.c b/tools/perf/lib/tests/test-cpumap.c new file mode 100644 index 000000000000..76a43cfb83a1 --- /dev/null +++ b/tools/perf/lib/tests/test-cpumap.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + +int main(int argc, char **argv) +{ + struct perf_cpu_map *cpus; + + __T_START; + + cpus = perf_cpu_map__dummy_new(); + if (!cpus) + return -1; + + perf_cpu_map__get(cpus); + perf_cpu_map__put(cpus); + perf_cpu_map__put(cpus); + + __T_OK; + return 0; +} -- cgit v1.2.3-59-g8ed1b From 43d6976365d5f90de487e8f9f49ab21775ae84f4 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:25:01 +0200 Subject: libperf: Add perf_thread_map test Add simple perf_thread_map tests. Committer testing: $ make O=/tmp/build/perf -C tools/perf/lib tests make: Entering directory '/home/acme/git/perf/tools/perf/lib' LINK test-cpumap-a LINK test-threadmap-a LINK test-cpumap-so LINK test-threadmap-so running static: - running test-cpumap.c...OK - running test-threadmap.c...OK running dynamic: - running test-cpumap.c...OK - running test-threadmap.c...OK make: Leaving directory '/home/acme/git/perf/tools/perf/lib' $ Signed-off-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-75-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/tests/Makefile | 2 +- tools/perf/lib/tests/test-threadmap.c | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tools/perf/lib/tests/test-threadmap.c (limited to 'tools') diff --git a/tools/perf/lib/tests/Makefile b/tools/perf/lib/tests/Makefile index b72c8c47df61..5dc84003e3a7 100644 --- a/tools/perf/lib/tests/Makefile +++ b/tools/perf/lib/tests/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) -TESTS = test-cpumap +TESTS = test-cpumap test-threadmap TESTS_SO := $(addsuffix -so,$(TESTS)) TESTS_A := $(addsuffix -a,$(TESTS)) diff --git a/tools/perf/lib/tests/test-threadmap.c b/tools/perf/lib/tests/test-threadmap.c new file mode 100644 index 000000000000..10a4f4cbbdd5 --- /dev/null +++ b/tools/perf/lib/tests/test-threadmap.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + +int main(int argc, char **argv) +{ + struct perf_thread_map *threads; + + __T_START; + + threads = perf_thread_map__new_dummy(); + if (!threads) + return -1; + + perf_thread_map__get(threads); + perf_thread_map__put(threads); + perf_thread_map__put(threads); + + __T_OK; + return 0; +} -- cgit v1.2.3-59-g8ed1b From 8ded5425fa71e2f7f60eb59d64ecdba80582b641 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:25:02 +0200 Subject: libperf: Add perf_evlist test Add 2 simple perf_evlist tests to test counters reading interface through the struct evlist object. Committer testing: # make -C tools/perf/lib tests make: Entering directory '/home/acme/git/perf/tools/perf/lib' LINK test-cpumap-a LINK test-threadmap-a LINK test-evlist-a LINK test-cpumap-so LINK test-threadmap-so LINK test-evlist-so running static: - running test-cpumap.c...OK - running test-threadmap.c...OK - running test-evlist.c...OK running dynamic: - running test-cpumap.c...OK - running test-threadmap.c...OK - running test-evlist.c...OK make: Leaving directory '/home/acme/git/perf/tools/perf/lib' # Signed-off-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-76-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/tests/Makefile | 2 +- tools/perf/lib/tests/test-evlist.c | 123 +++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 tools/perf/lib/tests/test-evlist.c (limited to 'tools') diff --git a/tools/perf/lib/tests/Makefile b/tools/perf/lib/tests/Makefile index 5dc84003e3a7..e66ed090f08e 100644 --- a/tools/perf/lib/tests/Makefile +++ b/tools/perf/lib/tests/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) -TESTS = test-cpumap test-threadmap +TESTS = test-cpumap test-threadmap test-evlist TESTS_SO := $(addsuffix -so,$(TESTS)) TESTS_A := $(addsuffix -a,$(TESTS)) diff --git a/tools/perf/lib/tests/test-evlist.c b/tools/perf/lib/tests/test-evlist.c new file mode 100644 index 000000000000..f24c531afcb6 --- /dev/null +++ b/tools/perf/lib/tests/test-evlist.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include + +static int test_stat_cpu(void) +{ + struct perf_cpu_map *cpus; + struct perf_evlist *evlist; + struct perf_evsel *evsel; + struct perf_event_attr attr1 = { + .type = PERF_TYPE_SOFTWARE, + .config = PERF_COUNT_SW_CPU_CLOCK, + }; + struct perf_event_attr attr2 = { + .type = PERF_TYPE_SOFTWARE, + .config = PERF_COUNT_SW_TASK_CLOCK, + }; + int err, cpu, tmp; + + cpus = perf_cpu_map__new(NULL); + __T("failed to create cpus", cpus); + + evlist = perf_evlist__new(); + __T("failed to create evlist", evlist); + + evsel = perf_evsel__new(&attr1); + __T("failed to create evsel1", evsel); + + perf_evlist__add(evlist, evsel); + + evsel = perf_evsel__new(&attr2); + __T("failed to create evsel2", evsel); + + perf_evlist__add(evlist, evsel); + + perf_evlist__set_maps(evlist, cpus, NULL); + + err = perf_evlist__open(evlist); + __T("failed to open evsel", err == 0); + + perf_evlist__for_each_evsel(evlist, evsel) { + cpus = perf_evsel__cpus(evsel); + + perf_cpu_map__for_each_cpu(cpu, tmp, cpus) { + struct perf_counts_values counts = { .val = 0 }; + + perf_evsel__read(evsel, cpu, 0, &counts); + __T("failed to read value for evsel", counts.val != 0); + } + } + + perf_evlist__close(evlist); + perf_evlist__delete(evlist); + + perf_cpu_map__put(cpus); + return 0; +} + +static int test_stat_thread(void) +{ + struct perf_counts_values counts = { .val = 0 }; + struct perf_thread_map *threads; + struct perf_evlist *evlist; + struct perf_evsel *evsel; + struct perf_event_attr attr1 = { + .type = PERF_TYPE_SOFTWARE, + .config = PERF_COUNT_SW_CPU_CLOCK, + }; + struct perf_event_attr attr2 = { + .type = PERF_TYPE_SOFTWARE, + .config = PERF_COUNT_SW_TASK_CLOCK, + }; + int err; + + threads = perf_thread_map__new_dummy(); + __T("failed to create threads", threads); + + perf_thread_map__set_pid(threads, 0, 0); + + evlist = perf_evlist__new(); + __T("failed to create evlist", evlist); + + evsel = perf_evsel__new(&attr1); + __T("failed to create evsel1", evsel); + + perf_evlist__add(evlist, evsel); + + evsel = perf_evsel__new(&attr2); + __T("failed to create evsel2", evsel); + + perf_evlist__add(evlist, evsel); + + perf_evlist__set_maps(evlist, NULL, threads); + + err = perf_evlist__open(evlist); + __T("failed to open evsel", err == 0); + + perf_evlist__for_each_evsel(evlist, evsel) { + perf_evsel__read(evsel, 0, 0, &counts); + __T("failed to read value for evsel", counts.val != 0); + } + + perf_evlist__close(evlist); + perf_evlist__delete(evlist); + + perf_thread_map__put(threads); + return 0; +} + +int main(int argc, char **argv) +{ + __T_START; + + test_stat_cpu(); + test_stat_thread(); + + __T_OK; + return 0; +} -- cgit v1.2.3-59-g8ed1b From bb5133ae4d404a8a08d8a94dfdea1c477c93e842 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:25:03 +0200 Subject: libperf: Add perf_evsel tests Add 2 simple perf_evsel tests to test counters reading interface through the struct evsel object. Committer testing: # make -C tools/perf/lib tests make: Entering directory '/home/acme/git/perf/tools/perf/lib' LINK test-cpumap-a LINK test-threadmap-a LINK test-evlist-a LINK test-evsel-a LINK test-cpumap-so LINK test-threadmap-so LINK test-evlist-so LINK test-evsel-so running static: - running test-cpumap.c...OK - running test-threadmap.c...OK - running test-evlist.c...OK - running test-evsel.c...OK running dynamic: - running test-cpumap.c...OK - running test-threadmap.c...OK - running test-evlist.c...OK - running test-evsel.c...OK make: Leaving directory '/home/acme/git/perf/tools/perf/lib' # Signed-off-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-77-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/tests/Makefile | 2 +- tools/perf/lib/tests/test-evsel.c | 82 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 tools/perf/lib/tests/test-evsel.c (limited to 'tools') diff --git a/tools/perf/lib/tests/Makefile b/tools/perf/lib/tests/Makefile index e66ed090f08e..1ee4e9ba848b 100644 --- a/tools/perf/lib/tests/Makefile +++ b/tools/perf/lib/tests/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) -TESTS = test-cpumap test-threadmap test-evlist +TESTS = test-cpumap test-threadmap test-evlist test-evsel TESTS_SO := $(addsuffix -so,$(TESTS)) TESTS_A := $(addsuffix -a,$(TESTS)) diff --git a/tools/perf/lib/tests/test-evsel.c b/tools/perf/lib/tests/test-evsel.c new file mode 100644 index 000000000000..268712292f60 --- /dev/null +++ b/tools/perf/lib/tests/test-evsel.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include + +static int test_stat_cpu(void) +{ + struct perf_cpu_map *cpus; + struct perf_evsel *evsel; + struct perf_event_attr attr = { + .type = PERF_TYPE_SOFTWARE, + .config = PERF_COUNT_SW_CPU_CLOCK, + }; + int err, cpu, tmp; + + cpus = perf_cpu_map__new(NULL); + __T("failed to create cpus", cpus); + + evsel = perf_evsel__new(&attr); + __T("failed to create evsel", evsel); + + err = perf_evsel__open(evsel, cpus, NULL); + __T("failed to open evsel", err == 0); + + perf_cpu_map__for_each_cpu(cpu, tmp, cpus) { + struct perf_counts_values counts = { .val = 0 }; + + perf_evsel__read(evsel, cpu, 0, &counts); + __T("failed to read value for evsel", counts.val != 0); + } + + perf_evsel__close(evsel); + perf_evsel__delete(evsel); + + perf_cpu_map__put(cpus); + return 0; +} + +static int test_stat_thread(void) +{ + struct perf_counts_values counts = { .val = 0 }; + struct perf_thread_map *threads; + struct perf_evsel *evsel; + struct perf_event_attr attr = { + .type = PERF_TYPE_SOFTWARE, + .config = PERF_COUNT_SW_TASK_CLOCK, + }; + int err; + + threads = perf_thread_map__new_dummy(); + __T("failed to create threads", threads); + + perf_thread_map__set_pid(threads, 0, 0); + + evsel = perf_evsel__new(&attr); + __T("failed to create evsel", evsel); + + err = perf_evsel__open(evsel, NULL, threads); + __T("failed to open evsel", err == 0); + + perf_evsel__read(evsel, 0, 0, &counts); + __T("failed to read value for evsel", counts.val != 0); + + perf_evsel__close(evsel); + perf_evsel__delete(evsel); + + perf_thread_map__put(threads); + return 0; +} + +int main(int argc, char **argv) +{ + __T_START; + + test_stat_cpu(); + test_stat_thread(); + + __T_OK; + return 0; +} -- cgit v1.2.3-59-g8ed1b From 6bda376ff416cf713773d38b743953a1a9bc0603 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:25:04 +0200 Subject: libperf: Add perf_evlist__enable/disable test Add simple perf_evlist enable/disable test together with evlist counter reading interface. Committer testing: # make -C tools/perf/lib tests make: Entering directory '/home/acme/git/perf/tools/perf/lib' LINK test-cpumap-a LINK test-threadmap-a LINK test-evlist-a LINK test-evsel-a LINK test-cpumap-so LINK test-threadmap-so LINK test-evlist-so LINK test-evsel-so running static: - running test-cpumap.c...OK - running test-threadmap.c...OK - running test-evlist.c...OK - running test-evsel.c...OK running dynamic: - running test-cpumap.c...OK - running test-threadmap.c...OK - running test-evlist.c...OK - running test-evsel.c...OK make: Leaving directory '/home/acme/git/perf/tools/perf/lib' # Signed-off-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-78-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/tests/test-evlist.c | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'tools') diff --git a/tools/perf/lib/tests/test-evlist.c b/tools/perf/lib/tests/test-evlist.c index f24c531afcb6..4e1407f20ffd 100644 --- a/tools/perf/lib/tests/test-evlist.c +++ b/tools/perf/lib/tests/test-evlist.c @@ -111,12 +111,75 @@ static int test_stat_thread(void) return 0; } +static int test_stat_thread_enable(void) +{ + struct perf_counts_values counts = { .val = 0 }; + struct perf_thread_map *threads; + struct perf_evlist *evlist; + struct perf_evsel *evsel; + struct perf_event_attr attr1 = { + .type = PERF_TYPE_SOFTWARE, + .config = PERF_COUNT_SW_CPU_CLOCK, + .disabled = 1, + }; + struct perf_event_attr attr2 = { + .type = PERF_TYPE_SOFTWARE, + .config = PERF_COUNT_SW_TASK_CLOCK, + .disabled = 1, + }; + int err; + + threads = perf_thread_map__new_dummy(); + __T("failed to create threads", threads); + + perf_thread_map__set_pid(threads, 0, 0); + + evlist = perf_evlist__new(); + __T("failed to create evlist", evlist); + + evsel = perf_evsel__new(&attr1); + __T("failed to create evsel1", evsel); + + perf_evlist__add(evlist, evsel); + + evsel = perf_evsel__new(&attr2); + __T("failed to create evsel2", evsel); + + perf_evlist__add(evlist, evsel); + + perf_evlist__set_maps(evlist, NULL, threads); + + err = perf_evlist__open(evlist); + __T("failed to open evsel", err == 0); + + perf_evlist__for_each_evsel(evlist, evsel) { + perf_evsel__read(evsel, 0, 0, &counts); + __T("failed to read value for evsel", counts.val == 0); + } + + perf_evlist__enable(evlist); + + perf_evlist__for_each_evsel(evlist, evsel) { + perf_evsel__read(evsel, 0, 0, &counts); + __T("failed to read value for evsel", counts.val != 0); + } + + perf_evlist__disable(evlist); + + perf_evlist__close(evlist); + perf_evlist__delete(evlist); + + perf_thread_map__put(threads); + return 0; +} + int main(int argc, char **argv) { __T_START; test_stat_cpu(); test_stat_thread(); + test_stat_thread_enable(); __T_OK; return 0; -- cgit v1.2.3-59-g8ed1b From 02266a2d9cf7e04bf3d4b4457654839dc253f605 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:25:05 +0200 Subject: libperf: Add perf_evsel__enable/disable test Add simple perf_evsel enable/disable test together with evsel counter reading interface. Committer testing: # make -C tools/perf/lib tests make: Entering directory '/home/acme/git/perf/tools/perf/lib' LINK test-cpumap-a LINK test-threadmap-a LINK test-evlist-a LINK test-evsel-a LINK test-cpumap-so LINK test-threadmap-so LINK test-evlist-so LINK test-evsel-so running static: - running test-cpumap.c...OK - running test-threadmap.c...OK - running test-evlist.c...OK - running test-evsel.c...OK running dynamic: - running test-cpumap.c...OK - running test-threadmap.c...OK - running test-evlist.c...OK - running test-evsel.c...OK make: Leaving directory '/home/acme/git/perf/tools/perf/lib' # Signed-off-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-79-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/tests/test-evsel.c | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'tools') diff --git a/tools/perf/lib/tests/test-evsel.c b/tools/perf/lib/tests/test-evsel.c index 268712292f60..2c648fe5617e 100644 --- a/tools/perf/lib/tests/test-evsel.c +++ b/tools/perf/lib/tests/test-evsel.c @@ -70,12 +70,55 @@ static int test_stat_thread(void) return 0; } +static int test_stat_thread_enable(void) +{ + struct perf_counts_values counts = { .val = 0 }; + struct perf_thread_map *threads; + struct perf_evsel *evsel; + struct perf_event_attr attr = { + .type = PERF_TYPE_SOFTWARE, + .config = PERF_COUNT_SW_TASK_CLOCK, + .disabled = 1, + }; + int err; + + threads = perf_thread_map__new_dummy(); + __T("failed to create threads", threads); + + perf_thread_map__set_pid(threads, 0, 0); + + evsel = perf_evsel__new(&attr); + __T("failed to create evsel", evsel); + + err = perf_evsel__open(evsel, NULL, threads); + __T("failed to open evsel", err == 0); + + perf_evsel__read(evsel, 0, 0, &counts); + __T("failed to read value for evsel", counts.val == 0); + + err = perf_evsel__enable(evsel); + __T("failed to enable evsel", err == 0); + + perf_evsel__read(evsel, 0, 0, &counts); + __T("failed to read value for evsel", counts.val != 0); + + err = perf_evsel__disable(evsel); + __T("failed to enable evsel", err == 0); + + perf_evsel__close(evsel); + perf_evsel__delete(evsel); + + perf_thread_map__put(threads); + return 0; +} + int main(int argc, char **argv) { __T_START; test_stat_cpu(); test_stat_thread(); + test_stat_thread_enable(); __T_OK; return 0; -- cgit v1.2.3-59-g8ed1b From f4f48e9c1adb49f732ac0abc4b2513f2b62a10cb Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 21 Jul 2019 13:25:06 +0200 Subject: libperf: Initial documentation Add initial drafts of documentation files, hugely unfinished. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190721112506.12306-80-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/Documentation/Makefile | 7 ++ tools/perf/lib/Documentation/man/libperf.rst | 100 +++++++++++++++++ tools/perf/lib/Documentation/tutorial/tutorial.rst | 123 +++++++++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 tools/perf/lib/Documentation/Makefile create mode 100644 tools/perf/lib/Documentation/man/libperf.rst create mode 100644 tools/perf/lib/Documentation/tutorial/tutorial.rst (limited to 'tools') diff --git a/tools/perf/lib/Documentation/Makefile b/tools/perf/lib/Documentation/Makefile new file mode 100644 index 000000000000..586425a88795 --- /dev/null +++ b/tools/perf/lib/Documentation/Makefile @@ -0,0 +1,7 @@ +all: + rst2man man/libperf.rst > man/libperf.7 + rst2pdf tutorial/tutorial.rst + +clean: + rm -f man/libperf.7 + rm -f tutorial/tutorial.pdf diff --git a/tools/perf/lib/Documentation/man/libperf.rst b/tools/perf/lib/Documentation/man/libperf.rst new file mode 100644 index 000000000000..09a270fccb9c --- /dev/null +++ b/tools/perf/lib/Documentation/man/libperf.rst @@ -0,0 +1,100 @@ +.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) + +libperf + +The libperf library provides an API to access the linux kernel perf +events subsystem. It provides the following high level objects: + + - struct perf_cpu_map + - struct perf_thread_map + - struct perf_evlist + - struct perf_evsel + +reference +========= +Function reference by header files: + +perf/core.h +----------- +.. code-block:: c + + typedef int (\*libperf_print_fn_t)(enum libperf_print_level level, + const char \*, va_list ap); + + void libperf_set_print(libperf_print_fn_t fn); + +perf/cpumap.h +------------- +.. code-block:: c + + struct perf_cpu_map \*perf_cpu_map__dummy_new(void); + struct perf_cpu_map \*perf_cpu_map__new(const char \*cpu_list); + struct perf_cpu_map \*perf_cpu_map__read(FILE \*file); + struct perf_cpu_map \*perf_cpu_map__get(struct perf_cpu_map \*map); + void perf_cpu_map__put(struct perf_cpu_map \*map); + int perf_cpu_map__cpu(const struct perf_cpu_map \*cpus, int idx); + int perf_cpu_map__nr(const struct perf_cpu_map \*cpus); + perf_cpu_map__for_each_cpu(cpu, idx, cpus) + +perf/threadmap.h +---------------- +.. code-block:: c + + struct perf_thread_map \*perf_thread_map__new_dummy(void); + void perf_thread_map__set_pid(struct perf_thread_map \*map, int thread, pid_t pid); + char \*perf_thread_map__comm(struct perf_thread_map \*map, int thread); + struct perf_thread_map \*perf_thread_map__get(struct perf_thread_map \*map); + void perf_thread_map__put(struct perf_thread_map \*map); + +perf/evlist.h +------------- +.. code-block:: + + void perf_evlist__init(struct perf_evlist \*evlist); + void perf_evlist__add(struct perf_evlist \*evlist, + struct perf_evsel \*evsel); + void perf_evlist__remove(struct perf_evlist \*evlist, + struct perf_evsel \*evsel); + struct perf_evlist \*perf_evlist__new(void); + void perf_evlist__delete(struct perf_evlist \*evlist); + struct perf_evsel\* perf_evlist__next(struct perf_evlist \*evlist, + struct perf_evsel \*evsel); + int perf_evlist__open(struct perf_evlist \*evlist); + void perf_evlist__close(struct perf_evlist \*evlist); + void perf_evlist__enable(struct perf_evlist \*evlist); + void perf_evlist__disable(struct perf_evlist \*evlist); + perf_evlist__for_each_evsel(evlist, pos) + void perf_evlist__set_maps(struct perf_evlist \*evlist, + struct perf_cpu_map \*cpus, + struct perf_thread_map \*threads); + +perf/evsel.h +------------ +.. code-block:: c + + struct perf_counts_values { + union { + struct { + uint64_t val; + uint64_t ena; + uint64_t run; + }; + uint64_t values[3]; + }; + }; + + void perf_evsel__init(struct perf_evsel \*evsel, + struct perf_event_attr \*attr); + struct perf_evsel \*perf_evsel__new(struct perf_event_attr \*attr); + void perf_evsel__delete(struct perf_evsel \*evsel); + int perf_evsel__open(struct perf_evsel \*evsel, struct perf_cpu_map \*cpus, + struct perf_thread_map \*threads); + void perf_evsel__close(struct perf_evsel \*evsel); + int perf_evsel__read(struct perf_evsel \*evsel, int cpu, int thread, + struct perf_counts_values \*count); + int perf_evsel__enable(struct perf_evsel \*evsel); + int perf_evsel__disable(struct perf_evsel \*evsel); + int perf_evsel__apply_filter(struct perf_evsel \*evsel, const char \*filter); + struct perf_cpu_map \*perf_evsel__cpus(struct perf_evsel \*evsel); + struct perf_thread_map \*perf_evsel__threads(struct perf_evsel \*evsel); + struct perf_event_attr \*perf_evsel__attr(struct perf_evsel \*evsel); diff --git a/tools/perf/lib/Documentation/tutorial/tutorial.rst b/tools/perf/lib/Documentation/tutorial/tutorial.rst new file mode 100644 index 000000000000..7be7bc27b385 --- /dev/null +++ b/tools/perf/lib/Documentation/tutorial/tutorial.rst @@ -0,0 +1,123 @@ +.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) + +libperf tutorial +================ + +Compile and install libperf from kernel sources +=============================================== +.. code-block:: bash + + git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git + cd linux/tools/perf/lib + make + sudo make install prefix=/usr + +Libperf object +============== +The libperf library provides several high level objects: + +struct perf_cpu_map + Provides a cpu list abstraction. + +struct perf_thread_map + Provides a thread list abstraction. + +struct perf_evsel + Provides an abstraction for single a perf event. + +struct perf_evlist + Gathers several struct perf_evsel object and performs functions on all of them. + +The exported API binds these objects together, +for full reference see the libperf.7 man page. + +Examples +======== +Examples aim to explain libperf functionality on simple use cases. +They are based in on a checked out linux kernel git tree: + +.. code-block:: bash + + $ cd tools/perf/lib/Documentation/tutorial/ + $ ls -d ex-* + ex-1-compile ex-2-evsel-stat ex-3-evlist-stat + +ex-1-compile example +==================== +This example shows the basic usage of *struct perf_cpu_map*, +how to create it and display its cpus: + +.. code-block:: bash + + $ cd ex-1-compile/ + $ make + gcc -o test test.c -lperf + $ ./test + 0 1 2 3 4 5 6 7 + + +The full code listing is here: + +.. code-block:: c + + 1 #include + 2 + 3 int main(int argc, char **Argv) + 4 { + 5 struct perf_cpu_map *cpus; + 6 int cpu, tmp; + 7 + 8 cpus = perf_cpu_map__new(NULL); + 9 + 10 perf_cpu_map__for_each_cpu(cpu, tmp, cpus) + 11 fprintf(stdout, "%d ", cpu); + 12 + 13 fprintf(stdout, "\n"); + 14 + 15 perf_cpu_map__put(cpus); + 16 return 0; + 17 } + + +First you need to include the proper header to have *struct perf_cpumap* +declaration and functions: + +.. code-block:: c + + 1 #include + + +The *struct perf_cpumap* object is created by *perf_cpu_map__new* call. +The *NULL* argument asks it to populate the object with the current online CPUs list: + +.. code-block:: c + + 8 cpus = perf_cpu_map__new(NULL); + +This is paired with a *perf_cpu_map__put*, that drops its reference at the end, possibly deleting it. + +.. code-block:: c + + 15 perf_cpu_map__put(cpus); + +The iteration through the *struct perf_cpumap* CPUs is done using the *perf_cpu_map__for_each_cpu* +macro which requires 3 arguments: + +- cpu - the cpu numer +- tmp - iteration helper variable +- cpus - the *struct perf_cpumap* object + +.. code-block:: c + + 10 perf_cpu_map__for_each_cpu(cpu, tmp, cpus) + 11 fprintf(stdout, "%d ", cpu); + +ex-2-evsel-stat example +======================= + +TBD + +ex-3-evlist-stat example +======================== + +TBD -- cgit v1.2.3-59-g8ed1b From 123a039d0d54de6d5bafd551e7aa17569e13e315 Mon Sep 17 00:00:00 2001 From: Michael Petlan Date: Fri, 19 Jul 2019 12:08:37 +0200 Subject: perf vendor events power9: Added missing event descriptions Documentation source: https://wiki.raptorcs.com/w/images/6/6b/POWER9_PMU_UG_v12_28NOV2018_pub.pdf Signed-off-by: Michael Petlan Reviewed-by: Madhavan Srinivasan Cc: Ananth N Mavinakayanahalli Cc: Carl Love Cc: Michael Ellerman Cc: Naveen N. Rao Cc: Paul Clarke Cc: Sukadev Bhattiprolu Cc: linuxppc-dev@ozlabs.org LPU-Reference: 20190719100837.7503-1-mpetlan@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/pmu-events/arch/powerpc/power9/memory.json | 2 +- tools/perf/pmu-events/arch/powerpc/power9/other.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/perf/pmu-events/arch/powerpc/power9/memory.json b/tools/perf/pmu-events/arch/powerpc/power9/memory.json index 2e2ebc700c74..c3bb283e37e9 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/memory.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/memory.json @@ -52,7 +52,7 @@ {, "EventCode": "0x4D02C", "EventName": "PM_PMC1_REWIND", - "BriefDescription": "" + "BriefDescription": "PMC1 rewind event" }, {, "EventCode": "0x15158", diff --git a/tools/perf/pmu-events/arch/powerpc/power9/other.json b/tools/perf/pmu-events/arch/powerpc/power9/other.json index 48cf4f920b3f..62b864269623 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/other.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/other.json @@ -237,7 +237,7 @@ {, "EventCode": "0xD0B0", "EventName": "PM_HWSYNC", - "BriefDescription": "" + "BriefDescription": "A hwsync instruction was decoded and transferred" }, {, "EventCode": "0x168B0", @@ -1232,7 +1232,7 @@ {, "EventCode": "0xD8AC", "EventName": "PM_LWSYNC", - "BriefDescription": "" + "BriefDescription": "An lwsync instruction was decoded and transferred" }, {, "EventCode": "0x2094", @@ -1747,7 +1747,7 @@ {, "EventCode": "0xD8B0", "EventName": "PM_PTESYNC", - "BriefDescription": "" + "BriefDescription": "A ptesync instruction was counted when the instruction is decoded and transmitted" }, {, "EventCode": "0x26086", @@ -2107,7 +2107,7 @@ {, "EventCode": "0xF080", "EventName": "PM_LSU_STCX_FAIL", - "BriefDescription": "" + "BriefDescription": "The LSU detects the condition that a stcx instruction failed. No requirement to wait for a response from the nest" }, {, "EventCode": "0x30038", -- cgit v1.2.3-59-g8ed1b From 3745ee18017e36be34f6f2a81e802a20e54e5e8b Mon Sep 17 00:00:00 2001 From: Petar Penkov Date: Mon, 29 Jul 2019 09:59:16 -0700 Subject: bpf: sync bpf.h to tools/ Sync updated documentation for bpf_redirect_map. Sync the bpf_tcp_gen_syncookie helper function definition with the one in tools/uapi. Signed-off-by: Petar Penkov Reviewed-by: Lorenz Bauer Signed-off-by: Alexei Starovoitov --- tools/include/uapi/linux/bpf.h | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 21d0f6863df3..4393bd4b2419 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -1572,8 +1572,11 @@ union bpf_attr { * but this is only implemented for native XDP (with driver * support) as of this writing). * - * All values for *flags* are reserved for future usage, and must - * be left at zero. + * The lower two bits of *flags* are used as the return code if + * the map lookup fails. This is so that the return value can be + * one of the XDP program return codes up to XDP_TX, as chosen by + * the caller. Any higher bits in the *flags* argument must be + * unset. * * When used to redirect packets to net devices, this helper * provides a high performance increase over **bpf_redirect**\ (). @@ -2711,6 +2714,33 @@ union bpf_attr { * **-EPERM** if no permission to send the *sig*. * * **-EAGAIN** if bpf program can try again. + * + * s64 bpf_tcp_gen_syncookie(struct bpf_sock *sk, void *iph, u32 iph_len, struct tcphdr *th, u32 th_len) + * Description + * Try to issue a SYN cookie for the packet with corresponding + * IP/TCP headers, *iph* and *th*, on the listening socket in *sk*. + * + * *iph* points to the start of the IPv4 or IPv6 header, while + * *iph_len* contains **sizeof**\ (**struct iphdr**) or + * **sizeof**\ (**struct ip6hdr**). + * + * *th* points to the start of the TCP header, while *th_len* + * contains the length of the TCP header. + * + * Return + * On success, lower 32 bits hold the generated SYN cookie in + * followed by 16 bits which hold the MSS value for that cookie, + * and the top 16 bits are unused. + * + * On failure, the returned value is one of the following: + * + * **-EINVAL** SYN cookie cannot be issued due to error + * + * **-ENOENT** SYN cookie should not be issued (no SYN flood) + * + * **-EOPNOTSUPP** kernel configuration does not enable SYN cookies + * + * **-EPROTONOSUPPORT** IP packet version is not 4 or 6 */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -2822,7 +2852,8 @@ union bpf_attr { FN(strtoul), \ FN(sk_storage_get), \ FN(sk_storage_delete), \ - FN(send_signal), + FN(send_signal), \ + FN(tcp_gen_syncookie), /* integer value in 'imm' field of BPF_CALL instruction selects which helper * function eBPF program intends to call -- cgit v1.2.3-59-g8ed1b From 637f71c09ba22d1042f5b48b58c249ee5665d44d Mon Sep 17 00:00:00 2001 From: Petar Penkov Date: Mon, 29 Jul 2019 09:59:17 -0700 Subject: selftests/bpf: bpf_tcp_gen_syncookie->bpf_helpers Expose bpf_tcp_gen_syncookie to selftests. Signed-off-by: Petar Penkov Reviewed-by: Lorenz Bauer Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/bpf_helpers.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h index f804f210244e..120aa86c58d3 100644 --- a/tools/testing/selftests/bpf/bpf_helpers.h +++ b/tools/testing/selftests/bpf/bpf_helpers.h @@ -228,6 +228,9 @@ static void *(*bpf_sk_storage_get)(void *map, struct bpf_sock *sk, static int (*bpf_sk_storage_delete)(void *map, struct bpf_sock *sk) = (void *)BPF_FUNC_sk_storage_delete; static int (*bpf_send_signal)(unsigned sig) = (void *)BPF_FUNC_send_signal; +static long long (*bpf_tcp_gen_syncookie)(struct bpf_sock *sk, void *ip, + int ip_len, void *tcp, int tcp_len) = + (void *) BPF_FUNC_tcp_gen_syncookie; /* llvm builtin functions that eBPF C program may use to * emit BPF_LD_ABS and BPF_LD_IND instructions -- cgit v1.2.3-59-g8ed1b From 91bc35789db4e1a489be7ab6e318e6265202e096 Mon Sep 17 00:00:00 2001 From: Petar Penkov Date: Mon, 29 Jul 2019 09:59:18 -0700 Subject: selftests/bpf: add test for bpf_tcp_gen_syncookie Modify the existing bpf_tcp_check_syncookie test to also generate a SYN cookie, pass the packet to the kernel, and verify that the two cookies are the same (and both valid). Since cloned SKBs are skipped during generic XDP, this test does not issue a SYN cookie when run in XDP mode. We therefore only check that a valid SYN cookie was issued at the TC hook. Additionally, verify that the MSS for that SYN cookie is within expected range. Signed-off-by: Petar Penkov Reviewed-by: Lorenz Bauer Signed-off-by: Alexei Starovoitov --- .../bpf/progs/test_tcp_check_syncookie_kern.c | 48 +++++++++++++++-- .../selftests/bpf/test_tcp_check_syncookie.sh | 3 ++ .../selftests/bpf/test_tcp_check_syncookie_user.c | 61 +++++++++++++++++++--- 3 files changed, 99 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/progs/test_tcp_check_syncookie_kern.c b/tools/testing/selftests/bpf/progs/test_tcp_check_syncookie_kern.c index 1ab095bcacd8..d8803dfa8d32 100644 --- a/tools/testing/selftests/bpf/progs/test_tcp_check_syncookie_kern.c +++ b/tools/testing/selftests/bpf/progs/test_tcp_check_syncookie_kern.c @@ -19,10 +19,29 @@ struct bpf_map_def SEC("maps") results = { .type = BPF_MAP_TYPE_ARRAY, .key_size = sizeof(__u32), - .value_size = sizeof(__u64), - .max_entries = 1, + .value_size = sizeof(__u32), + .max_entries = 3, }; +static __always_inline __s64 gen_syncookie(void *data_end, struct bpf_sock *sk, + void *iph, __u32 ip_size, + struct tcphdr *tcph) +{ + __u32 thlen = tcph->doff * 4; + + if (tcph->syn && !tcph->ack) { + // packet should only have an MSS option + if (thlen != 24) + return 0; + + if ((void *)tcph + thlen > data_end) + return 0; + + return bpf_tcp_gen_syncookie(sk, iph, ip_size, tcph, thlen); + } + return 0; +} + static __always_inline void check_syncookie(void *ctx, void *data, void *data_end) { @@ -33,8 +52,10 @@ static __always_inline void check_syncookie(void *ctx, void *data, struct ipv6hdr *ipv6h; struct tcphdr *tcph; int ret; + __u32 key_mss = 2; + __u32 key_gen = 1; __u32 key = 0; - __u64 value = 1; + __s64 seq_mss; ethh = data; if (ethh + 1 > data_end) @@ -66,6 +87,9 @@ static __always_inline void check_syncookie(void *ctx, void *data, if (sk->state != BPF_TCP_LISTEN) goto release; + seq_mss = gen_syncookie(data_end, sk, ipv4h, sizeof(*ipv4h), + tcph); + ret = bpf_tcp_check_syncookie(sk, ipv4h, sizeof(*ipv4h), tcph, sizeof(*tcph)); break; @@ -95,6 +119,9 @@ static __always_inline void check_syncookie(void *ctx, void *data, if (sk->state != BPF_TCP_LISTEN) goto release; + seq_mss = gen_syncookie(data_end, sk, ipv6h, sizeof(*ipv6h), + tcph); + ret = bpf_tcp_check_syncookie(sk, ipv6h, sizeof(*ipv6h), tcph, sizeof(*tcph)); break; @@ -103,8 +130,19 @@ static __always_inline void check_syncookie(void *ctx, void *data, return; } - if (ret == 0) - bpf_map_update_elem(&results, &key, &value, 0); + if (seq_mss > 0) { + __u32 cookie = (__u32)seq_mss; + __u32 mss = seq_mss >> 32; + + bpf_map_update_elem(&results, &key_gen, &cookie, 0); + bpf_map_update_elem(&results, &key_mss, &mss, 0); + } + + if (ret == 0) { + __u32 cookie = bpf_ntohl(tcph->ack_seq) - 1; + + bpf_map_update_elem(&results, &key, &cookie, 0); + } release: bpf_sk_release(sk); diff --git a/tools/testing/selftests/bpf/test_tcp_check_syncookie.sh b/tools/testing/selftests/bpf/test_tcp_check_syncookie.sh index d48e51716d19..9b3617d770a5 100755 --- a/tools/testing/selftests/bpf/test_tcp_check_syncookie.sh +++ b/tools/testing/selftests/bpf/test_tcp_check_syncookie.sh @@ -37,6 +37,9 @@ setup() ns1_exec ip link set lo up ns1_exec sysctl -w net.ipv4.tcp_syncookies=2 + ns1_exec sysctl -w net.ipv4.tcp_window_scaling=0 + ns1_exec sysctl -w net.ipv4.tcp_timestamps=0 + ns1_exec sysctl -w net.ipv4.tcp_sack=0 wait_for_ip 127.0.0.1 wait_for_ip ::1 diff --git a/tools/testing/selftests/bpf/test_tcp_check_syncookie_user.c b/tools/testing/selftests/bpf/test_tcp_check_syncookie_user.c index 87829c86c746..b9e991d43155 100644 --- a/tools/testing/selftests/bpf/test_tcp_check_syncookie_user.c +++ b/tools/testing/selftests/bpf/test_tcp_check_syncookie_user.c @@ -2,6 +2,7 @@ // Copyright (c) 2018 Facebook // Copyright (c) 2019 Cloudflare +#include #include #include #include @@ -77,7 +78,7 @@ out: return fd; } -static int get_map_fd_by_prog_id(int prog_id) +static int get_map_fd_by_prog_id(int prog_id, bool *xdp) { struct bpf_prog_info info = {}; __u32 info_len = sizeof(info); @@ -104,6 +105,8 @@ static int get_map_fd_by_prog_id(int prog_id) goto err; } + *xdp = info.type == BPF_PROG_TYPE_XDP; + map_fd = bpf_map_get_fd_by_id(map_ids[0]); if (map_fd < 0) log_err("Failed to get fd by map id %d", map_ids[0]); @@ -113,18 +116,32 @@ err: return map_fd; } -static int run_test(int server_fd, int results_fd) +static int run_test(int server_fd, int results_fd, bool xdp) { int client = -1, srv_client = -1; int ret = 0; __u32 key = 0; - __u64 value = 0; + __u32 key_gen = 1; + __u32 key_mss = 2; + __u32 value = 0; + __u32 value_gen = 0; + __u32 value_mss = 0; if (bpf_map_update_elem(results_fd, &key, &value, 0) < 0) { log_err("Can't clear results"); goto err; } + if (bpf_map_update_elem(results_fd, &key_gen, &value_gen, 0) < 0) { + log_err("Can't clear results"); + goto err; + } + + if (bpf_map_update_elem(results_fd, &key_mss, &value_mss, 0) < 0) { + log_err("Can't clear results"); + goto err; + } + client = connect_to_server(server_fd); if (client == -1) goto err; @@ -140,8 +157,35 @@ static int run_test(int server_fd, int results_fd) goto err; } - if (value != 1) { - log_err("Didn't match syncookie: %llu", value); + if (value == 0) { + log_err("Didn't match syncookie: %u", value); + goto err; + } + + if (bpf_map_lookup_elem(results_fd, &key_gen, &value_gen) < 0) { + log_err("Can't lookup result"); + goto err; + } + + if (xdp && value_gen == 0) { + // SYN packets do not get passed through generic XDP, skip the + // rest of the test. + printf("Skipping XDP cookie check\n"); + goto out; + } + + if (bpf_map_lookup_elem(results_fd, &key_mss, &value_mss) < 0) { + log_err("Can't lookup result"); + goto err; + } + + if (value != value_gen) { + log_err("BPF generated cookie does not match kernel one"); + goto err; + } + + if (value_mss < 536 || value_mss > USHRT_MAX) { + log_err("Unexpected MSS retrieved"); goto err; } @@ -163,13 +207,14 @@ int main(int argc, char **argv) int server_v6 = -1; int results = -1; int err = 0; + bool xdp; if (argc < 2) { fprintf(stderr, "Usage: %s prog_id\n", argv[0]); exit(1); } - results = get_map_fd_by_prog_id(atoi(argv[1])); + results = get_map_fd_by_prog_id(atoi(argv[1]), &xdp); if (results < 0) { log_err("Can't get map"); goto err; @@ -194,10 +239,10 @@ int main(int argc, char **argv) if (server_v6 == -1) goto err; - if (run_test(server, results)) + if (run_test(server, results, xdp)) goto err; - if (run_test(server_v6, results)) + if (run_test(server_v6, results, xdp)) goto err; printf("ok\n"); -- cgit v1.2.3-59-g8ed1b From bf8ff0f8cfd73e850c01b453ddb79609bd83279c Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Tue, 30 Jul 2019 11:05:41 -0700 Subject: selftests/bpf: fix clearing buffered output between tests/subtests Clear buffered output once test or subtests finishes even if test was successful. Not doing this leads to accumulation of output from previous tests and on first failed tests lots of irrelevant output will be dumped, greatly confusing things. v1->v2: fix Fixes tag, add more context to patch Fixes: 3a516a0a3a7b ("selftests/bpf: add sub-tests support for test_progs") Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/test_progs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index 546d99b3ec34..db00196c8315 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -46,8 +46,8 @@ static void dump_test_log(const struct prog_test_def *test, bool failed) if (env.log_buf[env.log_cnt - 1] != '\n') fprintf(stdout, "\n"); } - env.log_cnt = 0; } + env.log_cnt = 0; } void test__end_subtest() -- cgit v1.2.3-59-g8ed1b From a98bf57391a24a68ec8381b9d35b60c2bee79150 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Tue, 30 Jul 2019 14:03:00 -0700 Subject: tools: bpftool: add support for reporting the effective cgroup progs Takshak said in the original submission: With different bpf attach_flags available to attach bpf programs specially with BPF_F_ALLOW_OVERRIDE and BPF_F_ALLOW_MULTI, the list of effective bpf-programs available to any sub-cgroups really needs to be available for easy debugging. Using BPF_F_QUERY_EFFECTIVE flag, one can get the list of not only attached bpf-programs to a cgroup but also the inherited ones from parent cgroup. So a new option is introduced to use BPF_F_QUERY_EFFECTIVE query flag here to list all the effective bpf-programs available for execution at a specified cgroup. Reused modified test program test_cgroup_attach from tools/testing/selftests/bpf: # ./test_cgroup_attach With old bpftool: # bpftool cgroup show /sys/fs/cgroup/cgroup-test-work-dir/cg1/ ID AttachType AttachFlags Name 271 egress multi pkt_cntr_1 272 egress multi pkt_cntr_2 Attached new program pkt_cntr_4 in cg2 gives following: # bpftool cgroup show /sys/fs/cgroup/cgroup-test-work-dir/cg1/cg2 ID AttachType AttachFlags Name 273 egress override pkt_cntr_4 And with new "effective" option it shows all effective programs for cg2: # bpftool cgroup show /sys/fs/cgroup/cgroup-test-work-dir/cg1/cg2 effective ID AttachType AttachFlags Name 273 egress override pkt_cntr_4 271 egress override pkt_cntr_1 272 egress override pkt_cntr_2 Compared to original submission use a local flag instead of global option. We need to clear query_flags on every command, in case batch mode wants to use varying settings. v2: (Takshak) - forbid duplicated flags; - fix cgroup path freeing. Signed-off-by: Takshak Chahande Signed-off-by: Jakub Kicinski Reviewed-by: Quentin Monnet Reviewed-by: Takshak Chahande Signed-off-by: Alexei Starovoitov --- tools/bpf/bpftool/Documentation/bpftool-cgroup.rst | 16 +++-- tools/bpf/bpftool/bash-completion/bpftool | 15 ++-- tools/bpf/bpftool/cgroup.c | 83 ++++++++++++++-------- 3 files changed, 76 insertions(+), 38 deletions(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst index 585f270c2d25..06a28b07787d 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst @@ -20,8 +20,8 @@ SYNOPSIS CGROUP COMMANDS =============== -| **bpftool** **cgroup { show | list }** *CGROUP* -| **bpftool** **cgroup tree** [*CGROUP_ROOT*] +| **bpftool** **cgroup { show | list }** *CGROUP* [**effective**] +| **bpftool** **cgroup tree** [*CGROUP_ROOT*] [**effective**] | **bpftool** **cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*] | **bpftool** **cgroup detach** *CGROUP* *ATTACH_TYPE* *PROG* | **bpftool** **cgroup help** @@ -35,13 +35,17 @@ CGROUP COMMANDS DESCRIPTION =========== - **bpftool cgroup { show | list }** *CGROUP* + **bpftool cgroup { show | list }** *CGROUP* [**effective**] List all programs attached to the cgroup *CGROUP*. Output will start with program ID followed by attach type, attach flags and program name. - **bpftool cgroup tree** [*CGROUP_ROOT*] + If **effective** is specified retrieve effective programs that + will execute for events within a cgroup. This includes + inherited along with attached ones. + + **bpftool cgroup tree** [*CGROUP_ROOT*] [**effective**] Iterate over all cgroups in *CGROUP_ROOT* and list all attached programs. If *CGROUP_ROOT* is not specified, bpftool uses cgroup v2 mountpoint. @@ -50,6 +54,10 @@ DESCRIPTION commands: it starts with absolute cgroup path, followed by program ID, attach type, attach flags and program name. + If **effective** is specified retrieve effective programs that + will execute for events within a cgroup. This includes + inherited along with attached ones. + **bpftool cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*] Attach program *PROG* to the cgroup *CGROUP* with attach type *ATTACH_TYPE* and optional *ATTACH_FLAGS*. diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool index 6b961a5ed100..df16c5415444 100644 --- a/tools/bpf/bpftool/bash-completion/bpftool +++ b/tools/bpf/bpftool/bash-completion/bpftool @@ -710,12 +710,15 @@ _bpftool() ;; cgroup) case $command in - show|list) - _filedir - return 0 - ;; - tree) - _filedir + show|list|tree) + case $cword in + 3) + _filedir + ;; + 4) + COMPREPLY=( $( compgen -W 'effective' -- "$cur" ) ) + ;; + esac return 0 ;; attach|detach) diff --git a/tools/bpf/bpftool/cgroup.c b/tools/bpf/bpftool/cgroup.c index f3c05b08c68c..44352b5aca85 100644 --- a/tools/bpf/bpftool/cgroup.c +++ b/tools/bpf/bpftool/cgroup.c @@ -29,6 +29,8 @@ " recvmsg4 | recvmsg6 | sysctl |\n" \ " getsockopt | setsockopt }" +static unsigned int query_flags; + static const char * const attach_type_strings[] = { [BPF_CGROUP_INET_INGRESS] = "ingress", [BPF_CGROUP_INET_EGRESS] = "egress", @@ -107,7 +109,8 @@ static int count_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type) __u32 prog_cnt = 0; int ret; - ret = bpf_prog_query(cgroup_fd, type, 0, NULL, NULL, &prog_cnt); + ret = bpf_prog_query(cgroup_fd, type, query_flags, NULL, + NULL, &prog_cnt); if (ret) return -1; @@ -125,8 +128,8 @@ static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type, int ret; prog_cnt = ARRAY_SIZE(prog_ids); - ret = bpf_prog_query(cgroup_fd, type, 0, &attach_flags, prog_ids, - &prog_cnt); + ret = bpf_prog_query(cgroup_fd, type, query_flags, &attach_flags, + prog_ids, &prog_cnt); if (ret) return ret; @@ -158,20 +161,34 @@ static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type, static int do_show(int argc, char **argv) { enum bpf_attach_type type; + const char *path; int cgroup_fd; int ret = -1; - if (argc < 1) { - p_err("too few parameters for cgroup show"); - goto exit; - } else if (argc > 1) { - p_err("too many parameters for cgroup show"); - goto exit; + query_flags = 0; + + if (!REQ_ARGS(1)) + return -1; + path = GET_ARG(); + + while (argc) { + if (is_prefix(*argv, "effective")) { + if (query_flags & BPF_F_QUERY_EFFECTIVE) { + p_err("duplicated argument: %s", *argv); + return -1; + } + query_flags |= BPF_F_QUERY_EFFECTIVE; + NEXT_ARG(); + } else { + p_err("expected no more arguments, 'effective', got: '%s'?", + *argv); + return -1; + } } - cgroup_fd = open(argv[0], O_RDONLY); + cgroup_fd = open(path, O_RDONLY); if (cgroup_fd < 0) { - p_err("can't open cgroup %s", argv[0]); + p_err("can't open cgroup %s", path); goto exit; } @@ -294,26 +311,37 @@ static char *find_cgroup_root(void) static int do_show_tree(int argc, char **argv) { - char *cgroup_root; + char *cgroup_root, *cgroup_alloced = NULL; int ret; - switch (argc) { - case 0: - cgroup_root = find_cgroup_root(); - if (!cgroup_root) { + query_flags = 0; + + if (!argc) { + cgroup_alloced = find_cgroup_root(); + if (!cgroup_alloced) { p_err("cgroup v2 isn't mounted"); return -1; } - break; - case 1: - cgroup_root = argv[0]; - break; - default: - p_err("too many parameters for cgroup tree"); - return -1; + cgroup_root = cgroup_alloced; + } else { + cgroup_root = GET_ARG(); + + while (argc) { + if (is_prefix(*argv, "effective")) { + if (query_flags & BPF_F_QUERY_EFFECTIVE) { + p_err("duplicated argument: %s", *argv); + return -1; + } + query_flags |= BPF_F_QUERY_EFFECTIVE; + NEXT_ARG(); + } else { + p_err("expected no more arguments, 'effective', got: '%s'?", + *argv); + return -1; + } + } } - if (json_output) jsonw_start_array(json_wtr); else @@ -338,8 +366,7 @@ static int do_show_tree(int argc, char **argv) if (json_output) jsonw_end_array(json_wtr); - if (argc == 0) - free(cgroup_root); + free(cgroup_alloced); return ret; } @@ -459,8 +486,8 @@ static int do_help(int argc, char **argv) } fprintf(stderr, - "Usage: %s %s { show | list } CGROUP\n" - " %s %s tree [CGROUP_ROOT]\n" + "Usage: %s %s { show | list } CGROUP [**effective**]\n" + " %s %s tree [CGROUP_ROOT] [**effective**]\n" " %s %s attach CGROUP ATTACH_TYPE PROG [ATTACH_FLAGS]\n" " %s %s detach CGROUP ATTACH_TYPE PROG\n" " %s %s help\n" -- cgit v1.2.3-59-g8ed1b From 7700476f319844022f6e469e7acb578178ee29de Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Wed, 31 Jul 2019 10:30:26 +0000 Subject: selftests: mlxsw: Fix local variable declarations in DSCP tests These two tests have some problems in the global scope pollution and on contrary, contain unnecessary local declarations. Fix them. Signed-off-by: Petr Machata Signed-off-by: David S. Miller --- tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh | 6 ++++-- tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh index 40f16f2a3afd..5cbff8038f84 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh @@ -36,8 +36,6 @@ source $lib_dir/lib.sh h1_create() { - local dscp; - simple_if_init $h1 192.0.2.1/28 tc qdisc add dev $h1 clsact dscp_capture_install $h1 10 @@ -67,6 +65,7 @@ h2_destroy() dscp_map() { local base=$1; shift + local prio for prio in {0..7}; do echo app=$prio,5,$((base + prio)) @@ -138,6 +137,7 @@ dscp_ping_test() local prio=$1; shift local dev_10=$1; shift local dev_20=$1; shift + local key local dscp_10=$(((prio + 10) << 2)) local dscp_20=$(((prio + 20) << 2)) @@ -175,6 +175,8 @@ dscp_ping_test() test_dscp() { + local prio + for prio in {0..7}; do dscp_ping_test v$h1 192.0.2.1 192.0.2.2 $prio $h1 $h2 done diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh index 9faf02e32627..f25e3229e1cc 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh @@ -52,8 +52,6 @@ reprioritize() h1_create() { - local dscp; - simple_if_init $h1 192.0.2.1/28 tc qdisc add dev $h1 clsact dscp_capture_install $h1 0 @@ -87,6 +85,7 @@ h2_destroy() dscp_map() { local base=$1; shift + local prio for prio in {0..7}; do echo app=$prio,5,$((base + prio)) @@ -156,6 +155,7 @@ dscp_ping_test() local reprio=$1; shift local dev1=$1; shift local dev2=$1; shift + local i local prio2=$($reprio $prio) # ICMP Request egress prio local prio3=$($reprio $prio2) # ICMP Response egress prio @@ -205,6 +205,7 @@ __test_update() { local update=$1; shift local reprio=$1; shift + local prio sysctl_restore net.ipv4.ip_forward_update_priority sysctl_set net.ipv4.ip_forward_update_priority $update -- cgit v1.2.3-59-g8ed1b From d11786bb9664a5bed47e7839265f49bb26d54a1b Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Wed, 31 Jul 2019 10:30:27 +0000 Subject: selftests: mlxsw: Add a test for leftover DSCP rule Commit dedfde2fe1c4 ("mlxsw: spectrum_dcb: Configure DSCP map as the last rule is removed") fixed a problem in mlxsw where last DSCP rule to be removed remained in effect when DSCP rewrite was applied. Add a selftest that covers this problem. Signed-off-by: Petr Machata Signed-off-by: David S. Miller --- .../selftests/drivers/net/mlxsw/qos_dscp_router.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh index f25e3229e1cc..c745ce3befee 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh @@ -31,6 +31,7 @@ ALL_TESTS=" ping_ipv4 test_update test_no_update + test_dscp_leftover " lib_dir=$(dirname $0)/../../../net/forwarding @@ -50,6 +51,11 @@ reprioritize() echo ${reprio[$in]} } +zero() +{ + echo 0 +} + h1_create() { simple_if_init $h1 192.0.2.1/28 @@ -225,6 +231,19 @@ test_no_update() __test_update 0 echo } +# Test that when the last APP rule is removed, the prio->DSCP map is properly +# set to zeroes, and that the last APP rule does not stay active in the ASIC. +test_dscp_leftover() +{ + lldptool -T -i $swp2 -V APP -d $(dscp_map 0) >/dev/null + lldpad_app_wait_del + + __test_update 0 zero + + lldptool -T -i $swp2 -V APP $(dscp_map 0) >/dev/null + lldpad_app_wait_set $swp2 +} + trap cleanup EXIT setup_prepare -- cgit v1.2.3-59-g8ed1b From 0eba31ef5c8913adfd103c45c32d4856f1aa85cc Mon Sep 17 00:00:00 2001 From: Lucas Bates Date: Mon, 29 Jul 2019 19:18:12 -0400 Subject: tc-testing: Clarify the use of tdc's -d option The -d command line argument to tdc requires the name of a physical device on the system where the tests will be run. If -d has not been used, tdc will skip tests that require a physical device. This patch is intended to better document what the -d option does and how it is used. Signed-off-by: Lucas Bates Signed-off-by: David S. Miller --- tools/testing/selftests/tc-testing/README | 4 +++- tools/testing/selftests/tc-testing/tdc.py | 12 ++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/tc-testing/README b/tools/testing/selftests/tc-testing/README index 22e5da9008fd..b0954c873e2f 100644 --- a/tools/testing/selftests/tc-testing/README +++ b/tools/testing/selftests/tc-testing/README @@ -128,7 +128,9 @@ optional arguments: -v, --verbose Show the commands that are being run -N, --notap Suppress tap results for command under test -d DEVICE, --device DEVICE - Execute the test case in flower category + Execute test cases that use a physical device, where + DEVICE is its name. (If not defined, tests that require + a physical device will be skipped) -P, --pause Pause execution just before post-suite stage selection: diff --git a/tools/testing/selftests/tc-testing/tdc.py b/tools/testing/selftests/tc-testing/tdc.py index f04321ace9fb..e566c70e64a1 100755 --- a/tools/testing/selftests/tc-testing/tdc.py +++ b/tools/testing/selftests/tc-testing/tdc.py @@ -356,12 +356,14 @@ def test_runner(pm, args, filtered_tests): time.sleep(2) for tidx in testlist: if "flower" in tidx["category"] and args.device == None: + errmsg = "Tests using the DEV2 variable must define the name of a " + errmsg += "physical NIC with the -d option when running tdc.\n" + errmsg += "Test has been skipped." if args.verbose > 1: - print('Not executing test {} {} because DEV2 not defined'. - format(tidx['id'], tidx['name'])) + print(errmsg) res = TestResult(tidx['id'], tidx['name']) res.set_result(ResultState.skip) - res.set_errormsg('Not executed because DEV2 is not defined') + res.set_errormsg(errmsg) tsr.add_resultdata(res) continue try: @@ -499,7 +501,9 @@ def set_args(parser): choices=['none', 'xunit', 'tap'], help='Specify the format for test results. (Default: TAP)') parser.add_argument('-d', '--device', - help='Execute the test case in flower category') + help='Execute test cases that use a physical device, ' + + 'where DEVICE is its name. (If not defined, tests ' + + 'that require a physical device will be skipped)') parser.add_argument( '-P', '--pause', action='store_true', help='Pause execution just before post-suite stage') -- cgit v1.2.3-59-g8ed1b From 56fbc24116f458a0ea48f9f37fe770fd791042d9 Mon Sep 17 00:00:00 2001 From: Takshak Chahande Date: Wed, 31 Jul 2019 15:10:55 -0700 Subject: libbpf : make libbpf_num_possible_cpus function thread safe Having static variable `cpus` in libbpf_num_possible_cpus function without guarding it with mutex makes this function thread-unsafe. If multiple threads accessing this function, in the current form; it leads to incrementing the static variable value `cpus` in the multiple of total available CPUs. Used local stack variable to calculate the number of possible CPUs and then updated the static variable using WRITE_ONCE(). Changes since v1: * added stack variable to calculate cpus * serialized static variable update using WRITE_ONCE() * fixed Fixes tag Fixes: 6446b3155521 ("bpf: add a new API libbpf_num_possible_cpus()") Signed-off-by: Takshak Chahande Acked-by: Andrey Ignatov Reviewed-by: Jakub Kicinski Signed-off-by: Alexei Starovoitov --- tools/lib/bpf/libbpf.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 6718d0b90130..2e84fa5b8479 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -4995,13 +4995,15 @@ int libbpf_num_possible_cpus(void) static const char *fcpu = "/sys/devices/system/cpu/possible"; int len = 0, n = 0, il = 0, ir = 0; unsigned int start = 0, end = 0; + int tmp_cpus = 0; static int cpus; char buf[128]; int error = 0; int fd = -1; - if (cpus > 0) - return cpus; + tmp_cpus = READ_ONCE(cpus); + if (tmp_cpus > 0) + return tmp_cpus; fd = open(fcpu, O_RDONLY); if (fd < 0) { @@ -5024,7 +5026,7 @@ int libbpf_num_possible_cpus(void) } buf[len] = '\0'; - for (ir = 0, cpus = 0; ir <= len; ir++) { + for (ir = 0, tmp_cpus = 0; ir <= len; ir++) { /* Each sub string separated by ',' has format \d+-\d+ or \d+ */ if (buf[ir] == ',' || buf[ir] == '\0') { buf[ir] = '\0'; @@ -5036,13 +5038,15 @@ int libbpf_num_possible_cpus(void) } else if (n == 1) { end = start; } - cpus += end - start + 1; + tmp_cpus += end - start + 1; il = ir + 1; } } - if (cpus <= 0) { - pr_warning("Invalid #CPUs %d from %s\n", cpus, fcpu); + if (tmp_cpus <= 0) { + pr_warning("Invalid #CPUs %d from %s\n", tmp_cpus, fcpu); return -EINVAL; } - return cpus; + + WRITE_ONCE(cpus, tmp_cpus); + return tmp_cpus; } -- cgit v1.2.3-59-g8ed1b From 7455cdd1a0fe9a1367ee99596ea2564031daec00 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 11 Feb 2019 12:13:57 -0800 Subject: tools/memory-model: Make scripts be executable This commit simplifies life a bit by making all of the scripts in tools/memory-model/scripts be executable. Signed-off-by: Paul E. McKenney --- tools/memory-model/scripts/checkghlitmus.sh | 0 tools/memory-model/scripts/checklitmushist.sh | 0 tools/memory-model/scripts/cmplitmushist.sh | 0 tools/memory-model/scripts/initlitmushist.sh | 0 tools/memory-model/scripts/judgelitmus.sh | 0 tools/memory-model/scripts/newlitmushist.sh | 0 tools/memory-model/scripts/parseargs.sh | 0 tools/memory-model/scripts/runlitmushist.sh | 0 8 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tools/memory-model/scripts/checkghlitmus.sh mode change 100644 => 100755 tools/memory-model/scripts/checklitmushist.sh mode change 100644 => 100755 tools/memory-model/scripts/cmplitmushist.sh mode change 100644 => 100755 tools/memory-model/scripts/initlitmushist.sh mode change 100644 => 100755 tools/memory-model/scripts/judgelitmus.sh mode change 100644 => 100755 tools/memory-model/scripts/newlitmushist.sh mode change 100644 => 100755 tools/memory-model/scripts/parseargs.sh mode change 100644 => 100755 tools/memory-model/scripts/runlitmushist.sh (limited to 'tools') diff --git a/tools/memory-model/scripts/checkghlitmus.sh b/tools/memory-model/scripts/checkghlitmus.sh old mode 100644 new mode 100755 diff --git a/tools/memory-model/scripts/checklitmushist.sh b/tools/memory-model/scripts/checklitmushist.sh old mode 100644 new mode 100755 diff --git a/tools/memory-model/scripts/cmplitmushist.sh b/tools/memory-model/scripts/cmplitmushist.sh old mode 100644 new mode 100755 diff --git a/tools/memory-model/scripts/initlitmushist.sh b/tools/memory-model/scripts/initlitmushist.sh old mode 100644 new mode 100755 diff --git a/tools/memory-model/scripts/judgelitmus.sh b/tools/memory-model/scripts/judgelitmus.sh old mode 100644 new mode 100755 diff --git a/tools/memory-model/scripts/newlitmushist.sh b/tools/memory-model/scripts/newlitmushist.sh old mode 100644 new mode 100755 diff --git a/tools/memory-model/scripts/parseargs.sh b/tools/memory-model/scripts/parseargs.sh old mode 100644 new mode 100755 diff --git a/tools/memory-model/scripts/runlitmushist.sh b/tools/memory-model/scripts/runlitmushist.sh old mode 100644 new mode 100755 -- cgit v1.2.3-59-g8ed1b From 3415ec643e7bd644b03026efbe2f2b36cbe9b34b Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Thu, 1 Aug 2019 00:24:05 -0700 Subject: libbpf: set BTF FD for prog only when there is supported .BTF.ext data 5d01ab7bac46 ("libbpf: fix erroneous multi-closing of BTF FD") introduced backwards-compatibility issue, manifesting itself as -E2BIG error returned on program load due to unknown non-zero btf_fd attribute value for BPF_PROG_LOAD sys_bpf() sub-command. This patch fixes bug by ensuring that we only ever associate BTF FD with program if there is a BTF.ext data that was successfully loaded into kernel, which automatically means kernel supports func_info/line_info and associated BTF FD for progs (checked and ensured also by BTF sanitization code). Fixes: 5d01ab7bac46 ("libbpf: fix erroneous multi-closing of BTF FD") Reported-by: Andrey Ignatov Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov --- tools/lib/bpf/libbpf.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 2e84fa5b8479..2b57d7ea7836 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -2472,7 +2472,11 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt, load_attr.license = license; load_attr.kern_version = kern_version; load_attr.prog_ifindex = prog->prog_ifindex; - btf_fd = bpf_object__btf_fd(prog->obj); + /* if .BTF.ext was loaded, kernel supports associated BTF for prog */ + if (prog->obj->btf_ext) + btf_fd = bpf_object__btf_fd(prog->obj); + else + btf_fd = -1; load_attr.prog_btf_fd = btf_fd >= 0 ? btf_fd : 0; load_attr.func_info = prog->func_info; load_attr.func_info_rec_size = prog->func_info_rec_size; -- cgit v1.2.3-59-g8ed1b From f1fc7249dddc0e52d9e805e2e661caa118649509 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Tue, 30 Jul 2019 18:38:27 -0700 Subject: selftests/bpf: tests for jmp to 1st insn Add 2 tests that check JIT code generation to jumps to 1st insn. 1st test is similar to syzbot reproducer. The backwards branch is never taken at runtime. 2nd test has branch to 1st insn that executes. The test is written as two bpf functions, since it's not possible to construct valid single bpf program that jumps to 1st insn. Signed-off-by: Alexei Starovoitov Acked-by: Song Liu --- tools/testing/selftests/bpf/verifier/loops1.c | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/verifier/loops1.c b/tools/testing/selftests/bpf/verifier/loops1.c index 5e980a5ab69d..1fc4e61e9f9f 100644 --- a/tools/testing/selftests/bpf/verifier/loops1.c +++ b/tools/testing/selftests/bpf/verifier/loops1.c @@ -159,3 +159,31 @@ .errstr = "loop detected", .prog_type = BPF_PROG_TYPE_TRACEPOINT, }, +{ + "not-taken loop with back jump to 1st insn", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 123), + BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 4, -2), + BPF_EXIT_INSN(), + }, + .result = ACCEPT, + .prog_type = BPF_PROG_TYPE_XDP, + .retval = 123, +}, +{ + "taken loop with back jump to 1st insn", + .insns = { + BPF_MOV64_IMM(BPF_REG_1, 10), + BPF_MOV64_IMM(BPF_REG_2, 0), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), + BPF_EXIT_INSN(), + BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1), + BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 1), + BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, -3), + BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), + BPF_EXIT_INSN(), + }, + .result = ACCEPT, + .prog_type = BPF_PROG_TYPE_XDP, + .retval = 55, +}, -- cgit v1.2.3-59-g8ed1b From fd5ef31f370a8b7000794cd8a428b349dbfbbb80 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Mon, 29 Jul 2019 14:51:11 -0700 Subject: selftests/bpf: extend sockopt_sk selftest with TCP_CONGESTION use case Ignore SOL_TCP:TCP_CONGESTION in getsockopt and always override SOL_TCP:TCP_CONGESTION with "cubic" in setsockopt hook. Call setsockopt(SOL_TCP, TCP_CONGESTION) with short optval ("nv") to make sure BPF program has enough buffer space to replace it with "cubic". Signed-off-by: Stanislav Fomichev Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/progs/sockopt_sk.c | 22 ++++++++++++++++++++++ tools/testing/selftests/bpf/test_sockopt_sk.c | 25 +++++++++++++++++++++++++ 2 files changed, 47 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/progs/sockopt_sk.c b/tools/testing/selftests/bpf/progs/sockopt_sk.c index 076122c898e9..9a3d1c79e6fe 100644 --- a/tools/testing/selftests/bpf/progs/sockopt_sk.c +++ b/tools/testing/selftests/bpf/progs/sockopt_sk.c @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include +#include #include #include "bpf_helpers.h" @@ -42,6 +44,14 @@ int _getsockopt(struct bpf_sockopt *ctx) return 1; } + if (ctx->level == SOL_TCP && ctx->optname == TCP_CONGESTION) { + /* Not interested in SOL_TCP:TCP_CONGESTION; + * let next BPF program in the cgroup chain or kernel + * handle it. + */ + return 1; + } + if (ctx->level != SOL_CUSTOM) return 0; /* EPERM, deny everything except custom level */ @@ -91,6 +101,18 @@ int _setsockopt(struct bpf_sockopt *ctx) return 1; } + if (ctx->level == SOL_TCP && ctx->optname == TCP_CONGESTION) { + /* Always use cubic */ + + if (optval + 5 > optval_end) + return 0; /* EPERM, bounds check */ + + memcpy(optval, "cubic", 5); + ctx->optlen = 5; + + return 1; + } + if (ctx->level != SOL_CUSTOM) return 0; /* EPERM, deny everything except custom level */ diff --git a/tools/testing/selftests/bpf/test_sockopt_sk.c b/tools/testing/selftests/bpf/test_sockopt_sk.c index 036b652e5ca9..e4f6055d92e9 100644 --- a/tools/testing/selftests/bpf/test_sockopt_sk.c +++ b/tools/testing/selftests/bpf/test_sockopt_sk.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -25,6 +26,7 @@ static int getsetsockopt(void) union { char u8[4]; __u32 u32; + char cc[16]; /* TCP_CA_NAME_MAX */ } buf = {}; socklen_t optlen; @@ -115,6 +117,29 @@ static int getsetsockopt(void) goto err; } + /* TCP_CONGESTION can extend the string */ + + strcpy(buf.cc, "nv"); + err = setsockopt(fd, SOL_TCP, TCP_CONGESTION, &buf, strlen("nv")); + if (err) { + log_err("Failed to call setsockopt(TCP_CONGESTION)"); + goto err; + } + + + optlen = sizeof(buf.cc); + err = getsockopt(fd, SOL_TCP, TCP_CONGESTION, &buf, &optlen); + if (err) { + log_err("Failed to call getsockopt(TCP_CONGESTION)"); + goto err; + } + + if (strcmp(buf.cc, "cubic") != 0) { + log_err("Unexpected getsockopt(TCP_CONGESTION) %s != %s", + buf.cc, "cubic"); + goto err; + } + close(fd); return 0; err: -- cgit v1.2.3-59-g8ed1b From 2c667e5eae232f7f4a4fc30f58e51abdb0dc43c5 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 21 Jun 2019 10:32:57 -0700 Subject: torture: Expand last_ts variable in kvm-test-1-run.sh The kvm-test-1-run.sh script says 'test -z "last_ts"' which always evaluates to true (AKA zero) regardless of the value of the last_ts shell variable. This commit therefore inserts the needed dollar sign ("$"). Signed-off-by: Paul E. McKenney --- tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh index 27b7b5693ede..33c669619736 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh @@ -227,7 +227,7 @@ then must_continue=yes fi last_ts="`tail $resdir/console.log | grep '^\[ *[0-9]\+\.[0-9]\+]' | tail -1 | sed -e 's/^\[ *//' -e 's/\..*$//'`" - if test -z "last_ts" + if test -z "$last_ts" then last_ts=0 fi -- cgit v1.2.3-59-g8ed1b From f4e8352928587ef8772df3d269a328efa609daaa Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 27 Jun 2019 14:05:54 -0700 Subject: rcutorture: Test TREE03 with the threadirqs kernel boot parameter Since commit 05f415715ce45 ("rcu: Speed up expedited GPs when interrupting RCU reader") in v5.0 and through v5.1, booting with the threadirqs kernel boot parameter caused self-deadlocks, which can be reproduced using the following command on an 8-CPU system: tools/testing/selftests/rcutorture/bin/kvm.sh --duration 5 --configs "TREE03" --bootargs "threadirqs" This commit therefore adds the threadirqs kernel boot parameter to the TREE03 rcutorture scenario in order to more quickly detect future similar bugs. Link: http://lkml.kernel.org/r/20190626135447.y24mvfuid5fifwjc@linutronix.de Signed-off-by: Paul E. McKenney Cc: Sebastian Andrzej Siewior Cc: Joel Fernandes --- tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot b/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot index 5c3213cc3ad7..1c218944b1e9 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot @@ -3,3 +3,4 @@ rcutree.gp_preinit_delay=12 rcutree.gp_init_delay=3 rcutree.gp_cleanup_delay=3 rcutree.kthread_prio=2 +threadirqs -- cgit v1.2.3-59-g8ed1b From 2040f414d12f31be3e73eb3f5048d2b1cdec48f6 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 31 Jul 2019 17:15:23 +0200 Subject: KVM: selftests: Split ucall.c into architecture specific files The way we exit from a guest to userspace is very specific to the architecture: On x86, we use PIO, on aarch64 we are using MMIO and on s390x we're going to use an instruction instead. The possibility to select a type via the ucall_type_t enum is currently also completely unused, so the code in ucall.c currently looks more complex than required. Let's split this up into architecture specific ucall.c files instead, so we can get rid of the #ifdefs and the unnecessary ucall_type_t handling. Reviewed-by: Andrew Jones Signed-off-by: Thomas Huth Acked-by: Paolo Bonzini Link: https://lore.kernel.org/r/20190731151525.17156-2-thuth@redhat.com Signed-off-by: Christian Borntraeger --- tools/testing/selftests/kvm/Makefile | 6 +- tools/testing/selftests/kvm/dirty_log_test.c | 2 +- tools/testing/selftests/kvm/include/kvm_util.h | 8 +- tools/testing/selftests/kvm/lib/aarch64/ucall.c | 112 +++++++++++++++++ tools/testing/selftests/kvm/lib/ucall.c | 157 ------------------------ tools/testing/selftests/kvm/lib/x86_64/ucall.c | 56 +++++++++ 6 files changed, 173 insertions(+), 168 deletions(-) create mode 100644 tools/testing/selftests/kvm/lib/aarch64/ucall.c delete mode 100644 tools/testing/selftests/kvm/lib/ucall.c create mode 100644 tools/testing/selftests/kvm/lib/x86_64/ucall.c (limited to 'tools') diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index ba7849751989..a51e3b83df40 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -7,9 +7,9 @@ top_srcdir = ../../../.. KSFT_KHDR_INSTALL := 1 UNAME_M := $(shell uname -m) -LIBKVM = lib/assert.c lib/elf.c lib/io.c lib/kvm_util.c lib/ucall.c lib/sparsebit.c -LIBKVM_x86_64 = lib/x86_64/processor.c lib/x86_64/vmx.c -LIBKVM_aarch64 = lib/aarch64/processor.c +LIBKVM = lib/assert.c lib/elf.c lib/io.c lib/kvm_util.c lib/sparsebit.c +LIBKVM_x86_64 = lib/x86_64/processor.c lib/x86_64/vmx.c lib/x86_64/ucall.c +LIBKVM_aarch64 = lib/aarch64/processor.c lib/aarch64/ucall.c LIBKVM_s390x = lib/s390x/processor.c TEST_GEN_PROGS_x86_64 = x86_64/cr4_cpuid_sync_test diff --git a/tools/testing/selftests/kvm/dirty_log_test.c b/tools/testing/selftests/kvm/dirty_log_test.c index ceb52b952637..5d5ae1be4984 100644 --- a/tools/testing/selftests/kvm/dirty_log_test.c +++ b/tools/testing/selftests/kvm/dirty_log_test.c @@ -337,7 +337,7 @@ static void run_test(enum vm_guest_mode mode, unsigned long iterations, vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid()); #endif #ifdef __aarch64__ - ucall_init(vm, UCALL_MMIO, NULL); + ucall_init(vm, NULL); #endif /* Export the shared variables to the guest */ diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index e0e66b115ef2..5463b7896a0a 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -165,12 +165,6 @@ int vm_create_device(struct kvm_vm *vm, struct kvm_create_device *cd); memcpy(&(g), _p, sizeof(g)); \ }) -/* ucall implementation types */ -typedef enum { - UCALL_PIO, - UCALL_MMIO, -} ucall_type_t; - /* Common ucalls */ enum { UCALL_NONE, @@ -186,7 +180,7 @@ struct ucall { uint64_t args[UCALL_MAX_ARGS]; }; -void ucall_init(struct kvm_vm *vm, ucall_type_t type, void *arg); +void ucall_init(struct kvm_vm *vm, void *arg); void ucall_uninit(struct kvm_vm *vm); void ucall(uint64_t cmd, int nargs, ...); uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc); diff --git a/tools/testing/selftests/kvm/lib/aarch64/ucall.c b/tools/testing/selftests/kvm/lib/aarch64/ucall.c new file mode 100644 index 000000000000..6cd91970fbad --- /dev/null +++ b/tools/testing/selftests/kvm/lib/aarch64/ucall.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ucall support. A ucall is a "hypercall to userspace". + * + * Copyright (C) 2018, Red Hat, Inc. + */ +#include "kvm_util.h" +#include "../kvm_util_internal.h" + +static vm_vaddr_t *ucall_exit_mmio_addr; + +static bool ucall_mmio_init(struct kvm_vm *vm, vm_paddr_t gpa) +{ + if (kvm_userspace_memory_region_find(vm, gpa, gpa + 1)) + return false; + + virt_pg_map(vm, gpa, gpa, 0); + + ucall_exit_mmio_addr = (vm_vaddr_t *)gpa; + sync_global_to_guest(vm, ucall_exit_mmio_addr); + + return true; +} + +void ucall_init(struct kvm_vm *vm, void *arg) +{ + vm_paddr_t gpa, start, end, step, offset; + unsigned int bits; + bool ret; + + if (arg) { + gpa = (vm_paddr_t)arg; + ret = ucall_mmio_init(vm, gpa); + TEST_ASSERT(ret, "Can't set ucall mmio address to %lx", gpa); + return; + } + + /* + * Find an address within the allowed physical and virtual address + * spaces, that does _not_ have a KVM memory region associated with + * it. Identity mapping an address like this allows the guest to + * access it, but as KVM doesn't know what to do with it, it + * will assume it's something userspace handles and exit with + * KVM_EXIT_MMIO. Well, at least that's how it works for AArch64. + * Here we start with a guess that the addresses around 5/8th + * of the allowed space are unmapped and then work both down and + * up from there in 1/16th allowed space sized steps. + * + * Note, we need to use VA-bits - 1 when calculating the allowed + * virtual address space for an identity mapping because the upper + * half of the virtual address space is the two's complement of the + * lower and won't match physical addresses. + */ + bits = vm->va_bits - 1; + bits = vm->pa_bits < bits ? vm->pa_bits : bits; + end = 1ul << bits; + start = end * 5 / 8; + step = end / 16; + for (offset = 0; offset < end - start; offset += step) { + if (ucall_mmio_init(vm, start - offset)) + return; + if (ucall_mmio_init(vm, start + offset)) + return; + } + TEST_ASSERT(false, "Can't find a ucall mmio address"); +} + +void ucall_uninit(struct kvm_vm *vm) +{ + ucall_exit_mmio_addr = 0; + sync_global_to_guest(vm, ucall_exit_mmio_addr); +} + +void ucall(uint64_t cmd, int nargs, ...) +{ + struct ucall uc = { + .cmd = cmd, + }; + va_list va; + int i; + + nargs = nargs <= UCALL_MAX_ARGS ? nargs : UCALL_MAX_ARGS; + + va_start(va, nargs); + for (i = 0; i < nargs; ++i) + uc.args[i] = va_arg(va, uint64_t); + va_end(va); + + *ucall_exit_mmio_addr = (vm_vaddr_t)&uc; +} + +uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc) +{ + struct kvm_run *run = vcpu_state(vm, vcpu_id); + struct ucall ucall = {}; + + if (run->exit_reason == KVM_EXIT_MMIO && + run->mmio.phys_addr == (uint64_t)ucall_exit_mmio_addr) { + vm_vaddr_t gva; + + TEST_ASSERT(run->mmio.is_write && run->mmio.len == 8, + "Unexpected ucall exit mmio address access"); + memcpy(&gva, run->mmio.data, sizeof(gva)); + memcpy(&ucall, addr_gva2hva(vm, gva), sizeof(ucall)); + + vcpu_run_complete_io(vm, vcpu_id); + if (uc) + memcpy(uc, &ucall, sizeof(ucall)); + } + + return ucall.cmd; +} diff --git a/tools/testing/selftests/kvm/lib/ucall.c b/tools/testing/selftests/kvm/lib/ucall.c deleted file mode 100644 index dd9a66700f96..000000000000 --- a/tools/testing/selftests/kvm/lib/ucall.c +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * ucall support. A ucall is a "hypercall to userspace". - * - * Copyright (C) 2018, Red Hat, Inc. - */ -#include "kvm_util.h" -#include "kvm_util_internal.h" - -#define UCALL_PIO_PORT ((uint16_t)0x1000) - -static ucall_type_t ucall_type; -static vm_vaddr_t *ucall_exit_mmio_addr; - -static bool ucall_mmio_init(struct kvm_vm *vm, vm_paddr_t gpa) -{ - if (kvm_userspace_memory_region_find(vm, gpa, gpa + 1)) - return false; - - virt_pg_map(vm, gpa, gpa, 0); - - ucall_exit_mmio_addr = (vm_vaddr_t *)gpa; - sync_global_to_guest(vm, ucall_exit_mmio_addr); - - return true; -} - -void ucall_init(struct kvm_vm *vm, ucall_type_t type, void *arg) -{ - ucall_type = type; - sync_global_to_guest(vm, ucall_type); - - if (type == UCALL_PIO) - return; - - if (type == UCALL_MMIO) { - vm_paddr_t gpa, start, end, step, offset; - unsigned bits; - bool ret; - - if (arg) { - gpa = (vm_paddr_t)arg; - ret = ucall_mmio_init(vm, gpa); - TEST_ASSERT(ret, "Can't set ucall mmio address to %lx", gpa); - return; - } - - /* - * Find an address within the allowed physical and virtual address - * spaces, that does _not_ have a KVM memory region associated with - * it. Identity mapping an address like this allows the guest to - * access it, but as KVM doesn't know what to do with it, it - * will assume it's something userspace handles and exit with - * KVM_EXIT_MMIO. Well, at least that's how it works for AArch64. - * Here we start with a guess that the addresses around 5/8th - * of the allowed space are unmapped and then work both down and - * up from there in 1/16th allowed space sized steps. - * - * Note, we need to use VA-bits - 1 when calculating the allowed - * virtual address space for an identity mapping because the upper - * half of the virtual address space is the two's complement of the - * lower and won't match physical addresses. - */ - bits = vm->va_bits - 1; - bits = vm->pa_bits < bits ? vm->pa_bits : bits; - end = 1ul << bits; - start = end * 5 / 8; - step = end / 16; - for (offset = 0; offset < end - start; offset += step) { - if (ucall_mmio_init(vm, start - offset)) - return; - if (ucall_mmio_init(vm, start + offset)) - return; - } - TEST_ASSERT(false, "Can't find a ucall mmio address"); - } -} - -void ucall_uninit(struct kvm_vm *vm) -{ - ucall_type = 0; - sync_global_to_guest(vm, ucall_type); - ucall_exit_mmio_addr = 0; - sync_global_to_guest(vm, ucall_exit_mmio_addr); -} - -static void ucall_pio_exit(struct ucall *uc) -{ -#ifdef __x86_64__ - asm volatile("in %[port], %%al" - : : [port] "d" (UCALL_PIO_PORT), "D" (uc) : "rax"); -#endif -} - -static void ucall_mmio_exit(struct ucall *uc) -{ - *ucall_exit_mmio_addr = (vm_vaddr_t)uc; -} - -void ucall(uint64_t cmd, int nargs, ...) -{ - struct ucall uc = { - .cmd = cmd, - }; - va_list va; - int i; - - nargs = nargs <= UCALL_MAX_ARGS ? nargs : UCALL_MAX_ARGS; - - va_start(va, nargs); - for (i = 0; i < nargs; ++i) - uc.args[i] = va_arg(va, uint64_t); - va_end(va); - - switch (ucall_type) { - case UCALL_PIO: - ucall_pio_exit(&uc); - break; - case UCALL_MMIO: - ucall_mmio_exit(&uc); - break; - }; -} - -uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc) -{ - struct kvm_run *run = vcpu_state(vm, vcpu_id); - struct ucall ucall = {}; - bool got_ucall = false; - -#ifdef __x86_64__ - if (ucall_type == UCALL_PIO && run->exit_reason == KVM_EXIT_IO && - run->io.port == UCALL_PIO_PORT) { - struct kvm_regs regs; - vcpu_regs_get(vm, vcpu_id, ®s); - memcpy(&ucall, addr_gva2hva(vm, (vm_vaddr_t)regs.rdi), sizeof(ucall)); - got_ucall = true; - } -#endif - if (ucall_type == UCALL_MMIO && run->exit_reason == KVM_EXIT_MMIO && - run->mmio.phys_addr == (uint64_t)ucall_exit_mmio_addr) { - vm_vaddr_t gva; - TEST_ASSERT(run->mmio.is_write && run->mmio.len == 8, - "Unexpected ucall exit mmio address access"); - memcpy(&gva, run->mmio.data, sizeof(gva)); - memcpy(&ucall, addr_gva2hva(vm, gva), sizeof(ucall)); - got_ucall = true; - } - - if (got_ucall) { - vcpu_run_complete_io(vm, vcpu_id); - if (uc) - memcpy(uc, &ucall, sizeof(ucall)); - } - - return ucall.cmd; -} diff --git a/tools/testing/selftests/kvm/lib/x86_64/ucall.c b/tools/testing/selftests/kvm/lib/x86_64/ucall.c new file mode 100644 index 000000000000..4bfc9a90b1de --- /dev/null +++ b/tools/testing/selftests/kvm/lib/x86_64/ucall.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ucall support. A ucall is a "hypercall to userspace". + * + * Copyright (C) 2018, Red Hat, Inc. + */ +#include "kvm_util.h" + +#define UCALL_PIO_PORT ((uint16_t)0x1000) + +void ucall_init(struct kvm_vm *vm, void *arg) +{ +} + +void ucall_uninit(struct kvm_vm *vm) +{ +} + +void ucall(uint64_t cmd, int nargs, ...) +{ + struct ucall uc = { + .cmd = cmd, + }; + va_list va; + int i; + + nargs = nargs <= UCALL_MAX_ARGS ? nargs : UCALL_MAX_ARGS; + + va_start(va, nargs); + for (i = 0; i < nargs; ++i) + uc.args[i] = va_arg(va, uint64_t); + va_end(va); + + asm volatile("in %[port], %%al" + : : [port] "d" (UCALL_PIO_PORT), "D" (&uc) : "rax"); +} + +uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc) +{ + struct kvm_run *run = vcpu_state(vm, vcpu_id); + struct ucall ucall = {}; + + if (run->exit_reason == KVM_EXIT_IO && run->io.port == UCALL_PIO_PORT) { + struct kvm_regs regs; + + vcpu_regs_get(vm, vcpu_id, ®s); + memcpy(&ucall, addr_gva2hva(vm, (vm_vaddr_t)regs.rdi), + sizeof(ucall)); + + vcpu_run_complete_io(vm, vcpu_id); + if (uc) + memcpy(uc, &ucall, sizeof(ucall)); + } + + return ucall.cmd; +} -- cgit v1.2.3-59-g8ed1b From f90f57b3971a3370be5a3cf02ae783b4bf728b7f Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 31 Jul 2019 17:15:24 +0200 Subject: KVM: selftests: Implement ucall() for s390x On s390x, we can neither exit via PIO nor MMIO, but have to use an instruction like DIAGNOSE. Now that ucall() is implemented, we can use it in the sync_reg_test on s390x, too. Reviewed-by: Andrew Jones Signed-off-by: Thomas Huth Link: https://lore.kernel.org/r/20190731151525.17156-3-thuth@redhat.com Signed-off-by: Christian Borntraeger --- tools/testing/selftests/kvm/Makefile | 2 +- tools/testing/selftests/kvm/lib/s390x/ucall.c | 56 ++++++++++++++++++++++ tools/testing/selftests/kvm/s390x/sync_regs_test.c | 6 ++- 3 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 tools/testing/selftests/kvm/lib/s390x/ucall.c (limited to 'tools') diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index a51e3b83df40..75ea1ecbf85a 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -10,7 +10,7 @@ UNAME_M := $(shell uname -m) LIBKVM = lib/assert.c lib/elf.c lib/io.c lib/kvm_util.c lib/sparsebit.c LIBKVM_x86_64 = lib/x86_64/processor.c lib/x86_64/vmx.c lib/x86_64/ucall.c LIBKVM_aarch64 = lib/aarch64/processor.c lib/aarch64/ucall.c -LIBKVM_s390x = lib/s390x/processor.c +LIBKVM_s390x = lib/s390x/processor.c lib/s390x/ucall.c TEST_GEN_PROGS_x86_64 = x86_64/cr4_cpuid_sync_test TEST_GEN_PROGS_x86_64 += x86_64/evmcs_test diff --git a/tools/testing/selftests/kvm/lib/s390x/ucall.c b/tools/testing/selftests/kvm/lib/s390x/ucall.c new file mode 100644 index 000000000000..fd589dc9bfab --- /dev/null +++ b/tools/testing/selftests/kvm/lib/s390x/ucall.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ucall support. A ucall is a "hypercall to userspace". + * + * Copyright (C) 2019 Red Hat, Inc. + */ +#include "kvm_util.h" + +void ucall_init(struct kvm_vm *vm, void *arg) +{ +} + +void ucall_uninit(struct kvm_vm *vm) +{ +} + +void ucall(uint64_t cmd, int nargs, ...) +{ + struct ucall uc = { + .cmd = cmd, + }; + va_list va; + int i; + + nargs = nargs <= UCALL_MAX_ARGS ? nargs : UCALL_MAX_ARGS; + + va_start(va, nargs); + for (i = 0; i < nargs; ++i) + uc.args[i] = va_arg(va, uint64_t); + va_end(va); + + /* Exit via DIAGNOSE 0x501 (normally used for breakpoints) */ + asm volatile ("diag 0,%0,0x501" : : "a"(&uc) : "memory"); +} + +uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc) +{ + struct kvm_run *run = vcpu_state(vm, vcpu_id); + struct ucall ucall = {}; + + if (run->exit_reason == KVM_EXIT_S390_SIEIC && + run->s390_sieic.icptcode == 4 && + (run->s390_sieic.ipa >> 8) == 0x83 && /* 0x83 means DIAGNOSE */ + (run->s390_sieic.ipb >> 16) == 0x501) { + int reg = run->s390_sieic.ipa & 0xf; + + memcpy(&ucall, addr_gva2hva(vm, run->s.regs.gprs[reg]), + sizeof(ucall)); + + vcpu_run_complete_io(vm, vcpu_id); + if (uc) + memcpy(uc, &ucall, sizeof(ucall)); + } + + return ucall.cmd; +} diff --git a/tools/testing/selftests/kvm/s390x/sync_regs_test.c b/tools/testing/selftests/kvm/s390x/sync_regs_test.c index e85ff0d69548..bbc93094519b 100644 --- a/tools/testing/selftests/kvm/s390x/sync_regs_test.c +++ b/tools/testing/selftests/kvm/s390x/sync_regs_test.c @@ -25,9 +25,11 @@ static void guest_code(void) { + register u64 stage asm("11") = 0; + for (;;) { - asm volatile ("diag 0,0,0x501"); - asm volatile ("ahi 11,1"); + GUEST_SYNC(0); + asm volatile ("ahi %0,1" : : "r"(stage)); } } -- cgit v1.2.3-59-g8ed1b From a049a377164c3eca7d5323cd9896b64d2120c415 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 31 Jul 2019 17:15:25 +0200 Subject: KVM: selftests: Enable dirty_log_test on s390x To run the dirty_log_test on s390x, we have to make sure that we access the dirty log bitmap with little endian byte ordering and we have to properly align the memslot of the guest. Also all dirty bits of a segment are set once on s390x when one of the pages of a segment are written to for the first time, so we have to make sure that we touch all pages during the first iteration to keep the test in sync here. DEFAULT_GUEST_TEST_MEM needs an adjustment, too. On some s390x distributions, the ELF binary is linked to address 0x80000000, so we have to avoid that our test region overlaps into this area. 0xc0000000 seems to be a good alternative that should work on x86 and aarch64, too. Acked-by: Paolo Bonzini Reviewed-by: Andrew Jones Signed-off-by: Thomas Huth Link: https://lore.kernel.org/r/20190731151525.17156-4-thuth@redhat.com Signed-off-by: Christian Borntraeger --- tools/testing/selftests/kvm/Makefile | 1 + tools/testing/selftests/kvm/dirty_log_test.c | 59 ++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 75ea1ecbf85a..1b48a94b4350 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -33,6 +33,7 @@ TEST_GEN_PROGS_aarch64 += dirty_log_test TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus TEST_GEN_PROGS_s390x += s390x/sync_regs_test +TEST_GEN_PROGS_s390x += dirty_log_test TEST_GEN_PROGS_s390x += kvm_create_max_vcpus TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(UNAME_M)) diff --git a/tools/testing/selftests/kvm/dirty_log_test.c b/tools/testing/selftests/kvm/dirty_log_test.c index 5d5ae1be4984..dc3346e090f5 100644 --- a/tools/testing/selftests/kvm/dirty_log_test.c +++ b/tools/testing/selftests/kvm/dirty_log_test.c @@ -26,8 +26,8 @@ /* The memory slot index to track dirty pages */ #define TEST_MEM_SLOT_INDEX 1 -/* Default guest test memory offset, 1G */ -#define DEFAULT_GUEST_TEST_MEM 0x40000000 +/* Default guest test virtual memory offset */ +#define DEFAULT_GUEST_TEST_MEM 0xc0000000 /* How many pages to dirty for each guest loop */ #define TEST_PAGES_PER_LOOP 1024 @@ -38,6 +38,27 @@ /* Interval for each host loop (ms) */ #define TEST_HOST_LOOP_INTERVAL 10UL +/* Dirty bitmaps are always little endian, so we need to swap on big endian */ +#if defined(__s390x__) +# define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7) +# define test_bit_le(nr, addr) \ + test_bit((nr) ^ BITOP_LE_SWIZZLE, addr) +# define set_bit_le(nr, addr) \ + set_bit((nr) ^ BITOP_LE_SWIZZLE, addr) +# define clear_bit_le(nr, addr) \ + clear_bit((nr) ^ BITOP_LE_SWIZZLE, addr) +# define test_and_set_bit_le(nr, addr) \ + test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, addr) +# define test_and_clear_bit_le(nr, addr) \ + test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, addr) +#else +# define test_bit_le test_bit +# define set_bit_le set_bit +# define clear_bit_le clear_bit +# define test_and_set_bit_le test_and_set_bit +# define test_and_clear_bit_le test_and_clear_bit +#endif + /* * Guest/Host shared variables. Ensure addr_gva2hva() and/or * sync_global_to/from_guest() are used when accessing from @@ -69,11 +90,23 @@ static uint64_t guest_test_virt_mem = DEFAULT_GUEST_TEST_MEM; */ static void guest_code(void) { + uint64_t addr; int i; + /* + * On s390x, all pages of a 1M segment are initially marked as dirty + * when a page of the segment is written to for the very first time. + * To compensate this specialty in this test, we need to touch all + * pages during the first iteration. + */ + for (i = 0; i < guest_num_pages; i++) { + addr = guest_test_virt_mem + i * guest_page_size; + *(uint64_t *)addr = READ_ONCE(iteration); + } + while (true) { for (i = 0; i < TEST_PAGES_PER_LOOP; i++) { - uint64_t addr = guest_test_virt_mem; + addr = guest_test_virt_mem; addr += (READ_ONCE(random_array[i]) % guest_num_pages) * guest_page_size; addr &= ~(host_page_size - 1); @@ -158,15 +191,15 @@ static void vm_dirty_log_verify(unsigned long *bmap) value_ptr = host_test_mem + page * host_page_size; /* If this is a special page that we were tracking... */ - if (test_and_clear_bit(page, host_bmap_track)) { + if (test_and_clear_bit_le(page, host_bmap_track)) { host_track_next_count++; - TEST_ASSERT(test_bit(page, bmap), + TEST_ASSERT(test_bit_le(page, bmap), "Page %"PRIu64" should have its dirty bit " "set in this iteration but it is missing", page); } - if (test_bit(page, bmap)) { + if (test_bit_le(page, bmap)) { host_dirty_count++; /* * If the bit is set, the value written onto @@ -209,7 +242,7 @@ static void vm_dirty_log_verify(unsigned long *bmap) * should report its dirtyness in the * next run */ - set_bit(page, host_bmap_track); + set_bit_le(page, host_bmap_track); } } } @@ -293,6 +326,10 @@ static void run_test(enum vm_guest_mode mode, unsigned long iterations, * case where the size is not aligned to 64 pages. */ guest_num_pages = (1ul << (30 - guest_page_shift)) + 16; +#ifdef __s390x__ + /* Round up to multiple of 1M (segment size) */ + guest_num_pages = (guest_num_pages + 0xff) & ~0xffUL; +#endif host_page_size = getpagesize(); host_num_pages = (guest_num_pages * guest_page_size) / host_page_size + !!((guest_num_pages * guest_page_size) % host_page_size); @@ -304,6 +341,11 @@ static void run_test(enum vm_guest_mode mode, unsigned long iterations, guest_test_phys_mem = phys_offset; } +#ifdef __s390x__ + /* Align to 1M (segment size) */ + guest_test_phys_mem &= ~((1 << 20) - 1); +#endif + DEBUG("guest physical test memory offset: 0x%lx\n", guest_test_phys_mem); bmap = bitmap_alloc(host_num_pages); @@ -454,6 +496,9 @@ int main(int argc, char *argv[]) vm_guest_mode_params_init(VM_MODE_P48V48_64K, true, true); } #endif +#ifdef __s390x__ + vm_guest_mode_params_init(VM_MODE_P40V48_4K, true, true); +#endif while ((opt = getopt(argc, argv, "hi:I:p:m:")) != -1) { switch (opt) { -- cgit v1.2.3-59-g8ed1b From acda655fefae352a48eec87c8f8487de1608a48b Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 1 Aug 2019 11:56:34 -0700 Subject: selftests: Add nettest Add nettest - a simple program with an implementation for various networking APIs. nettest is used for tcp, udp and raw functional tests for both IPv4 and IPv6. Point of this command versus existing utilities: - controlled implementation of the APIs and the order in which they are called, - ability to verify ingress device, local and remote addresses, - timeout for controlled test length, - ability to discriminate a timeout from a system call failure, and - simplicity with test scripts. The command returns: 0 on success, 1 for any system call failure, and 2 on timeout. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/Makefile | 2 +- tools/testing/selftests/net/nettest.c | 1756 +++++++++++++++++++++++++++++++++ 2 files changed, 1757 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/net/nettest.c (limited to 'tools') diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 1b24e36b4047..ba9ee36c9e94 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -12,7 +12,7 @@ TEST_PROGS += udpgro_bench.sh udpgro.sh test_vxlan_under_vrf.sh reuseport_addr_a TEST_PROGS += test_vxlan_fdb_changelink.sh so_txtime.sh ipv6_flowlabel.sh TEST_PROGS += tcp_fastopen_backup_key.sh TEST_PROGS_EXTENDED := in_netns.sh -TEST_GEN_FILES = socket +TEST_GEN_FILES = socket nettest TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy reuseport_addr_any TEST_GEN_FILES += tcp_mmap tcp_inq psock_snd txring_overwrite TEST_GEN_FILES += udpgso udpgso_bench_tx udpgso_bench_rx ip_defrag diff --git a/tools/testing/selftests/net/nettest.c b/tools/testing/selftests/net/nettest.c new file mode 100644 index 000000000000..9278f8460d75 --- /dev/null +++ b/tools/testing/selftests/net/nettest.c @@ -0,0 +1,1756 @@ +// SPDX-License-Identifier: GPL-2.0 +/* nettest - used for functional tests of networking APIs + * + * Copyright (c) 2013-2019 David Ahern . All rights reserved. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef IPV6_UNICAST_IF +#define IPV6_UNICAST_IF 76 +#endif +#ifndef IPV6_MULTICAST_IF +#define IPV6_MULTICAST_IF 17 +#endif + +#define DEFAULT_PORT 12345 + +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +struct sock_args { + /* local address */ + union { + struct in_addr in; + struct in6_addr in6; + } local_addr; + + /* remote address */ + union { + struct in_addr in; + struct in6_addr in6; + } remote_addr; + int scope_id; /* remote scope; v6 send only */ + + struct in_addr grp; /* multicast group */ + + unsigned int has_local_ip:1, + has_remote_ip:1, + has_grp:1, + has_expected_laddr:1, + has_expected_raddr:1, + bind_test_only:1; + + unsigned short port; + + int type; /* DGRAM, STREAM, RAW */ + int protocol; + int version; /* AF_INET/AF_INET6 */ + + int use_setsockopt; + int use_cmsg; + const char *dev; + int ifindex; + const char *password; + + /* expected addresses and device index for connection */ + int expected_ifindex; + + /* local address */ + union { + struct in_addr in; + struct in6_addr in6; + } expected_laddr; + + /* remote address */ + union { + struct in_addr in; + struct in6_addr in6; + } expected_raddr; +}; + +static int server_mode; +static unsigned int prog_timeout = 5; +static unsigned int interactive; +static int iter = 1; +static char *msg = "Hello world!"; +static int msglen; +static int quiet; +static int try_broadcast = 1; + +static char *timestamp(char *timebuf, int buflen) +{ + time_t now; + + now = time(NULL); + if (strftime(timebuf, buflen, "%T", localtime(&now)) == 0) { + memset(timebuf, 0, buflen); + strncpy(timebuf, "00:00:00", buflen-1); + } + + return timebuf; +} + +static void log_msg(const char *format, ...) +{ + char timebuf[64]; + va_list args; + + if (quiet) + return; + + fprintf(stdout, "%s %s:", + timestamp(timebuf, sizeof(timebuf)), + server_mode ? "server" : "client"); + va_start(args, format); + vfprintf(stdout, format, args); + va_end(args); + + fflush(stdout); +} + +static void log_error(const char *format, ...) +{ + char timebuf[64]; + va_list args; + + if (quiet) + return; + + fprintf(stderr, "%s %s:", + timestamp(timebuf, sizeof(timebuf)), + server_mode ? "server" : "client"); + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + + fflush(stderr); +} + +static void log_err_errno(const char *fmt, ...) +{ + char timebuf[64]; + va_list args; + + if (quiet) + return; + + fprintf(stderr, "%s %s: ", + timestamp(timebuf, sizeof(timebuf)), + server_mode ? "server" : "client"); + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + + fprintf(stderr, ": %d: %s\n", errno, strerror(errno)); + fflush(stderr); +} + +static void log_address(const char *desc, struct sockaddr *sa) +{ + char addrstr[64]; + + if (quiet) + return; + + if (sa->sa_family == AF_INET) { + struct sockaddr_in *s = (struct sockaddr_in *) sa; + + log_msg("%s %s:%d", + desc, + inet_ntop(AF_INET, &s->sin_addr, addrstr, + sizeof(addrstr)), + ntohs(s->sin_port)); + + } else if (sa->sa_family == AF_INET6) { + struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) sa; + + log_msg("%s [%s]:%d", + desc, + inet_ntop(AF_INET6, &s6->sin6_addr, addrstr, + sizeof(addrstr)), + ntohs(s6->sin6_port)); + } + + printf("\n"); + + fflush(stdout); +} + +static int tcp_md5sig(int sd, void *addr, socklen_t alen, const char *password) +{ + struct tcp_md5sig md5sig; + int keylen = password ? strlen(password) : 0; + int rc; + + memset(&md5sig, 0, sizeof(md5sig)); + memcpy(&md5sig.tcpm_addr, addr, alen); + md5sig.tcpm_keylen = keylen; + + if (keylen) + memcpy(md5sig.tcpm_key, password, keylen); + + rc = setsockopt(sd, IPPROTO_TCP, TCP_MD5SIG, &md5sig, sizeof(md5sig)); + if (rc < 0) { + /* ENOENT is harmless. Returned when a password is cleared */ + if (errno == ENOENT) + rc = 0; + else + log_err_errno("setsockopt(TCP_MD5SIG)"); + } + + return rc; +} + +static int tcp_md5_remote(int sd, struct sock_args *args) +{ + struct sockaddr_in sin = { + .sin_family = AF_INET, + }; + struct sockaddr_in6 sin6 = { + .sin6_family = AF_INET6, + }; + void *addr; + int alen; + + switch (args->version) { + case AF_INET: + sin.sin_port = htons(args->port); + sin.sin_addr = args->remote_addr.in; + addr = &sin; + alen = sizeof(sin); + break; + case AF_INET6: + sin6.sin6_port = htons(args->port); + sin6.sin6_addr = args->remote_addr.in6; + addr = &sin6; + alen = sizeof(sin6); + break; + default: + log_error("unknown address family\n"); + exit(1); + } + + if (tcp_md5sig(sd, addr, alen, args->password)) + return -1; + + return 0; +} + +static int get_ifidx(const char *ifname) +{ + struct ifreq ifdata; + int sd, rc; + + if (!ifname || *ifname == '\0') + return 0; + + memset(&ifdata, 0, sizeof(ifdata)); + + strcpy(ifdata.ifr_name, ifname); + + sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + if (sd < 0) { + log_err_errno("socket failed"); + return 0; + } + + rc = ioctl(sd, SIOCGIFINDEX, (char *)&ifdata); + close(sd); + if (rc != 0) { + log_err_errno("ioctl(SIOCGIFINDEX) failed"); + return 0; + } + + return ifdata.ifr_ifindex; +} + +static int bind_to_device(int sd, const char *name) +{ + int rc; + + rc = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name)+1); + if (rc < 0) + log_err_errno("setsockopt(SO_BINDTODEVICE)"); + + return rc; +} + +static int get_bind_to_device(int sd, char *name, size_t len) +{ + int rc; + socklen_t optlen = len; + + name[0] = '\0'; + rc = getsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, name, &optlen); + if (rc < 0) + log_err_errno("setsockopt(SO_BINDTODEVICE)"); + + return rc; +} + +static int check_device(int sd, struct sock_args *args) +{ + int ifindex = 0; + char name[32]; + + if (get_bind_to_device(sd, name, sizeof(name))) + *name = '\0'; + else + ifindex = get_ifidx(name); + + log_msg(" bound to device %s/%d\n", + *name ? name : "", ifindex); + + if (!args->expected_ifindex) + return 0; + + if (args->expected_ifindex != ifindex) { + log_error("Device index mismatch: expected %d have %d\n", + args->expected_ifindex, ifindex); + return 1; + } + + log_msg("Device index matches: expected %d have %d\n", + args->expected_ifindex, ifindex); + + return 0; +} + +static int set_pktinfo_v4(int sd) +{ + int one = 1; + int rc; + + rc = setsockopt(sd, SOL_IP, IP_PKTINFO, &one, sizeof(one)); + if (rc < 0 && rc != -ENOTSUP) + log_err_errno("setsockopt(IP_PKTINFO)"); + + return rc; +} + +static int set_recvpktinfo_v6(int sd) +{ + int one = 1; + int rc; + + rc = setsockopt(sd, SOL_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one)); + if (rc < 0 && rc != -ENOTSUP) + log_err_errno("setsockopt(IPV6_RECVPKTINFO)"); + + return rc; +} + +static int set_recverr_v4(int sd) +{ + int one = 1; + int rc; + + rc = setsockopt(sd, SOL_IP, IP_RECVERR, &one, sizeof(one)); + if (rc < 0 && rc != -ENOTSUP) + log_err_errno("setsockopt(IP_RECVERR)"); + + return rc; +} + +static int set_recverr_v6(int sd) +{ + int one = 1; + int rc; + + rc = setsockopt(sd, SOL_IPV6, IPV6_RECVERR, &one, sizeof(one)); + if (rc < 0 && rc != -ENOTSUP) + log_err_errno("setsockopt(IPV6_RECVERR)"); + + return rc; +} + +static int set_unicast_if(int sd, int ifindex, int version) +{ + int opt = IP_UNICAST_IF; + int level = SOL_IP; + int rc; + + ifindex = htonl(ifindex); + + if (version == AF_INET6) { + opt = IPV6_UNICAST_IF; + level = SOL_IPV6; + } + rc = setsockopt(sd, level, opt, &ifindex, sizeof(ifindex)); + if (rc < 0) + log_err_errno("setsockopt(IP_UNICAST_IF)"); + + return rc; +} + +static int set_multicast_if(int sd, int ifindex) +{ + struct ip_mreqn mreq = { .imr_ifindex = ifindex }; + int rc; + + rc = setsockopt(sd, SOL_IP, IP_MULTICAST_IF, &mreq, sizeof(mreq)); + if (rc < 0) + log_err_errno("setsockopt(IP_MULTICAST_IF)"); + + return rc; +} + +static int set_membership(int sd, uint32_t grp, uint32_t addr, const char *dev) +{ + uint32_t if_addr = addr; + struct ip_mreqn mreq; + int rc; + + if (addr == htonl(INADDR_ANY) && !dev) { + log_error("Either local address or device needs to be given for multicast membership\n"); + return -1; + } + + mreq.imr_multiaddr.s_addr = grp; + mreq.imr_address.s_addr = if_addr; + mreq.imr_ifindex = dev ? get_ifidx(dev) : 0; + + rc = setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); + if (rc < 0) { + log_err_errno("setsockopt(IP_ADD_MEMBERSHIP)"); + return -1; + } + + return 0; +} + +static int set_broadcast(int sd) +{ + unsigned int one = 1; + int rc = 0; + + if (setsockopt(sd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) != 0) { + log_err_errno("setsockopt(SO_BROADCAST)"); + rc = -1; + } + + return rc; +} + +static int set_reuseport(int sd) +{ + unsigned int one = 1; + int rc = 0; + + if (setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) != 0) { + log_err_errno("setsockopt(SO_REUSEPORT)"); + rc = -1; + } + + return rc; +} + +static int set_reuseaddr(int sd) +{ + unsigned int one = 1; + int rc = 0; + + if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) != 0) { + log_err_errno("setsockopt(SO_REUSEADDR)"); + rc = -1; + } + + return rc; +} + +static int str_to_uint(const char *str, int min, int max, unsigned int *value) +{ + int number; + char *end; + + errno = 0; + number = (unsigned int) strtoul(str, &end, 0); + + /* entire string should be consumed by conversion + * and value should be between min and max + */ + if (((*end == '\0') || (*end == '\n')) && (end != str) && + (errno != ERANGE) && (min <= number) && (number <= max)) { + *value = number; + return 0; + } + + return -1; +} + +static int expected_addr_match(struct sockaddr *sa, void *expected, + const char *desc) +{ + char addrstr[64]; + int rc = 0; + + if (sa->sa_family == AF_INET) { + struct sockaddr_in *s = (struct sockaddr_in *) sa; + struct in_addr *exp_in = (struct in_addr *) expected; + + if (s->sin_addr.s_addr != exp_in->s_addr) { + log_error("%s address does not match expected %s", + desc, + inet_ntop(AF_INET, exp_in, + addrstr, sizeof(addrstr))); + rc = 1; + } + } else if (sa->sa_family == AF_INET6) { + struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) sa; + struct in6_addr *exp_in = (struct in6_addr *) expected; + + if (memcmp(&s6->sin6_addr, exp_in, sizeof(*exp_in))) { + log_error("%s address does not match expected %s", + desc, + inet_ntop(AF_INET6, exp_in, + addrstr, sizeof(addrstr))); + rc = 1; + } + } else { + log_error("%s address does not match expected - unknown family", + desc); + rc = 1; + } + + if (!rc) + log_msg("%s address matches expected\n", desc); + + return rc; +} + +static int show_sockstat(int sd, struct sock_args *args) +{ + struct sockaddr_in6 local_addr, remote_addr; + socklen_t alen = sizeof(local_addr); + struct sockaddr *sa; + const char *desc; + int rc = 0; + + desc = server_mode ? "server local:" : "client local:"; + sa = (struct sockaddr *) &local_addr; + if (getsockname(sd, sa, &alen) == 0) { + log_address(desc, sa); + + if (args->has_expected_laddr) { + rc = expected_addr_match(sa, &args->expected_laddr, + "local"); + } + } else { + log_err_errno("getsockname failed"); + } + + sa = (struct sockaddr *) &remote_addr; + desc = server_mode ? "server peer:" : "client peer:"; + if (getpeername(sd, sa, &alen) == 0) { + log_address(desc, sa); + + if (args->has_expected_raddr) { + rc |= expected_addr_match(sa, &args->expected_raddr, + "remote"); + } + } else { + log_err_errno("getpeername failed"); + } + + return rc; +} + +static int get_index_from_cmsg(struct msghdr *m) +{ + struct cmsghdr *cm; + int ifindex = 0; + char buf[64]; + + for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(m); + m->msg_controllen != 0 && cm; + cm = (struct cmsghdr *)CMSG_NXTHDR(m, cm)) { + + if (cm->cmsg_level == SOL_IP && + cm->cmsg_type == IP_PKTINFO) { + struct in_pktinfo *pi; + + pi = (struct in_pktinfo *)(CMSG_DATA(cm)); + inet_ntop(AF_INET, &pi->ipi_addr, buf, sizeof(buf)); + ifindex = pi->ipi_ifindex; + } else if (cm->cmsg_level == SOL_IPV6 && + cm->cmsg_type == IPV6_PKTINFO) { + struct in6_pktinfo *pi6; + + pi6 = (struct in6_pktinfo *)(CMSG_DATA(cm)); + inet_ntop(AF_INET6, &pi6->ipi6_addr, buf, sizeof(buf)); + ifindex = pi6->ipi6_ifindex; + } + } + + if (ifindex) { + log_msg(" pktinfo: ifindex %d dest addr %s\n", + ifindex, buf); + } + return ifindex; +} + +static int send_msg_no_cmsg(int sd, void *addr, socklen_t alen) +{ + int err; + +again: + err = sendto(sd, msg, msglen, 0, addr, alen); + if (err < 0) { + if (errno == EACCES && try_broadcast) { + try_broadcast = 0; + if (!set_broadcast(sd)) + goto again; + errno = EACCES; + } + + log_err_errno("sendto failed"); + return 1; + } + + return 0; +} + +static int send_msg_cmsg(int sd, void *addr, socklen_t alen, + int ifindex, int version) +{ + unsigned char cmsgbuf[64]; + struct iovec iov[2]; + struct cmsghdr *cm; + struct msghdr m; + int err; + + iov[0].iov_base = msg; + iov[0].iov_len = msglen; + m.msg_iov = iov; + m.msg_iovlen = 1; + m.msg_name = (caddr_t)addr; + m.msg_namelen = alen; + + memset(cmsgbuf, 0, sizeof(cmsgbuf)); + cm = (struct cmsghdr *)cmsgbuf; + m.msg_control = (caddr_t)cm; + + if (version == AF_INET) { + struct in_pktinfo *pi; + + cm->cmsg_level = SOL_IP; + cm->cmsg_type = IP_PKTINFO; + cm->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); + pi = (struct in_pktinfo *)(CMSG_DATA(cm)); + pi->ipi_ifindex = ifindex; + + m.msg_controllen = cm->cmsg_len; + + } else if (version == AF_INET6) { + struct in6_pktinfo *pi6; + + cm->cmsg_level = SOL_IPV6; + cm->cmsg_type = IPV6_PKTINFO; + cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); + + pi6 = (struct in6_pktinfo *)(CMSG_DATA(cm)); + pi6->ipi6_ifindex = ifindex; + + m.msg_controllen = cm->cmsg_len; + } + +again: + err = sendmsg(sd, &m, 0); + if (err < 0) { + if (errno == EACCES && try_broadcast) { + try_broadcast = 0; + if (!set_broadcast(sd)) + goto again; + errno = EACCES; + } + + log_err_errno("sendmsg failed"); + return 1; + } + + return 0; +} + + +static int send_msg(int sd, void *addr, socklen_t alen, struct sock_args *args) +{ + if (args->type == SOCK_STREAM) { + if (write(sd, msg, msglen) < 0) { + log_err_errno("write failed sending msg to peer"); + return 1; + } + } else if (args->ifindex && args->use_cmsg) { + if (send_msg_cmsg(sd, addr, alen, args->ifindex, args->version)) + return 1; + } else { + if (send_msg_no_cmsg(sd, addr, alen)) + return 1; + } + + log_msg("Sent message:\n"); + log_msg(" %.24s%s\n", msg, msglen > 24 ? " ..." : ""); + + return 0; +} + +static int socket_read_dgram(int sd, struct sock_args *args) +{ + unsigned char addr[sizeof(struct sockaddr_in6)]; + struct sockaddr *sa = (struct sockaddr *) addr; + socklen_t alen = sizeof(addr); + struct iovec iov[2]; + struct msghdr m = { + .msg_name = (caddr_t)addr, + .msg_namelen = alen, + .msg_iov = iov, + .msg_iovlen = 1, + }; + unsigned char cmsgbuf[256]; + struct cmsghdr *cm = (struct cmsghdr *)cmsgbuf; + char buf[16*1024]; + int ifindex; + int len; + + iov[0].iov_base = (caddr_t)buf; + iov[0].iov_len = sizeof(buf); + + memset(cmsgbuf, 0, sizeof(cmsgbuf)); + m.msg_control = (caddr_t)cm; + m.msg_controllen = sizeof(cmsgbuf); + + len = recvmsg(sd, &m, 0); + if (len == 0) { + log_msg("peer closed connection.\n"); + return 0; + } else if (len < 0) { + log_msg("failed to read message: %d: %s\n", + errno, strerror(errno)); + return -1; + } + + buf[len] = '\0'; + + log_address("Message from:", sa); + log_msg(" %.24s%s\n", buf, len > 24 ? " ..." : ""); + + ifindex = get_index_from_cmsg(&m); + if (args->expected_ifindex) { + if (args->expected_ifindex != ifindex) { + log_error("Device index mismatch: expected %d have %d\n", + args->expected_ifindex, ifindex); + return -1; + } + log_msg("Device index matches: expected %d have %d\n", + args->expected_ifindex, ifindex); + } + + if (!interactive && server_mode) { + if (sa->sa_family == AF_INET6) { + struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) sa; + struct in6_addr *in6 = &s6->sin6_addr; + + if (IN6_IS_ADDR_V4MAPPED(in6)) { + const uint32_t *pa = (uint32_t *) &in6->s6_addr; + struct in_addr in4; + struct sockaddr_in *sin; + + sin = (struct sockaddr_in *) addr; + pa += 3; + in4.s_addr = *pa; + sin->sin_addr = in4; + sin->sin_family = AF_INET; + if (send_msg_cmsg(sd, addr, alen, + ifindex, AF_INET) < 0) + goto out_err; + } + } +again: + iov[0].iov_len = len; + + if (args->version == AF_INET6) { + struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) sa; + + if (args->dev) { + /* avoid PKTINFO conflicts with bindtodev */ + if (sendto(sd, buf, len, 0, + (void *) addr, alen) < 0) + goto out_err; + } else { + /* kernel is allowing scope_id to be set to VRF + * index for LLA. for sends to global address + * reset scope id + */ + s6->sin6_scope_id = ifindex; + if (sendmsg(sd, &m, 0) < 0) + goto out_err; + } + } else { + int err; + + err = sendmsg(sd, &m, 0); + if (err < 0) { + if (errno == EACCES && try_broadcast) { + try_broadcast = 0; + if (!set_broadcast(sd)) + goto again; + errno = EACCES; + } + goto out_err; + } + } + log_msg("Sent message:\n"); + log_msg(" %.24s%s\n", buf, len > 24 ? " ..." : ""); + } + + return 1; +out_err: + log_err_errno("failed to send msg to peer"); + return -1; +} + +static int socket_read_stream(int sd) +{ + char buf[1024]; + int len; + + len = read(sd, buf, sizeof(buf)-1); + if (len == 0) { + log_msg("client closed connection.\n"); + return 0; + } else if (len < 0) { + log_msg("failed to read message\n"); + return -1; + } + + buf[len] = '\0'; + log_msg("Incoming message:\n"); + log_msg(" %.24s%s\n", buf, len > 24 ? " ..." : ""); + + if (!interactive && server_mode) { + if (write(sd, buf, len) < 0) { + log_err_errno("failed to send buf"); + return -1; + } + log_msg("Sent message:\n"); + log_msg(" %.24s%s\n", buf, len > 24 ? " ..." : ""); + } + + return 1; +} + +static int socket_read(int sd, struct sock_args *args) +{ + if (args->type == SOCK_STREAM) + return socket_read_stream(sd); + + return socket_read_dgram(sd, args); +} + +static int stdin_to_socket(int sd, int type, void *addr, socklen_t alen) +{ + char buf[1024]; + int len; + + if (fgets(buf, sizeof(buf), stdin) == NULL) + return 0; + + len = strlen(buf); + if (type == SOCK_STREAM) { + if (write(sd, buf, len) < 0) { + log_err_errno("failed to send buf"); + return -1; + } + } else { + int err; + +again: + err = sendto(sd, buf, len, 0, addr, alen); + if (err < 0) { + if (errno == EACCES && try_broadcast) { + try_broadcast = 0; + if (!set_broadcast(sd)) + goto again; + errno = EACCES; + } + log_err_errno("failed to send msg to peer"); + return -1; + } + } + log_msg("Sent message:\n"); + log_msg(" %.24s%s\n", buf, len > 24 ? " ..." : ""); + + return 1; +} + +static void set_recv_attr(int sd, int version) +{ + if (version == AF_INET6) { + set_recvpktinfo_v6(sd); + set_recverr_v6(sd); + } else { + set_pktinfo_v4(sd); + set_recverr_v4(sd); + } +} + +static int msg_loop(int client, int sd, void *addr, socklen_t alen, + struct sock_args *args) +{ + struct timeval timeout = { .tv_sec = prog_timeout }, *ptval = NULL; + fd_set rfds; + int nfds; + int rc; + + if (args->type != SOCK_STREAM) + set_recv_attr(sd, args->version); + + if (msg) { + msglen = strlen(msg); + + /* client sends first message */ + if (client) { + if (send_msg(sd, addr, alen, args)) + return 1; + } + if (!interactive) { + ptval = &timeout; + if (!prog_timeout) + timeout.tv_sec = 5; + } + } + + nfds = interactive ? MAX(fileno(stdin), sd) + 1 : sd + 1; + while (1) { + FD_ZERO(&rfds); + FD_SET(sd, &rfds); + if (interactive) + FD_SET(fileno(stdin), &rfds); + + rc = select(nfds, &rfds, NULL, NULL, ptval); + if (rc < 0) { + if (errno == EINTR) + continue; + + rc = 1; + log_err_errno("select failed"); + break; + } else if (rc == 0) { + log_error("Timed out waiting for response\n"); + rc = 2; + break; + } + + if (FD_ISSET(sd, &rfds)) { + rc = socket_read(sd, args); + if (rc < 0) { + rc = 1; + break; + } + if (rc == 0) + break; + } + + rc = 0; + + if (FD_ISSET(fileno(stdin), &rfds)) { + if (stdin_to_socket(sd, args->type, addr, alen) <= 0) + break; + } + + if (interactive) + continue; + + if (iter != -1) { + --iter; + if (iter == 0) + break; + } + + log_msg("Going into quiet mode\n"); + quiet = 1; + + if (client) { + if (send_msg(sd, addr, alen, args)) { + rc = 1; + break; + } + } + } + + return rc; +} + +static int msock_init(struct sock_args *args, int server) +{ + uint32_t if_addr = htonl(INADDR_ANY); + struct sockaddr_in laddr = { + .sin_family = AF_INET, + .sin_port = htons(args->port), + }; + int one = 1; + int sd; + + if (!server && args->has_local_ip) + if_addr = args->local_addr.in.s_addr; + + sd = socket(PF_INET, SOCK_DGRAM, 0); + if (sd < 0) { + log_err_errno("socket"); + return -1; + } + + if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, + (char *)&one, sizeof(one)) < 0) { + log_err_errno("Setting SO_REUSEADDR error"); + goto out_err; + } + + if (setsockopt(sd, SOL_SOCKET, SO_BROADCAST, + (char *)&one, sizeof(one)) < 0) + log_err_errno("Setting SO_BROADCAST error"); + + if (args->dev && bind_to_device(sd, args->dev) != 0) + goto out_err; + else if (args->use_setsockopt && + set_multicast_if(sd, args->ifindex)) + goto out_err; + + laddr.sin_addr.s_addr = if_addr; + + if (bind(sd, (struct sockaddr *) &laddr, sizeof(laddr)) < 0) { + log_err_errno("bind failed"); + goto out_err; + } + + if (server && + set_membership(sd, args->grp.s_addr, + args->local_addr.in.s_addr, args->dev)) + goto out_err; + + return sd; +out_err: + close(sd); + return -1; +} + +static int msock_server(struct sock_args *args) +{ + return msock_init(args, 1); +} + +static int msock_client(struct sock_args *args) +{ + return msock_init(args, 0); +} + +static int bind_socket(int sd, struct sock_args *args) +{ + struct sockaddr_in serv_addr = { + .sin_family = AF_INET, + }; + struct sockaddr_in6 serv6_addr = { + .sin6_family = AF_INET6, + }; + void *addr; + socklen_t alen; + + if (!args->has_local_ip && args->type == SOCK_RAW) + return 0; + + switch (args->version) { + case AF_INET: + serv_addr.sin_port = htons(args->port); + serv_addr.sin_addr = args->local_addr.in; + addr = &serv_addr; + alen = sizeof(serv_addr); + break; + + case AF_INET6: + serv6_addr.sin6_port = htons(args->port); + serv6_addr.sin6_addr = args->local_addr.in6; + addr = &serv6_addr; + alen = sizeof(serv6_addr); + break; + + default: + log_error("Invalid address family\n"); + return -1; + } + + if (bind(sd, addr, alen) < 0) { + log_err_errno("error binding socket"); + return -1; + } + + return 0; +} + +static int lsock_init(struct sock_args *args) +{ + long flags; + int sd; + + sd = socket(args->version, args->type, args->protocol); + if (sd < 0) { + log_err_errno("Error opening socket"); + return -1; + } + + if (set_reuseaddr(sd) != 0) + goto err; + + if (set_reuseport(sd) != 0) + goto err; + + if (args->dev && bind_to_device(sd, args->dev) != 0) + goto err; + else if (args->use_setsockopt && + set_unicast_if(sd, args->ifindex, args->version)) + goto err; + + if (bind_socket(sd, args)) + goto err; + + if (args->bind_test_only) + goto out; + + if (args->type == SOCK_STREAM && listen(sd, 1) < 0) { + log_err_errno("listen failed"); + goto err; + } + + flags = fcntl(sd, F_GETFL); + if ((flags < 0) || (fcntl(sd, F_SETFL, flags|O_NONBLOCK) < 0)) { + log_err_errno("Failed to set non-blocking option"); + goto err; + } + + if (fcntl(sd, F_SETFD, FD_CLOEXEC) < 0) + log_err_errno("Failed to set close-on-exec flag"); + +out: + return sd; + +err: + close(sd); + return -1; +} + +static int do_server(struct sock_args *args) +{ + struct timeval timeout = { .tv_sec = prog_timeout }, *ptval = NULL; + unsigned char addr[sizeof(struct sockaddr_in6)] = {}; + socklen_t alen = sizeof(addr); + int lsd, csd = -1; + + fd_set rfds; + int rc; + + if (prog_timeout) + ptval = &timeout; + + if (args->has_grp) + lsd = msock_server(args); + else + lsd = lsock_init(args); + + if (lsd < 0) + return 1; + + if (args->bind_test_only) { + close(lsd); + return 0; + } + + if (args->type != SOCK_STREAM) { + rc = msg_loop(0, lsd, (void *) addr, alen, args); + close(lsd); + return rc; + } + + if (args->password && tcp_md5_remote(lsd, args)) { + close(lsd); + return -1; + } + + while (1) { + log_msg("\n"); + log_msg("waiting for client connection.\n"); + FD_ZERO(&rfds); + FD_SET(lsd, &rfds); + + rc = select(lsd+1, &rfds, NULL, NULL, ptval); + if (rc == 0) { + rc = 2; + break; + } + + if (rc < 0) { + if (errno == EINTR) + continue; + + log_err_errno("select failed"); + break; + } + + if (FD_ISSET(lsd, &rfds)) { + + csd = accept(lsd, (void *) addr, &alen); + if (csd < 0) { + log_err_errno("accept failed"); + break; + } + + rc = show_sockstat(csd, args); + if (rc) + break; + + rc = check_device(csd, args); + if (rc) + break; + } + + rc = msg_loop(0, csd, (void *) addr, alen, args); + close(csd); + + if (!interactive) + break; + } + + close(lsd); + + return rc; +} + +static int wait_for_connect(int sd) +{ + struct timeval _tv = { .tv_sec = prog_timeout }, *tv = NULL; + fd_set wfd; + int val = 0, sz = sizeof(val); + int rc; + + FD_ZERO(&wfd); + FD_SET(sd, &wfd); + + if (prog_timeout) + tv = &_tv; + + rc = select(FD_SETSIZE, NULL, &wfd, NULL, tv); + if (rc == 0) { + log_error("connect timed out\n"); + return -2; + } else if (rc < 0) { + log_err_errno("select failed"); + return -3; + } + + if (getsockopt(sd, SOL_SOCKET, SO_ERROR, &val, (socklen_t *)&sz) < 0) { + log_err_errno("getsockopt(SO_ERROR) failed"); + return -4; + } + + if (val != 0) { + log_error("connect failed: %d: %s\n", val, strerror(val)); + return -1; + } + + return 0; +} + +static int connectsock(void *addr, socklen_t alen, struct sock_args *args) +{ + int sd, rc = -1; + long flags; + + sd = socket(args->version, args->type, args->protocol); + if (sd < 0) { + log_err_errno("Failed to create socket"); + return -1; + } + + flags = fcntl(sd, F_GETFL); + if ((flags < 0) || (fcntl(sd, F_SETFL, flags|O_NONBLOCK) < 0)) { + log_err_errno("Failed to set non-blocking option"); + goto err; + } + + if (set_reuseport(sd) != 0) + goto err; + + if (args->dev && bind_to_device(sd, args->dev) != 0) + goto err; + else if (args->use_setsockopt && + set_unicast_if(sd, args->ifindex, args->version)) + goto err; + + if (args->has_local_ip && bind_socket(sd, args)) + goto err; + + if (args->type != SOCK_STREAM) + goto out; + + if (args->password && tcp_md5sig(sd, addr, alen, args->password)) + goto err; + + if (args->bind_test_only) + goto out; + + if (connect(sd, addr, alen) < 0) { + if (errno != EINPROGRESS) { + log_err_errno("Failed to connect to remote host"); + rc = -1; + goto err; + } + rc = wait_for_connect(sd); + if (rc < 0) + goto err; + } +out: + return sd; + +err: + close(sd); + return rc; +} + +static int do_client(struct sock_args *args) +{ + struct sockaddr_in sin = { + .sin_family = AF_INET, + }; + struct sockaddr_in6 sin6 = { + .sin6_family = AF_INET6, + }; + void *addr; + int alen; + int rc = 0; + int sd; + + if (!args->has_remote_ip && !args->has_grp) { + fprintf(stderr, "remote IP or multicast group not given\n"); + return 1; + } + + switch (args->version) { + case AF_INET: + sin.sin_port = htons(args->port); + if (args->has_grp) + sin.sin_addr = args->grp; + else + sin.sin_addr = args->remote_addr.in; + addr = &sin; + alen = sizeof(sin); + break; + case AF_INET6: + sin6.sin6_port = htons(args->port); + sin6.sin6_addr = args->remote_addr.in6; + sin6.sin6_scope_id = args->scope_id; + addr = &sin6; + alen = sizeof(sin6); + break; + } + + if (args->has_grp) + sd = msock_client(args); + else + sd = connectsock(addr, alen, args); + + if (sd < 0) + return -sd; + + if (args->bind_test_only) + goto out; + + if (args->type == SOCK_STREAM) { + rc = show_sockstat(sd, args); + if (rc != 0) + goto out; + } + + rc = msg_loop(1, sd, addr, alen, args); + +out: + close(sd); + + return rc; +} + +enum addr_type { + ADDR_TYPE_LOCAL, + ADDR_TYPE_REMOTE, + ADDR_TYPE_MCAST, + ADDR_TYPE_EXPECTED_LOCAL, + ADDR_TYPE_EXPECTED_REMOTE, +}; + +static int convert_addr(struct sock_args *args, const char *_str, + enum addr_type atype) +{ + int family = args->version; + struct in6_addr *in6; + struct in_addr *in; + const char *desc; + char *str, *dev; + void *addr; + int rc = 0; + + str = strdup(_str); + if (!str) + return -ENOMEM; + + switch (atype) { + case ADDR_TYPE_LOCAL: + desc = "local"; + addr = &args->local_addr; + break; + case ADDR_TYPE_REMOTE: + desc = "remote"; + addr = &args->remote_addr; + break; + case ADDR_TYPE_MCAST: + desc = "mcast grp"; + addr = &args->grp; + break; + case ADDR_TYPE_EXPECTED_LOCAL: + desc = "expected local"; + addr = &args->expected_laddr; + break; + case ADDR_TYPE_EXPECTED_REMOTE: + desc = "expected remote"; + addr = &args->expected_raddr; + break; + default: + log_error("unknown address type"); + exit(1); + } + + switch (family) { + case AF_INET: + in = (struct in_addr *) addr; + if (str) { + if (inet_pton(AF_INET, str, in) == 0) { + log_error("Invalid %s IP address\n", desc); + rc = -1; + goto out; + } + } else { + in->s_addr = htonl(INADDR_ANY); + } + break; + + case AF_INET6: + dev = strchr(str, '%'); + if (dev) { + *dev = '\0'; + dev++; + } + + in6 = (struct in6_addr *) addr; + if (str) { + if (inet_pton(AF_INET6, str, in6) == 0) { + log_error("Invalid %s IPv6 address\n", desc); + rc = -1; + goto out; + } + } else { + *in6 = in6addr_any; + } + if (dev) { + args->scope_id = get_ifidx(dev); + if (args->scope_id < 0) { + log_error("Invalid scope on %s IPv6 address\n", + desc); + rc = -1; + goto out; + } + } + break; + + default: + log_error("Invalid address family\n"); + } + +out: + free(str); + return rc; +} + +static char *random_msg(int len) +{ + int i, n = 0, olen = len + 1; + char *m; + + if (len <= 0) + return NULL; + + m = malloc(olen); + if (!m) + return NULL; + + while (len > 26) { + i = snprintf(m + n, olen - n, "%.26s", + "abcdefghijklmnopqrstuvwxyz"); + n += i; + len -= i; + } + i = snprintf(m + n, olen - n, "%.*s", len, + "abcdefghijklmnopqrstuvwxyz"); + return m; +} + +#define GETOPT_STR "sr:l:p:t:g:P:DRn:M:d:SCi6L:0:1:2:Fbq" + +static void print_usage(char *prog) +{ + printf( + "usage: %s OPTS\n" + "Required:\n" + " -r addr remote address to connect to (client mode only)\n" + " -p port port to connect to (client mode)/listen on (server mode)\n" + " (default: %d)\n" + " -s server mode (default: client mode)\n" + " -t timeout seconds (default: none)\n" + "\n" + "Optional:\n" + " -F Restart server loop\n" + " -6 IPv6 (default is IPv4)\n" + " -P proto protocol for socket: icmp, ospf (default: none)\n" + " -D|R datagram (D) / raw (R) socket (default stream)\n" + " -l addr local address to bind to\n" + "\n" + " -d dev bind socket to given device name\n" + " -S use setsockopt (IP_UNICAST_IF or IP_MULTICAST_IF)\n" + " to set device binding\n" + " -C use cmsg and IP_PKTINFO to specify device binding\n" + "\n" + " -L len send random message of given length\n" + " -n num number of times to send message\n" + "\n" + " -M password use MD5 sum protection\n" + " -g grp multicast group (e.g., 239.1.1.1)\n" + " -i interactive mode (default is echo and terminate)\n" + "\n" + " -0 addr Expected local address\n" + " -1 addr Expected remote address\n" + " -2 dev Expected device name (or index) to receive packet\n" + "\n" + " -b Bind test only.\n" + " -q Be quiet. Run test without printing anything.\n" + , prog, DEFAULT_PORT); +} + +int main(int argc, char *argv[]) +{ + struct sock_args args = { + .version = AF_INET, + .type = SOCK_STREAM, + .port = DEFAULT_PORT, + }; + struct protoent *pe; + unsigned int tmp; + int forever = 0; + + /* process inputs */ + extern char *optarg; + int rc = 0; + + /* + * process input args + */ + + while ((rc = getopt(argc, argv, GETOPT_STR)) != -1) { + switch (rc) { + case 's': + server_mode = 1; + break; + case 'F': + forever = 1; + break; + case 'l': + args.has_local_ip = 1; + if (convert_addr(&args, optarg, ADDR_TYPE_LOCAL) < 0) + return 1; + break; + case 'r': + args.has_remote_ip = 1; + if (convert_addr(&args, optarg, ADDR_TYPE_REMOTE) < 0) + return 1; + break; + case 'p': + if (str_to_uint(optarg, 1, 65535, &tmp) != 0) { + fprintf(stderr, "Invalid port\n"); + return 1; + } + args.port = (unsigned short) tmp; + break; + case 't': + if (str_to_uint(optarg, 0, INT_MAX, + &prog_timeout) != 0) { + fprintf(stderr, "Invalid timeout\n"); + return 1; + } + break; + case 'D': + args.type = SOCK_DGRAM; + break; + case 'R': + args.type = SOCK_RAW; + args.port = 0; + break; + case 'P': + pe = getprotobyname(optarg); + if (pe) { + args.protocol = pe->p_proto; + } else { + if (str_to_uint(optarg, 0, 0xffff, &tmp) != 0) { + fprintf(stderr, "Invalid potocol\n"); + return 1; + } + args.protocol = tmp; + } + break; + case 'n': + iter = atoi(optarg); + break; + case 'L': + msg = random_msg(atoi(optarg)); + break; + case 'M': + args.password = optarg; + break; + case 'S': + args.use_setsockopt = 1; + break; + case 'C': + args.use_cmsg = 1; + break; + case 'd': + args.dev = optarg; + args.ifindex = get_ifidx(optarg); + if (args.ifindex < 0) { + fprintf(stderr, "Invalid device name\n"); + return 1; + } + break; + case 'i': + interactive = 1; + break; + case 'g': + args.has_grp = 1; + if (convert_addr(&args, optarg, ADDR_TYPE_MCAST) < 0) + return 1; + args.type = SOCK_DGRAM; + break; + case '6': + args.version = AF_INET6; + break; + case 'b': + args.bind_test_only = 1; + break; + case '0': + args.has_expected_laddr = 1; + if (convert_addr(&args, optarg, + ADDR_TYPE_EXPECTED_LOCAL)) + return 1; + break; + case '1': + args.has_expected_raddr = 1; + if (convert_addr(&args, optarg, + ADDR_TYPE_EXPECTED_REMOTE)) + return 1; + + break; + case '2': + if (str_to_uint(optarg, 0, 0x7ffffff, &tmp) != 0) { + tmp = get_ifidx(optarg); + if (tmp < 0) { + fprintf(stderr, + "Invalid device index\n"); + return 1; + } + } + args.expected_ifindex = (int)tmp; + break; + case 'q': + quiet = 1; + break; + default: + print_usage(argv[0]); + return 1; + } + } + + if (args.password && + (!args.has_remote_ip || args.type != SOCK_STREAM)) { + log_error("MD5 passwords apply to TCP only and require a remote ip for the password\n"); + return 1; + } + + if ((args.use_setsockopt || args.use_cmsg) && !args.ifindex) { + fprintf(stderr, "Device binding not specified\n"); + return 1; + } + if (args.use_setsockopt || args.use_cmsg) + args.dev = NULL; + + if (iter == 0) { + fprintf(stderr, "Invalid number of messages to send\n"); + return 1; + } + + if (args.type == SOCK_STREAM && !args.protocol) + args.protocol = IPPROTO_TCP; + if (args.type == SOCK_DGRAM && !args.protocol) + args.protocol = IPPROTO_UDP; + + if ((args.type == SOCK_STREAM || args.type == SOCK_DGRAM) && + args.port == 0) { + fprintf(stderr, "Invalid port number\n"); + return 1; + } + + if (!server_mode && !args.has_grp && + !args.has_remote_ip && !args.has_local_ip) { + fprintf(stderr, + "Local (server mode) or remote IP (client IP) required\n"); + return 1; + } + + if (interactive) { + prog_timeout = 0; + msg = NULL; + } + + if (server_mode) { + do { + rc = do_server(&args); + } while (forever); + + return rc; + } + return do_client(&args); +} -- cgit v1.2.3-59-g8ed1b From 6f9d5cacfe07308fd4007ebdcb76861752d0a1ad Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 1 Aug 2019 11:56:35 -0700 Subject: selftests: Setup for functional tests for fib and socket lookups Initial commit for functional test suite for fib and socket lookups. This commit contains the namespace setup, networking config, test options and other basic infrastructure. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/Makefile | 2 +- tools/testing/selftests/net/fcnal-test.sh | 520 ++++++++++++++++++++++++++++++ 2 files changed, 521 insertions(+), 1 deletion(-) create mode 100755 tools/testing/selftests/net/fcnal-test.sh (limited to 'tools') diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index ba9ee36c9e94..70f2d6656170 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -10,7 +10,7 @@ TEST_PROGS += fib_tests.sh fib-onlink-tests.sh pmtu.sh udpgso.sh ip_defrag.sh TEST_PROGS += udpgso_bench.sh fib_rule_tests.sh msg_zerocopy.sh psock_snd.sh TEST_PROGS += udpgro_bench.sh udpgro.sh test_vxlan_under_vrf.sh reuseport_addr_any.sh TEST_PROGS += test_vxlan_fdb_changelink.sh so_txtime.sh ipv6_flowlabel.sh -TEST_PROGS += tcp_fastopen_backup_key.sh +TEST_PROGS += tcp_fastopen_backup_key.sh fcnal-test.sh TEST_PROGS_EXTENDED := in_netns.sh TEST_GEN_FILES = socket nettest TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy reuseport_addr_any diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh new file mode 100755 index 000000000000..22cfbd2fd09c --- /dev/null +++ b/tools/testing/selftests/net/fcnal-test.sh @@ -0,0 +1,520 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2019 David Ahern . All rights reserved. +# +# IPv4 and IPv6 functional tests focusing on VRF and routing lookups +# for various permutations: +# 1. icmp, tcp, udp and netfilter +# 2. client, server, no-server +# 3. global address on interface +# 4. global address on 'lo' +# 5. remote and local traffic +# 6. VRF and non-VRF permutations +# +# Setup: +# ns-A | ns-B +# No VRF case: +# [ lo ] [ eth1 ]---|---[ eth1 ] [ lo ] +# remote address +# VRF case: +# [ red ]---[ eth1 ]---|---[ eth1 ] [ lo ] +# +# ns-A: +# eth1: 172.16.1.1/24, 2001:db8:1::1/64 +# lo: 127.0.0.1/8, ::1/128 +# 172.16.2.1/32, 2001:db8:2::1/128 +# red: 127.0.0.1/8, ::1/128 +# 172.16.3.1/32, 2001:db8:3::1/128 +# +# ns-B: +# eth1: 172.16.1.2/24, 2001:db8:1::2/64 +# lo2: 127.0.0.1/8, ::1/128 +# 172.16.2.2/32, 2001:db8:2::2/128 +# +# server / client nomenclature relative to ns-A + +VERBOSE=0 + +NSA_DEV=eth1 +NSB_DEV=eth1 +VRF=red +VRF_TABLE=1101 + +# IPv4 config +NSA_IP=172.16.1.1 +NSB_IP=172.16.1.2 +VRF_IP=172.16.3.1 + +# IPv6 config +NSA_IP6=2001:db8:1::1 +NSB_IP6=2001:db8:1::2 +VRF_IP6=2001:db8:3::1 + +NSA_LO_IP=172.16.2.1 +NSB_LO_IP=172.16.2.2 +NSA_LO_IP6=2001:db8:2::1 +NSB_LO_IP6=2001:db8:2::2 + +MCAST=ff02::1 +# set after namespace create +NSA_LINKIP6= +NSB_LINKIP6= + +NSA=ns-A +NSB=ns-B + +NSA_CMD="ip netns exec ${NSA}" +NSB_CMD="ip netns exec ${NSB}" + +which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping) + +################################################################################ +# utilities + +log_test() +{ + local rc=$1 + local expected=$2 + local msg="$3" + + [ "${VERBOSE}" = "1" ] && echo + + if [ ${rc} -eq ${expected} ]; then + nsuccess=$((nsuccess+1)) + printf "TEST: %-70s [ OK ]\n" "${msg}" + else + nfail=$((nfail+1)) + printf "TEST: %-70s [FAIL]\n" "${msg}" + if [ "${PAUSE_ON_FAIL}" = "yes" ]; then + echo + echo "hit enter to continue, 'q' to quit" + read a + [ "$a" = "q" ] && exit 1 + fi + fi + + if [ "${PAUSE}" = "yes" ]; then + echo + echo "hit enter to continue, 'q' to quit" + read a + [ "$a" = "q" ] && exit 1 + fi + + kill_procs +} + +log_test_addr() +{ + local addr=$1 + local rc=$2 + local expected=$3 + local msg="$4" + local astr + + astr=$(addr2str ${addr}) + log_test $rc $expected "$msg - ${astr}" +} + +log_section() +{ + echo + echo "###########################################################################" + echo "$*" + echo "###########################################################################" + echo +} + +log_subsection() +{ + echo + echo "#################################################################" + echo "$*" + echo +} + +log_start() +{ + # make sure we have no test instances running + kill_procs + + if [ "${VERBOSE}" = "1" ]; then + echo + echo "#######################################################" + fi +} + +log_debug() +{ + if [ "${VERBOSE}" = "1" ]; then + echo + echo "$*" + echo + fi +} + +show_hint() +{ + if [ "${VERBOSE}" = "1" ]; then + echo "HINT: $*" + echo + fi +} + +kill_procs() +{ + killall nettest ping ping6 >/dev/null 2>&1 + sleep 1 +} + +do_run_cmd() +{ + local cmd="$*" + local out + + if [ "$VERBOSE" = "1" ]; then + echo "COMMAND: ${cmd}" + fi + + out=$($cmd 2>&1) + rc=$? + if [ "$VERBOSE" = "1" -a -n "$out" ]; then + echo "$out" + fi + + return $rc +} + +run_cmd() +{ + do_run_cmd ${NSA_CMD} $* +} + +run_cmd_nsb() +{ + do_run_cmd ${NSB_CMD} $* +} + +setup_cmd() +{ + local cmd="$*" + local rc + + run_cmd ${cmd} + rc=$? + if [ $rc -ne 0 ]; then + # show user the command if not done so already + if [ "$VERBOSE" = "0" ]; then + echo "setup command: $cmd" + fi + echo "failed. stopping tests" + if [ "${PAUSE_ON_FAIL}" = "yes" ]; then + echo + echo "hit enter to continue" + read a + fi + exit $rc + fi +} + +setup_cmd_nsb() +{ + local cmd="$*" + local rc + + run_cmd_nsb ${cmd} + rc=$? + if [ $rc -ne 0 ]; then + # show user the command if not done so already + if [ "$VERBOSE" = "0" ]; then + echo "setup command: $cmd" + fi + echo "failed. stopping tests" + if [ "${PAUSE_ON_FAIL}" = "yes" ]; then + echo + echo "hit enter to continue" + read a + fi + exit $rc + fi +} + +# set sysctl values in NS-A +set_sysctl() +{ + echo "SYSCTL: $*" + echo + run_cmd sysctl -q -w $* +} + +################################################################################ +# Setup for tests + +addr2str() +{ + case "$1" in + 127.0.0.1) echo "loopback";; + ::1) echo "IPv6 loopback";; + + ${NSA_IP}) echo "ns-A IP";; + ${NSA_IP6}) echo "ns-A IPv6";; + ${NSA_LO_IP}) echo "ns-A loopback IP";; + ${NSA_LO_IP6}) echo "ns-A loopback IPv6";; + ${NSA_LINKIP6}|${NSA_LINKIP6}%*) echo "ns-A IPv6 LLA";; + + ${NSB_IP}) echo "ns-B IP";; + ${NSB_IP6}) echo "ns-B IPv6";; + ${NSB_LO_IP}) echo "ns-B loopback IP";; + ${NSB_LO_IP6}) echo "ns-B loopback IPv6";; + ${NSB_LINKIP6}|${NSB_LINKIP6}%*) echo "ns-B IPv6 LLA";; + + ${VRF_IP}) echo "VRF IP";; + ${VRF_IP6}) echo "VRF IPv6";; + + ${MCAST}%*) echo "multicast IP";; + + *) echo "unknown";; + esac +} + +get_linklocal() +{ + local ns=$1 + local dev=$2 + local addr + + addr=$(ip -netns ${ns} -6 -br addr show dev ${dev} | \ + awk '{ + for (i = 3; i <= NF; ++i) { + if ($i ~ /^fe80/) + print $i + } + }' + ) + addr=${addr/\/*} + + [ -z "$addr" ] && return 1 + + echo $addr + + return 0 +} + +################################################################################ +# create namespaces and vrf + +create_vrf() +{ + local ns=$1 + local vrf=$2 + local table=$3 + local addr=$4 + local addr6=$5 + + ip -netns ${ns} link add ${vrf} type vrf table ${table} + ip -netns ${ns} link set ${vrf} up + ip -netns ${ns} route add vrf ${vrf} unreachable default metric 8192 + ip -netns ${ns} -6 route add vrf ${vrf} unreachable default metric 8192 + + ip -netns ${ns} addr add 127.0.0.1/8 dev ${vrf} + ip -netns ${ns} -6 addr add ::1 dev ${vrf} nodad + if [ "${addr}" != "-" ]; then + ip -netns ${ns} addr add dev ${vrf} ${addr} + fi + if [ "${addr6}" != "-" ]; then + ip -netns ${ns} -6 addr add dev ${vrf} ${addr6} + fi + + ip -netns ${ns} ru del pref 0 + ip -netns ${ns} ru add pref 32765 from all lookup local + ip -netns ${ns} -6 ru del pref 0 + ip -netns ${ns} -6 ru add pref 32765 from all lookup local +} + +create_ns() +{ + local ns=$1 + local addr=$2 + local addr6=$3 + + ip netns add ${ns} + + ip -netns ${ns} link set lo up + if [ "${addr}" != "-" ]; then + ip -netns ${ns} addr add dev lo ${addr} + fi + if [ "${addr6}" != "-" ]; then + ip -netns ${ns} -6 addr add dev lo ${addr6} + fi + + ip -netns ${ns} ro add unreachable default metric 8192 + ip -netns ${ns} -6 ro add unreachable default metric 8192 + + ip netns exec ${ns} sysctl -qw net.ipv4.ip_forward=1 + ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1 + ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.forwarding=1 + ip netns exec ${ns} sysctl -qw net.ipv6.conf.default.forwarding=1 +} + +# create veth pair to connect namespaces and apply addresses. +connect_ns() +{ + local ns1=$1 + local ns1_dev=$2 + local ns1_addr=$3 + local ns1_addr6=$4 + local ns2=$5 + local ns2_dev=$6 + local ns2_addr=$7 + local ns2_addr6=$8 + + ip -netns ${ns1} li add ${ns1_dev} type veth peer name tmp + ip -netns ${ns1} li set ${ns1_dev} up + ip -netns ${ns1} li set tmp netns ${ns2} name ${ns2_dev} + ip -netns ${ns2} li set ${ns2_dev} up + + if [ "${ns1_addr}" != "-" ]; then + ip -netns ${ns1} addr add dev ${ns1_dev} ${ns1_addr} + ip -netns ${ns2} addr add dev ${ns2_dev} ${ns2_addr} + fi + + if [ "${ns1_addr6}" != "-" ]; then + ip -netns ${ns1} addr add dev ${ns1_dev} ${ns1_addr6} + ip -netns ${ns2} addr add dev ${ns2_dev} ${ns2_addr6} + fi +} + +cleanup() +{ + # explicit cleanups to check those code paths + ip netns | grep -q ${NSA} + if [ $? -eq 0 ]; then + ip -netns ${NSA} link delete ${VRF} + ip -netns ${NSA} ro flush table ${VRF_TABLE} + + ip -netns ${NSA} addr flush dev ${NSA_DEV} + ip -netns ${NSA} -6 addr flush dev ${NSA_DEV} + ip -netns ${NSA} link set dev ${NSA_DEV} down + ip -netns ${NSA} link del dev ${NSA_DEV} + + ip netns del ${NSA} + fi + + ip netns del ${NSB} +} + +setup() +{ + local with_vrf=${1} + + # make sure we are starting with a clean slate + kill_procs + cleanup 2>/dev/null + + log_debug "Configuring network namespaces" + set -e + + create_ns ${NSA} ${NSA_LO_IP}/32 ${NSA_LO_IP6}/128 + create_ns ${NSB} ${NSB_LO_IP}/32 ${NSB_LO_IP6}/128 + connect_ns ${NSA} ${NSA_DEV} ${NSA_IP}/24 ${NSA_IP6}/64 \ + ${NSB} ${NSB_DEV} ${NSB_IP}/24 ${NSB_IP6}/64 + + NSA_LINKIP6=$(get_linklocal ${NSA} ${NSA_DEV}) + NSB_LINKIP6=$(get_linklocal ${NSB} ${NSB_DEV}) + + # tell ns-A how to get to remote addresses of ns-B + if [ "${with_vrf}" = "yes" ]; then + create_vrf ${NSA} ${VRF} ${VRF_TABLE} ${VRF_IP} ${VRF_IP6} + + ip -netns ${NSA} link set dev ${NSA_DEV} vrf ${VRF} + ip -netns ${NSA} ro add vrf ${VRF} ${NSB_LO_IP}/32 via ${NSB_IP} dev ${NSA_DEV} + ip -netns ${NSA} -6 ro add vrf ${VRF} ${NSB_LO_IP6}/128 via ${NSB_IP6} dev ${NSA_DEV} + + ip -netns ${NSB} ro add ${VRF_IP}/32 via ${NSA_IP} dev ${NSB_DEV} + ip -netns ${NSB} -6 ro add ${VRF_IP6}/128 via ${NSA_IP6} dev ${NSB_DEV} + else + ip -netns ${NSA} ro add ${NSB_LO_IP}/32 via ${NSB_IP} dev ${NSA_DEV} + ip -netns ${NSA} ro add ${NSB_LO_IP6}/128 via ${NSB_IP6} dev ${NSA_DEV} + fi + + + # tell ns-B how to get to remote addresses of ns-A + ip -netns ${NSB} ro add ${NSA_LO_IP}/32 via ${NSA_IP} dev ${NSB_DEV} + ip -netns ${NSB} ro add ${NSA_LO_IP6}/128 via ${NSA_IP6} dev ${NSB_DEV} + + set +e + + sleep 1 +} + +################################################################################ +# usage + +usage() +{ + cat < Test name/set to run + -p Pause on fail + -P Pause after each test + -v Be verbose +EOF +} + +################################################################################ +# main + +TESTS_IPV4="" +TESTS_IPV6="" +PAUSE_ON_FAIL=no +PAUSE=no + +while getopts :46t:pPvh o +do + case $o in + 4) TESTS=ipv4;; + 6) TESTS=ipv6;; + t) TESTS=$OPTARG;; + p) PAUSE_ON_FAIL=yes;; + P) PAUSE=yes;; + v) VERBOSE=1;; + h) usage; exit 0;; + *) usage; exit 1;; + esac +done + +# make sure we don't pause twice +[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no + +# +# show user test config +# +if [ -z "$TESTS" ]; then + TESTS="$TESTS_IPV4 $TESTS_IPV6 $TESTS_OTHER" +elif [ "$TESTS" = "ipv4" ]; then + TESTS="$TESTS_IPV4" +elif [ "$TESTS" = "ipv6" ]; then + TESTS="$TESTS_IPV6" +fi + +declare -i nfail=0 +declare -i nsuccess=0 + +for t in $TESTS +do + case $t in + # setup namespaces and config, but do not run any tests + setup) setup; exit 0;; + vrf_setup) setup "yes"; exit 0;; + + help) echo "Test names: $TESTS"; exit 0;; + esac +done + +cleanup 2>/dev/null + +printf "\nTests passed: %3d\n" ${nsuccess} +printf "Tests failed: %3d\n" ${nfail} -- cgit v1.2.3-59-g8ed1b From c032dd8cc7e23bbcc53e00b262594657ff1b7532 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 1 Aug 2019 11:56:36 -0700 Subject: selftests: Add ipv4 ping tests to fcnal-test Add ping tests to fcnal-test.sh. Covers the permutations of directly connected addresses, routed destinations, VRF and non-VRF, and expected failures. Setup includes unreachable routes and fib rules blocking traffic. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/fcnal-test.sh | 268 +++++++++++++++++++++++++++++- 1 file changed, 267 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh index 22cfbd2fd09c..3f6e786b34ae 100755 --- a/tools/testing/selftests/net/fcnal-test.sh +++ b/tools/testing/selftests/net/fcnal-test.sh @@ -447,6 +447,270 @@ setup() sleep 1 } +################################################################################ +# IPv4 + +ipv4_ping_novrf() +{ + local a + + # + # out + # + for a in ${NSB_IP} ${NSB_LO_IP} + do + log_start + run_cmd ping -c1 -w1 ${a} + log_test_addr ${a} $? 0 "ping out" + + log_start + run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 0 "ping out, device bind" + + log_start + run_cmd ping -c1 -w1 -I ${NSA_LO_IP} ${a} + log_test_addr ${a} $? 0 "ping out, address bind" + done + + # + # in + # + for a in ${NSA_IP} ${NSA_LO_IP} + do + log_start + run_cmd_nsb ping -c1 -w1 ${a} + log_test_addr ${a} $? 0 "ping in" + done + + # + # local traffic + # + for a in ${NSA_IP} ${NSA_LO_IP} 127.0.0.1 + do + log_start + run_cmd ping -c1 -w1 ${a} + log_test_addr ${a} $? 0 "ping local" + done + + # + # local traffic, socket bound to device + # + # address on device + a=${NSA_IP} + log_start + run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 0 "ping local, device bind" + + # loopback addresses not reachable from device bind + # fails in a really weird way though because ipv4 special cases + # route lookups with oif set. + for a in ${NSA_LO_IP} 127.0.0.1 + do + log_start + show_hint "Fails since address on loopback device is out of device scope" + run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 1 "ping local, device bind" + done + + # + # ip rule blocks reachability to remote address + # + log_start + setup_cmd ip rule add pref 32765 from all lookup local + setup_cmd ip rule del pref 0 from all lookup local + setup_cmd ip rule add pref 50 to ${NSB_LO_IP} prohibit + setup_cmd ip rule add pref 51 from ${NSB_IP} prohibit + + a=${NSB_LO_IP} + run_cmd ping -c1 -w1 ${a} + log_test_addr ${a} $? 2 "ping out, blocked by rule" + + # NOTE: ipv4 actually allows the lookup to fail and yet still create + # a viable rtable if the oif (e.g., bind to device) is set, so this + # case succeeds despite the rule + # run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a} + + a=${NSA_LO_IP} + log_start + show_hint "Response generates ICMP (or arp request is ignored) due to ip rule" + run_cmd_nsb ping -c1 -w1 ${a} + log_test_addr ${a} $? 1 "ping in, blocked by rule" + + [ "$VERBOSE" = "1" ] && echo + setup_cmd ip rule del pref 32765 from all lookup local + setup_cmd ip rule add pref 0 from all lookup local + setup_cmd ip rule del pref 50 to ${NSB_LO_IP} prohibit + setup_cmd ip rule del pref 51 from ${NSB_IP} prohibit + + # + # route blocks reachability to remote address + # + log_start + setup_cmd ip route replace unreachable ${NSB_LO_IP} + setup_cmd ip route replace unreachable ${NSB_IP} + + a=${NSB_LO_IP} + run_cmd ping -c1 -w1 ${a} + log_test_addr ${a} $? 2 "ping out, blocked by route" + + # NOTE: ipv4 actually allows the lookup to fail and yet still create + # a viable rtable if the oif (e.g., bind to device) is set, so this + # case succeeds despite not having a route for the address + # run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a} + + a=${NSA_LO_IP} + log_start + show_hint "Response is dropped (or arp request is ignored) due to ip route" + run_cmd_nsb ping -c1 -w1 ${a} + log_test_addr ${a} $? 1 "ping in, blocked by route" + + # + # remove 'remote' routes; fallback to default + # + log_start + setup_cmd ip ro del ${NSB_LO_IP} + + a=${NSB_LO_IP} + run_cmd ping -c1 -w1 ${a} + log_test_addr ${a} $? 2 "ping out, unreachable default route" + + # NOTE: ipv4 actually allows the lookup to fail and yet still create + # a viable rtable if the oif (e.g., bind to device) is set, so this + # case succeeds despite not having a route for the address + # run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a} +} + +ipv4_ping_vrf() +{ + local a + + # should default on; does not exist on older kernels + set_sysctl net.ipv4.raw_l3mdev_accept=1 2>/dev/null + + # + # out + # + for a in ${NSB_IP} ${NSB_LO_IP} + do + log_start + run_cmd ping -c1 -w1 -I ${VRF} ${a} + log_test_addr ${a} $? 0 "ping out, VRF bind" + + log_start + run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 0 "ping out, device bind" + + log_start + run_cmd ip vrf exec ${VRF} ping -c1 -w1 -I ${NSA_IP} ${a} + log_test_addr ${a} $? 0 "ping out, vrf device + dev address bind" + + log_start + run_cmd ip vrf exec ${VRF} ping -c1 -w1 -I ${VRF_IP} ${a} + log_test_addr ${a} $? 0 "ping out, vrf device + vrf address bind" + done + + # + # in + # + for a in ${NSA_IP} ${VRF_IP} + do + log_start + run_cmd_nsb ping -c1 -w1 ${a} + log_test_addr ${a} $? 0 "ping in" + done + + # + # local traffic, local address + # + for a in ${NSA_IP} ${VRF_IP} 127.0.0.1 + do + log_start + show_hint "Source address should be ${a}" + run_cmd ping -c1 -w1 -I ${VRF} ${a} + log_test_addr ${a} $? 0 "ping local, VRF bind" + done + + # + # local traffic, socket bound to device + # + # address on device + a=${NSA_IP} + log_start + run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 0 "ping local, device bind" + + # vrf device is out of scope + for a in ${VRF_IP} 127.0.0.1 + do + log_start + show_hint "Fails since address on vrf device is out of device scope" + run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 1 "ping local, device bind" + done + + # + # ip rule blocks address + # + log_start + setup_cmd ip rule add pref 50 to ${NSB_LO_IP} prohibit + setup_cmd ip rule add pref 51 from ${NSB_IP} prohibit + + a=${NSB_LO_IP} + run_cmd ping -c1 -w1 -I ${VRF} ${a} + log_test_addr ${a} $? 2 "ping out, vrf bind, blocked by rule" + + log_start + run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 2 "ping out, device bind, blocked by rule" + + a=${NSA_LO_IP} + log_start + show_hint "Response lost due to ip rule" + run_cmd_nsb ping -c1 -w1 ${a} + log_test_addr ${a} $? 1 "ping in, blocked by rule" + + [ "$VERBOSE" = "1" ] && echo + setup_cmd ip rule del pref 50 to ${NSB_LO_IP} prohibit + setup_cmd ip rule del pref 51 from ${NSB_IP} prohibit + + # + # remove 'remote' routes; fallback to default + # + log_start + setup_cmd ip ro del vrf ${VRF} ${NSB_LO_IP} + + a=${NSB_LO_IP} + run_cmd ping -c1 -w1 -I ${VRF} ${a} + log_test_addr ${a} $? 2 "ping out, vrf bind, unreachable route" + + log_start + run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 2 "ping out, device bind, unreachable route" + + a=${NSA_LO_IP} + log_start + show_hint "Response lost by unreachable route" + run_cmd_nsb ping -c1 -w1 ${a} + log_test_addr ${a} $? 1 "ping in, unreachable route" +} + +ipv4_ping() +{ + log_section "IPv4 ping" + + log_subsection "No VRF" + setup + set_sysctl net.ipv4.raw_l3mdev_accept=0 2>/dev/null + ipv4_ping_novrf + setup + set_sysctl net.ipv4.raw_l3mdev_accept=1 2>/dev/null + ipv4_ping_novrf + + log_subsection "With VRF" + setup "yes" + ipv4_ping_vrf +} + ################################################################################ # usage @@ -467,7 +731,7 @@ EOF ################################################################################ # main -TESTS_IPV4="" +TESTS_IPV4="ipv4_ping" TESTS_IPV6="" PAUSE_ON_FAIL=no PAUSE=no @@ -506,6 +770,8 @@ declare -i nsuccess=0 for t in $TESTS do case $t in + ipv4_ping|ping) ipv4_ping;; + # setup namespaces and config, but do not run any tests setup) setup; exit 0;; vrf_setup) setup "yes"; exit 0;; -- cgit v1.2.3-59-g8ed1b From c0644e71df3302ce44ef4572d3df9fb4758bcb8b Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 1 Aug 2019 11:56:37 -0700 Subject: selftests: Add ipv6 ping tests to fcnal-test Add IPv6 ping tests to fcnal-test.sh. Covers the permutations of directly connected addresses, routed destinations, VRF and non-VRF, and expected failures. Setup includes unreachable routes and fib rules blocking traffic. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/fcnal-test.sh | 284 +++++++++++++++++++++++++++++- 1 file changed, 283 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh index 3f6e786b34ae..4da510f6d625 100755 --- a/tools/testing/selftests/net/fcnal-test.sh +++ b/tools/testing/selftests/net/fcnal-test.sh @@ -711,6 +711,287 @@ ipv4_ping() ipv4_ping_vrf } +################################################################################ +# IPv6 + +ipv6_ping_novrf() +{ + local a + + # should not have an impact, but make a known state + set_sysctl net.ipv4.raw_l3mdev_accept=0 2>/dev/null + + # + # out + # + for a in ${NSB_IP6} ${NSB_LO_IP6} ${NSB_LINKIP6}%${NSA_DEV} ${MCAST}%${NSA_DEV} + do + log_start + run_cmd ${ping6} -c1 -w1 ${a} + log_test_addr ${a} $? 0 "ping out" + done + + for a in ${NSB_IP6} ${NSB_LO_IP6} + do + log_start + run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 0 "ping out, device bind" + + log_start + run_cmd ${ping6} -c1 -w1 -I ${NSA_LO_IP6} ${a} + log_test_addr ${a} $? 0 "ping out, loopback address bind" + done + + # + # in + # + for a in ${NSA_IP6} ${NSA_LO_IP6} ${NSA_LINKIP6}%${NSB_DEV} ${MCAST}%${NSB_DEV} + do + log_start + run_cmd_nsb ${ping6} -c1 -w1 ${a} + log_test_addr ${a} $? 0 "ping in" + done + + # + # local traffic, local address + # + for a in ${NSA_IP6} ${NSA_LO_IP6} ::1 ${NSA_LINKIP6}%${NSA_DEV} ${MCAST}%${NSA_DEV} + do + log_start + run_cmd ${ping6} -c1 -w1 ${a} + log_test_addr ${a} $? 0 "ping local, no bind" + done + + for a in ${NSA_IP6} ${NSA_LINKIP6}%${NSA_DEV} ${MCAST}%${NSA_DEV} + do + log_start + run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 0 "ping local, device bind" + done + + for a in ${NSA_LO_IP6} ::1 + do + log_start + show_hint "Fails since address on loopback is out of device scope" + run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 2 "ping local, device bind" + done + + # + # ip rule blocks address + # + log_start + setup_cmd ip -6 rule add pref 32765 from all lookup local + setup_cmd ip -6 rule del pref 0 from all lookup local + setup_cmd ip -6 rule add pref 50 to ${NSB_LO_IP6} prohibit + setup_cmd ip -6 rule add pref 51 from ${NSB_IP6} prohibit + + a=${NSB_LO_IP6} + run_cmd ${ping6} -c1 -w1 ${a} + log_test_addr ${a} $? 2 "ping out, blocked by rule" + + log_start + run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 2 "ping out, device bind, blocked by rule" + + a=${NSA_LO_IP6} + log_start + show_hint "Response lost due to ip rule" + run_cmd_nsb ${ping6} -c1 -w1 ${a} + log_test_addr ${a} $? 1 "ping in, blocked by rule" + + setup_cmd ip -6 rule add pref 0 from all lookup local + setup_cmd ip -6 rule del pref 32765 from all lookup local + setup_cmd ip -6 rule del pref 50 to ${NSB_LO_IP6} prohibit + setup_cmd ip -6 rule del pref 51 from ${NSB_IP6} prohibit + + # + # route blocks reachability to remote address + # + log_start + setup_cmd ip -6 route del ${NSB_LO_IP6} + setup_cmd ip -6 route add unreachable ${NSB_LO_IP6} metric 10 + setup_cmd ip -6 route add unreachable ${NSB_IP6} metric 10 + + a=${NSB_LO_IP6} + run_cmd ${ping6} -c1 -w1 ${a} + log_test_addr ${a} $? 2 "ping out, blocked by route" + + log_start + run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 2 "ping out, device bind, blocked by route" + + a=${NSA_LO_IP6} + log_start + show_hint "Response lost due to ip route" + run_cmd_nsb ${ping6} -c1 -w1 ${a} + log_test_addr ${a} $? 1 "ping in, blocked by route" + + + # + # remove 'remote' routes; fallback to default + # + log_start + setup_cmd ip -6 ro del unreachable ${NSB_LO_IP6} + setup_cmd ip -6 ro del unreachable ${NSB_IP6} + + a=${NSB_LO_IP6} + run_cmd ${ping6} -c1 -w1 ${a} + log_test_addr ${a} $? 2 "ping out, unreachable route" + + log_start + run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 2 "ping out, device bind, unreachable route" +} + +ipv6_ping_vrf() +{ + local a + + # should default on; does not exist on older kernels + set_sysctl net.ipv4.raw_l3mdev_accept=1 2>/dev/null + + # + # out + # + for a in ${NSB_IP6} ${NSB_LO_IP6} + do + log_start + run_cmd ${ping6} -c1 -w1 -I ${VRF} ${a} + log_test_addr ${a} $? 0 "ping out, VRF bind" + done + + for a in ${NSB_LINKIP6}%${VRF} ${MCAST}%${VRF} + do + log_start + show_hint "Fails since VRF device does not support linklocal or multicast" + run_cmd ${ping6} -c1 -w1 ${a} + log_test_addr ${a} $? 2 "ping out, VRF bind" + done + + for a in ${NSB_IP6} ${NSB_LO_IP6} ${NSB_LINKIP6}%${NSA_DEV} ${MCAST}%${NSA_DEV} + do + log_start + run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 0 "ping out, device bind" + done + + for a in ${NSB_IP6} ${NSB_LO_IP6} ${NSB_LINKIP6}%${NSA_DEV} + do + log_start + run_cmd ip vrf exec ${VRF} ${ping6} -c1 -w1 -I ${VRF_IP6} ${a} + log_test_addr ${a} $? 0 "ping out, vrf device+address bind" + done + + # + # in + # + for a in ${NSA_IP6} ${VRF_IP6} ${NSA_LINKIP6}%${NSB_DEV} ${MCAST}%${NSB_DEV} + do + log_start + run_cmd_nsb ${ping6} -c1 -w1 ${a} + log_test_addr ${a} $? 0 "ping in" + done + + a=${NSA_LO_IP6} + log_start + show_hint "Fails since loopback address is out of VRF scope" + run_cmd_nsb ${ping6} -c1 -w1 ${a} + log_test_addr ${a} $? 1 "ping in" + + # + # local traffic, local address + # + for a in ${NSA_IP6} ${VRF_IP6} ::1 + do + log_start + show_hint "Source address should be ${a}" + run_cmd ${ping6} -c1 -w1 -I ${VRF} ${a} + log_test_addr ${a} $? 0 "ping local, VRF bind" + done + + for a in ${NSA_IP6} ${NSA_LINKIP6}%${NSA_DEV} ${MCAST}%${NSA_DEV} + do + log_start + run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 0 "ping local, device bind" + done + + # LLA to GUA - remove ipv6 global addresses from ns-B + setup_cmd_nsb ip -6 addr del ${NSB_IP6}/64 dev ${NSB_DEV} + setup_cmd_nsb ip -6 addr del ${NSB_LO_IP6}/128 dev lo + setup_cmd_nsb ip -6 ro add ${NSA_IP6}/128 via ${NSA_LINKIP6} dev ${NSB_DEV} + + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd_nsb ${ping6} -c1 -w1 ${NSA_IP6} + log_test_addr ${a} $? 0 "ping in, LLA to GUA" + done + + setup_cmd_nsb ip -6 ro del ${NSA_IP6}/128 via ${NSA_LINKIP6} dev ${NSB_DEV} + setup_cmd_nsb ip -6 addr add ${NSB_IP6}/64 dev ${NSB_DEV} + setup_cmd_nsb ip -6 addr add ${NSB_LO_IP6}/128 dev lo + + # + # ip rule blocks address + # + log_start + setup_cmd ip -6 rule add pref 50 to ${NSB_LO_IP6} prohibit + setup_cmd ip -6 rule add pref 51 from ${NSB_IP6} prohibit + + a=${NSB_LO_IP6} + run_cmd ${ping6} -c1 -w1 ${a} + log_test_addr ${a} $? 2 "ping out, blocked by rule" + + log_start + run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 2 "ping out, device bind, blocked by rule" + + a=${NSA_LO_IP6} + log_start + show_hint "Response lost due to ip rule" + run_cmd_nsb ${ping6} -c1 -w1 ${a} + log_test_addr ${a} $? 1 "ping in, blocked by rule" + + log_start + setup_cmd ip -6 rule del pref 50 to ${NSB_LO_IP6} prohibit + setup_cmd ip -6 rule del pref 51 from ${NSB_IP6} prohibit + + # + # remove 'remote' routes; fallback to default + # + log_start + setup_cmd ip -6 ro del ${NSB_LO_IP6} vrf ${VRF} + + a=${NSB_LO_IP6} + run_cmd ${ping6} -c1 -w1 ${a} + log_test_addr ${a} $? 2 "ping out, unreachable route" + + log_start + run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a} + log_test_addr ${a} $? 2 "ping out, device bind, unreachable route" + + ip -netns ${NSB} -6 ro del ${NSA_LO_IP6} + a=${NSA_LO_IP6} + log_start + run_cmd_nsb ${ping6} -c1 -w1 ${a} + log_test_addr ${a} $? 2 "ping in, unreachable route" +} + +ipv6_ping() +{ + log_section "IPv6 ping" + + log_subsection "No VRF" + setup + ipv6_ping_novrf + + log_subsection "With VRF" + setup "yes" + ipv6_ping_vrf +} + ################################################################################ # usage @@ -732,7 +1013,7 @@ EOF # main TESTS_IPV4="ipv4_ping" -TESTS_IPV6="" +TESTS_IPV6="ipv6_ping" PAUSE_ON_FAIL=no PAUSE=no @@ -771,6 +1052,7 @@ for t in $TESTS do case $t in ipv4_ping|ping) ipv4_ping;; + ipv6_ping|ping6) ipv6_ping;; # setup namespaces and config, but do not run any tests setup) setup; exit 0;; -- cgit v1.2.3-59-g8ed1b From bbd7c764086b4e6bea8c37e94914f6e5fee34f7d Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 1 Aug 2019 11:56:38 -0700 Subject: selftests: Add ipv4 tcp tests to fcnal-test Add tcp tests to fcnal-test.sh. Covers the permutations of directly connected addresses, routed destinations, VRF and non-VRF, and expected failures for both clients and servers. Includes permutations with net.ipv4.tcp_l3mdev_accept set to 0 and 1. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/fcnal-test.sh | 315 +++++++++++++++++++++++++++++- 1 file changed, 314 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh index 4da510f6d625..f9e2f1464dcd 100755 --- a/tools/testing/selftests/net/fcnal-test.sh +++ b/tools/testing/selftests/net/fcnal-test.sh @@ -711,6 +711,317 @@ ipv4_ping() ipv4_ping_vrf } +################################################################################ +# IPv4 TCP + +ipv4_tcp_novrf() +{ + local a + + # + # server tests + # + for a in ${NSA_IP} ${NSA_LO_IP} + do + log_start + run_cmd nettest -s & + sleep 1 + run_cmd_nsb nettest -r ${a} + log_test_addr ${a} $? 0 "Global server" + done + + a=${NSA_IP} + log_start + run_cmd nettest -s -d ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -r ${a} + log_test_addr ${a} $? 0 "Device server" + + # verify TCP reset sent and received + for a in ${NSA_IP} ${NSA_LO_IP} + do + log_start + show_hint "Should fail 'Connection refused' since there is no server" + run_cmd_nsb nettest -r ${a} + log_test_addr ${a} $? 1 "No server" + done + + # + # client + # + for a in ${NSB_IP} ${NSB_LO_IP} + do + log_start + run_cmd_nsb nettest -s & + sleep 1 + run_cmd nettest -r ${a} -0 ${NSA_IP} + log_test_addr ${a} $? 0 "Client" + + log_start + run_cmd_nsb nettest -s & + sleep 1 + run_cmd nettest -r ${a} -d ${NSA_DEV} + log_test_addr ${a} $? 0 "Client, device bind" + + log_start + show_hint "Should fail 'Connection refused'" + run_cmd nettest -r ${a} + log_test_addr ${a} $? 1 "No server, unbound client" + + log_start + show_hint "Should fail 'Connection refused'" + run_cmd nettest -r ${a} -d ${NSA_DEV} + log_test_addr ${a} $? 1 "No server, device client" + done + + # + # local address tests + # + for a in ${NSA_IP} ${NSA_LO_IP} 127.0.0.1 + do + log_start + run_cmd nettest -s & + sleep 1 + run_cmd nettest -r ${a} -0 ${a} -1 ${a} + log_test_addr ${a} $? 0 "Global server, local connection" + done + + a=${NSA_IP} + log_start + run_cmd nettest -s -d ${NSA_DEV} & + sleep 1 + run_cmd nettest -r ${a} -0 ${a} + log_test_addr ${a} $? 0 "Device server, unbound client, local connection" + + for a in ${NSA_LO_IP} 127.0.0.1 + do + log_start + show_hint "Should fail 'Connection refused' since addresses on loopback are out of device scope" + run_cmd nettest -s -d ${NSA_DEV} & + sleep 1 + run_cmd nettest -r ${a} + log_test_addr ${a} $? 1 "Device server, unbound client, local connection" + done + + a=${NSA_IP} + log_start + run_cmd nettest -s & + sleep 1 + run_cmd nettest -r ${a} -0 ${a} -d ${NSA_DEV} + log_test_addr ${a} $? 0 "Global server, device client, local connection" + + for a in ${NSA_LO_IP} 127.0.0.1 + do + log_start + show_hint "Should fail 'No route to host' since addresses on loopback are out of device scope" + run_cmd nettest -s & + sleep 1 + run_cmd nettest -r ${a} -d ${NSA_DEV} + log_test_addr ${a} $? 1 "Global server, device client, local connection" + done + + a=${NSA_IP} + log_start + run_cmd nettest -s -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -d ${NSA_DEV} -r ${a} -0 ${a} + log_test_addr ${a} $? 0 "Device server, device client, local connection" + + log_start + show_hint "Should fail 'Connection refused'" + run_cmd nettest -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 1 "No server, device client, local conn" +} + +ipv4_tcp_vrf() +{ + local a + + # disable global server + log_subsection "Global server disabled" + + set_sysctl net.ipv4.tcp_l3mdev_accept=0 + + # + # server tests + # + for a in ${NSA_IP} ${VRF_IP} + do + log_start + show_hint "Should fail 'Connection refused' since global server with VRF is disabled" + run_cmd nettest -s & + sleep 1 + run_cmd_nsb nettest -r ${a} + log_test_addr ${a} $? 1 "Global server" + + log_start + run_cmd nettest -s -d ${VRF} -2 ${VRF} & + sleep 1 + run_cmd_nsb nettest -r ${a} + log_test_addr ${a} $? 0 "VRF server" + + log_start + run_cmd nettest -s -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -r ${a} + log_test_addr ${a} $? 0 "Device server" + + # verify TCP reset received + log_start + show_hint "Should fail 'Connection refused' since there is no server" + run_cmd_nsb nettest -r ${a} + log_test_addr ${a} $? 1 "No server" + done + + # local address tests + # (${VRF_IP} and 127.0.0.1 both timeout) + a=${NSA_IP} + log_start + show_hint "Should fail 'Connection refused' since global server with VRF is disabled" + run_cmd nettest -s & + sleep 1 + run_cmd nettest -r ${a} -d ${NSA_DEV} + log_test_addr ${a} $? 1 "Global server, local connection" + + # + # enable VRF global server + # + log_subsection "VRF Global server enabled" + set_sysctl net.ipv4.tcp_l3mdev_accept=1 + + for a in ${NSA_IP} ${VRF_IP} + do + log_start + show_hint "client socket should be bound to VRF" + run_cmd nettest -s -2 ${VRF} & + sleep 1 + run_cmd_nsb nettest -r ${a} + log_test_addr ${a} $? 0 "Global server" + + log_start + show_hint "client socket should be bound to VRF" + run_cmd nettest -s -d ${VRF} -2 ${VRF} & + sleep 1 + run_cmd_nsb nettest -r ${a} + log_test_addr ${a} $? 0 "VRF server" + + # verify TCP reset received + log_start + show_hint "Should fail 'Connection refused'" + run_cmd_nsb nettest -r ${a} + log_test_addr ${a} $? 1 "No server" + done + + a=${NSA_IP} + log_start + show_hint "client socket should be bound to device" + run_cmd nettest -s -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -r ${a} + log_test_addr ${a} $? 0 "Device server" + + # local address tests + for a in ${NSA_IP} ${VRF_IP} + do + log_start + show_hint "Should fail 'No route to host' since client is not bound to VRF" + run_cmd nettest -s -2 ${VRF} & + sleep 1 + run_cmd nettest -r ${a} + log_test_addr ${a} $? 1 "Global server, local connection" + done + + # + # client + # + for a in ${NSB_IP} ${NSB_LO_IP} + do + log_start + run_cmd_nsb nettest -s & + sleep 1 + run_cmd nettest -r ${a} -d ${VRF} + log_test_addr ${a} $? 0 "Client, VRF bind" + + log_start + run_cmd_nsb nettest -s & + sleep 1 + run_cmd nettest -r ${a} -d ${NSA_DEV} + log_test_addr ${a} $? 0 "Client, device bind" + + log_start + show_hint "Should fail 'Connection refused'" + run_cmd nettest -r ${a} -d ${VRF} + log_test_addr ${a} $? 1 "No server, VRF client" + + log_start + show_hint "Should fail 'Connection refused'" + run_cmd nettest -r ${a} -d ${NSA_DEV} + log_test_addr ${a} $? 1 "No server, device client" + done + + for a in ${NSA_IP} ${VRF_IP} 127.0.0.1 + do + log_start + run_cmd nettest -s -d ${VRF} -2 ${VRF} & + sleep 1 + run_cmd nettest -r ${a} -d ${VRF} -0 ${a} + log_test_addr ${a} $? 0 "VRF server, VRF client, local connection" + done + + a=${NSA_IP} + log_start + run_cmd nettest -s -d ${VRF} -2 ${VRF} & + sleep 1 + run_cmd nettest -r ${a} -d ${NSA_DEV} -0 ${a} + log_test_addr ${a} $? 0 "VRF server, device client, local connection" + + log_start + show_hint "Should fail 'No route to host' since client is out of VRF scope" + run_cmd nettest -s -d ${VRF} & + sleep 1 + run_cmd nettest -r ${a} + log_test_addr ${a} $? 1 "VRF server, unbound client, local connection" + + log_start + run_cmd nettest -s -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -r ${a} -d ${VRF} -0 ${a} + log_test_addr ${a} $? 0 "Device server, VRF client, local connection" + + log_start + run_cmd nettest -s -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -r ${a} -d ${NSA_DEV} -0 ${a} + log_test_addr ${a} $? 0 "Device server, device client, local connection" +} + +ipv4_tcp() +{ + log_section "IPv4/TCP" + + which nettest >/dev/null + if [ $? -ne 0 ]; then + log_error "nettest not found; skipping tests" + return + fi + + log_subsection "No VRF" + setup + + # tcp_l3mdev_accept should have no affect without VRF; + # run tests with it enabled and disabled to verify + log_subsection "tcp_l3mdev_accept disabled" + set_sysctl net.ipv4.tcp_l3mdev_accept=0 + ipv4_tcp_novrf + log_subsection "tcp_l3mdev_accept enabled" + set_sysctl net.ipv4.tcp_l3mdev_accept=1 + ipv4_tcp_novrf + + log_subsection "With VRF" + setup "yes" + ipv4_tcp_vrf +} + ################################################################################ # IPv6 @@ -1012,7 +1323,7 @@ EOF ################################################################################ # main -TESTS_IPV4="ipv4_ping" +TESTS_IPV4="ipv4_ping ipv4_tcp" TESTS_IPV6="ipv6_ping" PAUSE_ON_FAIL=no PAUSE=no @@ -1052,6 +1363,8 @@ for t in $TESTS do case $t in ipv4_ping|ping) ipv4_ping;; + ipv4_tcp|tcp) ipv4_tcp;; + ipv6_ping|ping6) ipv6_ping;; # setup namespaces and config, but do not run any tests -- cgit v1.2.3-59-g8ed1b From a071bbf20539fa9166820c34c71cf2167dc23833 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 1 Aug 2019 11:56:39 -0700 Subject: selftests: Add ipv6 tcp tests to fcnal-test Add IPv6 tcp tests to fcnal-test.sh. Covers the permutations of directly connected addresses, routed destinations, VRF and non-VRF, and expected failures for both clients and servers. Includes permutations with net.ipv4.tcp_l3mdev_accept set to 0 and 1. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/fcnal-test.sh | 370 +++++++++++++++++++++++++++++- 1 file changed, 369 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh index f9e2f1464dcd..97291c6d17c5 100755 --- a/tools/testing/selftests/net/fcnal-test.sh +++ b/tools/testing/selftests/net/fcnal-test.sh @@ -1303,6 +1303,373 @@ ipv6_ping() ipv6_ping_vrf } +################################################################################ +# IPv6 TCP + +ipv6_tcp_novrf() +{ + local a + + # + # server tests + # + for a in ${NSA_IP6} ${NSA_LO_IP6} ${NSA_LINKIP6}%${NSB_DEV} + do + log_start + run_cmd nettest -6 -s & + sleep 1 + run_cmd_nsb nettest -6 -r ${a} + log_test_addr ${a} $? 0 "Global server" + done + + # verify TCP reset received + for a in ${NSA_IP6} ${NSA_LO_IP6} ${NSA_LINKIP6}%${NSB_DEV} + do + log_start + show_hint "Should fail 'Connection refused'" + run_cmd_nsb nettest -6 -r ${a} + log_test_addr ${a} $? 1 "No server" + done + + # + # client + # + for a in ${NSB_IP6} ${NSB_LO_IP6} ${NSB_LINKIP6}%${NSA_DEV} + do + log_start + run_cmd_nsb nettest -6 -s & + sleep 1 + run_cmd nettest -6 -r ${a} + log_test_addr ${a} $? 0 "Client" + done + + for a in ${NSB_IP6} ${NSB_LO_IP6} ${NSB_LINKIP6}%${NSA_DEV} + do + log_start + run_cmd_nsb nettest -6 -s & + sleep 1 + run_cmd nettest -6 -r ${a} -d ${NSA_DEV} + log_test_addr ${a} $? 0 "Client, device bind" + done + + for a in ${NSB_IP6} ${NSB_LO_IP6} ${NSB_LINKIP6}%${NSA_DEV} + do + log_start + show_hint "Should fail 'Connection refused'" + run_cmd nettest -6 -r ${a} -d ${NSA_DEV} + log_test_addr ${a} $? 1 "No server, device client" + done + + # + # local address tests + # + for a in ${NSA_IP6} ${NSA_LO_IP6} ::1 + do + log_start + run_cmd nettest -6 -s & + sleep 1 + run_cmd nettest -6 -r ${a} + log_test_addr ${a} $? 0 "Global server, local connection" + done + + a=${NSA_IP6} + log_start + run_cmd nettest -6 -s -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -6 -r ${a} -0 ${a} + log_test_addr ${a} $? 0 "Device server, unbound client, local connection" + + for a in ${NSA_LO_IP6} ::1 + do + log_start + show_hint "Should fail 'Connection refused' since addresses on loopback are out of device scope" + run_cmd nettest -6 -s -d ${NSA_DEV} & + sleep 1 + run_cmd nettest -6 -r ${a} + log_test_addr ${a} $? 1 "Device server, unbound client, local connection" + done + + a=${NSA_IP6} + log_start + run_cmd nettest -6 -s & + sleep 1 + run_cmd nettest -6 -r ${a} -d ${NSA_DEV} -0 ${a} + log_test_addr ${a} $? 0 "Global server, device client, local connection" + + for a in ${NSA_LO_IP6} ::1 + do + log_start + show_hint "Should fail 'Connection refused' since addresses on loopback are out of device scope" + run_cmd nettest -6 -s & + sleep 1 + run_cmd nettest -6 -r ${a} -d ${NSA_DEV} + log_test_addr ${a} $? 1 "Global server, device client, local connection" + done + + for a in ${NSA_IP6} ${NSA_LINKIP6} + do + log_start + run_cmd nettest -6 -s -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -6 -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 0 "Device server, device client, local conn" + done + + for a in ${NSA_IP6} ${NSA_LINKIP6} + do + log_start + show_hint "Should fail 'Connection refused'" + run_cmd nettest -6 -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 1 "No server, device client, local conn" + done +} + +ipv6_tcp_vrf() +{ + local a + + # disable global server + log_subsection "Global server disabled" + + set_sysctl net.ipv4.tcp_l3mdev_accept=0 + + # + # server tests + # + for a in ${NSA_IP6} ${VRF_IP6} ${NSA_LINKIP6}%${NSB_DEV} + do + log_start + show_hint "Should fail 'Connection refused' since global server with VRF is disabled" + run_cmd nettest -6 -s & + sleep 1 + run_cmd_nsb nettest -6 -r ${a} + log_test_addr ${a} $? 1 "Global server" + done + + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest -6 -s -d ${VRF} -2 ${VRF} & + sleep 1 + run_cmd_nsb nettest -6 -r ${a} + log_test_addr ${a} $? 0 "VRF server" + done + + # link local is always bound to ingress device + a=${NSA_LINKIP6}%${NSB_DEV} + log_start + run_cmd nettest -6 -s -d ${VRF} -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -6 -r ${a} + log_test_addr ${a} $? 0 "VRF server" + + for a in ${NSA_IP6} ${VRF_IP6} ${NSA_LINKIP6}%${NSB_DEV} + do + log_start + run_cmd nettest -6 -s -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -6 -r ${a} + log_test_addr ${a} $? 0 "Device server" + done + + # verify TCP reset received + for a in ${NSA_IP6} ${VRF_IP6} ${NSA_LINKIP6}%${NSB_DEV} + do + log_start + show_hint "Should fail 'Connection refused'" + run_cmd_nsb nettest -6 -r ${a} + log_test_addr ${a} $? 1 "No server" + done + + # local address tests + a=${NSA_IP6} + log_start + show_hint "Should fail 'Connection refused' since global server with VRF is disabled" + run_cmd nettest -6 -s & + sleep 1 + run_cmd nettest -6 -r ${a} -d ${NSA_DEV} + log_test_addr ${a} $? 1 "Global server, local connection" + + # + # enable VRF global server + # + log_subsection "VRF Global server enabled" + set_sysctl net.ipv4.tcp_l3mdev_accept=1 + + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest -6 -s -2 ${VRF} & + sleep 1 + run_cmd_nsb nettest -6 -r ${a} + log_test_addr ${a} $? 0 "Global server" + done + + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest -6 -s -d ${VRF} -2 ${VRF} & + sleep 1 + run_cmd_nsb nettest -6 -r ${a} + log_test_addr ${a} $? 0 "VRF server" + done + + # For LLA, child socket is bound to device + a=${NSA_LINKIP6}%${NSB_DEV} + log_start + run_cmd nettest -6 -s -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -6 -r ${a} + log_test_addr ${a} $? 0 "Global server" + + log_start + run_cmd nettest -6 -s -d ${VRF} -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -6 -r ${a} + log_test_addr ${a} $? 0 "VRF server" + + for a in ${NSA_IP6} ${NSA_LINKIP6}%${NSB_DEV} + do + log_start + run_cmd nettest -6 -s -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -6 -r ${a} + log_test_addr ${a} $? 0 "Device server" + done + + # verify TCP reset received + for a in ${NSA_IP6} ${VRF_IP6} ${NSA_LINKIP6}%${NSB_DEV} + do + log_start + show_hint "Should fail 'Connection refused'" + run_cmd_nsb nettest -6 -r ${a} + log_test_addr ${a} $? 1 "No server" + done + + # local address tests + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + show_hint "Fails 'No route to host' since client is not in VRF" + run_cmd nettest -6 -s -2 ${VRF} & + sleep 1 + run_cmd nettest -6 -r ${a} + log_test_addr ${a} $? 1 "Global server, local connection" + done + + + # + # client + # + for a in ${NSB_IP6} ${NSB_LO_IP6} + do + log_start + run_cmd_nsb nettest -6 -s & + sleep 1 + run_cmd nettest -6 -r ${a} -d ${VRF} + log_test_addr ${a} $? 0 "Client, VRF bind" + done + + a=${NSB_LINKIP6} + log_start + show_hint "Fails since VRF device does not allow linklocal addresses" + run_cmd_nsb nettest -6 -s & + sleep 1 + run_cmd nettest -6 -r ${a} -d ${VRF} + log_test_addr ${a} $? 1 "Client, VRF bind" + + for a in ${NSB_IP6} ${NSB_LO_IP6} ${NSB_LINKIP6} + do + log_start + run_cmd_nsb nettest -6 -s & + sleep 1 + run_cmd nettest -6 -r ${a} -d ${NSA_DEV} + log_test_addr ${a} $? 0 "Client, device bind" + done + + for a in ${NSB_IP6} ${NSB_LO_IP6} + do + log_start + show_hint "Should fail 'Connection refused'" + run_cmd nettest -6 -r ${a} -d ${VRF} + log_test_addr ${a} $? 1 "No server, VRF client" + done + + for a in ${NSB_IP6} ${NSB_LO_IP6} ${NSB_LINKIP6} + do + log_start + show_hint "Should fail 'Connection refused'" + run_cmd nettest -6 -r ${a} -d ${NSA_DEV} + log_test_addr ${a} $? 1 "No server, device client" + done + + for a in ${NSA_IP6} ${VRF_IP6} ::1 + do + log_start + run_cmd nettest -6 -s -d ${VRF} -2 ${VRF} & + sleep 1 + run_cmd nettest -6 -r ${a} -d ${VRF} -0 ${a} + log_test_addr ${a} $? 0 "VRF server, VRF client, local connection" + done + + a=${NSA_IP6} + log_start + run_cmd nettest -6 -s -d ${VRF} -2 ${VRF} & + sleep 1 + run_cmd nettest -6 -r ${a} -d ${NSA_DEV} -0 ${a} + log_test_addr ${a} $? 0 "VRF server, device client, local connection" + + a=${NSA_IP6} + log_start + show_hint "Should fail since unbound client is out of VRF scope" + run_cmd nettest -6 -s -d ${VRF} & + sleep 1 + run_cmd nettest -6 -r ${a} + log_test_addr ${a} $? 1 "VRF server, unbound client, local connection" + + log_start + run_cmd nettest -6 -s -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -6 -r ${a} -d ${VRF} -0 ${a} + log_test_addr ${a} $? 0 "Device server, VRF client, local connection" + + for a in ${NSA_IP6} ${NSA_LINKIP6} + do + log_start + run_cmd nettest -6 -s -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -6 -r ${a} -d ${NSA_DEV} -0 ${a} + log_test_addr ${a} $? 0 "Device server, device client, local connection" + done +} + +ipv6_tcp() +{ + log_section "IPv6/TCP" + + which nettest >/dev/null + if [ $? -ne 0 ]; then + log_error "nettest not found; skipping tests" + return + fi + + log_subsection "No VRF" + setup + + # tcp_l3mdev_accept should have no affect without VRF; + # run tests with it enabled and disabled to verify + log_subsection "tcp_l3mdev_accept disabled" + set_sysctl net.ipv4.tcp_l3mdev_accept=0 + ipv6_tcp_novrf + log_subsection "tcp_l3mdev_accept enabled" + set_sysctl net.ipv4.tcp_l3mdev_accept=1 + ipv6_tcp_novrf + + log_subsection "With VRF" + setup "yes" + ipv6_tcp_vrf +} + ################################################################################ # usage @@ -1324,7 +1691,7 @@ EOF # main TESTS_IPV4="ipv4_ping ipv4_tcp" -TESTS_IPV6="ipv6_ping" +TESTS_IPV6="ipv6_ping ipv6_tcp" PAUSE_ON_FAIL=no PAUSE=no @@ -1366,6 +1733,7 @@ do ipv4_tcp|tcp) ipv4_tcp;; ipv6_ping|ping6) ipv6_ping;; + ipv6_tcp|tcp6) ipv6_tcp;; # setup namespaces and config, but do not run any tests setup) setup; exit 0;; -- cgit v1.2.3-59-g8ed1b From a4368be9ad23d2a8e13c2b98409f9df166a4c9c5 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 1 Aug 2019 11:56:40 -0700 Subject: selftests: Add ipv4 udp tests to fcnal-test Add udp tests to fcnal-test.sh. Covers the permutations of directly connected addresses, routed destinations, VRF and non-VRF, and expected failures for both clients and servers. Includes permutations with net.ipv4.udp_l3mdev_accept set to 0 and 1. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/fcnal-test.sh | 381 +++++++++++++++++++++++++++++- 1 file changed, 380 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh index 97291c6d17c5..afe9eb55d04a 100755 --- a/tools/testing/selftests/net/fcnal-test.sh +++ b/tools/testing/selftests/net/fcnal-test.sh @@ -1022,6 +1022,384 @@ ipv4_tcp() ipv4_tcp_vrf } +################################################################################ +# IPv4 UDP + +ipv4_udp_novrf() +{ + local a + + # + # server tests + # + for a in ${NSA_IP} ${NSA_LO_IP} + do + log_start + run_cmd nettest -D -s -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -D -r ${a} + log_test_addr ${a} $? 0 "Global server" + + log_start + show_hint "Should fail 'Connection refused' since there is no server" + run_cmd_nsb nettest -D -r ${a} + log_test_addr ${a} $? 1 "No server" + done + + a=${NSA_IP} + log_start + run_cmd nettest -D -d ${NSA_DEV} -s -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -D -r ${a} + log_test_addr ${a} $? 0 "Device server" + + # + # client + # + for a in ${NSB_IP} ${NSB_LO_IP} + do + log_start + run_cmd_nsb nettest -D -s & + sleep 1 + run_cmd nettest -D -r ${a} -0 ${NSA_IP} + log_test_addr ${a} $? 0 "Client" + + log_start + run_cmd_nsb nettest -D -s & + sleep 1 + run_cmd nettest -D -r ${a} -d ${NSA_DEV} -0 ${NSA_IP} + log_test_addr ${a} $? 0 "Client, device bind" + + log_start + run_cmd_nsb nettest -D -s & + sleep 1 + run_cmd nettest -D -r ${a} -d ${NSA_DEV} -C -0 ${NSA_IP} + log_test_addr ${a} $? 0 "Client, device send via cmsg" + + log_start + run_cmd_nsb nettest -D -s & + sleep 1 + run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S -0 ${NSA_IP} + log_test_addr ${a} $? 0 "Client, device bind via IP_UNICAST_IF" + + log_start + show_hint "Should fail 'Connection refused'" + run_cmd nettest -D -r ${a} + log_test_addr ${a} $? 1 "No server, unbound client" + + log_start + show_hint "Should fail 'Connection refused'" + run_cmd nettest -D -r ${a} -d ${NSA_DEV} + log_test_addr ${a} $? 1 "No server, device client" + done + + # + # local address tests + # + for a in ${NSA_IP} ${NSA_LO_IP} 127.0.0.1 + do + log_start + run_cmd nettest -D -s & + sleep 1 + run_cmd nettest -D -r ${a} -0 ${a} -1 ${a} + log_test_addr ${a} $? 0 "Global server, local connection" + done + + a=${NSA_IP} + log_start + run_cmd nettest -s -D -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -D -r ${a} + log_test_addr ${a} $? 0 "Device server, unbound client, local connection" + + for a in ${NSA_LO_IP} 127.0.0.1 + do + log_start + show_hint "Should fail 'Connection refused' since address is out of device scope" + run_cmd nettest -s -D -d ${NSA_DEV} & + sleep 1 + run_cmd nettest -D -r ${a} + log_test_addr ${a} $? 1 "Device server, unbound client, local connection" + done + + a=${NSA_IP} + log_start + run_cmd nettest -s -D & + sleep 1 + run_cmd nettest -D -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 0 "Global server, device client, local connection" + + log_start + run_cmd nettest -s -D & + sleep 1 + run_cmd nettest -D -d ${NSA_DEV} -C -r ${a} + log_test_addr ${a} $? 0 "Global server, device send via cmsg, local connection" + + log_start + run_cmd nettest -s -D & + sleep 1 + run_cmd nettest -D -d ${NSA_DEV} -S -r ${a} + log_test_addr ${a} $? 0 "Global server, device client via IP_UNICAST_IF, local connection" + + # IPv4 with device bind has really weird behavior - it overrides the + # fib lookup, generates an rtable and tries to send the packet. This + # causes failures for local traffic at different places + for a in ${NSA_LO_IP} 127.0.0.1 + do + log_start + show_hint "Should fail since addresses on loopback are out of device scope" + run_cmd nettest -D -s & + sleep 1 + run_cmd nettest -D -r ${a} -d ${NSA_DEV} + log_test_addr ${a} $? 2 "Global server, device client, local connection" + + log_start + show_hint "Should fail since addresses on loopback are out of device scope" + run_cmd nettest -D -s & + sleep 1 + run_cmd nettest -D -r ${a} -d ${NSA_DEV} -C + log_test_addr ${a} $? 1 "Global server, device send via cmsg, local connection" + + log_start + show_hint "Should fail since addresses on loopback are out of device scope" + run_cmd nettest -D -s & + sleep 1 + run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S + log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection" + done + + a=${NSA_IP} + log_start + run_cmd nettest -D -s -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -D -d ${NSA_DEV} -r ${a} -0 ${a} + log_test_addr ${a} $? 0 "Device server, device client, local conn" + + log_start + run_cmd nettest -D -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 2 "No server, device client, local conn" +} + +ipv4_udp_vrf() +{ + local a + + # disable global server + log_subsection "Global server disabled" + set_sysctl net.ipv4.udp_l3mdev_accept=0 + + # + # server tests + # + for a in ${NSA_IP} ${VRF_IP} + do + log_start + show_hint "Fails because ingress is in a VRF and global server is disabled" + run_cmd nettest -D -s & + sleep 1 + run_cmd_nsb nettest -D -r ${a} + log_test_addr ${a} $? 1 "Global server" + + log_start + run_cmd nettest -D -d ${VRF} -s -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -D -r ${a} + log_test_addr ${a} $? 0 "VRF server" + + log_start + run_cmd nettest -D -d ${NSA_DEV} -s -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -D -r ${a} + log_test_addr ${a} $? 0 "Enslaved device server" + + log_start + show_hint "Should fail 'Connection refused' since there is no server" + run_cmd_nsb nettest -D -r ${a} + log_test_addr ${a} $? 1 "No server" + + log_start + show_hint "Should fail 'Connection refused' since global server is out of scope" + run_cmd nettest -D -s & + sleep 1 + run_cmd nettest -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 1 "Global server, VRF client, local connection" + done + + a=${NSA_IP} + log_start + run_cmd nettest -s -D -d ${VRF} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 0 "VRF server, VRF client, local conn" + + log_start + run_cmd nettest -s -D -d ${VRF} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -D -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 0 "VRF server, enslaved device client, local connection" + + a=${NSA_IP} + log_start + run_cmd nettest -s -D -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 0 "Enslaved device server, VRF client, local conn" + + log_start + run_cmd nettest -s -D -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -D -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 0 "Enslaved device server, device client, local conn" + + # enable global server + log_subsection "Global server enabled" + set_sysctl net.ipv4.udp_l3mdev_accept=1 + + # + # server tests + # + for a in ${NSA_IP} ${VRF_IP} + do + log_start + run_cmd nettest -D -s -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -D -r ${a} + log_test_addr ${a} $? 0 "Global server" + + log_start + run_cmd nettest -D -d ${VRF} -s -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -D -r ${a} + log_test_addr ${a} $? 0 "VRF server" + + log_start + run_cmd nettest -D -d ${NSA_DEV} -s -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -D -r ${a} + log_test_addr ${a} $? 0 "Enslaved device server" + + log_start + show_hint "Should fail 'Connection refused'" + run_cmd_nsb nettest -D -r ${a} + log_test_addr ${a} $? 1 "No server" + done + + # + # client tests + # + log_start + run_cmd_nsb nettest -D -s & + sleep 1 + run_cmd nettest -d ${VRF} -D -r ${NSB_IP} -1 ${NSA_IP} + log_test $? 0 "VRF client" + + log_start + run_cmd_nsb nettest -D -s & + sleep 1 + run_cmd nettest -d ${NSA_DEV} -D -r ${NSB_IP} -1 ${NSA_IP} + log_test $? 0 "Enslaved device client" + + # negative test - should fail + log_start + show_hint "Should fail 'Connection refused'" + run_cmd nettest -D -d ${VRF} -r ${NSB_IP} + log_test $? 1 "No server, VRF client" + + log_start + show_hint "Should fail 'Connection refused'" + run_cmd nettest -D -d ${NSA_DEV} -r ${NSB_IP} + log_test $? 1 "No server, enslaved device client" + + # + # local address tests + # + a=${NSA_IP} + log_start + run_cmd nettest -D -s -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 0 "Global server, VRF client, local conn" + + log_start + run_cmd nettest -s -D -d ${VRF} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 0 "VRF server, VRF client, local conn" + + log_start + run_cmd nettest -s -D -d ${VRF} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -D -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 0 "VRF server, device client, local conn" + + log_start + run_cmd nettest -s -D -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 0 "Enslaved device server, VRF client, local conn" + + log_start + run_cmd nettest -s -D -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -D -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 0 "Enslaved device server, device client, local conn" + + for a in ${VRF_IP} 127.0.0.1 + do + log_start + run_cmd nettest -D -s -2 ${VRF} & + sleep 1 + run_cmd nettest -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 0 "Global server, VRF client, local conn" + done + + for a in ${VRF_IP} 127.0.0.1 + do + log_start + run_cmd nettest -s -D -d ${VRF} -2 ${VRF} & + sleep 1 + run_cmd nettest -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 0 "VRF server, VRF client, local conn" + done + + # negative test - should fail + # verifies ECONNREFUSED + for a in ${NSA_IP} ${VRF_IP} 127.0.0.1 + do + log_start + show_hint "Should fail 'Connection refused'" + run_cmd nettest -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 1 "No server, VRF client, local conn" + done +} + +ipv4_udp() +{ + which nettest >/dev/null + if [ $? -ne 0 ]; then + log_error "nettest not found; skipping tests" + return + fi + + log_section "IPv4/UDP" + log_subsection "No VRF" + + setup + + # udp_l3mdev_accept should have no affect without VRF; + # run tests with it enabled and disabled to verify + log_subsection "udp_l3mdev_accept disabled" + set_sysctl net.ipv4.udp_l3mdev_accept=0 + ipv4_udp_novrf + log_subsection "udp_l3mdev_accept enabled" + set_sysctl net.ipv4.udp_l3mdev_accept=1 + ipv4_udp_novrf + + log_subsection "With VRF" + setup "yes" + ipv4_udp_vrf +} + ################################################################################ # IPv6 @@ -1690,7 +2068,7 @@ EOF ################################################################################ # main -TESTS_IPV4="ipv4_ping ipv4_tcp" +TESTS_IPV4="ipv4_ping ipv4_tcp ipv4_udp" TESTS_IPV6="ipv6_ping ipv6_tcp" PAUSE_ON_FAIL=no PAUSE=no @@ -1731,6 +2109,7 @@ do case $t in ipv4_ping|ping) ipv4_ping;; ipv4_tcp|tcp) ipv4_tcp;; + ipv4_udp|udp) ipv4_udp;; ipv6_ping|ping6) ipv6_ping;; ipv6_tcp|tcp6) ipv6_tcp;; -- cgit v1.2.3-59-g8ed1b From 6abdb651255784f1907d8c8fcbf7e4ba4196b1da Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 1 Aug 2019 11:56:41 -0700 Subject: selftests: Add ipv6 udp tests to fcnal-test Add IPv6 udp tests to fcnal-test.sh. Covers the permutations of directly connected addresses, routed destinations, VRF and non-VRF, and expected failures for both clients and servers. Includes permutations with net.ipv4.udp_l3mdev_accept set to 0 and 1. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/fcnal-test.sh | 492 +++++++++++++++++++++++++++++- 1 file changed, 491 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh index afe9eb55d04a..2a2e692bc242 100755 --- a/tools/testing/selftests/net/fcnal-test.sh +++ b/tools/testing/selftests/net/fcnal-test.sh @@ -2048,6 +2048,495 @@ ipv6_tcp() ipv6_tcp_vrf } +################################################################################ +# IPv6 UDP + +ipv6_udp_novrf() +{ + local a + + # + # server tests + # + for a in ${NSA_IP6} ${NSA_LINKIP6}%${NSB_DEV} + do + log_start + run_cmd nettest -6 -D -s -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -6 -D -r ${a} + log_test_addr ${a} $? 0 "Global server" + + log_start + run_cmd nettest -6 -D -d ${NSA_DEV} -s -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -6 -D -r ${a} + log_test_addr ${a} $? 0 "Device server" + done + + a=${NSA_LO_IP6} + log_start + run_cmd nettest -6 -D -s -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -6 -D -r ${a} + log_test_addr ${a} $? 0 "Global server" + + # should fail since loopback address is out of scope for a device + # bound server, but it does not - hence this is more documenting + # behavior. + #log_start + #show_hint "Should fail since loopback address is out of scope" + #run_cmd nettest -6 -D -d ${NSA_DEV} -s -2 ${NSA_DEV} & + #sleep 1 + #run_cmd_nsb nettest -6 -D -r ${a} + #log_test_addr ${a} $? 1 "Device server" + + # negative test - should fail + for a in ${NSA_IP6} ${NSA_LO_IP6} ${NSA_LINKIP6}%${NSB_DEV} + do + log_start + show_hint "Should fail 'Connection refused' since there is no server" + run_cmd_nsb nettest -6 -D -r ${a} + log_test_addr ${a} $? 1 "No server" + done + + # + # client + # + for a in ${NSB_IP6} ${NSB_LO_IP6} ${NSB_LINKIP6}%${NSA_DEV} + do + log_start + run_cmd_nsb nettest -6 -D -s & + sleep 1 + run_cmd nettest -6 -D -r ${a} -0 ${NSA_IP6} + log_test_addr ${a} $? 0 "Client" + + log_start + run_cmd_nsb nettest -6 -D -s & + sleep 1 + run_cmd nettest -6 -D -r ${a} -d ${NSA_DEV} -0 ${NSA_IP6} + log_test_addr ${a} $? 0 "Client, device bind" + + log_start + run_cmd_nsb nettest -6 -D -s & + sleep 1 + run_cmd nettest -6 -D -r ${a} -d ${NSA_DEV} -C -0 ${NSA_IP6} + log_test_addr ${a} $? 0 "Client, device send via cmsg" + + log_start + run_cmd_nsb nettest -6 -D -s & + sleep 1 + run_cmd nettest -6 -D -r ${a} -d ${NSA_DEV} -S -0 ${NSA_IP6} + log_test_addr ${a} $? 0 "Client, device bind via IPV6_UNICAST_IF" + + log_start + show_hint "Should fail 'Connection refused'" + run_cmd nettest -6 -D -r ${a} + log_test_addr ${a} $? 1 "No server, unbound client" + + log_start + show_hint "Should fail 'Connection refused'" + run_cmd nettest -6 -D -r ${a} -d ${NSA_DEV} + log_test_addr ${a} $? 1 "No server, device client" + done + + # + # local address tests + # + for a in ${NSA_IP6} ${NSA_LO_IP6} ::1 + do + log_start + run_cmd nettest -6 -D -s & + sleep 1 + run_cmd nettest -6 -D -r ${a} -0 ${a} -1 ${a} + log_test_addr ${a} $? 0 "Global server, local connection" + done + + a=${NSA_IP6} + log_start + run_cmd nettest -6 -s -D -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -6 -D -r ${a} + log_test_addr ${a} $? 0 "Device server, unbound client, local connection" + + for a in ${NSA_LO_IP6} ::1 + do + log_start + show_hint "Should fail 'Connection refused' since address is out of device scope" + run_cmd nettest -6 -s -D -d ${NSA_DEV} & + sleep 1 + run_cmd nettest -6 -D -r ${a} + log_test_addr ${a} $? 1 "Device server, local connection" + done + + a=${NSA_IP6} + log_start + run_cmd nettest -6 -s -D & + sleep 1 + run_cmd nettest -6 -D -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 0 "Global server, device client, local connection" + + log_start + run_cmd nettest -6 -s -D & + sleep 1 + run_cmd nettest -6 -D -d ${NSA_DEV} -C -r ${a} + log_test_addr ${a} $? 0 "Global server, device send via cmsg, local connection" + + log_start + run_cmd nettest -6 -s -D & + sleep 1 + run_cmd nettest -6 -D -d ${NSA_DEV} -S -r ${a} + log_test_addr ${a} $? 0 "Global server, device client via IPV6_UNICAST_IF, local connection" + + for a in ${NSA_LO_IP6} ::1 + do + log_start + show_hint "Should fail 'No route to host' since addresses on loopback are out of device scope" + run_cmd nettest -6 -D -s & + sleep 1 + run_cmd nettest -6 -D -r ${a} -d ${NSA_DEV} + log_test_addr ${a} $? 1 "Global server, device client, local connection" + + log_start + show_hint "Should fail 'No route to host' since addresses on loopback are out of device scope" + run_cmd nettest -6 -D -s & + sleep 1 + run_cmd nettest -6 -D -r ${a} -d ${NSA_DEV} -C + log_test_addr ${a} $? 1 "Global server, device send via cmsg, local connection" + + log_start + show_hint "Should fail 'No route to host' since addresses on loopback are out of device scope" + run_cmd nettest -6 -D -s & + sleep 1 + run_cmd nettest -6 -D -r ${a} -d ${NSA_DEV} -S + log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection" + done + + a=${NSA_IP6} + log_start + run_cmd nettest -6 -D -s -d ${NSA_DEV} -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -6 -D -d ${NSA_DEV} -r ${a} -0 ${a} + log_test_addr ${a} $? 0 "Device server, device client, local conn" + + log_start + show_hint "Should fail 'Connection refused'" + run_cmd nettest -6 -D -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 1 "No server, device client, local conn" + + # LLA to GUA + run_cmd_nsb ip -6 addr del ${NSB_IP6}/64 dev ${NSB_DEV} + run_cmd_nsb ip -6 ro add ${NSA_IP6}/128 dev ${NSB_DEV} + log_start + run_cmd nettest -6 -s -D & + sleep 1 + run_cmd_nsb nettest -6 -D -r ${NSA_IP6} + log_test $? 0 "UDP in - LLA to GUA" + + run_cmd_nsb ip -6 ro del ${NSA_IP6}/128 dev ${NSB_DEV} + run_cmd_nsb ip -6 addr add ${NSB_IP6}/64 dev ${NSB_DEV} nodad +} + +ipv6_udp_vrf() +{ + local a + + # disable global server + log_subsection "Global server disabled" + set_sysctl net.ipv4.udp_l3mdev_accept=0 + + # + # server tests + # + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + show_hint "Should fail 'Connection refused' since global server is disabled" + run_cmd nettest -6 -D -s & + sleep 1 + run_cmd_nsb nettest -6 -D -r ${a} + log_test_addr ${a} $? 1 "Global server" + done + + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest -6 -D -d ${VRF} -s -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -6 -D -r ${a} + log_test_addr ${a} $? 0 "VRF server" + done + + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest -6 -D -d ${NSA_DEV} -s -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -6 -D -r ${a} + log_test_addr ${a} $? 0 "Enslaved device server" + done + + # negative test - should fail + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + show_hint "Should fail 'Connection refused' since there is no server" + run_cmd_nsb nettest -6 -D -r ${a} + log_test_addr ${a} $? 1 "No server" + done + + # + # local address tests + # + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + show_hint "Should fail 'Connection refused' since global server is disabled" + run_cmd nettest -6 -D -s & + sleep 1 + run_cmd nettest -6 -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 1 "Global server, VRF client, local conn" + done + + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest -6 -D -d ${VRF} -s & + sleep 1 + run_cmd nettest -6 -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 0 "VRF server, VRF client, local conn" + done + + a=${NSA_IP6} + log_start + show_hint "Should fail 'Connection refused' since global server is disabled" + run_cmd nettest -6 -D -s & + sleep 1 + run_cmd nettest -6 -D -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 1 "Global server, device client, local conn" + + log_start + run_cmd nettest -6 -D -d ${VRF} -s -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -6 -D -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 0 "VRF server, device client, local conn" + + log_start + run_cmd nettest -6 -D -d ${NSA_DEV} -s -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -6 -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 0 "Enslaved device server, VRF client, local conn" + + log_start + run_cmd nettest -6 -D -d ${NSA_DEV} -s -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -6 -D -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 0 "Enslaved device server, device client, local conn" + + # disable global server + log_subsection "Global server enabled" + set_sysctl net.ipv4.udp_l3mdev_accept=1 + + # + # server tests + # + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest -6 -D -s -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -6 -D -r ${a} + log_test_addr ${a} $? 0 "Global server" + done + + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest -6 -D -d ${VRF} -s -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -6 -D -r ${a} + log_test_addr ${a} $? 0 "VRF server" + done + + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest -6 -D -d ${NSA_DEV} -s -2 ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest -6 -D -r ${a} + log_test_addr ${a} $? 0 "Enslaved device server" + done + + # negative test - should fail + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd_nsb nettest -6 -D -r ${a} + log_test_addr ${a} $? 1 "No server" + done + + # + # client tests + # + log_start + run_cmd_nsb nettest -6 -D -s & + sleep 1 + run_cmd nettest -6 -D -d ${VRF} -r ${NSB_IP6} + log_test $? 0 "VRF client" + + # negative test - should fail + log_start + run_cmd nettest -6 -D -d ${VRF} -r ${NSB_IP6} + log_test $? 1 "No server, VRF client" + + log_start + run_cmd_nsb nettest -6 -D -s & + sleep 1 + run_cmd nettest -6 -D -d ${NSA_DEV} -r ${NSB_IP6} + log_test $? 0 "Enslaved device client" + + # negative test - should fail + log_start + run_cmd nettest -6 -D -d ${NSA_DEV} -r ${NSB_IP6} + log_test $? 1 "No server, enslaved device client" + + # + # local address tests + # + a=${NSA_IP6} + log_start + run_cmd nettest -6 -D -s -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -6 -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 0 "Global server, VRF client, local conn" + + #log_start + run_cmd nettest -6 -D -d ${VRF} -s -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -6 -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 0 "VRF server, VRF client, local conn" + + + a=${VRF_IP6} + log_start + run_cmd nettest -6 -D -s -2 ${VRF} & + sleep 1 + run_cmd nettest -6 -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 0 "Global server, VRF client, local conn" + + log_start + run_cmd nettest -6 -D -d ${VRF} -s -2 ${VRF} & + sleep 1 + run_cmd nettest -6 -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 0 "VRF server, VRF client, local conn" + + # negative test - should fail + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest -6 -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 1 "No server, VRF client, local conn" + done + + # device to global IP + a=${NSA_IP6} + log_start + run_cmd nettest -6 -D -s -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -6 -D -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 0 "Global server, device client, local conn" + + log_start + run_cmd nettest -6 -D -d ${VRF} -s -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -6 -D -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 0 "VRF server, device client, local conn" + + log_start + run_cmd nettest -6 -D -d ${NSA_DEV} -s -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -6 -D -d ${VRF} -r ${a} + log_test_addr ${a} $? 0 "Device server, VRF client, local conn" + + log_start + run_cmd nettest -6 -D -d ${NSA_DEV} -s -2 ${NSA_DEV} & + sleep 1 + run_cmd nettest -6 -D -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 0 "Device server, device client, local conn" + + log_start + run_cmd nettest -6 -D -d ${NSA_DEV} -r ${a} + log_test_addr ${a} $? 1 "No server, device client, local conn" + + + # link local addresses + log_start + run_cmd nettest -6 -D -s & + sleep 1 + run_cmd_nsb nettest -6 -D -d ${NSB_DEV} -r ${NSA_LINKIP6} + log_test $? 0 "Global server, linklocal IP" + + log_start + run_cmd_nsb nettest -6 -D -d ${NSB_DEV} -r ${NSA_LINKIP6} + log_test $? 1 "No server, linklocal IP" + + + log_start + run_cmd_nsb nettest -6 -D -s & + sleep 1 + run_cmd nettest -6 -D -d ${NSA_DEV} -r ${NSB_LINKIP6} + log_test $? 0 "Enslaved device client, linklocal IP" + + log_start + run_cmd nettest -6 -D -d ${NSA_DEV} -r ${NSB_LINKIP6} + log_test $? 1 "No server, device client, peer linklocal IP" + + + log_start + run_cmd nettest -6 -D -s & + sleep 1 + run_cmd nettest -6 -D -d ${NSA_DEV} -r ${NSA_LINKIP6} + log_test $? 0 "Enslaved device client, local conn - linklocal IP" + + log_start + run_cmd nettest -6 -D -d ${NSA_DEV} -r ${NSA_LINKIP6} + log_test $? 1 "No server, device client, local conn - linklocal IP" + + # LLA to GUA + run_cmd_nsb ip -6 addr del ${NSB_IP6}/64 dev ${NSB_DEV} + run_cmd_nsb ip -6 ro add ${NSA_IP6}/128 dev ${NSB_DEV} + log_start + run_cmd nettest -6 -s -D & + sleep 1 + run_cmd_nsb nettest -6 -D -r ${NSA_IP6} + log_test $? 0 "UDP in - LLA to GUA" + + run_cmd_nsb ip -6 ro del ${NSA_IP6}/128 dev ${NSB_DEV} + run_cmd_nsb ip -6 addr add ${NSB_IP6}/64 dev ${NSB_DEV} nodad +} + +ipv6_udp() +{ + # should not matter, but set to known state + set_sysctl net.ipv4.udp_early_demux=1 + + log_section "IPv6/UDP" + log_subsection "No VRF" + setup + + # udp_l3mdev_accept should have no affect without VRF; + # run tests with it enabled and disabled to verify + log_subsection "udp_l3mdev_accept disabled" + set_sysctl net.ipv4.udp_l3mdev_accept=0 + ipv6_udp_novrf + log_subsection "udp_l3mdev_accept enabled" + set_sysctl net.ipv4.udp_l3mdev_accept=1 + ipv6_udp_novrf + + log_subsection "With VRF" + setup "yes" + ipv6_udp_vrf +} + ################################################################################ # usage @@ -2069,7 +2558,7 @@ EOF # main TESTS_IPV4="ipv4_ping ipv4_tcp ipv4_udp" -TESTS_IPV6="ipv6_ping ipv6_tcp" +TESTS_IPV6="ipv6_ping ipv6_tcp ipv6_udp" PAUSE_ON_FAIL=no PAUSE=no @@ -2113,6 +2602,7 @@ do ipv6_ping|ping6) ipv6_ping;; ipv6_tcp|tcp6) ipv6_tcp;; + ipv6_udp|udp6) ipv6_udp;; # setup namespaces and config, but do not run any tests setup) setup; exit 0;; -- cgit v1.2.3-59-g8ed1b From 75b2b2b3db4ce660541709c52e826e2ac5c602ad Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 1 Aug 2019 11:56:42 -0700 Subject: selftests: Add ipv4 address bind tests to fcnal-test Add address bind tests to fcnal-test.sh. Verifies socket binding to local addresses for raw, tcp and udp including device and VRF cases. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/fcnal-test.sh | 111 +++++++++++++++++++++++++++++- 1 file changed, 110 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh index 2a2e692bc242..6023ee1c6980 100755 --- a/tools/testing/selftests/net/fcnal-test.sh +++ b/tools/testing/selftests/net/fcnal-test.sh @@ -1400,6 +1400,114 @@ ipv4_udp() ipv4_udp_vrf } +################################################################################ +# IPv4 address bind +# +# verifies ability or inability to bind to an address / device + +ipv4_addr_bind_novrf() +{ + # + # raw socket + # + for a in ${NSA_IP} ${NSA_LO_IP} + do + log_start + run_cmd nettest -s -R -P icmp -l ${a} -b + log_test_addr ${a} $? 0 "Raw socket bind to local address" + + log_start + run_cmd nettest -s -R -P icmp -l ${a} -d ${NSA_DEV} -b + log_test_addr ${a} $? 0 "Raw socket bind to local address after device bind" + done + + # + # tcp sockets + # + a=${NSA_IP} + log_start + run_cmd nettest -l ${a} -r ${NSB_IP} -t1 -b + log_test_addr ${a} $? 0 "TCP socket bind to local address" + + log_start + run_cmd nettest -l ${a} -r ${NSB_IP} -d ${NSA_DEV} -t1 -b + log_test_addr ${a} $? 0 "TCP socket bind to local address after device bind" + + # Sadly, the kernel allows binding a socket to a device and then + # binding to an address not on the device. The only restriction + # is that the address is valid in the L3 domain. So this test + # passes when it really should not + #a=${NSA_LO_IP} + #log_start + #show_hint "Should fail with 'Cannot assign requested address'" + #run_cmd nettest -s -l ${a} -d ${NSA_DEV} -t1 -b + #log_test_addr ${a} $? 1 "TCP socket bind to out of scope local address" +} + +ipv4_addr_bind_vrf() +{ + # + # raw socket + # + for a in ${NSA_IP} ${VRF_IP} + do + log_start + run_cmd nettest -s -R -P icmp -l ${a} -b + log_test_addr ${a} $? 0 "Raw socket bind to local address" + + log_start + run_cmd nettest -s -R -P icmp -l ${a} -d ${NSA_DEV} -b + log_test_addr ${a} $? 0 "Raw socket bind to local address after device bind" + log_start + run_cmd nettest -s -R -P icmp -l ${a} -d ${VRF} -b + log_test_addr ${a} $? 0 "Raw socket bind to local address after VRF bind" + done + + a=${NSA_LO_IP} + log_start + show_hint "Address on loopback is out of VRF scope" + run_cmd nettest -s -R -P icmp -l ${a} -d ${VRF} -b + log_test_addr ${a} $? 1 "Raw socket bind to out of scope address after VRF bind" + + # + # tcp sockets + # + for a in ${NSA_IP} ${VRF_IP} + do + log_start + run_cmd nettest -s -l ${a} -d ${VRF} -t1 -b + log_test_addr ${a} $? 0 "TCP socket bind to local address" + + log_start + run_cmd nettest -s -l ${a} -d ${NSA_DEV} -t1 -b + log_test_addr ${a} $? 0 "TCP socket bind to local address after device bind" + done + + a=${NSA_LO_IP} + log_start + show_hint "Address on loopback out of scope for VRF" + run_cmd nettest -s -l ${a} -d ${VRF} -t1 -b + log_test_addr ${a} $? 1 "TCP socket bind to invalid local address for VRF" + + log_start + show_hint "Address on loopback out of scope for device in VRF" + run_cmd nettest -s -l ${a} -d ${NSA_DEV} -t1 -b + log_test_addr ${a} $? 1 "TCP socket bind to invalid local address for device bind" +} + +ipv4_addr_bind() +{ + log_section "IPv4 address binds" + + log_subsection "No VRF" + setup + ipv4_addr_bind_novrf + + log_subsection "With VRF" + setup "yes" + ipv4_addr_bind_vrf +} + ################################################################################ # IPv6 @@ -2557,7 +2665,7 @@ EOF ################################################################################ # main -TESTS_IPV4="ipv4_ping ipv4_tcp ipv4_udp" +TESTS_IPV4="ipv4_ping ipv4_tcp ipv4_udp ipv4_addr_bind" TESTS_IPV6="ipv6_ping ipv6_tcp ipv6_udp" PAUSE_ON_FAIL=no PAUSE=no @@ -2599,6 +2707,7 @@ do ipv4_ping|ping) ipv4_ping;; ipv4_tcp|tcp) ipv4_tcp;; ipv4_udp|udp) ipv4_udp;; + ipv4_bind|bind) ipv4_addr_bind;; ipv6_ping|ping6) ipv6_ping;; ipv6_tcp|tcp6) ipv6_tcp;; -- cgit v1.2.3-59-g8ed1b From 34d0302ab86172b373e38ef02ea10519ab1c2388 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 1 Aug 2019 11:56:43 -0700 Subject: selftests: Add ipv6 address bind tests to fcnal-test Add IPv6 address bind tests to fcnal-test.sh. Verifies socket binding to local addresses for raw, tcp and udp including device and VRF cases. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/fcnal-test.sh | 110 +++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh index 6023ee1c6980..48e74d62e009 100755 --- a/tools/testing/selftests/net/fcnal-test.sh +++ b/tools/testing/selftests/net/fcnal-test.sh @@ -2645,6 +2645,113 @@ ipv6_udp() ipv6_udp_vrf } +################################################################################ +# IPv6 address bind + +ipv6_addr_bind_novrf() +{ + # + # raw socket + # + for a in ${NSA_IP6} ${NSA_LO_IP6} + do + log_start + run_cmd nettest -6 -s -R -P ipv6-icmp -l ${a} -b + log_test_addr ${a} $? 0 "Raw socket bind to local address" + + log_start + run_cmd nettest -6 -s -R -P ipv6-icmp -l ${a} -d ${NSA_DEV} -b + log_test_addr ${a} $? 0 "Raw socket bind to local address after device bind" + done + + # + # tcp sockets + # + a=${NSA_IP6} + log_start + run_cmd nettest -6 -s -l ${a} -t1 -b + log_test_addr ${a} $? 0 "TCP socket bind to local address" + + log_start + run_cmd nettest -6 -s -l ${a} -d ${NSA_DEV} -t1 -b + log_test_addr ${a} $? 0 "TCP socket bind to local address after device bind" + + a=${NSA_LO_IP6} + log_start + show_hint "Should fail with 'Cannot assign requested address'" + run_cmd nettest -6 -s -l ${a} -d ${NSA_DEV} -t1 -b + log_test_addr ${a} $? 1 "TCP socket bind to out of scope local address" +} + +ipv6_addr_bind_vrf() +{ + # + # raw socket + # + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest -6 -s -R -P ipv6-icmp -l ${a} -d ${VRF} -b + log_test_addr ${a} $? 0 "Raw socket bind to local address after vrf bind" + + log_start + run_cmd nettest -6 -s -R -P ipv6-icmp -l ${a} -d ${NSA_DEV} -b + log_test_addr ${a} $? 0 "Raw socket bind to local address after device bind" + done + + a=${NSA_LO_IP6} + log_start + show_hint "Address on loopback is out of VRF scope" + run_cmd nettest -6 -s -R -P ipv6-icmp -l ${a} -d ${VRF} -b + log_test_addr ${a} $? 1 "Raw socket bind to invalid local address after vrf bind" + + # + # tcp sockets + # + # address on enslaved device is valid for the VRF or device in a VRF + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest -6 -s -l ${a} -d ${VRF} -t1 -b + log_test_addr ${a} $? 0 "TCP socket bind to local address with VRF bind" + done + + a=${NSA_IP6} + log_start + run_cmd nettest -6 -s -l ${a} -d ${NSA_DEV} -t1 -b + log_test_addr ${a} $? 0 "TCP socket bind to local address with device bind" + + a=${VRF_IP6} + log_start + run_cmd nettest -6 -s -l ${a} -d ${NSA_DEV} -t1 -b + log_test_addr ${a} $? 1 "TCP socket bind to VRF address with device bind" + + a=${NSA_LO_IP6} + log_start + show_hint "Address on loopback out of scope for VRF" + run_cmd nettest -6 -s -l ${a} -d ${VRF} -t1 -b + log_test_addr ${a} $? 1 "TCP socket bind to invalid local address for VRF" + + log_start + show_hint "Address on loopback out of scope for device in VRF" + run_cmd nettest -6 -s -l ${a} -d ${NSA_DEV} -t1 -b + log_test_addr ${a} $? 1 "TCP socket bind to invalid local address for device bind" + +} + +ipv6_addr_bind() +{ + log_section "IPv6 address binds" + + log_subsection "No VRF" + setup + ipv6_addr_bind_novrf + + log_subsection "With VRF" + setup "yes" + ipv6_addr_bind_vrf +} + ################################################################################ # usage @@ -2666,7 +2773,7 @@ EOF # main TESTS_IPV4="ipv4_ping ipv4_tcp ipv4_udp ipv4_addr_bind" -TESTS_IPV6="ipv6_ping ipv6_tcp ipv6_udp" +TESTS_IPV6="ipv6_ping ipv6_tcp ipv6_udp ipv6_addr_bind" PAUSE_ON_FAIL=no PAUSE=no @@ -2712,6 +2819,7 @@ do ipv6_ping|ping6) ipv6_ping;; ipv6_tcp|tcp6) ipv6_tcp;; ipv6_udp|udp6) ipv6_udp;; + ipv6_bind|bind6) ipv6_addr_bind;; # setup namespaces and config, but do not run any tests setup) setup; exit 0;; -- cgit v1.2.3-59-g8ed1b From 0113f726856e389461fb0fc8d519fc2e8fe52d46 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 1 Aug 2019 11:56:44 -0700 Subject: selftests: Add ipv4 runtime tests to fcnal-test Add runtime tests where passive (no traffic flowing) and active (with traffic) sockets are expected to be reset on device deletes. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/fcnal-test.sh | 185 +++++++++++++++++++++++++++++- 1 file changed, 184 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh index 48e74d62e009..b8bdab733ecd 100755 --- a/tools/testing/selftests/net/fcnal-test.sh +++ b/tools/testing/selftests/net/fcnal-test.sh @@ -1508,6 +1508,188 @@ ipv4_addr_bind() ipv4_addr_bind_vrf } +################################################################################ +# IPv4 runtime tests + +ipv4_rt() +{ + local desc="$1" + local varg="$2" + local with_vrf="yes" + local a + + # + # server tests + # + for a in ${NSA_IP} ${VRF_IP} + do + log_start + run_cmd nettest ${varg} -s & + sleep 1 + run_cmd_nsb nettest ${varg} -r ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, global server" + + setup ${with_vrf} + done + + for a in ${NSA_IP} ${VRF_IP} + do + log_start + run_cmd nettest ${varg} -s -d ${VRF} & + sleep 1 + run_cmd_nsb nettest ${varg} -r ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, VRF server" + + setup ${with_vrf} + done + + a=${NSA_IP} + log_start + run_cmd nettest ${varg} -s -d ${NSA_DEV} & + sleep 1 + run_cmd_nsb nettest ${varg} -r ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, enslaved device server" + + setup ${with_vrf} + + # + # client test + # + log_start + run_cmd_nsb nettest ${varg} -s & + sleep 1 + run_cmd nettest ${varg} -d ${VRF} -r ${NSB_IP} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, VRF client" + + setup ${with_vrf} + + log_start + run_cmd_nsb nettest ${varg} -s & + sleep 1 + run_cmd nettest ${varg} -d ${NSA_DEV} -r ${NSB_IP} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, enslaved device client" + + setup ${with_vrf} + + # + # local address tests + # + for a in ${NSA_IP} ${VRF_IP} + do + log_start + run_cmd nettest ${varg} -s & + sleep 1 + run_cmd nettest ${varg} -d ${VRF} -r ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, global server, VRF client, local" + + setup ${with_vrf} + done + + for a in ${NSA_IP} ${VRF_IP} + do + log_start + run_cmd nettest ${varg} -d ${VRF} -s & + sleep 1 + run_cmd nettest ${varg} -d ${VRF} -r ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, VRF server and client, local" + + setup ${with_vrf} + done + + a=${NSA_IP} + log_start + run_cmd nettest ${varg} -s & + sleep 1 + run_cmd nettest ${varg} -d ${NSA_DEV} -r ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, global server, enslaved device client, local" + + setup ${with_vrf} + + log_start + run_cmd nettest ${varg} -d ${VRF} -s & + sleep 1 + run_cmd nettest ${varg} -d ${NSA_DEV} -r ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, VRF server, enslaved device client, local" + + setup ${with_vrf} + + log_start + run_cmd nettest ${varg} -d ${NSA_DEV} -s & + sleep 1 + run_cmd nettest ${varg} -d ${NSA_DEV} -r ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, enslaved device server and client, local" +} + +ipv4_ping_rt() +{ + local with_vrf="yes" + local a + + for a in ${NSA_IP} ${VRF_IP} + do + log_start + run_cmd_nsb ping -f ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "Device delete with active traffic - ping in" + + setup ${with_vrf} + done + + a=${NSB_IP} + log_start + run_cmd ping -f -I ${VRF} ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "Device delete with active traffic - ping out" +} + +ipv4_runtime() +{ + log_section "Run time tests - ipv4" + + setup "yes" + ipv4_ping_rt + + setup "yes" + ipv4_rt "TCP active socket" "-n -1" + + setup "yes" + ipv4_rt "TCP passive socket" "-i" +} + ################################################################################ # IPv6 @@ -2772,7 +2954,7 @@ EOF ################################################################################ # main -TESTS_IPV4="ipv4_ping ipv4_tcp ipv4_udp ipv4_addr_bind" +TESTS_IPV4="ipv4_ping ipv4_tcp ipv4_udp ipv4_addr_bind ipv4_runtime" TESTS_IPV6="ipv6_ping ipv6_tcp ipv6_udp ipv6_addr_bind" PAUSE_ON_FAIL=no PAUSE=no @@ -2815,6 +2997,7 @@ do ipv4_tcp|tcp) ipv4_tcp;; ipv4_udp|udp) ipv4_udp;; ipv4_bind|bind) ipv4_addr_bind;; + ipv4_runtime) ipv4_runtime;; ipv6_ping|ping6) ipv6_ping;; ipv6_tcp|tcp6) ipv6_tcp;; -- cgit v1.2.3-59-g8ed1b From 4cd12f61b55bc6a670900d75806a2f0122fc6658 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 1 Aug 2019 11:56:45 -0700 Subject: selftests: Add ipv6 runtime tests to fcnal-test Add IPv6 runtime tests where passive (no traffic flowing) and active (with traffic) sockets are expected to be reset on device deletes. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/fcnal-test.sh | 188 +++++++++++++++++++++++++++++- 1 file changed, 187 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh index b8bdab733ecd..dcfe0b13dfe9 100755 --- a/tools/testing/selftests/net/fcnal-test.sh +++ b/tools/testing/selftests/net/fcnal-test.sh @@ -2934,6 +2934,191 @@ ipv6_addr_bind() ipv6_addr_bind_vrf } +################################################################################ +# IPv6 runtime tests + +ipv6_rt() +{ + local desc="$1" + local varg="-6 $2" + local with_vrf="yes" + local a + + # + # server tests + # + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest ${varg} -s & + sleep 1 + run_cmd_nsb nettest ${varg} -r ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, global server" + + setup ${with_vrf} + done + + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest ${varg} -d ${VRF} -s & + sleep 1 + run_cmd_nsb nettest ${varg} -r ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, VRF server" + + setup ${with_vrf} + done + + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest ${varg} -d ${NSA_DEV} -s & + sleep 1 + run_cmd_nsb nettest ${varg} -r ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, enslaved device server" + + setup ${with_vrf} + done + + # + # client test + # + log_start + run_cmd_nsb nettest ${varg} -s & + sleep 1 + run_cmd nettest ${varg} -d ${VRF} -r ${NSB_IP6} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test 0 0 "${desc}, VRF client" + + setup ${with_vrf} + + log_start + run_cmd_nsb nettest ${varg} -s & + sleep 1 + run_cmd nettest ${varg} -d ${NSA_DEV} -r ${NSB_IP6} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test 0 0 "${desc}, enslaved device client" + + setup ${with_vrf} + + + # + # local address tests + # + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest ${varg} -s & + sleep 1 + run_cmd nettest ${varg} -d ${VRF} -r ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, global server, VRF client" + + setup ${with_vrf} + done + + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest ${varg} -d ${VRF} -s & + sleep 1 + run_cmd nettest ${varg} -d ${VRF} -r ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, VRF server and client" + + setup ${with_vrf} + done + + a=${NSA_IP6} + log_start + run_cmd nettest ${varg} -s & + sleep 1 + run_cmd nettest ${varg} -d ${NSA_DEV} -r ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, global server, device client" + + setup ${with_vrf} + + log_start + run_cmd nettest ${varg} -d ${VRF} -s & + sleep 1 + run_cmd nettest ${varg} -d ${NSA_DEV} -r ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, VRF server, device client" + + setup ${with_vrf} + + log_start + run_cmd nettest ${varg} -d ${NSA_DEV} -s & + sleep 1 + run_cmd nettest ${varg} -d ${NSA_DEV} -r ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "${desc}, device server, device client" +} + +ipv6_ping_rt() +{ + local with_vrf="yes" + local a + + a=${NSA_IP6} + log_start + run_cmd_nsb ${ping6} -f ${a} & + sleep 3 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "Device delete with active traffic - ping in" + + setup ${with_vrf} + + log_start + run_cmd ${ping6} -f ${NSB_IP6} -I ${VRF} & + sleep 1 + run_cmd ip link del ${VRF} + sleep 1 + log_test_addr ${a} 0 0 "Device delete with active traffic - ping out" +} + +ipv6_runtime() +{ + log_section "Run time tests - ipv6" + + setup "yes" + ipv6_ping_rt + + setup "yes" + ipv6_rt "TCP active socket" "-n -1" + + setup "yes" + ipv6_rt "TCP passive socket" "-i" + + setup "yes" + ipv6_rt "UDP active socket" "-D -n -1" +} + ################################################################################ # usage @@ -2955,7 +3140,7 @@ EOF # main TESTS_IPV4="ipv4_ping ipv4_tcp ipv4_udp ipv4_addr_bind ipv4_runtime" -TESTS_IPV6="ipv6_ping ipv6_tcp ipv6_udp ipv6_addr_bind" +TESTS_IPV6="ipv6_ping ipv6_tcp ipv6_udp ipv6_addr_bind ipv6_runtime" PAUSE_ON_FAIL=no PAUSE=no @@ -3003,6 +3188,7 @@ do ipv6_tcp|tcp6) ipv6_tcp;; ipv6_udp|udp6) ipv6_udp;; ipv6_bind|bind6) ipv6_addr_bind;; + ipv6_runtime) ipv6_runtime;; # setup namespaces and config, but do not run any tests setup) setup; exit 0;; -- cgit v1.2.3-59-g8ed1b From 88f2b36053b97d3299976dd3af1c768a7f5d9c55 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 1 Aug 2019 11:56:46 -0700 Subject: selftests: Add ipv4 netfilter tests to fcnal-test Add netfilter tests to send tcp reset or icmp unreachable for a port. Initial tests are VRF only. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/fcnal-test.sh | 69 ++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh index dcfe0b13dfe9..6f56c91e2d66 100755 --- a/tools/testing/selftests/net/fcnal-test.sh +++ b/tools/testing/selftests/net/fcnal-test.sh @@ -3119,6 +3119,72 @@ ipv6_runtime() ipv6_rt "UDP active socket" "-D -n -1" } +################################################################################ +# netfilter blocking connections + +netfilter_tcp_reset() +{ + local a + + for a in ${NSA_IP} ${VRF_IP} + do + log_start + run_cmd nettest -s & + sleep 1 + run_cmd_nsb nettest -r ${a} + log_test_addr ${a} $? 1 "Global server, reject with TCP-reset on Rx" + done +} + +netfilter_icmp() +{ + local stype="$1" + local arg + local a + + [ "${stype}" = "UDP" ] && arg="-D" + + for a in ${NSA_IP} ${VRF_IP} + do + log_start + run_cmd nettest ${arg} -s & + sleep 1 + run_cmd_nsb nettest ${arg} -r ${a} + log_test_addr ${a} $? 1 "Global ${stype} server, Rx reject icmp-port-unreach" + done +} + +ipv4_netfilter() +{ + which nettest >/dev/null + if [ $? -ne 0 ]; then + log_error "nettest not found; skipping tests" + return + fi + + log_section "IPv4 Netfilter" + log_subsection "TCP reset" + + setup "yes" + run_cmd iptables -A INPUT -p tcp --dport 12345 -j REJECT --reject-with tcp-reset + + netfilter_tcp_reset + + log_start + log_subsection "ICMP unreachable" + + log_start + run_cmd iptables -F + run_cmd iptables -A INPUT -p tcp --dport 12345 -j REJECT --reject-with icmp-port-unreachable + run_cmd iptables -A INPUT -p udp --dport 12345 -j REJECT --reject-with icmp-port-unreachable + + netfilter_icmp "TCP" + netfilter_icmp "UDP" + + log_start + iptables -F +} + ################################################################################ # usage @@ -3139,7 +3205,7 @@ EOF ################################################################################ # main -TESTS_IPV4="ipv4_ping ipv4_tcp ipv4_udp ipv4_addr_bind ipv4_runtime" +TESTS_IPV4="ipv4_ping ipv4_tcp ipv4_udp ipv4_addr_bind ipv4_runtime ipv4_netfilter" TESTS_IPV6="ipv6_ping ipv6_tcp ipv6_udp ipv6_addr_bind ipv6_runtime" PAUSE_ON_FAIL=no PAUSE=no @@ -3183,6 +3249,7 @@ do ipv4_udp|udp) ipv4_udp;; ipv4_bind|bind) ipv4_addr_bind;; ipv4_runtime) ipv4_runtime;; + ipv4_netfilter) ipv4_netfilter;; ipv6_ping|ping6) ipv6_ping;; ipv6_tcp|tcp6) ipv6_tcp;; -- cgit v1.2.3-59-g8ed1b From db6641ee6e9e728efb71bda93740559dc55f696c Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 1 Aug 2019 11:56:47 -0700 Subject: selftests: Add ipv6 netfilter tests to fcnal-test Add IPv6 netfilter tests to send tcp reset or icmp unreachable for a port. Initial tests are VRF only. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/fcnal-test.sh | 65 ++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh index 6f56c91e2d66..17eec10e06bf 100755 --- a/tools/testing/selftests/net/fcnal-test.sh +++ b/tools/testing/selftests/net/fcnal-test.sh @@ -3185,6 +3185,68 @@ ipv4_netfilter() iptables -F } +netfilter_tcp6_reset() +{ + local a + + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest -6 -s & + sleep 1 + run_cmd_nsb nettest -6 -r ${a} + log_test_addr ${a} $? 1 "Global server, reject with TCP-reset on Rx" + done +} + +netfilter_icmp6() +{ + local stype="$1" + local arg + local a + + [ "${stype}" = "UDP" ] && arg="$arg -D" + + for a in ${NSA_IP6} ${VRF_IP6} + do + log_start + run_cmd nettest -6 -s ${arg} & + sleep 1 + run_cmd_nsb nettest -6 ${arg} -r ${a} + log_test_addr ${a} $? 1 "Global ${stype} server, Rx reject icmp-port-unreach" + done +} + +ipv6_netfilter() +{ + which nettest >/dev/null + if [ $? -ne 0 ]; then + log_error "nettest not found; skipping tests" + return + fi + + log_section "IPv6 Netfilter" + log_subsection "TCP reset" + + setup "yes" + run_cmd ip6tables -A INPUT -p tcp --dport 12345 -j REJECT --reject-with tcp-reset + + netfilter_tcp6_reset + + log_subsection "ICMP unreachable" + + log_start + run_cmd ip6tables -F + run_cmd ip6tables -A INPUT -p tcp --dport 12345 -j REJECT --reject-with icmp6-port-unreachable + run_cmd ip6tables -A INPUT -p udp --dport 12345 -j REJECT --reject-with icmp6-port-unreachable + + netfilter_icmp6 "TCP" + netfilter_icmp6 "UDP" + + log_start + ip6tables -F +} + ################################################################################ # usage @@ -3206,7 +3268,7 @@ EOF # main TESTS_IPV4="ipv4_ping ipv4_tcp ipv4_udp ipv4_addr_bind ipv4_runtime ipv4_netfilter" -TESTS_IPV6="ipv6_ping ipv6_tcp ipv6_udp ipv6_addr_bind ipv6_runtime" +TESTS_IPV6="ipv6_ping ipv6_tcp ipv6_udp ipv6_addr_bind ipv6_runtime ipv6_netfilter" PAUSE_ON_FAIL=no PAUSE=no @@ -3256,6 +3318,7 @@ do ipv6_udp|udp6) ipv6_udp;; ipv6_bind|bind6) ipv6_addr_bind;; ipv6_runtime) ipv6_runtime;; + ipv6_netfilter) ipv6_netfilter;; # setup namespaces and config, but do not run any tests setup) setup; exit 0;; -- cgit v1.2.3-59-g8ed1b From 56eba15d1c601d7e8a40b2997c9aff72bdae9b0f Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 1 Aug 2019 11:56:48 -0700 Subject: selftests: Add use case section to fcnal-test Add use case section to fcnal-test. Initial test is VRF based with a bridge and vlans. The commands stem from bug reports fixed by: a173f066c7cf ("netfilter: bridge: Don't sabotage nf_hook calls from an l3mdev") cd6428988bf4 ("netfilter: bridge: Don't sabotage nf_hook calls for an l3mdev slave") Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/fcnal-test.sh | 124 ++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh index 17eec10e06bf..bd6b564382ec 100755 --- a/tools/testing/selftests/net/fcnal-test.sh +++ b/tools/testing/selftests/net/fcnal-test.sh @@ -3247,6 +3247,126 @@ ipv6_netfilter() ip6tables -F } +################################################################################ +# specific use cases + +# VRF only. +# ns-A device enslaved to bridge. Verify traffic with and without +# br_netfilter module loaded. Repeat with SVI on bridge. +use_case_br() +{ + setup "yes" + + setup_cmd ip link set ${NSA_DEV} down + setup_cmd ip addr del dev ${NSA_DEV} ${NSA_IP}/24 + setup_cmd ip -6 addr del dev ${NSA_DEV} ${NSA_IP6}/64 + + setup_cmd ip link add br0 type bridge + setup_cmd ip addr add dev br0 ${NSA_IP}/24 + setup_cmd ip -6 addr add dev br0 ${NSA_IP6}/64 nodad + + setup_cmd ip li set ${NSA_DEV} master br0 + setup_cmd ip li set ${NSA_DEV} up + setup_cmd ip li set br0 up + setup_cmd ip li set br0 vrf ${VRF} + + rmmod br_netfilter 2>/dev/null + sleep 5 # DAD + + run_cmd ip neigh flush all + run_cmd ping -c1 -w1 -I br0 ${NSB_IP} + log_test $? 0 "Bridge into VRF - IPv4 ping out" + + run_cmd ip neigh flush all + run_cmd ${ping6} -c1 -w1 -I br0 ${NSB_IP6} + log_test $? 0 "Bridge into VRF - IPv6 ping out" + + run_cmd ip neigh flush all + run_cmd_nsb ping -c1 -w1 ${NSA_IP} + log_test $? 0 "Bridge into VRF - IPv4 ping in" + + run_cmd ip neigh flush all + run_cmd_nsb ${ping6} -c1 -w1 ${NSA_IP6} + log_test $? 0 "Bridge into VRF - IPv6 ping in" + + modprobe br_netfilter + if [ $? -eq 0 ]; then + run_cmd ip neigh flush all + run_cmd ping -c1 -w1 -I br0 ${NSB_IP} + log_test $? 0 "Bridge into VRF with br_netfilter - IPv4 ping out" + + run_cmd ip neigh flush all + run_cmd ${ping6} -c1 -w1 -I br0 ${NSB_IP6} + log_test $? 0 "Bridge into VRF with br_netfilter - IPv6 ping out" + + run_cmd ip neigh flush all + run_cmd_nsb ping -c1 -w1 ${NSA_IP} + log_test $? 0 "Bridge into VRF with br_netfilter - IPv4 ping in" + + run_cmd ip neigh flush all + run_cmd_nsb ${ping6} -c1 -w1 ${NSA_IP6} + log_test $? 0 "Bridge into VRF with br_netfilter - IPv6 ping in" + fi + + setup_cmd ip li set br0 nomaster + setup_cmd ip li add br0.100 link br0 type vlan id 100 + setup_cmd ip li set br0.100 vrf ${VRF} up + setup_cmd ip addr add dev br0.100 172.16.101.1/24 + setup_cmd ip -6 addr add dev br0.100 2001:db8:101::1/64 nodad + + setup_cmd_nsb ip li add vlan100 link ${NSB_DEV} type vlan id 100 + setup_cmd_nsb ip addr add dev vlan100 172.16.101.2/24 + setup_cmd_nsb ip -6 addr add dev vlan100 2001:db8:101::2/64 nodad + setup_cmd_nsb ip li set vlan100 up + sleep 1 + + rmmod br_netfilter 2>/dev/null + + run_cmd ip neigh flush all + run_cmd ping -c1 -w1 -I br0.100 172.16.101.2 + log_test $? 0 "Bridge vlan into VRF - IPv4 ping out" + + run_cmd ip neigh flush all + run_cmd ${ping6} -c1 -w1 -I br0.100 2001:db8:101::2 + log_test $? 0 "Bridge vlan into VRF - IPv6 ping out" + + run_cmd ip neigh flush all + run_cmd_nsb ping -c1 -w1 172.16.101.1 + log_test $? 0 "Bridge vlan into VRF - IPv4 ping in" + + run_cmd ip neigh flush all + run_cmd_nsb ${ping6} -c1 -w1 2001:db8:101::1 + log_test $? 0 "Bridge vlan into VRF - IPv6 ping in" + + modprobe br_netfilter + if [ $? -eq 0 ]; then + run_cmd ip neigh flush all + run_cmd ping -c1 -w1 -I br0.100 172.16.101.2 + log_test $? 0 "Bridge vlan into VRF with br_netfilter - IPv4 ping out" + + run_cmd ip neigh flush all + run_cmd ${ping6} -c1 -w1 -I br0.100 2001:db8:101::2 + log_test $? 0 "Bridge vlan into VRF with br_netfilter - IPv6 ping out" + + run_cmd ip neigh flush all + run_cmd_nsb ping -c1 -w1 172.16.101.1 + log_test $? 0 "Bridge vlan into VRF - IPv4 ping in" + + run_cmd ip neigh flush all + run_cmd_nsb ${ping6} -c1 -w1 2001:db8:101::1 + log_test $? 0 "Bridge vlan into VRF - IPv6 ping in" + fi + + setup_cmd ip li del br0 2>/dev/null + setup_cmd_nsb ip li del vlan100 2>/dev/null +} + +use_cases() +{ + log_section "Use cases" + use_case_br +} + ################################################################################ # usage @@ -3269,6 +3389,8 @@ EOF TESTS_IPV4="ipv4_ping ipv4_tcp ipv4_udp ipv4_addr_bind ipv4_runtime ipv4_netfilter" TESTS_IPV6="ipv6_ping ipv6_tcp ipv6_udp ipv6_addr_bind ipv6_runtime ipv6_netfilter" +TESTS_OTHER="use_cases" + PAUSE_ON_FAIL=no PAUSE=no @@ -3320,6 +3442,8 @@ do ipv6_runtime) ipv6_runtime;; ipv6_netfilter) ipv6_netfilter;; + use_cases) use_cases;; + # setup namespaces and config, but do not run any tests setup) setup; exit 0;; vrf_setup) setup "yes"; exit 0;; -- cgit v1.2.3-59-g8ed1b From 0ca1bbb7f4212aeef83a67a8aed9da1d84567fcc Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 30 Jul 2019 14:57:18 +0200 Subject: selftests: netfilter: extend flowtable test script for ipsec 'flow offload' expression should not offload flows that will be subject to ipsec, but it does. This results in a connectivity blackhole for the affected flows -- first packets will go through (offload happens after established state is reached), but all remaining ones bypass ipsec encryption and are thus discarded by the peer. This can be worked around by adding "rt ipsec exists accept" before the 'flow offload' rule matches. This test case will fail, support for such flows is added in next patch. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- tools/testing/selftests/netfilter/nft_flowtable.sh | 48 ++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/netfilter/nft_flowtable.sh b/tools/testing/selftests/netfilter/nft_flowtable.sh index fe52488a6f72..16571ac1dab4 100755 --- a/tools/testing/selftests/netfilter/nft_flowtable.sh +++ b/tools/testing/selftests/netfilter/nft_flowtable.sh @@ -321,4 +321,52 @@ else ip netns exec nsr1 nft list ruleset fi +KEY_SHA="0x"$(ps -xaf | sha1sum | cut -d " " -f 1) +KEY_AES="0x"$(ps -xaf | md5sum | cut -d " " -f 1) +SPI1=$RANDOM +SPI2=$RANDOM + +if [ $SPI1 -eq $SPI2 ]; then + SPI2=$((SPI2+1)) +fi + +do_esp() { + local ns=$1 + local me=$2 + local remote=$3 + local lnet=$4 + local rnet=$5 + local spi_out=$6 + local spi_in=$7 + + ip -net $ns xfrm state add src $remote dst $me proto esp spi $spi_in enc aes $KEY_AES auth sha1 $KEY_SHA mode tunnel sel src $rnet dst $lnet + ip -net $ns xfrm state add src $me dst $remote proto esp spi $spi_out enc aes $KEY_AES auth sha1 $KEY_SHA mode tunnel sel src $lnet dst $rnet + + # to encrypt packets as they go out (includes forwarded packets that need encapsulation) + ip -net $ns xfrm policy add src $lnet dst $rnet dir out tmpl src $me dst $remote proto esp mode tunnel priority 1 action allow + # to fwd decrypted packets after esp processing: + ip -net $ns xfrm policy add src $rnet dst $lnet dir fwd tmpl src $remote dst $me proto esp mode tunnel priority 1 action allow + +} + +do_esp nsr1 192.168.10.1 192.168.10.2 10.0.1.0/24 10.0.2.0/24 $SPI1 $SPI2 + +do_esp nsr2 192.168.10.2 192.168.10.1 10.0.2.0/24 10.0.1.0/24 $SPI2 $SPI1 + +ip netns exec nsr1 nft delete table ip nat + +# restore default routes +ip -net ns2 route del 192.168.10.1 via 10.0.2.1 +ip -net ns2 route add default via 10.0.2.1 +ip -net ns2 route add default via dead:2::1 + +test_tcp_forwarding ns1 ns2 +if [ $? -eq 0 ] ;then + echo "PASS: ipsec tunnel mode for ns1/ns2" +else + echo "FAIL: ipsec tunnel mode for ns1/ns2" + ip netns exec nsr1 nft list ruleset 1>&2 + ip netns exec nsr1 cat /proc/net/xfrm_stat 1>&2 +fi + exit $ret -- cgit v1.2.3-59-g8ed1b From a9e21bea1f815c2ec917ecc0efe0a7049c825d5b Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 5 Aug 2019 11:52:11 +0100 Subject: ][next] selftests: nettest: fix spelling mistake: "potocol" -> "protocol" There is a spelling mistake in an error messgae. Fix it. Signed-off-by: Colin Ian King Acked-by: Shuah Khan Signed-off-by: David S. Miller --- tools/testing/selftests/net/nettest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/nettest.c b/tools/testing/selftests/net/nettest.c index 9278f8460d75..83515e5ea4dc 100644 --- a/tools/testing/selftests/net/nettest.c +++ b/tools/testing/selftests/net/nettest.c @@ -1627,7 +1627,7 @@ int main(int argc, char *argv[]) args.protocol = pe->p_proto; } else { if (str_to_uint(optarg, 0, 0xffff, &tmp) != 0) { - fprintf(stderr, "Invalid potocol\n"); + fprintf(stderr, "Invalid protocol\n"); return 1; } args.protocol = tmp; -- cgit v1.2.3-59-g8ed1b From a78d0dbec712999ecd2f800eea0f62dc93867a78 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Fri, 2 Aug 2019 15:54:01 -0700 Subject: selftests/bpf: add loop test 4 Add a test that returns a 'random' number between [0, 2^20) If state pruning is not working correctly for loop body the number of processed insns will be 2^20 * num_of_insns_in_loop_body and the program will be rejected. Signed-off-by: Alexei Starovoitov Acked-by: Andrii Nakryiko Acked-by: Yonghong Song --- .../testing/selftests/bpf/prog_tests/bpf_verif_scale.c | 1 + tools/testing/selftests/bpf/progs/loop4.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/loop4.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c b/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c index b4be96162ff4..e9e72d8d7aae 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c @@ -71,6 +71,7 @@ void test_bpf_verif_scale(void) { "loop1.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, { "loop2.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, + { "loop4.o", BPF_PROG_TYPE_SCHED_CLS }, /* partial unroll. 19k insn in a loop. * Total program size 20.8k insn. diff --git a/tools/testing/selftests/bpf/progs/loop4.c b/tools/testing/selftests/bpf/progs/loop4.c new file mode 100644 index 000000000000..650859022771 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/loop4.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Facebook +#include +#include "bpf_helpers.h" + +char _license[] SEC("license") = "GPL"; + +SEC("socket") +int combinations(volatile struct __sk_buff* skb) +{ + int ret = 0, i; + +#pragma nounroll + for (i = 0; i < 20; i++) + if (skb->len) + ret |= 1 << i; + return ret; +} -- cgit v1.2.3-59-g8ed1b From 8c30396074c131765b19eb3cb7ff764a4f2f2913 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Fri, 2 Aug 2019 16:23:40 -0700 Subject: selftests/bpf: add loop test 5 Add a test with multiple exit conditions. It's not an infinite loop only when the verifier can properly track all math on variable 'i' through all possible ways of executing this loop. barrier()s are needed to disable llvm optimization that combines multiple branches into fewer branches. Signed-off-by: Alexei Starovoitov Acked-by: Yonghong Song --- .../selftests/bpf/prog_tests/bpf_verif_scale.c | 1 + tools/testing/selftests/bpf/progs/loop5.c | 32 ++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/loop5.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c b/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c index e9e72d8d7aae..0caf8eafa9eb 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c @@ -72,6 +72,7 @@ void test_bpf_verif_scale(void) { "loop1.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, { "loop2.o", BPF_PROG_TYPE_RAW_TRACEPOINT }, { "loop4.o", BPF_PROG_TYPE_SCHED_CLS }, + { "loop5.o", BPF_PROG_TYPE_SCHED_CLS }, /* partial unroll. 19k insn in a loop. * Total program size 20.8k insn. diff --git a/tools/testing/selftests/bpf/progs/loop5.c b/tools/testing/selftests/bpf/progs/loop5.c new file mode 100644 index 000000000000..28d1d668f07c --- /dev/null +++ b/tools/testing/selftests/bpf/progs/loop5.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Facebook +#include +#include "bpf_helpers.h" +#define barrier() __asm__ __volatile__("": : :"memory") + +char _license[] SEC("license") = "GPL"; + +SEC("socket") +int while_true(volatile struct __sk_buff* skb) +{ + int i = 0; + + while (1) { + if (skb->len) + i += 3; + else + i += 7; + if (i == 9) + break; + barrier(); + if (i == 10) + break; + barrier(); + if (i == 13) + break; + barrier(); + if (i == 14) + break; + } + return i; +} -- cgit v1.2.3-59-g8ed1b From 9ce1263033cd2ad393e2ff0df4a1c4ab4992c9df Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Tue, 23 Jul 2019 19:58:52 +0200 Subject: selftests, arm64: add a selftest for passing tagged pointers to kernel This patch is a part of a series that extends kernel ABI to allow to pass tagged user pointers (with the top byte set to something else other than 0x00) as syscall arguments. This patch adds a simple test, that calls the uname syscall with a tagged user pointer as an argument. Without the kernel accepting tagged user pointers the test fails with EFAULT. Reviewed-by: Catalin Marinas Acked-by: Kees Cook Signed-off-by: Andrey Konovalov Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/.gitignore | 1 + tools/testing/selftests/arm64/Makefile | 11 ++++++++++ tools/testing/selftests/arm64/run_tags_test.sh | 12 +++++++++++ tools/testing/selftests/arm64/tags_test.c | 29 ++++++++++++++++++++++++++ 4 files changed, 53 insertions(+) create mode 100644 tools/testing/selftests/arm64/.gitignore create mode 100644 tools/testing/selftests/arm64/Makefile create mode 100755 tools/testing/selftests/arm64/run_tags_test.sh create mode 100644 tools/testing/selftests/arm64/tags_test.c (limited to 'tools') diff --git a/tools/testing/selftests/arm64/.gitignore b/tools/testing/selftests/arm64/.gitignore new file mode 100644 index 000000000000..e8fae8d61ed6 --- /dev/null +++ b/tools/testing/selftests/arm64/.gitignore @@ -0,0 +1 @@ +tags_test diff --git a/tools/testing/selftests/arm64/Makefile b/tools/testing/selftests/arm64/Makefile new file mode 100644 index 000000000000..a61b2e743e99 --- /dev/null +++ b/tools/testing/selftests/arm64/Makefile @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 + +# ARCH can be overridden by the user for cross compiling +ARCH ?= $(shell uname -m 2>/dev/null || echo not) + +ifneq (,$(filter $(ARCH),aarch64 arm64)) +TEST_GEN_PROGS := tags_test +TEST_PROGS := run_tags_test.sh +endif + +include ../lib.mk diff --git a/tools/testing/selftests/arm64/run_tags_test.sh b/tools/testing/selftests/arm64/run_tags_test.sh new file mode 100755 index 000000000000..745f11379930 --- /dev/null +++ b/tools/testing/selftests/arm64/run_tags_test.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +echo "--------------------" +echo "running tags test" +echo "--------------------" +./tags_test +if [ $? -ne 0 ]; then + echo "[FAIL]" +else + echo "[PASS]" +fi diff --git a/tools/testing/selftests/arm64/tags_test.c b/tools/testing/selftests/arm64/tags_test.c new file mode 100644 index 000000000000..22a1b266e373 --- /dev/null +++ b/tools/testing/selftests/arm64/tags_test.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include + +#define SHIFT_TAG(tag) ((uint64_t)(tag) << 56) +#define SET_TAG(ptr, tag) (((uint64_t)(ptr) & ~SHIFT_TAG(0xff)) | \ + SHIFT_TAG(tag)) + +int main(void) +{ + static int tbi_enabled = 0; + struct utsname *ptr, *tagged_ptr; + int err; + + if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == 0) + tbi_enabled = 1; + ptr = (struct utsname *)malloc(sizeof(*ptr)); + if (tbi_enabled) + tagged_ptr = (struct utsname *)SET_TAG(ptr, 0x42); + err = uname(tagged_ptr); + free(ptr); + + return err; +} -- cgit v1.2.3-59-g8ed1b From e63f3085709e92bd876e2977a07099d56bbda1c2 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Sun, 28 Jul 2019 00:22:30 +0200 Subject: pidfd: add pidfd_wait tests Add tests for pidfd_wait() and CLONE_WAIT_PID: - test that waitid(P_PIDFD) fails on /proc/ - test that waitid(P_PIDFD) fails on /dev/null - test that waitid(P_PIDFD) can wait on a pidfd - test that waitid(P_PIDFD) can wait on a pidfd and return siginfo_t - test that waitid(P_PIDFD) works with WEXITED - test that waitid(P_PIDFD) works with WSTOPPED - test that waitid(P_PIDFD) works with WUNTRACED - test that waitid(P_PIDFD) works with WCONTINUED - test that waitid(P_PIDFD) works with WNOWAIT - test that waitid(P_PIDFD)works with WNOHANG Signed-off-by: Christian Brauner Reviewed-by: Kees Cook Cc: Arnd Bergmann Cc: "Eric W. Biederman" Cc: Joel Fernandes (Google) Cc: Thomas Gleixner Cc: David Howells Cc: Jann Horn Cc: Andy Lutomirsky Cc: Andrew Morton Cc: Oleg Nesterov Cc: Aleksa Sarai Cc: Linus Torvalds Cc: Al Viro Link: https://lore.kernel.org/r/20190727222229.6516-3-christian@brauner.io --- tools/testing/selftests/pidfd/.gitignore | 1 + tools/testing/selftests/pidfd/Makefile | 2 +- tools/testing/selftests/pidfd/pidfd.h | 25 +++ tools/testing/selftests/pidfd/pidfd_test.c | 14 -- tools/testing/selftests/pidfd/pidfd_wait.c | 271 +++++++++++++++++++++++++++++ 5 files changed, 298 insertions(+), 15 deletions(-) create mode 100644 tools/testing/selftests/pidfd/pidfd_wait.c (limited to 'tools') diff --git a/tools/testing/selftests/pidfd/.gitignore b/tools/testing/selftests/pidfd/.gitignore index 16d84d117bc0..730ef9dc08cc 100644 --- a/tools/testing/selftests/pidfd/.gitignore +++ b/tools/testing/selftests/pidfd/.gitignore @@ -1,2 +1,3 @@ pidfd_open_test pidfd_test +pidfd_wait diff --git a/tools/testing/selftests/pidfd/Makefile b/tools/testing/selftests/pidfd/Makefile index 720b2d884b3c..7c97e890f353 100644 --- a/tools/testing/selftests/pidfd/Makefile +++ b/tools/testing/selftests/pidfd/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only CFLAGS += -g -I../../../../usr/include/ -lpthread -TEST_GEN_PROGS := pidfd_test pidfd_open_test +TEST_GEN_PROGS := pidfd_test pidfd_open_test pidfd_wait include ../lib.mk diff --git a/tools/testing/selftests/pidfd/pidfd.h b/tools/testing/selftests/pidfd/pidfd.h index 8452e910463f..7d7d0ca05e0b 100644 --- a/tools/testing/selftests/pidfd/pidfd.h +++ b/tools/testing/selftests/pidfd/pidfd.h @@ -16,6 +16,26 @@ #include "../kselftest.h" +#ifndef P_PIDFD +#define P_PIDFD 3 +#endif + +#ifndef CLONE_PIDFD +#define CLONE_PIDFD 0x00001000 +#endif + +#ifndef __NR_pidfd_open +#define __NR_pidfd_open -1 +#endif + +#ifndef __NR_pidfd_send_signal +#define __NR_pidfd_send_signal -1 +#endif + +#ifndef __NR_clone3 +#define __NR_clone3 -1 +#endif + /* * The kernel reserves 300 pids via RESERVED_PIDS in kernel/pid.c * That means, when it wraps around any pid < 300 will be skipped. @@ -53,5 +73,10 @@ again: return WEXITSTATUS(status); } +static inline int sys_pidfd_send_signal(int pidfd, int sig, siginfo_t *info, + unsigned int flags) +{ + return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags); +} #endif /* __PIDFD_H */ diff --git a/tools/testing/selftests/pidfd/pidfd_test.c b/tools/testing/selftests/pidfd/pidfd_test.c index 7eaa8a3de262..42e3eb494d72 100644 --- a/tools/testing/selftests/pidfd/pidfd_test.c +++ b/tools/testing/selftests/pidfd/pidfd_test.c @@ -21,20 +21,12 @@ #include "pidfd.h" #include "../kselftest.h" -#ifndef __NR_pidfd_send_signal -#define __NR_pidfd_send_signal -1 -#endif - #define str(s) _str(s) #define _str(s) #s #define CHILD_THREAD_MIN_WAIT 3 /* seconds */ #define MAX_EVENTS 5 -#ifndef CLONE_PIDFD -#define CLONE_PIDFD 0x00001000 -#endif - static pid_t pidfd_clone(int flags, int *pidfd, int (*fn)(void *)) { size_t stack_size = 1024; @@ -47,12 +39,6 @@ static pid_t pidfd_clone(int flags, int *pidfd, int (*fn)(void *)) #endif } -static inline int sys_pidfd_send_signal(int pidfd, int sig, siginfo_t *info, - unsigned int flags) -{ - return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags); -} - static int signal_received; static void set_signal_received_on_sigusr1(int sig) diff --git a/tools/testing/selftests/pidfd/pidfd_wait.c b/tools/testing/selftests/pidfd/pidfd_wait.c new file mode 100644 index 000000000000..7079f8eef792 --- /dev/null +++ b/tools/testing/selftests/pidfd/pidfd_wait.c @@ -0,0 +1,271 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pidfd.h" +#include "../kselftest.h" + +#define ptr_to_u64(ptr) ((__u64)((uintptr_t)(ptr))) + +static pid_t sys_clone3(struct clone_args *args) +{ + return syscall(__NR_clone3, args, sizeof(struct clone_args)); +} + +static int sys_waitid(int which, pid_t pid, siginfo_t *info, int options, + struct rusage *ru) +{ + return syscall(__NR_waitid, which, pid, info, options, ru); +} + +static int test_pidfd_wait_simple(void) +{ + const char *test_name = "pidfd wait simple"; + int pidfd = -1, status = 0; + pid_t parent_tid = -1; + struct clone_args args = { + .parent_tid = ptr_to_u64(&parent_tid), + .pidfd = ptr_to_u64(&pidfd), + .flags = CLONE_PIDFD | CLONE_PARENT_SETTID, + .exit_signal = SIGCHLD, + }; + int ret; + pid_t pid; + siginfo_t info = { + .si_signo = 0, + }; + + pidfd = open("/proc/self", O_DIRECTORY | O_RDONLY | O_CLOEXEC); + if (pidfd < 0) + ksft_exit_fail_msg("%s test: failed to open /proc/self %s\n", + test_name, strerror(errno)); + + pid = sys_waitid(P_PIDFD, pidfd, &info, WEXITED, NULL); + if (pid == 0) + ksft_exit_fail_msg( + "%s test: succeeded to wait on invalid pidfd %s\n", + test_name, strerror(errno)); + close(pidfd); + pidfd = -1; + + pidfd = open("/dev/null", O_RDONLY | O_CLOEXEC); + if (pidfd == 0) + ksft_exit_fail_msg("%s test: failed to open /dev/null %s\n", + test_name, strerror(errno)); + + pid = sys_waitid(P_PIDFD, pidfd, &info, WEXITED, NULL); + if (pid == 0) + ksft_exit_fail_msg( + "%s test: succeeded to wait on invalid pidfd %s\n", + test_name, strerror(errno)); + close(pidfd); + pidfd = -1; + + pid = sys_clone3(&args); + if (pid < 0) + ksft_exit_fail_msg("%s test: failed to create new process %s\n", + test_name, strerror(errno)); + + if (pid == 0) + exit(EXIT_SUCCESS); + + pid = sys_waitid(P_PIDFD, pidfd, &info, WEXITED, NULL); + if (pid < 0) + ksft_exit_fail_msg( + "%s test: failed to wait on process with pid %d and pidfd %d: %s\n", + test_name, parent_tid, pidfd, strerror(errno)); + + if (!WIFEXITED(info.si_status) || WEXITSTATUS(info.si_status)) + ksft_exit_fail_msg( + "%s test: unexpected status received after waiting on process with pid %d and pidfd %d: %s\n", + test_name, parent_tid, pidfd, strerror(errno)); + close(pidfd); + + if (info.si_signo != SIGCHLD) + ksft_exit_fail_msg( + "%s test: unexpected si_signo value %d received after waiting on process with pid %d and pidfd %d: %s\n", + test_name, info.si_signo, parent_tid, pidfd, + strerror(errno)); + + if (info.si_code != CLD_EXITED) + ksft_exit_fail_msg( + "%s test: unexpected si_code value %d received after waiting on process with pid %d and pidfd %d: %s\n", + test_name, info.si_code, parent_tid, pidfd, + strerror(errno)); + + if (info.si_pid != parent_tid) + ksft_exit_fail_msg( + "%s test: unexpected si_pid value %d received after waiting on process with pid %d and pidfd %d: %s\n", + test_name, info.si_pid, parent_tid, pidfd, + strerror(errno)); + + ksft_test_result_pass("%s test: Passed\n", test_name); + return 0; +} + +static int test_pidfd_wait_states(void) +{ + const char *test_name = "pidfd wait states"; + int pidfd = -1, status = 0; + pid_t parent_tid = -1; + struct clone_args args = { + .parent_tid = ptr_to_u64(&parent_tid), + .pidfd = ptr_to_u64(&pidfd), + .flags = CLONE_PIDFD | CLONE_PARENT_SETTID, + .exit_signal = SIGCHLD, + }; + int ret; + pid_t pid; + siginfo_t info = { + .si_signo = 0, + }; + + pid = sys_clone3(&args); + if (pid < 0) + ksft_exit_fail_msg("%s test: failed to create new process %s\n", + test_name, strerror(errno)); + + if (pid == 0) { + kill(getpid(), SIGSTOP); + kill(getpid(), SIGSTOP); + exit(EXIT_SUCCESS); + } + + ret = sys_waitid(P_PIDFD, pidfd, &info, WSTOPPED, NULL); + if (ret < 0) + ksft_exit_fail_msg( + "%s test: failed to wait on WSTOPPED process with pid %d and pidfd %d: %s\n", + test_name, parent_tid, pidfd, strerror(errno)); + + if (info.si_signo != SIGCHLD) + ksft_exit_fail_msg( + "%s test: unexpected si_signo value %d received after waiting on process with pid %d and pidfd %d: %s\n", + test_name, info.si_signo, parent_tid, pidfd, + strerror(errno)); + + if (info.si_code != CLD_STOPPED) + ksft_exit_fail_msg( + "%s test: unexpected si_code value %d received after waiting on process with pid %d and pidfd %d: %s\n", + test_name, info.si_code, parent_tid, pidfd, + strerror(errno)); + + if (info.si_pid != parent_tid) + ksft_exit_fail_msg( + "%s test: unexpected si_pid value %d received after waiting on process with pid %d and pidfd %d: %s\n", + test_name, info.si_pid, parent_tid, pidfd, + strerror(errno)); + + ret = sys_pidfd_send_signal(pidfd, SIGCONT, NULL, 0); + if (ret < 0) + ksft_exit_fail_msg( + "%s test: failed to send signal to process with pid %d and pidfd %d: %s\n", + test_name, parent_tid, pidfd, strerror(errno)); + + ret = sys_waitid(P_PIDFD, pidfd, &info, WCONTINUED, NULL); + if (ret < 0) + ksft_exit_fail_msg( + "%s test: failed to wait WCONTINUED on process with pid %d and pidfd %d: %s\n", + test_name, parent_tid, pidfd, strerror(errno)); + + if (info.si_signo != SIGCHLD) + ksft_exit_fail_msg( + "%s test: unexpected si_signo value %d received after waiting on process with pid %d and pidfd %d: %s\n", + test_name, info.si_signo, parent_tid, pidfd, + strerror(errno)); + + if (info.si_code != CLD_CONTINUED) + ksft_exit_fail_msg( + "%s test: unexpected si_code value %d received after waiting on process with pid %d and pidfd %d: %s\n", + test_name, info.si_code, parent_tid, pidfd, + strerror(errno)); + + if (info.si_pid != parent_tid) + ksft_exit_fail_msg( + "%s test: unexpected si_pid value %d received after waiting on process with pid %d and pidfd %d: %s\n", + test_name, info.si_pid, parent_tid, pidfd, + strerror(errno)); + + ret = sys_waitid(P_PIDFD, pidfd, &info, WUNTRACED, NULL); + if (ret < 0) + ksft_exit_fail_msg( + "%s test: failed to wait on WUNTRACED process with pid %d and pidfd %d: %s\n", + test_name, parent_tid, pidfd, strerror(errno)); + + if (info.si_signo != SIGCHLD) + ksft_exit_fail_msg( + "%s test: unexpected si_signo value %d received after waiting on process with pid %d and pidfd %d: %s\n", + test_name, info.si_signo, parent_tid, pidfd, + strerror(errno)); + + if (info.si_code != CLD_STOPPED) + ksft_exit_fail_msg( + "%s test: unexpected si_code value %d received after waiting on process with pid %d and pidfd %d: %s\n", + test_name, info.si_code, parent_tid, pidfd, + strerror(errno)); + + if (info.si_pid != parent_tid) + ksft_exit_fail_msg( + "%s test: unexpected si_pid value %d received after waiting on process with pid %d and pidfd %d: %s\n", + test_name, info.si_pid, parent_tid, pidfd, + strerror(errno)); + + ret = sys_pidfd_send_signal(pidfd, SIGKILL, NULL, 0); + if (ret < 0) + ksft_exit_fail_msg( + "%s test: failed to send SIGKILL to process with pid %d and pidfd %d: %s\n", + test_name, parent_tid, pidfd, strerror(errno)); + + ret = sys_waitid(P_PIDFD, pidfd, &info, WEXITED, NULL); + if (ret < 0) + ksft_exit_fail_msg( + "%s test: failed to wait on WEXITED process with pid %d and pidfd %d: %s\n", + test_name, parent_tid, pidfd, strerror(errno)); + + if (info.si_signo != SIGCHLD) + ksft_exit_fail_msg( + "%s test: unexpected si_signo value %d received after waiting on process with pid %d and pidfd %d: %s\n", + test_name, info.si_signo, parent_tid, pidfd, + strerror(errno)); + + if (info.si_code != CLD_KILLED) + ksft_exit_fail_msg( + "%s test: unexpected si_code value %d received after waiting on process with pid %d and pidfd %d: %s\n", + test_name, info.si_code, parent_tid, pidfd, + strerror(errno)); + + if (info.si_pid != parent_tid) + ksft_exit_fail_msg( + "%s test: unexpected si_pid value %d received after waiting on process with pid %d and pidfd %d: %s\n", + test_name, info.si_pid, parent_tid, pidfd, + strerror(errno)); + + close(pidfd); + + ksft_test_result_pass("%s test: Passed\n", test_name); + return 0; +} + +int main(int argc, char **argv) +{ + ksft_print_header(); + ksft_set_plan(2); + + test_pidfd_wait_simple(); + test_pidfd_wait_states(); + + return ksft_exit_pass(); +} -- cgit v1.2.3-59-g8ed1b From 2ec2f99abd2c75b507410c5def731fe1b483271b Mon Sep 17 00:00:00 2001 From: Suren Baghdasaryan Date: Fri, 26 Jul 2019 09:22:25 -0700 Subject: tests: move common definitions and functions into pidfd.h Move definitions and functions used across different pidfd tests into pidfd.h header. Signed-off-by: Suren Baghdasaryan Reviewed-by: Christian Brauner Link: https://lore.kernel.org/r/20190726162226.252750-1-surenb@google.com Signed-off-by: Christian Brauner --- tools/testing/selftests/pidfd/pidfd.h | 5 +++++ tools/testing/selftests/pidfd/pidfd_open_test.c | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/pidfd/pidfd.h b/tools/testing/selftests/pidfd/pidfd.h index 7d7d0ca05e0b..c6bc68329f4b 100644 --- a/tools/testing/selftests/pidfd/pidfd.h +++ b/tools/testing/selftests/pidfd/pidfd.h @@ -73,6 +73,11 @@ again: return WEXITSTATUS(status); } +static inline int sys_pidfd_open(pid_t pid, unsigned int flags) +{ + return syscall(__NR_pidfd_open, pid, flags); +} + static inline int sys_pidfd_send_signal(int pidfd, int sig, siginfo_t *info, unsigned int flags) { diff --git a/tools/testing/selftests/pidfd/pidfd_open_test.c b/tools/testing/selftests/pidfd/pidfd_open_test.c index 0377133dd6dc..b9fe75fc3e51 100644 --- a/tools/testing/selftests/pidfd/pidfd_open_test.c +++ b/tools/testing/selftests/pidfd/pidfd_open_test.c @@ -22,11 +22,6 @@ #include "pidfd.h" #include "../kselftest.h" -static inline int sys_pidfd_open(pid_t pid, unsigned int flags) -{ - return syscall(__NR_pidfd_open, pid, flags); -} - static int safe_int(const char *numstr, int *converted) { char *err = NULL; -- cgit v1.2.3-59-g8ed1b From aed5a8df3dbbd804409d40f821e0768891cfd5ab Mon Sep 17 00:00:00 2001 From: Suren Baghdasaryan Date: Fri, 26 Jul 2019 09:22:26 -0700 Subject: tests: add pidfd poll tests This adds testing for polling on pidfd of a process being killed. Test runs 10000 iterations by default to stress test pidfd polling functionality. It accepts an optional command-line parameter to override the number or iterations to run. Specifically, it tests for: - pidfd_open on a child process succeeds - pidfd_send_signal on a child process succeeds - polling on pidfd succeeds and returns exactly one event - returned event is POLLIN - event is received within 3 secs of the process being killed 10000 iterations was chosen because of the race condition being tested which is not consistently reproducible but usually is revealed after less than 2000 iterations. Reveals race fixed by commit b191d6491be6 ("pidfd: fix a poll race when setting exit_state") Signed-off-by: Suren Baghdasaryan Link: https://lore.kernel.org/r/20190726162226.252750-2-surenb@google.com Signed-off-by: Christian Brauner --- tools/testing/selftests/pidfd/.gitignore | 1 + tools/testing/selftests/pidfd/Makefile | 2 +- tools/testing/selftests/pidfd/pidfd_poll_test.c | 117 ++++++++++++++++++++++++ 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/pidfd/pidfd_poll_test.c (limited to 'tools') diff --git a/tools/testing/selftests/pidfd/.gitignore b/tools/testing/selftests/pidfd/.gitignore index 730ef9dc08cc..8d069490e17b 100644 --- a/tools/testing/selftests/pidfd/.gitignore +++ b/tools/testing/selftests/pidfd/.gitignore @@ -1,3 +1,4 @@ pidfd_open_test +pidfd_poll_test pidfd_test pidfd_wait diff --git a/tools/testing/selftests/pidfd/Makefile b/tools/testing/selftests/pidfd/Makefile index 7c97e890f353..464c9b76148f 100644 --- a/tools/testing/selftests/pidfd/Makefile +++ b/tools/testing/selftests/pidfd/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only CFLAGS += -g -I../../../../usr/include/ -lpthread -TEST_GEN_PROGS := pidfd_test pidfd_open_test pidfd_wait +TEST_GEN_PROGS := pidfd_test pidfd_open_test pidfd_poll_test pidfd_wait include ../lib.mk diff --git a/tools/testing/selftests/pidfd/pidfd_poll_test.c b/tools/testing/selftests/pidfd/pidfd_poll_test.c new file mode 100644 index 000000000000..4b115444dfe9 --- /dev/null +++ b/tools/testing/selftests/pidfd/pidfd_poll_test.c @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0 + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pidfd.h" +#include "../kselftest.h" + +static bool timeout; + +static void handle_alarm(int sig) +{ + timeout = true; +} + +int main(int argc, char **argv) +{ + struct pollfd fds; + int iter, nevents; + int nr_iterations = 10000; + + fds.events = POLLIN; + + if (argc > 2) + ksft_exit_fail_msg("Unexpected command line argument\n"); + + if (argc == 2) { + nr_iterations = atoi(argv[1]); + if (nr_iterations <= 0) + ksft_exit_fail_msg("invalid input parameter %s\n", + argv[1]); + } + + ksft_print_msg("running pidfd poll test for %d iterations\n", + nr_iterations); + + for (iter = 0; iter < nr_iterations; iter++) { + int pidfd; + int child_pid = fork(); + + if (child_pid < 0) { + if (errno == EAGAIN) { + iter--; + continue; + } + ksft_exit_fail_msg( + "%s - failed to fork a child process\n", + strerror(errno)); + } + + if (child_pid == 0) { + /* Child process just sleeps for a min and exits */ + sleep(60); + exit(EXIT_SUCCESS); + } + + /* Parent kills the child and waits for its death */ + pidfd = sys_pidfd_open(child_pid, 0); + if (pidfd < 0) + ksft_exit_fail_msg("%s - pidfd_open failed\n", + strerror(errno)); + + /* Setup 3 sec alarm - plenty of time */ + if (signal(SIGALRM, handle_alarm) == SIG_ERR) + ksft_exit_fail_msg("%s - signal failed\n", + strerror(errno)); + alarm(3); + + /* Send SIGKILL to the child */ + if (sys_pidfd_send_signal(pidfd, SIGKILL, NULL, 0)) + ksft_exit_fail_msg("%s - pidfd_send_signal failed\n", + strerror(errno)); + + /* Wait for the death notification */ + fds.fd = pidfd; + nevents = poll(&fds, 1, -1); + + /* Check for error conditions */ + if (nevents < 0) + ksft_exit_fail_msg("%s - poll failed\n", + strerror(errno)); + + if (nevents != 1) + ksft_exit_fail_msg("unexpected poll result: %d\n", + nevents); + + if (!(fds.revents & POLLIN)) + ksft_exit_fail_msg( + "unexpected event type received: 0x%x\n", + fds.revents); + + if (timeout) + ksft_exit_fail_msg( + "death notification wait timeout\n"); + + close(pidfd); + /* Wait for child to prevent zombies */ + if (waitpid(child_pid, NULL, 0) < 0) + ksft_exit_fail_msg("%s - waitpid failed\n", + strerror(errno)); + + } + + ksft_test_result_pass("pidfd poll test: pass\n"); + return ksft_exit_pass(); +} -- cgit v1.2.3-59-g8ed1b From 946152b3c5d6bab128db8eee226ec2665429b79c Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Tue, 6 Aug 2019 10:45:27 -0700 Subject: selftests/bpf: test_progs: switch to open_memstream Use open_memstream to override stdout during test execution. The copy of the original stdout is held in env.stdout and used to print subtest info and dump failed log. test_{v,}printf are now simple wrappers around stdout and will be removed in the next patch. v5: * fix -v crash by always setting env.std{in,err} (Alexei Starovoitov) * drop force_log check from stdio_hijack (Andrii Nakryiko) v4: * one field per line for stdout/stderr (Andrii Nakryiko) v3: * don't do strlen over log_buf, log_cnt has it already (Andrii Nakryiko) v2: * add ifdef __GLIBC__ around open_memstream (maybe pointless since we already depend on glibc for argp_parse) * hijack stderr as well (Andrii Nakryiko) * don't hijack for every test, do it once (Andrii Nakryiko) * log_cap -> log_size (Andrii Nakryiko) * do fseeko in a proper place (Andrii Nakryiko) * check open_memstream returned value (Andrii Nakryiko) Cc: Andrii Nakryiko Acked-by: Andrii Nakryiko Signed-off-by: Stanislav Fomichev Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/test_progs.c | 115 ++++++++++++++++--------------- tools/testing/selftests/bpf/test_progs.h | 3 +- 2 files changed, 62 insertions(+), 56 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index db00196c8315..6ea289ba307b 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -40,14 +40,20 @@ static bool should_run(struct test_selector *sel, int num, const char *name) static void dump_test_log(const struct prog_test_def *test, bool failed) { + if (stdout == env.stdout) + return; + + fflush(stdout); /* exports env.log_buf & env.log_cnt */ + if (env.verbose || test->force_log || failed) { if (env.log_cnt) { - fprintf(stdout, "%s", env.log_buf); + fprintf(env.stdout, "%s", env.log_buf); if (env.log_buf[env.log_cnt - 1] != '\n') - fprintf(stdout, "\n"); + fprintf(env.stdout, "\n"); } } - env.log_cnt = 0; + + fseeko(stdout, 0, SEEK_SET); /* rewind */ } void test__end_subtest() @@ -62,7 +68,7 @@ void test__end_subtest() dump_test_log(test, sub_error_cnt); - printf("#%d/%d %s:%s\n", + fprintf(env.stdout, "#%d/%d %s:%s\n", test->test_num, test->subtest_num, test->subtest_name, sub_error_cnt ? "FAIL" : "OK"); } @@ -79,7 +85,8 @@ bool test__start_subtest(const char *name) test->subtest_num++; if (!name || !name[0]) { - fprintf(stderr, "Subtest #%d didn't provide sub-test name!\n", + fprintf(env.stderr, + "Subtest #%d didn't provide sub-test name!\n", test->subtest_num); return false; } @@ -100,53 +107,7 @@ void test__force_log() { void test__vprintf(const char *fmt, va_list args) { - size_t rem_sz; - int ret = 0; - - if (env.verbose || (env.test && env.test->force_log)) { - vfprintf(stderr, fmt, args); - return; - } - -try_again: - rem_sz = env.log_cap - env.log_cnt; - if (rem_sz) { - va_list ap; - - va_copy(ap, args); - /* we reserved extra byte for \0 at the end */ - ret = vsnprintf(env.log_buf + env.log_cnt, rem_sz + 1, fmt, ap); - va_end(ap); - - if (ret < 0) { - env.log_buf[env.log_cnt] = '\0'; - fprintf(stderr, "failed to log w/ fmt '%s'\n", fmt); - return; - } - } - - if (!rem_sz || ret > rem_sz) { - size_t new_sz = env.log_cap * 3 / 2; - char *new_buf; - - if (new_sz < 4096) - new_sz = 4096; - if (new_sz < ret + env.log_cnt) - new_sz = ret + env.log_cnt; - - /* +1 for guaranteed space for terminating \0 */ - new_buf = realloc(env.log_buf, new_sz + 1); - if (!new_buf) { - fprintf(stderr, "failed to realloc log buffer: %d\n", - errno); - return; - } - env.log_buf = new_buf; - env.log_cap = new_sz; - goto try_again; - } - - env.log_cnt += ret; + vprintf(fmt, args); } void test__printf(const char *fmt, ...) @@ -477,6 +438,48 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) return 0; } +static void stdio_hijack(void) +{ +#ifdef __GLIBC__ + env.stdout = stdout; + env.stderr = stderr; + + if (env.verbose) { + /* nothing to do, output to stdout by default */ + return; + } + + /* stdout and stderr -> buffer */ + fflush(stdout); + + stdout = open_memstream(&env.log_buf, &env.log_cnt); + if (!stdout) { + stdout = env.stdout; + perror("open_memstream"); + return; + } + + stderr = stdout; +#endif +} + +static void stdio_restore(void) +{ +#ifdef __GLIBC__ + if (stdout == env.stdout) + return; + + fclose(stdout); + free(env.log_buf); + + env.log_buf = NULL; + env.log_cnt = 0; + + stdout = env.stdout; + stderr = env.stderr; +#endif +} + int main(int argc, char **argv) { static const struct argp argp = { @@ -496,6 +499,7 @@ int main(int argc, char **argv) env.jit_enabled = is_jit_enabled(); + stdio_hijack(); for (i = 0; i < prog_test_cnt; i++) { struct prog_test_def *test = &prog_test_defs[i]; int old_pass_cnt = pass_cnt; @@ -523,13 +527,14 @@ int main(int argc, char **argv) dump_test_log(test, test->error_cnt); - printf("#%d %s:%s\n", test->test_num, test->test_name, - test->error_cnt ? "FAIL" : "OK"); + fprintf(env.stdout, "#%d %s:%s\n", + test->test_num, test->test_name, + test->error_cnt ? "FAIL" : "OK"); } + stdio_restore(); printf("Summary: %d/%d PASSED, %d FAILED\n", env.succ_cnt, env.sub_succ_cnt, env.fail_cnt); - free(env.log_buf); free(env.test_selector.num_set); free(env.subtest_selector.num_set); diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h index afd14962456f..541f9eab5eed 100644 --- a/tools/testing/selftests/bpf/test_progs.h +++ b/tools/testing/selftests/bpf/test_progs.h @@ -56,9 +56,10 @@ struct test_env { bool jit_enabled; struct prog_test_def *test; + FILE *stdout; + FILE *stderr; char *log_buf; size_t log_cnt; - size_t log_cap; int succ_cnt; /* successful tests */ int sub_succ_cnt; /* successful sub-tests */ -- cgit v1.2.3-59-g8ed1b From 66bd2ec1e0d9781133eb1a14eddb68facc69d54b Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Tue, 6 Aug 2019 10:45:28 -0700 Subject: selftests/bpf: test_progs: test__printf -> printf Now that test__printf is a simple wraper around printf, let's drop it (and test__vprintf as well). Cc: Andrii Nakryiko Acked-by: Andrii Nakryiko Signed-off-by: Stanislav Fomichev Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c | 4 ++-- tools/testing/selftests/bpf/prog_tests/l4lb_all.c | 2 +- tools/testing/selftests/bpf/prog_tests/map_lock.c | 10 +++++----- tools/testing/selftests/bpf/prog_tests/send_signal.c | 4 ++-- tools/testing/selftests/bpf/prog_tests/spinlock.c | 2 +- .../selftests/bpf/prog_tests/stacktrace_build_id.c | 4 ++-- .../selftests/bpf/prog_tests/stacktrace_build_id_nmi.c | 4 ++-- tools/testing/selftests/bpf/prog_tests/xdp_noinline.c | 4 ++-- tools/testing/selftests/bpf/test_progs.c | 16 +--------------- tools/testing/selftests/bpf/test_progs.h | 10 ++++------ 10 files changed, 22 insertions(+), 38 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c b/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c index 0caf8eafa9eb..1a1eae356f81 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c @@ -5,13 +5,13 @@ static int libbpf_debug_print(enum libbpf_print_level level, const char *format, va_list args) { if (level != LIBBPF_DEBUG) { - test__vprintf(format, args); + vprintf(format, args); return 0; } if (!strstr(format, "verifier log")) return 0; - test__vprintf("%s", args); + vprintf("%s", args); return 0; } diff --git a/tools/testing/selftests/bpf/prog_tests/l4lb_all.c b/tools/testing/selftests/bpf/prog_tests/l4lb_all.c index 5ce572c03a5f..20ddca830e68 100644 --- a/tools/testing/selftests/bpf/prog_tests/l4lb_all.c +++ b/tools/testing/selftests/bpf/prog_tests/l4lb_all.c @@ -74,7 +74,7 @@ static void test_l4lb(const char *file) } if (bytes != MAGIC_BYTES * NUM_ITER * 2 || pkts != NUM_ITER * 2) { error_cnt++; - test__printf("test_l4lb:FAIL:stats %lld %lld\n", bytes, pkts); + printf("test_l4lb:FAIL:stats %lld %lld\n", bytes, pkts); } out: bpf_object__close(obj); diff --git a/tools/testing/selftests/bpf/prog_tests/map_lock.c b/tools/testing/selftests/bpf/prog_tests/map_lock.c index 2e78217ed3fd..ee99368c595c 100644 --- a/tools/testing/selftests/bpf/prog_tests/map_lock.c +++ b/tools/testing/selftests/bpf/prog_tests/map_lock.c @@ -9,12 +9,12 @@ static void *parallel_map_access(void *arg) for (i = 0; i < 10000; i++) { err = bpf_map_lookup_elem_flags(map_fd, &key, vars, BPF_F_LOCK); if (err) { - test__printf("lookup failed\n"); + printf("lookup failed\n"); error_cnt++; goto out; } if (vars[0] != 0) { - test__printf("lookup #%d var[0]=%d\n", i, vars[0]); + printf("lookup #%d var[0]=%d\n", i, vars[0]); error_cnt++; goto out; } @@ -22,8 +22,8 @@ static void *parallel_map_access(void *arg) for (j = 2; j < 17; j++) { if (vars[j] == rnd) continue; - test__printf("lookup #%d var[1]=%d var[%d]=%d\n", - i, rnd, j, vars[j]); + printf("lookup #%d var[1]=%d var[%d]=%d\n", + i, rnd, j, vars[j]); error_cnt++; goto out; } @@ -43,7 +43,7 @@ void test_map_lock(void) err = bpf_prog_load(file, BPF_PROG_TYPE_CGROUP_SKB, &obj, &prog_fd); if (err) { - test__printf("test_map_lock:bpf_prog_load errno %d\n", errno); + printf("test_map_lock:bpf_prog_load errno %d\n", errno); goto close_prog; } map_fd[0] = bpf_find_map(__func__, obj, "hash_map"); diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c index 461b423d0584..1575f0a1f586 100644 --- a/tools/testing/selftests/bpf/prog_tests/send_signal.c +++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c @@ -202,8 +202,8 @@ static int test_send_signal_nmi(void) -1 /* cpu */, -1 /* group_fd */, 0 /* flags */); if (pmu_fd == -1) { if (errno == ENOENT) { - test__printf("%s:SKIP:no PERF_COUNT_HW_CPU_CYCLES\n", - __func__); + printf("%s:SKIP:no PERF_COUNT_HW_CPU_CYCLES\n", + __func__); return 0; } /* Let the test fail with a more informative message */ diff --git a/tools/testing/selftests/bpf/prog_tests/spinlock.c b/tools/testing/selftests/bpf/prog_tests/spinlock.c index deb2db5b85b0..114ebe6a438e 100644 --- a/tools/testing/selftests/bpf/prog_tests/spinlock.c +++ b/tools/testing/selftests/bpf/prog_tests/spinlock.c @@ -12,7 +12,7 @@ void test_spinlock(void) err = bpf_prog_load(file, BPF_PROG_TYPE_CGROUP_SKB, &obj, &prog_fd); if (err) { - test__printf("test_spin_lock:bpf_prog_load errno %d\n", errno); + printf("test_spin_lock:bpf_prog_load errno %d\n", errno); goto close_prog; } for (i = 0; i < 4; i++) diff --git a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c index 356d2c017a9c..ac44fda84833 100644 --- a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c +++ b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c @@ -109,8 +109,8 @@ retry: if (build_id_matches < 1 && retry--) { bpf_link__destroy(link); bpf_object__close(obj); - test__printf("%s:WARN:Didn't find expected build ID from the map, retrying\n", - __func__); + printf("%s:WARN:Didn't find expected build ID from the map, retrying\n", + __func__); goto retry; } diff --git a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c index f44f2c159714..9557b7dfb782 100644 --- a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c +++ b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c @@ -140,8 +140,8 @@ retry: if (build_id_matches < 1 && retry--) { bpf_link__destroy(link); bpf_object__close(obj); - test__printf("%s:WARN:Didn't find expected build ID from the map, retrying\n", - __func__); + printf("%s:WARN:Didn't find expected build ID from the map, retrying\n", + __func__); goto retry; } diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_noinline.c b/tools/testing/selftests/bpf/prog_tests/xdp_noinline.c index b5404494b8aa..15f7c272edb0 100644 --- a/tools/testing/selftests/bpf/prog_tests/xdp_noinline.c +++ b/tools/testing/selftests/bpf/prog_tests/xdp_noinline.c @@ -75,8 +75,8 @@ void test_xdp_noinline(void) } if (bytes != MAGIC_BYTES * NUM_ITER * 2 || pkts != NUM_ITER * 2) { error_cnt++; - test__printf("test_xdp_noinline:FAIL:stats %lld %lld\n", - bytes, pkts); + printf("test_xdp_noinline:FAIL:stats %lld %lld\n", + bytes, pkts); } out: bpf_object__close(obj); diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index 6ea289ba307b..6c11c796ea1f 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -105,20 +105,6 @@ void test__force_log() { env.test->force_log = true; } -void test__vprintf(const char *fmt, va_list args) -{ - vprintf(fmt, args); -} - -void test__printf(const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - test__vprintf(fmt, args); - va_end(args); -} - struct ipv4_packet pkt_v4 = { .eth.h_proto = __bpf_constant_htons(ETH_P_IP), .iph.ihl = 5, @@ -310,7 +296,7 @@ static int libbpf_print_fn(enum libbpf_print_level level, { if (!env.very_verbose && level == LIBBPF_DEBUG) return 0; - test__vprintf(format, args); + vprintf(format, args); return 0; } diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h index 541f9eab5eed..37d427f5a1e5 100644 --- a/tools/testing/selftests/bpf/test_progs.h +++ b/tools/testing/selftests/bpf/test_progs.h @@ -70,8 +70,6 @@ extern int error_cnt; extern int pass_cnt; extern struct test_env env; -extern void test__printf(const char *fmt, ...); -extern void test__vprintf(const char *fmt, va_list args); extern void test__force_log(); extern bool test__start_subtest(const char *name); @@ -97,12 +95,12 @@ extern struct ipv6_packet pkt_v6; int __ret = !!(condition); \ if (__ret) { \ error_cnt++; \ - test__printf("%s:FAIL:%s ", __func__, tag); \ - test__printf(format); \ + printf("%s:FAIL:%s ", __func__, tag); \ + printf(format); \ } else { \ pass_cnt++; \ - test__printf("%s:PASS:%s %d nsec\n", \ - __func__, tag, duration); \ + printf("%s:PASS:%s %d nsec\n", \ + __func__, tag, duration); \ } \ __ret; \ }) -- cgit v1.2.3-59-g8ed1b From 16e910d4467ccdf1cae5035e71035e5f7197e77d Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Tue, 6 Aug 2019 10:45:29 -0700 Subject: selftests/bpf: test_progs: drop extra trailing tab Small (un)related cleanup. Cc: Andrii Nakryiko Acked-by: Andrii Nakryiko Signed-off-by: Stanislav Fomichev Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/test_progs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index 6c11c796ea1f..12895d03d58b 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -278,7 +278,7 @@ enum ARG_KEYS { ARG_VERIFIER_STATS = 's', ARG_VERBOSE = 'v', }; - + static const struct argp_option opts[] = { { "num", ARG_TEST_NUM, "NUM", 0, "Run test number NUM only " }, -- cgit v1.2.3-59-g8ed1b From ef20a9b27c66278ac2f85006db8ea11d5f61a781 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 7 Aug 2019 14:39:48 -0700 Subject: libbpf: add helpers for working with BTF types Add lots of frequently used helpers that simplify working with BTF types. Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov --- tools/lib/bpf/btf.h | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) (limited to 'tools') diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h index 88a52ae56fc6..2604dc099855 100644 --- a/tools/lib/bpf/btf.h +++ b/tools/lib/bpf/btf.h @@ -5,6 +5,7 @@ #define __LIBBPF_BTF_H #include +#include #include #ifdef __cplusplus @@ -120,6 +121,183 @@ LIBBPF_API void btf_dump__free(struct btf_dump *d); LIBBPF_API int btf_dump__dump_type(struct btf_dump *d, __u32 id); +/* + * A set of helpers for easier BTF types handling + */ +static inline __u16 btf_kind(const struct btf_type *t) +{ + return BTF_INFO_KIND(t->info); +} + +static inline __u16 btf_vlen(const struct btf_type *t) +{ + return BTF_INFO_VLEN(t->info); +} + +static inline bool btf_kflag(const struct btf_type *t) +{ + return BTF_INFO_KFLAG(t->info); +} + +static inline bool btf_is_int(const struct btf_type *t) +{ + return btf_kind(t) == BTF_KIND_INT; +} + +static inline bool btf_is_ptr(const struct btf_type *t) +{ + return btf_kind(t) == BTF_KIND_PTR; +} + +static inline bool btf_is_array(const struct btf_type *t) +{ + return btf_kind(t) == BTF_KIND_ARRAY; +} + +static inline bool btf_is_struct(const struct btf_type *t) +{ + return btf_kind(t) == BTF_KIND_STRUCT; +} + +static inline bool btf_is_union(const struct btf_type *t) +{ + return btf_kind(t) == BTF_KIND_UNION; +} + +static inline bool btf_is_composite(const struct btf_type *t) +{ + __u16 kind = btf_kind(t); + + return kind == BTF_KIND_STRUCT || kind == BTF_KIND_UNION; +} + +static inline bool btf_is_enum(const struct btf_type *t) +{ + return btf_kind(t) == BTF_KIND_ENUM; +} + +static inline bool btf_is_fwd(const struct btf_type *t) +{ + return btf_kind(t) == BTF_KIND_FWD; +} + +static inline bool btf_is_typedef(const struct btf_type *t) +{ + return btf_kind(t) == BTF_KIND_TYPEDEF; +} + +static inline bool btf_is_volatile(const struct btf_type *t) +{ + return btf_kind(t) == BTF_KIND_VOLATILE; +} + +static inline bool btf_is_const(const struct btf_type *t) +{ + return btf_kind(t) == BTF_KIND_CONST; +} + +static inline bool btf_is_restrict(const struct btf_type *t) +{ + return btf_kind(t) == BTF_KIND_RESTRICT; +} + +static inline bool btf_is_mod(const struct btf_type *t) +{ + __u16 kind = btf_kind(t); + + return kind == BTF_KIND_VOLATILE || + kind == BTF_KIND_CONST || + kind == BTF_KIND_RESTRICT; +} + +static inline bool btf_is_func(const struct btf_type *t) +{ + return btf_kind(t) == BTF_KIND_FUNC; +} + +static inline bool btf_is_func_proto(const struct btf_type *t) +{ + return btf_kind(t) == BTF_KIND_FUNC_PROTO; +} + +static inline bool btf_is_var(const struct btf_type *t) +{ + return btf_kind(t) == BTF_KIND_VAR; +} + +static inline bool btf_is_datasec(const struct btf_type *t) +{ + return btf_kind(t) == BTF_KIND_DATASEC; +} + +static inline __u8 btf_int_encoding(const struct btf_type *t) +{ + return BTF_INT_ENCODING(*(__u32 *)(t + 1)); +} + +static inline __u8 btf_int_offset(const struct btf_type *t) +{ + return BTF_INT_OFFSET(*(__u32 *)(t + 1)); +} + +static inline __u8 btf_int_bits(const struct btf_type *t) +{ + return BTF_INT_BITS(*(__u32 *)(t + 1)); +} + +static inline struct btf_array *btf_array(const struct btf_type *t) +{ + return (struct btf_array *)(t + 1); +} + +static inline struct btf_enum *btf_enum(const struct btf_type *t) +{ + return (struct btf_enum *)(t + 1); +} + +static inline struct btf_member *btf_members(const struct btf_type *t) +{ + return (struct btf_member *)(t + 1); +} + +/* Get bit offset of a member with specified index. */ +static inline __u32 btf_member_bit_offset(const struct btf_type *t, + __u32 member_idx) +{ + const struct btf_member *m = btf_members(t) + member_idx; + bool kflag = btf_kflag(t); + + return kflag ? BTF_MEMBER_BIT_OFFSET(m->offset) : m->offset; +} +/* + * Get bitfield size of a member, assuming t is BTF_KIND_STRUCT or + * BTF_KIND_UNION. If member is not a bitfield, zero is returned. + */ +static inline __u32 btf_member_bitfield_size(const struct btf_type *t, + __u32 member_idx) +{ + const struct btf_member *m = btf_members(t) + member_idx; + bool kflag = btf_kflag(t); + + return kflag ? BTF_MEMBER_BITFIELD_SIZE(m->offset) : 0; +} + +static inline struct btf_param *btf_params(const struct btf_type *t) +{ + return (struct btf_param *)(t + 1); +} + +static inline struct btf_var *btf_var(const struct btf_type *t) +{ + return (struct btf_var *)(t + 1); +} + +static inline struct btf_var_secinfo * +btf_var_secinfos(const struct btf_type *t) +{ + return (struct btf_var_secinfo *)(t + 1); +} + #ifdef __cplusplus } /* extern "C" */ #endif -- cgit v1.2.3-59-g8ed1b From b03bc6853c0e0c97da842434e8056f1b9d9a1f4a Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 7 Aug 2019 14:39:49 -0700 Subject: libbpf: convert libbpf code to use new btf helpers Simplify code by relying on newly added BTF helper functions. Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov --- tools/lib/bpf/btf.c | 181 ++++++++++++++++++++++------------------------- tools/lib/bpf/btf_dump.c | 138 ++++++++++++------------------------ tools/lib/bpf/libbpf.c | 60 ++++++++-------- 3 files changed, 158 insertions(+), 221 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 467224feb43b..1cd4e5d67158 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -19,13 +19,6 @@ #define BTF_MAX_NR_TYPES 0x7fffffff #define BTF_MAX_STR_OFFSET 0x7fffffff -#define IS_MODIFIER(k) (((k) == BTF_KIND_TYPEDEF) || \ - ((k) == BTF_KIND_VOLATILE) || \ - ((k) == BTF_KIND_CONST) || \ - ((k) == BTF_KIND_RESTRICT)) - -#define IS_VAR(k) ((k) == BTF_KIND_VAR) - static struct btf_type btf_void; struct btf { @@ -192,9 +185,9 @@ static int btf_parse_str_sec(struct btf *btf) static int btf_type_size(struct btf_type *t) { int base_size = sizeof(struct btf_type); - __u16 vlen = BTF_INFO_VLEN(t->info); + __u16 vlen = btf_vlen(t); - switch (BTF_INFO_KIND(t->info)) { + switch (btf_kind(t)) { case BTF_KIND_FWD: case BTF_KIND_CONST: case BTF_KIND_VOLATILE: @@ -219,7 +212,7 @@ static int btf_type_size(struct btf_type *t) case BTF_KIND_DATASEC: return base_size + vlen * sizeof(struct btf_var_secinfo); default: - pr_debug("Unsupported BTF_KIND:%u\n", BTF_INFO_KIND(t->info)); + pr_debug("Unsupported BTF_KIND:%u\n", btf_kind(t)); return -EINVAL; } } @@ -263,7 +256,7 @@ const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 type_id) static bool btf_type_is_void(const struct btf_type *t) { - return t == &btf_void || BTF_INFO_KIND(t->info) == BTF_KIND_FWD; + return t == &btf_void || btf_is_fwd(t); } static bool btf_type_is_void_or_null(const struct btf_type *t) @@ -284,7 +277,7 @@ __s64 btf__resolve_size(const struct btf *btf, __u32 type_id) t = btf__type_by_id(btf, type_id); for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t); i++) { - switch (BTF_INFO_KIND(t->info)) { + switch (btf_kind(t)) { case BTF_KIND_INT: case BTF_KIND_STRUCT: case BTF_KIND_UNION: @@ -303,7 +296,7 @@ __s64 btf__resolve_size(const struct btf *btf, __u32 type_id) type_id = t->type; break; case BTF_KIND_ARRAY: - array = (const struct btf_array *)(t + 1); + array = btf_array(t); if (nelems && array->nelems > UINT32_MAX / nelems) return -E2BIG; nelems *= array->nelems; @@ -334,8 +327,7 @@ int btf__resolve_type(const struct btf *btf, __u32 type_id) t = btf__type_by_id(btf, type_id); while (depth < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t) && - (IS_MODIFIER(BTF_INFO_KIND(t->info)) || - IS_VAR(BTF_INFO_KIND(t->info)))) { + (btf_is_mod(t) || btf_is_typedef(t) || btf_is_var(t))) { type_id = t->type; t = btf__type_by_id(btf, type_id); depth++; @@ -554,11 +546,11 @@ static int compare_vsi_off(const void *_a, const void *_b) static int btf_fixup_datasec(struct bpf_object *obj, struct btf *btf, struct btf_type *t) { - __u32 size = 0, off = 0, i, vars = BTF_INFO_VLEN(t->info); + __u32 size = 0, off = 0, i, vars = btf_vlen(t); const char *name = btf__name_by_offset(btf, t->name_off); const struct btf_type *t_var; struct btf_var_secinfo *vsi; - struct btf_var *var; + const struct btf_var *var; int ret; if (!name) { @@ -574,12 +566,11 @@ static int btf_fixup_datasec(struct bpf_object *obj, struct btf *btf, t->size = size; - for (i = 0, vsi = (struct btf_var_secinfo *)(t + 1); - i < vars; i++, vsi++) { + for (i = 0, vsi = btf_var_secinfos(t); i < vars; i++, vsi++) { t_var = btf__type_by_id(btf, vsi->type); - var = (struct btf_var *)(t_var + 1); + var = btf_var(t_var); - if (BTF_INFO_KIND(t_var->info) != BTF_KIND_VAR) { + if (!btf_is_var(t_var)) { pr_debug("Non-VAR type seen in section %s\n", name); return -EINVAL; } @@ -595,7 +586,8 @@ static int btf_fixup_datasec(struct bpf_object *obj, struct btf *btf, ret = bpf_object__variable_offset(obj, name, &off); if (ret) { - pr_debug("No offset found in symbol table for VAR %s\n", name); + pr_debug("No offset found in symbol table for VAR %s\n", + name); return -ENOENT; } @@ -619,7 +611,7 @@ int btf__finalize_data(struct bpf_object *obj, struct btf *btf) * is section size and global variable offset. We use * the info from the ELF itself for this purpose. */ - if (BTF_INFO_KIND(t->info) == BTF_KIND_DATASEC) { + if (btf_is_datasec(t)) { err = btf_fixup_datasec(obj, btf, t); if (err) break; @@ -774,14 +766,13 @@ int btf__get_map_kv_tids(const struct btf *btf, const char *map_name, return -EINVAL; } - if (BTF_INFO_KIND(container_type->info) != BTF_KIND_STRUCT || - BTF_INFO_VLEN(container_type->info) < 2) { + if (!btf_is_struct(container_type) || btf_vlen(container_type) < 2) { pr_warning("map:%s container_name:%s is an invalid container struct\n", map_name, container_name); return -EINVAL; } - key = (struct btf_member *)(container_type + 1); + key = btf_members(container_type); value = key + 1; key_size = btf__resolve_size(btf, key->type); @@ -1440,10 +1431,9 @@ static struct btf_dedup *btf_dedup_new(struct btf *btf, struct btf_ext *btf_ext, d->map[0] = 0; for (i = 1; i <= btf->nr_types; i++) { struct btf_type *t = d->btf->types[i]; - __u16 kind = BTF_INFO_KIND(t->info); /* VAR and DATASEC are never deduped and are self-canonical */ - if (kind == BTF_KIND_VAR || kind == BTF_KIND_DATASEC) + if (btf_is_var(t) || btf_is_datasec(t)) d->map[i] = i; else d->map[i] = BTF_UNPROCESSED_ID; @@ -1484,11 +1474,11 @@ static int btf_for_each_str_off(struct btf_dedup *d, str_off_fn_t fn, void *ctx) if (r) return r; - switch (BTF_INFO_KIND(t->info)) { + switch (btf_kind(t)) { case BTF_KIND_STRUCT: case BTF_KIND_UNION: { - struct btf_member *m = (struct btf_member *)(t + 1); - __u16 vlen = BTF_INFO_VLEN(t->info); + struct btf_member *m = btf_members(t); + __u16 vlen = btf_vlen(t); for (j = 0; j < vlen; j++) { r = fn(&m->name_off, ctx); @@ -1499,8 +1489,8 @@ static int btf_for_each_str_off(struct btf_dedup *d, str_off_fn_t fn, void *ctx) break; } case BTF_KIND_ENUM: { - struct btf_enum *m = (struct btf_enum *)(t + 1); - __u16 vlen = BTF_INFO_VLEN(t->info); + struct btf_enum *m = btf_enum(t); + __u16 vlen = btf_vlen(t); for (j = 0; j < vlen; j++) { r = fn(&m->name_off, ctx); @@ -1511,8 +1501,8 @@ static int btf_for_each_str_off(struct btf_dedup *d, str_off_fn_t fn, void *ctx) break; } case BTF_KIND_FUNC_PROTO: { - struct btf_param *m = (struct btf_param *)(t + 1); - __u16 vlen = BTF_INFO_VLEN(t->info); + struct btf_param *m = btf_params(t); + __u16 vlen = btf_vlen(t); for (j = 0; j < vlen; j++) { r = fn(&m->name_off, ctx); @@ -1801,16 +1791,16 @@ static long btf_hash_enum(struct btf_type *t) /* Check structural equality of two ENUMs. */ static bool btf_equal_enum(struct btf_type *t1, struct btf_type *t2) { - struct btf_enum *m1, *m2; + const struct btf_enum *m1, *m2; __u16 vlen; int i; if (!btf_equal_common(t1, t2)) return false; - vlen = BTF_INFO_VLEN(t1->info); - m1 = (struct btf_enum *)(t1 + 1); - m2 = (struct btf_enum *)(t2 + 1); + vlen = btf_vlen(t1); + m1 = btf_enum(t1); + m2 = btf_enum(t2); for (i = 0; i < vlen; i++) { if (m1->name_off != m2->name_off || m1->val != m2->val) return false; @@ -1822,8 +1812,7 @@ static bool btf_equal_enum(struct btf_type *t1, struct btf_type *t2) static inline bool btf_is_enum_fwd(struct btf_type *t) { - return BTF_INFO_KIND(t->info) == BTF_KIND_ENUM && - BTF_INFO_VLEN(t->info) == 0; + return btf_is_enum(t) && btf_vlen(t) == 0; } static bool btf_compat_enum(struct btf_type *t1, struct btf_type *t2) @@ -1843,8 +1832,8 @@ static bool btf_compat_enum(struct btf_type *t1, struct btf_type *t2) */ static long btf_hash_struct(struct btf_type *t) { - struct btf_member *member = (struct btf_member *)(t + 1); - __u32 vlen = BTF_INFO_VLEN(t->info); + const struct btf_member *member = btf_members(t); + __u32 vlen = btf_vlen(t); long h = btf_hash_common(t); int i; @@ -1864,16 +1853,16 @@ static long btf_hash_struct(struct btf_type *t) */ static bool btf_shallow_equal_struct(struct btf_type *t1, struct btf_type *t2) { - struct btf_member *m1, *m2; + const struct btf_member *m1, *m2; __u16 vlen; int i; if (!btf_equal_common(t1, t2)) return false; - vlen = BTF_INFO_VLEN(t1->info); - m1 = (struct btf_member *)(t1 + 1); - m2 = (struct btf_member *)(t2 + 1); + vlen = btf_vlen(t1); + m1 = btf_members(t1); + m2 = btf_members(t2); for (i = 0; i < vlen; i++) { if (m1->name_off != m2->name_off || m1->offset != m2->offset) return false; @@ -1890,7 +1879,7 @@ static bool btf_shallow_equal_struct(struct btf_type *t1, struct btf_type *t2) */ static long btf_hash_array(struct btf_type *t) { - struct btf_array *info = (struct btf_array *)(t + 1); + const struct btf_array *info = btf_array(t); long h = btf_hash_common(t); h = hash_combine(h, info->type); @@ -1908,13 +1897,13 @@ static long btf_hash_array(struct btf_type *t) */ static bool btf_equal_array(struct btf_type *t1, struct btf_type *t2) { - struct btf_array *info1, *info2; + const struct btf_array *info1, *info2; if (!btf_equal_common(t1, t2)) return false; - info1 = (struct btf_array *)(t1 + 1); - info2 = (struct btf_array *)(t2 + 1); + info1 = btf_array(t1); + info2 = btf_array(t2); return info1->type == info2->type && info1->index_type == info2->index_type && info1->nelems == info2->nelems; @@ -1927,14 +1916,10 @@ static bool btf_equal_array(struct btf_type *t1, struct btf_type *t2) */ static bool btf_compat_array(struct btf_type *t1, struct btf_type *t2) { - struct btf_array *info1, *info2; - if (!btf_equal_common(t1, t2)) return false; - info1 = (struct btf_array *)(t1 + 1); - info2 = (struct btf_array *)(t2 + 1); - return info1->nelems == info2->nelems; + return btf_array(t1)->nelems == btf_array(t2)->nelems; } /* @@ -1944,8 +1929,8 @@ static bool btf_compat_array(struct btf_type *t1, struct btf_type *t2) */ static long btf_hash_fnproto(struct btf_type *t) { - struct btf_param *member = (struct btf_param *)(t + 1); - __u16 vlen = BTF_INFO_VLEN(t->info); + const struct btf_param *member = btf_params(t); + __u16 vlen = btf_vlen(t); long h = btf_hash_common(t); int i; @@ -1966,16 +1951,16 @@ static long btf_hash_fnproto(struct btf_type *t) */ static bool btf_equal_fnproto(struct btf_type *t1, struct btf_type *t2) { - struct btf_param *m1, *m2; + const struct btf_param *m1, *m2; __u16 vlen; int i; if (!btf_equal_common(t1, t2)) return false; - vlen = BTF_INFO_VLEN(t1->info); - m1 = (struct btf_param *)(t1 + 1); - m2 = (struct btf_param *)(t2 + 1); + vlen = btf_vlen(t1); + m1 = btf_params(t1); + m2 = btf_params(t2); for (i = 0; i < vlen; i++) { if (m1->name_off != m2->name_off || m1->type != m2->type) return false; @@ -1992,7 +1977,7 @@ static bool btf_equal_fnproto(struct btf_type *t1, struct btf_type *t2) */ static bool btf_compat_fnproto(struct btf_type *t1, struct btf_type *t2) { - struct btf_param *m1, *m2; + const struct btf_param *m1, *m2; __u16 vlen; int i; @@ -2000,9 +1985,9 @@ static bool btf_compat_fnproto(struct btf_type *t1, struct btf_type *t2) if (t1->name_off != t2->name_off || t1->info != t2->info) return false; - vlen = BTF_INFO_VLEN(t1->info); - m1 = (struct btf_param *)(t1 + 1); - m2 = (struct btf_param *)(t2 + 1); + vlen = btf_vlen(t1); + m1 = btf_params(t1); + m2 = btf_params(t2); for (i = 0; i < vlen; i++) { if (m1->name_off != m2->name_off) return false; @@ -2028,7 +2013,7 @@ static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id) __u32 cand_id; long h; - switch (BTF_INFO_KIND(t->info)) { + switch (btf_kind(t)) { case BTF_KIND_CONST: case BTF_KIND_VOLATILE: case BTF_KIND_RESTRICT: @@ -2141,13 +2126,13 @@ static uint32_t resolve_fwd_id(struct btf_dedup *d, uint32_t type_id) { __u32 orig_type_id = type_id; - if (BTF_INFO_KIND(d->btf->types[type_id]->info) != BTF_KIND_FWD) + if (!btf_is_fwd(d->btf->types[type_id])) return type_id; while (is_type_mapped(d, type_id) && d->map[type_id] != type_id) type_id = d->map[type_id]; - if (BTF_INFO_KIND(d->btf->types[type_id]->info) != BTF_KIND_FWD) + if (!btf_is_fwd(d->btf->types[type_id])) return type_id; return orig_type_id; @@ -2156,7 +2141,7 @@ static uint32_t resolve_fwd_id(struct btf_dedup *d, uint32_t type_id) static inline __u16 btf_fwd_kind(struct btf_type *t) { - return BTF_INFO_KFLAG(t->info) ? BTF_KIND_UNION : BTF_KIND_STRUCT; + return btf_kflag(t) ? BTF_KIND_UNION : BTF_KIND_STRUCT; } /* @@ -2277,8 +2262,8 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id, cand_type = d->btf->types[cand_id]; canon_type = d->btf->types[canon_id]; - cand_kind = BTF_INFO_KIND(cand_type->info); - canon_kind = BTF_INFO_KIND(canon_type->info); + cand_kind = btf_kind(cand_type); + canon_kind = btf_kind(canon_type); if (cand_type->name_off != canon_type->name_off) return 0; @@ -2327,12 +2312,12 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id, return btf_dedup_is_equiv(d, cand_type->type, canon_type->type); case BTF_KIND_ARRAY: { - struct btf_array *cand_arr, *canon_arr; + const struct btf_array *cand_arr, *canon_arr; if (!btf_compat_array(cand_type, canon_type)) return 0; - cand_arr = (struct btf_array *)(cand_type + 1); - canon_arr = (struct btf_array *)(canon_type + 1); + cand_arr = btf_array(cand_type); + canon_arr = btf_array(canon_type); eq = btf_dedup_is_equiv(d, cand_arr->index_type, canon_arr->index_type); if (eq <= 0) @@ -2342,14 +2327,14 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id, case BTF_KIND_STRUCT: case BTF_KIND_UNION: { - struct btf_member *cand_m, *canon_m; + const struct btf_member *cand_m, *canon_m; __u16 vlen; if (!btf_shallow_equal_struct(cand_type, canon_type)) return 0; - vlen = BTF_INFO_VLEN(cand_type->info); - cand_m = (struct btf_member *)(cand_type + 1); - canon_m = (struct btf_member *)(canon_type + 1); + vlen = btf_vlen(cand_type); + cand_m = btf_members(cand_type); + canon_m = btf_members(canon_type); for (i = 0; i < vlen; i++) { eq = btf_dedup_is_equiv(d, cand_m->type, canon_m->type); if (eq <= 0) @@ -2362,7 +2347,7 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id, } case BTF_KIND_FUNC_PROTO: { - struct btf_param *cand_p, *canon_p; + const struct btf_param *cand_p, *canon_p; __u16 vlen; if (!btf_compat_fnproto(cand_type, canon_type)) @@ -2370,9 +2355,9 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id, eq = btf_dedup_is_equiv(d, cand_type->type, canon_type->type); if (eq <= 0) return eq; - vlen = BTF_INFO_VLEN(cand_type->info); - cand_p = (struct btf_param *)(cand_type + 1); - canon_p = (struct btf_param *)(canon_type + 1); + vlen = btf_vlen(cand_type); + cand_p = btf_params(cand_type); + canon_p = btf_params(canon_type); for (i = 0; i < vlen; i++) { eq = btf_dedup_is_equiv(d, cand_p->type, canon_p->type); if (eq <= 0) @@ -2427,8 +2412,8 @@ static void btf_dedup_merge_hypot_map(struct btf_dedup *d) targ_type_id = d->hypot_map[cand_type_id]; t_id = resolve_type_id(d, targ_type_id); c_id = resolve_type_id(d, cand_type_id); - t_kind = BTF_INFO_KIND(d->btf->types[t_id]->info); - c_kind = BTF_INFO_KIND(d->btf->types[c_id]->info); + t_kind = btf_kind(d->btf->types[t_id]); + c_kind = btf_kind(d->btf->types[c_id]); /* * Resolve FWD into STRUCT/UNION. * It's ok to resolve FWD into STRUCT/UNION that's not yet @@ -2497,7 +2482,7 @@ static int btf_dedup_struct_type(struct btf_dedup *d, __u32 type_id) return 0; t = d->btf->types[type_id]; - kind = BTF_INFO_KIND(t->info); + kind = btf_kind(t); if (kind != BTF_KIND_STRUCT && kind != BTF_KIND_UNION) return 0; @@ -2592,7 +2577,7 @@ static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id) t = d->btf->types[type_id]; d->map[type_id] = BTF_IN_PROGRESS_ID; - switch (BTF_INFO_KIND(t->info)) { + switch (btf_kind(t)) { case BTF_KIND_CONST: case BTF_KIND_VOLATILE: case BTF_KIND_RESTRICT: @@ -2616,7 +2601,7 @@ static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id) break; case BTF_KIND_ARRAY: { - struct btf_array *info = (struct btf_array *)(t + 1); + struct btf_array *info = btf_array(t); ref_type_id = btf_dedup_ref_type(d, info->type); if (ref_type_id < 0) @@ -2650,8 +2635,8 @@ static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id) return ref_type_id; t->type = ref_type_id; - vlen = BTF_INFO_VLEN(t->info); - param = (struct btf_param *)(t + 1); + vlen = btf_vlen(t); + param = btf_params(t); for (i = 0; i < vlen; i++) { ref_type_id = btf_dedup_ref_type(d, param->type); if (ref_type_id < 0) @@ -2791,7 +2776,7 @@ static int btf_dedup_remap_type(struct btf_dedup *d, __u32 type_id) struct btf_type *t = d->btf->types[type_id]; int i, r; - switch (BTF_INFO_KIND(t->info)) { + switch (btf_kind(t)) { case BTF_KIND_INT: case BTF_KIND_ENUM: break; @@ -2811,7 +2796,7 @@ static int btf_dedup_remap_type(struct btf_dedup *d, __u32 type_id) break; case BTF_KIND_ARRAY: { - struct btf_array *arr_info = (struct btf_array *)(t + 1); + struct btf_array *arr_info = btf_array(t); r = btf_dedup_remap_type_id(d, arr_info->type); if (r < 0) @@ -2826,8 +2811,8 @@ static int btf_dedup_remap_type(struct btf_dedup *d, __u32 type_id) case BTF_KIND_STRUCT: case BTF_KIND_UNION: { - struct btf_member *member = (struct btf_member *)(t + 1); - __u16 vlen = BTF_INFO_VLEN(t->info); + struct btf_member *member = btf_members(t); + __u16 vlen = btf_vlen(t); for (i = 0; i < vlen; i++) { r = btf_dedup_remap_type_id(d, member->type); @@ -2840,8 +2825,8 @@ static int btf_dedup_remap_type(struct btf_dedup *d, __u32 type_id) } case BTF_KIND_FUNC_PROTO: { - struct btf_param *param = (struct btf_param *)(t + 1); - __u16 vlen = BTF_INFO_VLEN(t->info); + struct btf_param *param = btf_params(t); + __u16 vlen = btf_vlen(t); r = btf_dedup_remap_type_id(d, t->type); if (r < 0) @@ -2859,8 +2844,8 @@ static int btf_dedup_remap_type(struct btf_dedup *d, __u32 type_id) } case BTF_KIND_DATASEC: { - struct btf_var_secinfo *var = (struct btf_var_secinfo *)(t + 1); - __u16 vlen = BTF_INFO_VLEN(t->info); + struct btf_var_secinfo *var = btf_var_secinfos(t); + __u16 vlen = btf_vlen(t); for (i = 0; i < vlen; i++) { r = btf_dedup_remap_type_id(d, var->type); diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c index 7065bb5b2752..715967762312 100644 --- a/tools/lib/bpf/btf_dump.c +++ b/tools/lib/bpf/btf_dump.c @@ -100,21 +100,6 @@ static bool str_equal_fn(const void *a, const void *b, void *ctx) return strcmp(a, b) == 0; } -static __u16 btf_kind_of(const struct btf_type *t) -{ - return BTF_INFO_KIND(t->info); -} - -static __u16 btf_vlen_of(const struct btf_type *t) -{ - return BTF_INFO_VLEN(t->info); -} - -static bool btf_kflag_of(const struct btf_type *t) -{ - return BTF_INFO_KFLAG(t->info); -} - static const char *btf_name_of(const struct btf_dump *d, __u32 name_off) { return btf__name_by_offset(d->btf, name_off); @@ -349,7 +334,7 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr) */ struct btf_dump_type_aux_state *tstate = &d->type_states[id]; const struct btf_type *t; - __u16 kind, vlen; + __u16 vlen; int err, i; /* return true, letting typedefs know that it's ok to be emitted */ @@ -357,18 +342,16 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr) return 1; t = btf__type_by_id(d->btf, id); - kind = btf_kind_of(t); if (tstate->order_state == ORDERING) { /* type loop, but resolvable through fwd declaration */ - if ((kind == BTF_KIND_STRUCT || kind == BTF_KIND_UNION) && - through_ptr && t->name_off != 0) + if (btf_is_composite(t) && through_ptr && t->name_off != 0) return 0; pr_warning("unsatisfiable type cycle, id:[%u]\n", id); return -ELOOP; } - switch (kind) { + switch (btf_kind(t)) { case BTF_KIND_INT: tstate->order_state = ORDERED; return 0; @@ -378,14 +361,12 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr) tstate->order_state = ORDERED; return err; - case BTF_KIND_ARRAY: { - const struct btf_array *a = (void *)(t + 1); + case BTF_KIND_ARRAY: + return btf_dump_order_type(d, btf_array(t)->type, through_ptr); - return btf_dump_order_type(d, a->type, through_ptr); - } case BTF_KIND_STRUCT: case BTF_KIND_UNION: { - const struct btf_member *m = (void *)(t + 1); + const struct btf_member *m = btf_members(t); /* * struct/union is part of strong link, only if it's embedded * (so no ptr in a path) or it's anonymous (so has to be @@ -396,7 +377,7 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr) tstate->order_state = ORDERING; - vlen = btf_vlen_of(t); + vlen = btf_vlen(t); for (i = 0; i < vlen; i++, m++) { err = btf_dump_order_type(d, m->type, false); if (err < 0) @@ -447,7 +428,7 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr) return btf_dump_order_type(d, t->type, through_ptr); case BTF_KIND_FUNC_PROTO: { - const struct btf_param *p = (void *)(t + 1); + const struct btf_param *p = btf_params(t); bool is_strong; err = btf_dump_order_type(d, t->type, through_ptr); @@ -455,7 +436,7 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr) return err; is_strong = err > 0; - vlen = btf_vlen_of(t); + vlen = btf_vlen(t); for (i = 0; i < vlen; i++, p++) { err = btf_dump_order_type(d, p->type, through_ptr); if (err < 0) @@ -553,7 +534,7 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id) return; t = btf__type_by_id(d->btf, id); - kind = btf_kind_of(t); + kind = btf_kind(t); if (top_level_def && t->name_off == 0) { pr_warning("unexpected nameless definition, id:[%u]\n", id); @@ -618,12 +599,9 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id) case BTF_KIND_RESTRICT: btf_dump_emit_type(d, t->type, cont_id); break; - case BTF_KIND_ARRAY: { - const struct btf_array *a = (void *)(t + 1); - - btf_dump_emit_type(d, a->type, cont_id); + case BTF_KIND_ARRAY: + btf_dump_emit_type(d, btf_array(t)->type, cont_id); break; - } case BTF_KIND_FWD: btf_dump_emit_fwd_def(d, id, t); btf_dump_printf(d, ";\n\n"); @@ -656,8 +634,8 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id) * applicable */ if (top_level_def || t->name_off == 0) { - const struct btf_member *m = (void *)(t + 1); - __u16 vlen = btf_vlen_of(t); + const struct btf_member *m = btf_members(t); + __u16 vlen = btf_vlen(t); int i, new_cont_id; new_cont_id = t->name_off == 0 ? cont_id : id; @@ -678,8 +656,8 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id) } break; case BTF_KIND_FUNC_PROTO: { - const struct btf_param *p = (void *)(t + 1); - __u16 vlen = btf_vlen_of(t); + const struct btf_param *p = btf_params(t); + __u16 vlen = btf_vlen(t); int i; btf_dump_emit_type(d, t->type, cont_id); @@ -696,7 +674,7 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id) static int btf_align_of(const struct btf *btf, __u32 id) { const struct btf_type *t = btf__type_by_id(btf, id); - __u16 kind = btf_kind_of(t); + __u16 kind = btf_kind(t); switch (kind) { case BTF_KIND_INT: @@ -709,15 +687,12 @@ static int btf_align_of(const struct btf *btf, __u32 id) case BTF_KIND_CONST: case BTF_KIND_RESTRICT: return btf_align_of(btf, t->type); - case BTF_KIND_ARRAY: { - const struct btf_array *a = (void *)(t + 1); - - return btf_align_of(btf, a->type); - } + case BTF_KIND_ARRAY: + return btf_align_of(btf, btf_array(t)->type); case BTF_KIND_STRUCT: case BTF_KIND_UNION: { - const struct btf_member *m = (void *)(t + 1); - __u16 vlen = btf_vlen_of(t); + const struct btf_member *m = btf_members(t); + __u16 vlen = btf_vlen(t); int i, align = 1; for (i = 0; i < vlen; i++, m++) @@ -726,7 +701,7 @@ static int btf_align_of(const struct btf *btf, __u32 id) return align; } default: - pr_warning("unsupported BTF_KIND:%u\n", btf_kind_of(t)); + pr_warning("unsupported BTF_KIND:%u\n", btf_kind(t)); return 1; } } @@ -737,20 +712,18 @@ static bool btf_is_struct_packed(const struct btf *btf, __u32 id, const struct btf_member *m; int align, i, bit_sz; __u16 vlen; - bool kflag; align = btf_align_of(btf, id); /* size of a non-packed struct has to be a multiple of its alignment*/ if (t->size % align) return true; - m = (void *)(t + 1); - kflag = btf_kflag_of(t); - vlen = btf_vlen_of(t); + m = btf_members(t); + vlen = btf_vlen(t); /* all non-bitfield fields have to be naturally aligned */ for (i = 0; i < vlen; i++, m++) { align = btf_align_of(btf, m->type); - bit_sz = kflag ? BTF_MEMBER_BITFIELD_SIZE(m->offset) : 0; + bit_sz = btf_member_bitfield_size(t, i); if (bit_sz == 0 && m->offset % (8 * align) != 0) return true; } @@ -807,7 +780,7 @@ static void btf_dump_emit_struct_fwd(struct btf_dump *d, __u32 id, const struct btf_type *t) { btf_dump_printf(d, "%s %s", - btf_kind_of(t) == BTF_KIND_STRUCT ? "struct" : "union", + btf_is_struct(t) ? "struct" : "union", btf_dump_type_name(d, id)); } @@ -816,12 +789,11 @@ static void btf_dump_emit_struct_def(struct btf_dump *d, const struct btf_type *t, int lvl) { - const struct btf_member *m = (void *)(t + 1); - bool kflag = btf_kflag_of(t), is_struct; + const struct btf_member *m = btf_members(t); + bool is_struct = btf_is_struct(t); int align, i, packed, off = 0; - __u16 vlen = btf_vlen_of(t); + __u16 vlen = btf_vlen(t); - is_struct = btf_kind_of(t) == BTF_KIND_STRUCT; packed = is_struct ? btf_is_struct_packed(d->btf, id, t) : 0; align = packed ? 1 : btf_align_of(d->btf, id); @@ -835,8 +807,8 @@ static void btf_dump_emit_struct_def(struct btf_dump *d, int m_off, m_sz; fname = btf_name_of(d, m->name_off); - m_sz = kflag ? BTF_MEMBER_BITFIELD_SIZE(m->offset) : 0; - m_off = kflag ? BTF_MEMBER_BIT_OFFSET(m->offset) : m->offset; + m_sz = btf_member_bitfield_size(t, i); + m_off = btf_member_bit_offset(t, i); align = packed ? 1 : btf_align_of(d->btf, m->type); btf_dump_emit_bit_padding(d, off, m_off, m_sz, align, lvl + 1); @@ -870,8 +842,8 @@ static void btf_dump_emit_enum_def(struct btf_dump *d, __u32 id, const struct btf_type *t, int lvl) { - const struct btf_enum *v = (void *)(t+1); - __u16 vlen = btf_vlen_of(t); + const struct btf_enum *v = btf_enum(t); + __u16 vlen = btf_vlen(t); const char *name; size_t dup_cnt; int i; @@ -905,7 +877,7 @@ static void btf_dump_emit_fwd_def(struct btf_dump *d, __u32 id, { const char *name = btf_dump_type_name(d, id); - if (btf_kflag_of(t)) + if (btf_kflag(t)) btf_dump_printf(d, "union %s", name); else btf_dump_printf(d, "struct %s", name); @@ -987,7 +959,6 @@ static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id, struct id_stack decl_stack; const struct btf_type *t; int err, stack_start; - __u16 kind; stack_start = d->decl_stack_cnt; for (;;) { @@ -1008,8 +979,7 @@ static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id, break; t = btf__type_by_id(d->btf, id); - kind = btf_kind_of(t); - switch (kind) { + switch (btf_kind(t)) { case BTF_KIND_PTR: case BTF_KIND_VOLATILE: case BTF_KIND_CONST: @@ -1017,12 +987,9 @@ static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id, case BTF_KIND_FUNC_PROTO: id = t->type; break; - case BTF_KIND_ARRAY: { - const struct btf_array *a = (void *)(t + 1); - - id = a->type; + case BTF_KIND_ARRAY: + id = btf_array(t)->type; break; - } case BTF_KIND_INT: case BTF_KIND_ENUM: case BTF_KIND_FWD: @@ -1032,7 +999,7 @@ static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id, goto done; default: pr_warning("unexpected type in decl chain, kind:%u, id:[%u]\n", - kind, id); + btf_kind(t), id); goto done; } } @@ -1070,7 +1037,7 @@ static void btf_dump_emit_mods(struct btf_dump *d, struct id_stack *decl_stack) id = decl_stack->ids[decl_stack->cnt - 1]; t = btf__type_by_id(d->btf, id); - switch (btf_kind_of(t)) { + switch (btf_kind(t)) { case BTF_KIND_VOLATILE: btf_dump_printf(d, "volatile "); break; @@ -1087,20 +1054,6 @@ static void btf_dump_emit_mods(struct btf_dump *d, struct id_stack *decl_stack) } } -static bool btf_is_mod_kind(const struct btf *btf, __u32 id) -{ - const struct btf_type *t = btf__type_by_id(btf, id); - - switch (btf_kind_of(t)) { - case BTF_KIND_VOLATILE: - case BTF_KIND_CONST: - case BTF_KIND_RESTRICT: - return true; - default: - return false; - } -} - static void btf_dump_emit_name(const struct btf_dump *d, const char *name, bool last_was_ptr) { @@ -1139,7 +1092,7 @@ static void btf_dump_emit_type_chain(struct btf_dump *d, } t = btf__type_by_id(d->btf, id); - kind = btf_kind_of(t); + kind = btf_kind(t); switch (kind) { case BTF_KIND_INT: @@ -1185,7 +1138,7 @@ static void btf_dump_emit_type_chain(struct btf_dump *d, btf_dump_printf(d, " restrict"); break; case BTF_KIND_ARRAY: { - const struct btf_array *a = (void *)(t + 1); + const struct btf_array *a = btf_array(t); const struct btf_type *next_t; __u32 next_id; bool multidim; @@ -1201,7 +1154,8 @@ static void btf_dump_emit_type_chain(struct btf_dump *d, */ while (decls->cnt) { next_id = decls->ids[decls->cnt - 1]; - if (btf_is_mod_kind(d->btf, next_id)) + next_t = btf__type_by_id(d->btf, next_id); + if (btf_is_mod(next_t)) decls->cnt--; else break; @@ -1214,7 +1168,7 @@ static void btf_dump_emit_type_chain(struct btf_dump *d, } next_t = btf__type_by_id(d->btf, next_id); - multidim = btf_kind_of(next_t) == BTF_KIND_ARRAY; + multidim = btf_is_array(next_t); /* we need space if we have named non-pointer */ if (fname[0] && !last_was_ptr) btf_dump_printf(d, " "); @@ -1228,8 +1182,8 @@ static void btf_dump_emit_type_chain(struct btf_dump *d, return; } case BTF_KIND_FUNC_PROTO: { - const struct btf_param *p = (void *)(t + 1); - __u16 vlen = btf_vlen_of(t); + const struct btf_param *p = btf_params(t); + __u16 vlen = btf_vlen(t); int i; btf_dump_emit_mods(d, decls); diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index ead915aec349..8fc62b6b1cd6 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -1049,9 +1049,9 @@ static bool get_map_field_int(const char *map_name, const struct btf *btf, const struct btf_array *arr_info; const struct btf_type *arr_t; - if (BTF_INFO_KIND(t->info) != BTF_KIND_PTR) { + if (!btf_is_ptr(t)) { pr_warning("map '%s': attr '%s': expected PTR, got %u.\n", - map_name, name, BTF_INFO_KIND(t->info)); + map_name, name, btf_kind(t)); return false; } @@ -1061,12 +1061,12 @@ static bool get_map_field_int(const char *map_name, const struct btf *btf, map_name, name, t->type); return false; } - if (BTF_INFO_KIND(arr_t->info) != BTF_KIND_ARRAY) { + if (!btf_is_array(arr_t)) { pr_warning("map '%s': attr '%s': expected ARRAY, got %u.\n", - map_name, name, BTF_INFO_KIND(arr_t->info)); + map_name, name, btf_kind(arr_t)); return false; } - arr_info = (const void *)(arr_t + 1); + arr_info = btf_array(arr_t); *res = arr_info->nelems; return true; } @@ -1084,11 +1084,11 @@ static int bpf_object__init_user_btf_map(struct bpf_object *obj, struct bpf_map *map; int vlen, i; - vi = (const struct btf_var_secinfo *)(const void *)(sec + 1) + var_idx; + vi = btf_var_secinfos(sec) + var_idx; var = btf__type_by_id(obj->btf, vi->type); - var_extra = (const void *)(var + 1); + var_extra = btf_var(var); map_name = btf__name_by_offset(obj->btf, var->name_off); - vlen = BTF_INFO_VLEN(var->info); + vlen = btf_vlen(var); if (map_name == NULL || map_name[0] == '\0') { pr_warning("map #%d: empty name.\n", var_idx); @@ -1098,9 +1098,9 @@ static int bpf_object__init_user_btf_map(struct bpf_object *obj, pr_warning("map '%s' BTF data is corrupted.\n", map_name); return -EINVAL; } - if (BTF_INFO_KIND(var->info) != BTF_KIND_VAR) { + if (!btf_is_var(var)) { pr_warning("map '%s': unexpected var kind %u.\n", - map_name, BTF_INFO_KIND(var->info)); + map_name, btf_kind(var)); return -EINVAL; } if (var_extra->linkage != BTF_VAR_GLOBAL_ALLOCATED && @@ -1111,9 +1111,9 @@ static int bpf_object__init_user_btf_map(struct bpf_object *obj, } def = skip_mods_and_typedefs(obj->btf, var->type); - if (BTF_INFO_KIND(def->info) != BTF_KIND_STRUCT) { + if (!btf_is_struct(def)) { pr_warning("map '%s': unexpected def kind %u.\n", - map_name, BTF_INFO_KIND(var->info)); + map_name, btf_kind(var)); return -EINVAL; } if (def->size > vi->size) { @@ -1136,8 +1136,8 @@ static int bpf_object__init_user_btf_map(struct bpf_object *obj, pr_debug("map '%s': at sec_idx %d, offset %zu.\n", map_name, map->sec_idx, map->sec_offset); - vlen = BTF_INFO_VLEN(def->info); - m = (const void *)(def + 1); + vlen = btf_vlen(def); + m = btf_members(def); for (i = 0; i < vlen; i++, m++) { const char *name = btf__name_by_offset(obj->btf, m->name_off); @@ -1187,9 +1187,9 @@ static int bpf_object__init_user_btf_map(struct bpf_object *obj, map_name, m->type); return -EINVAL; } - if (BTF_INFO_KIND(t->info) != BTF_KIND_PTR) { + if (!btf_is_ptr(t)) { pr_warning("map '%s': key spec is not PTR: %u.\n", - map_name, BTF_INFO_KIND(t->info)); + map_name, btf_kind(t)); return -EINVAL; } sz = btf__resolve_size(obj->btf, t->type); @@ -1230,9 +1230,9 @@ static int bpf_object__init_user_btf_map(struct bpf_object *obj, map_name, m->type); return -EINVAL; } - if (BTF_INFO_KIND(t->info) != BTF_KIND_PTR) { + if (!btf_is_ptr(t)) { pr_warning("map '%s': value spec is not PTR: %u.\n", - map_name, BTF_INFO_KIND(t->info)); + map_name, btf_kind(t)); return -EINVAL; } sz = btf__resolve_size(obj->btf, t->type); @@ -1293,7 +1293,7 @@ static int bpf_object__init_user_btf_maps(struct bpf_object *obj, bool strict) nr_types = btf__get_nr_types(obj->btf); for (i = 1; i <= nr_types; i++) { t = btf__type_by_id(obj->btf, i); - if (BTF_INFO_KIND(t->info) != BTF_KIND_DATASEC) + if (!btf_is_datasec(t)) continue; name = btf__name_by_offset(obj->btf, t->name_off); if (strcmp(name, MAPS_ELF_SEC) == 0) { @@ -1307,7 +1307,7 @@ static int bpf_object__init_user_btf_maps(struct bpf_object *obj, bool strict) return -ENOENT; } - vlen = BTF_INFO_VLEN(sec->info); + vlen = btf_vlen(sec); for (i = 0; i < vlen; i++) { err = bpf_object__init_user_btf_map(obj, sec, i, obj->efile.btf_maps_shndx, @@ -1368,24 +1368,22 @@ static void bpf_object__sanitize_btf(struct bpf_object *obj) struct btf *btf = obj->btf; struct btf_type *t; int i, j, vlen; - __u16 kind; if (!obj->btf || (has_func && has_datasec)) return; for (i = 1; i <= btf__get_nr_types(btf); i++) { t = (struct btf_type *)btf__type_by_id(btf, i); - kind = BTF_INFO_KIND(t->info); - if (!has_datasec && kind == BTF_KIND_VAR) { + if (!has_datasec && btf_is_var(t)) { /* replace VAR with INT */ t->info = BTF_INFO_ENC(BTF_KIND_INT, 0, 0); t->size = sizeof(int); - *(int *)(t+1) = BTF_INT_ENC(0, 0, 32); - } else if (!has_datasec && kind == BTF_KIND_DATASEC) { + *(int *)(t + 1) = BTF_INT_ENC(0, 0, 32); + } else if (!has_datasec && btf_is_datasec(t)) { /* replace DATASEC with STRUCT */ - struct btf_var_secinfo *v = (void *)(t + 1); - struct btf_member *m = (void *)(t + 1); + const struct btf_var_secinfo *v = btf_var_secinfos(t); + struct btf_member *m = btf_members(t); struct btf_type *vt; char *name; @@ -1396,7 +1394,7 @@ static void bpf_object__sanitize_btf(struct bpf_object *obj) name++; } - vlen = BTF_INFO_VLEN(t->info); + vlen = btf_vlen(t); t->info = BTF_INFO_ENC(BTF_KIND_STRUCT, 0, vlen); for (j = 0; j < vlen; j++, v++, m++) { /* order of field assignments is important */ @@ -1406,12 +1404,12 @@ static void bpf_object__sanitize_btf(struct bpf_object *obj) vt = (void *)btf__type_by_id(btf, v->type); m->name_off = vt->name_off; } - } else if (!has_func && kind == BTF_KIND_FUNC_PROTO) { + } else if (!has_func && btf_is_func_proto(t)) { /* replace FUNC_PROTO with ENUM */ - vlen = BTF_INFO_VLEN(t->info); + vlen = btf_vlen(t); t->info = BTF_INFO_ENC(BTF_KIND_ENUM, 0, vlen); t->size = sizeof(__u32); /* kernel enforced */ - } else if (!has_func && kind == BTF_KIND_FUNC) { + } else if (!has_func && btf_is_func(t)) { /* replace FUNC with TYPEDEF */ t->info = BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0); } -- cgit v1.2.3-59-g8ed1b From 4cedc0dad9b5bf55c4180c833be35e27e5d6cdbb Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 7 Aug 2019 14:39:50 -0700 Subject: libbpf: add .BTF.ext offset relocation section loading Add support for BPF CO-RE offset relocations. Add section/record iteration macros for .BTF.ext. These macro are useful for iterating over each .BTF.ext record, either for dumping out contents or later for BPF CO-RE relocation handling. To enable other parts of libbpf to work with .BTF.ext contents, moved a bunch of type definitions into libbpf_internal.h. Signed-off-by: Andrii Nakryiko Acked-by: Song Liu Signed-off-by: Alexei Starovoitov --- tools/lib/bpf/btf.c | 69 +++++++++++--------------- tools/lib/bpf/btf.h | 4 ++ tools/lib/bpf/libbpf_internal.h | 105 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+), 42 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 1cd4e5d67158..aacb7608f02d 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -35,47 +35,6 @@ struct btf { int fd; }; -struct btf_ext_info { - /* - * info points to the individual info section (e.g. func_info and - * line_info) from the .BTF.ext. It does not include the __u32 rec_size. - */ - void *info; - __u32 rec_size; - __u32 len; -}; - -struct btf_ext { - union { - struct btf_ext_header *hdr; - void *data; - }; - struct btf_ext_info func_info; - struct btf_ext_info line_info; - __u32 data_size; -}; - -struct btf_ext_info_sec { - __u32 sec_name_off; - __u32 num_info; - /* Followed by num_info * record_size number of bytes */ - __u8 data[0]; -}; - -/* The minimum bpf_func_info checked by the loader */ -struct bpf_func_info_min { - __u32 insn_off; - __u32 type_id; -}; - -/* The minimum bpf_line_info checked by the loader */ -struct bpf_line_info_min { - __u32 insn_off; - __u32 file_name_off; - __u32 line_off; - __u32 line_col; -}; - static inline __u64 ptr_to_u64(const void *ptr) { return (__u64) (unsigned long) ptr; @@ -822,6 +781,9 @@ static int btf_ext_setup_info(struct btf_ext *btf_ext, /* The start of the info sec (including the __u32 record_size). */ void *info; + if (ext_sec->len == 0) + return 0; + if (ext_sec->off & 0x03) { pr_debug(".BTF.ext %s section is not aligned to 4 bytes\n", ext_sec->desc); @@ -925,11 +887,24 @@ static int btf_ext_setup_line_info(struct btf_ext *btf_ext) return btf_ext_setup_info(btf_ext, ¶m); } +static int btf_ext_setup_offset_reloc(struct btf_ext *btf_ext) +{ + struct btf_ext_sec_setup_param param = { + .off = btf_ext->hdr->offset_reloc_off, + .len = btf_ext->hdr->offset_reloc_len, + .min_rec_size = sizeof(struct bpf_offset_reloc), + .ext_info = &btf_ext->offset_reloc_info, + .desc = "offset_reloc", + }; + + return btf_ext_setup_info(btf_ext, ¶m); +} + static int btf_ext_parse_hdr(__u8 *data, __u32 data_size) { const struct btf_ext_header *hdr = (struct btf_ext_header *)data; - if (data_size < offsetof(struct btf_ext_header, func_info_off) || + if (data_size < offsetofend(struct btf_ext_header, hdr_len) || data_size < hdr->hdr_len) { pr_debug("BTF.ext header not found"); return -EINVAL; @@ -987,6 +962,9 @@ struct btf_ext *btf_ext__new(__u8 *data, __u32 size) } memcpy(btf_ext->data, data, size); + if (btf_ext->hdr->hdr_len < + offsetofend(struct btf_ext_header, line_info_len)) + goto done; err = btf_ext_setup_func_info(btf_ext); if (err) goto done; @@ -995,6 +973,13 @@ struct btf_ext *btf_ext__new(__u8 *data, __u32 size) if (err) goto done; + if (btf_ext->hdr->hdr_len < + offsetofend(struct btf_ext_header, offset_reloc_len)) + goto done; + err = btf_ext_setup_offset_reloc(btf_ext); + if (err) + goto done; + done: if (err) { btf_ext__free(btf_ext); diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h index 2604dc099855..9cb44b4fbf60 100644 --- a/tools/lib/bpf/btf.h +++ b/tools/lib/bpf/btf.h @@ -58,6 +58,10 @@ struct btf_ext_header { __u32 func_info_len; __u32 line_info_off; __u32 line_info_len; + + /* optional part of .BTF.ext header */ + __u32 offset_reloc_off; + __u32 offset_reloc_len; }; LIBBPF_API void btf__free(struct btf *btf); diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h index 2ac29bd36226..2e83a34f8c79 100644 --- a/tools/lib/bpf/libbpf_internal.h +++ b/tools/lib/bpf/libbpf_internal.h @@ -29,6 +29,10 @@ #ifndef max # define max(x, y) ((x) < (y) ? (y) : (x)) #endif +#ifndef offsetofend +# define offsetofend(TYPE, FIELD) \ + (offsetof(TYPE, FIELD) + sizeof(((TYPE *)0)->FIELD)) +#endif extern void libbpf_print(enum libbpf_print_level level, const char *format, ...) @@ -46,4 +50,105 @@ do { \ int libbpf__load_raw_btf(const char *raw_types, size_t types_len, const char *str_sec, size_t str_len); +struct btf_ext_info { + /* + * info points to the individual info section (e.g. func_info and + * line_info) from the .BTF.ext. It does not include the __u32 rec_size. + */ + void *info; + __u32 rec_size; + __u32 len; +}; + +#define for_each_btf_ext_sec(seg, sec) \ + for (sec = (seg)->info; \ + (void *)sec < (seg)->info + (seg)->len; \ + sec = (void *)sec + sizeof(struct btf_ext_info_sec) + \ + (seg)->rec_size * sec->num_info) + +#define for_each_btf_ext_rec(seg, sec, i, rec) \ + for (i = 0, rec = (void *)&(sec)->data; \ + i < (sec)->num_info; \ + i++, rec = (void *)rec + (seg)->rec_size) + +struct btf_ext { + union { + struct btf_ext_header *hdr; + void *data; + }; + struct btf_ext_info func_info; + struct btf_ext_info line_info; + struct btf_ext_info offset_reloc_info; + __u32 data_size; +}; + +struct btf_ext_info_sec { + __u32 sec_name_off; + __u32 num_info; + /* Followed by num_info * record_size number of bytes */ + __u8 data[0]; +}; + +/* The minimum bpf_func_info checked by the loader */ +struct bpf_func_info_min { + __u32 insn_off; + __u32 type_id; +}; + +/* The minimum bpf_line_info checked by the loader */ +struct bpf_line_info_min { + __u32 insn_off; + __u32 file_name_off; + __u32 line_off; + __u32 line_col; +}; + +/* The minimum bpf_offset_reloc checked by the loader + * + * Offset relocation captures the following data: + * - insn_off - instruction offset (in bytes) within a BPF program that needs + * its insn->imm field to be relocated with actual offset; + * - type_id - BTF type ID of the "root" (containing) entity of a relocatable + * offset; + * - access_str_off - offset into corresponding .BTF string section. String + * itself encodes an accessed field using a sequence of field and array + * indicies, separated by colon (:). It's conceptually very close to LLVM's + * getelementptr ([0]) instruction's arguments for identifying offset to + * a field. + * + * Example to provide a better feel. + * + * struct sample { + * int a; + * struct { + * int b[10]; + * }; + * }; + * + * struct sample *s = ...; + * int x = &s->a; // encoded as "0:0" (a is field #0) + * int y = &s->b[5]; // encoded as "0:1:0:5" (anon struct is field #1, + * // b is field #0 inside anon struct, accessing elem #5) + * int z = &s[10]->b; // encoded as "10:1" (ptr is used as an array) + * + * type_id for all relocs in this example will capture BTF type id of + * `struct sample`. + * + * Such relocation is emitted when using __builtin_preserve_access_index() + * Clang built-in, passing expression that captures field address, e.g.: + * + * bpf_probe_read(&dst, sizeof(dst), + * __builtin_preserve_access_index(&src->a.b.c)); + * + * In this case Clang will emit offset relocation recording necessary data to + * be able to find offset of embedded `a.b.c` field within `src` struct. + * + * [0] https://llvm.org/docs/LangRef.html#getelementptr-instruction + */ +struct bpf_offset_reloc { + __u32 insn_off; + __u32 type_id; + __u32 access_str_off; +}; + #endif /* __LIBBPF_LIBBPF_INTERNAL_H */ -- cgit v1.2.3-59-g8ed1b From ddc7c3042614e273044f698d2beab25cc3842d45 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 7 Aug 2019 14:39:51 -0700 Subject: libbpf: implement BPF CO-RE offset relocation algorithm This patch implements the core logic for BPF CO-RE offsets relocations. Every instruction that needs to be relocated has corresponding bpf_offset_reloc as part of BTF.ext. Relocations are performed by trying to match recorded "local" relocation spec against potentially many compatible "target" types, creating corresponding spec. Details of the algorithm are noted in corresponding comments in the code. Signed-off-by: Andrii Nakryiko Acked-by: Song Liu Signed-off-by: Alexei Starovoitov --- tools/lib/bpf/libbpf.c | 881 ++++++++++++++++++++++++++++++++++++++++++++++++- tools/lib/bpf/libbpf.h | 1 + 2 files changed, 864 insertions(+), 18 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 8fc62b6b1cd6..3abf2dd1b3b5 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,7 @@ #include "btf.h" #include "str_error.h" #include "libbpf_internal.h" +#include "hashmap.h" #ifndef EM_BPF #define EM_BPF 247 @@ -1015,23 +1017,21 @@ static int bpf_object__init_user_maps(struct bpf_object *obj, bool strict) return 0; } -static const struct btf_type *skip_mods_and_typedefs(const struct btf *btf, - __u32 id) +static const struct btf_type * +skip_mods_and_typedefs(const struct btf *btf, __u32 id, __u32 *res_id) { const struct btf_type *t = btf__type_by_id(btf, id); - while (true) { - switch (BTF_INFO_KIND(t->info)) { - case BTF_KIND_VOLATILE: - case BTF_KIND_CONST: - case BTF_KIND_RESTRICT: - case BTF_KIND_TYPEDEF: - t = btf__type_by_id(btf, t->type); - break; - default: - return t; - } + if (res_id) + *res_id = id; + + while (btf_is_mod(t) || btf_is_typedef(t)) { + if (res_id) + *res_id = t->type; + t = btf__type_by_id(btf, t->type); } + + return t; } /* @@ -1044,7 +1044,7 @@ static const struct btf_type *skip_mods_and_typedefs(const struct btf *btf, static bool get_map_field_int(const char *map_name, const struct btf *btf, const struct btf_type *def, const struct btf_member *m, __u32 *res) { - const struct btf_type *t = skip_mods_and_typedefs(btf, m->type); + const struct btf_type *t = skip_mods_and_typedefs(btf, m->type, NULL); const char *name = btf__name_by_offset(btf, m->name_off); const struct btf_array *arr_info; const struct btf_type *arr_t; @@ -1110,7 +1110,7 @@ static int bpf_object__init_user_btf_map(struct bpf_object *obj, return -EOPNOTSUPP; } - def = skip_mods_and_typedefs(obj->btf, var->type); + def = skip_mods_and_typedefs(obj->btf, var->type, NULL); if (!btf_is_struct(def)) { pr_warning("map '%s': unexpected def kind %u.\n", map_name, btf_kind(var)); @@ -2290,6 +2290,844 @@ bpf_program_reloc_btf_ext(struct bpf_program *prog, struct bpf_object *obj, return 0; } +#define BPF_CORE_SPEC_MAX_LEN 64 + +/* represents BPF CO-RE field or array element accessor */ +struct bpf_core_accessor { + __u32 type_id; /* struct/union type or array element type */ + __u32 idx; /* field index or array index */ + const char *name; /* field name or NULL for array accessor */ +}; + +struct bpf_core_spec { + const struct btf *btf; + /* high-level spec: named fields and array indices only */ + struct bpf_core_accessor spec[BPF_CORE_SPEC_MAX_LEN]; + /* high-level spec length */ + int len; + /* raw, low-level spec: 1-to-1 with accessor spec string */ + int raw_spec[BPF_CORE_SPEC_MAX_LEN]; + /* raw spec length */ + int raw_len; + /* field byte offset represented by spec */ + __u32 offset; +}; + +static bool str_is_empty(const char *s) +{ + return !s || !s[0]; +} + +/* + * Turn bpf_offset_reloc into a low- and high-level spec representation, + * validating correctness along the way, as well as calculating resulting + * field offset (in bytes), specified by accessor string. Low-level spec + * captures every single level of nestedness, including traversing anonymous + * struct/union members. High-level one only captures semantically meaningful + * "turning points": named fields and array indicies. + * E.g., for this case: + * + * struct sample { + * int __unimportant; + * struct { + * int __1; + * int __2; + * int a[7]; + * }; + * }; + * + * struct sample *s = ...; + * + * int x = &s->a[3]; // access string = '0:1:2:3' + * + * Low-level spec has 1:1 mapping with each element of access string (it's + * just a parsed access string representation): [0, 1, 2, 3]. + * + * High-level spec will capture only 3 points: + * - intial zero-index access by pointer (&s->... is the same as &s[0]...); + * - field 'a' access (corresponds to '2' in low-level spec); + * - array element #3 access (corresponds to '3' in low-level spec). + * + */ +static int bpf_core_spec_parse(const struct btf *btf, + __u32 type_id, + const char *spec_str, + struct bpf_core_spec *spec) +{ + int access_idx, parsed_len, i; + const struct btf_type *t; + const char *name; + __u32 id; + __s64 sz; + + if (str_is_empty(spec_str) || *spec_str == ':') + return -EINVAL; + + memset(spec, 0, sizeof(*spec)); + spec->btf = btf; + + /* parse spec_str="0:1:2:3:4" into array raw_spec=[0, 1, 2, 3, 4] */ + while (*spec_str) { + if (*spec_str == ':') + ++spec_str; + if (sscanf(spec_str, "%d%n", &access_idx, &parsed_len) != 1) + return -EINVAL; + if (spec->raw_len == BPF_CORE_SPEC_MAX_LEN) + return -E2BIG; + spec_str += parsed_len; + spec->raw_spec[spec->raw_len++] = access_idx; + } + + if (spec->raw_len == 0) + return -EINVAL; + + /* first spec value is always reloc type array index */ + t = skip_mods_and_typedefs(btf, type_id, &id); + if (!t) + return -EINVAL; + + access_idx = spec->raw_spec[0]; + spec->spec[0].type_id = id; + spec->spec[0].idx = access_idx; + spec->len++; + + sz = btf__resolve_size(btf, id); + if (sz < 0) + return sz; + spec->offset = access_idx * sz; + + for (i = 1; i < spec->raw_len; i++) { + t = skip_mods_and_typedefs(btf, id, &id); + if (!t) + return -EINVAL; + + access_idx = spec->raw_spec[i]; + + if (btf_is_composite(t)) { + const struct btf_member *m; + __u32 offset; + + if (access_idx >= btf_vlen(t)) + return -EINVAL; + if (btf_member_bitfield_size(t, access_idx)) + return -EINVAL; + + offset = btf_member_bit_offset(t, access_idx); + if (offset % 8) + return -EINVAL; + spec->offset += offset / 8; + + m = btf_members(t) + access_idx; + if (m->name_off) { + name = btf__name_by_offset(btf, m->name_off); + if (str_is_empty(name)) + return -EINVAL; + + spec->spec[spec->len].type_id = id; + spec->spec[spec->len].idx = access_idx; + spec->spec[spec->len].name = name; + spec->len++; + } + + id = m->type; + } else if (btf_is_array(t)) { + const struct btf_array *a = btf_array(t); + + t = skip_mods_and_typedefs(btf, a->type, &id); + if (!t || access_idx >= a->nelems) + return -EINVAL; + + spec->spec[spec->len].type_id = id; + spec->spec[spec->len].idx = access_idx; + spec->len++; + + sz = btf__resolve_size(btf, id); + if (sz < 0) + return sz; + spec->offset += access_idx * sz; + } else { + pr_warning("relo for [%u] %s (at idx %d) captures type [%d] of unexpected kind %d\n", + type_id, spec_str, i, id, btf_kind(t)); + return -EINVAL; + } + } + + return 0; +} + +static bool bpf_core_is_flavor_sep(const char *s) +{ + /* check X___Y name pattern, where X and Y are not underscores */ + return s[0] != '_' && /* X */ + s[1] == '_' && s[2] == '_' && s[3] == '_' && /* ___ */ + s[4] != '_'; /* Y */ +} + +/* Given 'some_struct_name___with_flavor' return the length of a name prefix + * before last triple underscore. Struct name part after last triple + * underscore is ignored by BPF CO-RE relocation during relocation matching. + */ +static size_t bpf_core_essential_name_len(const char *name) +{ + size_t n = strlen(name); + int i; + + for (i = n - 5; i >= 0; i--) { + if (bpf_core_is_flavor_sep(name + i)) + return i + 1; + } + return n; +} + +/* dynamically sized list of type IDs */ +struct ids_vec { + __u32 *data; + int len; +}; + +static void bpf_core_free_cands(struct ids_vec *cand_ids) +{ + free(cand_ids->data); + free(cand_ids); +} + +static struct ids_vec *bpf_core_find_cands(const struct btf *local_btf, + __u32 local_type_id, + const struct btf *targ_btf) +{ + size_t local_essent_len, targ_essent_len; + const char *local_name, *targ_name; + const struct btf_type *t; + struct ids_vec *cand_ids; + __u32 *new_ids; + int i, err, n; + + t = btf__type_by_id(local_btf, local_type_id); + if (!t) + return ERR_PTR(-EINVAL); + + local_name = btf__name_by_offset(local_btf, t->name_off); + if (str_is_empty(local_name)) + return ERR_PTR(-EINVAL); + local_essent_len = bpf_core_essential_name_len(local_name); + + cand_ids = calloc(1, sizeof(*cand_ids)); + if (!cand_ids) + return ERR_PTR(-ENOMEM); + + n = btf__get_nr_types(targ_btf); + for (i = 1; i <= n; i++) { + t = btf__type_by_id(targ_btf, i); + targ_name = btf__name_by_offset(targ_btf, t->name_off); + if (str_is_empty(targ_name)) + continue; + + targ_essent_len = bpf_core_essential_name_len(targ_name); + if (targ_essent_len != local_essent_len) + continue; + + if (strncmp(local_name, targ_name, local_essent_len) == 0) { + pr_debug("[%d] %s: found candidate [%d] %s\n", + local_type_id, local_name, i, targ_name); + new_ids = realloc(cand_ids->data, cand_ids->len + 1); + if (!new_ids) { + err = -ENOMEM; + goto err_out; + } + cand_ids->data = new_ids; + cand_ids->data[cand_ids->len++] = i; + } + } + return cand_ids; +err_out: + bpf_core_free_cands(cand_ids); + return ERR_PTR(err); +} + +/* Check two types for compatibility, skipping const/volatile/restrict and + * typedefs, to ensure we are relocating offset to the compatible entities: + * - any two STRUCTs/UNIONs are compatible and can be mixed; + * - any two FWDs are compatible; + * - any two PTRs are always compatible; + * - for ENUMs, check sizes, names are ignored; + * - for INT, size and bitness should match, signedness is ignored; + * - for ARRAY, dimensionality is ignored, element types are checked for + * compatibility recursively; + * - everything else shouldn't be ever a target of relocation. + * These rules are not set in stone and probably will be adjusted as we get + * more experience with using BPF CO-RE relocations. + */ +static int bpf_core_fields_are_compat(const struct btf *local_btf, + __u32 local_id, + const struct btf *targ_btf, + __u32 targ_id) +{ + const struct btf_type *local_type, *targ_type; + +recur: + local_type = skip_mods_and_typedefs(local_btf, local_id, &local_id); + targ_type = skip_mods_and_typedefs(targ_btf, targ_id, &targ_id); + if (!local_type || !targ_type) + return -EINVAL; + + if (btf_is_composite(local_type) && btf_is_composite(targ_type)) + return 1; + if (btf_kind(local_type) != btf_kind(targ_type)) + return 0; + + switch (btf_kind(local_type)) { + case BTF_KIND_FWD: + case BTF_KIND_PTR: + return 1; + case BTF_KIND_ENUM: + return local_type->size == targ_type->size; + case BTF_KIND_INT: + return btf_int_offset(local_type) == 0 && + btf_int_offset(targ_type) == 0 && + local_type->size == targ_type->size && + btf_int_bits(local_type) == btf_int_bits(targ_type); + case BTF_KIND_ARRAY: + local_id = btf_array(local_type)->type; + targ_id = btf_array(targ_type)->type; + goto recur; + default: + pr_warning("unexpected kind %d relocated, local [%d], target [%d]\n", + btf_kind(local_type), local_id, targ_id); + return 0; + } +} + +/* + * Given single high-level named field accessor in local type, find + * corresponding high-level accessor for a target type. Along the way, + * maintain low-level spec for target as well. Also keep updating target + * offset. + * + * Searching is performed through recursive exhaustive enumeration of all + * fields of a struct/union. If there are any anonymous (embedded) + * structs/unions, they are recursively searched as well. If field with + * desired name is found, check compatibility between local and target types, + * before returning result. + * + * 1 is returned, if field is found. + * 0 is returned if no compatible field is found. + * <0 is returned on error. + */ +static int bpf_core_match_member(const struct btf *local_btf, + const struct bpf_core_accessor *local_acc, + const struct btf *targ_btf, + __u32 targ_id, + struct bpf_core_spec *spec, + __u32 *next_targ_id) +{ + const struct btf_type *local_type, *targ_type; + const struct btf_member *local_member, *m; + const char *local_name, *targ_name; + __u32 local_id; + int i, n, found; + + targ_type = skip_mods_and_typedefs(targ_btf, targ_id, &targ_id); + if (!targ_type) + return -EINVAL; + if (!btf_is_composite(targ_type)) + return 0; + + local_id = local_acc->type_id; + local_type = btf__type_by_id(local_btf, local_id); + local_member = btf_members(local_type) + local_acc->idx; + local_name = btf__name_by_offset(local_btf, local_member->name_off); + + n = btf_vlen(targ_type); + m = btf_members(targ_type); + for (i = 0; i < n; i++, m++) { + __u32 offset; + + /* bitfield relocations not supported */ + if (btf_member_bitfield_size(targ_type, i)) + continue; + offset = btf_member_bit_offset(targ_type, i); + if (offset % 8) + continue; + + /* too deep struct/union/array nesting */ + if (spec->raw_len == BPF_CORE_SPEC_MAX_LEN) + return -E2BIG; + + /* speculate this member will be the good one */ + spec->offset += offset / 8; + spec->raw_spec[spec->raw_len++] = i; + + targ_name = btf__name_by_offset(targ_btf, m->name_off); + if (str_is_empty(targ_name)) { + /* embedded struct/union, we need to go deeper */ + found = bpf_core_match_member(local_btf, local_acc, + targ_btf, m->type, + spec, next_targ_id); + if (found) /* either found or error */ + return found; + } else if (strcmp(local_name, targ_name) == 0) { + /* matching named field */ + struct bpf_core_accessor *targ_acc; + + targ_acc = &spec->spec[spec->len++]; + targ_acc->type_id = targ_id; + targ_acc->idx = i; + targ_acc->name = targ_name; + + *next_targ_id = m->type; + found = bpf_core_fields_are_compat(local_btf, + local_member->type, + targ_btf, m->type); + if (!found) + spec->len--; /* pop accessor */ + return found; + } + /* member turned out not to be what we looked for */ + spec->offset -= offset / 8; + spec->raw_len--; + } + + return 0; +} + +/* + * Try to match local spec to a target type and, if successful, produce full + * target spec (high-level, low-level + offset). + */ +static int bpf_core_spec_match(struct bpf_core_spec *local_spec, + const struct btf *targ_btf, __u32 targ_id, + struct bpf_core_spec *targ_spec) +{ + const struct btf_type *targ_type; + const struct bpf_core_accessor *local_acc; + struct bpf_core_accessor *targ_acc; + int i, sz, matched; + + memset(targ_spec, 0, sizeof(*targ_spec)); + targ_spec->btf = targ_btf; + + local_acc = &local_spec->spec[0]; + targ_acc = &targ_spec->spec[0]; + + for (i = 0; i < local_spec->len; i++, local_acc++, targ_acc++) { + targ_type = skip_mods_and_typedefs(targ_spec->btf, targ_id, + &targ_id); + if (!targ_type) + return -EINVAL; + + if (local_acc->name) { + matched = bpf_core_match_member(local_spec->btf, + local_acc, + targ_btf, targ_id, + targ_spec, &targ_id); + if (matched <= 0) + return matched; + } else { + /* for i=0, targ_id is already treated as array element + * type (because it's the original struct), for others + * we should find array element type first + */ + if (i > 0) { + const struct btf_array *a; + + if (!btf_is_array(targ_type)) + return 0; + + a = btf_array(targ_type); + if (local_acc->idx >= a->nelems) + return 0; + if (!skip_mods_and_typedefs(targ_btf, a->type, + &targ_id)) + return -EINVAL; + } + + /* too deep struct/union/array nesting */ + if (targ_spec->raw_len == BPF_CORE_SPEC_MAX_LEN) + return -E2BIG; + + targ_acc->type_id = targ_id; + targ_acc->idx = local_acc->idx; + targ_acc->name = NULL; + targ_spec->len++; + targ_spec->raw_spec[targ_spec->raw_len] = targ_acc->idx; + targ_spec->raw_len++; + + sz = btf__resolve_size(targ_btf, targ_id); + if (sz < 0) + return sz; + targ_spec->offset += local_acc->idx * sz; + } + } + + return 1; +} + +/* + * Patch relocatable BPF instruction. + * Expected insn->imm value is provided for validation, as well as the new + * relocated value. + * + * Currently three kinds of BPF instructions are supported: + * 1. rX = (assignment with immediate operand); + * 2. rX += (arithmetic operations with immediate operand); + * 3. *(rX) = (indirect memory assignment with immediate operand). + * + * If actual insn->imm value is wrong, bail out. + */ +static int bpf_core_reloc_insn(struct bpf_program *prog, int insn_off, + __u32 orig_off, __u32 new_off) +{ + struct bpf_insn *insn; + int insn_idx; + __u8 class; + + if (insn_off % sizeof(struct bpf_insn)) + return -EINVAL; + insn_idx = insn_off / sizeof(struct bpf_insn); + + insn = &prog->insns[insn_idx]; + class = BPF_CLASS(insn->code); + + if (class == BPF_ALU || class == BPF_ALU64) { + if (BPF_SRC(insn->code) != BPF_K) + return -EINVAL; + if (insn->imm != orig_off) + return -EINVAL; + insn->imm = new_off; + pr_debug("prog '%s': patched insn #%d (ALU/ALU64) imm %d -> %d\n", + bpf_program__title(prog, false), + insn_idx, orig_off, new_off); + } else { + pr_warning("prog '%s': trying to relocate unrecognized insn #%d, code:%x, src:%x, dst:%x, off:%x, imm:%x\n", + bpf_program__title(prog, false), + insn_idx, insn->code, insn->src_reg, insn->dst_reg, + insn->off, insn->imm); + return -EINVAL; + } + return 0; +} + +/* + * Probe few well-known locations for vmlinux kernel image and try to load BTF + * data out of it to use for target BTF. + */ +static struct btf *bpf_core_find_kernel_btf(void) +{ + const char *locations[] = { + "/lib/modules/%1$s/vmlinux-%1$s", + "/usr/lib/modules/%1$s/kernel/vmlinux", + }; + char path[PATH_MAX + 1]; + struct utsname buf; + struct btf *btf; + int i; + + uname(&buf); + + for (i = 0; i < ARRAY_SIZE(locations); i++) { + snprintf(path, PATH_MAX, locations[i], buf.release); + + if (access(path, R_OK)) + continue; + + btf = btf__parse_elf(path, NULL); + pr_debug("kernel BTF load from '%s': %ld\n", + path, PTR_ERR(btf)); + if (IS_ERR(btf)) + continue; + + return btf; + } + + pr_warning("failed to find valid kernel BTF\n"); + return ERR_PTR(-ESRCH); +} + +/* Output spec definition in the format: + * [] () + => @, + * where is a C-syntax view of recorded field access, e.g.: x.a[3].b + */ +static void bpf_core_dump_spec(int level, const struct bpf_core_spec *spec) +{ + const struct btf_type *t; + const char *s; + __u32 type_id; + int i; + + type_id = spec->spec[0].type_id; + t = btf__type_by_id(spec->btf, type_id); + s = btf__name_by_offset(spec->btf, t->name_off); + libbpf_print(level, "[%u] %s + ", type_id, s); + + for (i = 0; i < spec->raw_len; i++) + libbpf_print(level, "%d%s", spec->raw_spec[i], + i == spec->raw_len - 1 ? " => " : ":"); + + libbpf_print(level, "%u @ &x", spec->offset); + + for (i = 0; i < spec->len; i++) { + if (spec->spec[i].name) + libbpf_print(level, ".%s", spec->spec[i].name); + else + libbpf_print(level, "[%u]", spec->spec[i].idx); + } + +} + +static size_t bpf_core_hash_fn(const void *key, void *ctx) +{ + return (size_t)key; +} + +static bool bpf_core_equal_fn(const void *k1, const void *k2, void *ctx) +{ + return k1 == k2; +} + +static void *u32_as_hash_key(__u32 x) +{ + return (void *)(uintptr_t)x; +} + +/* + * CO-RE relocate single instruction. + * + * The outline and important points of the algorithm: + * 1. For given local type, find corresponding candidate target types. + * Candidate type is a type with the same "essential" name, ignoring + * everything after last triple underscore (___). E.g., `sample`, + * `sample___flavor_one`, `sample___flavor_another_one`, are all candidates + * for each other. Names with triple underscore are referred to as + * "flavors" and are useful, among other things, to allow to + * specify/support incompatible variations of the same kernel struct, which + * might differ between different kernel versions and/or build + * configurations. + * + * N.B. Struct "flavors" could be generated by bpftool's BTF-to-C + * converter, when deduplicated BTF of a kernel still contains more than + * one different types with the same name. In that case, ___2, ___3, etc + * are appended starting from second name conflict. But start flavors are + * also useful to be defined "locally", in BPF program, to extract same + * data from incompatible changes between different kernel + * versions/configurations. For instance, to handle field renames between + * kernel versions, one can use two flavors of the struct name with the + * same common name and use conditional relocations to extract that field, + * depending on target kernel version. + * 2. For each candidate type, try to match local specification to this + * candidate target type. Matching involves finding corresponding + * high-level spec accessors, meaning that all named fields should match, + * as well as all array accesses should be within the actual bounds. Also, + * types should be compatible (see bpf_core_fields_are_compat for details). + * 3. It is supported and expected that there might be multiple flavors + * matching the spec. As long as all the specs resolve to the same set of + * offsets across all candidates, there is not error. If there is any + * ambiguity, CO-RE relocation will fail. This is necessary to accomodate + * imprefection of BTF deduplication, which can cause slight duplication of + * the same BTF type, if some directly or indirectly referenced (by + * pointer) type gets resolved to different actual types in different + * object files. If such situation occurs, deduplicated BTF will end up + * with two (or more) structurally identical types, which differ only in + * types they refer to through pointer. This should be OK in most cases and + * is not an error. + * 4. Candidate types search is performed by linearly scanning through all + * types in target BTF. It is anticipated that this is overall more + * efficient memory-wise and not significantly worse (if not better) + * CPU-wise compared to prebuilding a map from all local type names to + * a list of candidate type names. It's also sped up by caching resolved + * list of matching candidates per each local "root" type ID, that has at + * least one bpf_offset_reloc associated with it. This list is shared + * between multiple relocations for the same type ID and is updated as some + * of the candidates are pruned due to structural incompatibility. + */ +static int bpf_core_reloc_offset(struct bpf_program *prog, + const struct bpf_offset_reloc *relo, + int relo_idx, + const struct btf *local_btf, + const struct btf *targ_btf, + struct hashmap *cand_cache) +{ + const char *prog_name = bpf_program__title(prog, false); + struct bpf_core_spec local_spec, cand_spec, targ_spec; + const void *type_key = u32_as_hash_key(relo->type_id); + const struct btf_type *local_type, *cand_type; + const char *local_name, *cand_name; + struct ids_vec *cand_ids; + __u32 local_id, cand_id; + const char *spec_str; + int i, j, err; + + local_id = relo->type_id; + local_type = btf__type_by_id(local_btf, local_id); + if (!local_type) + return -EINVAL; + + local_name = btf__name_by_offset(local_btf, local_type->name_off); + if (str_is_empty(local_name)) + return -EINVAL; + + spec_str = btf__name_by_offset(local_btf, relo->access_str_off); + if (str_is_empty(spec_str)) + return -EINVAL; + + err = bpf_core_spec_parse(local_btf, local_id, spec_str, &local_spec); + if (err) { + pr_warning("prog '%s': relo #%d: parsing [%d] %s + %s failed: %d\n", + prog_name, relo_idx, local_id, local_name, spec_str, + err); + return -EINVAL; + } + + pr_debug("prog '%s': relo #%d: spec is ", prog_name, relo_idx); + bpf_core_dump_spec(LIBBPF_DEBUG, &local_spec); + libbpf_print(LIBBPF_DEBUG, "\n"); + + if (!hashmap__find(cand_cache, type_key, (void **)&cand_ids)) { + cand_ids = bpf_core_find_cands(local_btf, local_id, targ_btf); + if (IS_ERR(cand_ids)) { + pr_warning("prog '%s': relo #%d: target candidate search failed for [%d] %s: %ld", + prog_name, relo_idx, local_id, local_name, + PTR_ERR(cand_ids)); + return PTR_ERR(cand_ids); + } + err = hashmap__set(cand_cache, type_key, cand_ids, NULL, NULL); + if (err) { + bpf_core_free_cands(cand_ids); + return err; + } + } + + for (i = 0, j = 0; i < cand_ids->len; i++) { + cand_id = cand_ids->data[i]; + cand_type = btf__type_by_id(targ_btf, cand_id); + cand_name = btf__name_by_offset(targ_btf, cand_type->name_off); + + err = bpf_core_spec_match(&local_spec, targ_btf, + cand_id, &cand_spec); + pr_debug("prog '%s': relo #%d: matching candidate #%d %s against spec ", + prog_name, relo_idx, i, cand_name); + bpf_core_dump_spec(LIBBPF_DEBUG, &cand_spec); + libbpf_print(LIBBPF_DEBUG, ": %d\n", err); + if (err < 0) { + pr_warning("prog '%s': relo #%d: matching error: %d\n", + prog_name, relo_idx, err); + return err; + } + if (err == 0) + continue; + + if (j == 0) { + targ_spec = cand_spec; + } else if (cand_spec.offset != targ_spec.offset) { + /* if there are many candidates, they should all + * resolve to the same offset + */ + pr_warning("prog '%s': relo #%d: offset ambiguity: %u != %u\n", + prog_name, relo_idx, cand_spec.offset, + targ_spec.offset); + return -EINVAL; + } + + cand_ids->data[j++] = cand_spec.spec[0].type_id; + } + + cand_ids->len = j; + if (cand_ids->len == 0) { + pr_warning("prog '%s': relo #%d: no matching targets found for [%d] %s + %s\n", + prog_name, relo_idx, local_id, local_name, spec_str); + return -ESRCH; + } + + err = bpf_core_reloc_insn(prog, relo->insn_off, + local_spec.offset, targ_spec.offset); + if (err) { + pr_warning("prog '%s': relo #%d: failed to patch insn at offset %d: %d\n", + prog_name, relo_idx, relo->insn_off, err); + return -EINVAL; + } + + return 0; +} + +static int +bpf_core_reloc_offsets(struct bpf_object *obj, const char *targ_btf_path) +{ + const struct btf_ext_info_sec *sec; + const struct bpf_offset_reloc *rec; + const struct btf_ext_info *seg; + struct hashmap_entry *entry; + struct hashmap *cand_cache = NULL; + struct bpf_program *prog; + struct btf *targ_btf; + const char *sec_name; + int i, err = 0; + + if (targ_btf_path) + targ_btf = btf__parse_elf(targ_btf_path, NULL); + else + targ_btf = bpf_core_find_kernel_btf(); + if (IS_ERR(targ_btf)) { + pr_warning("failed to get target BTF: %ld\n", + PTR_ERR(targ_btf)); + return PTR_ERR(targ_btf); + } + + cand_cache = hashmap__new(bpf_core_hash_fn, bpf_core_equal_fn, NULL); + if (IS_ERR(cand_cache)) { + err = PTR_ERR(cand_cache); + goto out; + } + + seg = &obj->btf_ext->offset_reloc_info; + for_each_btf_ext_sec(seg, sec) { + sec_name = btf__name_by_offset(obj->btf, sec->sec_name_off); + if (str_is_empty(sec_name)) { + err = -EINVAL; + goto out; + } + prog = bpf_object__find_program_by_title(obj, sec_name); + if (!prog) { + pr_warning("failed to find program '%s' for CO-RE offset relocation\n", + sec_name); + err = -EINVAL; + goto out; + } + + pr_debug("prog '%s': performing %d CO-RE offset relocs\n", + sec_name, sec->num_info); + + for_each_btf_ext_rec(seg, sec, i, rec) { + err = bpf_core_reloc_offset(prog, rec, i, obj->btf, + targ_btf, cand_cache); + if (err) { + pr_warning("prog '%s': relo #%d: failed to relocate: %d\n", + sec_name, i, err); + goto out; + } + } + } + +out: + btf__free(targ_btf); + if (!IS_ERR_OR_NULL(cand_cache)) { + hashmap__for_each_entry(cand_cache, entry, i) { + bpf_core_free_cands(entry->value); + } + hashmap__free(cand_cache); + } + return err; +} + +static int +bpf_object__relocate_core(struct bpf_object *obj, const char *targ_btf_path) +{ + int err = 0; + + if (obj->btf_ext->offset_reloc_info.len) + err = bpf_core_reloc_offsets(obj, targ_btf_path); + + return err; +} + static int bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj, struct reloc_desc *relo) @@ -2397,14 +3235,21 @@ bpf_program__relocate(struct bpf_program *prog, struct bpf_object *obj) return 0; } - static int -bpf_object__relocate(struct bpf_object *obj) +bpf_object__relocate(struct bpf_object *obj, const char *targ_btf_path) { struct bpf_program *prog; size_t i; int err; + if (obj->btf_ext) { + err = bpf_object__relocate_core(obj, targ_btf_path); + if (err) { + pr_warning("failed to perform CO-RE relocations: %d\n", + err); + return err; + } + } for (i = 0; i < obj->nr_programs; i++) { prog = &obj->programs[i]; @@ -2805,7 +3650,7 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr) obj->loaded = true; CHECK_ERR(bpf_object__create_maps(obj), err, out); - CHECK_ERR(bpf_object__relocate(obj), err, out); + CHECK_ERR(bpf_object__relocate(obj, attr->target_btf_path), err, out); CHECK_ERR(bpf_object__load_progs(obj, attr->log_level), err, out); return 0; diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 8a9d462a6f6d..e8f70977d137 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -92,6 +92,7 @@ LIBBPF_API void bpf_object__close(struct bpf_object *object); struct bpf_object_load_attr { struct bpf_object *obj; int log_level; + const char *target_btf_path; }; /* Load/unload object into/from kernel */ -- cgit v1.2.3-59-g8ed1b From 2dc26d5a4f2e97364542030a4a51e4a50c14bae3 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 7 Aug 2019 14:39:52 -0700 Subject: selftests/bpf: add BPF_CORE_READ relocatable read macro Add BPF_CORE_READ macro used in tests to do bpf_core_read(), which automatically captures offset relocation. Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/bpf_helpers.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h index 120aa86c58d3..8b503ea142f0 100644 --- a/tools/testing/selftests/bpf/bpf_helpers.h +++ b/tools/testing/selftests/bpf/bpf_helpers.h @@ -504,4 +504,24 @@ struct pt_regs; (void *)(PT_REGS_FP(ctx) + sizeof(ip))); }) #endif +/* + * BPF_CORE_READ abstracts away bpf_probe_read() call and captures offset + * relocation for source address using __builtin_preserve_access_index() + * built-in, provided by Clang. + * + * __builtin_preserve_access_index() takes as an argument an expression of + * taking an address of a field within struct/union. It makes compiler emit + * a relocation, which records BTF type ID describing root struct/union and an + * accessor string which describes exact embedded field that was used to take + * an address. See detailed description of this relocation format and + * semantics in comments to struct bpf_offset_reloc in libbpf_internal.h. + * + * This relocation allows libbpf to adjust BPF instruction to use correct + * actual field offset, based on target kernel BTF type that matches original + * (local) BTF, used to record relocation. + */ +#define BPF_CORE_READ(dst, src) \ + bpf_probe_read((dst), sizeof(*(src)), \ + __builtin_preserve_access_index(src)) + #endif -- cgit v1.2.3-59-g8ed1b From df36e621418b0de4d4afec5f8002d45ee636bb5c Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 7 Aug 2019 14:39:53 -0700 Subject: selftests/bpf: add CO-RE relocs testing setup Add CO-RE relocation test runner. Add one simple test validating that libbpf's logic for searching for kernel image and loading BTF out of it works. Signed-off-by: Andrii Nakryiko Acked-by: Song Liu Signed-off-by: Alexei Starovoitov --- .../testing/selftests/bpf/prog_tests/core_reloc.c | 129 +++++++++++++++++++++ .../selftests/bpf/progs/test_core_reloc_kernel.c | 36 ++++++ 2 files changed, 165 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/core_reloc.c create mode 100644 tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/core_reloc.c b/tools/testing/selftests/bpf/prog_tests/core_reloc.c new file mode 100644 index 000000000000..4323a459c8a2 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/core_reloc.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0 +#include + +struct core_reloc_test_case { + const char *case_name; + const char *bpf_obj_file; + const char *btf_src_file; + const char *input; + int input_len; + const char *output; + int output_len; + bool fails; +}; + +static struct core_reloc_test_case test_cases[] = { + /* validate we can find kernel image and use its BTF for relocs */ + { + .case_name = "kernel", + .bpf_obj_file = "test_core_reloc_kernel.o", + .btf_src_file = NULL, /* load from /lib/modules/$(uname -r) */ + .input = "", + .input_len = 0, + .output = "\1", /* true */ + .output_len = 1, + }, +}; + +struct data { + char in[256]; + char out[256]; +}; + +void test_core_reloc(void) +{ + const char *probe_name = "raw_tracepoint/sys_enter"; + struct bpf_object_load_attr load_attr = {}; + struct core_reloc_test_case *test_case; + int err, duration = 0, i, equal; + struct bpf_link *link = NULL; + struct bpf_map *data_map; + struct bpf_program *prog; + struct bpf_object *obj; + const int zero = 0; + struct data data; + + for (i = 0; i < ARRAY_SIZE(test_cases); i++) { + test_case = &test_cases[i]; + + if (!test__start_subtest(test_case->case_name)) + continue; + + obj = bpf_object__open(test_case->bpf_obj_file); + if (CHECK(IS_ERR_OR_NULL(obj), "obj_open", + "failed to open '%s': %ld\n", + test_case->bpf_obj_file, PTR_ERR(obj))) + continue; + + prog = bpf_object__find_program_by_title(obj, probe_name); + if (CHECK(!prog, "find_probe", + "prog '%s' not found\n", probe_name)) + goto cleanup; + bpf_program__set_type(prog, BPF_PROG_TYPE_RAW_TRACEPOINT); + + load_attr.obj = obj; + load_attr.log_level = 0; + load_attr.target_btf_path = test_case->btf_src_file; + err = bpf_object__load_xattr(&load_attr); + if (test_case->fails) { + CHECK(!err, "obj_load_fail", + "should fail to load prog '%s'\n", probe_name); + goto cleanup; + } else { + if (CHECK(err, "obj_load", + "failed to load prog '%s': %d\n", + probe_name, err)) + goto cleanup; + } + + link = bpf_program__attach_raw_tracepoint(prog, "sys_enter"); + if (CHECK(IS_ERR(link), "attach_raw_tp", "err %ld\n", + PTR_ERR(link))) + goto cleanup; + + data_map = bpf_object__find_map_by_name(obj, "test_cor.bss"); + if (CHECK(!data_map, "find_data_map", "data map not found\n")) + goto cleanup; + + memset(&data, 0, sizeof(data)); + memcpy(data.in, test_case->input, test_case->input_len); + + err = bpf_map_update_elem(bpf_map__fd(data_map), + &zero, &data, 0); + if (CHECK(err, "update_data_map", + "failed to update .data map: %d\n", err)) + goto cleanup; + + /* trigger test run */ + usleep(1); + + err = bpf_map_lookup_elem(bpf_map__fd(data_map), &zero, &data); + if (CHECK(err, "get_result", + "failed to get output data: %d\n", err)) + goto cleanup; + + equal = memcmp(data.out, test_case->output, + test_case->output_len) == 0; + if (CHECK(!equal, "check_result", + "input/output data don't match\n")) { + int j; + + for (j = 0; j < test_case->input_len; j++) { + printf("input byte #%d: 0x%02hhx\n", + j, test_case->input[j]); + } + for (j = 0; j < test_case->output_len; j++) { + printf("output byte #%d: EXP 0x%02hhx GOT 0x%02hhx\n", + j, test_case->output[j], data.out[j]); + } + goto cleanup; + } + +cleanup: + if (!IS_ERR_OR_NULL(link)) { + bpf_link__destroy(link); + link = NULL; + } + bpf_object__close(obj); + } +} diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c b/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c new file mode 100644 index 000000000000..37e02aa3f0c8 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Facebook + +#include +#include +#include "bpf_helpers.h" + +char _license[] SEC("license") = "GPL"; + +static volatile struct data { + char in[256]; + char out[256]; +} data; + +struct task_struct { + int pid; + int tgid; +}; + +SEC("raw_tracepoint/sys_enter") +int test_core_kernel(void *ctx) +{ + struct task_struct *task = (void *)bpf_get_current_task(); + uint64_t pid_tgid = bpf_get_current_pid_tgid(); + int pid, tgid; + + if (BPF_CORE_READ(&pid, &task->pid) || + BPF_CORE_READ(&tgid, &task->tgid)) + return 1; + + /* validate pid + tgid matches */ + data.out[0] = (((uint64_t)pid << 32) | tgid) == pid_tgid; + + return 0; +} + -- cgit v1.2.3-59-g8ed1b From 002d3afce65518dc5dfc398a37c2be2a6bf559c4 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 7 Aug 2019 14:39:54 -0700 Subject: selftests/bpf: add CO-RE relocs struct flavors tests Add tests verifying that BPF program can use various struct/union "flavors" to extract data from the same target struct/union. Signed-off-by: Andrii Nakryiko Acked-by: Song Liu Signed-off-by: Alexei Starovoitov --- .../testing/selftests/bpf/prog_tests/core_reloc.c | 34 ++++++++++++ .../selftests/bpf/progs/btf__core_reloc_flavors.c | 3 ++ .../btf__core_reloc_flavors__err_wrong_name.c | 3 ++ .../testing/selftests/bpf/progs/core_reloc_types.h | 15 ++++++ .../selftests/bpf/progs/test_core_reloc_flavors.c | 62 ++++++++++++++++++++++ 5 files changed, 117 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_flavors.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_flavors__err_wrong_name.c create mode 100644 tools/testing/selftests/bpf/progs/core_reloc_types.h create mode 100644 tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/core_reloc.c b/tools/testing/selftests/bpf/prog_tests/core_reloc.c index 4323a459c8a2..59fd9cb207ab 100644 --- a/tools/testing/selftests/bpf/prog_tests/core_reloc.c +++ b/tools/testing/selftests/bpf/prog_tests/core_reloc.c @@ -1,5 +1,32 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include "progs/core_reloc_types.h" + +#define STRUCT_TO_CHAR_PTR(struct_name) (const char *)&(struct struct_name) + +#define FLAVORS_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) { \ + .a = 42, \ + .b = 0xc001, \ + .c = 0xbeef, \ +} + +#define FLAVORS_CASE_COMMON(name) \ + .case_name = #name, \ + .bpf_obj_file = "test_core_reloc_flavors.o", \ + .btf_src_file = "btf__core_reloc_" #name ".o" \ + +#define FLAVORS_CASE(name) { \ + FLAVORS_CASE_COMMON(name), \ + .input = FLAVORS_DATA(core_reloc_##name), \ + .input_len = sizeof(struct core_reloc_##name), \ + .output = FLAVORS_DATA(core_reloc_flavors), \ + .output_len = sizeof(struct core_reloc_flavors), \ +} + +#define FLAVORS_ERR_CASE(name) { \ + FLAVORS_CASE_COMMON(name), \ + .fails = true, \ +} struct core_reloc_test_case { const char *case_name; @@ -23,6 +50,13 @@ static struct core_reloc_test_case test_cases[] = { .output = "\1", /* true */ .output_len = 1, }, + + /* validate BPF program can use multiple flavors to match against + * single target BTF type + */ + FLAVORS_CASE(flavors), + + FLAVORS_ERR_CASE(flavors__err_wrong_name), }; struct data { diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_flavors.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_flavors.c new file mode 100644 index 000000000000..b74455b91227 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_flavors.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_flavors x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_flavors__err_wrong_name.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_flavors__err_wrong_name.c new file mode 100644 index 000000000000..7b6035f86ee6 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_flavors__err_wrong_name.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_flavors__err_wrong_name x) {} diff --git a/tools/testing/selftests/bpf/progs/core_reloc_types.h b/tools/testing/selftests/bpf/progs/core_reloc_types.h new file mode 100644 index 000000000000..33b0c6a61912 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/core_reloc_types.h @@ -0,0 +1,15 @@ +/* + * FLAVORS + */ +struct core_reloc_flavors { + int a; + int b; + int c; +}; + +/* this is not a flavor, as it doesn't have triple underscore */ +struct core_reloc_flavors__err_wrong_name { + int a; + int b; + int c; +}; diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c b/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c new file mode 100644 index 000000000000..9fda73e87972 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Facebook + +#include +#include +#include "bpf_helpers.h" + +char _license[] SEC("license") = "GPL"; + +static volatile struct data { + char in[256]; + char out[256]; +} data; + +struct core_reloc_flavors { + int a; + int b; + int c; +}; + +/* local flavor with reversed layout */ +struct core_reloc_flavors___reversed { + int c; + int b; + int a; +}; + +/* local flavor with nested/overlapping layout */ +struct core_reloc_flavors___weird { + struct { + int b; + }; + /* a and c overlap in local flavor, but this should still work + * correctly with target original flavor + */ + union { + int a; + int c; + }; +}; + +SEC("raw_tracepoint/sys_enter") +int test_core_flavors(void *ctx) +{ + struct core_reloc_flavors *in_orig = (void *)&data.in; + struct core_reloc_flavors___reversed *in_rev = (void *)&data.in; + struct core_reloc_flavors___weird *in_weird = (void *)&data.in; + struct core_reloc_flavors *out = (void *)&data.out; + + /* read a using weird layout */ + if (BPF_CORE_READ(&out->a, &in_weird->a)) + return 1; + /* read b using reversed layout */ + if (BPF_CORE_READ(&out->b, &in_rev->b)) + return 1; + /* read c using original layout */ + if (BPF_CORE_READ(&out->c, &in_orig->c)) + return 1; + + return 0; +} + -- cgit v1.2.3-59-g8ed1b From ec6438a988a43dcb03f0a04f3f51a48aba54764a Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 7 Aug 2019 14:39:55 -0700 Subject: selftests/bpf: add CO-RE relocs nesting tests Add a bunch of test validating correct handling of nested structs/unions. Signed-off-by: Andrii Nakryiko Acked-by: Song Liu Signed-off-by: Alexei Starovoitov --- .../testing/selftests/bpf/prog_tests/core_reloc.c | 39 +++ .../selftests/bpf/progs/btf__core_reloc_nesting.c | 3 + .../progs/btf__core_reloc_nesting___anon_embed.c | 3 + .../btf__core_reloc_nesting___dup_compat_types.c | 5 + ...btf__core_reloc_nesting___err_array_container.c | 3 + .../btf__core_reloc_nesting___err_array_field.c | 3 + ...__core_reloc_nesting___err_dup_incompat_types.c | 4 + ...f__core_reloc_nesting___err_missing_container.c | 3 + .../btf__core_reloc_nesting___err_missing_field.c | 3 + ..._core_reloc_nesting___err_nonstruct_container.c | 3 + ...__core_reloc_nesting___err_partial_match_dups.c | 4 + .../progs/btf__core_reloc_nesting___err_too_deep.c | 3 + .../btf__core_reloc_nesting___extra_nesting.c | 3 + .../btf__core_reloc_nesting___struct_union_mixup.c | 3 + .../testing/selftests/bpf/progs/core_reloc_types.h | 293 +++++++++++++++++++++ .../selftests/bpf/progs/test_core_reloc_nesting.c | 46 ++++ 16 files changed, 421 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_nesting.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___anon_embed.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___dup_compat_types.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_array_container.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_array_field.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_dup_incompat_types.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_missing_container.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_missing_field.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_nonstruct_container.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_partial_match_dups.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_too_deep.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___extra_nesting.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___struct_union_mixup.c create mode 100644 tools/testing/selftests/bpf/progs/test_core_reloc_nesting.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/core_reloc.c b/tools/testing/selftests/bpf/prog_tests/core_reloc.c index 59fd9cb207ab..3e9344e41556 100644 --- a/tools/testing/selftests/bpf/prog_tests/core_reloc.c +++ b/tools/testing/selftests/bpf/prog_tests/core_reloc.c @@ -28,6 +28,29 @@ .fails = true, \ } +#define NESTING_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) { \ + .a = { .a = { .a = 42 } }, \ + .b = { .b = { .b = 0xc001 } }, \ +} + +#define NESTING_CASE_COMMON(name) \ + .case_name = #name, \ + .bpf_obj_file = "test_core_reloc_nesting.o", \ + .btf_src_file = "btf__core_reloc_" #name ".o" + +#define NESTING_CASE(name) { \ + NESTING_CASE_COMMON(name), \ + .input = NESTING_DATA(core_reloc_##name), \ + .input_len = sizeof(struct core_reloc_##name), \ + .output = NESTING_DATA(core_reloc_nesting), \ + .output_len = sizeof(struct core_reloc_nesting) \ +} + +#define NESTING_ERR_CASE(name) { \ + NESTING_CASE_COMMON(name), \ + .fails = true, \ +} + struct core_reloc_test_case { const char *case_name; const char *bpf_obj_file; @@ -57,6 +80,22 @@ static struct core_reloc_test_case test_cases[] = { FLAVORS_CASE(flavors), FLAVORS_ERR_CASE(flavors__err_wrong_name), + + /* various struct/enum nesting and resolution scenarios */ + NESTING_CASE(nesting), + NESTING_CASE(nesting___anon_embed), + NESTING_CASE(nesting___struct_union_mixup), + NESTING_CASE(nesting___extra_nesting), + NESTING_CASE(nesting___dup_compat_types), + + NESTING_ERR_CASE(nesting___err_missing_field), + NESTING_ERR_CASE(nesting___err_array_field), + NESTING_ERR_CASE(nesting___err_missing_container), + NESTING_ERR_CASE(nesting___err_nonstruct_container), + NESTING_ERR_CASE(nesting___err_array_container), + NESTING_ERR_CASE(nesting___err_dup_incompat_types), + NESTING_ERR_CASE(nesting___err_partial_match_dups), + NESTING_ERR_CASE(nesting___err_too_deep), }; struct data { diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting.c new file mode 100644 index 000000000000..4480fcc0f183 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_nesting x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___anon_embed.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___anon_embed.c new file mode 100644 index 000000000000..13e108f76ece --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___anon_embed.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_nesting___anon_embed x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___dup_compat_types.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___dup_compat_types.c new file mode 100644 index 000000000000..76b54fda5fbb --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___dup_compat_types.c @@ -0,0 +1,5 @@ +#include "core_reloc_types.h" + +void f1(struct core_reloc_nesting___dup_compat_types x) {} +void f2(struct core_reloc_nesting___dup_compat_types__2 x) {} +void f3(struct core_reloc_nesting___dup_compat_types__3 x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_array_container.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_array_container.c new file mode 100644 index 000000000000..975fb95db810 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_array_container.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_nesting___err_array_container x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_array_field.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_array_field.c new file mode 100644 index 000000000000..ad66c67e7980 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_array_field.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_nesting___err_array_field x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_dup_incompat_types.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_dup_incompat_types.c new file mode 100644 index 000000000000..35c5f8da6812 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_dup_incompat_types.c @@ -0,0 +1,4 @@ +#include "core_reloc_types.h" + +void f1(struct core_reloc_nesting___err_dup_incompat_types__1 x) {} +void f2(struct core_reloc_nesting___err_dup_incompat_types__2 x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_missing_container.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_missing_container.c new file mode 100644 index 000000000000..142e332041db --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_missing_container.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_nesting___err_missing_container x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_missing_field.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_missing_field.c new file mode 100644 index 000000000000..efcae167fab9 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_missing_field.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_nesting___err_missing_field x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_nonstruct_container.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_nonstruct_container.c new file mode 100644 index 000000000000..97aaaedd8ada --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_nonstruct_container.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_nesting___err_nonstruct_container x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_partial_match_dups.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_partial_match_dups.c new file mode 100644 index 000000000000..ffde35086e90 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_partial_match_dups.c @@ -0,0 +1,4 @@ +#include "core_reloc_types.h" + +void f1(struct core_reloc_nesting___err_partial_match_dups__a x) {} +void f2(struct core_reloc_nesting___err_partial_match_dups__b x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_too_deep.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_too_deep.c new file mode 100644 index 000000000000..39a2fadd8e95 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___err_too_deep.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_nesting___err_too_deep x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___extra_nesting.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___extra_nesting.c new file mode 100644 index 000000000000..a09d9dfb20df --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___extra_nesting.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_nesting___extra_nesting x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___struct_union_mixup.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___struct_union_mixup.c new file mode 100644 index 000000000000..3d8a1a74012f --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_nesting___struct_union_mixup.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_nesting___struct_union_mixup x) {} diff --git a/tools/testing/selftests/bpf/progs/core_reloc_types.h b/tools/testing/selftests/bpf/progs/core_reloc_types.h index 33b0c6a61912..340ee2bcd463 100644 --- a/tools/testing/selftests/bpf/progs/core_reloc_types.h +++ b/tools/testing/selftests/bpf/progs/core_reloc_types.h @@ -13,3 +13,296 @@ struct core_reloc_flavors__err_wrong_name { int b; int c; }; + +/* + * NESTING + */ +/* original set up, used to record relocations in BPF program */ +struct core_reloc_nesting_substruct { + int a; +}; + +union core_reloc_nesting_subunion { + int b; +}; + +struct core_reloc_nesting { + union { + struct core_reloc_nesting_substruct a; + } a; + struct { + union core_reloc_nesting_subunion b; + } b; +}; + +/* inlined anonymous struct/union instead of named structs in original */ +struct core_reloc_nesting___anon_embed { + int __just_for_padding; + union { + struct { + int a; + } a; + } a; + struct { + union { + int b; + } b; + } b; +}; + +/* different mix of nested structs/unions than in original */ +struct core_reloc_nesting___struct_union_mixup { + int __a; + struct { + int __a; + union { + char __a; + int a; + } a; + } a; + int __b; + union { + int __b; + union { + char __b; + int b; + } b; + } b; +}; + +/* extra anon structs/unions, but still valid a.a.a and b.b.b accessors */ +struct core_reloc_nesting___extra_nesting { + int __padding; + struct { + struct { + struct { + struct { + union { + int a; + } a; + }; + }; + } a; + int __some_more; + struct { + union { + union { + union { + struct { + int b; + }; + } b; + }; + } b; + }; + }; +}; + +/* three flavors of same struct with different structure but same layout for + * a.a.a and b.b.b, thus successfully resolved and relocatable */ +struct core_reloc_nesting___dup_compat_types { + char __just_for_padding; + /* 3 more bytes of padding */ + struct { + struct { + int a; /* offset 4 */ + } a; + } a; + long long __more_padding; + struct { + struct { + int b; /* offset 16 */ + } b; + } b; +}; + +struct core_reloc_nesting___dup_compat_types__2 { + int __aligned_padding; + struct { + int __trickier_noop[0]; + struct { + char __some_more_noops[0]; + int a; /* offset 4 */ + } a; + } a; + int __more_padding; + struct { + struct { + struct { + int __critical_padding; + int b; /* offset 16 */ + } b; + int __does_not_matter; + }; + } b; + int __more_irrelevant_stuff; +}; + +struct core_reloc_nesting___dup_compat_types__3 { + char __correct_padding[4]; + struct { + struct { + int a; /* offset 4 */ + } a; + } a; + /* 8 byte padding due to next struct's alignment */ + struct { + struct { + int b; + } b; + } b __attribute__((aligned(16))); +}; + +/* b.b.b field is missing */ +struct core_reloc_nesting___err_missing_field { + struct { + struct { + int a; + } a; + } a; + struct { + struct { + int x; + } b; + } b; +}; + +/* b.b.b field is an array of integers instead of plain int */ +struct core_reloc_nesting___err_array_field { + struct { + struct { + int a; + } a; + } a; + struct { + struct { + int b[1]; + } b; + } b; +}; + +/* middle b container is missing */ +struct core_reloc_nesting___err_missing_container { + struct { + struct { + int a; + } a; + } a; + struct { + int x; + } b; +}; + +/* middle b container is referenced through pointer instead of being embedded */ +struct core_reloc_nesting___err_nonstruct_container { + struct { + struct { + int a; + } a; + } a; + struct { + struct { + int b; + } *b; + } b; +}; + +/* middle b container is an array of structs instead of plain struct */ +struct core_reloc_nesting___err_array_container { + struct { + struct { + int a; + } a; + } a; + struct { + struct { + int b; + } b[1]; + } b; +}; + +/* two flavors of same struct with incompatible layout for b.b.b */ +struct core_reloc_nesting___err_dup_incompat_types__1 { + struct { + struct { + int a; /* offset 0 */ + } a; + } a; + struct { + struct { + int b; /* offset 4 */ + } b; + } b; +}; + +struct core_reloc_nesting___err_dup_incompat_types__2 { + struct { + struct { + int a; /* offset 0 */ + } a; + } a; + int __extra_padding; + struct { + struct { + int b; /* offset 8 (!) */ + } b; + } b; +}; + +/* two flavors of same struct having one of a.a.a and b.b.b, but not both */ +struct core_reloc_nesting___err_partial_match_dups__a { + struct { + struct { + int a; + } a; + } a; +}; + +struct core_reloc_nesting___err_partial_match_dups__b { + struct { + struct { + int b; + } b; + } b; +}; + +struct core_reloc_nesting___err_too_deep { + struct { + struct { + int a; + } a; + } a; + /* 65 levels of nestedness for b.b.b */ + struct { + struct { + struct { struct { struct { struct { struct { + struct { struct { struct { struct { struct { + struct { struct { struct { struct { struct { + struct { struct { struct { struct { struct { + struct { struct { struct { struct { struct { + struct { struct { struct { struct { struct { + struct { struct { struct { struct { struct { + struct { struct { struct { struct { struct { + struct { struct { struct { struct { struct { + struct { struct { struct { struct { struct { + struct { struct { struct { struct { struct { + struct { struct { struct { struct { struct { + /* this one is one too much */ + struct { + int b; + }; + }; }; }; }; }; + }; }; }; }; }; + }; }; }; }; }; + }; }; }; }; }; + }; }; }; }; }; + }; }; }; }; }; + }; }; }; }; }; + }; }; }; }; }; + }; }; }; }; }; + }; }; }; }; }; + }; }; }; }; }; + }; }; }; }; }; + } b; + } b; +}; diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_nesting.c b/tools/testing/selftests/bpf/progs/test_core_reloc_nesting.c new file mode 100644 index 000000000000..3ca30cec2b39 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_nesting.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Facebook + +#include +#include +#include "bpf_helpers.h" + +char _license[] SEC("license") = "GPL"; + +static volatile struct data { + char in[256]; + char out[256]; +} data; + +struct core_reloc_nesting_substruct { + int a; +}; + +union core_reloc_nesting_subunion { + int b; +}; + +/* int a.a.a and b.b.b accesses */ +struct core_reloc_nesting { + union { + struct core_reloc_nesting_substruct a; + } a; + struct { + union core_reloc_nesting_subunion b; + } b; +}; + +SEC("raw_tracepoint/sys_enter") +int test_core_nesting(void *ctx) +{ + struct core_reloc_nesting *in = (void *)&data.in; + struct core_reloc_nesting *out = (void *)&data.out; + + if (BPF_CORE_READ(&out->a.a.a, &in->a.a.a)) + return 1; + if (BPF_CORE_READ(&out->b.b.b, &in->b.b.b)) + return 1; + + return 0; +} + -- cgit v1.2.3-59-g8ed1b From 20a9ad2e71368da8e831317f0a545e4bfb31cce1 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 7 Aug 2019 14:39:56 -0700 Subject: selftests/bpf: add CO-RE relocs array tests Add tests for various array handling/relocation scenarios. Signed-off-by: Andrii Nakryiko Acked-by: Song Liu Signed-off-by: Alexei Starovoitov --- .../testing/selftests/bpf/prog_tests/core_reloc.c | 41 +++++++++++ .../selftests/bpf/progs/btf__core_reloc_arrays.c | 3 + .../progs/btf__core_reloc_arrays___diff_arr_dim.c | 3 + .../btf__core_reloc_arrays___diff_arr_val_sz.c | 3 + .../progs/btf__core_reloc_arrays___err_non_array.c | 3 + .../btf__core_reloc_arrays___err_too_shallow.c | 3 + .../progs/btf__core_reloc_arrays___err_too_small.c | 3 + .../btf__core_reloc_arrays___err_wrong_val_type1.c | 3 + .../btf__core_reloc_arrays___err_wrong_val_type2.c | 3 + .../testing/selftests/bpf/progs/core_reloc_types.h | 81 ++++++++++++++++++++++ .../selftests/bpf/progs/test_core_reloc_arrays.c | 55 +++++++++++++++ 11 files changed, 201 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_arrays.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___diff_arr_dim.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___diff_arr_val_sz.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_non_array.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_too_shallow.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_too_small.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_wrong_val_type1.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_wrong_val_type2.c create mode 100644 tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/core_reloc.c b/tools/testing/selftests/bpf/prog_tests/core_reloc.c index 3e9344e41556..3b40160c0837 100644 --- a/tools/testing/selftests/bpf/prog_tests/core_reloc.c +++ b/tools/testing/selftests/bpf/prog_tests/core_reloc.c @@ -51,6 +51,36 @@ .fails = true, \ } +#define ARRAYS_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) { \ + .a = { [2] = 1 }, \ + .b = { [1] = { [2] = { [3] = 2 } } }, \ + .c = { [1] = { .c = 3 } }, \ + .d = { [0] = { [0] = { .d = 4 } } }, \ +} + +#define ARRAYS_CASE_COMMON(name) \ + .case_name = #name, \ + .bpf_obj_file = "test_core_reloc_arrays.o", \ + .btf_src_file = "btf__core_reloc_" #name ".o" + +#define ARRAYS_CASE(name) { \ + ARRAYS_CASE_COMMON(name), \ + .input = ARRAYS_DATA(core_reloc_##name), \ + .input_len = sizeof(struct core_reloc_##name), \ + .output = STRUCT_TO_CHAR_PTR(core_reloc_arrays_output) { \ + .a2 = 1, \ + .b123 = 2, \ + .c1c = 3, \ + .d00d = 4, \ + }, \ + .output_len = sizeof(struct core_reloc_arrays_output) \ +} + +#define ARRAYS_ERR_CASE(name) { \ + ARRAYS_CASE_COMMON(name), \ + .fails = true, \ +} + struct core_reloc_test_case { const char *case_name; const char *bpf_obj_file; @@ -96,6 +126,17 @@ static struct core_reloc_test_case test_cases[] = { NESTING_ERR_CASE(nesting___err_dup_incompat_types), NESTING_ERR_CASE(nesting___err_partial_match_dups), NESTING_ERR_CASE(nesting___err_too_deep), + + /* various array access relocation scenarios */ + ARRAYS_CASE(arrays), + ARRAYS_CASE(arrays___diff_arr_dim), + ARRAYS_CASE(arrays___diff_arr_val_sz), + + ARRAYS_ERR_CASE(arrays___err_too_small), + ARRAYS_ERR_CASE(arrays___err_too_shallow), + ARRAYS_ERR_CASE(arrays___err_non_array), + ARRAYS_ERR_CASE(arrays___err_wrong_val_type1), + ARRAYS_ERR_CASE(arrays___err_wrong_val_type2), }; struct data { diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays.c new file mode 100644 index 000000000000..018ed7fbba3a --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_arrays x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___diff_arr_dim.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___diff_arr_dim.c new file mode 100644 index 000000000000..13d662c57014 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___diff_arr_dim.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_arrays___diff_arr_dim x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___diff_arr_val_sz.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___diff_arr_val_sz.c new file mode 100644 index 000000000000..a351f418c85d --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___diff_arr_val_sz.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_arrays___diff_arr_val_sz x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_non_array.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_non_array.c new file mode 100644 index 000000000000..a8735009becc --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_non_array.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_arrays___err_non_array x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_too_shallow.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_too_shallow.c new file mode 100644 index 000000000000..2a67c28b1e75 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_too_shallow.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_arrays___err_too_shallow x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_too_small.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_too_small.c new file mode 100644 index 000000000000..1142c08c925f --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_too_small.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_arrays___err_too_small x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_wrong_val_type1.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_wrong_val_type1.c new file mode 100644 index 000000000000..795a5b729176 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_wrong_val_type1.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_arrays___err_wrong_val_type1 x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_wrong_val_type2.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_wrong_val_type2.c new file mode 100644 index 000000000000..3af74b837c4d --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_wrong_val_type2.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_arrays___err_wrong_val_type2 x) {} diff --git a/tools/testing/selftests/bpf/progs/core_reloc_types.h b/tools/testing/selftests/bpf/progs/core_reloc_types.h index 340ee2bcd463..45de7986ea2e 100644 --- a/tools/testing/selftests/bpf/progs/core_reloc_types.h +++ b/tools/testing/selftests/bpf/progs/core_reloc_types.h @@ -306,3 +306,84 @@ struct core_reloc_nesting___err_too_deep { } b; } b; }; + +/* + * ARRAYS + */ +struct core_reloc_arrays_output { + int a2; + char b123; + int c1c; + int d00d; +}; + +struct core_reloc_arrays_substruct { + int c; + int d; +}; + +struct core_reloc_arrays { + int a[5]; + char b[2][3][4]; + struct core_reloc_arrays_substruct c[3]; + struct core_reloc_arrays_substruct d[1][2]; +}; + +/* bigger array dimensions */ +struct core_reloc_arrays___diff_arr_dim { + int a[7]; + char b[3][4][5]; + struct core_reloc_arrays_substruct c[4]; + struct core_reloc_arrays_substruct d[2][3]; +}; + +/* different size of array's value (struct) */ +struct core_reloc_arrays___diff_arr_val_sz { + int a[5]; + char b[2][3][4]; + struct { + int __padding1; + int c; + int __padding2; + } c[3]; + struct { + int __padding1; + int d; + int __padding2; + } d[1][2]; +}; + +struct core_reloc_arrays___err_too_small { + int a[2]; /* this one is too small */ + char b[2][3][4]; + struct core_reloc_arrays_substruct c[3]; + struct core_reloc_arrays_substruct d[1][2]; +}; + +struct core_reloc_arrays___err_too_shallow { + int a[5]; + char b[2][3]; /* this one lacks one dimension */ + struct core_reloc_arrays_substruct c[3]; + struct core_reloc_arrays_substruct d[1][2]; +}; + +struct core_reloc_arrays___err_non_array { + int a; /* not an array */ + char b[2][3][4]; + struct core_reloc_arrays_substruct c[3]; + struct core_reloc_arrays_substruct d[1][2]; +}; + +struct core_reloc_arrays___err_wrong_val_type1 { + char a[5]; /* char instead of int */ + char b[2][3][4]; + struct core_reloc_arrays_substruct c[3]; + struct core_reloc_arrays_substruct d[1][2]; +}; + +struct core_reloc_arrays___err_wrong_val_type2 { + int a[5]; + char b[2][3][4]; + int c[3]; /* value is not a struct */ + struct core_reloc_arrays_substruct d[1][2]; +}; diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c b/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c new file mode 100644 index 000000000000..bf67f0fdf743 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Facebook + +#include +#include +#include "bpf_helpers.h" + +char _license[] SEC("license") = "GPL"; + +static volatile struct data { + char in[256]; + char out[256]; +} data; + +struct core_reloc_arrays_output { + int a2; + char b123; + int c1c; + int d00d; +}; + +struct core_reloc_arrays_substruct { + int c; + int d; +}; + +struct core_reloc_arrays { + int a[5]; + char b[2][3][4]; + struct core_reloc_arrays_substruct c[3]; + struct core_reloc_arrays_substruct d[1][2]; +}; + +SEC("raw_tracepoint/sys_enter") +int test_core_arrays(void *ctx) +{ + struct core_reloc_arrays *in = (void *)&data.in; + struct core_reloc_arrays_output *out = (void *)&data.out; + + /* in->a[2] */ + if (BPF_CORE_READ(&out->a2, &in->a[2])) + return 1; + /* in->b[1][2][3] */ + if (BPF_CORE_READ(&out->b123, &in->b[1][2][3])) + return 1; + /* in->c[1].c */ + if (BPF_CORE_READ(&out->c1c, &in->c[1].c)) + return 1; + /* in->d[0][0].d */ + if (BPF_CORE_READ(&out->d00d, &in->d[0][0].d)) + return 1; + + return 0; +} + -- cgit v1.2.3-59-g8ed1b From d9db3550300f4390e457c79189e2601c107f9fe6 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 7 Aug 2019 14:39:57 -0700 Subject: selftests/bpf: add CO-RE relocs enum/ptr/func_proto tests Test CO-RE relocation handling of ints, enums, pointers, func protos, etc. Signed-off-by: Andrii Nakryiko Acked-by: Song Liu Signed-off-by: Alexei Starovoitov --- .../testing/selftests/bpf/prog_tests/core_reloc.c | 36 ++++++++++++ .../bpf/progs/btf__core_reloc_primitives.c | 3 + .../btf__core_reloc_primitives___diff_enum_def.c | 3 + .../btf__core_reloc_primitives___diff_func_proto.c | 3 + .../btf__core_reloc_primitives___diff_ptr_type.c | 3 + .../btf__core_reloc_primitives___err_non_enum.c | 3 + .../btf__core_reloc_primitives___err_non_int.c | 3 + .../btf__core_reloc_primitives___err_non_ptr.c | 3 + .../testing/selftests/bpf/progs/core_reloc_types.h | 67 ++++++++++++++++++++++ .../bpf/progs/test_core_reloc_primitives.c | 43 ++++++++++++++ 10 files changed, 167 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_primitives.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___diff_enum_def.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___diff_func_proto.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___diff_ptr_type.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___err_non_enum.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___err_non_int.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___err_non_ptr.c create mode 100644 tools/testing/selftests/bpf/progs/test_core_reloc_primitives.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/core_reloc.c b/tools/testing/selftests/bpf/prog_tests/core_reloc.c index 3b40160c0837..37b36df93ded 100644 --- a/tools/testing/selftests/bpf/prog_tests/core_reloc.c +++ b/tools/testing/selftests/bpf/prog_tests/core_reloc.c @@ -81,6 +81,32 @@ .fails = true, \ } +#define PRIMITIVES_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) { \ + .a = 1, \ + .b = 2, \ + .c = 3, \ + .d = (void *)4, \ + .f = (void *)5, \ +} + +#define PRIMITIVES_CASE_COMMON(name) \ + .case_name = #name, \ + .bpf_obj_file = "test_core_reloc_primitives.o", \ + .btf_src_file = "btf__core_reloc_" #name ".o" + +#define PRIMITIVES_CASE(name) { \ + PRIMITIVES_CASE_COMMON(name), \ + .input = PRIMITIVES_DATA(core_reloc_##name), \ + .input_len = sizeof(struct core_reloc_##name), \ + .output = PRIMITIVES_DATA(core_reloc_primitives), \ + .output_len = sizeof(struct core_reloc_primitives), \ +} + +#define PRIMITIVES_ERR_CASE(name) { \ + PRIMITIVES_CASE_COMMON(name), \ + .fails = true, \ +} + struct core_reloc_test_case { const char *case_name; const char *bpf_obj_file; @@ -137,6 +163,16 @@ static struct core_reloc_test_case test_cases[] = { ARRAYS_ERR_CASE(arrays___err_non_array), ARRAYS_ERR_CASE(arrays___err_wrong_val_type1), ARRAYS_ERR_CASE(arrays___err_wrong_val_type2), + + /* enum/ptr/int handling scenarios */ + PRIMITIVES_CASE(primitives), + PRIMITIVES_CASE(primitives___diff_enum_def), + PRIMITIVES_CASE(primitives___diff_func_proto), + PRIMITIVES_CASE(primitives___diff_ptr_type), + + PRIMITIVES_ERR_CASE(primitives___err_non_enum), + PRIMITIVES_ERR_CASE(primitives___err_non_int), + PRIMITIVES_ERR_CASE(primitives___err_non_ptr), }; struct data { diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives.c new file mode 100644 index 000000000000..96b90e39242a --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_primitives x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___diff_enum_def.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___diff_enum_def.c new file mode 100644 index 000000000000..6e87233a3ed0 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___diff_enum_def.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_primitives___diff_enum_def x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___diff_func_proto.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___diff_func_proto.c new file mode 100644 index 000000000000..d9f48e80b9d9 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___diff_func_proto.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_primitives___diff_func_proto x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___diff_ptr_type.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___diff_ptr_type.c new file mode 100644 index 000000000000..c718f75f8f3b --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___diff_ptr_type.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_primitives___diff_ptr_type x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___err_non_enum.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___err_non_enum.c new file mode 100644 index 000000000000..b8a120830891 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___err_non_enum.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_primitives___err_non_enum x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___err_non_int.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___err_non_int.c new file mode 100644 index 000000000000..ad8b3c9aa76f --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___err_non_int.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_primitives___err_non_int x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___err_non_ptr.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___err_non_ptr.c new file mode 100644 index 000000000000..e20bc1d42d0a --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_primitives___err_non_ptr.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_primitives___err_non_ptr x) {} diff --git a/tools/testing/selftests/bpf/progs/core_reloc_types.h b/tools/testing/selftests/bpf/progs/core_reloc_types.h index 45de7986ea2e..7526a5f5755b 100644 --- a/tools/testing/selftests/bpf/progs/core_reloc_types.h +++ b/tools/testing/selftests/bpf/progs/core_reloc_types.h @@ -387,3 +387,70 @@ struct core_reloc_arrays___err_wrong_val_type2 { int c[3]; /* value is not a struct */ struct core_reloc_arrays_substruct d[1][2]; }; + +/* + * PRIMITIVES + */ +enum core_reloc_primitives_enum { + A = 0, + B = 1, +}; + +struct core_reloc_primitives { + char a; + int b; + enum core_reloc_primitives_enum c; + void *d; + int (*f)(const char *); +}; + +struct core_reloc_primitives___diff_enum_def { + char a; + int b; + void *d; + int (*f)(const char *); + enum { + X = 100, + Y = 200, + } c; /* inline enum def with differing set of values */ +}; + +struct core_reloc_primitives___diff_func_proto { + void (*f)(int); /* incompatible function prototype */ + void *d; + enum core_reloc_primitives_enum c; + int b; + char a; +}; + +struct core_reloc_primitives___diff_ptr_type { + const char * const d; /* different pointee type + modifiers */ + char a; + int b; + enum core_reloc_primitives_enum c; + int (*f)(const char *); +}; + +struct core_reloc_primitives___err_non_enum { + char a[1]; + int b; + int c; /* int instead of enum */ + void *d; + int (*f)(const char *); +}; + +struct core_reloc_primitives___err_non_int { + char a[1]; + int *b; /* ptr instead of int */ + enum core_reloc_primitives_enum c; + void *d; + int (*f)(const char *); +}; + +struct core_reloc_primitives___err_non_ptr { + char a[1]; + int b; + enum core_reloc_primitives_enum c; + int d; /* int instead of ptr */ + int (*f)(const char *); +}; diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_primitives.c b/tools/testing/selftests/bpf/progs/test_core_reloc_primitives.c new file mode 100644 index 000000000000..add52f23ab35 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_primitives.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Facebook + +#include +#include +#include "bpf_helpers.h" + +char _license[] SEC("license") = "GPL"; + +static volatile struct data { + char in[256]; + char out[256]; +} data; + +enum core_reloc_primitives_enum { + A = 0, + B = 1, +}; + +struct core_reloc_primitives { + char a; + int b; + enum core_reloc_primitives_enum c; + void *d; + int (*f)(const char *); +}; + +SEC("raw_tracepoint/sys_enter") +int test_core_primitives(void *ctx) +{ + struct core_reloc_primitives *in = (void *)&data.in; + struct core_reloc_primitives *out = (void *)&data.out; + + if (BPF_CORE_READ(&out->a, &in->a) || + BPF_CORE_READ(&out->b, &in->b) || + BPF_CORE_READ(&out->c, &in->c) || + BPF_CORE_READ(&out->d, &in->d) || + BPF_CORE_READ(&out->f, &in->f)) + return 1; + + return 0; +} + -- cgit v1.2.3-59-g8ed1b From 9654e2ae908eb0d51b0b79c7c50df0754ed38edd Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 7 Aug 2019 14:39:58 -0700 Subject: selftests/bpf: add CO-RE relocs modifiers/typedef tests Add tests validating correct handling of various combinations of typedefs and const/volatile/restrict modifiers. Signed-off-by: Andrii Nakryiko Acked-by: Song Liu Signed-off-by: Alexei Starovoitov --- .../testing/selftests/bpf/prog_tests/core_reloc.c | 27 ++++++++ .../selftests/bpf/progs/btf__core_reloc_mods.c | 3 + .../bpf/progs/btf__core_reloc_mods___mod_swap.c | 3 + .../bpf/progs/btf__core_reloc_mods___typedefs.c | 3 + .../testing/selftests/bpf/progs/core_reloc_types.h | 72 ++++++++++++++++++++++ .../selftests/bpf/progs/test_core_reloc_mods.c | 62 +++++++++++++++++++ 6 files changed, 170 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_mods.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_mods___mod_swap.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_mods___typedefs.c create mode 100644 tools/testing/selftests/bpf/progs/test_core_reloc_mods.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/core_reloc.c b/tools/testing/selftests/bpf/prog_tests/core_reloc.c index 37b36df93ded..9dadf462a951 100644 --- a/tools/testing/selftests/bpf/prog_tests/core_reloc.c +++ b/tools/testing/selftests/bpf/prog_tests/core_reloc.c @@ -107,6 +107,28 @@ .fails = true, \ } +#define MODS_CASE(name) { \ + .case_name = #name, \ + .bpf_obj_file = "test_core_reloc_mods.o", \ + .btf_src_file = "btf__core_reloc_" #name ".o", \ + .input = STRUCT_TO_CHAR_PTR(core_reloc_##name) { \ + .a = 1, \ + .b = 2, \ + .c = (void *)3, \ + .d = (void *)4, \ + .e = { [2] = 5 }, \ + .f = { [1] = 6 }, \ + .g = { .x = 7 }, \ + .h = { .y = 8 }, \ + }, \ + .input_len = sizeof(struct core_reloc_##name), \ + .output = STRUCT_TO_CHAR_PTR(core_reloc_mods_output) { \ + .a = 1, .b = 2, .c = 3, .d = 4, \ + .e = 5, .f = 6, .g = 7, .h = 8, \ + }, \ + .output_len = sizeof(struct core_reloc_mods_output), \ +} + struct core_reloc_test_case { const char *case_name; const char *bpf_obj_file; @@ -173,6 +195,11 @@ static struct core_reloc_test_case test_cases[] = { PRIMITIVES_ERR_CASE(primitives___err_non_enum), PRIMITIVES_ERR_CASE(primitives___err_non_int), PRIMITIVES_ERR_CASE(primitives___err_non_ptr), + + /* const/volatile/restrict and typedefs scenarios */ + MODS_CASE(mods), + MODS_CASE(mods___mod_swap), + MODS_CASE(mods___typedefs), }; struct data { diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_mods.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_mods.c new file mode 100644 index 000000000000..124197a2e813 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_mods.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_mods x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_mods___mod_swap.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_mods___mod_swap.c new file mode 100644 index 000000000000..f8a6592ca75f --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_mods___mod_swap.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_mods___mod_swap x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_mods___typedefs.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_mods___typedefs.c new file mode 100644 index 000000000000..5c0d73687247 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_mods___typedefs.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_mods___typedefs x) {} diff --git a/tools/testing/selftests/bpf/progs/core_reloc_types.h b/tools/testing/selftests/bpf/progs/core_reloc_types.h index 7526a5f5755b..3401e8342e57 100644 --- a/tools/testing/selftests/bpf/progs/core_reloc_types.h +++ b/tools/testing/selftests/bpf/progs/core_reloc_types.h @@ -454,3 +454,75 @@ struct core_reloc_primitives___err_non_ptr { int d; /* int instead of ptr */ int (*f)(const char *); }; + +/* + * MODS + */ +struct core_reloc_mods_output { + int a, b, c, d, e, f, g, h; +}; + +typedef const int int_t; +typedef const char *char_ptr_t; +typedef const int arr_t[7]; + +struct core_reloc_mods_substruct { + int x; + int y; +}; + +typedef struct { + int x; + int y; +} core_reloc_mods_substruct_t; + +struct core_reloc_mods { + int a; + int_t b; + char *c; + char_ptr_t d; + int e[3]; + arr_t f; + struct core_reloc_mods_substruct g; + core_reloc_mods_substruct_t h; +}; + +/* a/b, c/d, e/f, and g/h pairs are swapped */ +struct core_reloc_mods___mod_swap { + int b; + int_t a; + char *d; + char_ptr_t c; + int f[3]; + arr_t e; + struct { + int y; + int x; + } h; + core_reloc_mods_substruct_t g; +}; + +typedef int int1_t; +typedef int1_t int2_t; +typedef int2_t int3_t; + +typedef int arr1_t[5]; +typedef arr1_t arr2_t; +typedef arr2_t arr3_t; +typedef arr3_t arr4_t; + +typedef const char * const volatile restrict fancy_char_ptr_t; + +typedef core_reloc_mods_substruct_t core_reloc_mods_substruct_tt; + +/* we need more typedefs */ +struct core_reloc_mods___typedefs { + core_reloc_mods_substruct_tt g; + core_reloc_mods_substruct_tt h; + arr4_t f; + arr4_t e; + fancy_char_ptr_t d; + fancy_char_ptr_t c; + int3_t b; + int3_t a; +}; diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_mods.c b/tools/testing/selftests/bpf/progs/test_core_reloc_mods.c new file mode 100644 index 000000000000..f98b942c062b --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_mods.c @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Facebook + +#include +#include +#include "bpf_helpers.h" + +char _license[] SEC("license") = "GPL"; + +static volatile struct data { + char in[256]; + char out[256]; +} data; + +struct core_reloc_mods_output { + int a, b, c, d, e, f, g, h; +}; + +typedef const int int_t; +typedef const char *char_ptr_t; +typedef const int arr_t[7]; + +struct core_reloc_mods_substruct { + int x; + int y; +}; + +typedef struct { + int x; + int y; +} core_reloc_mods_substruct_t; + +struct core_reloc_mods { + int a; + int_t b; + char *c; + char_ptr_t d; + int e[3]; + arr_t f; + struct core_reloc_mods_substruct g; + core_reloc_mods_substruct_t h; +}; + +SEC("raw_tracepoint/sys_enter") +int test_core_mods(void *ctx) +{ + struct core_reloc_mods *in = (void *)&data.in; + struct core_reloc_mods_output *out = (void *)&data.out; + + if (BPF_CORE_READ(&out->a, &in->a) || + BPF_CORE_READ(&out->b, &in->b) || + BPF_CORE_READ(&out->c, &in->c) || + BPF_CORE_READ(&out->d, &in->d) || + BPF_CORE_READ(&out->e, &in->e[2]) || + BPF_CORE_READ(&out->f, &in->f[1]) || + BPF_CORE_READ(&out->g, &in->g.x) || + BPF_CORE_READ(&out->h, &in->h.y)) + return 1; + + return 0; +} + -- cgit v1.2.3-59-g8ed1b From d698f9dbdbed036ef28a96cd34a1b5d7fe58750e Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 7 Aug 2019 14:39:59 -0700 Subject: selftests/bpf: add CO-RE relocs ptr-as-array tests Add test validating correct relocation handling for cases where pointer to something is used as an array. E.g.: int *ptr = ...; int x = ptr[42]; Signed-off-by: Andrii Nakryiko Acked-by: Song Liu Signed-off-by: Alexei Starovoitov --- .../testing/selftests/bpf/prog_tests/core_reloc.c | 20 +++++++++++++++ .../bpf/progs/btf__core_reloc_ptr_as_arr.c | 3 +++ .../progs/btf__core_reloc_ptr_as_arr___diff_sz.c | 3 +++ .../testing/selftests/bpf/progs/core_reloc_types.h | 13 ++++++++++ .../bpf/progs/test_core_reloc_ptr_as_arr.c | 30 ++++++++++++++++++++++ 5 files changed, 69 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_ptr_as_arr.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_ptr_as_arr___diff_sz.c create mode 100644 tools/testing/selftests/bpf/progs/test_core_reloc_ptr_as_arr.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/core_reloc.c b/tools/testing/selftests/bpf/prog_tests/core_reloc.c index 9dadf462a951..2cfe0bdc53f8 100644 --- a/tools/testing/selftests/bpf/prog_tests/core_reloc.c +++ b/tools/testing/selftests/bpf/prog_tests/core_reloc.c @@ -129,6 +129,22 @@ .output_len = sizeof(struct core_reloc_mods_output), \ } +#define PTR_AS_ARR_CASE(name) { \ + .case_name = #name, \ + .bpf_obj_file = "test_core_reloc_ptr_as_arr.o", \ + .btf_src_file = "btf__core_reloc_" #name ".o", \ + .input = (const char *)&(struct core_reloc_##name []){ \ + { .a = 1 }, \ + { .a = 2 }, \ + { .a = 3 }, \ + }, \ + .input_len = 3 * sizeof(struct core_reloc_##name), \ + .output = STRUCT_TO_CHAR_PTR(core_reloc_ptr_as_arr) { \ + .a = 3, \ + }, \ + .output_len = sizeof(struct core_reloc_ptr_as_arr), \ +} + struct core_reloc_test_case { const char *case_name; const char *bpf_obj_file; @@ -200,6 +216,10 @@ static struct core_reloc_test_case test_cases[] = { MODS_CASE(mods), MODS_CASE(mods___mod_swap), MODS_CASE(mods___typedefs), + + /* handling "ptr is an array" semantics */ + PTR_AS_ARR_CASE(ptr_as_arr), + PTR_AS_ARR_CASE(ptr_as_arr___diff_sz), }; struct data { diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_ptr_as_arr.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_ptr_as_arr.c new file mode 100644 index 000000000000..8da52432ba17 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_ptr_as_arr.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_ptr_as_arr x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_ptr_as_arr___diff_sz.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_ptr_as_arr___diff_sz.c new file mode 100644 index 000000000000..003acfc9a3e7 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_ptr_as_arr___diff_sz.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_ptr_as_arr___diff_sz x) {} diff --git a/tools/testing/selftests/bpf/progs/core_reloc_types.h b/tools/testing/selftests/bpf/progs/core_reloc_types.h index 3401e8342e57..c17c9279deae 100644 --- a/tools/testing/selftests/bpf/progs/core_reloc_types.h +++ b/tools/testing/selftests/bpf/progs/core_reloc_types.h @@ -526,3 +526,16 @@ struct core_reloc_mods___typedefs { int3_t b; int3_t a; }; + +/* + * PTR_AS_ARR + */ +struct core_reloc_ptr_as_arr { + int a; +}; + +struct core_reloc_ptr_as_arr___diff_sz { + int :32; /* padding */ + char __some_more_padding; + int a; +}; diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_ptr_as_arr.c b/tools/testing/selftests/bpf/progs/test_core_reloc_ptr_as_arr.c new file mode 100644 index 000000000000..526b7ddc7ea1 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_ptr_as_arr.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Facebook + +#include +#include +#include "bpf_helpers.h" + +char _license[] SEC("license") = "GPL"; + +static volatile struct data { + char in[256]; + char out[256]; +} data; + +struct core_reloc_ptr_as_arr { + int a; +}; + +SEC("raw_tracepoint/sys_enter") +int test_core_ptr_as_arr(void *ctx) +{ + struct core_reloc_ptr_as_arr *in = (void *)&data.in; + struct core_reloc_ptr_as_arr *out = (void *)&data.out; + + if (BPF_CORE_READ(&out->a, &in[2].a)) + return 1; + + return 0; +} + -- cgit v1.2.3-59-g8ed1b From c1f5e7dd19e71cd3607572bb957def618a33519a Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 7 Aug 2019 14:40:00 -0700 Subject: selftests/bpf: add CO-RE relocs ints tests Add various tests validating handling compatible/incompatible integer types. Signed-off-by: Andrii Nakryiko Acked-by: Song Liu Signed-off-by: Alexei Starovoitov --- .../testing/selftests/bpf/prog_tests/core_reloc.c | 40 ++++++++ .../selftests/bpf/progs/btf__core_reloc_ints.c | 3 + .../bpf/progs/btf__core_reloc_ints___bool.c | 3 + .../progs/btf__core_reloc_ints___err_bitfield.c | 3 + .../progs/btf__core_reloc_ints___err_wrong_sz_16.c | 3 + .../progs/btf__core_reloc_ints___err_wrong_sz_32.c | 3 + .../progs/btf__core_reloc_ints___err_wrong_sz_64.c | 3 + .../progs/btf__core_reloc_ints___err_wrong_sz_8.c | 3 + .../progs/btf__core_reloc_ints___reverse_sign.c | 3 + .../testing/selftests/bpf/progs/core_reloc_types.h | 101 +++++++++++++++++++++ .../selftests/bpf/progs/test_core_reloc_ints.c | 44 +++++++++ 11 files changed, 209 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_ints.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_ints___bool.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_bitfield.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_wrong_sz_16.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_wrong_sz_32.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_wrong_sz_64.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_wrong_sz_8.c create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_ints___reverse_sign.c create mode 100644 tools/testing/selftests/bpf/progs/test_core_reloc_ints.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/core_reloc.c b/tools/testing/selftests/bpf/prog_tests/core_reloc.c index 2cfe0bdc53f8..251ef8c518f0 100644 --- a/tools/testing/selftests/bpf/prog_tests/core_reloc.c +++ b/tools/testing/selftests/bpf/prog_tests/core_reloc.c @@ -145,6 +145,35 @@ .output_len = sizeof(struct core_reloc_ptr_as_arr), \ } +#define INTS_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) { \ + .u8_field = 1, \ + .s8_field = 2, \ + .u16_field = 3, \ + .s16_field = 4, \ + .u32_field = 5, \ + .s32_field = 6, \ + .u64_field = 7, \ + .s64_field = 8, \ +} + +#define INTS_CASE_COMMON(name) \ + .case_name = #name, \ + .bpf_obj_file = "test_core_reloc_ints.o", \ + .btf_src_file = "btf__core_reloc_" #name ".o" + +#define INTS_CASE(name) { \ + INTS_CASE_COMMON(name), \ + .input = INTS_DATA(core_reloc_##name), \ + .input_len = sizeof(struct core_reloc_##name), \ + .output = INTS_DATA(core_reloc_ints), \ + .output_len = sizeof(struct core_reloc_ints), \ +} + +#define INTS_ERR_CASE(name) { \ + INTS_CASE_COMMON(name), \ + .fails = true, \ +} + struct core_reloc_test_case { const char *case_name; const char *bpf_obj_file; @@ -220,6 +249,17 @@ static struct core_reloc_test_case test_cases[] = { /* handling "ptr is an array" semantics */ PTR_AS_ARR_CASE(ptr_as_arr), PTR_AS_ARR_CASE(ptr_as_arr___diff_sz), + + /* int signedness/sizing/bitfield handling */ + INTS_CASE(ints), + INTS_CASE(ints___bool), + INTS_CASE(ints___reverse_sign), + + INTS_ERR_CASE(ints___err_bitfield), + INTS_ERR_CASE(ints___err_wrong_sz_8), + INTS_ERR_CASE(ints___err_wrong_sz_16), + INTS_ERR_CASE(ints___err_wrong_sz_32), + INTS_ERR_CASE(ints___err_wrong_sz_64), }; struct data { diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_ints.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_ints.c new file mode 100644 index 000000000000..7d0f041042c5 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_ints.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_ints x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___bool.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___bool.c new file mode 100644 index 000000000000..f9359450186e --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___bool.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_ints___bool x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_bitfield.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_bitfield.c new file mode 100644 index 000000000000..50369e8320a0 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_bitfield.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_ints___err_bitfield x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_wrong_sz_16.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_wrong_sz_16.c new file mode 100644 index 000000000000..823bac13d641 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_wrong_sz_16.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_ints___err_wrong_sz_16 x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_wrong_sz_32.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_wrong_sz_32.c new file mode 100644 index 000000000000..b44f3be18535 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_wrong_sz_32.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_ints___err_wrong_sz_32 x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_wrong_sz_64.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_wrong_sz_64.c new file mode 100644 index 000000000000..9a3dd2099c0f --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_wrong_sz_64.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_ints___err_wrong_sz_64 x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_wrong_sz_8.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_wrong_sz_8.c new file mode 100644 index 000000000000..9f11ef5f6e88 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___err_wrong_sz_8.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_ints___err_wrong_sz_8 x) {} diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___reverse_sign.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___reverse_sign.c new file mode 100644 index 000000000000..aafb1c5819d7 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_ints___reverse_sign.c @@ -0,0 +1,3 @@ +#include "core_reloc_types.h" + +void f(struct core_reloc_ints___reverse_sign x) {} diff --git a/tools/testing/selftests/bpf/progs/core_reloc_types.h b/tools/testing/selftests/bpf/progs/core_reloc_types.h index c17c9279deae..5f3ebd4f6dc3 100644 --- a/tools/testing/selftests/bpf/progs/core_reloc_types.h +++ b/tools/testing/selftests/bpf/progs/core_reloc_types.h @@ -1,3 +1,6 @@ +#include +#include + /* * FLAVORS */ @@ -539,3 +542,101 @@ struct core_reloc_ptr_as_arr___diff_sz { char __some_more_padding; int a; }; + +/* + * INTS + */ +struct core_reloc_ints { + uint8_t u8_field; + int8_t s8_field; + uint16_t u16_field; + int16_t s16_field; + uint32_t u32_field; + int32_t s32_field; + uint64_t u64_field; + int64_t s64_field; +}; + +/* signed/unsigned types swap */ +struct core_reloc_ints___reverse_sign { + int8_t u8_field; + uint8_t s8_field; + int16_t u16_field; + uint16_t s16_field; + int32_t u32_field; + uint32_t s32_field; + int64_t u64_field; + uint64_t s64_field; +}; + +struct core_reloc_ints___bool { + bool u8_field; /* bool instead of uint8 */ + int8_t s8_field; + uint16_t u16_field; + int16_t s16_field; + uint32_t u32_field; + int32_t s32_field; + uint64_t u64_field; + int64_t s64_field; +}; + +struct core_reloc_ints___err_bitfield { + uint8_t u8_field; + int8_t s8_field; + uint16_t u16_field; + int16_t s16_field; + uint32_t u32_field: 32; /* bitfields are not supported */ + int32_t s32_field; + uint64_t u64_field; + int64_t s64_field; +}; + +struct core_reloc_ints___err_wrong_sz_8 { + uint16_t u8_field; /* not 8-bit anymore */ + int16_t s8_field; /* not 8-bit anymore */ + + uint16_t u16_field; + int16_t s16_field; + uint32_t u32_field; + int32_t s32_field; + uint64_t u64_field; + int64_t s64_field; +}; + +struct core_reloc_ints___err_wrong_sz_16 { + uint8_t u8_field; + int8_t s8_field; + + uint32_t u16_field; /* not 16-bit anymore */ + int32_t s16_field; /* not 16-bit anymore */ + + uint32_t u32_field; + int32_t s32_field; + uint64_t u64_field; + int64_t s64_field; +}; + +struct core_reloc_ints___err_wrong_sz_32 { + uint8_t u8_field; + int8_t s8_field; + uint16_t u16_field; + int16_t s16_field; + + uint64_t u32_field; /* not 32-bit anymore */ + int64_t s32_field; /* not 32-bit anymore */ + + uint64_t u64_field; + int64_t s64_field; +}; + +struct core_reloc_ints___err_wrong_sz_64 { + uint8_t u8_field; + int8_t s8_field; + uint16_t u16_field; + int16_t s16_field; + uint32_t u32_field; + int32_t s32_field; + + uint32_t u64_field; /* not 64-bit anymore */ + int32_t s64_field; /* not 64-bit anymore */ +}; diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c b/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c new file mode 100644 index 000000000000..d99233c8008a --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Facebook + +#include +#include +#include "bpf_helpers.h" + +char _license[] SEC("license") = "GPL"; + +static volatile struct data { + char in[256]; + char out[256]; +} data; + +struct core_reloc_ints { + uint8_t u8_field; + int8_t s8_field; + uint16_t u16_field; + int16_t s16_field; + uint32_t u32_field; + int32_t s32_field; + uint64_t u64_field; + int64_t s64_field; +}; + +SEC("raw_tracepoint/sys_enter") +int test_core_ints(void *ctx) +{ + struct core_reloc_ints *in = (void *)&data.in; + struct core_reloc_ints *out = (void *)&data.out; + + if (BPF_CORE_READ(&out->u8_field, &in->u8_field) || + BPF_CORE_READ(&out->s8_field, &in->s8_field) || + BPF_CORE_READ(&out->u16_field, &in->u16_field) || + BPF_CORE_READ(&out->s16_field, &in->s16_field) || + BPF_CORE_READ(&out->u32_field, &in->u32_field) || + BPF_CORE_READ(&out->s32_field, &in->s32_field) || + BPF_CORE_READ(&out->u64_field, &in->u64_field) || + BPF_CORE_READ(&out->s64_field, &in->s64_field)) + return 1; + + return 0; +} + -- cgit v1.2.3-59-g8ed1b From 29e1c66872450adba0ad552ff6019932168676f3 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 7 Aug 2019 14:40:01 -0700 Subject: selftests/bpf: add CO-RE relocs misc tests Add tests validating few edge-cases of capturing offset relocations. Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov --- .../testing/selftests/bpf/prog_tests/core_reloc.c | 19 ++++++++ .../selftests/bpf/progs/btf__core_reloc_misc.c | 5 ++ .../testing/selftests/bpf/progs/core_reloc_types.h | 25 ++++++++++ .../selftests/bpf/progs/test_core_reloc_misc.c | 57 ++++++++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/btf__core_reloc_misc.c create mode 100644 tools/testing/selftests/bpf/progs/test_core_reloc_misc.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/core_reloc.c b/tools/testing/selftests/bpf/prog_tests/core_reloc.c index 251ef8c518f0..f3863f976a48 100644 --- a/tools/testing/selftests/bpf/prog_tests/core_reloc.c +++ b/tools/testing/selftests/bpf/prog_tests/core_reloc.c @@ -260,6 +260,25 @@ static struct core_reloc_test_case test_cases[] = { INTS_ERR_CASE(ints___err_wrong_sz_16), INTS_ERR_CASE(ints___err_wrong_sz_32), INTS_ERR_CASE(ints___err_wrong_sz_64), + + /* validate edge cases of capturing relocations */ + { + .case_name = "misc", + .bpf_obj_file = "test_core_reloc_misc.o", + .btf_src_file = "btf__core_reloc_misc.o", + .input = (const char *)&(struct core_reloc_misc_extensible[]){ + { .a = 1 }, + { .a = 2 }, /* not read */ + { .a = 3 }, + }, + .input_len = 4 * sizeof(int), + .output = STRUCT_TO_CHAR_PTR(core_reloc_misc_output) { + .a = 1, + .b = 1, + .c = 0, /* BUG in clang, should be 3 */ + }, + .output_len = sizeof(struct core_reloc_misc_output), + }, }; struct data { diff --git a/tools/testing/selftests/bpf/progs/btf__core_reloc_misc.c b/tools/testing/selftests/bpf/progs/btf__core_reloc_misc.c new file mode 100644 index 000000000000..ed9ad8b5b4f8 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/btf__core_reloc_misc.c @@ -0,0 +1,5 @@ +#include "core_reloc_types.h" + +void f1(struct core_reloc_misc___a x) {} +void f2(struct core_reloc_misc___b x) {} +void f3(struct core_reloc_misc_extensible x) {} diff --git a/tools/testing/selftests/bpf/progs/core_reloc_types.h b/tools/testing/selftests/bpf/progs/core_reloc_types.h index 5f3ebd4f6dc3..10a252b6da55 100644 --- a/tools/testing/selftests/bpf/progs/core_reloc_types.h +++ b/tools/testing/selftests/bpf/progs/core_reloc_types.h @@ -640,3 +640,28 @@ struct core_reloc_ints___err_wrong_sz_64 { uint32_t u64_field; /* not 64-bit anymore */ int32_t s64_field; /* not 64-bit anymore */ }; + +/* + * MISC + */ +struct core_reloc_misc_output { + int a, b, c; +}; + +struct core_reloc_misc___a { + int a1; + int a2; +}; + +struct core_reloc_misc___b { + int b1; + int b2; +}; + +/* this one extends core_reloc_misc_extensible struct from BPF prog */ +struct core_reloc_misc_extensible { + int a; + int b; + int c; + int d; +}; diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_misc.c b/tools/testing/selftests/bpf/progs/test_core_reloc_misc.c new file mode 100644 index 000000000000..c59984bd3e23 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_misc.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Facebook + +#include +#include +#include "bpf_helpers.h" + +char _license[] SEC("license") = "GPL"; + +static volatile struct data { + char in[256]; + char out[256]; +} data; + +struct core_reloc_misc_output { + int a, b, c; +}; + +struct core_reloc_misc___a { + int a1; + int a2; +}; + +struct core_reloc_misc___b { + int b1; + int b2; +}; + +/* fixed two first members, can be extended with new fields */ +struct core_reloc_misc_extensible { + int a; + int b; +}; + +SEC("raw_tracepoint/sys_enter") +int test_core_misc(void *ctx) +{ + struct core_reloc_misc___a *in_a = (void *)&data.in; + struct core_reloc_misc___b *in_b = (void *)&data.in; + struct core_reloc_misc_extensible *in_ext = (void *)&data.in; + struct core_reloc_misc_output *out = (void *)&data.out; + + /* record two different relocations with the same accessor string */ + if (BPF_CORE_READ(&out->a, &in_a->a1) || /* accessor: 0:0 */ + BPF_CORE_READ(&out->b, &in_b->b1)) /* accessor: 0:0 */ + return 1; + + /* Validate relocations capture array-only accesses for structs with + * fixed header, but with potentially extendable tail. This will read + * first 4 bytes of 2nd element of in_ext array of potentially + * variably sized struct core_reloc_misc_extensible. */ + if (BPF_CORE_READ(&out->c, &in_ext[2])) /* accessor: 2 */ + return 1; + + return 0; +} + -- cgit v1.2.3-59-g8ed1b From b707659213d3c70f2c704ec950df6263b4bffe84 Mon Sep 17 00:00:00 2001 From: Yonghong Song Date: Wed, 7 Aug 2019 17:38:56 -0700 Subject: tools/bpf: fix core_reloc.c compilation error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On my local machine, I have the following compilation errors: ===== In file included from prog_tests/core_reloc.c:3:0: ./progs/core_reloc_types.h:517:46: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘fancy_char_ptr_t’ typedef const char * const volatile restrict fancy_char_ptr_t; ^ ./progs/core_reloc_types.h:527:2: error: unknown type name ‘fancy_char_ptr_t’ fancy_char_ptr_t d; ^ ===== I am using gcc 4.8.5. Later compilers may change their behavior not emitting the error. Nevertheless, let us fix the issue. "restrict" can be tested without typedef. Fixes: 9654e2ae908e ("selftests/bpf: add CO-RE relocs modifiers/typedef tests") Cc: Andrii Nakryiko Signed-off-by: Yonghong Song Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/progs/core_reloc_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/progs/core_reloc_types.h b/tools/testing/selftests/bpf/progs/core_reloc_types.h index 10a252b6da55..f686a8138d90 100644 --- a/tools/testing/selftests/bpf/progs/core_reloc_types.h +++ b/tools/testing/selftests/bpf/progs/core_reloc_types.h @@ -514,7 +514,7 @@ typedef arr1_t arr2_t; typedef arr2_t arr3_t; typedef arr3_t arr4_t; -typedef const char * const volatile restrict fancy_char_ptr_t; +typedef const char * const volatile fancy_char_ptr_t; typedef core_reloc_mods_substruct_t core_reloc_mods_substruct_tt; -- cgit v1.2.3-59-g8ed1b From e858ef1cd4bc1bdfcd18114a8195236e336cee42 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Mon, 5 Aug 2019 15:41:37 -0700 Subject: selftests: Add l2tp tests Add IPv4 and IPv6 l2tp tests. Current set is over IP and with IPsec. v2 - add l2tp.sh to TEST_PROGS in Makefile Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/Makefile | 2 +- tools/testing/selftests/net/l2tp.sh | 382 +++++++++++++++++++++++++++++++++++ 2 files changed, 383 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/net/l2tp.sh (limited to 'tools') diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 70f2d6656170..0bd6b23c97ef 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -10,7 +10,7 @@ TEST_PROGS += fib_tests.sh fib-onlink-tests.sh pmtu.sh udpgso.sh ip_defrag.sh TEST_PROGS += udpgso_bench.sh fib_rule_tests.sh msg_zerocopy.sh psock_snd.sh TEST_PROGS += udpgro_bench.sh udpgro.sh test_vxlan_under_vrf.sh reuseport_addr_any.sh TEST_PROGS += test_vxlan_fdb_changelink.sh so_txtime.sh ipv6_flowlabel.sh -TEST_PROGS += tcp_fastopen_backup_key.sh fcnal-test.sh +TEST_PROGS += tcp_fastopen_backup_key.sh fcnal-test.sh l2tp.sh TEST_PROGS_EXTENDED := in_netns.sh TEST_GEN_FILES = socket nettest TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy reuseport_addr_any diff --git a/tools/testing/selftests/net/l2tp.sh b/tools/testing/selftests/net/l2tp.sh new file mode 100644 index 000000000000..5782433886fc --- /dev/null +++ b/tools/testing/selftests/net/l2tp.sh @@ -0,0 +1,382 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# L2TPv3 tunnel between 2 hosts +# +# host-1 | router | host-2 +# | | +# lo l2tp | | l2tp lo +# 172.16.101.1 172.16.1.1 | | 172.16.1.2 172.16.101.2 +# fc00:101::1 fc00:1::1 | | fc00:1::2 fc00:101::2 +# | | +# eth0 | | eth0 +# 10.1.1.1 | | 10.1.2.1 +# 2001:db8:1::1 | | 2001:db8:2::1 + +VERBOSE=0 +PAUSE_ON_FAIL=no + +which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping) + +################################################################################ +# +log_test() +{ + local rc=$1 + local expected=$2 + local msg="$3" + + if [ ${rc} -eq ${expected} ]; then + printf "TEST: %-60s [ OK ]\n" "${msg}" + nsuccess=$((nsuccess+1)) + else + ret=1 + nfail=$((nfail+1)) + printf "TEST: %-60s [FAIL]\n" "${msg}" + if [ "${PAUSE_ON_FAIL}" = "yes" ]; then + echo + echo "hit enter to continue, 'q' to quit" + read a + [ "$a" = "q" ] && exit 1 + fi + fi +} + +run_cmd() +{ + local ns + local cmd + local out + local rc + + ns="$1" + shift + cmd="$*" + + if [ "$VERBOSE" = "1" ]; then + printf " COMMAND: $cmd\n" + fi + + out=$(eval ip netns exec ${ns} ${cmd} 2>&1) + rc=$? + if [ "$VERBOSE" = "1" -a -n "$out" ]; then + echo " $out" + fi + + [ "$VERBOSE" = "1" ] && echo + + return $rc +} + +################################################################################ +# create namespaces and interconnects + +create_ns() +{ + local ns=$1 + local addr=$2 + local addr6=$3 + + [ -z "${addr}" ] && addr="-" + [ -z "${addr6}" ] && addr6="-" + + ip netns add ${ns} + + ip -netns ${ns} link set lo up + if [ "${addr}" != "-" ]; then + ip -netns ${ns} addr add dev lo ${addr} + fi + if [ "${addr6}" != "-" ]; then + ip -netns ${ns} -6 addr add dev lo ${addr6} + fi + + ip -netns ${ns} ro add unreachable default metric 8192 + ip -netns ${ns} -6 ro add unreachable default metric 8192 + + ip netns exec ${ns} sysctl -qw net.ipv4.ip_forward=1 + ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1 + ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.forwarding=1 + ip netns exec ${ns} sysctl -qw net.ipv6.conf.default.forwarding=1 + ip netns exec ${ns} sysctl -qw net.ipv6.conf.default.accept_dad=0 +} + +# create veth pair to connect namespaces and apply addresses. +connect_ns() +{ + local ns1=$1 + local ns1_dev=$2 + local ns1_addr=$3 + local ns1_addr6=$4 + local ns2=$5 + local ns2_dev=$6 + local ns2_addr=$7 + local ns2_addr6=$8 + + ip -netns ${ns1} li add ${ns1_dev} type veth peer name tmp + ip -netns ${ns1} li set ${ns1_dev} up + ip -netns ${ns1} li set tmp netns ${ns2} name ${ns2_dev} + ip -netns ${ns2} li set ${ns2_dev} up + + if [ "${ns1_addr}" != "-" ]; then + ip -netns ${ns1} addr add dev ${ns1_dev} ${ns1_addr} + ip -netns ${ns2} addr add dev ${ns2_dev} ${ns2_addr} + fi + + if [ "${ns1_addr6}" != "-" ]; then + ip -netns ${ns1} addr add dev ${ns1_dev} ${ns1_addr6} + ip -netns ${ns2} addr add dev ${ns2_dev} ${ns2_addr6} + fi +} + +################################################################################ +# test setup + +cleanup() +{ + local ns + + for ns in host-1 host-2 router + do + ip netns del ${ns} 2>/dev/null + done +} + +setup_l2tp_ipv4() +{ + # + # configure l2tpv3 tunnel on host-1 + # + ip -netns host-1 l2tp add tunnel tunnel_id 1041 peer_tunnel_id 1042 \ + encap ip local 10.1.1.1 remote 10.1.2.1 + ip -netns host-1 l2tp add session name l2tp4 tunnel_id 1041 \ + session_id 1041 peer_session_id 1042 + ip -netns host-1 link set dev l2tp4 up + ip -netns host-1 addr add dev l2tp4 172.16.1.1 peer 172.16.1.2 + + # + # configure l2tpv3 tunnel on host-2 + # + ip -netns host-2 l2tp add tunnel tunnel_id 1042 peer_tunnel_id 1041 \ + encap ip local 10.1.2.1 remote 10.1.1.1 + ip -netns host-2 l2tp add session name l2tp4 tunnel_id 1042 \ + session_id 1042 peer_session_id 1041 + ip -netns host-2 link set dev l2tp4 up + ip -netns host-2 addr add dev l2tp4 172.16.1.2 peer 172.16.1.1 + + # + # add routes to loopback addresses + # + ip -netns host-1 ro add 172.16.101.2/32 via 172.16.1.2 + ip -netns host-2 ro add 172.16.101.1/32 via 172.16.1.1 +} + +setup_l2tp_ipv6() +{ + # + # configure l2tpv3 tunnel on host-1 + # + ip -netns host-1 l2tp add tunnel tunnel_id 1061 peer_tunnel_id 1062 \ + encap ip local 2001:db8:1::1 remote 2001:db8:2::1 + ip -netns host-1 l2tp add session name l2tp6 tunnel_id 1061 \ + session_id 1061 peer_session_id 1062 + ip -netns host-1 link set dev l2tp6 up + ip -netns host-1 addr add dev l2tp6 fc00:1::1 peer fc00:1::2 + + # + # configure l2tpv3 tunnel on host-2 + # + ip -netns host-2 l2tp add tunnel tunnel_id 1062 peer_tunnel_id 1061 \ + encap ip local 2001:db8:2::1 remote 2001:db8:1::1 + ip -netns host-2 l2tp add session name l2tp6 tunnel_id 1062 \ + session_id 1062 peer_session_id 1061 + ip -netns host-2 link set dev l2tp6 up + ip -netns host-2 addr add dev l2tp6 fc00:1::2 peer fc00:1::1 + + # + # add routes to loopback addresses + # + ip -netns host-1 -6 ro add fc00:101::2/128 via fc00:1::2 + ip -netns host-2 -6 ro add fc00:101::1/128 via fc00:1::1 +} + +setup() +{ + # start clean + cleanup + + set -e + create_ns host-1 172.16.101.1/32 fc00:101::1/128 + create_ns host-2 172.16.101.2/32 fc00:101::2/128 + create_ns router + + connect_ns host-1 eth0 10.1.1.1/24 2001:db8:1::1/64 \ + router eth1 10.1.1.2/24 2001:db8:1::2/64 + + connect_ns host-2 eth0 10.1.2.1/24 2001:db8:2::1/64 \ + router eth2 10.1.2.2/24 2001:db8:2::2/64 + + ip -netns host-1 ro add 10.1.2.0/24 via 10.1.1.2 + ip -netns host-1 -6 ro add 2001:db8:2::/64 via 2001:db8:1::2 + + ip -netns host-2 ro add 10.1.1.0/24 via 10.1.2.2 + ip -netns host-2 -6 ro add 2001:db8:1::/64 via 2001:db8:2::2 + + setup_l2tp_ipv4 + setup_l2tp_ipv6 + set +e +} + +setup_ipsec() +{ + # + # IPv4 + # + run_cmd host-1 ip xfrm policy add \ + src 10.1.1.1 dst 10.1.2.1 dir out \ + tmpl proto esp mode transport + + run_cmd host-1 ip xfrm policy add \ + src 10.1.2.1 dst 10.1.1.1 dir in \ + tmpl proto esp mode transport + + run_cmd host-2 ip xfrm policy add \ + src 10.1.1.1 dst 10.1.2.1 dir in \ + tmpl proto esp mode transport + + run_cmd host-2 ip xfrm policy add \ + src 10.1.2.1 dst 10.1.1.1 dir out \ + tmpl proto esp mode transport + + ip -netns host-1 xfrm state add \ + src 10.1.1.1 dst 10.1.2.1 \ + spi 0x1000 proto esp aead 'rfc4106(gcm(aes))' \ + 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode transport + + ip -netns host-1 xfrm state add \ + src 10.1.2.1 dst 10.1.1.1 \ + spi 0x1001 proto esp aead 'rfc4106(gcm(aes))' \ + 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode transport + + ip -netns host-2 xfrm state add \ + src 10.1.1.1 dst 10.1.2.1 \ + spi 0x1000 proto esp aead 'rfc4106(gcm(aes))' \ + 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode transport + + ip -netns host-2 xfrm state add \ + src 10.1.2.1 dst 10.1.1.1 \ + spi 0x1001 proto esp aead 'rfc4106(gcm(aes))' \ + 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode transport + + # + # IPV6 + # + run_cmd host-1 ip -6 xfrm policy add \ + src 2001:db8:1::1 dst 2001:db8:2::1 dir out \ + tmpl proto esp mode transport + + run_cmd host-1 ip -6 xfrm policy add \ + src 2001:db8:2::1 dst 2001:db8:1::1 dir in \ + tmpl proto esp mode transport + + run_cmd host-2 ip -6 xfrm policy add \ + src 2001:db8:1::1 dst 2001:db8:2::1 dir in \ + tmpl proto esp mode transport + + run_cmd host-2 ip -6 xfrm policy add \ + src 2001:db8:2::1 dst 2001:db8:1::1 dir out \ + tmpl proto esp mode transport + + ip -netns host-1 -6 xfrm state add \ + src 2001:db8:1::1 dst 2001:db8:2::1 \ + spi 0x1000 proto esp aead 'rfc4106(gcm(aes))' \ + 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode transport + + ip -netns host-1 -6 xfrm state add \ + src 2001:db8:2::1 dst 2001:db8:1::1 \ + spi 0x1001 proto esp aead 'rfc4106(gcm(aes))' \ + 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode transport + + ip -netns host-2 -6 xfrm state add \ + src 2001:db8:1::1 dst 2001:db8:2::1 \ + spi 0x1000 proto esp aead 'rfc4106(gcm(aes))' \ + 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode transport + + ip -netns host-2 -6 xfrm state add \ + src 2001:db8:2::1 dst 2001:db8:1::1 \ + spi 0x1001 proto esp aead 'rfc4106(gcm(aes))' \ + 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode transport +} + +teardown_ipsec() +{ + run_cmd host-1 ip xfrm state flush + run_cmd host-1 ip xfrm policy flush + run_cmd host-2 ip xfrm state flush + run_cmd host-2 ip xfrm policy flush +} + +################################################################################ +# generate traffic through tunnel for various cases + +run_ping() +{ + local desc="$1" + + run_cmd host-1 ping -c1 -w1 172.16.1.2 + log_test $? 0 "IPv4 basic L2TP tunnel ${desc}" + + run_cmd host-1 ping -c1 -w1 -I 172.16.101.1 172.16.101.2 + log_test $? 0 "IPv4 route through L2TP tunnel ${desc}" + + run_cmd host-1 ${ping6} -c1 -w1 fc00:1::2 + log_test $? 0 "IPv6 basic L2TP tunnel ${desc}" + + run_cmd host-1 ${ping6} -c1 -w1 -I fc00:101::1 fc00:101::2 + log_test $? 0 "IPv6 route through L2TP tunnel ${desc}" +} + +run_tests() +{ + local desc + + setup + run_ping + + setup_ipsec + run_ping "- with IPsec" + run_cmd host-1 ping -c1 -w1 172.16.1.2 + log_test $? 0 "IPv4 basic L2TP tunnel ${desc}" + + run_cmd host-1 ping -c1 -w1 -I 172.16.101.1 172.16.101.2 + log_test $? 0 "IPv4 route through L2TP tunnel ${desc}" + + run_cmd host-1 ${ping6} -c1 -w1 fc00:1::2 + log_test $? 0 "IPv6 basic L2TP tunnel - with IPsec" + + run_cmd host-1 ${ping6} -c1 -w1 -I fc00:101::1 fc00:101::2 + log_test $? 0 "IPv6 route through L2TP tunnel - with IPsec" + + teardown_ipsec + run_ping "- after IPsec teardown" +} + +################################################################################ +# main + +declare -i nfail=0 +declare -i nsuccess=0 + +while getopts :pv o +do + case $o in + p) PAUSE_ON_FAIL=yes;; + v) VERBOSE=$(($VERBOSE + 1));; + *) exit 1;; + esac +done + +run_tests +cleanup + +printf "\nTests passed: %3d\n" ${nsuccess} +printf "Tests failed: %3d\n" ${nfail} -- cgit v1.2.3-59-g8ed1b From 7bc161846dcf4af0485f260930d17fdd892a4980 Mon Sep 17 00:00:00 2001 From: Roman Mashak Date: Wed, 7 Aug 2019 15:57:29 -0400 Subject: tc-testing: updated skbedit action tests with batch create/delete Update TDC tests with cases varifying ability of TC to install or delete batches of skbedit actions. Signed-off-by: Roman Mashak Signed-off-by: David S. Miller --- .../tc-testing/tc-tests/actions/skbedit.json | 47 ++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json b/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json index bf5ebf59c2d4..9cdd2e31ac2c 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json @@ -670,5 +670,52 @@ "teardown": [ "$TC actions flush action skbedit" ] + }, + { + "id": "630c", + "name": "Add batch of 32 skbedit actions with all parameters and cookie", + "category": [ + "actions", + "skbedit" + ], + "setup": [ + [ + "$TC actions flush action skbedit", + 0, + 1, + 255 + ] + ], + "cmdUnderTest": "bash -c \"for i in \\`seq 1 32\\`; do cmd=\\\"action skbedit queue_mapping 2 priority 10 mark 7/0xaabbccdd ptype host inheritdsfield index \\$i cookie aabbccddeeff112233445566778800a1 \\\"; args=\"\\$args\\$cmd\"; done && $TC actions add \\$args\"", + "expExitCode": "0", + "verifyCmd": "$TC actions list action skbedit", + "matchPattern": "^[ \t]+index [0-9]+ ref", + "matchCount": "32", + "teardown": [ + "$TC actions flush action skbedit" + ] + }, + { + "id": "706d", + "name": "Delete batch of 32 skbedit actions with all parameters", + "category": [ + "actions", + "skbedit" + ], + "setup": [ + [ + "$TC actions flush action skbedit", + 0, + 1, + 255 + ], + "bash -c \"for i in \\`seq 1 32\\`; do cmd=\\\"action skbedit queue_mapping 2 priority 10 mark 7/0xaabbccdd ptype host inheritdsfield index \\$i \\\"; args=\\\"\\$args\\$cmd\\\"; done && $TC actions add \\$args\"" + ], + "cmdUnderTest": "bash -c \"for i in \\`seq 1 32\\`; do cmd=\\\"action skbedit index \\$i \\\"; args=\"\\$args\\$cmd\"; done && $TC actions del \\$args\"", + "expExitCode": "0", + "verifyCmd": "$TC actions list action skbedit", + "matchPattern": "^[ \t]+index [0-9]+ ref", + "matchCount": "0", + "teardown": [] } ] -- cgit v1.2.3-59-g8ed1b From b3e78adcbf991a4e8b2ebb23c9889e968ec76c5f Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Tue, 6 Aug 2019 17:19:22 -0700 Subject: tools: bpftool: fix error message (prog -> object) Change an error message to work for any object being pinned not just programs. Fixes: 71bb428fe2c1 ("tools: bpf: add bpftool") Signed-off-by: Jakub Kicinski Reviewed-by: Quentin Monnet Signed-off-by: Daniel Borkmann --- tools/bpf/bpftool/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c index 5215e0870bcb..c52a6ffb8949 100644 --- a/tools/bpf/bpftool/common.c +++ b/tools/bpf/bpftool/common.c @@ -237,7 +237,7 @@ int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)) fd = get_fd_by_id(id); if (fd < 0) { - p_err("can't get prog by id (%u): %s", id, strerror(errno)); + p_err("can't open object by id (%u): %s", id, strerror(errno)); return -1; } -- cgit v1.2.3-59-g8ed1b From 3c7be384fe6da0d7b1d6fc0ad6b4a33edb73aad5 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Tue, 6 Aug 2019 17:19:23 -0700 Subject: tools: bpftool: add error message on pin failure No error message is currently printed if the pin syscall itself fails. It got lost in the loadall refactoring. Fixes: 77380998d91d ("bpftool: add loadall command") Reported-by: Andy Lutomirski Signed-off-by: Jakub Kicinski Reviewed-by: Quentin Monnet Acked-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann --- tools/bpf/bpftool/common.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c index c52a6ffb8949..6a71324be628 100644 --- a/tools/bpf/bpftool/common.c +++ b/tools/bpf/bpftool/common.c @@ -204,7 +204,11 @@ int do_pin_fd(int fd, const char *name) if (err) return err; - return bpf_obj_pin(fd, name); + err = bpf_obj_pin(fd, name); + if (err) + p_err("can't pin the object (%s): %s", name, strerror(errno)); + + return err; } int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)) -- cgit v1.2.3-59-g8ed1b From 6240973e5661a83df24e35a9a9c2013496931e2b Mon Sep 17 00:00:00 2001 From: "Joel Fernandes (Google)" Date: Mon, 29 Jul 2019 08:36:05 -0400 Subject: tools/memory-model: Use cumul-fence instead of fence in ->prop example To reduce ambiguity in the more exotic ->prop ordering example, this commit uses the term cumul-fence instead of the term fence for the two fences, so that the implict ->rfe on loads/stores to Y are covered by the description. Link: https://lore.kernel.org/lkml/20190729121745.GA140682@google.com Suggested-by: Alan Stern Signed-off-by: Joel Fernandes (Google) Acked-by: Alan Stern Signed-off-by: Paul E. McKenney --- tools/memory-model/Documentation/explanation.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/memory-model/Documentation/explanation.txt b/tools/memory-model/Documentation/explanation.txt index 68caa9a976d0..634dc6db26c4 100644 --- a/tools/memory-model/Documentation/explanation.txt +++ b/tools/memory-model/Documentation/explanation.txt @@ -1302,7 +1302,7 @@ followed by an arbitrary number of cumul-fence links, ending with an rfe link. You can concoct more exotic examples, containing more than one fence, although this quickly leads to diminishing returns in terms of complexity. For instance, here's an example containing a coe link -followed by two fences and an rfe link, utilizing the fact that +followed by two cumul-fences and an rfe link, utilizing the fact that release fences are A-cumulative: int x, y, z; @@ -1334,10 +1334,10 @@ If x = 2, r0 = 1, and r2 = 1 after this code runs then there is a prop link from P0's store to its load. This is because P0's store gets overwritten by P1's store since x = 2 at the end (a coe link), the smp_wmb() ensures that P1's store to x propagates to P2 before the -store to y does (the first fence), the store to y propagates to P2 +store to y does (the first cumul-fence), the store to y propagates to P2 before P2's load and store execute, P2's smp_store_release() guarantees that the stores to x and y both propagate to P0 before the -store to z does (the second fence), and P0's load executes after the +store to z does (the second cumul-fence), and P0's load executes after the store to z has propagated to P0 (an rfe link). In summary, the fact that the hb relation links memory access events -- cgit v1.2.3-59-g8ed1b From 6738ff85c3ee8073d5b030cb26241d0009d4ce29 Mon Sep 17 00:00:00 2001 From: Andrea Parri Date: Sat, 29 Jun 2019 23:10:44 +0200 Subject: tools/memory-model: Update the informal documentation The formal memory consistency model has added support for plain accesses (and data races). While updating the informal documentation to describe this addition to the model is highly desirable and important future work, update the informal documentation to at least acknowledge such addition. Signed-off-by: Andrea Parri Cc: Will Deacon Cc: Peter Zijlstra Cc: Boqun Feng Cc: Nicholas Piggin Cc: David Howells Cc: Jade Alglave Cc: Luc Maranget Cc: "Paul E. McKenney" Cc: Akira Yokosawa Cc: Daniel Lustig Signed-off-by: Paul E. McKenney Acked-by: Alan Stern --- tools/memory-model/Documentation/explanation.txt | 47 +++++++++++------------- tools/memory-model/README | 18 ++++----- 2 files changed, 30 insertions(+), 35 deletions(-) (limited to 'tools') diff --git a/tools/memory-model/Documentation/explanation.txt b/tools/memory-model/Documentation/explanation.txt index 634dc6db26c4..488f11f6c588 100644 --- a/tools/memory-model/Documentation/explanation.txt +++ b/tools/memory-model/Documentation/explanation.txt @@ -42,7 +42,8 @@ linux-kernel.bell and linux-kernel.cat files that make up the formal version of the model; they are extremely terse and their meanings are far from clear. -This document describes the ideas underlying the LKMM. It is meant +This document describes the ideas underlying the LKMM, but excluding +the modeling of bare C (or plain) shared memory accesses. It is meant for people who want to understand how the model was designed. It does not go into the details of the code in the .bell and .cat files; rather, it explains in English what the code expresses symbolically. @@ -354,31 +355,25 @@ be extremely complex. Optimizing compilers have great freedom in the way they translate source code to object code. They are allowed to apply transformations that add memory accesses, eliminate accesses, combine them, split them -into pieces, or move them around. Faced with all these possibilities, -the LKMM basically gives up. It insists that the code it analyzes -must contain no ordinary accesses to shared memory; all accesses must -be performed using READ_ONCE(), WRITE_ONCE(), or one of the other -atomic or synchronization primitives. These primitives prevent a -large number of compiler optimizations. In particular, it is -guaranteed that the compiler will not remove such accesses from the -generated code (unless it can prove the accesses will never be -executed), it will not change the order in which they occur in the -code (within limits imposed by the C standard), and it will not -introduce extraneous accesses. - -This explains why the MP and SB examples above used READ_ONCE() and -WRITE_ONCE() rather than ordinary memory accesses. Thanks to this -usage, we can be certain that in the MP example, P0's write event to -buf really is po-before its write event to flag, and similarly for the -other shared memory accesses in the examples. - -Private variables are not subject to this restriction. Since they are -not shared between CPUs, they can be accessed normally without -READ_ONCE() or WRITE_ONCE(), and there will be no ill effects. In -fact, they need not even be stored in normal memory at all -- in -principle a private variable could be stored in a CPU register (hence -the convention that these variables have names starting with the -letter 'r'). +into pieces, or move them around. The use of READ_ONCE(), WRITE_ONCE(), +or one of the other atomic or synchronization primitives prevents a +large number of compiler optimizations. In particular, it is guaranteed +that the compiler will not remove such accesses from the generated code +(unless it can prove the accesses will never be executed), it will not +change the order in which they occur in the code (within limits imposed +by the C standard), and it will not introduce extraneous accesses. + +The MP and SB examples above used READ_ONCE() and WRITE_ONCE() rather +than ordinary memory accesses. Thanks to this usage, we can be certain +that in the MP example, the compiler won't reorder P0's write event to +buf and P0's write event to flag, and similarly for the other shared +memory accesses in the examples. + +Since private variables are not shared between CPUs, they can be +accessed normally without READ_ONCE() or WRITE_ONCE(). In fact, they +need not even be stored in normal memory at all -- in principle a +private variable could be stored in a CPU register (hence the convention +that these variables have names starting with the letter 'r'). A WARNING diff --git a/tools/memory-model/README b/tools/memory-model/README index 2b87f3971548..fc07b52f2028 100644 --- a/tools/memory-model/README +++ b/tools/memory-model/README @@ -167,15 +167,15 @@ scripts Various scripts, see scripts/README. LIMITATIONS =========== -The Linux-kernel memory model has the following limitations: - -1. Compiler optimizations are not modeled. Of course, the use - of READ_ONCE() and WRITE_ONCE() limits the compiler's ability - to optimize, but there is Linux-kernel code that uses bare C - memory accesses. Handling this code is on the to-do list. - For more information, see Documentation/explanation.txt (in - particular, the "THE PROGRAM ORDER RELATION: po AND po-loc" - and "A WARNING" sections). +The Linux-kernel memory model (LKMM) has the following limitations: + +1. Compiler optimizations are not accurately modeled. Of course, + the use of READ_ONCE() and WRITE_ONCE() limits the compiler's + ability to optimize, but under some circumstances it is possible + for the compiler to undermine the memory model. For more + information, see Documentation/explanation.txt (in particular, + the "THE PROGRAM ORDER RELATION: po AND po-loc" and "A WARNING" + sections). Note that this limitation in turn limits LKMM's ability to accurately model address, control, and data dependencies. -- cgit v1.2.3-59-g8ed1b From 609a2ca57afc467fbc46b7f3453de4e1811456c5 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Thu, 8 Aug 2019 13:57:26 +0200 Subject: bpf: sync bpf.h to tools infrastructure Pull in updates in BPF helper function description. Signed-off-by: Daniel Borkmann Signed-off-by: David S. Miller --- tools/include/uapi/linux/bpf.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 4e455018da65..a5aa7d3ac6a1 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -1466,8 +1466,8 @@ union bpf_attr { * If no cookie has been set yet, generate a new cookie. Once * generated, the socket cookie remains stable for the life of the * socket. This helper can be useful for monitoring per socket - * networking traffic statistics as it provides a unique socket - * identifier per namespace. + * networking traffic statistics as it provides a global socket + * identifier that can be assumed unique. * Return * A 8-byte long non-decreasing number on success, or 0 if the * socket field is missing inside *skb*. @@ -1571,8 +1571,11 @@ union bpf_attr { * but this is only implemented for native XDP (with driver * support) as of this writing). * - * All values for *flags* are reserved for future usage, and must - * be left at zero. + * The lower two bits of *flags* are used as the return code if + * the map lookup fails. This is so that the return value can be + * one of the XDP program return codes up to XDP_TX, as chosen by + * the caller. Any higher bits in the *flags* argument must be + * unset. * * When used to redirect packets to net devices, this helper * provides a high performance increase over **bpf_redirect**\ (). -- cgit v1.2.3-59-g8ed1b From f887427b2cecfb57165f0207b33aed89dd29ab61 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Fri, 9 Aug 2019 16:13:38 -0700 Subject: selftests: Fix detection of nettest command in fcnal-test Most of the tests run by fcnal-test.sh relies on the nettest command. Rather than trying to cover all of the individual tests, check for the binary only at the beginning. Also removes the need for log_error which is undefined. Fixes: 6f9d5cacfe07 ("selftests: Setup for functional tests for fib and socket lookups") Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/fcnal-test.sh | 38 +++++-------------------------- 1 file changed, 6 insertions(+), 32 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh index bd6b564382ec..9fd3a0b97f0d 100755 --- a/tools/testing/selftests/net/fcnal-test.sh +++ b/tools/testing/selftests/net/fcnal-test.sh @@ -998,13 +998,6 @@ ipv4_tcp_vrf() ipv4_tcp() { log_section "IPv4/TCP" - - which nettest >/dev/null - if [ $? -ne 0 ]; then - log_error "nettest not found; skipping tests" - return - fi - log_subsection "No VRF" setup @@ -1375,12 +1368,6 @@ ipv4_udp_vrf() ipv4_udp() { - which nettest >/dev/null - if [ $? -ne 0 ]; then - log_error "nettest not found; skipping tests" - return - fi - log_section "IPv4/UDP" log_subsection "No VRF" @@ -2314,13 +2301,6 @@ ipv6_tcp_vrf() ipv6_tcp() { log_section "IPv6/TCP" - - which nettest >/dev/null - if [ $? -ne 0 ]; then - log_error "nettest not found; skipping tests" - return - fi - log_subsection "No VRF" setup @@ -3156,12 +3136,6 @@ netfilter_icmp() ipv4_netfilter() { - which nettest >/dev/null - if [ $? -ne 0 ]; then - log_error "nettest not found; skipping tests" - return - fi - log_section "IPv4 Netfilter" log_subsection "TCP reset" @@ -3219,12 +3193,6 @@ netfilter_icmp6() ipv6_netfilter() { - which nettest >/dev/null - if [ $? -ne 0 ]; then - log_error "nettest not found; skipping tests" - return - fi - log_section "IPv6 Netfilter" log_subsection "TCP reset" @@ -3422,6 +3390,12 @@ elif [ "$TESTS" = "ipv6" ]; then TESTS="$TESTS_IPV6" fi +which nettest >/dev/null +if [ $? -ne 0 ]; then + echo "'nettest' command not found; skipping tests" + exit 0 +fi + declare -i nfail=0 declare -i nsuccess=0 -- cgit v1.2.3-59-g8ed1b From 62ad42ec9c4933f8973e5a28d9abdb63f8f901a0 Mon Sep 17 00:00:00 2001 From: Roman Mashak Date: Fri, 9 Aug 2019 18:46:40 -0400 Subject: tc-testing: added tdc tests for matchall filter Signed-off-by: Roman Mashak Signed-off-by: David S. Miller --- .../tc-testing/tc-tests/filters/matchall.json | 391 +++++++++++++++++++++ 1 file changed, 391 insertions(+) create mode 100644 tools/testing/selftests/tc-testing/tc-tests/filters/matchall.json (limited to 'tools') diff --git a/tools/testing/selftests/tc-testing/tc-tests/filters/matchall.json b/tools/testing/selftests/tc-testing/tc-tests/filters/matchall.json new file mode 100644 index 000000000000..5f24c0598624 --- /dev/null +++ b/tools/testing/selftests/tc-testing/tc-tests/filters/matchall.json @@ -0,0 +1,391 @@ +[ + { + "id": "f62b", + "name": "Add ingress matchall filter for protocol ipv4 and action PASS", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 ingress" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ip matchall action ok", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol ip matchall", + "matchPattern": "^filter parent ffff: protocol ip pref 1 matchall.*handle 0x1.*gact action pass.*ref 1 bind 1", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "7f09", + "name": "Add egress matchall filter for protocol ipv4 and action PASS", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 root handle 1: prio" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent 1: handle 0x1 prio 1 protocol ip matchall action ok", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent 1: handle 1 prio 1 protocol ip matchall", + "matchPattern": "^filter parent 1: protocol ip pref 1 matchall.*handle 0x1.*gact action pass.*ref 1 bind 1", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 root handle 1: prio", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "0596", + "name": "Add ingress matchall filter for protocol ipv6 and action DROP", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 ingress" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv6 matchall action drop", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol ipv6 matchall", + "matchPattern": "^filter parent ffff: protocol ipv6 pref 1 matchall.*handle 0x1.*gact action drop.*ref 1 bind 1", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "41df", + "name": "Add egress matchall filter for protocol ipv6 and action DROP", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 root handle 1: prio" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent 1: handle 0x1 prio 1 protocol ipv6 matchall action drop", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent 1: handle 1 prio 1 protocol ipv6 matchall", + "matchPattern": "^filter parent 1: protocol ipv6 pref 1 matchall.*handle 0x1.*gact action drop.*ref 1 bind 1", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 root handle 1: prio", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "e1da", + "name": "Add ingress matchall filter for protocol ipv4 and action PASS with priority at 16-bit maximum", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 ingress" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 65535 protocol ipv4 matchall action pass", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 65535 protocol ipv4 matchall", + "matchPattern": "^filter parent ffff: protocol ip pref 65535 matchall.*handle 0x1.*gact action pass.*ref 1 bind 1", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "3de5", + "name": "Add egress matchall filter for protocol ipv4 and action PASS with priority at 16-bit maximum", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 root handle 1: prio" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent 1: handle 0x1 prio 65535 protocol ipv4 matchall action pass", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent 1: handle 1 prio 65535 protocol ipv4 matchall", + "matchPattern": "^filter parent 1: protocol ip pref 65535 matchall.*handle 0x1.*gact action pass.*ref 1 bind 1", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 root handle 1: prio", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "72d7", + "name": "Add ingress matchall filter for protocol ipv4 and action PASS with priority exceeding 16-bit maximum", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 ingress" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 655355 protocol ipv4 matchall action pass", + "expExitCode": "255", + "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 655355 protocol ipv4 matchall", + "matchPattern": "^filter parent ffff: protocol ip pref 655355 matchall.*handle 0x1.*gact action pass.*ref 1 bind 1", + "matchCount": "0", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "41d3", + "name": "Add egress matchall filter for protocol ipv4 and action PASS with priority exceeding 16-bit maximum", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 root handle 1: prio" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent 1: handle 0x1 prio 655355 protocol ipv4 matchall action pass", + "expExitCode": "255", + "verifyCmd": "$TC filter get dev $DEV1 parent 1: handle 1 prio 655355 protocol ipv4 matchall", + "matchPattern": "^filter parent 1: protocol ip pref 655355 matchall.*handle 0x1.*gact action pass.*ref 1 bind 1", + "matchCount": "0", + "teardown": [ + "$TC qdisc del dev $DEV1 root handle 1: prio", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "f755", + "name": "Add ingress matchall filter for all protocols and action CONTINUE with handle at 32-bit maximum", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 ingress" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0xffffffff prio 1 protocol all matchall action continue", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 0xffffffff prio 1 protocol all matchall", + "matchPattern": "^filter parent ffff: protocol all pref 1 matchall.*handle 0xffffffff.*gact action continue.*ref 1 bind 1", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "2c33", + "name": "Add egress matchall filter for all protocols and action CONTINUE with handle at 32-bit maximum", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 root handle 1: prio" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent 1: handle 0xffffffff prio 1 protocol all matchall action continue", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent 1: handle 0xffffffff prio 1 protocol all matchall", + "matchPattern": "^filter parent 1: protocol all pref 1 matchall.*handle 0xffffffff.*gact action continue.*ref 1 bind 1", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 root handle 1: prio", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "0e4a", + "name": "Add ingress matchall filter for all protocols and action RECLASSIFY with skip_hw flag", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 ingress" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol all matchall skip_hw action reclassify", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 0x1 prio 1 protocol all matchall", + "matchPattern": "^filter parent ffff: protocol all pref 1 matchall.*handle 0x1.*skip_hw.*not_in_hw.*gact action reclassify.*ref 1 bind 1", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "7f60", + "name": "Add egress matchall filter for all protocols and action RECLASSIFY with skip_hw flag", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 root handle 1: prio" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent 1: handle 0x1 prio 1 protocol all matchall skip_hw action reclassify", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent 1: handle 0x1 prio 1 protocol all matchall", + "matchPattern": "^filter parent 1: protocol all pref 1 matchall.*handle 0x1.*skip_hw.*not_in_hw.*gact action reclassify.*ref 1 bind 1", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 root handle 1: prio", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "8bd2", + "name": "Add ingress matchall filter for protocol ipv6 and action PASS with classid", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 ingress" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv6 matchall classid 1:1 action pass", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv6 matchall", + "matchPattern": "^filter parent ffff: protocol ipv6 pref 1 matchall.*handle 0x1.*flowid 1:1.*gact action pass.*ref 1 bind 1", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "2a4a", + "name": "Add ingress matchall filter for protocol ipv6 and action PASS with invalid classid", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 ingress" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv6 matchall classid 6789defg action pass", + "expExitCode": "1", + "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv6 matchall", + "matchPattern": "^filter protocol ipv6 pref 1 matchall.*handle 0x1.*flowid 6789defg.*gact action pass.*ref 1 bind 1", + "matchCount": "0", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "eaf8", + "name": "Delete single ingress matchall filter", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 ingress", + "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv6 matchall classid 1:2 action pass" + ], + "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv6 matchall", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv6 matchall", + "matchPattern": "^filter protocol ipv6 pref 1 matchall.*handle 0x1.*flowid 1:2.*gact action pass.*ref 1 bind 1", + "matchCount": "0", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "76ad", + "name": "Delete all ingress matchall filters", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 ingress", + "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol all matchall classid 1:2 action pass", + "$TC filter add dev $DEV1 parent ffff: handle 0x2 prio 2 protocol all matchall classid 1:3 action pass", + "$TC filter add dev $DEV1 parent ffff: handle 0x3 prio 3 protocol all matchall classid 1:4 action pass", + "$TC filter add dev $DEV1 parent ffff: handle 0x4 prio 4 protocol all matchall classid 1:5 action pass" + ], + "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff:", + "expExitCode": "0", + "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", + "matchPattern": "^filter protocol all pref.*matchall.*handle.*flowid.*gact action pass", + "matchCount": "0", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "1eb9", + "name": "Delete single ingress matchall filter out of multiple", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 ingress", + "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol all matchall classid 1:2 action pass", + "$TC filter add dev $DEV1 parent ffff: handle 0x2 prio 2 protocol all matchall classid 1:3 action pass", + "$TC filter add dev $DEV1 parent ffff: handle 0x3 prio 3 protocol all matchall classid 1:4 action pass", + "$TC filter add dev $DEV1 parent ffff: handle 0x4 prio 4 protocol all matchall classid 1:5 action pass" + ], + "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: protocol all handle 0x2 prio 2 matchall", + "expExitCode": "0", + "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", + "matchPattern": "^filter protocol all pref 2 matchall.*handle 0x2 flowid 1:2.*gact action pass", + "matchCount": "0", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "6d63", + "name": "Delete ingress matchall filter by chain ID", + "category": [ + "filter", + "matchall" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 ingress", + "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol all chain 1 matchall classid 1:1 action pass", + "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv4 chain 2 matchall classid 1:3 action continue" + ], + "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: chain 2", + "expExitCode": "0", + "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", + "matchPattern": "^filter protocol all pref 1 matchall chain 1 handle 0x1 flowid 1:1.*gact action pass", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "$IP link del dev $DEV1 type dummy" + ] + } +] -- cgit v1.2.3-59-g8ed1b From a664a834579ae8a6166ac9e5a3232976cab2c24d Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Fri, 9 Aug 2019 01:39:11 +0100 Subject: tools: bpftool: fix reading from /proc/config.gz /proc/config has never existed as far as I can see, but /proc/config.gz is present on Arch Linux. Add support for decompressing config.gz using zlib which is a mandatory dependency of libelf anyway. Replace existing stdio functions with gzFile operations since the latter transparently handles uncompressed and gzip-compressed files. Cc: Quentin Monnet Signed-off-by: Peter Wu Reviewed-by: Quentin Monnet Signed-off-by: Daniel Borkmann --- tools/bpf/bpftool/Makefile | 2 +- tools/bpf/bpftool/feature.c | 105 ++++++++++++++++++++++---------------------- 2 files changed, 54 insertions(+), 53 deletions(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile index a7afea4dec47..078bd0dcfba5 100644 --- a/tools/bpf/bpftool/Makefile +++ b/tools/bpf/bpftool/Makefile @@ -52,7 +52,7 @@ ifneq ($(EXTRA_LDFLAGS),) LDFLAGS += $(EXTRA_LDFLAGS) endif -LIBS = -lelf $(LIBBPF) +LIBS = -lelf -lz $(LIBBPF) INSTALL ?= install RM ?= rm -f diff --git a/tools/bpf/bpftool/feature.c b/tools/bpf/bpftool/feature.c index d672d9086fff..03bdc5b3ac49 100644 --- a/tools/bpf/bpftool/feature.c +++ b/tools/bpf/bpftool/feature.c @@ -14,6 +14,7 @@ #include #include +#include #include "main.h" @@ -284,34 +285,32 @@ static void probe_jit_limit(void) } } -static char *get_kernel_config_option(FILE *fd, const char *option) +static bool read_next_kernel_config_option(gzFile file, char *buf, size_t n, + char **value) { - size_t line_n = 0, optlen = strlen(option); - char *res, *strval, *line = NULL; - ssize_t n; + char *sep; - rewind(fd); - while ((n = getline(&line, &line_n, fd)) > 0) { - if (strncmp(line, option, optlen)) + while (gzgets(file, buf, n)) { + if (strncmp(buf, "CONFIG_", 7)) continue; - /* Check we have at least '=', value, and '\n' */ - if (strlen(line) < optlen + 3) - continue; - if (*(line + optlen) != '=') + + sep = strchr(buf, '='); + if (!sep) continue; /* Trim ending '\n' */ - line[strlen(line) - 1] = '\0'; + buf[strlen(buf) - 1] = '\0'; + + /* Split on '=' and ensure that a value is present. */ + *sep = '\0'; + if (!sep[1]) + continue; - /* Copy and return config option value */ - strval = line + optlen + 1; - res = strdup(strval); - free(line); - return res; + *value = sep + 1; + return true; } - free(line); - return NULL; + return false; } static void probe_kernel_image_config(void) @@ -386,59 +385,61 @@ static void probe_kernel_image_config(void) /* test_bpf module for BPF tests */ "CONFIG_TEST_BPF", }; - char *value, *buf = NULL; + char *values[ARRAY_SIZE(options)] = { }; struct utsname utsn; char path[PATH_MAX]; - size_t i, n; - ssize_t ret; - FILE *fd; + gzFile file = NULL; + char buf[4096]; + char *value; + size_t i; - if (uname(&utsn)) - goto no_config; + if (!uname(&utsn)) { + snprintf(path, sizeof(path), "/boot/config-%s", utsn.release); - snprintf(path, sizeof(path), "/boot/config-%s", utsn.release); + /* gzopen also accepts uncompressed files. */ + file = gzopen(path, "r"); + } - fd = fopen(path, "r"); - if (!fd && errno == ENOENT) { - /* Some distributions put the config file at /proc/config, give - * it a try. - * Sometimes it is also at /proc/config.gz but we do not try - * this one for now, it would require linking against libz. + if (!file) { + /* Some distributions build with CONFIG_IKCONFIG=y and put the + * config file at /proc/config.gz. */ - fd = fopen("/proc/config", "r"); + file = gzopen("/proc/config.gz", "r"); } - if (!fd) { + if (!file) { p_info("skipping kernel config, can't open file: %s", strerror(errno)); - goto no_config; + goto end_parse; } /* Sanity checks */ - ret = getline(&buf, &n, fd); - ret = getline(&buf, &n, fd); - if (!buf || !ret) { + if (!gzgets(file, buf, sizeof(buf)) || + !gzgets(file, buf, sizeof(buf))) { p_info("skipping kernel config, can't read from file: %s", strerror(errno)); - free(buf); - goto no_config; + goto end_parse; } if (strcmp(buf, "# Automatically generated file; DO NOT EDIT.\n")) { p_info("skipping kernel config, can't find correct file"); - free(buf); - goto no_config; + goto end_parse; } - free(buf); - for (i = 0; i < ARRAY_SIZE(options); i++) { - value = get_kernel_config_option(fd, options[i]); - print_kernel_option(options[i], value); - free(value); + while (read_next_kernel_config_option(file, buf, sizeof(buf), &value)) { + for (i = 0; i < ARRAY_SIZE(options); i++) { + if (values[i] || strcmp(buf, options[i])) + continue; + + values[i] = strdup(value); + } } - fclose(fd); - return; -no_config: - for (i = 0; i < ARRAY_SIZE(options); i++) - print_kernel_option(options[i], NULL); +end_parse: + if (file) + gzclose(file); + + for (i = 0; i < ARRAY_SIZE(options); i++) { + print_kernel_option(options[i], values[i]); + free(values[i]); + } } static bool probe_bpf_syscall(const char *define_prefix) -- cgit v1.2.3-59-g8ed1b From 57fc032ad643ffd018d66bd4c1bd3a91de4841e8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 30 Jul 2019 10:58:41 -0300 Subject: perf session: Avoid infinite loop when seeing invalid header.size Vince reported that when fuzzing the userland perf tool with a bogus perf.data file he got into a infinite loop in 'perf report'. Changing the return of fetch_mmaped_event() to ERR_PTR(-EINVAL) for that case gets us out of that infinite loop. Reported-by: Vince Weaver Tested-by: Vince Weaver Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lkml.kernel.org/r/20190726211415.GE24867@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 11e6093c941b..b9fe71d11bf6 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include #include #include @@ -1955,7 +1956,9 @@ fetch_mmaped_event(struct perf_session *session, /* We're not fetching the event so swap back again */ if (session->header.needs_swap) perf_event_header__bswap(&event->header); - return NULL; + pr_debug("%s: head=%#" PRIx64 " event->header_size=%#x, mmap_size=%#zx: fuzzed perf.data?\n", + __func__, head, event->header.size, mmap_size); + return ERR_PTR(-EINVAL); } return event; @@ -1973,6 +1976,9 @@ static int __perf_session__process_decomp_events(struct perf_session *session) while (decomp->head < decomp->size && !session_done()) { union perf_event *event = fetch_mmaped_event(session, decomp->head, decomp->size, decomp->data); + if (IS_ERR(event)) + return PTR_ERR(event); + if (!event) break; @@ -2072,6 +2078,9 @@ remap: more: event = fetch_mmaped_event(session, head, mmap_size, buf); + if (IS_ERR(event)) + return PTR_ERR(event); + if (!event) { if (mmaps[map_idx]) { munmap(mmaps[map_idx], mmap_size); -- cgit v1.2.3-59-g8ed1b From 61a461fcbd62d42c29a1ea6a9cc3838ad9f49401 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 30 Jul 2019 11:20:55 -0300 Subject: perf config: Honour $PERF_CONFIG env var to specify alternate .perfconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We had this comment in Documentation/perf_counter/config.c, i.e. since when we got this from the git sources, but never really did that getenv("PERF_CONFIG"), do it now as I need to disable whatever ~/.perfconfig root has so that tests parsing tool output are done for the expected default output or that we specify an alternate config file that when read will make the tools produce expected output. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Taeung Song Fixes: 078006012401 ("perf_counter tools: add in basic glue from Git") Link: https://lkml.kernel.org/n/tip-jo209zac9rut0dz1rqvbdlgm@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/perf.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 97e2628ea5dd..d4e4d53e8b44 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -441,6 +441,9 @@ int main(int argc, const char **argv) srandom(time(NULL)); + /* Setting $PERF_CONFIG makes perf read _only_ the given config file. */ + config_exclusive_filename = getenv("PERF_CONFIG"); + err = perf_config(perf_default_config, NULL); if (err) return err; -- cgit v1.2.3-59-g8ed1b From 5de9e5fda05b580c036e1fec6e2d8bf78eb2ac9d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 30 Jul 2019 11:30:37 -0300 Subject: perf config: Document the PERF_CONFIG environment variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There was a provision for setting this variable, but not the getenv("PERF_CONFIG") call to set it, as this was fixed in the previous cset, document that it can be used to ask for using an alternative .perfconfig file or to disable reading whatever file exists in the system or home directory, i.e. using: export PERF_CONFIG=/dev/null Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Taeung Song Link: https://lkml.kernel.org/n/tip-0u4o967hsk7j0o50zp9ctn89@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-config.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index e4aa268d2e38..c599623a1f3d 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -40,6 +40,10 @@ The '$HOME/.perfconfig' file is used to store a per-user configuration. The file '$(sysconfdir)/perfconfig' can be used to store a system-wide default configuration. +One an disable reading config files by setting the PERF_CONFIG environment +variable to /dev/null, or provide an alternate config file by setting that +variable. + When reading or writing, the values are read from the system and user configuration files by default, and options '--system' and '--user' can be used to tell the command to read from or write to only that location. -- cgit v1.2.3-59-g8ed1b From 4fe94ce1c6ba678b5f12b94bb9996eea4fc99e85 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 30 Jul 2019 11:37:44 -0300 Subject: perf test vfs_getname: Disable ~/.perfconfig to get default output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To get the expected output we have to ignore whatever changes the user has in its ~/.perfconfig file, so set PERF_CONFIG to /dev/null to achieve that. Before: # egrep 'trace|show_' ~/.perfconfig [trace] show_zeros = yes show_duration = no show_timestamp = no show_arg_names = no show_prefix = yes # echo $PERF_CONFIG # perf test "trace + vfs_getname" 70: Check open filename arg using perf trace + vfs_getname: FAILED! # export PERF_CONFIG=/dev/null # perf test "trace + vfs_getname" 70: Check open filename arg using perf trace + vfs_getname: Ok # After: # egrep 'trace|show_' ~/.perfconfig [trace] show_zeros = yes show_duration = no show_timestamp = no show_arg_names = no show_prefix = yes # echo $PERF_CONFIG # perf test "trace + vfs_getname" 70: Check open filename arg using perf trace + vfs_getname: Ok # Cc: Adrian Hunter Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Taeung Song Link: https://lkml.kernel.org/n/tip-3up27pexg5i3exuzqrvt4m8u@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/trace+probe_vfs_getname.sh | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/perf/tests/shell/trace+probe_vfs_getname.sh b/tools/perf/tests/shell/trace+probe_vfs_getname.sh index 45d269b0157e..11cc2af13f2b 100755 --- a/tools/perf/tests/shell/trace+probe_vfs_getname.sh +++ b/tools/perf/tests/shell/trace+probe_vfs_getname.sh @@ -32,6 +32,10 @@ if [ $err -ne 0 ] ; then exit $err fi +# Do not use whatever ~/.perfconfig file, it may change the output +# via trace.{show_timestamp,show_prefix,etc} +export PERF_CONFIG=/dev/null + trace_open_vfs_getname err=$? rm -f ${file} -- cgit v1.2.3-59-g8ed1b From 2b75863b0845764529e01014a5c90664d8044cbe Mon Sep 17 00:00:00 2001 From: Luke Mujica Date: Fri, 19 Jul 2019 13:22:53 -0700 Subject: perf tools: Fix paths in include statements These paths point to the wrong location but still work because they get picked up by a -I flag that happens to direct to the correct file. Fix paths to lead to the actual file location without help from include flags. Signed-off-by: Luke Mujica Cc: Alexander Shishkin Cc: Ian Rogers Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/20190719202253.220261-1-lukemujica@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/util/kvm-stat.c | 4 ++-- tools/perf/arch/x86/util/tsc.c | 6 +++--- tools/perf/ui/helpline.c | 4 ++-- tools/perf/ui/util.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/x86/util/kvm-stat.c b/tools/perf/arch/x86/util/kvm-stat.c index 54a3f2373c35..81b531a707bf 100644 --- a/tools/perf/arch/x86/util/kvm-stat.c +++ b/tools/perf/arch/x86/util/kvm-stat.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include -#include "../../util/kvm-stat.h" -#include "../../util/evsel.h" +#include "../../../util/kvm-stat.h" +#include "../../../util/evsel.h" #include #include #include diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c index 950539f9a4f7..b1eb963b4a6e 100644 --- a/tools/perf/arch/x86/util/tsc.c +++ b/tools/perf/arch/x86/util/tsc.c @@ -5,10 +5,10 @@ #include #include -#include "../../perf.h" +#include "../../../perf.h" #include -#include "../../util/debug.h" -#include "../../util/tsc.h" +#include "../../../util/debug.h" +#include "../../../util/tsc.h" int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc, struct perf_tsc_conversion *tc) diff --git a/tools/perf/ui/helpline.c b/tools/perf/ui/helpline.c index b3c421429ed4..54bcd08df87e 100644 --- a/tools/perf/ui/helpline.c +++ b/tools/perf/ui/helpline.c @@ -3,10 +3,10 @@ #include #include -#include "../debug.h" +#include "../util/debug.h" #include "helpline.h" #include "ui.h" -#include "../util.h" +#include "../util/util.h" char ui_helpline__current[512]; diff --git a/tools/perf/ui/util.c b/tools/perf/ui/util.c index 63bf06e80ab9..9ed76e88a3e4 100644 --- a/tools/perf/ui/util.c +++ b/tools/perf/ui/util.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "util.h" -#include "../debug.h" +#include "../util/debug.h" /* -- cgit v1.2.3-59-g8ed1b From b115df076d337a727017538d11d7d46f5bcbff15 Mon Sep 17 00:00:00 2001 From: Haiyan Song Date: Wed, 12 Jun 2019 16:15:42 +0800 Subject: perf vendor events intel: Add Icelake V1.00 event file Add a Intel event file for perf. Signed-off-by: Haiyan Song Reviewed-by: Kan Liang Cc: Alexander Shishkin Cc: Andi Kleen Cc: Jin Yao Cc: Jiri Olsa Cc: Peter Zijlstra Link: https://lkml.kernel.org/r/8859095e-5b02-d6b7-fbdc-3f42b714bae0@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/pmu-events/arch/x86/icelake/cache.json | 552 +++++++++++++ .../arch/x86/icelake/floating-point.json | 102 +++ .../perf/pmu-events/arch/x86/icelake/frontend.json | 424 ++++++++++ tools/perf/pmu-events/arch/x86/icelake/memory.json | 410 ++++++++++ tools/perf/pmu-events/arch/x86/icelake/other.json | 121 +++ .../perf/pmu-events/arch/x86/icelake/pipeline.json | 892 +++++++++++++++++++++ .../arch/x86/icelake/virtual-memory.json | 236 ++++++ tools/perf/pmu-events/arch/x86/mapfile.csv | 2 + 8 files changed, 2739 insertions(+) create mode 100644 tools/perf/pmu-events/arch/x86/icelake/cache.json create mode 100644 tools/perf/pmu-events/arch/x86/icelake/floating-point.json create mode 100644 tools/perf/pmu-events/arch/x86/icelake/frontend.json create mode 100644 tools/perf/pmu-events/arch/x86/icelake/memory.json create mode 100644 tools/perf/pmu-events/arch/x86/icelake/other.json create mode 100644 tools/perf/pmu-events/arch/x86/icelake/pipeline.json create mode 100644 tools/perf/pmu-events/arch/x86/icelake/virtual-memory.json (limited to 'tools') diff --git a/tools/perf/pmu-events/arch/x86/icelake/cache.json b/tools/perf/pmu-events/arch/x86/icelake/cache.json new file mode 100644 index 000000000000..3529fc338c17 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/icelake/cache.json @@ -0,0 +1,552 @@ +[ + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of demand Data Read requests that miss L2 cache. Only not rejected loads are counted.", + "EventCode": "0x24", + "Counter": "0,1,2,3", + "UMask": "0x21", + "PEBScounters": "0,1,2,3", + "EventName": "L2_RQSTS.DEMAND_DATA_RD_MISS", + "SampleAfterValue": "200003", + "BriefDescription": "Demand Data Read miss L2, no rejects" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the RFO (Read-for-Ownership) requests that miss L2 cache.", + "EventCode": "0x24", + "Counter": "0,1,2,3", + "UMask": "0x22", + "PEBScounters": "0,1,2,3", + "EventName": "L2_RQSTS.RFO_MISS", + "SampleAfterValue": "200003", + "BriefDescription": "RFO requests that miss L2 cache" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts L2 cache misses when fetching instructions.", + "EventCode": "0x24", + "Counter": "0,1,2,3", + "UMask": "0x24", + "PEBScounters": "0,1,2,3", + "EventName": "L2_RQSTS.CODE_RD_MISS", + "SampleAfterValue": "200003", + "BriefDescription": "L2 cache misses when fetching instructions" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts demand requests that miss L2 cache.", + "EventCode": "0x24", + "Counter": "0,1,2,3", + "UMask": "0x27", + "PEBScounters": "0,1,2,3", + "EventName": "L2_RQSTS.ALL_DEMAND_MISS", + "SampleAfterValue": "200003", + "BriefDescription": "Demand requests that miss L2 cache" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts Software prefetch requests that miss the L2 cache. This event accounts for PREFETCHNTA and PREFETCHT0/1/2 instructions.", + "EventCode": "0x24", + "Counter": "0,1,2,3", + "UMask": "0x28", + "PEBScounters": "0,1,2,3", + "EventName": "L2_RQSTS.SWPF_MISS", + "SampleAfterValue": "200003", + "BriefDescription": "SW prefetch requests that miss L2 cache." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of demand Data Read requests initiated by load instructions that hit L2 cache.", + "EventCode": "0x24", + "Counter": "0,1,2,3", + "UMask": "0xc1", + "PEBScounters": "0,1,2,3", + "EventName": "L2_RQSTS.DEMAND_DATA_RD_HIT", + "SampleAfterValue": "200003", + "BriefDescription": "Demand Data Read requests that hit L2 cache" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the RFO (Read-for-Ownership) requests that hit L2 cache.", + "EventCode": "0x24", + "Counter": "0,1,2,3", + "UMask": "0xc2", + "PEBScounters": "0,1,2,3", + "EventName": "L2_RQSTS.RFO_HIT", + "SampleAfterValue": "200003", + "BriefDescription": "RFO requests that hit L2 cache" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts L2 cache hits when fetching instructions, code reads.", + "EventCode": "0x24", + "Counter": "0,1,2,3", + "UMask": "0xc4", + "PEBScounters": "0,1,2,3", + "EventName": "L2_RQSTS.CODE_RD_HIT", + "SampleAfterValue": "200003", + "BriefDescription": "L2 cache hits when fetching instructions, code reads." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts Software prefetch requests that hit the L2 cache. This event accounts for PREFETCHNTA and PREFETCHT0/1/2 instructions.", + "EventCode": "0x24", + "Counter": "0,1,2,3", + "UMask": "0xc8", + "PEBScounters": "0,1,2,3", + "EventName": "L2_RQSTS.SWPF_HIT", + "SampleAfterValue": "200003", + "BriefDescription": "SW prefetch requests that hit L2 cache." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of demand Data Read requests (including requests from L1D hardware prefetchers). These loads may hit or miss L2 cache. Only non rejected loads are counted.", + "EventCode": "0x24", + "Counter": "0,1,2,3", + "UMask": "0xe1", + "PEBScounters": "0,1,2,3", + "EventName": "L2_RQSTS.ALL_DEMAND_DATA_RD", + "SampleAfterValue": "200003", + "BriefDescription": "Demand Data Read requests" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the total number of RFO (read for ownership) requests to L2 cache. L2 RFO requests include both L1D demand RFO misses as well as L1D RFO prefetches.", + "EventCode": "0x24", + "Counter": "0,1,2,3", + "UMask": "0xe2", + "PEBScounters": "0,1,2,3", + "EventName": "L2_RQSTS.ALL_RFO", + "SampleAfterValue": "200003", + "BriefDescription": "RFO requests to L2 cache" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the total number of L2 code requests.", + "EventCode": "0x24", + "Counter": "0,1,2,3", + "UMask": "0xe4", + "PEBScounters": "0,1,2,3", + "EventName": "L2_RQSTS.ALL_CODE_RD", + "SampleAfterValue": "200003", + "BriefDescription": "L2 code requests" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts demand requests to L2 cache.", + "EventCode": "0x24", + "Counter": "0,1,2,3", + "UMask": "0xe7", + "PEBScounters": "0,1,2,3", + "EventName": "L2_RQSTS.ALL_DEMAND_REFERENCES", + "SampleAfterValue": "200003", + "BriefDescription": "Demand requests to L2 cache" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts number of L1D misses that are outstanding in each cycle, that is each cycle the number of Fill Buffers (FB) outstanding required by Demand Reads. FB either is held by demand loads, or it is held by non-demand loads and gets hit at least once by demand. The valid outstanding interval is defined until the FB deallocation by one of the following ways: from FB allocation, if FB is allocated by demand from the demand Hit FB, if it is allocated by hardware or software prefetch. Note: In the L1D, a Demand Read contains cacheable or noncacheable demand loads, including ones causing cache-line splits and reads due to page walks resulted from any request type.", + "EventCode": "0x48", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "L1D_PEND_MISS.PENDING", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of L1D misses that are outstanding" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts duration of L1D miss outstanding in cycles.", + "EventCode": "0x48", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "L1D_PEND_MISS.PENDING_CYCLES", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles with L1D load Misses outstanding.", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts number of cycles a demand request has waited due to L1D Fill Buffer (FB) unavailablability. Demand requests include cacheable/uncacheable demand load, store, lock or SW prefetch accesses.", + "EventCode": "0x48", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "L1D_PEND_MISS.FB_FULL", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of cycles a demand request has waited due to L1D Fill Buffer (FB) unavailablability." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts number of phases a demand request has waited due to L1D Fill Buffer (FB) unavailablability. Demand requests include cacheable/uncacheable demand load, store, lock or SW prefetch accesses.", + "EventCode": "0x48", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "L1D_PEND_MISS.FB_FULL_PERIODS", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of phases a demand request has waited due to L1D Fill Buffer (FB) unavailablability.", + "CounterMask": "1", + "EdgeDetect": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts number of cycles a demand request has waited due to L1D due to lack of L2 resources. Demand requests include cacheable/uncacheable demand load, store, lock or SW prefetch accesses.", + "EventCode": "0x48", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "L1D_PEND_MISS.L2_STALL", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of cycles a demand request has waited due to L1D due to lack of L2 resources." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts L1D data line replacements including opportunistic replacements, and replacements that require stall-for-replace or block-for-replace.", + "EventCode": "0x51", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "L1D.REPLACEMENT", + "SampleAfterValue": "2000003", + "BriefDescription": "Counts the number of cache lines replaced in L1 data cache." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of offcore outstanding demand rfo Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", + "EventCode": "0x60", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_RFO", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles with offcore outstanding demand rfo reads transactions in SuperQueue (SQ), queue to uncore.", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of offcore outstanding cacheable Core Data Read transactions in the super queue every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", + "EventCode": "0x60", + "Counter": "0,1,2,3", + "UMask": "0x8", + "PEBScounters": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.ALL_DATA_RD", + "SampleAfterValue": "2000003", + "BriefDescription": "Offcore outstanding cacheable Core Data Read transactions in SuperQueue (SQ), queue to uncore" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles when offcore outstanding cacheable Core Data Read transactions are present in the super queue. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", + "EventCode": "0x60", + "Counter": "0,1,2,3", + "UMask": "0x8", + "PEBScounters": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DATA_RD", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles when offcore outstanding cacheable Core Data Read transactions are present in SuperQueue (SQ), queue to uncore.", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the Demand Data Read requests sent to uncore. Use it in conjunction with OFFCORE_REQUESTS_OUTSTANDING to determine average latency in the uncore.", + "EventCode": "0xB0", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS.DEMAND_DATA_RD", + "SampleAfterValue": "100003", + "BriefDescription": "Demand Data Read requests sent to uncore" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the demand RFO (read for ownership) requests including regular RFOs, locks, ItoM.", + "EventCode": "0xB0", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS.DEMAND_RFO", + "SampleAfterValue": "100003", + "BriefDescription": "Demand RFO requests including regular RFOs, locks, ItoM" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the demand and prefetch data reads. All Core Data Reads include cacheable 'Demands' and L2 prefetchers (not L3 prefetchers). Counting also covers reads due to page walks resulted from any request type.", + "EventCode": "0xB0", + "Counter": "0,1,2,3", + "UMask": "0x8", + "PEBScounters": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS.ALL_DATA_RD", + "SampleAfterValue": "100003", + "BriefDescription": "Demand and prefetch data reads" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts memory transactions reached the super queue including requests initiated by the core, all L3 prefetches, page walks, etc..", + "EventCode": "0xB0", + "Counter": "0,1,2,3", + "UMask": "0x80", + "PEBScounters": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS.ALL_REQUESTS", + "SampleAfterValue": "100003", + "BriefDescription": "Any memory transaction that reached the SQ." + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired load instructions that true miss the STLB.", + "EventCode": "0xD0", + "Counter": "0,1,2,3", + "UMask": "0x11", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.STLB_MISS_LOADS", + "SampleAfterValue": "100003", + "BriefDescription": "Retired load instructions that miss the STLB.", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired store instructions that true miss the STLB.", + "EventCode": "0xD0", + "Counter": "0,1,2,3", + "UMask": "0x12", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.STLB_MISS_STORES", + "SampleAfterValue": "100003", + "BriefDescription": "Retired store instructions that miss the STLB.", + "Data_LA": "1", + "L1_Hit_Indication": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired load instructions with locked access.", + "EventCode": "0xD0", + "Counter": "0,1,2,3", + "UMask": "0x21", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.LOCK_LOADS", + "SampleAfterValue": "100007", + "BriefDescription": "Retired load instructions with locked access.", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired load instructions that split across a cacheline boundary.", + "EventCode": "0xD0", + "Counter": "0,1,2,3", + "UMask": "0x41", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.SPLIT_LOADS", + "SampleAfterValue": "100003", + "BriefDescription": "Retired load instructions that split across a cacheline boundary.", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired store instructions that split across a cacheline boundary.", + "EventCode": "0xD0", + "Counter": "0,1,2,3", + "UMask": "0x42", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.SPLIT_STORES", + "SampleAfterValue": "100003", + "BriefDescription": "Retired store instructions that split across a cacheline boundary.", + "Data_LA": "1", + "L1_Hit_Indication": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts all retired load instructions. This event accounts for SW prefetch instructions for loads.", + "EventCode": "0xD0", + "Counter": "0,1,2,3", + "UMask": "0x81", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.ALL_LOADS", + "SampleAfterValue": "2000003", + "BriefDescription": "All retired load instructions.", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts all retired store instructions. This event account for SW prefetch instructions and PREFETCHW instruction for stores.", + "EventCode": "0xD0", + "Counter": "0,1,2,3", + "UMask": "0x82", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.ALL_STORES", + "SampleAfterValue": "2000003", + "BriefDescription": "All retired store instructions.", + "Data_LA": "1", + "L1_Hit_Indication": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L1 data cache. This event includes all SW prefetches and lock instructions regardless of the data source.", + "EventCode": "0xD1", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L1_HIT", + "SampleAfterValue": "2000003", + "BriefDescription": "Retired load instructions with L1 cache hits as data sources", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired load instructions with L2 cache hits as data sources.", + "EventCode": "0xD1", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L2_HIT", + "SampleAfterValue": "100003", + "BriefDescription": "Retired load instructions with L2 cache hits as data sources", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L3 cache.", + "EventCode": "0xD1", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L3_HIT", + "SampleAfterValue": "50021", + "BriefDescription": "Retired load instructions with L3 cache hits as data sources", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L1 cache.", + "EventCode": "0xD1", + "Counter": "0,1,2,3", + "UMask": "0x8", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L1_MISS", + "SampleAfterValue": "100003", + "BriefDescription": "Retired load instructions missed L1 cache as data sources", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired load instructions missed L2 cache as data sources.", + "EventCode": "0xD1", + "Counter": "0,1,2,3", + "UMask": "0x10", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L2_MISS", + "SampleAfterValue": "50021", + "BriefDescription": "Retired load instructions missed L2 cache as data sources", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L3 cache.", + "EventCode": "0xD1", + "Counter": "0,1,2,3", + "UMask": "0x20", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L3_MISS", + "SampleAfterValue": "100007", + "BriefDescription": "Retired load instructions missed L3 cache as data sources", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired load instructions with at least one uop was load missed in L1 but hit FB (Fill Buffers) due to preceding miss to the same cache line with data not ready.", + "EventCode": "0xd1", + "Counter": "0,1,2,3", + "UMask": "0x40", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.FB_HIT", + "SampleAfterValue": "100007", + "BriefDescription": "Number of completed demand load requests that missed the L1, but hit the FB(fill buffer), because a preceding miss to the same cacheline initiated the line to be brought into L1, but data is not yet ready in L1.", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the retired load instructions whose data sources were L3 hit and cross-core snoop missed in on-pkg core cache.", + "EventCode": "0xd2", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_MISS", + "SampleAfterValue": "20011", + "BriefDescription": "Retired load instructions whose data sources were L3 hit and cross-core snoop missed in on-pkg core cache.", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired load instructions whose data sources were L3 and cross-core snoop hits in on-pkg core cache.", + "EventCode": "0xd2", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_HIT", + "SampleAfterValue": "20011", + "BriefDescription": "Retired load instructions whose data sources were L3 and cross-core snoop hits in on-pkg core cache", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired load instructions whose data sources were HitM responses from shared L3.", + "EventCode": "0xd2", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_HITM", + "SampleAfterValue": "20011", + "BriefDescription": "Retired load instructions whose data sources were HitM responses from shared L3", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired load instructions whose data sources were hits in L3 without snoops required.", + "EventCode": "0xd2", + "Counter": "0,1,2,3", + "UMask": "0x8", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_NONE", + "SampleAfterValue": "100003", + "BriefDescription": "Retired load instructions whose data sources were hits in L3 without snoops required", + "Data_LA": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of L2 cache lines filling the L2. Counting does not cover rejects.", + "EventCode": "0xF1", + "Counter": "0,1,2,3", + "UMask": "0x1f", + "PEBScounters": "0,1,2,3", + "EventName": "L2_LINES_IN.ALL", + "SampleAfterValue": "100003", + "BriefDescription": "L2 cache lines filling L2" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the cycles for which the thread is active and the superQ cannot take any more entries.", + "EventCode": "0xF4", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "SQ_MISC.SQ_FULL", + "SampleAfterValue": "100003", + "BriefDescription": "Cycles the thread is active and superQ cannot take any more entries." + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/icelake/floating-point.json b/tools/perf/pmu-events/arch/x86/icelake/floating-point.json new file mode 100644 index 000000000000..594c5551f610 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/icelake/floating-point.json @@ -0,0 +1,102 @@ +[ + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts all microcode Floating Point assists.", + "EventCode": "0xC1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "ASSISTS.FP", + "SampleAfterValue": "100003", + "BriefDescription": "Counts all microcode FP assists.", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts number of SSE/AVX computational scalar double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 1 computational operation. Applies to SSE* and AVX* scalar double precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "EventCode": "0xc7", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FP_ARITH_INST_RETIRED.SCALAR_DOUBLE", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of SSE/AVX computational scalar double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 1 computation. Applies to SSE* and AVX* scalar double precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 RANGE SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts number of SSE/AVX computational scalar single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 1 computational operation. Applies to SSE* and AVX* scalar single precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT RSQRT RCP FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "EventCode": "0xc7", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FP_ARITH_INST_RETIRED.SCALAR_SINGLE", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of SSE/AVX computational scalar single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 1 computation. Applies to SSE* and AVX* scalar single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 RANGE SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts number of SSE/AVX computational 128-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 2 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "EventCode": "0xc7", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x4", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of SSE/AVX computational 128-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 2 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT RSQRT14 RCP14 RANGE DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts number of SSE/AVX computational 128-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 4 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT RSQRT RCP DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "EventCode": "0xc7", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x8", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of SSE/AVX computational 128-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 4 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts number of SSE/AVX computational 256-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 4 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "EventCode": "0xc7", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x10", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of SSE/AVX computational 256-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 4 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 RANGE SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts number of SSE/AVX computational 256-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 8 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT RSQRT RCP DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "EventCode": "0xc7", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x20", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of SSE/AVX computational 256-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 8 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 RANGE SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts number of SSE/AVX computational 512-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 8 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT RSQRT14 RCP14 RANGE FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "EventCode": "0xc7", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x40", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of SSE/AVX computational 512-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 16 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT RSQRT14 RCP14 RANGE FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts number of SSE/AVX computational 512-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 16 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT RSQRT14 RCP14 RANGE FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "EventCode": "0xc7", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x80", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of SSE/AVX computational 512-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 8 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT RSQRT14 RCP14 RANGE FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element." + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/icelake/frontend.json b/tools/perf/pmu-events/arch/x86/icelake/frontend.json new file mode 100644 index 000000000000..9c3cfbfcec0f --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/icelake/frontend.json @@ -0,0 +1,424 @@ +[ + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the MITE path. This also means that uops are not being delivered from the Decode Stream Buffer (DSB).", + "EventCode": "0x79", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "IDQ.MITE_UOPS", + "SampleAfterValue": "2000003", + "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from MITE path" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of cycles where optimal number of uops was delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", + "EventCode": "0x79", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "IDQ.MITE_CYCLES_OK", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles MITE is delivering optimal number of Uops", + "CounterMask": "5" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of cycles uops were delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", + "EventCode": "0x79", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "IDQ.MITE_CYCLES_ANY", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles MITE is delivering any Uop", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path.", + "EventCode": "0x79", + "Counter": "0,1,2,3", + "UMask": "0x8", + "PEBScounters": "0,1,2,3", + "EventName": "IDQ.DSB_UOPS", + "SampleAfterValue": "2000003", + "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of cycles where optimal number of uops was delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", + "EventCode": "0x79", + "Counter": "0,1,2,3", + "UMask": "0x8", + "PEBScounters": "0,1,2,3", + "EventName": "IDQ.DSB_CYCLES_OK", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles DSB is delivering optimal number of Uops", + "CounterMask": "5" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of cycles uops were delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path.", + "EventCode": "0x79", + "Counter": "0,1,2,3", + "UMask": "0x8", + "PEBScounters": "0,1,2,3", + "EventName": "IDQ.DSB_CYCLES_ANY", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles Decode Stream Buffer (DSB) is delivering any Uop", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Number of switches from DSB (Decode Stream Buffer) or MITE (legacy decode pipeline) to the Microcode Sequencer.", + "EventCode": "0x79", + "Counter": "0,1,2,3", + "UMask": "0x30", + "PEBScounters": "0,1,2,3", + "EventName": "IDQ.MS_SWITCHES", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of switches from DSB or MITE to the MS", + "CounterMask": "1", + "EdgeDetect": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the total number of uops delivered by the Microcode Sequencer (MS). Any instruction over 4 uops will be delivered by the MS. Some instructions such as transcendentals may additionally generate uops from the MS.", + "EventCode": "0x79", + "Counter": "0,1,2,3", + "UMask": "0x30", + "PEBScounters": "0,1,2,3", + "EventName": "IDQ.MS_UOPS", + "SampleAfterValue": "2000003", + "BriefDescription": "Uops delivered to IDQ while MS is busy" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Uops maybe initiated by Decode Stream Buffer (DSB) or MITE.", + "EventCode": "0x79", + "Counter": "0,1,2,3", + "UMask": "0x30", + "PEBScounters": "0,1,2,3", + "EventName": "IDQ.MS_CYCLES_ANY", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles when uops are being delivered to IDQ while MS is busy", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles where a code line fetch is stalled due to an L1 instruction cache miss. The legacy decode pipeline works at a 16 Byte granularity.", + "EventCode": "0x80", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "ICACHE_16B.IFDATA_STALL", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles where a code fetch is stalled due to L1 instruction cache miss." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts instruction fetch tag lookups that hit in the instruction cache (L1I). Counts at 64-byte cache-line granularity. Accounts for both cacheable and uncacheable accesses.", + "EventCode": "0x83", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "ICACHE_64B.IFTAG_HIT", + "SampleAfterValue": "200003", + "BriefDescription": "Instruction fetch tag lookups that hit in the instruction cache (L1I). Counts at 64-byte cache-line granularity." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts instruction fetch tag lookups that miss in the instruction cache (L1I). Counts at 64-byte cache-line granularity. Accounts for both cacheable and uncacheable accesses.", + "EventCode": "0x83", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "ICACHE_64B.IFTAG_MISS", + "SampleAfterValue": "200003", + "BriefDescription": "Instruction fetch tag lookups that miss in the instruction cache (L1I). Counts at 64-byte cache-line granularity." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles where a code fetch is stalled due to L1 instruction cache tag miss.", + "EventCode": "0x83", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "ICACHE_64B.IFTAG_STALL", + "SampleAfterValue": "200003", + "BriefDescription": "Cycles where a code fetch is stalled due to L1 instruction cache tag miss." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of uops not delivered to by the Instruction Decode Queue (IDQ) to the back-end of the pipeline when there was no back-end stalls. This event counts for one SMT thread in a given cycle.", + "EventCode": "0x9C", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CORE", + "SampleAfterValue": "2000003", + "BriefDescription": "Uops not delivered by IDQ when backend of the machine is not stalled" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of cycles when no uops were delivered by the Instruction Decode Queue (IDQ) to the back-end of the pipeline when there was no back-end stalls. This event counts for one SMT thread in a given cycle.", + "EventCode": "0x9c", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles when no uops are not delivered by the IDQ when backend of the machine is not stalled", + "CounterMask": "5" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of cycles when the optimal number of uops were delivered by the Instruction Decode Queue (IDQ) to the back-end of the pipeline when there was no back-end stalls. This event counts for one SMT thread in a given cycle.", + "EventCode": "0x9C", + "Invert": "1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_FE_WAS_OK", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles when optimal number of uops was delivered to the back-end when the back-end is not stalled", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Decode Stream Buffer (DSB) is a Uop-cache that holds translations of previously fetched instructions that were decoded by the legacy x86 decode pipeline (MITE). This event counts fetch penalty cycles when a transition occurs from DSB to MITE.", + "EventCode": "0xAB", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "DSB2MITE_SWITCHES.PENALTY_CYCLES", + "SampleAfterValue": "2000003", + "BriefDescription": "DSB-to-MITE switch true penalty cycles." + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired Instructions that experienced DSB (Decode stream buffer i.e. the decoded instruction-cache) miss.", + "EventCode": "0xC6", + "MSRValue": "0x11", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FRONTEND_RETIRED.DSB_MISS", + "MSRIndex": "0x3F7", + "SampleAfterValue": "100007", + "BriefDescription": "Retired Instructions who experienced DSB miss.", + "TakenAlone": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired Instructions who experienced Instruction L1 Cache true miss.", + "EventCode": "0xC6", + "MSRValue": "0x12", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FRONTEND_RETIRED.L1I_MISS", + "MSRIndex": "0x3F7", + "SampleAfterValue": "100007", + "BriefDescription": "Retired Instructions who experienced Instruction L1 Cache true miss.", + "TakenAlone": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired Instructions who experienced Instruction L2 Cache true miss.", + "EventCode": "0xC6", + "MSRValue": "0x13", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FRONTEND_RETIRED.L2_MISS", + "MSRIndex": "0x3F7", + "SampleAfterValue": "100007", + "BriefDescription": "Retired Instructions who experienced Instruction L2 Cache true miss.", + "TakenAlone": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired Instructions that experienced iTLB (Instruction TLB) true miss.", + "EventCode": "0xC6", + "MSRValue": "0x14", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FRONTEND_RETIRED.ITLB_MISS", + "MSRIndex": "0x3F7", + "SampleAfterValue": "100007", + "BriefDescription": "Retired Instructions who experienced iTLB true miss.", + "TakenAlone": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired Instructions that experienced STLB (2nd level TLB) true miss.", + "EventCode": "0xC6", + "MSRValue": "0x15", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FRONTEND_RETIRED.STLB_MISS", + "MSRIndex": "0x3F7", + "SampleAfterValue": "100007", + "BriefDescription": "Retired Instructions who experienced STLB (2nd level TLB) true miss.", + "TakenAlone": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 2 cycles which was not interrupted by a back-end stall.", + "EventCode": "0xC6", + "MSRValue": "0x500206", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2", + "MSRIndex": "0x3F7", + "SampleAfterValue": "100007", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 2 cycles which was not interrupted by a back-end stall.", + "TakenAlone": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 4 cycles which was not interrupted by a back-end stall.", + "EventCode": "0xC6", + "MSRValue": "0x500406", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_4", + "MSRIndex": "0x3F7", + "SampleAfterValue": "100007", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 4 cycles which was not interrupted by a back-end stall.", + "TakenAlone": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 8 cycles. During this period the front-end delivered no uops.", + "EventCode": "0xC6", + "MSRValue": "0x500806", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_8", + "MSRIndex": "0x3F7", + "SampleAfterValue": "100007", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 8 cycles which was not interrupted by a back-end stall.", + "TakenAlone": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 16 cycles. During this period the front-end delivered no uops.", + "EventCode": "0xC6", + "MSRValue": "0x501006", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_16", + "MSRIndex": "0x3F7", + "SampleAfterValue": "100007", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 16 cycles which was not interrupted by a back-end stall.", + "TakenAlone": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 32 cycles. During this period the front-end delivered no uops.", + "EventCode": "0xC6", + "MSRValue": "0x502006", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_32", + "MSRIndex": "0x3F7", + "SampleAfterValue": "100007", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 32 cycles which was not interrupted by a back-end stall.", + "TakenAlone": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 64 cycles which was not interrupted by a back-end stall.", + "EventCode": "0xC6", + "MSRValue": "0x504006", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_64", + "MSRIndex": "0x3F7", + "SampleAfterValue": "100007", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 64 cycles which was not interrupted by a back-end stall.", + "TakenAlone": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 128 cycles which was not interrupted by a back-end stall.", + "EventCode": "0xC6", + "MSRValue": "0x508006", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_128", + "MSRIndex": "0x3F7", + "SampleAfterValue": "100007", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 128 cycles which was not interrupted by a back-end stall.", + "TakenAlone": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 256 cycles which was not interrupted by a back-end stall.", + "EventCode": "0xC6", + "MSRValue": "0x510006", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_256", + "MSRIndex": "0x3F7", + "SampleAfterValue": "100007", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 256 cycles which was not interrupted by a back-end stall.", + "TakenAlone": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 512 cycles which was not interrupted by a back-end stall.", + "EventCode": "0xC6", + "MSRValue": "0x520006", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_512", + "MSRIndex": "0x3F7", + "SampleAfterValue": "100007", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 512 cycles which was not interrupted by a back-end stall.", + "TakenAlone": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after the front-end had at least 1 bubble-slot for a period of 2 cycles. A bubble-slot is an empty issue-pipeline slot while there was no RAT stall.", + "EventCode": "0xC6", + "MSRValue": "0x100206", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_1", + "MSRIndex": "0x3F7", + "SampleAfterValue": "100007", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 1 bubble-slot for a period of 2 cycles which was not interrupted by a back-end stall.", + "TakenAlone": "1" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/icelake/memory.json b/tools/perf/pmu-events/arch/x86/icelake/memory.json new file mode 100644 index 000000000000..f158366b9dd6 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/icelake/memory.json @@ -0,0 +1,410 @@ +[ + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times a TSX line had a cache conflict.", + "EventCode": "0x54", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "TX_MEM.ABORT_CONFLICT", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times a transactional abort was signaled due to a data conflict on a transactionally accessed address" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Speculatively counts the number Transactional Synchronization Extensions (TSX) Aborts due to a data capacity limitation for transactional writes.", + "EventCode": "0x54", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "TX_MEM.ABORT_CAPACITY_WRITE", + "SampleAfterValue": "2000003", + "BriefDescription": "Speculatively counts the number TSX Aborts due to a data capacity limitation for transactional writes." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times a TSX Abort was triggered due to a non-release/commit store to lock.", + "EventCode": "0x54", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "TX_MEM.ABORT_HLE_STORE_TO_ELIDED_LOCK", + "SampleAfterValue": "100003", + "BriefDescription": "Number of times a HLE transactional region aborted due to a non XRELEASE prefixed instruction writing to an elided lock in the elision buffer" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times a TSX Abort was triggered due to commit but Lock Buffer not empty.", + "EventCode": "0x54", + "Counter": "0,1,2,3", + "UMask": "0x8", + "PEBScounters": "0,1,2,3", + "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_NOT_EMPTY", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times an HLE transactional execution aborted due to NoAllocatedElisionBuffer being non-zero." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times a TSX Abort was triggered due to release/commit but data and address mismatch.", + "EventCode": "0x54", + "Counter": "0,1,2,3", + "UMask": "0x10", + "PEBScounters": "0,1,2,3", + "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_MISMATCH", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times an HLE transactional execution aborted due to XRELEASE lock not satisfying the address and value requirements in the elision buffer" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times a TSX Abort was triggered due to attempting an unsupported alignment from Lock Buffer.", + "EventCode": "0x54", + "Counter": "0,1,2,3", + "UMask": "0x20", + "PEBScounters": "0,1,2,3", + "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_UNSUPPORTED_ALIGNMENT", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times an HLE transactional execution aborted due to an unsupported read alignment from the elision buffer." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times we could not allocate Lock Buffer.", + "EventCode": "0x54", + "Counter": "0,1,2,3", + "UMask": "0x40", + "PEBScounters": "0,1,2,3", + "EventName": "TX_MEM.HLE_ELISION_BUFFER_FULL", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times HLE lock could not be elided due to ElisionBufferAvailable being zero." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts Unfriendly TSX abort triggered by a vzeroupper instruction.", + "EventCode": "0x5d", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "TX_EXEC.MISC2", + "SampleAfterValue": "2000003", + "BriefDescription": "Counts the number of times a class of instructions that may cause a transactional abort was executed inside a transactional region" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts Unfriendly TSX abort triggered by a nest count that is too deep.", + "EventCode": "0x5d", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x4", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "TX_EXEC.MISC3", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times an instruction execution caused the transactional nest count supported to be exceeded" + }, + { + "CollectPEBSRecord": "2", + "EventCode": "0xA3", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.CYCLES_L3_MISS", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles while L3 cache miss demand load is outstanding.", + "CounterMask": "2" + }, + { + "CollectPEBSRecord": "2", + "EventCode": "0xA3", + "Counter": "0,1,2,3", + "UMask": "0x6", + "PEBScounters": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.STALLS_L3_MISS", + "SampleAfterValue": "2000003", + "BriefDescription": "Execution stalls while L3 cache miss demand load is outstanding.", + "CounterMask": "6" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Demand Data Read requests who miss L3 cache.", + "EventCode": "0xB0", + "Counter": "0,1,2,3", + "UMask": "0x10", + "PEBScounters": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS.L3_MISS_DEMAND_DATA_RD", + "SampleAfterValue": "100003", + "BriefDescription": "Demand Data Read requests who miss L3 cache" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of Machine Clears detected dye to memory ordering. Memory Ordering Machine Clears may apply when a memory read may not conform to the memory ordering rules of the x86 architecture", + "EventCode": "0xc3", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "MACHINE_CLEARS.MEMORY_ORDERING", + "SampleAfterValue": "100003", + "BriefDescription": "Number of machine clears due to memory ordering conflicts." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times we entered an HLE region. Does not count nested transactions.", + "EventCode": "0xC8", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "HLE_RETIRED.START", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times an HLE execution started." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times HLE commit succeeded.", + "EventCode": "0xC8", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "HLE_RETIRED.COMMIT", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times an HLE execution successfully committed", + "Data_LA": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times HLE abort was triggered.", + "EventCode": "0xc8", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x4", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "HLE_RETIRED.ABORTED", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times an HLE execution aborted due to any reasons (multiple categories may count as one)." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times an HLE execution aborted due to various memory events (e.g., read/write capacity and conflicts).", + "EventCode": "0xC8", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x8", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "HLE_RETIRED.ABORTED_MEM", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times an HLE execution aborted due to various memory events (e.g., read/write capacity and conflicts)." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times an HLE execution aborted due to HLE-unfriendly instructions and certain unfriendly events (such as AD assists etc.).", + "EventCode": "0xC8", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x20", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "HLE_RETIRED.ABORTED_UNFRIENDLY", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times an HLE execution aborted due to HLE-unfriendly instructions and certain unfriendly events (such as AD assists etc.)." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times an HLE execution aborted due to unfriendly events (such as interrupts).", + "EventCode": "0xC8", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x80", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "HLE_RETIRED.ABORTED_EVENTS", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times an HLE execution aborted due to unfriendly events (such as interrupts)." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times we entered an RTM region. Does not count nested transactions.", + "EventCode": "0xC9", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "RTM_RETIRED.START", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times an RTM execution started." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times RTM commit succeeded.", + "EventCode": "0xC9", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "RTM_RETIRED.COMMIT", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times an RTM execution successfully committed" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times RTM abort was triggered.", + "EventCode": "0xc9", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x4", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "RTM_RETIRED.ABORTED", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times an RTM execution aborted.", + "Data_LA": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times an RTM execution aborted due to various memory events (e.g. read/write capacity and conflicts).", + "EventCode": "0xC9", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x8", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "RTM_RETIRED.ABORTED_MEM", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times an RTM execution aborted due to various memory events (e.g. read/write capacity and conflicts)" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times an RTM execution aborted due to HLE-unfriendly instructions.", + "EventCode": "0xC9", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x20", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "RTM_RETIRED.ABORTED_UNFRIENDLY", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times an RTM execution aborted due to HLE-unfriendly instructions" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times an RTM execution aborted due to incompatible memory type.", + "EventCode": "0xC9", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x40", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "RTM_RETIRED.ABORTED_MEMTYPE", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times an RTM execution aborted due to incompatible memory type" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times an RTM execution aborted due to none of the previous 4 categories (e.g. interrupt).", + "EventCode": "0xC9", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x80", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "RTM_RETIRED.ABORTED_EVENTS", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of times an RTM execution aborted due to none of the previous 4 categories (e.g. interrupt)" + }, + { + "PEBS": "2", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 4 cycles. Reported latency may be longer than just the memory latency.", + "EventCode": "0xcd", + "MSRValue": "0x4", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_4", + "MSRIndex": "0x3F6", + "SampleAfterValue": "100003", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 4 cycles.", + "TakenAlone": "1" + }, + { + "PEBS": "2", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 8 cycles. Reported latency may be longer than just the memory latency.", + "EventCode": "0xcd", + "MSRValue": "0x8", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_8", + "MSRIndex": "0x3F6", + "SampleAfterValue": "50021", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 8 cycles.", + "TakenAlone": "1" + }, + { + "PEBS": "2", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 16 cycles. Reported latency may be longer than just the memory latency.", + "EventCode": "0xcd", + "MSRValue": "0x10", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_16", + "MSRIndex": "0x3F6", + "SampleAfterValue": "20011", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 16 cycles.", + "TakenAlone": "1" + }, + { + "PEBS": "2", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 32 cycles. Reported latency may be longer than just the memory latency.", + "EventCode": "0xcd", + "MSRValue": "0x20", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_32", + "MSRIndex": "0x3F6", + "SampleAfterValue": "100007", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 32 cycles.", + "TakenAlone": "1" + }, + { + "PEBS": "2", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 64 cycles. Reported latency may be longer than just the memory latency.", + "EventCode": "0xcd", + "MSRValue": "0x40", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_64", + "MSRIndex": "0x3F6", + "SampleAfterValue": "2003", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 64 cycles.", + "TakenAlone": "1" + }, + { + "PEBS": "2", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 128 cycles. Reported latency may be longer than just the memory latency.", + "EventCode": "0xcd", + "MSRValue": "0x80", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_128", + "MSRIndex": "0x3F6", + "SampleAfterValue": "1009", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 128 cycles.", + "TakenAlone": "1" + }, + { + "PEBS": "2", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 256 cycles. Reported latency may be longer than just the memory latency.", + "EventCode": "0xcd", + "MSRValue": "0x100", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_256", + "MSRIndex": "0x3F6", + "SampleAfterValue": "503", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 256 cycles.", + "TakenAlone": "1" + }, + { + "PEBS": "2", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 512 cycles. Reported latency may be longer than just the memory latency.", + "EventCode": "0xcd", + "MSRValue": "0x200", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_512", + "MSRIndex": "0x3F6", + "SampleAfterValue": "101", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 512 cycles.", + "TakenAlone": "1" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/icelake/other.json b/tools/perf/pmu-events/arch/x86/icelake/other.json new file mode 100644 index 000000000000..f8dfdb847224 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/icelake/other.json @@ -0,0 +1,121 @@ +[ + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of available slots for an unhalted logical processor. The event increments by machine-width of the narrowest pipeline as employed by the Top-down Microarchitecture Analysis method. The count is distributed among unhalted logical processors (hyper-threads) who share the same physical core. Software can use this event as the denominator for the top-level metrics of the Top-down Microarchitecture Analysis method. This event is counted on a designated fixed counter (Fixed Counter 3) and is an architectural event.", + "Counter": "35", + "UMask": "0x4", + "PEBScounters": "35", + "EventName": "TOPDOWN.SLOTS", + "SampleAfterValue": "10000003", + "BriefDescription": "Counts the number of available slots for an unhalted logical processor." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts Core cycles where the core was running with power-delivery for baseline license level 0. This includes non-AVX codes, SSE, AVX 128-bit, and low-current AVX 256-bit codes.", + "EventCode": "0x28", + "Counter": "0,1,2,3", + "UMask": "0x7", + "PEBScounters": "0,1,2,3", + "EventName": "CORE_POWER.LVL0_TURBO_LICENSE", + "SampleAfterValue": "200003", + "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the Non-AVX turbo schedule." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts Core cycles where the core was running with power-delivery for license level 1. This includes high current AVX 256-bit instructions as well as low current AVX 512-bit instructions.", + "EventCode": "0x28", + "Counter": "0,1,2,3", + "UMask": "0x18", + "PEBScounters": "0,1,2,3", + "EventName": "CORE_POWER.LVL1_TURBO_LICENSE", + "SampleAfterValue": "200003", + "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the AVX2 turbo schedule." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Core cycles where the core was running with power-delivery for license level 2 (introduced in Skylake Server microarchtecture). This includes high current AVX 512-bit instructions.", + "EventCode": "0x28", + "Counter": "0,1,2,3", + "UMask": "0x20", + "PEBScounters": "0,1,2,3", + "EventName": "CORE_POWER.LVL2_TURBO_LICENSE", + "SampleAfterValue": "200003", + "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the AVX512 turbo schedule." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of PREFETCHNTA instructions executed.", + "EventCode": "0x32", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "SW_PREFETCH_ACCESS.NTA", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of PREFETCHNTA instructions executed." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of PREFETCHT0 instructions executed.", + "EventCode": "0x32", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "SW_PREFETCH_ACCESS.T0", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of PREFETCHT0 instructions executed." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of PREFETCHT1 or PREFETCHT2 instructions executed.", + "EventCode": "0x32", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "SW_PREFETCH_ACCESS.T1_T2", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of PREFETCHT1 or PREFETCHT2 instructions executed." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of PREFETCHW instructions executed.", + "EventCode": "0x32", + "Counter": "0,1,2,3", + "UMask": "0x8", + "PEBScounters": "0,1,2,3", + "EventName": "SW_PREFETCH_ACCESS.PREFETCHW", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of PREFETCHW instructions executed." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of available slots for an unhalted logical processor. The event increments by machine-width of the narrowest pipeline as employed by the Top-down Microarchitecture Analysis method. The count is distributed among unhalted logical processors (hyper-threads) who share the same physical core.", + "EventCode": "0xa4", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "TOPDOWN.SLOTS_P", + "SampleAfterValue": "10000003", + "BriefDescription": "Counts the number of available slots for an unhalted logical processor." + }, + { + "CollectPEBSRecord": "2", + "EventCode": "0xA4", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "TOPDOWN.BACKEND_BOUND_SLOTS", + "SampleAfterValue": "10000003", + "BriefDescription": "Issue slots where no uops were being issued due to lack of back end resources." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of occurrences where a microcode assist is invoked by hardware Examples include AD (page Access Dirty), FP and AVX related assists.", + "EventCode": "0xc1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x7", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "ASSISTS.ANY", + "SampleAfterValue": "100003", + "BriefDescription": "Number of occurrences where a microcode assist is invoked by hardware." + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/icelake/pipeline.json b/tools/perf/pmu-events/arch/x86/icelake/pipeline.json new file mode 100644 index 000000000000..6d8311e634aa --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/icelake/pipeline.json @@ -0,0 +1,892 @@ +[ + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of X86 instructions retired - an Architectural PerfMon event. Counting continues during hardware interrupts, traps, and inside interrupt handlers. Notes: INST_RETIRED.ANY is counted by a designated fixed counter freeing up programmable counters to count other events. INST_RETIRED.ANY_P is counted by a programmable counter.", + "Counter": "32", + "UMask": "0x1", + "PEBScounters": "32", + "EventName": "INST_RETIRED.ANY", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of instructions retired. Fixed Counter - architectural event" + }, + { + "PEBS": "2", + "CollectPEBSRecord": "3", + "PublicDescription": "A version of INST_RETIRED that allows for a more unbiased distribution of samples across instructions retired. It utilizes the Precise Distribution of Instructions Retired (PDIR) feature to mitigate some bias in how retired instructions get sampled. Use on Fixed Counter 0.", + "Counter": "32", + "UMask": "0x1", + "PEBScounters": "32", + "EventName": "INST_RETIRED.PREC_DIST", + "SampleAfterValue": "2000003", + "BriefDescription": "Precise instruction retired event with a reduced effect of PEBS shadow in IP distribution" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of core cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. This event is a component in many key event ratios. The core frequency may change from time to time due to transitions associated with Enhanced Intel SpeedStep Technology or TM2. For this reason this event may have a changing ratio with regards to time. When the core frequency is constant, this event can approximate elapsed time while the core was not in the halt state. It is counted on a dedicated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events.", + "Counter": "33", + "UMask": "0x2", + "PEBScounters": "33", + "EventName": "CPU_CLK_UNHALTED.THREAD", + "SampleAfterValue": "2000003", + "BriefDescription": "Core cycles when the thread is not in halt state" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of reference cycles when the core is not in a halt state. The core enters the halt state when it is running the HLT instruction or the MWAIT instruction. This event is not affected by core frequency changes (for example, P states, TM2 transitions) but has the same incrementing frequency as the time stamp counter. This event can approximate elapsed time while the core was not in a halt state. This event has a constant ratio with the CPU_CLK_UNHALTED.REF_XCLK event. It is counted on a dedicated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events. Note: On all current platforms this event stops counting during 'throttling (TM)' states duty off periods the processor is 'halted'. The counter update is done at a lower clock rate then the core clock the overflow status bit for this counter may appear 'sticky'. After the counter has overflowed and software clears the overflow status bit and resets the counter to less than MAX. The reset value to the counter is not clocked immediately so the overflow status bit will flip 'high (1)' and generate another PMI (if enabled) after which the reset value gets clocked into the counter. Therefore, software will get the interrupt, read the overflow status bit '1 for bit 34 while the counter value is less than MAX. Software should ignore this case.", + "Counter": "34", + "UMask": "0x3", + "PEBScounters": "34", + "EventName": "CPU_CLK_UNHALTED.REF_TSC", + "SampleAfterValue": "2000003", + "BriefDescription": "Reference cycles when the core is not in halt state." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times the load operation got the true Block-on-Store blocking code preventing store forwarding. This includes cases when: a. preceding store conflicts with the load (incomplete overlap),b. store forwarding is impossible due to u-arch limitations, c. preceding lock RMW operations are not forwarded, d. store has the no-forward bit set (uncacheable/page-split/masked stores), e. all-blocking stores are used (mostly, fences and port I/O), and others. The most common case is a load blocked due to its address range overlapping with a preceding smaller uncompleted store. Note: This event does not take into account cases of out-of-SW-control (for example, SbTailHit), unknown physical STA, and cases of blocking loads on store due to being non-WB memory type or a lock. These cases are covered by other events. See the table of not supported store forwards in the Optimization Guide.", + "EventCode": "0x03", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "LD_BLOCKS.STORE_FORWARD", + "SampleAfterValue": "100003", + "BriefDescription": "Loads blocked by overlapping with store buffer that cannot be forwarded." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use.", + "EventCode": "0x03", + "Counter": "0,1,2,3", + "UMask": "0x8", + "PEBScounters": "0,1,2,3", + "EventName": "LD_BLOCKS.NO_SR", + "SampleAfterValue": "100003", + "BriefDescription": "The number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times a load got blocked due to false dependencies in MOB due to partial compare on address.", + "EventCode": "0x07", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "LD_BLOCKS_PARTIAL.ADDRESS_ALIAS", + "SampleAfterValue": "100003", + "BriefDescription": "False dependencies in MOB due to partial compare on address." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts core cycles when the Resource allocator was stalled due to recovery from an earlier branch misprediction or machine clear event.", + "EventCode": "0x0D", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "INT_MISC.RECOVERY_CYCLES", + "SampleAfterValue": "2000003", + "BriefDescription": "Core cycles the allocator was stalled due to recovery from earlier clear event for this thread" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles the Backend cluster is recovering after a miss-speculation or a Store Buffer or Load Buffer drain stall.", + "EventCode": "0x0D", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x3", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "INT_MISC.ALL_RECOVERY_CYCLES", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles the Backend cluster is recovering after a miss-speculation or a Store Buffer or Load Buffer drain stall.", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Cycles after recovery from a branch misprediction or machine clear till the first uop is issued from the resteered path.", + "EventCode": "0x0d", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x80", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "INT_MISC.CLEAR_RESTEER_CYCLES", + "SampleAfterValue": "2000003", + "BriefDescription": "Counts cycles after recovery from a branch misprediction or machine clear till the first uop is issued from the resteered path." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of uops that the Resource Allocation Table (RAT) issues to the Reservation Station (RS).", + "EventCode": "0x0E", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_ISSUED.ANY", + "SampleAfterValue": "2000003", + "BriefDescription": "Uops that RAT issues to RS" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles during which the Resource Allocation Table (RAT) does not issue any Uops to the reservation station (RS) for the current thread.", + "EventCode": "0x0E", + "Invert": "1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_ISSUED.STALL_CYCLES", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles when RAT does not issue Uops to RS for the thread", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles when divide unit is busy executing divide or square root operations. Accounts for integer and floating-point operations.", + "EventCode": "0x14", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x9", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "ARITH.DIVIDER_ACTIVE", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles when divide unit is busy executing divide or square root operations.", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "This is an architectural event that counts the number of thread cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. The core frequency may change from time to time due to power or thermal throttling. For this reason, this event may have a changing ratio with regards to wall clock time.", + "EventCode": "0x3C", + "Counter": "0,1,2,3,4,5,6,7", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "CPU_CLK_UNHALTED.THREAD_P", + "SampleAfterValue": "2000003", + "BriefDescription": "Thread cycles when thread is not in halt state" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts core crystal clock cycles when the thread is unhalted.", + "EventCode": "0x3C", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "CPU_CLK_UNHALTED.REF_XCLK", + "SampleAfterValue": "25003", + "BriefDescription": "Core crystal clock cycles when the thread is unhalted." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts Core crystal clock cycles when current thread is unhalted and the other thread is halted.", + "EventCode": "0x3C", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE", + "SampleAfterValue": "25003", + "BriefDescription": "Core crystal clock cycles when this thread is unhalted and the other thread is halted." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts all not software-prefetch load dispatches that hit the fill buffer (FB) allocated for the software prefetch. It can also be incremented by some lock instructions. So it should only be used with profiling so that the locks can be excluded by ASM (Assembly File) inspection of the nearby instructions.", + "EventCode": "0x4c", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "LOAD_HIT_PREFETCH.SWPF", + "SampleAfterValue": "100003", + "BriefDescription": "Counts the number of demand load dispatches that hit L1D fill buffer (FB) allocated for software prefetch." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles during which the reservation station (RS) is empty for this logical processor. This is usually caused when the front-end pipeline runs into stravation periods (e.g. branch mispredictions or i-cache misses)", + "EventCode": "0x5E", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "RS_EVENTS.EMPTY_CYCLES", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles when Reservation Station (RS) is empty for the thread" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts end of periods where the Reservation Station (RS) was empty. Could be useful to closely sample on front-end latency issues (see the FRONTEND_RETIRED event of designated precise events)", + "EventCode": "0x5E", + "Invert": "1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "RS_EVENTS.EMPTY_END", + "SampleAfterValue": "2000003", + "BriefDescription": "Counts end of periods where the Reservation Station (RS) was empty.", + "CounterMask": "1", + "EdgeDetect": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles that the Instruction Length decoder (ILD) stalls occurred due to dynamically changing prefix length of the decoded instruction (by operand size prefix instruction 0x66, address size prefix instruction 0x67 or REX.W for Intel64). Count is proportional to the number of prefixes in a 16B-line. This may result in a three-cycle penalty for each LCP (Length changing prefix) in a 16-byte chunk.", + "EventCode": "0x87", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "ILD_STALL.LCP", + "SampleAfterValue": "2000003", + "BriefDescription": "Stalls caused by changing prefix length of the instruction." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 0.", + "EventCode": "0xa1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_DISPATCHED.PORT_0", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of uops executed on port 0" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 1.", + "EventCode": "0xa1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_DISPATCHED.PORT_1", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of uops executed on port 1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to ports 2 and 3.", + "EventCode": "0xa1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x4", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_DISPATCHED.PORT_2_3", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of uops executed on port 2 and 3" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to ports 5 and 9.", + "EventCode": "0xa1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x10", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_DISPATCHED.PORT_4_9", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of uops executed on port 4 and 9" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 5.", + "EventCode": "0xa1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x20", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_DISPATCHED.PORT_5", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of uops executed on port 5" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 6.", + "EventCode": "0xa1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x40", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_DISPATCHED.PORT_6", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of uops executed on port 6" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to ports 7 and 8.", + "EventCode": "0xa1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x80", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_DISPATCHED.PORT_7_8", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of uops executed on port 7 and 8" + }, + { + "CollectPEBSRecord": "2", + "EventCode": "0xa2", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "RESOURCE_STALLS.SCOREBOARD", + "SampleAfterValue": "2000003", + "BriefDescription": "Counts cycles where the pipeline is stalled due to serializing operations." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts allocation stall cycles caused by the store buffer (SB) being full. This counts cycles that the pipeline back-end blocked uop delivery from the front-end.", + "EventCode": "0xA2", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x8", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "RESOURCE_STALLS.SB", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles stalled due to no store buffers available. (not including draining form sync)." + }, + { + "CollectPEBSRecord": "2", + "EventCode": "0xA3", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.CYCLES_L2_MISS", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles while L2 cache miss demand load is outstanding.", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "EventCode": "0xA3", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x4", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "CYCLE_ACTIVITY.STALLS_TOTAL", + "SampleAfterValue": "2000003", + "BriefDescription": "Total execution stalls.", + "CounterMask": "4" + }, + { + "CollectPEBSRecord": "2", + "EventCode": "0xA3", + "Counter": "0,1,2,3", + "UMask": "0x5", + "PEBScounters": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.STALLS_L2_MISS", + "SampleAfterValue": "2000003", + "BriefDescription": "Execution stalls while L2 cache miss demand load is outstanding.", + "CounterMask": "5" + }, + { + "CollectPEBSRecord": "2", + "EventCode": "0xA3", + "Counter": "0,1,2,3", + "UMask": "0x8", + "PEBScounters": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.CYCLES_L1D_MISS", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles while L1 cache miss demand load is outstanding.", + "CounterMask": "8" + }, + { + "CollectPEBSRecord": "2", + "EventCode": "0xA3", + "Counter": "0,1,2,3", + "UMask": "0xc", + "PEBScounters": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.STALLS_L1D_MISS", + "SampleAfterValue": "2000003", + "BriefDescription": "Execution stalls while L1 cache miss demand load is outstanding.", + "CounterMask": "12" + }, + { + "CollectPEBSRecord": "2", + "EventCode": "0xA3", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x10", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "CYCLE_ACTIVITY.CYCLES_MEM_ANY", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles while memory subsystem has an outstanding load.", + "CounterMask": "16" + }, + { + "CollectPEBSRecord": "2", + "EventCode": "0xA3", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x14", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "CYCLE_ACTIVITY.STALLS_MEM_ANY", + "SampleAfterValue": "2000003", + "BriefDescription": "Execution stalls while memory subsystem has an outstanding load.", + "CounterMask": "20" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles during which a total of 1 uop was executed on all ports and Reservation Station (RS) was not empty.", + "EventCode": "0xa6", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "EXE_ACTIVITY.1_PORTS_UTIL", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles total of 1 uop is executed on all ports and Reservation Station was not empty." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles during which a total of 2 uops were executed on all ports and Reservation Station (RS) was not empty.", + "EventCode": "0xa6", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x4", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "EXE_ACTIVITY.2_PORTS_UTIL", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles total of 2 uops are executed on all ports and Reservation Station was not empty." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles where the Store Buffer was full and no loads caused an execution stall.", + "EventCode": "0xA6", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x40", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "EXE_ACTIVITY.BOUND_ON_STORES", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles where the Store Buffer was full and no loads caused an execution stall.", + "CounterMask": "2" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles during which no uops were executed on all ports and Reservation Station (RS) was not empty.", + "EventCode": "0xa6", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x80", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "EXE_ACTIVITY.EXE_BOUND_0_PORTS", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles where no uops were executed, the Reservation Station was not empty, the Store Buffer was full and there was no outstanding load." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of uops delivered to the back-end by the LSD(Loop Stream Detector).", + "EventCode": "0xA8", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "LSD.UOPS", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of Uops delivered by the LSD." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the cycles when at least one uop is delivered by the LSD (Loop-stream detector).", + "EventCode": "0xA8", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "LSD.CYCLES_ACTIVE", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles Uops delivered by the LSD, but didn't come from the decoder.", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the cycles when optimal number of uops is delivered by the LSD (Loop-stream detector).", + "EventCode": "0xa8", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "LSD.CYCLES_OK", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles optimal number of Uops delivered by the LSD, but did not come from the decoder.", + "CounterMask": "5" + }, + { + "CollectPEBSRecord": "2", + "EventCode": "0xB1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_EXECUTED.THREAD", + "SampleAfterValue": "2000003", + "BriefDescription": "Counts the number of uops to be executed per-thread each cycle." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles during which no uops were dispatched from the Reservation Station (RS) per thread.", + "EventCode": "0xB1", + "Invert": "1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_EXECUTED.STALL_CYCLES", + "SampleAfterValue": "2000003", + "BriefDescription": "Counts number of cycles no uops were dispatched to be executed on this thread.", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Cycles where at least 1 uop was executed per-thread.", + "EventCode": "0xb1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_EXECUTED.CYCLES_GE_1", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles where at least 1 uop was executed per-thread", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Cycles where at least 2 uops were executed per-thread.", + "EventCode": "0xb1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_EXECUTED.CYCLES_GE_2", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles where at least 2 uops were executed per-thread", + "CounterMask": "2" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Cycles where at least 3 uops were executed per-thread.", + "EventCode": "0xb1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_EXECUTED.CYCLES_GE_3", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles where at least 3 uops were executed per-thread", + "CounterMask": "3" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Cycles where at least 4 uops were executed per-thread.", + "EventCode": "0xb1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_EXECUTED.CYCLES_GE_4", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles where at least 4 uops were executed per-thread", + "CounterMask": "4" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of uops executed from any thread.", + "EventCode": "0xB1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_EXECUTED.CORE", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of uops executed on the core." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles when at least 1 micro-op is executed from any thread on physical core.", + "EventCode": "0xB1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_1", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles at least 1 micro-op is executed from any thread on physical core.", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles when at least 2 micro-ops are executed from any thread on physical core.", + "EventCode": "0xB1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_2", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles at least 2 micro-op is executed from any thread on physical core.", + "CounterMask": "2" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles when at least 3 micro-ops are executed from any thread on physical core.", + "EventCode": "0xB1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_3", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles at least 3 micro-op is executed from any thread on physical core.", + "CounterMask": "3" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles when at least 4 micro-ops are executed from any thread on physical core.", + "EventCode": "0xB1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_4", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles at least 4 micro-op is executed from any thread on physical core.", + "CounterMask": "4" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of x87 uops executed.", + "EventCode": "0xB1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x10", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_EXECUTED.X87", + "SampleAfterValue": "2000003", + "BriefDescription": "Counts the number of x87 uops dispatched." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of X86 instructions retired - an Architectural PerfMon event. Counting continues during hardware interrupts, traps, and inside interrupt handlers. Notes: INST_RETIRED.ANY is counted by a designated fixed counter freeing up programmable counters to count other events. INST_RETIRED.ANY_P is counted by a programmable counter.", + "EventCode": "0xC0", + "Counter": "0,1,2,3,4,5,6,7", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "INST_RETIRED.ANY_P", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of instructions retired. General Counter - architectural event" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of cycles using always true condition (uops_ret &lt; 16) applied to non PEBS uops retired event.", + "EventCode": "0xC2", + "Invert": "1", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_RETIRED.TOTAL_CYCLES", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycles with less than 10 actually retired uops.", + "CounterMask": "10" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the retirement slots used each cycle.", + "EventCode": "0xc2", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "UOPS_RETIRED.SLOTS", + "SampleAfterValue": "2000003", + "BriefDescription": "Retirement slots used." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of machine clears (nukes) of any type.", + "EventCode": "0xC3", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "MACHINE_CLEARS.COUNT", + "SampleAfterValue": "100003", + "BriefDescription": "Number of machine clears (nukes) of any type.", + "CounterMask": "1", + "EdgeDetect": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts self-modifying code (SMC) detected, which causes a machine clear.", + "EventCode": "0xC3", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x4", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "MACHINE_CLEARS.SMC", + "SampleAfterValue": "100003", + "BriefDescription": "Self-modifying code (SMC) detected." + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts all branch instructions retired.", + "EventCode": "0xC4", + "Counter": "0,1,2,3,4,5,6,7", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "BR_INST_RETIRED.ALL_BRANCHES", + "SampleAfterValue": "400009", + "BriefDescription": "All branch instructions retired." + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts taken conditional branch instructions retired.", + "EventCode": "0xc4", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "BR_INST_RETIRED.COND_TAKEN", + "SampleAfterValue": "400009", + "BriefDescription": "Taken conditional branch instructions retired." + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts both direct and indirect near call instructions retired.", + "EventCode": "0xC4", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "BR_INST_RETIRED.NEAR_CALL", + "SampleAfterValue": "100007", + "BriefDescription": "Direct and indirect near call instructions retired." + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts return instructions retired.", + "EventCode": "0xC4", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x8", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "BR_INST_RETIRED.NEAR_RETURN", + "SampleAfterValue": "100007", + "BriefDescription": "Return instructions retired." + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts not taken branch instructions retired.", + "EventCode": "0xC4", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x10", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "BR_INST_RETIRED.COND_NTAKEN", + "SampleAfterValue": "400009", + "BriefDescription": "Not taken branch instructions retired." + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts conditional branch instructions retired.", + "EventCode": "0xc4", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x11", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "BR_INST_RETIRED.COND", + "SampleAfterValue": "400009", + "BriefDescription": "Conditional branch instructions retired." + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts taken branch instructions retired.", + "EventCode": "0xC4", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x20", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "BR_INST_RETIRED.NEAR_TAKEN", + "SampleAfterValue": "400009", + "BriefDescription": "Taken branch instructions retired." + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts far branch instructions retired.", + "EventCode": "0xC4", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x40", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "BR_INST_RETIRED.FAR_BRANCH", + "SampleAfterValue": "100007", + "BriefDescription": "Far branch instructions retired." + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts all indirect branch instructions retired (excluding RETs. TSX aborts is considered indirect branch).", + "EventCode": "0xc4", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x80", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "BR_INST_RETIRED.INDIRECT", + "SampleAfterValue": "100003", + "BriefDescription": "All indirect branch instructions retired (excluding RETs. TSX aborts are considered indirect branch)." + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts all the retired branch instructions that were mispredicted by the processor. A branch misprediction occurs when the processor incorrectly predicts the destination of the branch. When the misprediction is discovered at execution, all the instructions executed in the wrong (speculative) path must be discarded, and the processor must start fetching from the correct path.", + "EventCode": "0xC5", + "Counter": "0,1,2,3,4,5,6,7", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "BR_MISP_RETIRED.ALL_BRANCHES", + "SampleAfterValue": "400009", + "BriefDescription": "All mispredicted branch instructions retired.", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts taken conditional mispredicted branch instructions retired.", + "EventCode": "0xc5", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "BR_MISP_RETIRED.COND_TAKEN", + "SampleAfterValue": "400009", + "BriefDescription": "number of branch instructions retired that were mispredicted and taken. Non PEBS", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts mispredicted conditional branch instructions retired.", + "EventCode": "0xc5", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x11", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "BR_MISP_RETIRED.COND", + "SampleAfterValue": "400009", + "BriefDescription": "Mispredicted conditional branch instructions retired.", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts number of near branch instructions retired that were mispredicted and taken.", + "EventCode": "0xC5", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x20", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "BR_MISP_RETIRED.NEAR_TAKEN", + "SampleAfterValue": "400009", + "BriefDescription": "Number of near branch instructions retired that were mispredicted and taken.", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts all miss-predicted indirect branch instructions retired (excluding RETs. TSX aborts is considered indirect branch).", + "EventCode": "0xC5", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x80", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "BR_MISP_RETIRED.INDIRECT", + "SampleAfterValue": "100003", + "BriefDescription": "All miss-predicted indirect branch instructions retired (excluding RETs. TSX aborts is considered indirect branch).", + "Data_LA": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Increments when an entry is added to the Last Branch Record (LBR) array (or removed from the array in case of RETURNs in call stack mode). The event requires LBR enable via IA32_DEBUGCTL MSR and branch type selection via MSR_LBR_SELECT.", + "EventCode": "0xcc", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x20", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "MISC_RETIRED.LBR_INSERTS", + "SampleAfterValue": "2000003", + "BriefDescription": "Increments whenever there is an update to the LBR array." + }, + { + "PublicDescription": "Counts number of retired PAUSE instructions (that do not end up with a VMExit to the VMM; TSX aborted Instructions may be counted).", + "EventCode": "0xcc", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x40", + "EventName": "MISC_RETIRED.PAUSE_INST", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of retired PAUSE instructions." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times the front-end is resteered when it finds a branch instruction in a fetch line. This occurs for the first time a branch instruction is fetched or when the branch is not tracked by the BPU (Branch Prediction Unit) anymore.", + "EventCode": "0xE6", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "BACLEARS.ANY", + "SampleAfterValue": "100003", + "BriefDescription": "Counts the total number when the front end is resteered, mainly when the BPU cannot provide a correct prediction and this is corrected by other branch handling mechanisms at the front end." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "This event distributes cycle counts between active hyperthreads, i.e., those in C0. A hyperthread becomes inactive when it executes the HLT or MWAIT instructions. If all other hyperthreads are inactive (or disabled or do not exist), all counts are attributed to this hyperthread. To obtain the full count when the Core is active, sum the counts from each hyperthread.", + "EventCode": "0xec", + "Counter": "0,1,2,3,4,5,6,7", + "UMask": "0x2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "EventName": "CPU_CLK_UNHALTED.DISTRIBUTED", + "SampleAfterValue": "2000003", + "BriefDescription": "Cycle counts are evenly distributed between active threads in the Core." + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/icelake/virtual-memory.json b/tools/perf/pmu-events/arch/x86/icelake/virtual-memory.json new file mode 100644 index 000000000000..7180a900c175 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/icelake/virtual-memory.json @@ -0,0 +1,236 @@ +[ + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts page walks completed due to demand data loads whose address translations missed in the TLB and were mapped to 4K pages. The page walks can end with or without a page fault.", + "EventCode": "0x08", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_4K", + "SampleAfterValue": "2000003", + "BriefDescription": "Page walks completed due to a demand data load to a 4K page." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts page walks completed due to demand data loads whose address translations missed in the TLB and were mapped to 2M/4M pages. The page walks can end with or without a page fault.", + "EventCode": "0x08", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4M", + "SampleAfterValue": "2000003", + "BriefDescription": "Page walks completed due to a demand data load to a 2M/4M page." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts demand data loads that caused a completed page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "EventCode": "0x08", + "Counter": "0,1,2,3", + "UMask": "0xe", + "PEBScounters": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED", + "SampleAfterValue": "100003", + "BriefDescription": "Load miss in all TLB levels causes a page walk that completes. (All page sizes)" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of page walks outstanding for a demand load in the PMH (Page Miss Handler) each cycle.", + "EventCode": "0x08", + "Counter": "0,1,2,3", + "UMask": "0x10", + "PEBScounters": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_PENDING", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of page walks outstanding for a demand load in the PMH each cycle." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles when at least one PMH (Page Miss Handler) is busy with a page walk for a demand load.", + "EventCode": "0x08", + "Counter": "0,1,2,3", + "UMask": "0x10", + "PEBScounters": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_ACTIVE", + "SampleAfterValue": "100003", + "BriefDescription": "Cycles when at least one PMH is busy with a page walk for a demand load.", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts loads that miss the DTLB (Data TLB) and hit the STLB (Second level TLB).", + "EventCode": "0x08", + "Counter": "0,1,2,3", + "UMask": "0x20", + "PEBScounters": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.STLB_HIT", + "SampleAfterValue": "2000003", + "BriefDescription": "Loads that miss the DTLB and hit the STLB." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts page walks completed due to demand data stores whose address translations missed in the TLB and were mapped to 4K pages. The page walks can end with or without a page fault.", + "EventCode": "0x49", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_4K", + "SampleAfterValue": "100003", + "BriefDescription": "Page walks completed due to a demand data store to a 4K page." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts page walks completed due to demand data stores whose address translations missed in the TLB and were mapped to 2M/4M pages. The page walks can end with or without a page fault.", + "EventCode": "0x49", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M", + "SampleAfterValue": "100003", + "BriefDescription": "Page walks completed due to a demand data store to a 2M/4M page." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts demand data stores that caused a completed page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "EventCode": "0x49", + "Counter": "0,1,2,3", + "UMask": "0xe", + "PEBScounters": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED", + "SampleAfterValue": "100003", + "BriefDescription": "Store misses in all TLB levels causes a page walk that completes. (All page sizes)" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of page walks outstanding for a store in the PMH (Page Miss Handler) each cycle.", + "EventCode": "0x49", + "Counter": "0,1,2,3", + "UMask": "0x10", + "PEBScounters": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_PENDING", + "SampleAfterValue": "2000003", + "BriefDescription": "Number of page walks outstanding for a store in the PMH each cycle." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles when at least one PMH (Page Miss Handler) is busy with a page walk for a store.", + "EventCode": "0x49", + "Counter": "0,1,2,3", + "UMask": "0x10", + "PEBScounters": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_ACTIVE", + "SampleAfterValue": "100003", + "BriefDescription": "Cycles when at least one PMH is busy with a page walk for a store.", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts stores that miss the DTLB (Data TLB) and hit the STLB (2nd Level TLB).", + "EventCode": "0x49", + "Counter": "0,1,2,3", + "UMask": "0x20", + "PEBScounters": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.STLB_HIT", + "SampleAfterValue": "100003", + "BriefDescription": "Stores that miss the DTLB and hit the STLB." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts completed page walks (4K page size) caused by a code fetch. This implies it missed in the ITLB and further levels of TLB. The page walk can end with or without a fault.", + "EventCode": "0x85", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_COMPLETED_4K", + "SampleAfterValue": "100003", + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (4K)" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts code misses in all ITLB (Instruction TLB) levels that caused a completed page walk (2M and 4M page sizes). The page walk can end with or without a fault.", + "EventCode": "0x85", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_COMPLETED_2M_4M", + "SampleAfterValue": "100003", + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (2M/4M)" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts completed page walks (2M and 4M page sizes) caused by a code fetch. This implies it missed in the ITLB (Instruction TLB) and further levels of TLB. The page walk can end with or without a fault.", + "EventCode": "0x85", + "Counter": "0,1,2,3", + "UMask": "0xe", + "PEBScounters": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_COMPLETED", + "SampleAfterValue": "100003", + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (All page sizes)" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of page walks outstanding for an outstanding code (instruction fetch) request in the PMH (Page Miss Handler) each cycle.", + "EventCode": "0x85", + "Counter": "0,1,2,3", + "UMask": "0x10", + "PEBScounters": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_PENDING", + "SampleAfterValue": "100003", + "BriefDescription": "Number of page walks outstanding for an outstanding code request in the PMH each cycle." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cycles when at least one PMH (Page Miss Handler) is busy with a page walk for a code (instruction fetch) request.", + "EventCode": "0x85", + "Counter": "0,1,2,3", + "UMask": "0x10", + "PEBScounters": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_ACTIVE", + "SampleAfterValue": "100003", + "BriefDescription": "Cycles when at least one PMH is busy with a page walk for code (instruction fetch) request.", + "CounterMask": "1" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts instruction fetch requests that miss the ITLB (Instruction TLB) and hit the STLB (Second-level TLB).", + "EventCode": "0x85", + "Counter": "0,1,2,3", + "UMask": "0x20", + "PEBScounters": "0,1,2,3", + "EventName": "ITLB_MISSES.STLB_HIT", + "SampleAfterValue": "100003", + "BriefDescription": "Instruction fetch requests that miss the ITLB and hit the STLB." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of flushes of the big or small ITLB pages. Counting include both TLB Flush (covering all sets) and TLB Set Clear (set-specific).", + "EventCode": "0xAE", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "ITLB.ITLB_FLUSH", + "SampleAfterValue": "100007", + "BriefDescription": "Flushing of the Instruction TLB (ITLB) pages, includes 4k/2M/4M pages." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of DTLB flush attempts of the thread-specific entries.", + "EventCode": "0xBD", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "TLB_FLUSH.DTLB_THREAD", + "SampleAfterValue": "100007", + "BriefDescription": "DTLB flush attempts of the thread-specific entries" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of any STLB flush attempts (such as entire, VPID, PCID, InvPage, CR3 write, etc.).", + "EventCode": "0xBD", + "Counter": "0,1,2,3", + "UMask": "0x20", + "PEBScounters": "0,1,2,3", + "EventName": "TLB_FLUSH.STLB_ANY", + "SampleAfterValue": "100007", + "BriefDescription": "STLB flush attempts" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/mapfile.csv b/tools/perf/pmu-events/arch/x86/mapfile.csv index d6984a3017e0..b90e5fec2f32 100644 --- a/tools/perf/pmu-events/arch/x86/mapfile.csv +++ b/tools/perf/pmu-events/arch/x86/mapfile.csv @@ -33,4 +33,6 @@ GenuineIntel-6-25,v2,westmereep-sp,core GenuineIntel-6-2F,v2,westmereex,core GenuineIntel-6-55-[01234],v1,skylakex,core GenuineIntel-6-55-[56789ABCDEF],v1,cascadelakex,core +GenuineIntel-6-7D,v1,icelake,core +GenuineIntel-6-7E,v1,icelake,core AuthenticAMD-23-[[:xdigit:]]+,v1,amdfam17h,core -- cgit v1.2.3-59-g8ed1b From 1205a2719e52b6b52e0f9c0011554419da0377a0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 6 Aug 2019 11:20:42 -0300 Subject: perf top: Set display thread COMM to help with debugging When we want to attach just to the thread that updates the display it helps having its COMM stand out, so change it from the default "perf" to "perf-top-UI". Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-5w0hmlk3zfvysxvpsh763k9w@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 1a4615a5f6c9..94e34853a238 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -601,6 +601,8 @@ static void *display_thread_tui(void *arg) */ unshare(CLONE_FS); + prctl(PR_SET_NAME, "perf-top-UI", 0, 0, 0); + perf_top__sort_new_samples(top); /* @@ -651,6 +653,8 @@ static void *display_thread(void *arg) */ unshare(CLONE_FS); + prctl(PR_SET_NAME, "perf-top-UI", 0, 0, 0); + display_setup_sig(); pthread__unblock_sigwinch(); repeat: -- cgit v1.2.3-59-g8ed1b From 7d1a5efa20dbfea97cb93b99c67ce5cd5c4a4dbc Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 7 Aug 2019 10:45:30 -0300 Subject: perf hists: Do not link a pair if already linked When we have multiple events in a group we link hist_entries in the non-leader evsel hists to the one in the leader that points to the same sorting criteria, in hists__match(). For 'perf report' we do this just once and then print the results, but for 'perf top' we need to look if this was already done in the previous refresh of the screen, so check for that and don't try to link again. This is part of having 'perf top' using the hists browser for showing multiple events in multiple columns. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-iwvb37rgb7upswhruwpcdnhw@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 4297f56b1e05..d923a5bb7b48 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -2453,7 +2453,7 @@ void hists__match(struct hists *leader, struct hists *other) pos = rb_entry(nd, struct hist_entry, rb_node_in); pair = hists__find_entry(other, pos); - if (pair) + if (pair && list_empty(&pair->pairs.node)) hist_entry__add_pair(pair, pos); } } -- cgit v1.2.3-59-g8ed1b From 3e70008a6021fffd2cd1614734603ea970773060 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Fri, 9 Aug 2019 18:47:52 +0800 Subject: perf trace: Fix segmentation fault when access syscall info on arm64 'perf trace' reports the segmentation fault as below on Arm64: # perf trace -e string -e augmented_raw_syscalls.c LLVM: dumping tools/perf/examples/bpf/augmented_raw_syscalls.o perf: Segmentation fault Obtained 12 stack frames. perf(sighandler_dump_stack+0x47) [0xaaaaac96ac87] linux-vdso.so.1(+0x5b7) [0xffffadbeb5b7] /lib/aarch64-linux-gnu/libc.so.6(strlen+0x10) [0xfffface7d5d0] /lib/aarch64-linux-gnu/libc.so.6(_IO_vfprintf+0x1ac7) [0xfffface49f97] /lib/aarch64-linux-gnu/libc.so.6(__vsnprintf_chk+0xc7) [0xffffacedfbe7] perf(scnprintf+0x97) [0xaaaaac9ca3ff] perf(+0x997bb) [0xaaaaac8e37bb] perf(cmd_trace+0x28e7) [0xaaaaac8ec09f] perf(+0xd4a13) [0xaaaaac91ea13] perf(main+0x62f) [0xaaaaac8a147f] /lib/aarch64-linux-gnu/libc.so.6(__libc_start_main+0xe3) [0xfffface22d23] perf(+0x57723) [0xaaaaac8a1723] Segmentation fault This issue is introduced by commit 30a910d7d3e0 ("perf trace: Preallocate the syscall table"), it allocates trace->syscalls.table[] array and the element count is 'trace->sctbl->syscalls.nr_entries'; but on Arm64, the system call number is not continuously used; e.g. the syscall maximum id is 436 but the real entries is only 281. So the table is allocated with 'nr_entries' as the element count, but it accesses the table with the syscall id, which might be out of the bound of the array and cause the segmentation fault. This patch allocates trace->syscalls.table[] with the element count is 'trace->sctbl->syscalls.max_id + 1', this allows any id to access the table without out of the bound. Signed-off-by: Leo Yan Cc: Alexander Shishkin Cc: Daniel Borkmann Cc: Jiri Olsa Cc: Martin KaFai Lau Cc: Namhyung Kim Cc: Song Liu Cc: Yonghong Song Fixes: 30a910d7d3e0 ("perf trace: Preallocate the syscall table") Link: http://lkml.kernel.org/r/20190809104752.27338-1-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 75eb3811e942..d553d06a9aeb 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1492,7 +1492,7 @@ static int trace__read_syscall_info(struct trace *trace, int id) const char *name = syscalltbl__name(trace->sctbl, id); if (trace->syscalls.table == NULL) { - trace->syscalls.table = calloc(trace->sctbl->syscalls.nr_entries, sizeof(*sc)); + trace->syscalls.table = calloc(trace->sctbl->syscalls.max_id + 1, sizeof(*sc)); if (trace->syscalls.table == NULL) return -ENOMEM; } -- cgit v1.2.3-59-g8ed1b From 5f8b4d5d237a3e2e35509da4e63769ae5c82c085 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 9 Aug 2019 17:56:06 -0300 Subject: perf hist: Remove dummy entries when finding real ones. When he have an event group we have multiple struct hist instances, one per evsel, and in each of these hists we may have hist_entries that point to the same thing being observed, say a symbol, i.e. if we're looking at instructions and cycles, then we'll have one hist_entry in the "instructions" evsel and another in the "cycles" evsel. We need to link those to then show one column for each. When we're looking at some other pair of events, say instructions and cache misses, we may have just the "instructions" hist entry and not one for "cache misses", as instructions not necessarily generate cache misses, as the logic expects one hist_entry per evsel, we end up adding "dummy" hist_entries. This is enough for 'perf report', that does this matching operation (hists__match()) just once after processing all events, but for 'perf top', we do this at each refresh, so we may finally find events matching and then we need to trow away the dummies and link with the real events. So if we find a match, traverse the link of matches and trow away dummies for that hists. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-dwvtjqqifsbsczeb35q6mqkk@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index d923a5bb7b48..8efbf58dc3d0 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -2436,7 +2436,7 @@ void hists__match(struct hists *leader, struct hists *other) { struct rb_root_cached *root; struct rb_node *nd; - struct hist_entry *pos, *pair; + struct hist_entry *pos, *pair, *pos_pair, *tmp_pair; if (symbol_conf.report_hierarchy) { /* hierarchy report always collapses entries */ @@ -2453,8 +2453,24 @@ void hists__match(struct hists *leader, struct hists *other) pos = rb_entry(nd, struct hist_entry, rb_node_in); pair = hists__find_entry(other, pos); - if (pair && list_empty(&pair->pairs.node)) + if (pair && list_empty(&pair->pairs.node)) { + list_for_each_entry_safe(pos_pair, tmp_pair, &pos->pairs.head, pairs.node) { + if (pos_pair->hists == other) { + /* + * XXX maybe decayed entries can appear + * here? but then we would have use + * after free, as decayed entries are + * freed see hists__delete_entry + */ + BUG_ON(!pos_pair->dummy); + list_del_init(&pos_pair->pairs.node); + hist_entry__delete(pos_pair); + break; + } + } + hist_entry__add_pair(pair, pos); + } } } -- cgit v1.2.3-59-g8ed1b From 40d81772dac45643cecc7add0e95356072265754 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 9 Aug 2019 16:44:34 -0300 Subject: perf top: Collapse and resort all evsels in a group And link them, i.e. find the hist entries in the non-leader events and link them to the ones in the leader. This should be the same thing already done for the 'perf report' case, but now we do it periodically. With this in place we get percentages in from the second overhead column on, not just on the first (the leader). Try it using: perf top --stdio -e '{cycles,instructions}' You should see something like: PerfTop: 20776 irqs/sec kernel:68.7% exact: 0.0% lost: 0/0 drop: 0/0 [cycles], (all, 8 CPUs) --------------------------------------------------------------------------------------------------- 4.44% 0.44% [kernel] [k] do_syscall_64 2.27% 0.17% [kernel] [k] entry_SYSCALL_64 1.73% 0.27% [kernel] [k] syscall_return_via_sysret 1.60% 0.91% [kernel] [k] _raw_spin_lock_irqsave 1.45% 3.53% libglib-2.0.so.0.6000.4 [.] g_string_insert_unichar 1.39% 0.21% [kernel] [k] copy_user_enhanced_fast_string 1.26% 1.15% [kernel] [k] psi_task_change 1.16% 0.14% libpixman-1.so.0.38.0 [.] 0x000000000006f403 1.00% 0.32% [kernel] [k] __sched_text_start 0.97% 2.11% [kernel] [k] n_tty_write 0.96% 0.04% [kernel] [k] queued_spin_lock_slowpath 0.93% 0.88% [kernel] [k] menu_select 0.87% 0.14% [kernel] [k] try_to_wake_up 0.77% 0.10% libpixman-1.so.0.38.0 [.] 0x000000000006f40b 0.73% 0.09% libpixman-1.so.0.38.0 [.] 0x000000000006f413 0.69% 0.48% libc-2.29.so [.] __memmove_avx_unaligned_erms 0.68% 0.29% [kernel] [k] _raw_spin_lock_irq 0.61% 0.04% libpixman-1.so.0.38.0 [.] 0x000000000006f423 0.60% 0.37% [kernel] [k] native_sched_clock 0.57% 0.23% [kernel] [k] do_idle 0.57% 0.23% [kernel] [k] __fget 0.56% 0.30% [kernel] [k] __switch_to_asm 0.56% 0.00% libc-2.29.so [.] __memset_avx2_erms 0.52% 0.32% [kernel] [k] _raw_spin_lock 0.49% 0.24% [kernel] [k] n_tty_poll 0.49% 0.54% libglib-2.0.so.0.6000.4 [.] g_mutex_lock 0.48% 0.62% [kernel] [k] _raw_spin_unlock_irqrestore 0.47% 0.27% [kernel] [k] __switch_to 0.47% 0.25% [kernel] [k] pick_next_task_fair 0.45% 0.17% [kernel] [k] filldir64 0.40% 0.16% [kernel] [k] update_rq_clock 0.39% 0.19% [kernel] [k] enqueue_task_fair # Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-uw8cjeifxvjpkjp6x2iil0ar@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 94e34853a238..78e7efc597a6 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -264,6 +264,30 @@ out_unlock: pthread_mutex_unlock(¬es->lock); } +static void evlist__resort_hists(struct evlist *evlist) +{ + struct evsel *pos; + + evlist__for_each_entry(evlist, pos) { + struct hists *hists = evsel__hists(pos); + + hists__collapse_resort(hists, NULL); + + /* Non-group events are considered as leader */ + if (symbol_conf.event_group && + !perf_evsel__is_group_leader(pos)) { + struct hists *leader_hists = evsel__hists(pos->leader); + + hists__match(leader_hists, hists); + hists__link(leader_hists, hists); + } + } + + evlist__for_each_entry(evlist, pos) { + perf_evsel__output_resort(pos, NULL); + } +} + static void perf_top__print_sym_table(struct perf_top *top) { char bf[160]; @@ -304,8 +328,7 @@ static void perf_top__print_sym_table(struct perf_top *top) } } - hists__collapse_resort(hists, NULL); - perf_evsel__output_resort(evsel, NULL); + evlist__resort_hists(top->evlist); hists__output_recalc_col_len(hists, top->print_entries - printed); putchar('\n'); @@ -570,8 +593,7 @@ static void perf_top__sort_new_samples(void *arg) } } - hists__collapse_resort(hists, NULL); - perf_evsel__output_resort(evsel, NULL); + evlist__resort_hists(t->evlist); if (t->lost || t->drop) pr_warning("Too slow to read ring buffer (change period (-c/-F) or limit CPUs (-C)\n"); -- cgit v1.2.3-59-g8ed1b From 74d5f3d06f707eb5f7e1908ad88954bde02000ce Mon Sep 17 00:00:00 2001 From: Igor Lubashev Date: Wed, 7 Aug 2019 10:44:14 -0400 Subject: tools build: Add capability-related feature detection Add utilities to help checking capabilities of the running procss. Make perf link with libcap, if it is available. If no libcap-dev[el], assume no capabilities. Committer testing: $ make O=/tmp/build/perf -C tools/perf install-bin make: Entering directory '/home/acme/git/perf/tools/perf' BUILD: Doing 'make -j8' parallel build Auto-detecting system features: ... libbfd: [ on ] ... libcap: [ OFF ] ... libelf: [ on ] Makefile.config:833: No libcap found, disables capability support, please install libcap-devel/libcap-dev $ grep libcap /tmp/build/perf/FEATURE-DUMP feature-libcap=0 $ cat /tmp/build/perf/feature/test-libcap.make.output test-libcap.c:2:10: fatal error: sys/capability.h: No such file or directory 2 | #include | ^~~~~~~~~~~~~~~~~~ compilation terminated. $ Now install libcap-devel and try again: $ make O=/tmp/build/perf -C tools/perf install-bin make: Entering directory '/home/acme/git/perf/tools/perf' BUILD: Doing 'make -j8' parallel build Warning: Kernel ABI header at 'tools/include/linux/bits.h' differs from latest version at 'include/linux/bits.h' diff -u tools/include/linux/bits.h include/linux/bits.h Warning: Kernel ABI header at 'tools/arch/x86/include/asm/cpufeatures.h' differs from latest version at 'arch/x86/include/asm/cpufeatures.h' diff -u tools/arch/x86/include/asm/cpufeatures.h arch/x86/include/asm/cpufeatures.h Auto-detecting system features: ... libbfd: [ on ] ... libcap: [ on ] ... libelf: [ on ] > CC /tmp/build/perf/jvmti/libjvmti.o > $ grep libcap /tmp/build/perf/FEATURE-DUMP feature-libcap=1 $ cat /tmp/build/perf/feature/test-libcap.make.output $ ldd /tmp/build/perf/feature/test-libcap.make.bin ldd: /tmp/build/perf/feature/test-libcap.make.bin: No such file or directory $ ldd /tmp/build/perf/feature/test-libcap.bin linux-vdso.so.1 (0x00007ffc35bfe000) libcap.so.2 => /lib64/libcap.so.2 (0x00007ff9c62ff000) libc.so.6 => /lib64/libc.so.6 (0x00007ff9c6139000) /lib64/ld-linux-x86-64.so.2 (0x00007ff9c6326000) $ Signed-off-by: Igor Lubashev Acked-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Alexey Budankov Cc: James Morris Cc: Mathieu Poirier Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Suzuki Poulouse [ split from a larger patch ] Link: http://lkml.kernel.org/r/8a1e76cf5c7c9796d0d4d240fbaa85305298aafa.1565188228.git.ilubashe@akamai.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/build/Makefile.feature | 2 ++ tools/build/feature/Makefile | 4 ++++ tools/build/feature/test-libcap.c | 20 ++++++++++++++++++++ tools/perf/Makefile.config | 11 +++++++++++ tools/perf/Makefile.perf | 2 ++ 5 files changed, 39 insertions(+) create mode 100644 tools/build/feature/test-libcap.c (limited to 'tools') diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature index 86b793dffbc4..8a19753cc26a 100644 --- a/tools/build/Makefile.feature +++ b/tools/build/Makefile.feature @@ -42,6 +42,7 @@ FEATURE_TESTS_BASIC := \ gtk2-infobar \ libaudit \ libbfd \ + libcap \ libelf \ libelf-getphdrnum \ libelf-gelf_getnote \ @@ -110,6 +111,7 @@ FEATURE_DISPLAY ?= \ gtk2 \ libaudit \ libbfd \ + libcap \ libelf \ libnuma \ numa_num_possible_cpus \ diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile index 0658b8cd0e53..8499385365c0 100644 --- a/tools/build/feature/Makefile +++ b/tools/build/feature/Makefile @@ -20,6 +20,7 @@ FILES= \ test-libbfd-liberty.bin \ test-libbfd-liberty-z.bin \ test-cplus-demangle.bin \ + test-libcap.bin \ test-libelf.bin \ test-libelf-getphdrnum.bin \ test-libelf-gelf_getnote.bin \ @@ -105,6 +106,9 @@ $(OUTPUT)test-fortify-source.bin: $(OUTPUT)test-bionic.bin: $(BUILD) +$(OUTPUT)test-libcap.bin: + $(BUILD) -lcap + $(OUTPUT)test-libelf.bin: $(BUILD) -lelf diff --git a/tools/build/feature/test-libcap.c b/tools/build/feature/test-libcap.c new file mode 100644 index 000000000000..d2a2e152195f --- /dev/null +++ b/tools/build/feature/test-libcap.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + +int main(void) +{ + cap_flag_value_t val; + cap_t caps = cap_get_proc(); + + if (!caps) + return 1; + + if (cap_get_flag(caps, CAP_SYS_ADMIN, CAP_EFFECTIVE, &val) != 0) + return 1; + + if (cap_free(caps) != 0) + return 1; + + return 0; +} diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index e4988f49ea79..9a06787fedc6 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -824,6 +824,17 @@ ifndef NO_LIBZSTD endif endif +ifndef NO_LIBCAP + ifeq ($(feature-libcap), 1) + CFLAGS += -DHAVE_LIBCAP_SUPPORT + EXTLIBS += -lcap + $(call detected,CONFIG_LIBCAP) + else + msg := $(warning No libcap found, disables capability support, please install libcap-devel/libcap-dev); + NO_LIBCAP := 1 + endif +endif + ifndef NO_BACKTRACE ifeq ($(feature-backtrace), 1) CFLAGS += -DHAVE_BACKTRACE_SUPPORT diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 67512a12276b..f9807d8c005b 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -88,6 +88,8 @@ include ../scripts/utilities.mak # # Define NO_LIBBPF if you do not want BPF support # +# Define NO_LIBCAP if you do not want process capabilities considered by perf +# # Define NO_SDT if you do not want to define SDT event in perf tools, # note that it doesn't disable SDT scanning support. # -- cgit v1.2.3-59-g8ed1b From d66fa3c70e598746a907e5db5ed024035e01817a Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Tue, 13 Aug 2019 01:38:33 +0100 Subject: tools: bpftool: add feature check for zlib bpftool requires libelf, and zlib for decompressing /proc/config.gz. zlib is a transitive dependency via libelf, and became mandatory since elfutils 0.165 (Jan 2016). The feature check of libelf is already done in the elfdep target of tools/lib/bpf/Makefile, pulled in by bpftool via a dependency on libbpf.a. Add a similar feature check for zlib. Suggested-by: Jakub Kicinski Signed-off-by: Peter Wu Acked-by: Jakub Kicinski Signed-off-by: Daniel Borkmann --- tools/bpf/bpftool/Makefile | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile index 078bd0dcfba5..4c9d1ffc3fc7 100644 --- a/tools/bpf/bpftool/Makefile +++ b/tools/bpf/bpftool/Makefile @@ -58,8 +58,8 @@ INSTALL ?= install RM ?= rm -f FEATURE_USER = .bpftool -FEATURE_TESTS = libbfd disassembler-four-args reallocarray -FEATURE_DISPLAY = libbfd disassembler-four-args +FEATURE_TESTS = libbfd disassembler-four-args reallocarray zlib +FEATURE_DISPLAY = libbfd disassembler-four-args zlib check_feat := 1 NON_CHECK_FEAT_TARGETS := clean uninstall doc doc-clean doc-install doc-uninstall @@ -111,6 +111,8 @@ OBJS = $(patsubst %.c,$(OUTPUT)%.o,$(SRCS)) $(OUTPUT)disasm.o $(OUTPUT)disasm.o: $(srctree)/kernel/bpf/disasm.c $(QUIET_CC)$(COMPILE.c) -MMD -o $@ $< +$(OUTPUT)feature.o: | zdep + $(OUTPUT)bpftool: $(OBJS) $(LIBBPF) $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) @@ -149,6 +151,9 @@ doc-uninstall: FORCE: -.PHONY: all FORCE clean install uninstall +zdep: + @if [ "$(feature-zlib)" != "1" ]; then echo "No zlib found"; exit 1 ; fi + +.PHONY: all FORCE clean install uninstall zdep .PHONY: doc doc-clean doc-install doc-uninstall .DEFAULT_GOAL := all -- cgit v1.2.3-59-g8ed1b From 9840a4ffcf0b26e08472ed53d176a6a0f1d4c498 Mon Sep 17 00:00:00 2001 From: Petar Penkov Date: Mon, 12 Aug 2019 16:30:39 -0700 Subject: selftests/bpf: fix race in flow dissector tests Since the "last_dissection" map holds only the flow keys for the most recent packet, there is a small race in the skb-less flow dissector tests if a new packet comes between transmitting the test packet, and reading its keys from the map. If this happens, the test packet keys will be overwritten and the test will fail. Changing the "last_dissection" map to a hash map, keyed on the source/dest port pair resolves this issue. Additionally, let's clear the last test results from the map between tests to prevent previous test cases from interfering with the following test cases. Fixes: 0905beec9f52 ("selftests/bpf: run flow dissector tests in skb-less mode") Signed-off-by: Petar Penkov Signed-off-by: Daniel Borkmann --- .../selftests/bpf/prog_tests/flow_dissector.c | 22 +++++++++++++++++++++- tools/testing/selftests/bpf/progs/bpf_flow.c | 13 ++++++------- 2 files changed, 27 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c index 700d73d2f22a..6892b88ae065 100644 --- a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c +++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c @@ -109,6 +109,8 @@ struct test tests[] = { .iph.protocol = IPPROTO_TCP, .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES), .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, }, .keys = { .nhoff = ETH_HLEN, @@ -116,6 +118,8 @@ struct test tests[] = { .addr_proto = ETH_P_IP, .ip_proto = IPPROTO_TCP, .n_proto = __bpf_constant_htons(ETH_P_IP), + .sport = 80, + .dport = 8080, }, }, { @@ -125,6 +129,8 @@ struct test tests[] = { .iph.nexthdr = IPPROTO_TCP, .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES), .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, }, .keys = { .nhoff = ETH_HLEN, @@ -132,6 +138,8 @@ struct test tests[] = { .addr_proto = ETH_P_IPV6, .ip_proto = IPPROTO_TCP, .n_proto = __bpf_constant_htons(ETH_P_IPV6), + .sport = 80, + .dport = 8080, }, }, { @@ -143,6 +151,8 @@ struct test tests[] = { .iph.protocol = IPPROTO_TCP, .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES), .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, }, .keys = { .nhoff = ETH_HLEN + VLAN_HLEN, @@ -150,6 +160,8 @@ struct test tests[] = { .addr_proto = ETH_P_IP, .ip_proto = IPPROTO_TCP, .n_proto = __bpf_constant_htons(ETH_P_IP), + .sport = 80, + .dport = 8080, }, }, { @@ -161,6 +173,8 @@ struct test tests[] = { .iph.nexthdr = IPPROTO_TCP, .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES), .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, }, .keys = { .nhoff = ETH_HLEN + VLAN_HLEN * 2, @@ -169,6 +183,8 @@ struct test tests[] = { .addr_proto = ETH_P_IPV6, .ip_proto = IPPROTO_TCP, .n_proto = __bpf_constant_htons(ETH_P_IPV6), + .sport = 80, + .dport = 8080, }, }, { @@ -487,7 +503,8 @@ void test_flow_dissector(void) BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG; struct bpf_prog_test_run_attr tattr = {}; struct bpf_flow_keys flow_keys = {}; - __u32 key = 0; + __u32 key = (__u32)(tests[i].keys.sport) << 16 | + tests[i].keys.dport; /* For skb-less case we can't pass input flags; run * only the tests that have a matching set of flags. @@ -504,6 +521,9 @@ void test_flow_dissector(void) CHECK_ATTR(err, tests[i].name, "skb-less err %d\n", err); CHECK_FLOW_KEYS(tests[i].name, flow_keys, tests[i].keys); + + err = bpf_map_delete_elem(keys_fd, &key); + CHECK_ATTR(err, tests[i].name, "bpf_map_delete_elem %d\n", err); } bpf_prog_detach(prog_fd, BPF_FLOW_DISSECTOR); diff --git a/tools/testing/selftests/bpf/progs/bpf_flow.c b/tools/testing/selftests/bpf/progs/bpf_flow.c index 08bd8b9d58d0..040a44206f29 100644 --- a/tools/testing/selftests/bpf/progs/bpf_flow.c +++ b/tools/testing/selftests/bpf/progs/bpf_flow.c @@ -65,8 +65,8 @@ struct { } jmp_table SEC(".maps"); struct { - __uint(type, BPF_MAP_TYPE_ARRAY); - __uint(max_entries, 1); + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 1024); __type(key, __u32); __type(value, struct bpf_flow_keys); } last_dissection SEC(".maps"); @@ -74,12 +74,11 @@ struct { static __always_inline int export_flow_keys(struct bpf_flow_keys *keys, int ret) { - struct bpf_flow_keys *val; - __u32 key = 0; + __u32 key = (__u32)(keys->sport) << 16 | keys->dport; + struct bpf_flow_keys val; - val = bpf_map_lookup_elem(&last_dissection, &key); - if (val) - memcpy(val, keys, sizeof(*val)); + memcpy(&val, keys, sizeof(val)); + bpf_map_update_elem(&last_dissection, &key, &val, BPF_ANY); return ret; } -- cgit v1.2.3-59-g8ed1b From a1916a153c254cd0ad13b23bed262ed56922cc7a Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Tue, 13 Aug 2019 11:54:43 -0700 Subject: libbpf: attempt to load kernel BTF from sysfs first Add support for loading kernel BTF from sysfs (/sys/kernel/btf/vmlinux) as a target BTF. Also extend the list of on disk search paths for vmlinux ELF image with entries that perf is searching for. Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann --- tools/lib/bpf/libbpf.c | 64 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 3abf2dd1b3b5..8462dab02812 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -2807,15 +2807,61 @@ static int bpf_core_reloc_insn(struct bpf_program *prog, int insn_off, return 0; } +static struct btf *btf_load_raw(const char *path) +{ + struct btf *btf; + size_t read_cnt; + struct stat st; + void *data; + FILE *f; + + if (stat(path, &st)) + return ERR_PTR(-errno); + + data = malloc(st.st_size); + if (!data) + return ERR_PTR(-ENOMEM); + + f = fopen(path, "rb"); + if (!f) { + btf = ERR_PTR(-errno); + goto cleanup; + } + + read_cnt = fread(data, 1, st.st_size, f); + fclose(f); + if (read_cnt < st.st_size) { + btf = ERR_PTR(-EBADF); + goto cleanup; + } + + btf = btf__new(data, read_cnt); + +cleanup: + free(data); + return btf; +} + /* * Probe few well-known locations for vmlinux kernel image and try to load BTF * data out of it to use for target BTF. */ static struct btf *bpf_core_find_kernel_btf(void) { - const char *locations[] = { - "/lib/modules/%1$s/vmlinux-%1$s", - "/usr/lib/modules/%1$s/kernel/vmlinux", + struct { + const char *path_fmt; + bool raw_btf; + } locations[] = { + /* try canonical vmlinux BTF through sysfs first */ + { "/sys/kernel/btf/vmlinux", true /* raw BTF */ }, + /* fall back to trying to find vmlinux ELF on disk otherwise */ + { "/boot/vmlinux-%1$s" }, + { "/lib/modules/%1$s/vmlinux-%1$s" }, + { "/lib/modules/%1$s/build/vmlinux" }, + { "/usr/lib/modules/%1$s/kernel/vmlinux" }, + { "/usr/lib/debug/boot/vmlinux-%1$s" }, + { "/usr/lib/debug/boot/vmlinux-%1$s.debug" }, + { "/usr/lib/debug/lib/modules/%1$s/vmlinux" }, }; char path[PATH_MAX + 1]; struct utsname buf; @@ -2825,14 +2871,18 @@ static struct btf *bpf_core_find_kernel_btf(void) uname(&buf); for (i = 0; i < ARRAY_SIZE(locations); i++) { - snprintf(path, PATH_MAX, locations[i], buf.release); + snprintf(path, PATH_MAX, locations[i].path_fmt, buf.release); if (access(path, R_OK)) continue; - btf = btf__parse_elf(path, NULL); - pr_debug("kernel BTF load from '%s': %ld\n", - path, PTR_ERR(btf)); + if (locations[i].raw_btf) + btf = btf_load_raw(path); + else + btf = btf__parse_elf(path, NULL); + + pr_debug("loading kernel BTF '%s': %ld\n", + path, IS_ERR(btf) ? PTR_ERR(btf) : 0); if (IS_ERR(btf)) continue; -- cgit v1.2.3-59-g8ed1b From f1409116835a8ae7cd924e2829772c470eb6cba4 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Fri, 9 Aug 2019 19:02:59 -0300 Subject: media: selftests: ir: fix ir_loopback test failure The decoder is called rc-mm, not rcmm. This was renamed late in the cycle so this bug crept in. Acked-by: Shuah Khan Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- tools/testing/selftests/ir/ir_loopback.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/ir/ir_loopback.c b/tools/testing/selftests/ir/ir_loopback.c index e700e09e3682..af7f9c7d59bc 100644 --- a/tools/testing/selftests/ir/ir_loopback.c +++ b/tools/testing/selftests/ir/ir_loopback.c @@ -54,9 +54,9 @@ static const struct { { RC_PROTO_RC6_MCE, "rc-6-mce", 0x00007fff, "rc-6" }, { RC_PROTO_SHARP, "sharp", 0x1fff, "sharp" }, { RC_PROTO_IMON, "imon", 0x7fffffff, "imon" }, - { RC_PROTO_RCMM12, "rcmm-12", 0x00000fff, "rcmm" }, - { RC_PROTO_RCMM24, "rcmm-24", 0x00ffffff, "rcmm" }, - { RC_PROTO_RCMM32, "rcmm-32", 0xffffffff, "rcmm" }, + { RC_PROTO_RCMM12, "rcmm-12", 0x00000fff, "rc-mm" }, + { RC_PROTO_RCMM24, "rcmm-24", 0x00ffffff, "rc-mm" }, + { RC_PROTO_RCMM32, "rcmm-32", 0xffffffff, "rc-mm" }, }; int lirc_open(const char *rc) -- cgit v1.2.3-59-g8ed1b From c22e150e3afa6f8db2300bd510e4ac26bbee1bf3 Mon Sep 17 00:00:00 2001 From: Igor Lubashev Date: Wed, 7 Aug 2019 10:44:14 -0400 Subject: perf tools: Add helpers to use capabilities if present Add utilities to help checking capabilities of the running procss. Make perf link with libcap, if it is available. If no libcap-dev[el], fallback to the geteuid() == 0 test used before. Committer notes: $ perf test python 18: 'import perf' in python : FAILED! $ perf test -v python Couldn't bump rlimit(MEMLOCK), failures may take place when creating BPF maps, etc 18: 'import perf' in python : --- start --- test child forked, pid 23288 Traceback (most recent call last): File "", line 1, in ImportError: /tmp/build/perf/python/perf.so: undefined symbol: cap_get_flag test child finished with -1 ---- end ---- 'import perf' in python: FAILED! $ This happens because differently from the perf binary generated with this patch applied: $ ldd /tmp/build/perf/perf | grep libcap libcap.so.2 => /lib64/libcap.so.2 (0x00007f724a4ef000) $ The python binding isn't linking with libcap: $ ldd /tmp/build/perf/python/perf.so | grep libcap $ So add 'cap' to the 'extra_libraries' variable in tools/perf/util/setup.py, and rebuild: $ perf test python 18: 'import perf' in python : Ok $ If we explicitely disable libcap it also continues to work: $ make NO_LIBCAP=1 -C tools/perf O=/tmp/build/perf install-bin $ ldd /tmp/build/perf/perf | grep libcap $ ldd /tmp/build/perf/python/perf.so | grep libcap $ perf test python 18: 'import perf' in python : Ok $ Signed-off-by: Igor Lubashev Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: James Morris Cc: Mathieu Poirier Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Suzuki Poulouse Cc: linux-arm-kernel@lists.infradead.org [ split from a larger patch ] Link: http://lkml.kernel.org/r/8a1e76cf5c7c9796d0d4d240fbaa85305298aafa.1565188228.git.ilubashe@akamai.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/Build | 2 ++ tools/perf/util/cap.c | 29 +++++++++++++++++++++++++++++ tools/perf/util/cap.h | 27 +++++++++++++++++++++++++++ tools/perf/util/event.h | 1 + tools/perf/util/python-ext-sources | 1 + tools/perf/util/setup.py | 2 ++ tools/perf/util/util.c | 9 +++++++++ 7 files changed, 71 insertions(+) create mode 100644 tools/perf/util/cap.c create mode 100644 tools/perf/util/cap.h (limited to 'tools') diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 7abf05131889..7cda749059a9 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -148,6 +148,8 @@ perf-$(CONFIG_ZLIB) += zlib.o perf-$(CONFIG_LZMA) += lzma.o perf-$(CONFIG_ZSTD) += zstd.o +perf-$(CONFIG_LIBCAP) += cap.o + perf-y += demangle-java.o perf-y += demangle-rust.o diff --git a/tools/perf/util/cap.c b/tools/perf/util/cap.c new file mode 100644 index 000000000000..c3ba841bbf37 --- /dev/null +++ b/tools/perf/util/cap.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Capability utilities + */ + +#ifdef HAVE_LIBCAP_SUPPORT + +#include "cap.h" +#include +#include + +bool perf_cap__capable(cap_value_t cap) +{ + cap_flag_value_t val; + cap_t caps = cap_get_proc(); + + if (!caps) + return false; + + if (cap_get_flag(caps, cap, CAP_EFFECTIVE, &val) != 0) + val = CAP_CLEAR; + + if (cap_free(caps) != 0) + return false; + + return val == CAP_SET; +} + +#endif /* HAVE_LIBCAP_SUPPORT */ diff --git a/tools/perf/util/cap.h b/tools/perf/util/cap.h new file mode 100644 index 000000000000..10af94e473da --- /dev/null +++ b/tools/perf/util/cap.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PERF_CAP_H +#define __PERF_CAP_H + +#include +#include +#include + +#ifdef HAVE_LIBCAP_SUPPORT + +#include + +bool perf_cap__capable(cap_value_t cap); + +#else + +#include +#include + +static inline bool perf_cap__capable(int cap __maybe_unused) +{ + return geteuid() == 0; +} + +#endif /* HAVE_LIBCAP_SUPPORT */ + +#endif /* __PERF_CAP_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 70841d115349..0e164e8ae28d 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -851,6 +851,7 @@ void cpu_map_data__synthesize(struct cpu_map_data *data, struct perf_cpu_map *m void event_attr_init(struct perf_event_attr *attr); int perf_event_paranoid(void); +bool perf_event_paranoid_check(int max_level); extern int sysctl_perf_event_max_stack; extern int sysctl_perf_event_max_contexts_per_stack; diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index 235bd9803390..c6dd478956f1 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources @@ -7,6 +7,7 @@ util/python.c ../lib/ctype.c +util/cap.c util/evlist.c util/evsel.c util/cpumap.c diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py index d48f9cd58964..aa344a163eaf 100644 --- a/tools/perf/util/setup.py +++ b/tools/perf/util/setup.py @@ -59,6 +59,8 @@ ext_sources = list(map(lambda x: '%s/%s' % (src_perf, x) , ext_sources)) extra_libraries = [] if '-DHAVE_LIBNUMA_SUPPORT' in cflags: extra_libraries = [ 'numa' ] +if '-DHAVE_LIBCAP_SUPPORT' in cflags: + extra_libraries += [ 'cap' ] perf = Extension('perf', sources = ext_sources, diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 9c3c97697387..6fd130a5d8f2 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -16,10 +16,12 @@ #include #include #include +#include #include #include #include #include +#include "cap.h" #include "strlist.h" #include "string2.h" @@ -403,6 +405,13 @@ int perf_event_paranoid(void) return value; } + +bool perf_event_paranoid_check(int max_level) +{ + return perf_cap__capable(CAP_SYS_ADMIN) || + perf_event_paranoid() <= max_level; +} + static int fetch_ubuntu_kernel_version(unsigned int *puint) { -- cgit v1.2.3-59-g8ed1b From 97993bd6eb89bf08649c01d4d57453feca4314f8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 12 Aug 2019 16:43:08 -0300 Subject: perf tools: Add NO_LIBCAP=1 to the minimal build test We need to add these so that we test building without all selectable features. Acked-by: Igor Lubashev Cc: Alexander Shishkin Cc: Alexey Budankov Cc: James Morris Cc: Jiri Olsa Cc: Mathieu Poirier Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Suzuki Poulouse Link: https://lkml.kernel.org/n/tip-eknnvp22elznj0cl5a39hc4v@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/make | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/tests/make b/tools/perf/tests/make index 5363a12a8b9b..70c48475896d 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make @@ -108,6 +108,7 @@ make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 make_minimal += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 make_minimal += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1 make_minimal += NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 NO_LIBZSTD=1 +make_minimal += NO_LIBCAP=1 # $(run) contains all available tests run := make_pure -- cgit v1.2.3-59-g8ed1b From 083c1359b0e03867a8c7effd21d4c0be3639f336 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 13 Aug 2019 11:38:19 -0300 Subject: perf tools: Add CAP_SYSLOG define for older systems Some of the systems I test don't have that define, provide it conditionally since we'll use it in the kptr_restrict checks in the next patch. Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Igor Lubashev Cc: James Morris Cc: Jiri Olsa Cc: Mathieu Poirier Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Suzuki Poulouse Link: https://lkml.kernel.org/n/tip-dcize2v6jjab7tds5ngz97dk@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cap.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools') diff --git a/tools/perf/util/cap.h b/tools/perf/util/cap.h index 10af94e473da..051dc590ceee 100644 --- a/tools/perf/util/cap.h +++ b/tools/perf/util/cap.h @@ -24,4 +24,9 @@ static inline bool perf_cap__capable(int cap __maybe_unused) #endif /* HAVE_LIBCAP_SUPPORT */ +/* For older systems */ +#ifndef CAP_SYSLOG +#define CAP_SYSLOG 34 +#endif + #endif /* __PERF_CAP_H */ -- cgit v1.2.3-59-g8ed1b From c766f3df635de14295e410c6dd5410bc416c24a0 Mon Sep 17 00:00:00 2001 From: Igor Lubashev Date: Wed, 7 Aug 2019 10:44:17 -0400 Subject: perf ftrace: Use CAP_SYS_ADMIN instead of euid==0 The kernel requires CAP_SYS_ADMIN instead of euid==0 to mount debugfs for ftrace. Make perf do the same. Signed-off-by: Igor Lubashev Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: James Morris Cc: Mathieu Poirier Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Suzuki Poulouse Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/bd8763b72ed4d58d0b42d44fbc7eb474d32e53a3.1565188228.git.ilubashe@akamai.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-ftrace.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 20d4c0ce8b53..01a5bb58eb04 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "debug.h" #include @@ -21,6 +22,7 @@ #include "target.h" #include "cpumap.h" #include "thread_map.h" +#include "util/cap.h" #include "util/config.h" @@ -281,7 +283,7 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv) .events = POLLIN, }; - if (geteuid() != 0) { + if (!perf_cap__capable(CAP_SYS_ADMIN)) { pr_err("ftrace only works for root!\n"); return -1; } -- cgit v1.2.3-59-g8ed1b From 73e5de70dca00344cb48e018131a4cadec0fabf0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 12 Aug 2019 17:27:11 -0300 Subject: perf ftrace: Improve error message about capability to use ftrace If we link against libcap, then we can state that CAP_SYS_ADMIN is needed, if not, fallback to telling the user it needs to be root, as was before linking against libcap. Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Igor Lubashev Cc: James Morris Cc: Jiri Olsa Cc: Mathieu Poirier Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Suzuki Poulouse Link: https://lkml.kernel.org/n/tip-hhnbjdo8r67054of9zm2kxtl@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-ftrace.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 01a5bb58eb04..1367bb5046a7 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -284,7 +284,13 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv) }; if (!perf_cap__capable(CAP_SYS_ADMIN)) { - pr_err("ftrace only works for root!\n"); + pr_err("ftrace only works for %s!\n", +#ifdef HAVE_LIBCAP_SUPPORT + "users with the SYS_ADMIN capability" +#else + "root" +#endif + ); return -1; } -- cgit v1.2.3-59-g8ed1b From ce7b0e426ef359ee1d4a6126314ee3547a8eed87 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Tue, 6 Aug 2019 17:41:01 +0300 Subject: perf record: Add an option to take an AUX snapshot on exit It is sometimes useful to generate a snapshot when perf record exits; I've been using a wrapper script around the workload that would do a killall -USR2 perf when the workload exits. This patch makes it easier and also works when perf record is attached to a pre-existing task. A new snapshot option 'e' can be specified in -S to enable this behavior: root@elsewhere:~# perf record -e intel_pt// -Se sleep 1 [ perf record: Woken up 2 times to write data ] [ perf record: Captured and wrote 0.085 MB perf.data ] Co-developed-by: Adrian Hunter Signed-off-by: Alexander Shishkin Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190806144101.62892-1-alexander.shishkin@linux.intel.com [ Fixed up !HAVE_AUXTRACE_SUPPORT build in builtin-record.c, adding 2 missing __maybe_unused ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-record.txt | 11 +++++++--- tools/perf/builtin-record.c | 35 ++++++++++++++++++++++++++++---- tools/perf/perf.h | 1 + tools/perf/util/auxtrace.c | 14 +++++++++++-- tools/perf/util/auxtrace.h | 2 +- 5 files changed, 53 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 15e0fa87241b..d5e58e0a2bca 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -422,9 +422,14 @@ CLOCK_BOOTTIME, CLOCK_REALTIME and CLOCK_TAI. -S:: --snapshot:: Select AUX area tracing Snapshot Mode. This option is valid only with an -AUX area tracing event. Optionally the number of bytes to capture per -snapshot can be specified. In Snapshot Mode, trace data is captured only when -signal SIGUSR2 is received. +AUX area tracing event. Optionally, certain snapshot capturing parameters +can be specified in a string that follows this option: + 'e': take one last snapshot on exit; guarantees that there is at least one + snapshot in the output file; + : if the PMU supports this, specify the desired snapshot size. + +In Snapshot Mode trace data is captured only when signal SIGUSR2 is received +and on exit if the above 'e' option is given. --proc-map-timeout:: When processing pre-existing threads /proc/XXX/mmap, it may take a long time, diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index d31d7a5a1be3..f71631f2bcb5 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -613,19 +613,35 @@ out: return rc; } -static void record__read_auxtrace_snapshot(struct record *rec) +static void record__read_auxtrace_snapshot(struct record *rec, bool on_exit) { pr_debug("Recording AUX area tracing snapshot\n"); if (record__auxtrace_read_snapshot_all(rec) < 0) { trigger_error(&auxtrace_snapshot_trigger); } else { - if (auxtrace_record__snapshot_finish(rec->itr)) + if (auxtrace_record__snapshot_finish(rec->itr, on_exit)) trigger_error(&auxtrace_snapshot_trigger); else trigger_ready(&auxtrace_snapshot_trigger); } } +static int record__auxtrace_snapshot_exit(struct record *rec) +{ + if (trigger_is_error(&auxtrace_snapshot_trigger)) + return 0; + + if (!auxtrace_record__snapshot_started && + auxtrace_record__snapshot_start(rec->itr)) + return -1; + + record__read_auxtrace_snapshot(rec, true); + if (trigger_is_error(&auxtrace_snapshot_trigger)) + return -1; + + return 0; +} + static int record__auxtrace_init(struct record *rec) { int err; @@ -654,7 +670,8 @@ int record__auxtrace_mmap_read(struct record *rec __maybe_unused, } static inline -void record__read_auxtrace_snapshot(struct record *rec __maybe_unused) +void record__read_auxtrace_snapshot(struct record *rec __maybe_unused, + bool on_exit __maybe_unused) { } @@ -664,6 +681,12 @@ int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused) return 0; } +static inline +int record__auxtrace_snapshot_exit(struct record *rec __maybe_unused) +{ + return 0; +} + static int record__auxtrace_init(struct record *rec __maybe_unused) { return 0; @@ -1536,7 +1559,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) if (auxtrace_record__snapshot_started) { auxtrace_record__snapshot_started = 0; if (!trigger_is_error(&auxtrace_snapshot_trigger)) - record__read_auxtrace_snapshot(rec); + record__read_auxtrace_snapshot(rec, false); if (trigger_is_error(&auxtrace_snapshot_trigger)) { pr_err("AUX area tracing snapshot failed\n"); err = -1; @@ -1609,9 +1632,13 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) disabled = true; } } + trigger_off(&auxtrace_snapshot_trigger); trigger_off(&switch_output_trigger); + if (opts->auxtrace_snapshot_on_exit) + record__auxtrace_snapshot_exit(rec); + if (forks && workload_exec_errno) { char msg[STRERR_BUFSIZE]; const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg)); diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 74d0124d38f3..dc0a7a237887 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -57,6 +57,7 @@ struct record_opts { bool running_time; bool full_auxtrace; bool auxtrace_snapshot_mode; + bool auxtrace_snapshot_on_exit; bool record_namespaces; bool record_switch_events; bool all_kernel; diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 65728cdeefb6..72ce4c5e7c78 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -539,9 +539,9 @@ int auxtrace_record__snapshot_start(struct auxtrace_record *itr) return 0; } -int auxtrace_record__snapshot_finish(struct auxtrace_record *itr) +int auxtrace_record__snapshot_finish(struct auxtrace_record *itr, bool on_exit) { - if (itr && itr->snapshot_finish) + if (!on_exit && itr && itr->snapshot_finish) return itr->snapshot_finish(itr); return 0; } @@ -577,6 +577,16 @@ int auxtrace_parse_snapshot_options(struct auxtrace_record *itr, if (!str) return 0; + /* PMU-agnostic options */ + switch (*str) { + case 'e': + opts->auxtrace_snapshot_on_exit = true; + str++; + break; + default: + break; + } + if (itr) return itr->parse_snapshot_options(itr, opts, str); diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index 17eb04a1da4d..8ccabacd0b11 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -499,7 +499,7 @@ int auxtrace_record__info_fill(struct auxtrace_record *itr, size_t priv_size); void auxtrace_record__free(struct auxtrace_record *itr); int auxtrace_record__snapshot_start(struct auxtrace_record *itr); -int auxtrace_record__snapshot_finish(struct auxtrace_record *itr); +int auxtrace_record__snapshot_finish(struct auxtrace_record *itr, bool on_exit); int auxtrace_record__find_snapshot(struct auxtrace_record *itr, int idx, struct auxtrace_mmap *mm, unsigned char *data, u64 *head, u64 *old); -- cgit v1.2.3-59-g8ed1b From 5a4b58e5d64ac7ebca175ffd8d74ca1b5cb0a01f Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 6 Aug 2019 11:46:02 +0300 Subject: perf tools: Add aux_output attribute flag Add aux_output attribute flag to match the kernel's perf_event.h file. Signed-off-by: Adrian Hunter Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190806084606.4021-4-alexander.shishkin@linux.intel.com Signed-off-by: Alexander Shishkin Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/linux/perf_event.h | 3 ++- tools/perf/util/evsel.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h index 7198ddd0c6b1..bb7b271397a6 100644 --- a/tools/include/uapi/linux/perf_event.h +++ b/tools/include/uapi/linux/perf_event.h @@ -374,7 +374,8 @@ struct perf_event_attr { namespaces : 1, /* include namespaces data */ ksymbol : 1, /* include ksymbol events */ bpf_event : 1, /* include bpf events */ - __reserved_1 : 33; + aux_output : 1, /* generate AUX records instead of events */ + __reserved_1 : 32; union { __u32 wakeup_events; /* wakeup every n events */ diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 64bc32ed6dfa..897a97af2d81 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1587,6 +1587,7 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr, PRINT_ATTRf(namespaces, p_unsigned); PRINT_ATTRf(ksymbol, p_unsigned); PRINT_ATTRf(bpf_event, p_unsigned); + PRINT_ATTRf(aux_output, p_unsigned); PRINT_ATTRn("{ wakeup_events, wakeup_watermark }", wakeup_events, p_unsigned); PRINT_ATTRf(bp_type, p_unsigned); -- cgit v1.2.3-59-g8ed1b From 181ebb5e23a5e480f6d6aa2816a9c4aaa65afa59 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 6 Aug 2019 11:46:03 +0300 Subject: perf tools: Add itrace option 'o' to synthesize aux-output events Add itrace option 'o' to synthesize events recorded in the AUX area due to the use of perf record's aux-output config term. Signed-off-by: Adrian Hunter Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190806084606.4021-5-alexander.shishkin@linux.intel.com Signed-off-by: Alexander Shishkin Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/itrace.txt | 2 ++ tools/perf/util/auxtrace.c | 4 ++++ tools/perf/util/auxtrace.h | 3 +++ 3 files changed, 9 insertions(+) (limited to 'tools') diff --git a/tools/perf/Documentation/itrace.txt b/tools/perf/Documentation/itrace.txt index c2182cbabde3..82ff7dad40c2 100644 --- a/tools/perf/Documentation/itrace.txt +++ b/tools/perf/Documentation/itrace.txt @@ -5,6 +5,8 @@ x synthesize transactions events w synthesize ptwrite events p synthesize power events + o synthesize other events recorded due to the use + of aux-output (refer to perf record) e synthesize error events d create a debug log g synthesize a call chain (use with i or x) diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 72ce4c5e7c78..60428576426e 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -974,6 +974,7 @@ void itrace_synth_opts__set_default(struct itrace_synth_opts *synth_opts, synth_opts->transactions = true; synth_opts->ptwrites = true; synth_opts->pwr_events = true; + synth_opts->other_events = true; synth_opts->errors = true; if (no_sample) { synth_opts->period_type = PERF_ITRACE_PERIOD_INSTRUCTIONS; @@ -1071,6 +1072,9 @@ int itrace_parse_synth_opts(const struct option *opt, const char *str, case 'p': synth_opts->pwr_events = true; break; + case 'o': + synth_opts->other_events = true; + break; case 'e': synth_opts->errors = true; break; diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index 8ccabacd0b11..8e637ac3918e 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -60,6 +60,8 @@ enum itrace_period_type { * @transactions: whether to synthesize events for transactions * @ptwrites: whether to synthesize events for ptwrites * @pwr_events: whether to synthesize power events + * @other_events: whether to synthesize other events recorded due to the use of + * aux_output * @errors: whether to synthesize decoder error events * @dont_decode: whether to skip decoding entirely * @log: write a decoding log @@ -86,6 +88,7 @@ struct itrace_synth_opts { bool transactions; bool ptwrites; bool pwr_events; + bool other_events; bool errors; bool dont_decode; bool log; -- cgit v1.2.3-59-g8ed1b From 9e64cefe4335b0f2799956d3f3cca8bb652d950f Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 6 Aug 2019 11:46:04 +0300 Subject: perf intel-pt: Process options for PEBS event synthesis Process synth_opts.other_events and attr.aux_output to set up for synthesizing PEBs via Intel PT events. Signed-off-by: Adrian Hunter Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190806084606.4021-6-alexander.shishkin@linux.intel.com Signed-off-by: Alexander Shishkin [ Fixed up libbperf clashes, i.e. some places using perf_evsel (now in libperf) need to use instead 'evsel' (a tools/perf only abstraction) ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/util/intel-pt.c | 23 +++++++++++++++++++++++ tools/perf/util/intel-pt.c | 18 ++++++++++++++++++ 2 files changed, 41 insertions(+) (limited to 'tools') diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 218a4e694618..a8e633aa278a 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -548,6 +548,26 @@ static int intel_pt_validate_config(struct perf_pmu *intel_pt_pmu, evsel->core.attr.config); } +/* + * Currently, there is not enough information to disambiguate different PEBS + * events, so only allow one. + */ +static bool intel_pt_too_many_aux_output(struct evlist *evlist) +{ + struct evsel *evsel; + int aux_output_cnt = 0; + + evlist__for_each_entry(evlist, evsel) + aux_output_cnt += !!evsel->core.attr.aux_output; + + if (aux_output_cnt > 1) { + pr_err(INTEL_PT_PMU_NAME " supports at most one event with aux-output\n"); + return true; + } + + return false; +} + static int intel_pt_recording_options(struct auxtrace_record *itr, struct evlist *evlist, struct record_opts *opts) @@ -588,6 +608,9 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, return -EINVAL; } + if (intel_pt_too_many_aux_output(evlist)) + return -EINVAL; + if (!opts->full_auxtrace) return 0; diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 4c52204868d8..ea504fa9b623 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -2894,6 +2894,22 @@ static int intel_pt_synth_events(struct intel_pt *pt, return 0; } +static void intel_pt_setup_pebs_events(struct intel_pt *pt) +{ + struct evsel *evsel; + + if (!pt->synth_opts.other_events) + return; + + evlist__for_each_entry(pt->session->evlist, evsel) { + if (evsel->core.attr.aux_output && evsel->id) { + pt->sample_pebs = true; + pt->pebs_evsel = evsel; + return; + } + } +} + static struct evsel *intel_pt_find_sched_switch(struct evlist *evlist) { struct evsel *evsel; @@ -3263,6 +3279,8 @@ int intel_pt_process_auxtrace_info(union perf_event *event, if (err) goto err_delete_thread; + intel_pt_setup_pebs_events(pt); + err = auxtrace_queues__process_index(&pt->queues, session); if (err) goto err_delete_thread; -- cgit v1.2.3-59-g8ed1b From 1b9921546a9641aefc4a52c1c635b96b67142993 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 6 Aug 2019 11:46:05 +0300 Subject: perf tools: Add aux-output config term Expose the aux_output attribute flag to the user to configure, by adding a config term 'aux-output'. For events that support it, selection of 'aux-output' causes the generation of AUX records instead of event records. This requires that an AUX area event is also provided. Signed-off-by: Adrian Hunter Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190806084606.4021-7-alexander.shishkin@linux.intel.com Signed-off-by: Alexander Shishkin Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-record.txt | 2 ++ tools/perf/util/evsel.c | 3 +++ tools/perf/util/evsel.h | 2 ++ tools/perf/util/parse-events.c | 8 ++++++++ tools/perf/util/parse-events.h | 1 + tools/perf/util/parse-events.l | 1 + 6 files changed, 17 insertions(+) (limited to 'tools') diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index d5e58e0a2bca..c6f9f31b6039 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -60,6 +60,8 @@ OPTIONS - 'name' : User defined event name. Single quotes (') may be used to escape symbols in the name from parsing by shell and tool like this: name=\'CPU_CLK_UNHALTED.THREAD:cmask=0x1\'. + - 'aux-output': Generate AUX records instead of events. This requires + that an AUX area event is also provided. See the linkperf:perf-list[1] man page for more parameters. diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 897a97af2d81..5da40511546b 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -833,6 +833,9 @@ static void apply_config_terms(struct evsel *evsel, break; case PERF_EVSEL__CONFIG_TERM_PERCORE: break; + case PERF_EVSEL__CONFIG_TERM_AUX_OUTPUT: + attr->aux_output = term->val.aux_output ? 1 : 0; + break; default: break; } diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 3cf35aa782b9..8a316dd54cd0 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -52,6 +52,7 @@ enum term_type { PERF_EVSEL__CONFIG_TERM_DRV_CFG, PERF_EVSEL__CONFIG_TERM_BRANCH, PERF_EVSEL__CONFIG_TERM_PERCORE, + PERF_EVSEL__CONFIG_TERM_AUX_OUTPUT, }; struct perf_evsel_config_term { @@ -70,6 +71,7 @@ struct perf_evsel_config_term { char *branch; unsigned long max_events; bool percore; + bool aux_output; } val; bool weak; }; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 2cfec3b7a982..9101568946d2 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -963,6 +963,7 @@ static const char *config_term_names[__PARSE_EVENTS__TERM_TYPE_NR] = { [PARSE_EVENTS__TERM_TYPE_NOOVERWRITE] = "no-overwrite", [PARSE_EVENTS__TERM_TYPE_DRV_CFG] = "driver-config", [PARSE_EVENTS__TERM_TYPE_PERCORE] = "percore", + [PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT] = "aux-output", }; static bool config_term_shrinked; @@ -1083,6 +1084,9 @@ do { \ return -EINVAL; } break; + case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT: + CHECK_TYPE_VAL(NUM); + break; default: err->str = strdup("unknown term"); err->idx = term->err_term; @@ -1133,6 +1137,7 @@ static int config_term_tracepoint(struct perf_event_attr *attr, case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS: case PARSE_EVENTS__TERM_TYPE_OVERWRITE: case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE: + case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT: return config_term_common(attr, term, err); default: if (err) { @@ -1225,6 +1230,9 @@ do { \ ADD_CONFIG_TERM(PERCORE, percore, term->val.num ? true : false); break; + case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT: + ADD_CONFIG_TERM(AUX_OUTPUT, aux_output, term->val.num ? 1 : 0); + break; default: break; } diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 48111b8fc232..616ca1eda0eb 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -76,6 +76,7 @@ enum { PARSE_EVENTS__TERM_TYPE_OVERWRITE, PARSE_EVENTS__TERM_TYPE_DRV_CFG, PARSE_EVENTS__TERM_TYPE_PERCORE, + PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT, __PARSE_EVENTS__TERM_TYPE_NR, }; diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index ca6098874fe2..7469497cd28e 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l @@ -284,6 +284,7 @@ no-inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOINHERIT); } overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_OVERWRITE); } no-overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOOVERWRITE); } percore { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_PERCORE); } +aux-output { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT); } , { return ','; } "/" { BEGIN(INITIAL); return '/'; } {name_minus} { return str(yyscanner, PE_NAME); } -- cgit v1.2.3-59-g8ed1b From 243384dd25c8ea721c5c82a229eaf33cbd1bfd52 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 6 Aug 2019 11:46:06 +0300 Subject: perf intel-pt: Add brief documentation for PEBS via Intel PT Document how to select PEBS via Intel PT and how to display synthesized PEBS samples. Signed-off-by: Adrian Hunter Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190806084606.4021-8-alexander.shishkin@linux.intel.com Signed-off-by: Alexander Shishkin [ Update the example to use a group with intel_pt// as the group leader, as per Alex comment ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/intel-pt.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'tools') diff --git a/tools/perf/Documentation/intel-pt.txt b/tools/perf/Documentation/intel-pt.txt index 50c5b60101bd..e0d9e7dd4f17 100644 --- a/tools/perf/Documentation/intel-pt.txt +++ b/tools/perf/Documentation/intel-pt.txt @@ -919,3 +919,18 @@ amended to take the number of elements as a parameter. Note there is currently no advantage to using Intel PT instead of LBR, but that may change in the future if greater use is made of the data. + + +PEBS via Intel PT +================= + +Some hardware has the feature to redirect PEBS records to the Intel PT trace. +Recording is selected by using the aux-output config term e.g. + + perf record -c 10000 -e '{intel_pt/branch=0/,cycles/aux-output/ppp}' uname + +Note that currently, software only supports redirecting at most one PEBS event. + +To display PEBS events from the Intel PT trace, use the itrace 'o' option e.g. + + perf script --itrace=oe -- cgit v1.2.3-59-g8ed1b From acb9f2d4755a70e31343f99791aa43b05401b996 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 13 Aug 2019 11:06:38 -0300 Subject: perf evsel: Provide meaningful warning when trying to use 'aux_output' on older kernels Just like we do with the 'write_backwards' feature: Before: # perf record -e {intel_pt/branch=0/,cycles/aux-output/ppp} uname Error: The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (cycles/aux-output/ppp). /bin/dmesg | grep -i perf may provide additional information. # After: # perf record -e {intel_pt/branch=0/,cycles/aux-output/ppp} uname Error: The 'aux_output' feature is not supported, update the kernel. # Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lkml.kernel.org/n/tip-wgjsjroe1e150c0metgwmqwd@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 11 +++++++++-- tools/perf/util/evsel.h | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 5da40511546b..0a33f7322ecc 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1738,7 +1738,8 @@ int evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus, int pid = -1, err; enum { NO_CHANGE, SET_TO_MAX, INCREASED_MAX } set_rlimit = NO_CHANGE; - if (perf_missing_features.write_backward && evsel->core.attr.write_backward) + if ((perf_missing_features.write_backward && evsel->core.attr.write_backward) || + (perf_missing_features.aux_output && evsel->core.attr.aux_output)) return -EINVAL; if (cpus == NULL) { @@ -1912,7 +1913,11 @@ try_fallback: * Must probe features in the order they were added to the * perf_event_attr interface. */ - if (!perf_missing_features.bpf_event && evsel->core.attr.bpf_event) { + if (!perf_missing_features.aux_output && evsel->core.attr.aux_output) { + perf_missing_features.aux_output = true; + pr_debug2("Kernel has no attr.aux_output support, bailing out\n"); + goto out_close; + } else if (!perf_missing_features.bpf_event && evsel->core.attr.bpf_event) { perf_missing_features.bpf_event = true; pr_debug2("switching off bpf_event\n"); goto fallback_missing_features; @@ -2926,6 +2931,8 @@ int perf_evsel__open_strerror(struct evsel *evsel, struct target *target, return scnprintf(msg, size, "clockid feature not supported."); if (perf_missing_features.clockid_wrong) return scnprintf(msg, size, "wrong clockid (%d).", clockid); + if (perf_missing_features.aux_output) + return scnprintf(msg, size, "The 'aux_output' feature is not supported, update the kernel."); break; default: break; diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 8a316dd54cd0..9cd6e3ae479a 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -184,6 +184,7 @@ struct perf_missing_features { bool group_read; bool ksymbol; bool bpf_event; + bool aux_output; }; extern struct perf_missing_features perf_missing_features; -- cgit v1.2.3-59-g8ed1b From 38fe26b46f55538c2cb8b96500caed6ae9d59d46 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 28 Jun 2019 20:22:09 +0300 Subject: tools: Keep list of tools in alphabetical order When `make help` is executed it lists the possible tools to build, though couple of entries is kept unordered. Fix it here. Signed-off-by: Andy Shevchenko Acked-by: Song Liu Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Martin KaFai Lau Cc: Yonghong Song Link: https://lkml.kernel.org/n/tip-0ke3p64ksa0hnbueh52n3v3q@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/Makefile b/tools/Makefile index 68defd7ecf5d..7e42f7b8bfa7 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -10,6 +10,7 @@ help: @echo 'Possible targets:' @echo '' @echo ' acpi - ACPI tools' + @echo ' bpf - misc BPF tools' @echo ' cgroup - cgroup tools' @echo ' cpupower - a tool for all things x86 CPU power' @echo ' debugging - tools for debugging' @@ -23,12 +24,11 @@ help: @echo ' kvm_stat - top-like utility for displaying kvm statistics' @echo ' leds - LEDs tools' @echo ' liblockdep - user-space wrapper for kernel locking-validator' - @echo ' bpf - misc BPF tools' + @echo ' objtool - an ELF object analysis tool' @echo ' pci - PCI tools' @echo ' perf - Linux performance measurement and analysis tool' @echo ' selftests - various kernel selftests' @echo ' spi - spi tools' - @echo ' objtool - an ELF object analysis tool' @echo ' tmon - thermal monitoring and tuning tool' @echo ' turbostat - Intel CPU idle stats and freq reporting tool' @echo ' usb - USB testing tools' -- cgit v1.2.3-59-g8ed1b From 3143906c2770778d89b730e0342b745d1b4a8303 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Thu, 1 Aug 2019 14:30:43 -0400 Subject: perf.data documentation: Clarify HEADER_SAMPLE_TOPOLOGY format The perf.data file format documentation for HEADER_SAMPLE_TOPOLOGY specifies the layout in a confusing manner that doesn't match the rest of the document. This patch attempts to describe things consistent with the rest of the file. Signed-off-by: Vince Weaver Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Andi Kleen Cc: Chong Jiang Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Simon Que Link: http://lkml.kernel.org/r/alpine.DEB.2.21.1908011425240.14303@macbook-air Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf.data-file-format.txt | 25 +++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/perf/Documentation/perf.data-file-format.txt b/tools/perf/Documentation/perf.data-file-format.txt index d030c87ed9f5..b0152e1095c5 100644 --- a/tools/perf/Documentation/perf.data-file-format.txt +++ b/tools/perf/Documentation/perf.data-file-format.txt @@ -298,16 +298,21 @@ Physical memory map and its node assignments. The format of data in MEM_TOPOLOGY is as follows: - 0 - version | for future changes - 8 - block_size_bytes | /sys/devices/system/memory/block_size_bytes - 16 - count | number of nodes - -For each node we store map of physical indexes: - - 32 - node id | node index - 40 - size | size of bitmap - 48 - bitmap | bitmap of memory indexes that belongs to node - | /sys/devices/system/node/node/memory + u64 version; // Currently 1 + u64 block_size_bytes; // /sys/devices/system/memory/block_size_bytes + u64 count; // number of nodes + +struct memory_node { + u64 node_id; // node index + u64 size; // size of bitmap + struct bitmap { + /* size of bitmap again */ + u64 bitmapsize; + /* bitmap of memory indexes that belongs to node */ + /* /sys/devices/system/node/node/memory */ + u64 entries[(bitmapsize/64)+1]; + } +}[count]; The MEM_TOPOLOGY can be displayed with following command: -- cgit v1.2.3-59-g8ed1b From 0a4d8fb229dd78f9e0752817339e19e903b37a60 Mon Sep 17 00:00:00 2001 From: Tan Xiaojun Date: Fri, 2 Aug 2019 11:48:57 +0800 Subject: perf record: Support aarch64 random socket_id assignment Same as in the commit 01766229533f ("perf record: Support s390 random socket_id assignment"), aarch64 also have this problem. Without this fix: [root@localhost perf]# ./perf report --header -I -v ... socket_id number is too big.You may need to upgrade the perf tool. # ======== # captured on : Thu Aug 1 22:58:38 2019 # header version : 1 ... # Core ID and Socket ID information is not available ... With this fix: [root@localhost perf]# ./perf report --header -I -v ... cpumask list: 0-31 cpumask list: 32-63 cpumask list: 64-95 cpumask list: 96-127 # ======== # captured on : Thu Aug 1 22:58:38 2019 # header version : 1 ... # CPU 0: Core ID 0, Socket ID 36 # CPU 1: Core ID 1, Socket ID 36 ... # CPU 126: Core ID 126, Socket ID 8442 # CPU 127: Core ID 127, Socket ID 8442 ... Signed-off-by: Tan Xiaojun Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Kan Liang Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Song Liu Cc: Steven Rostedt (VMware) Cc: Tzvetomir Stoyanov (VMware) Link: http://lkml.kernel.org/r/1564717737-21602-1-git-send-email-tanxiaojun@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/header.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index b04c2b6b28b3..1f2965a07bef 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -2252,8 +2252,10 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused) /* On s390 the socket_id number is not related to the numbers of cpus. * The socket_id number might be higher than the numbers of cpus. * This depends on the configuration. + * AArch64 is the same. */ - if (ph->env.arch && !strncmp(ph->env.arch, "s390", 4)) + if (ph->env.arch && (!strncmp(ph->env.arch, "s390", 4) + || !strncmp(ph->env.arch, "aarch64", 7))) do_core_id_test = false; for (i = 0; i < (u32)cpu_nr; i++) { -- cgit v1.2.3-59-g8ed1b From 1cd8fa288eb83c1fe0dfa492b09d228a8d802fbf Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 13 Aug 2019 12:07:14 -0300 Subject: perf ui: No need to set ui_browser to 1 twice We need to do it only when fallbacking from GTK to the TUI. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-dda0acxqef1k72n9z4myjbjt@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c index 44fe824e96cd..3bc7c9a6fae9 100644 --- a/tools/perf/ui/setup.c +++ b/tools/perf/ui/setup.c @@ -89,9 +89,9 @@ void setup_browser(bool fallback_to_pager) printf("GTK browser requested but could not find %s\n", PERF_GTK_DSO); sleep(1); + use_browser = 1; /* fall through */ case 1: - use_browser = 1; if (ui__init() == 0) break; /* fall through */ -- cgit v1.2.3-59-g8ed1b From 27df5c7068bf23cab282dc64b1c9894429b3b8a0 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Wed, 14 Aug 2019 12:41:09 +0200 Subject: selftests/bpf: fix "bind{4, 6} deny specific IP & port" on s390 "bind4 allow specific IP & port" and "bind6 deny specific IP & port" fail on s390 because of endianness issue: the 4 IP address bytes are loaded as a word and compared with a constant, but the value of this constant should be different on big- and little- endian machines, which is not the case right now. Use __bpf_constant_ntohl to generate proper value based on machine endianness. Fixes: 1d436885b23b ("selftests/bpf: Selftest for sys_bind post-hooks.") Signed-off-by: Ilya Leoshkevich Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/test_sock.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_sock.c b/tools/testing/selftests/bpf/test_sock.c index fb679ac3d4b0..0e6652733462 100644 --- a/tools/testing/selftests/bpf/test_sock.c +++ b/tools/testing/selftests/bpf/test_sock.c @@ -13,6 +13,7 @@ #include #include "cgroup_helpers.h" +#include "bpf_endian.h" #include "bpf_rlimit.h" #include "bpf_util.h" @@ -232,7 +233,8 @@ static struct sock_test tests[] = { /* if (ip == expected && port == expected) */ BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6, offsetof(struct bpf_sock, src_ip6[3])), - BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0x01000000, 4), + BPF_JMP_IMM(BPF_JNE, BPF_REG_7, + __bpf_constant_ntohl(0x00000001), 4), BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6, offsetof(struct bpf_sock, src_port)), BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0x2001, 2), @@ -261,7 +263,8 @@ static struct sock_test tests[] = { /* if (ip == expected && port == expected) */ BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6, offsetof(struct bpf_sock, src_ip4)), - BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0x0100007F, 4), + BPF_JMP_IMM(BPF_JNE, BPF_REG_7, + __bpf_constant_ntohl(0x7F000001), 4), BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6, offsetof(struct bpf_sock, src_port)), BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0x1002, 2), -- cgit v1.2.3-59-g8ed1b From a9436dca115d121d98e0b30f078f3294ce13fa18 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Wed, 14 Aug 2019 12:37:24 +0100 Subject: tools: bpftool: compile with $(EXTRA_WARNINGS) Compile bpftool with $(EXTRA_WARNINGS), as defined in scripts/Makefile.include, and fix the new warnings produced. Simply leave -Wswitch-enum out of the warning list, as we have several switch-case structures where it is not desirable to process all values of an enum. Remove -Wshadow from the warnings we manually add to CFLAGS, as it is handled in $(EXTRA_WARNINGS). Signed-off-by: Quentin Monnet Reviewed-by: Jakub Kicinski Signed-off-by: Daniel Borkmann --- tools/bpf/bpftool/Makefile | 3 ++- tools/bpf/bpftool/cgroup.c | 2 +- tools/bpf/bpftool/perf.c | 4 ++++ 3 files changed, 7 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile index 4c9d1ffc3fc7..f284c207765a 100644 --- a/tools/bpf/bpftool/Makefile +++ b/tools/bpf/bpftool/Makefile @@ -37,7 +37,8 @@ prefix ?= /usr/local bash_compdir ?= /usr/share/bash-completion/completions CFLAGS += -O2 -CFLAGS += -W -Wall -Wextra -Wno-unused-parameter -Wshadow -Wno-missing-field-initializers +CFLAGS += -W -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers +CFLAGS += $(filter-out -Wswitch-enum,$(EXTRA_WARNINGS)) CFLAGS += -DPACKAGE='"bpftool"' -D__EXPORTED_HEADERS__ \ -I$(srctree)/kernel/bpf/ \ -I$(srctree)/tools/include \ diff --git a/tools/bpf/bpftool/cgroup.c b/tools/bpf/bpftool/cgroup.c index 44352b5aca85..1ef45e55039e 100644 --- a/tools/bpf/bpftool/cgroup.c +++ b/tools/bpf/bpftool/cgroup.c @@ -120,8 +120,8 @@ static int count_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type) static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type, int level) { + const char *attach_flags_str; __u32 prog_ids[1024] = {0}; - char *attach_flags_str; __u32 prog_cnt, iter; __u32 attach_flags; char buf[32]; diff --git a/tools/bpf/bpftool/perf.c b/tools/bpf/bpftool/perf.c index f2a545e667c4..b2046f33e23f 100644 --- a/tools/bpf/bpftool/perf.c +++ b/tools/bpf/bpftool/perf.c @@ -104,6 +104,8 @@ static void print_perf_json(int pid, int fd, __u32 prog_id, __u32 fd_type, jsonw_string_field(json_wtr, "filename", buf); jsonw_lluint_field(json_wtr, "offset", probe_offset); break; + default: + break; } jsonw_end_object(json_wtr); } @@ -140,6 +142,8 @@ static void print_perf_plain(int pid, int fd, __u32 prog_id, __u32 fd_type, printf("uretprobe filename %s offset %llu\n", buf, probe_offset); break; + default: + break; } } -- cgit v1.2.3-59-g8ed1b From 5518ba4ebd7d1e15fc558af05fa600198535f074 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 7 Aug 2019 14:31:11 -0700 Subject: tools/testing/nvdimm: Fix fallthrough warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the expected 'fall through' designation to fix: tools/testing/nvdimm/test/nfit.c: In function ‘nd_intel_test_finish_query’: tools/testing/nvdimm/test/nfit.c:433:13: warning: this statement may fall through [-Wimplicit-fallthrough=] fw->state = FW_STATE_UPDATED; ~~~~~~~~~~^~~~~~~~~~~~~~~~~~ tools/testing/nvdimm/test/nfit.c:435:2: note: here case FW_STATE_UPDATED: ^~~~ Reviewed-by: Vishal Verma Link: https://lore.kernel.org/r/156521347159.1442374.1381360879102718899.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams --- tools/testing/nvdimm/test/nfit.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c index 507e6f4cbb53..bf6422a6af7f 100644 --- a/tools/testing/nvdimm/test/nfit.c +++ b/tools/testing/nvdimm/test/nfit.c @@ -428,10 +428,9 @@ static int nd_intel_test_finish_query(struct nfit_test *t, dev_dbg(dev, "%s: still verifying\n", __func__); break; } - dev_dbg(dev, "%s: transition out verify\n", __func__); fw->state = FW_STATE_UPDATED; - /* we are going to fall through if it's "done" */ + /* fall through */ case FW_STATE_UPDATED: nd_cmd->status = 0; /* bogus test version */ -- cgit v1.2.3-59-g8ed1b From 92cd0f0be3d7adb63611c28693ec0399beded837 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 14 Aug 2019 18:18:55 +0200 Subject: selftests: kvm: do not try running the VM in vmx_set_nested_state_test This test is only covering various edge cases of the KVM_SET_NESTED_STATE ioctl. Running the VM does not really add anything. Signed-off-by: Paolo Bonzini --- .../selftests/kvm/x86_64/vmx_set_nested_state_test.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c index ed7218d166da..a99fc66dafeb 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c @@ -27,22 +27,13 @@ void test_nested_state(struct kvm_vm *vm, struct kvm_nested_state *state) { - volatile struct kvm_run *run; - vcpu_nested_state_set(vm, VCPU_ID, state, false); - run = vcpu_state(vm, VCPU_ID); - vcpu_run(vm, VCPU_ID); - TEST_ASSERT(run->exit_reason == KVM_EXIT_SHUTDOWN, - "Got exit_reason other than KVM_EXIT_SHUTDOWN: %u (%s),\n", - run->exit_reason, - exit_reason_str(run->exit_reason)); } void test_nested_state_expect_errno(struct kvm_vm *vm, struct kvm_nested_state *state, int expected_errno) { - volatile struct kvm_run *run; int rv; rv = vcpu_nested_state_set(vm, VCPU_ID, state, true); @@ -50,12 +41,6 @@ void test_nested_state_expect_errno(struct kvm_vm *vm, "Expected %s (%d) from vcpu_nested_state_set but got rv: %i errno: %s (%d)", strerror(expected_errno), expected_errno, rv, strerror(errno), errno); - run = vcpu_state(vm, VCPU_ID); - vcpu_run(vm, VCPU_ID); - TEST_ASSERT(run->exit_reason == KVM_EXIT_SHUTDOWN, - "Got exit_reason other than KVM_EXIT_SHUTDOWN: %u (%s),\n", - run->exit_reason, - exit_reason_str(run->exit_reason)); } void test_nested_state_expect_einval(struct kvm_vm *vm, -- cgit v1.2.3-59-g8ed1b From 65efa61dc0d536d5f0602c33ee805a57cc07e9dc Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 14 Aug 2019 12:02:41 -0400 Subject: selftests: kvm: provide common function to enable eVMCS There are two tests already enabling eVMCS and a third is coming. Add a function that enables the capability and tests the result. Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/include/evmcs.h | 2 ++ tools/testing/selftests/kvm/lib/x86_64/vmx.c | 20 ++++++++++++++++++++ tools/testing/selftests/kvm/x86_64/evmcs_test.c | 15 ++------------- tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c | 12 ++++-------- 4 files changed, 28 insertions(+), 21 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/include/evmcs.h b/tools/testing/selftests/kvm/include/evmcs.h index 4059014d93ea..4912d23844bc 100644 --- a/tools/testing/selftests/kvm/include/evmcs.h +++ b/tools/testing/selftests/kvm/include/evmcs.h @@ -220,6 +220,8 @@ struct hv_enlightened_vmcs { struct hv_enlightened_vmcs *current_evmcs; struct hv_vp_assist_page *current_vp_assist; +int vcpu_enable_evmcs(struct kvm_vm *vm, int vcpu_id); + static inline int enable_vp_assist(uint64_t vp_assist_pa, void *vp_assist) { u64 val = (vp_assist_pa & HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_MASK) | diff --git a/tools/testing/selftests/kvm/lib/x86_64/vmx.c b/tools/testing/selftests/kvm/lib/x86_64/vmx.c index 204f847bd065..9cef0455b819 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/vmx.c +++ b/tools/testing/selftests/kvm/lib/x86_64/vmx.c @@ -12,6 +12,26 @@ bool enable_evmcs; +int vcpu_enable_evmcs(struct kvm_vm *vm, int vcpu_id) +{ + uint16_t evmcs_ver; + + struct kvm_enable_cap enable_evmcs_cap = { + .cap = KVM_CAP_HYPERV_ENLIGHTENED_VMCS, + .args[0] = (unsigned long)&evmcs_ver + }; + + vcpu_ioctl(vm, vcpu_id, KVM_ENABLE_CAP, &enable_evmcs_cap); + + /* KVM should return supported EVMCS version range */ + TEST_ASSERT(((evmcs_ver >> 8) >= (evmcs_ver & 0xff)) && + (evmcs_ver & 0xff) > 0, + "Incorrect EVMCS version range: %x:%x\n", + evmcs_ver & 0xff, evmcs_ver >> 8); + + return evmcs_ver; +} + /* Allocate memory regions for nested VMX tests. * * Input Args: diff --git a/tools/testing/selftests/kvm/x86_64/evmcs_test.c b/tools/testing/selftests/kvm/x86_64/evmcs_test.c index f95c08343b48..92915e6408e7 100644 --- a/tools/testing/selftests/kvm/x86_64/evmcs_test.c +++ b/tools/testing/selftests/kvm/x86_64/evmcs_test.c @@ -79,11 +79,6 @@ int main(int argc, char *argv[]) struct kvm_x86_state *state; struct ucall uc; int stage; - uint16_t evmcs_ver; - struct kvm_enable_cap enable_evmcs_cap = { - .cap = KVM_CAP_HYPERV_ENLIGHTENED_VMCS, - .args[0] = (unsigned long)&evmcs_ver - }; /* Create VM */ vm = vm_create_default(VCPU_ID, 0, guest_code); @@ -96,13 +91,7 @@ int main(int argc, char *argv[]) exit(KSFT_SKIP); } - vcpu_ioctl(vm, VCPU_ID, KVM_ENABLE_CAP, &enable_evmcs_cap); - - /* KVM should return supported EVMCS version range */ - TEST_ASSERT(((evmcs_ver >> 8) >= (evmcs_ver & 0xff)) && - (evmcs_ver & 0xff) > 0, - "Incorrect EVMCS version range: %x:%x\n", - evmcs_ver & 0xff, evmcs_ver >> 8); + vcpu_enable_evmcs(vm, VCPU_ID); run = vcpu_state(vm, VCPU_ID); @@ -146,7 +135,7 @@ int main(int argc, char *argv[]) kvm_vm_restart(vm, O_RDWR); vm_vcpu_add(vm, VCPU_ID); vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid()); - vcpu_ioctl(vm, VCPU_ID, KVM_ENABLE_CAP, &enable_evmcs_cap); + vcpu_enable_evmcs(vm, VCPU_ID); vcpu_load_state(vm, VCPU_ID, state); run = vcpu_state(vm, VCPU_ID); free(state); diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c b/tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c index f72b3043db0e..ee59831fbc98 100644 --- a/tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c +++ b/tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c @@ -18,6 +18,7 @@ #include "test_util.h" #include "kvm_util.h" #include "processor.h" +#include "vmx.h" #define VCPU_ID 0 @@ -106,12 +107,7 @@ int main(int argc, char *argv[]) { struct kvm_vm *vm; int rv; - uint16_t evmcs_ver; struct kvm_cpuid2 *hv_cpuid_entries; - struct kvm_enable_cap enable_evmcs_cap = { - .cap = KVM_CAP_HYPERV_ENLIGHTENED_VMCS, - .args[0] = (unsigned long)&evmcs_ver - }; /* Tell stdout not to buffer its content */ setbuf(stdout, NULL); @@ -136,14 +132,14 @@ int main(int argc, char *argv[]) free(hv_cpuid_entries); - rv = _vcpu_ioctl(vm, VCPU_ID, KVM_ENABLE_CAP, &enable_evmcs_cap); - - if (rv) { + if (!kvm_check_cap(KVM_CAP_HYPERV_ENLIGHTENED_VMCS)) { fprintf(stderr, "Enlightened VMCS is unsupported, skip related test\n"); goto vm_free; } + vcpu_enable_evmcs(vm, VCPU_ID); + hv_cpuid_entries = kvm_get_supported_hv_cpuid(vm); if (!hv_cpuid_entries) return 1; -- cgit v1.2.3-59-g8ed1b From c930e19790bbbff31c018009907c813fa0925f63 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 14 Aug 2019 12:07:34 -0400 Subject: selftests: kvm: fix vmx_set_nested_state_test vmx_set_nested_state_test is trying to use the KVM_STATE_NESTED_EVMCS without enabling enlightened VMCS first. Correct the outcome of the test, and actually test that it succeeds after the capability is enabled. Signed-off-by: Paolo Bonzini --- .../selftests/kvm/x86_64/vmx_set_nested_state_test.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c index a99fc66dafeb..853e370e8a39 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c @@ -25,6 +25,8 @@ #define VMCS12_REVISION 0x11e57ed0 #define VCPU_ID 5 +bool have_evmcs; + void test_nested_state(struct kvm_vm *vm, struct kvm_nested_state *state) { vcpu_nested_state_set(vm, VCPU_ID, state, false); @@ -75,8 +77,9 @@ void set_default_vmx_state(struct kvm_nested_state *state, int size) { memset(state, 0, size); state->flags = KVM_STATE_NESTED_GUEST_MODE | - KVM_STATE_NESTED_RUN_PENDING | - KVM_STATE_NESTED_EVMCS; + KVM_STATE_NESTED_RUN_PENDING; + if (have_evmcs) + state->flags |= KVM_STATE_NESTED_EVMCS; state->format = 0; state->size = size; state->hdr.vmx.vmxon_pa = 0x1000; @@ -126,13 +129,19 @@ void test_vmx_nested_state(struct kvm_vm *vm) /* * Setting vmxon_pa == -1ull and vmcs_pa == -1ull exits early without * setting the nested state but flags other than eVMCS must be clear. + * The eVMCS flag can be set if the enlightened VMCS capability has + * been enabled. */ set_default_vmx_state(state, state_sz); state->hdr.vmx.vmxon_pa = -1ull; state->hdr.vmx.vmcs12_pa = -1ull; test_nested_state_expect_einval(vm, state); - state->flags = KVM_STATE_NESTED_EVMCS; + state->flags &= KVM_STATE_NESTED_EVMCS; + if (have_evmcs) { + test_nested_state_expect_einval(vm, state); + vcpu_enable_evmcs(vm, VCPU_ID); + } test_nested_state(vm, state); /* It is invalid to have vmxon_pa == -1ull and SMM flags non-zero. */ @@ -217,6 +226,8 @@ int main(int argc, char *argv[]) struct kvm_nested_state state; struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1); + have_evmcs = kvm_check_cap(KVM_CAP_HYPERV_ENLIGHTENED_VMCS); + if (!kvm_check_cap(KVM_CAP_NESTED_STATE)) { printf("KVM_CAP_NESTED_STATE not available, skipping test\n"); exit(KSFT_SKIP); -- cgit v1.2.3-59-g8ed1b From 11e54d35e6d5c3533b706753224ef38ea235684b Mon Sep 17 00:00:00 2001 From: Haiyan Song Date: Thu, 15 Aug 2019 11:59:42 +0800 Subject: perf vendor events intel: Add Tremontx event file v1.02 Add a Intel event file for perf. Signed-off-by: Haiyan Song Reviewed-by: Kan Liang Cc: Alexander Shishkin Cc: Andi Kleen Cc: Jin Yao Cc: Jiri Olsa Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190815035942.30602-1-haiyanx.song@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/pmu-events/arch/x86/mapfile.csv | 1 + tools/perf/pmu-events/arch/x86/tremontx/cache.json | 111 ++++++ .../pmu-events/arch/x86/tremontx/frontend.json | 26 ++ .../perf/pmu-events/arch/x86/tremontx/memory.json | 26 ++ tools/perf/pmu-events/arch/x86/tremontx/other.json | 26 ++ .../pmu-events/arch/x86/tremontx/pipeline.json | 111 ++++++ .../arch/x86/tremontx/uncore-memory.json | 73 ++++ .../pmu-events/arch/x86/tremontx/uncore-other.json | 431 +++++++++++++++++++++ .../pmu-events/arch/x86/tremontx/uncore-power.json | 11 + .../arch/x86/tremontx/virtual-memory.json | 86 ++++ 10 files changed, 902 insertions(+) create mode 100644 tools/perf/pmu-events/arch/x86/tremontx/cache.json create mode 100644 tools/perf/pmu-events/arch/x86/tremontx/frontend.json create mode 100644 tools/perf/pmu-events/arch/x86/tremontx/memory.json create mode 100644 tools/perf/pmu-events/arch/x86/tremontx/other.json create mode 100644 tools/perf/pmu-events/arch/x86/tremontx/pipeline.json create mode 100644 tools/perf/pmu-events/arch/x86/tremontx/uncore-memory.json create mode 100644 tools/perf/pmu-events/arch/x86/tremontx/uncore-other.json create mode 100644 tools/perf/pmu-events/arch/x86/tremontx/uncore-power.json create mode 100644 tools/perf/pmu-events/arch/x86/tremontx/virtual-memory.json (limited to 'tools') diff --git a/tools/perf/pmu-events/arch/x86/mapfile.csv b/tools/perf/pmu-events/arch/x86/mapfile.csv index b90e5fec2f32..745ced083844 100644 --- a/tools/perf/pmu-events/arch/x86/mapfile.csv +++ b/tools/perf/pmu-events/arch/x86/mapfile.csv @@ -35,4 +35,5 @@ GenuineIntel-6-55-[01234],v1,skylakex,core GenuineIntel-6-55-[56789ABCDEF],v1,cascadelakex,core GenuineIntel-6-7D,v1,icelake,core GenuineIntel-6-7E,v1,icelake,core +GenuineIntel-6-86,v1,tremontx,core AuthenticAMD-23-[[:xdigit:]]+,v1,amdfam17h,core diff --git a/tools/perf/pmu-events/arch/x86/tremontx/cache.json b/tools/perf/pmu-events/arch/x86/tremontx/cache.json new file mode 100644 index 000000000000..f88040171b4d --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/tremontx/cache.json @@ -0,0 +1,111 @@ +[ + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cacheable memory requests that miss in the the Last Level Cache. Requests include Demand Loads, Reads for Ownership(RFO), Instruction fetches and L1 HW prefetches. If the platform has an L3 cache, last level cache is the L3, otherwise it is the L2.", + "EventCode": "0x2e", + "Counter": "0,1,2,3", + "UMask": "0x41", + "PEBScounters": "0,1,2,3", + "EventName": "LONGEST_LAT_CACHE.MISS", + "PDIR_COUNTER": "na", + "SampleAfterValue": "200003", + "BriefDescription": "Counts memory requests originating from the core that miss in the last level cache. If the platform has an L3 cache, last level cache is the L3, otherwise it is the L2." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts cacheable memory requests that access the Last Level Cache. Requests include Demand Loads, Reads for Ownership(RFO), Instruction fetches and L1 HW prefetches. If the platform has an L3 cache, last level cache is the L3, otherwise it is the L2.", + "EventCode": "0x2e", + "Counter": "0,1,2,3", + "UMask": "0x4f", + "PEBScounters": "0,1,2,3", + "EventName": "LONGEST_LAT_CACHE.REFERENCE", + "PDIR_COUNTER": "na", + "SampleAfterValue": "200003", + "BriefDescription": "Counts memory requests originating from the core that reference a cache line in the last level cache. If the platform has an L3 cache, last level cache is the L3, otherwise it is the L2." + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of load uops retired. This event is Precise Event capable", + "EventCode": "0xd0", + "Counter": "0,1,2,3", + "UMask": "0x81", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_UOPS_RETIRED.ALL_LOADS", + "SampleAfterValue": "200003", + "BriefDescription": "Counts the number of load uops retired.", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of store uops retired. This event is Precise Event capable", + "EventCode": "0xd0", + "Counter": "0,1,2,3", + "UMask": "0x82", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_UOPS_RETIRED.ALL_STORES", + "SampleAfterValue": "200003", + "BriefDescription": "Counts the number of store uops retired.", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "EventCode": "0xd1", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_LOAD_UOPS_RETIRED.L1_HIT", + "SampleAfterValue": "200003", + "BriefDescription": "Counts the number of load uops retired that hit the level 1 data cache", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "EventCode": "0xd1", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_LOAD_UOPS_RETIRED.L2_HIT", + "SampleAfterValue": "200003", + "BriefDescription": "Counts the number of load uops retired that hit in the level 2 cache", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "EventCode": "0xd1", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_LOAD_UOPS_RETIRED.L3_HIT", + "SampleAfterValue": "200003", + "BriefDescription": "Counts the number of load uops retired that miss in the level 3 cache" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "EventCode": "0xd1", + "Counter": "0,1,2,3", + "UMask": "0x8", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_LOAD_UOPS_RETIRED.L1_MISS", + "SampleAfterValue": "200003", + "BriefDescription": "Counts the number of load uops retired that miss in the level 1 data cache", + "Data_LA": "1" + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "EventCode": "0xd1", + "Counter": "0,1,2,3", + "UMask": "0x10", + "PEBScounters": "0,1,2,3", + "EventName": "MEM_LOAD_UOPS_RETIRED.L2_MISS", + "SampleAfterValue": "200003", + "BriefDescription": "Counts the number of load uops retired that miss in the level 2 cache", + "Data_LA": "1" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/tremontx/frontend.json b/tools/perf/pmu-events/arch/x86/tremontx/frontend.json new file mode 100644 index 000000000000..73b0a1ed5756 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/tremontx/frontend.json @@ -0,0 +1,26 @@ +[ + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts requests to the Instruction Cache (ICache) for one or more bytes in an ICache Line and that cache line is not in the ICache (miss). The event strives to count on a cache line basis, so that multiple accesses which miss in a single cache line count as one ICACHE.MISS. Specifically, the event counts when straight line code crosses the cache line boundary, or when a branch target is to a new line, and that cache line is not in the ICache.", + "EventCode": "0x80", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "ICACHE.MISSES", + "PDIR_COUNTER": "na", + "SampleAfterValue": "200003", + "BriefDescription": "Counts requests to the Instruction Cache (ICache) for one or more bytes in a cache line and they do not hit in the ICache (miss)." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts requests to the Instruction Cache (ICache) for one or more bytes in an ICache Line. The event strives to count on a cache line basis, so that multiple fetches to a single cache line count as one ICACHE.ACCESS. Specifically, the event counts when accesses from straight line code crosses the cache line boundary, or when a branch target is to a new line.", + "EventCode": "0x80", + "Counter": "0,1,2,3", + "UMask": "0x3", + "PEBScounters": "0,1,2,3", + "EventName": "ICACHE.ACCESSES", + "PDIR_COUNTER": "na", + "SampleAfterValue": "200003", + "BriefDescription": "Counts requests to the Instruction Cache (ICache) for one or more bytes cache Line." + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/tremontx/memory.json b/tools/perf/pmu-events/arch/x86/tremontx/memory.json new file mode 100644 index 000000000000..65469e84f35b --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/tremontx/memory.json @@ -0,0 +1,26 @@ +[ + { + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "EventCode": "0XB7", + "MSRValue": "0x000000003F04000001", + "Counter": "0,1,2,3", + "UMask": "0x1", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS", + "MSRIndex": "0x1a6,0x1a7", + "SampleAfterValue": "100003", + "BriefDescription": "Counts demand data reads that was not supplied by the L3 cache.", + "Offcore": "1" + }, + { + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "EventCode": "0XB7", + "MSRValue": "0x000000003F04000002", + "Counter": "0,1,2,3", + "UMask": "0x1", + "EventName": "OCR.DEMAND_RFO.L3_MISS", + "MSRIndex": "0x1a6,0x1a7", + "SampleAfterValue": "100003", + "BriefDescription": "Counts all demand reads for ownership (RFO) requests and software based prefetches for exclusive ownership (PREFETCHW) that was not supplied by the L3 cache.", + "Offcore": "1" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/tremontx/other.json b/tools/perf/pmu-events/arch/x86/tremontx/other.json new file mode 100644 index 000000000000..85bf3c8f3914 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/tremontx/other.json @@ -0,0 +1,26 @@ +[ + { + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "EventCode": "0XB7", + "MSRValue": "0x000000000000010001", + "Counter": "0,1,2,3", + "UMask": "0x1", + "EventName": "OCR.DEMAND_DATA_RD.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "SampleAfterValue": "100003", + "BriefDescription": "Counts demand data reads that have any response type.", + "Offcore": "1" + }, + { + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "EventCode": "0XB7", + "MSRValue": "0x000000000000010002", + "Counter": "0,1,2,3", + "UMask": "0x1", + "EventName": "OCR.DEMAND_RFO.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "SampleAfterValue": "100003", + "BriefDescription": "Counts all demand reads for ownership (RFO) requests and software based prefetches for exclusive ownership (PREFETCHW) that have any response type.", + "Offcore": "1" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/tremontx/pipeline.json b/tools/perf/pmu-events/arch/x86/tremontx/pipeline.json new file mode 100644 index 000000000000..05a8f6a7d9c0 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/tremontx/pipeline.json @@ -0,0 +1,111 @@ +[ + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of instructions that retire. For instructions that consist of multiple uops, this event counts the retirement of the last uop of the instruction. The counter continues counting during hardware interrupts, traps, and inside interrupt handlers. This event uses fixed counter 0.", + "Counter": "32", + "UMask": "0x1", + "PEBScounters": "32", + "EventName": "INST_RETIRED.ANY", + "SampleAfterValue": "2000003", + "BriefDescription": "Counts the number of instructions retired. (Fixed event)" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of core cycles while the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. The core frequency may change from time to time. For this reason this event may have a changing ratio with regards to time. This event uses fixed counter 1.", + "Counter": "33", + "UMask": "0x2", + "PEBScounters": "33", + "EventName": "CPU_CLK_UNHALTED.CORE", + "PDIR_COUNTER": "na", + "SampleAfterValue": "2000003", + "BriefDescription": "Counts the number of unhalted core clock cycles. (Fixed event)" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of reference cycles that the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. The core frequency may change from time. This event is not affected by core frequency changes and at a fixed frequency. This event uses fixed counter 2.", + "Counter": "34", + "UMask": "0x3", + "PEBScounters": "34", + "EventName": "CPU_CLK_UNHALTED.REF_TSC", + "PDIR_COUNTER": "na", + "SampleAfterValue": "2000003", + "BriefDescription": "Counts the number of unhalted reference clock cycles at TSC frequency. (Fixed event)" + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of core cycles while the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. The core frequency may change from time to time. For this reason this event may have a changing ratio with regards to time. This event uses a programmable general purpose performance counter.", + "EventCode": "0x3c", + "Counter": "0,1,2,3", + "PEBScounters": "0,1,2,3", + "EventName": "CPU_CLK_UNHALTED.CORE_P", + "PDIR_COUNTER": "na", + "SampleAfterValue": "2000003", + "BriefDescription": "Counts the number of unhalted core clock cycles." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts reference cycles (at TSC frequency) when core is not halted. This event uses a programmable general purpose perfmon counter.", + "EventCode": "0x3c", + "Counter": "0,1,2,3", + "UMask": "0x1", + "PEBScounters": "0,1,2,3", + "EventName": "CPU_CLK_UNHALTED.REF", + "PDIR_COUNTER": "na", + "SampleAfterValue": "2000003", + "BriefDescription": "Counts the number of unhalted reference clock cycles at TSC frequency." + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of instructions that retire execution. For instructions that consist of multiple uops, this event counts the retirement of the last uop of the instruction. The event continues counting during hardware interrupts, traps, and inside interrupt handlers. This is an architectural performance event. This event uses a Programmable general purpose perfmon counter. *This event is Precise Event capable: The EventingRIP field in the PEBS record is precise to the address of the instruction which caused the event.", + "EventCode": "0xc0", + "Counter": "0,1,2,3", + "PEBScounters": "0,1,2,3", + "EventName": "INST_RETIRED.ANY_P", + "SampleAfterValue": "2000003", + "BriefDescription": "Counts the number of instructions retired." + }, + { + "CollectPEBSRecord": "2", + "EventCode": "0xc3", + "Counter": "0,1,2,3", + "PEBScounters": "0,1,2,3", + "EventName": "MACHINE_CLEARS.ANY", + "PDIR_COUNTER": "na", + "SampleAfterValue": "20003", + "BriefDescription": "Counts all machine clears due to, but not limited to memory ordering, memory disambiguation, SMC, page faults and FP assist." + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts branch instructions retired for all branch types. This event is Precise Event capable. This is an architectural event.", + "EventCode": "0xc4", + "Counter": "0,1,2,3", + "PEBScounters": "0,1,2,3", + "EventName": "BR_INST_RETIRED.ALL_BRANCHES", + "SampleAfterValue": "200003", + "BriefDescription": "Counts the number of branch instructions retired for all branch types." + }, + { + "PEBS": "1", + "CollectPEBSRecord": "2", + "PublicDescription": "Counts mispredicted branch instructions retired for all branch types. This event is Precise Event capable. This is an architectural event.", + "EventCode": "0xc5", + "Counter": "0,1,2,3", + "PEBScounters": "0,1,2,3", + "EventName": "BR_MISP_RETIRED.ALL_BRANCHES", + "SampleAfterValue": "200003", + "BriefDescription": "Counts the number of mispredicted branch instructions retired." + }, + { + "CollectPEBSRecord": "2", + "EventCode": "0xcd", + "Counter": "0,1,2,3", + "PEBScounters": "0,1,2,3", + "EventName": "CYCLES_DIV_BUSY.ANY", + "PDIR_COUNTER": "na", + "SampleAfterValue": "2000003", + "BriefDescription": "Counts cycles the floating point divider or integer divider or both are busy. Does not imply a stall waiting for either divider." + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/tremontx/uncore-memory.json b/tools/perf/pmu-events/arch/x86/tremontx/uncore-memory.json new file mode 100644 index 000000000000..15376f2cf052 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/tremontx/uncore-memory.json @@ -0,0 +1,73 @@ +[ + { + "BriefDescription": "read requests to memory controller. Derived from unc_m_cas_count.rd", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x04", + "EventName": "LLC_MISSES.MEM_READ", + "PerPkg": "1", + "ScaleUnit": "64Bytes", + "UMask": "0x0f", + "Unit": "iMC" + }, + { + "BriefDescription": "write requests to memory controller. Derived from unc_m_cas_count.wr", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x04", + "EventName": "LLC_MISSES.MEM_WRITE", + "PerPkg": "1", + "ScaleUnit": "64Bytes", + "UMask": "0x30", + "Unit": "iMC" + }, + { + "BriefDescription": "Memory controller clock ticks", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventName": "UNC_M_CLOCKTICKS", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Pre-charge for reads", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x02", + "EventName": "UNC_M_PRE_COUNT.RD", + "PerPkg": "1", + "UMask": "0x04", + "Unit": "iMC" + }, + { + "BriefDescription": "Pre-charge for writes", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x02", + "EventName": "UNC_M_PRE_COUNT.WR", + "PerPkg": "1", + "UMask": "0x08", + "Unit": "iMC" + }, + { + "BriefDescription": "Precharge due to read on page miss, write on page miss or PGT", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x02", + "EventName": "UNC_M_PRE_COUNT.ALL", + "PerPkg": "1", + "UMask": "0x1c", + "Unit": "iMC" + }, + { + "BriefDescription": "DRAM Precharge commands. : Precharge due to page table", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x02", + "EventName": "UNC_M_PRE_COUNT.PGT", + "PerPkg": "1", + "PublicDescription": "DRAM Precharge commands. : Precharge due to page table : Counts the number of DRAM Precharge commands sent on this channel.", + "UMask": "0x10", + "Unit": "iMC" + } +] diff --git a/tools/perf/pmu-events/arch/x86/tremontx/uncore-other.json b/tools/perf/pmu-events/arch/x86/tremontx/uncore-other.json new file mode 100644 index 000000000000..6deff1fe89e3 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/tremontx/uncore-other.json @@ -0,0 +1,431 @@ +[ + { + "BriefDescription": "Uncore cache clock ticks", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventName": "UNC_CHA_CLOCKTICKS", + "PerPkg": "1", + "Unit": "CHA" + }, + { + "BriefDescription": "LLC misses - Uncacheable reads (from cpu) . Derived from unc_cha_tor_inserts.ia_miss", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x35", + "EventName": "LLC_MISSES.UNCACHEABLE", + "Filter": "config1=0x40e33", + "PerPkg": "1", + "UMask": "0xC001FE01", + "UMaskExt": "0xC001FE", + "Unit": "CHA" + }, + { + "BriefDescription": "MMIO reads. Derived from unc_cha_tor_inserts.ia_miss", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x35", + "EventName": "LLC_MISSES.MMIO_READ", + "Filter": "config1=0x40040e33", + "PerPkg": "1", + "UMask": "0xC001FE01", + "UMaskExt": "0xC001FE", + "Unit": "CHA" + }, + { + "BriefDescription": "MMIO writes. Derived from unc_cha_tor_inserts.ia_miss", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x35", + "EventName": "LLC_MISSES.MMIO_WRITE", + "Filter": "config1=0x40041e33", + "PerPkg": "1", + "UMask": "0xC001FE01", + "UMaskExt": "0xC001FE", + "Unit": "CHA" + }, + { + "BriefDescription": "Streaming stores (full cache line). Derived from unc_cha_tor_inserts.ia_miss", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x35", + "EventName": "LLC_REFERENCES.STREAMING_FULL", + "Filter": "config1=0x41833", + "PerPkg": "1", + "ScaleUnit": "64Bytes", + "UMask": "0xC001FE01", + "UMaskExt": "0xC001FE", + "Unit": "CHA" + }, + { + "BriefDescription": "Streaming stores (partial cache line). Derived from unc_cha_tor_inserts.ia_miss", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x35", + "EventName": "LLC_REFERENCES.STREAMING_PARTIAL", + "Filter": "config1=0x41a33", + "PerPkg": "1", + "ScaleUnit": "64Bytes", + "UMask": "0xC001FE01", + "UMaskExt": "0xC001FE", + "Unit": "CHA" + }, + { + "BriefDescription": "PCI Express bandwidth reading at IIO. Derived from unc_iio_data_req_of_cpu.mem_read.part0", + "Counter": "0,1", + "CounterType": "PGMABLE", + "EventCode": "0x83", + "EventName": "LLC_MISSES.PCIE_READ", + "FCMask": "0x07", + "Filter": "ch_mask=0x1f", + "MetricExpr": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART0 +UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART1 +UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART2 +UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART3", + "MetricName": "LLC_MISSES.PCIE_READ", + "PerPkg": "1", + "PortMask": "0x01", + "ScaleUnit": "4Bytes", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth writing at IIO. Derived from unc_iio_data_req_of_cpu.mem_write.part0", + "Counter": "0,1", + "CounterType": "PGMABLE", + "EventCode": "0x83", + "EventName": "LLC_MISSES.PCIE_WRITE", + "FCMask": "0x07", + "Filter": "ch_mask=0x1f", + "MetricExpr": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART0 +UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART1 +UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART2 +UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART3", + "MetricName": "LLC_MISSES.PCIE_WRITE", + "PerPkg": "1", + "PortMask": "0x01", + "ScaleUnit": "4Bytes", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth writing at IIO, part 1", + "Counter": "0,1", + "CounterType": "PGMABLE", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "ScaleUnit": "4Bytes", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth writing at IIO, part 2", + "Counter": "0,1", + "CounterType": "PGMABLE", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "ScaleUnit": "4Bytes", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth writing at IIO, part 3", + "Counter": "0,1", + "CounterType": "PGMABLE", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "ScaleUnit": "4Bytes", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth reading at IIO, part 1", + "Counter": "0,1", + "CounterType": "PGMABLE", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "ScaleUnit": "4Bytes", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth reading at IIO, part 2", + "Counter": "0,1", + "CounterType": "PGMABLE", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "ScaleUnit": "4Bytes", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth reading at IIO, part 3", + "Counter": "0,1", + "CounterType": "PGMABLE", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "ScaleUnit": "4Bytes", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "TOR Inserts; CRd misses from local IA", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x35", + "EventName": "UNC_CHA_TOR_INSERTS.IA_MISS_CRD", + "PerPkg": "1", + "PublicDescription": "TOR Inserts; Code read from local IA that misses in the snoop filter", + "UMask": "0xC80FFE01", + "UMaskExt": "0xC80FFE", + "Unit": "CHA" + }, + { + "BriefDescription": "TOR Inserts; CRd Pref misses from local IA", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x35", + "EventName": "UNC_CHA_TOR_INSERTS.IA_MISS_CRD_PREF", + "PerPkg": "1", + "PublicDescription": "TOR Inserts; Code read prefetch from local IA that misses in the snoop filter", + "UMask": "0xC88FFE01", + "UMaskExt": "0xC88FFE", + "Unit": "CHA" + }, + { + "BriefDescription": "TOR Inserts; DRd Opt misses from local IA", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x35", + "EventName": "UNC_CHA_TOR_INSERTS.IA_MISS_DRD_OPT", + "PerPkg": "1", + "PublicDescription": "TOR Inserts; Data read opt from local IA that misses in the snoop filter", + "UMask": "0xC827FE01", + "UMaskExt": "0xC827FE", + "Unit": "CHA" + }, + { + "BriefDescription": "TOR Inserts; DRd Opt Pref misses from local IA", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x35", + "EventName": "UNC_CHA_TOR_INSERTS.IA_MISS_DRD_OPT_PREF", + "PerPkg": "1", + "PublicDescription": "TOR Inserts; Data read opt prefetch from local IA that misses in the snoop filter", + "UMask": "0xC8A7FE01", + "UMaskExt": "0xC8A7FE", + "Unit": "CHA" + }, + { + "BriefDescription": "TOR Inserts; RFO misses from local IA", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x35", + "EventName": "UNC_CHA_TOR_INSERTS.IA_MISS_RFO", + "PerPkg": "1", + "PublicDescription": "TOR Inserts; Read for ownership from local IA that misses in the snoop filter", + "UMask": "0xC807FE01", + "UMaskExt": "0xC807FE", + "Unit": "CHA" + }, + { + "BriefDescription": "TOR Inserts; RFO pref misses from local IA", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x35", + "EventName": "UNC_CHA_TOR_INSERTS.IA_MISS_RFO_PREF", + "PerPkg": "1", + "PublicDescription": "TOR Inserts; Read for ownership prefetch from local IA that misses in the snoop filter", + "UMask": "0xC887FE01", + "UMaskExt": "0xC887FE", + "Unit": "CHA" + }, + { + "BriefDescription": "TOR Inserts; WCiL misses from local IA", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x35", + "EventName": "UNC_CHA_TOR_INSERTS.IA_MISS_WCIL", + "PerPkg": "1", + "PublicDescription": "TOR Inserts; Data read from local IA that misses in the snoop filter", + "UMask": "0xC86FFE01", + "UMaskExt": "0xC86FFE", + "Unit": "CHA" + }, + { + "BriefDescription": "TOR Inserts; WCiLF misses from local IA", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x35", + "EventName": "UNC_CHA_TOR_INSERTS.IA_MISS_WCILF", + "PerPkg": "1", + "PublicDescription": "TOR Inserts; Data read from local IA that misses in the snoop filter", + "UMask": "0xC867FE01", + "UMaskExt": "0xC867FE", + "Unit": "CHA" + }, + { + "BriefDescription": "Clockticks of the integrated IO (IIO) traffic controller", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x01", + "EventName": "UNC_IIO_CLOCKTICKS", + "PerPkg": "1", + "PublicDescription": "Clockticks of the integrated IO (IIO) traffic controller", + "Unit": "IIO" + }, + { + "BriefDescription": "Data requested of the CPU : Card reading from DRAM", + "Counter": "0,1", + "CounterType": "PGMABLE", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART4", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x10", + "PublicDescription": "Data requested of the CPU : Card reading from DRAM : Number of DWs (4 bytes) the card requests of the main die. Includes all requests initiated by the Card, including reads and writes. : x16 card plugged in to stack, Or x8 card plugged in to Lane 0/1, Or x4 card is plugged in to slot 0", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Data requested of the CPU : Card reading from DRAM", + "Counter": "0,1", + "CounterType": "PGMABLE", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART5", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x20", + "PublicDescription": "Data requested of the CPU : Card reading from DRAM : Number of DWs (4 bytes) the card requests of the main die. Includes all requests initiated by the Card, including reads and writes. : x4 card is plugged in to slot 1", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Data requested of the CPU : Card reading from DRAM", + "Counter": "0,1", + "CounterType": "PGMABLE", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART6", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x40", + "PublicDescription": "Data requested of the CPU : Card reading from DRAM : Number of DWs (4 bytes) the card requests of the main die. Includes all requests initiated by the Card, including reads and writes. : x8 card plugged in to Lane 2/3, Or x4 card is plugged in to slot 1", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Data requested of the CPU : Card reading from DRAM", + "Counter": "0,1", + "CounterType": "PGMABLE", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART7", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x80", + "PublicDescription": "Data requested of the CPU : Card reading from DRAM : Number of DWs (4 bytes) the card requests of the main die. Includes all requests initiated by the Card, including reads and writes. : x4 card is plugged in to slot 3", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Data requested of the CPU : Card writing to DRAM", + "Counter": "0,1", + "CounterType": "PGMABLE", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART4", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x10", + "PublicDescription": "Data requested of the CPU : Card writing to DRAM : Number of DWs (4 bytes) the card requests of the main die. Includes all requests initiated by the Card, including reads and writes. : x16 card plugged in to stack, Or x8 card plugged in to Lane 0/1, Or x4 card is plugged in to slot 0", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Data requested of the CPU : Card writing to DRAM", + "Counter": "0,1", + "CounterType": "PGMABLE", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART5", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x20", + "PublicDescription": "Data requested of the CPU : Card writing to DRAM : Number of DWs (4 bytes) the card requests of the main die. Includes all requests initiated by the Card, including reads and writes. : x4 card is plugged in to slot 1", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Data requested of the CPU : Card writing to DRAM", + "Counter": "0,1", + "CounterType": "PGMABLE", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART6", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x40", + "PublicDescription": "Data requested of the CPU : Card writing to DRAM : Number of DWs (4 bytes) the card requests of the main die. Includes all requests initiated by the Card, including reads and writes. : x8 card plugged in to Lane 2/3, Or x4 card is plugged in to slot 1", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Data requested of the CPU : Card writing to DRAM", + "Counter": "0,1", + "CounterType": "PGMABLE", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART7", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x80", + "PublicDescription": "Data requested of the CPU : Card writing to DRAM : Number of DWs (4 bytes) the card requests of the main die. Includes all requests initiated by the Card, including reads and writes. : x4 card is plugged in to slot 3", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Clockticks of the IO coherency tracker (IRP)", + "Counter": "0,1", + "CounterType": "PGMABLE", + "EventCode": "0x01", + "EventName": "UNC_I_CLOCKTICKS", + "PerPkg": "1", + "PublicDescription": "Clockticks of the IO coherency tracker (IRP)", + "Unit": "IRP" + }, + { + "BriefDescription": "Clockticks of the mesh to memory (M2M)", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventName": "UNC_M2M_CLOCKTICKS", + "PerPkg": "1", + "PublicDescription": "Clockticks of the mesh to memory (M2M)", + "Unit": "M2M" + }, + { + "BriefDescription": "Clockticks of the mesh to PCI (M2P)", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventCode": "0x01", + "EventName": "UNC_M2P_CLOCKTICKS", + "PerPkg": "1", + "PublicDescription": "Clockticks of the mesh to PCI (M2P)", + "Unit": "M2PCIe" + }, + { + "BriefDescription": "Clockticks in the UBOX using a dedicated 48-bit Fixed Counter", + "Counter": "FIXED", + "CounterType": "PGMABLE", + "EventCode": "0xff", + "EventName": "UNC_U_CLOCKTICKS", + "PerPkg": "1", + "PublicDescription": "Clockticks in the UBOX using a dedicated 48-bit Fixed Counter", + "Unit": "UBOX" + } +] diff --git a/tools/perf/pmu-events/arch/x86/tremontx/uncore-power.json b/tools/perf/pmu-events/arch/x86/tremontx/uncore-power.json new file mode 100644 index 000000000000..ea62c092b43f --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/tremontx/uncore-power.json @@ -0,0 +1,11 @@ +[ + { + "BriefDescription": "Clockticks of the power control unit (PCU)", + "Counter": "0,1,2,3", + "CounterType": "PGMABLE", + "EventName": "UNC_P_CLOCKTICKS", + "PerPkg": "1", + "PublicDescription": "Clockticks of the power control unit (PCU)", + "Unit": "PCU" + } +] diff --git a/tools/perf/pmu-events/arch/x86/tremontx/virtual-memory.json b/tools/perf/pmu-events/arch/x86/tremontx/virtual-memory.json new file mode 100644 index 000000000000..93e407a0f645 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/tremontx/virtual-memory.json @@ -0,0 +1,86 @@ +[ + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts page walks completed due to demand data loads (including SW prefetches) whose address translations missed in all TLB levels and were mapped to 4K pages. The page walks can end with or without a page fault.", + "EventCode": "0x08", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_4K", + "PDIR_COUNTER": "na", + "SampleAfterValue": "200003", + "BriefDescription": "Page walk completed due to a demand load to a 4K page." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts page walks completed due to demand data loads (including SW prefetches) whose address translations missed in all TLB levels and were mapped to 2M or 4M pages. The page walks can end with or without a page fault.", + "EventCode": "0x08", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4M", + "PDIR_COUNTER": "na", + "SampleAfterValue": "200003", + "BriefDescription": "Page walk completed due to a demand load to a 2M or 4M page." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts page walks completed due to demand data stores whose address translations missed in the TLB and were mapped to 4K pages. The page walks can end with or without a page fault.", + "EventCode": "0x49", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_4K", + "PDIR_COUNTER": "na", + "SampleAfterValue": "2000003", + "BriefDescription": "Page walk completed due to a demand data store to a 4K page." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts page walks completed due to demand data stores whose address translations missed in the TLB and were mapped to 2M or 4M pages. The page walks can end with or without a page fault.", + "EventCode": "0x49", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M", + "PDIR_COUNTER": "na", + "SampleAfterValue": "2000003", + "BriefDescription": "Page walk completed due to a demand data store to a 2M or 4M page." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts the number of times the machine was unable to find a translation in the Instruction Translation Lookaside Buffer (ITLB) and new translation was filled into the ITLB. The event is speculative in nature, but will not count translations (page walks) that are begun and not finished, or translations that are finished but not filled into the ITLB.", + "EventCode": "0x81", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "ITLB.FILLS", + "PDIR_COUNTER": "na", + "SampleAfterValue": "200003", + "BriefDescription": "Counts the number of times there was an ITLB miss and a new translation was filled into the ITLB." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts page walks completed due to instruction fetches whose address translations missed in the TLB and were mapped to 4K pages. The page walks can end with or without a page fault.", + "EventCode": "0x85", + "Counter": "0,1,2,3", + "UMask": "0x2", + "PEBScounters": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_COMPLETED_4K", + "PDIR_COUNTER": "na", + "SampleAfterValue": "2000003", + "BriefDescription": "Page walk completed due to an instruction fetch in a 4K page." + }, + { + "CollectPEBSRecord": "2", + "PublicDescription": "Counts page walks completed due to instruction fetches whose address translations missed in the TLB and were mapped to 2M or 4M pages. The page walks can end with or without a page fault.", + "EventCode": "0x85", + "Counter": "0,1,2,3", + "UMask": "0x4", + "PEBScounters": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_COMPLETED_2M_4M", + "PDIR_COUNTER": "na", + "SampleAfterValue": "2000003", + "BriefDescription": "Page walk completed due to an instruction fetch in a 2M or 4M page." + } +] \ No newline at end of file -- cgit v1.2.3-59-g8ed1b From f90a24171a8179a29e5e1532fd5bb94e59b5380e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 14 Aug 2019 16:20:13 -0300 Subject: perf script: Allow specifying event to switch on processing of other events Sometime we want to only consider events after something happens, so allow discarding events till such events is found, e.g.: Record all scheduler tracepoints and the sys_enter_nanosleep syscall event for the 'sleep 1' workload: # perf record -e sched:*,syscalls:sys_enter_nanosleep sleep 1 [ perf record: Woken up 31 times to write data ] [ perf record: Captured and wrote 0.032 MB perf.data (10 samples) ] # So we have these events in the generated perf data file: # perf evlist sched:sched_kthread_stop sched:sched_kthread_stop_ret sched:sched_waking sched:sched_wakeup sched:sched_wakeup_new sched:sched_switch sched:sched_migrate_task sched:sched_process_free sched:sched_process_exit sched:sched_wait_task sched:sched_process_wait sched:sched_process_fork sched:sched_process_exec sched:sched_stat_wait sched:sched_stat_sleep sched:sched_stat_iowait sched:sched_stat_blocked sched:sched_stat_runtime sched:sched_pi_setprio sched:sched_move_numa sched:sched_stick_numa sched:sched_swap_numa sched:sched_wake_idle_without_ipi syscalls:sys_enter_nanosleep # Tip: use 'perf evlist --trace-fields' to show fields for tracepoint events # Then show all of the events that actually took place in this 'perf record' session: # perf script :13637 13637 [002] 108237.581529: sched:sched_waking: comm=perf pid=13638 prio=120 target_cpu=001 :13637 13637 [002] 108237.581537: sched:sched_wakeup: perf:13638 [120] success=1 CPU:001 sleep 13638 [001] 108237.581992: sched:sched_process_exec: filename=/usr/bin/sleep pid=13638 old_pid=13638 sleep 13638 [001] 108237.582286: syscalls:sys_enter_nanosleep: rqtp: 0x7fff1948ac40, rmtp: 0x00000000 sleep 13638 [001] 108237.582289: sched:sched_stat_runtime: comm=sleep pid=13638 runtime=578104 [ns] vruntime=202889459556 [ns] sleep 13638 [001] 108237.582291: sched:sched_switch: sleep:13638 [120] S ==> swapper/1:0 [120] swapper 0 [001] 108238.582428: sched:sched_waking: comm=sleep pid=13638 prio=120 target_cpu=001 swapper 0 [001] 108238.582458: sched:sched_wakeup: sleep:13638 [120] success=1 CPU:001 sleep 13638 [001] 108238.582698: sched:sched_stat_runtime: comm=sleep pid=13638 runtime=173915 [ns] vruntime=202889633471 [ns] sleep 13638 [001] 108238.582782: sched:sched_process_exit: comm=sleep pid=13638 prio=120 # Now lets see only the ones that took place after a certain "marker": # perf script --switch-on syscalls:sys_enter_nanosleep sleep 13638 [001] 108237.582289: sched:sched_stat_runtime: comm=sleep pid=13638 runtime=578104 [ns] vruntime=202889459556 [ns] sleep 13638 [001] 108237.582291: sched:sched_switch: sleep:13638 [120] S ==> swapper/1:0 [120] swapper 0 [001] 108238.582428: sched:sched_waking: comm=sleep pid=13638 prio=120 target_cpu=001 swapper 0 [001] 108238.582458: sched:sched_wakeup: sleep:13638 [120] success=1 CPU:001 sleep 13638 [001] 108238.582698: sched:sched_stat_runtime: comm=sleep pid=13638 runtime=173915 [ns] vruntime=202889633471 [ns] sleep 13638 [001] 108238.582782: sched:sched_process_exit: comm=sleep pid=13638 prio=120 # Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-f1oo0ufdhrkx6nhy2lj1ierm@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-script.txt | 3 +++ tools/perf/builtin-script.c | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) (limited to 'tools') diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index caaab28f8400..9936819aae1c 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt @@ -417,6 +417,9 @@ include::itrace.txt[] For itrace only show specified functions and their callees for itrace. Multiple functions can be separated by comma. +--switch-on EVENT_NAME:: + Only consider events after this event is found. + SEE ALSO -------- linkperf:perf-record[1], linkperf:perf-script-perl[1], diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 31a529ec139f..d0bc7ccaf7bf 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1616,6 +1616,11 @@ static int perf_sample__fprintf_synth(struct perf_sample *sample, return 0; } +struct evswitch { + struct evsel *on; + bool discarding; +}; + struct perf_script { struct perf_tool tool; struct perf_session *session; @@ -1628,6 +1633,7 @@ struct perf_script { bool show_bpf_events; bool allocated; bool per_event_dump; + struct evswitch evswitch; struct perf_cpu_map *cpus; struct perf_thread_map *threads; int name_width; @@ -1805,6 +1811,13 @@ static void process_event(struct perf_script *script, if (!show_event(sample, evsel, thread, al)) return; + if (script->evswitch.on && script->evswitch.discarding) { + if (script->evswitch.on != evsel) + return; + + script->evswitch.discarding = false; + } + ++es->samples; perf_sample__fprintf_start(sample, thread, evsel, @@ -3395,6 +3408,7 @@ int cmd_script(int argc, const char **argv) struct utsname uts; char *script_path = NULL; const char **__argv; + const char *event_switch_on = NULL; int i, j, err = 0; struct perf_script script = { .tool = { @@ -3538,6 +3552,8 @@ int cmd_script(int argc, const char **argv) "file", "file saving guest os /proc/kallsyms"), OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules, "file", "file saving guest os /proc/modules"), + OPT_STRING(0, "switch-on", &event_switch_on, + "event", "Consider events from the first ocurrence of this event"), OPT_END() }; const char * const script_subcommands[] = { "record", "report", NULL }; @@ -3862,6 +3878,16 @@ int cmd_script(int argc, const char **argv) script.range_num); } + if (event_switch_on) { + script.evswitch.on = perf_evlist__find_evsel_by_str(session->evlist, event_switch_on); + if (script.evswitch.on == NULL) { + fprintf(stderr, "switch-on event not found (%s)\n", event_switch_on); + err = -ENOENT; + goto out_delete; + } + script.evswitch.discarding = true; + } + err = __cmd_script(&script); flush_scripting(); -- cgit v1.2.3-59-g8ed1b From 6469eb6dffeb44edfa3d4ca496b044b4a9c643b9 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 14 Aug 2019 16:40:58 -0300 Subject: perf script: Allow showing the --switch-on event One may want to see the --switch-on event as well, allow for that, using the previous cset example: # perf script --switch-on syscalls:sys_enter_nanosleep --show-on-off sleep 13638 [001] 108237.582286: syscalls:sys_enter_nanosleep: rqtp: 0x7fff1948ac40, rmtp: 0x00000000 sleep 13638 [001] 108237.582289: sched:sched_stat_runtime: comm=sleep pid=13638 runtime=578104 [ns] vruntime=202889459556 [ns] sleep 13638 [001] 108237.582291: sched:sched_switch: sleep:13638 [120] S ==> swapper/1:0 [120] swapper 0 [001] 108238.582428: sched:sched_waking: comm=sleep pid=13638 prio=120 target_cpu=001 swapper 0 [001] 108238.582458: sched:sched_wakeup: sleep:13638 [120] success=1 CPU:001 sleep 13638 [001] 108238.582698: sched:sched_stat_runtime: comm=sleep pid=13638 runtime=173915 [ns] vruntime=202889633471 [ns] sleep 13638 [001] 108238.582782: sched:sched_process_exit: comm=sleep pid=13638 prio=120 # # perf script --switch-on syscalls:sys_enter_nanosleep sleep 13638 [001] 108237.582289: sched:sched_stat_runtime: comm=sleep pid=13638 runtime=578104 [ns] vruntime=202889459556 [ns] sleep 13638 [001] 108237.582291: sched:sched_switch: sleep:13638 [120] S ==> swapper/1:0 [120] swapper 0 [001] 108238.582428: sched:sched_waking: comm=sleep pid=13638 prio=120 target_cpu=001 swapper 0 [001] 108238.582458: sched:sched_wakeup: sleep:13638 [120] success=1 CPU:001 sleep 13638 [001] 108238.582698: sched:sched_stat_runtime: comm=sleep pid=13638 runtime=173915 [ns] vruntime=202889633471 [ns] sleep 13638 [001] 108238.582782: sched:sched_process_exit: comm=sleep pid=13638 prio=120 # Signed-off-by: Arnaldo Carvalho de Melo Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Cc: Florian Weimer Link: https://lkml.kernel.org/n/tip-0omwwoywj1v63gu8cz0tr0cy@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-script.txt | 3 +++ tools/perf/builtin-script.c | 6 ++++++ 2 files changed, 9 insertions(+) (limited to 'tools') diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index 9936819aae1c..24eea68ee829 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt @@ -420,6 +420,9 @@ include::itrace.txt[] --switch-on EVENT_NAME:: Only consider events after this event is found. +--show-on-off-events:: + Show the --switch-on event too. + SEE ALSO -------- linkperf:perf-record[1], linkperf:perf-script-perl[1], diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index d0bc7ccaf7bf..fa0cc8b0eccc 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1619,6 +1619,7 @@ static int perf_sample__fprintf_synth(struct perf_sample *sample, struct evswitch { struct evsel *on; bool discarding; + bool show_on_off_events; }; struct perf_script { @@ -1816,6 +1817,9 @@ static void process_event(struct perf_script *script, return; script->evswitch.discarding = false; + + if (!script->evswitch.show_on_off_events) + return; } ++es->samples; @@ -3554,6 +3558,8 @@ int cmd_script(int argc, const char **argv) "file", "file saving guest os /proc/modules"), OPT_STRING(0, "switch-on", &event_switch_on, "event", "Consider events from the first ocurrence of this event"), + OPT_BOOLEAN(0, "show-on-off-events", &script.evswitch.show_on_off_events, + "Show the on/off switch events, used with --switch-on"), OPT_END() }; const char * const script_subcommands[] = { "record", "report", NULL }; -- cgit v1.2.3-59-g8ed1b From dd41f660c03a6d8f2c2f3b2cccf50d8c4e06dd42 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 14 Aug 2019 16:51:28 -0300 Subject: perf script: Allow specifying event to switch off processing of other events Counterpart of --switch-on: # perf record -e sched:*,syscalls:sys_*_nanosleep sleep 1 [ perf record: Woken up 36 times to write data ] [ perf record: Captured and wrote 0.032 MB perf.data (10 samples) ] # # perf script :20918 20918 [002] 109866.143696: sched:sched_waking: comm=perf pid=20919 prio=120 target_cpu=001 :20918 20918 [002] 109866.143702: sched:sched_wakeup: perf:20919 [120] success=1 CPU:001 sleep 20919 [001] 109866.144081: sched:sched_process_exec: filename=/usr/bin/sleep pid=20919 old_pid=20919 sleep 20919 [001] 109866.144408: syscalls:sys_enter_nanosleep: rqtp: 0x7ffc2384fef0, rmtp: 0x00000000 sleep 20919 [001] 109866.144411: sched:sched_stat_runtime: comm=sleep pid=20919 runtime=521249 [ns] vruntime=202919398131 [n> sleep 20919 [001] 109866.144412: sched:sched_switch: sleep:20919 [120] S ==> swapper/1:0 [120] swapper 0 [001] 109867.144568: sched:sched_waking: comm=sleep pid=20919 prio=120 target_cpu=001 swapper 0 [001] 109867.144586: sched:sched_wakeup: sleep:20919 [120] success=1 CPU:001 sleep 20919 [001] 109867.144614: syscalls:sys_exit_nanosleep: 0x0 sleep 20919 [001] 109867.144753: sched:sched_process_exit: comm=sleep pid=20919 prio=120 # # perf script --switch-off syscalls:sys_exit_nanosleep :20918 20918 [002] 109866.143696: sched:sched_waking: comm=perf pid=20919 prio=120 target_cpu=001 :20918 20918 [002] 109866.143702: sched:sched_wakeup: perf:20919 [120] success=1 CPU:001 sleep 20919 [001] 109866.144081: sched:sched_process_exec: filename=/usr/bin/sleep pid=20919 old_pid=20919 sleep 20919 [001] 109866.144408: syscalls:sys_enter_nanosleep: rqtp: 0x7ffc2384fef0, rmtp: 0x00000000 sleep 20919 [001] 109866.144411: sched:sched_stat_runtime: comm=sleep pid=20919 runtime=521249 [ns] vruntime=202919398131 [n> sleep 20919 [001] 109866.144412: sched:sched_switch: sleep:20919 [120] S ==> swapper/1:0 [120] swapper 0 [001] 109867.144568: sched:sched_waking: comm=sleep pid=20919 prio=120 target_cpu=001 swapper 0 [001] 109867.144586: sched:sched_wakeup: sleep:20919 [120] success=1 CPU:001 sleep 20919 [001] 109867.144753: sched:sched_process_exit: comm=sleep pid=20919 prio=120 # # perf script --switch-on syscalls:sys_enter_nanosleep --switch-off syscalls:sys_exit_nanosleep sleep 20919 [001] 109866.144411: sched:sched_stat_runtime: comm=sleep pid=20919 runtime=521249 [ns] vruntime=202919398131 [n> sleep 20919 [001] 109866.144412: sched:sched_switch: sleep:20919 [120] S ==> swapper/1:0 [120] swapper 0 [001] 109867.144568: sched:sched_waking: comm=sleep pid=20919 prio=120 target_cpu=001 swapper 0 [001] 109867.144586: sched:sched_wakeup: sleep:20919 [120] success=1 CPU:001 # # perf script --switch-on syscalls:sys_enter_nanosleep --switch-off syscalls:sys_exit_nanosleep --show-on-off sleep 20919 [001] 109866.144408: syscalls:sys_enter_nanosleep: rqtp: 0x7ffc2384fef0, rmtp: 0x00000000 sleep 20919 [001] 109866.144411: sched:sched_stat_runtime: comm=sleep pid=20919 runtime=521249 [ns] vruntime=202919398131 [n> sleep 20919 [001] 109866.144412: sched:sched_switch: sleep:20919 [120] S ==> swapper/1:0 [120] swapper 0 [001] 109867.144568: sched:sched_waking: comm=sleep pid=20919 prio=120 target_cpu=001 swapper 0 [001] 109867.144586: sched:sched_wakeup: sleep:20919 [120] success=1 CPU:001 sleep 20919 [001] 109867.144614: syscalls:sys_exit_nanosleep: 0x0 # Now think about using this together with 'perf probe' to create custom on/off events in your app :-) Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-li3j01c4tmj9kw6ydsl8swej@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-script.txt | 5 ++++- tools/perf/builtin-script.c | 31 ++++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index 24eea68ee829..2599b057e47b 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt @@ -420,8 +420,11 @@ include::itrace.txt[] --switch-on EVENT_NAME:: Only consider events after this event is found. +--switch-off EVENT_NAME:: + Stop considering events after this event is found. + --show-on-off-events:: - Show the --switch-on event too. + Show the --switch-on/off events too. SEE ALSO -------- diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index fa0cc8b0eccc..b6eed0f7e835 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1617,7 +1617,8 @@ static int perf_sample__fprintf_synth(struct perf_sample *sample, } struct evswitch { - struct evsel *on; + struct evsel *on, + *off; bool discarding; bool show_on_off_events; }; @@ -1820,8 +1821,20 @@ static void process_event(struct perf_script *script, if (!script->evswitch.show_on_off_events) return; + + goto print_it; } + if (script->evswitch.off && !script->evswitch.discarding) { + if (script->evswitch.off != evsel) + goto print_it; + + script->evswitch.discarding = true; + + if (!script->evswitch.show_on_off_events) + return; + } +print_it: ++es->samples; perf_sample__fprintf_start(sample, thread, evsel, @@ -3412,7 +3425,8 @@ int cmd_script(int argc, const char **argv) struct utsname uts; char *script_path = NULL; const char **__argv; - const char *event_switch_on = NULL; + const char *event_switch_on = NULL, + *event_switch_off = NULL; int i, j, err = 0; struct perf_script script = { .tool = { @@ -3557,7 +3571,9 @@ int cmd_script(int argc, const char **argv) OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules, "file", "file saving guest os /proc/modules"), OPT_STRING(0, "switch-on", &event_switch_on, - "event", "Consider events from the first ocurrence of this event"), + "event", "Consider events after the ocurrence of this event"), + OPT_STRING(0, "switch-off", &event_switch_off, + "event", "Stop considering events after the ocurrence of this event"), OPT_BOOLEAN(0, "show-on-off-events", &script.evswitch.show_on_off_events, "Show the on/off switch events, used with --switch-on"), OPT_END() @@ -3894,6 +3910,15 @@ int cmd_script(int argc, const char **argv) script.evswitch.discarding = true; } + if (event_switch_off) { + script.evswitch.off = perf_evlist__find_evsel_by_str(session->evlist, event_switch_off); + if (script.evswitch.off == NULL) { + fprintf(stderr, "switch-off event not found (%s)\n", event_switch_off); + err = -ENOENT; + goto out_delete; + } + } + err = __cmd_script(&script); flush_scripting(); -- cgit v1.2.3-59-g8ed1b From d2360442725fd29b3189887476c57059854a398c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 15 Aug 2019 10:37:24 -0300 Subject: perf evswitch: Move struct to a separate header to use in other tools Now that we see that the simple userspace-based "slicing" of events using delimiter events ("markers") works, lets move it to a separate header to make it available to other tools, next step will be having the switch on/off check done at the PERF_RECORD_SAMPLE processing function moved too. Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-z0cyi9ifzlr37cedr9xztc1k@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 8 +------- tools/perf/util/evswitch.h | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 tools/perf/util/evswitch.h (limited to 'tools') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index b6eed0f7e835..fff02e0d70c4 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -16,6 +16,7 @@ #include "util/trace-event.h" #include "util/evlist.h" #include "util/evsel.h" +#include "util/evswitch.h" #include "util/sort.h" #include "util/data.h" #include "util/auxtrace.h" @@ -1616,13 +1617,6 @@ static int perf_sample__fprintf_synth(struct perf_sample *sample, return 0; } -struct evswitch { - struct evsel *on, - *off; - bool discarding; - bool show_on_off_events; -}; - struct perf_script { struct perf_tool tool; struct perf_session *session; diff --git a/tools/perf/util/evswitch.h b/tools/perf/util/evswitch.h new file mode 100644 index 000000000000..bb88e8002f39 --- /dev/null +++ b/tools/perf/util/evswitch.h @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (C) 2019, Red Hat Inc, Arnaldo Carvalho de Melo +#ifndef __PERF_EVSWITCH_H +#define __PERF_EVSWITCH_H 1 + +#include + +struct evsel; + +struct evswitch { + struct evsel *on, *off; + bool discarding; + bool show_on_off_events; +}; + +#endif /* __PERF_EVSWITCH_H */ -- cgit v1.2.3-59-g8ed1b From 8829e56fa050998164e496d380cd69186ae9b8d0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 15 Aug 2019 11:00:11 -0300 Subject: perf evswitch: Move switch logic to use in other tools Now other tools that want switching can use an evswitch for that, just set it up and add it to the PERF_RECORD_SAMPLE processing function. Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-b1trj1q97qwfv251l66q3noj@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 23 ++--------------------- tools/perf/util/Build | 1 + tools/perf/util/evswitch.c | 31 +++++++++++++++++++++++++++++++ tools/perf/util/evswitch.h | 2 ++ 4 files changed, 36 insertions(+), 21 deletions(-) create mode 100644 tools/perf/util/evswitch.c (limited to 'tools') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index fff02e0d70c4..e7b950e977a9 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1807,28 +1807,9 @@ static void process_event(struct perf_script *script, if (!show_event(sample, evsel, thread, al)) return; - if (script->evswitch.on && script->evswitch.discarding) { - if (script->evswitch.on != evsel) - return; - - script->evswitch.discarding = false; - - if (!script->evswitch.show_on_off_events) - return; - - goto print_it; - } - - if (script->evswitch.off && !script->evswitch.discarding) { - if (script->evswitch.off != evsel) - goto print_it; - - script->evswitch.discarding = true; + if (evswitch__discard(&script->evswitch, evsel)) + return; - if (!script->evswitch.show_on_off_events) - return; - } -print_it: ++es->samples; perf_sample__fprintf_start(sample, thread, evsel, diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 7cda749059a9..b922c8c297ca 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -9,6 +9,7 @@ perf-y += event.o perf-y += evlist.o perf-y += evsel.o perf-y += evsel_fprintf.o +perf-y += evswitch.o perf-y += find_bit.o perf-y += get_current_dir_name.o perf-y += kallsyms.o diff --git a/tools/perf/util/evswitch.c b/tools/perf/util/evswitch.c new file mode 100644 index 000000000000..c87f988d81c8 --- /dev/null +++ b/tools/perf/util/evswitch.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (C) 2019, Red Hat Inc, Arnaldo Carvalho de Melo + +#include "evswitch.h" + +bool evswitch__discard(struct evswitch *evswitch, struct evsel *evsel) +{ + if (evswitch->on && evswitch->discarding) { + if (evswitch->on != evsel) + return true; + + evswitch->discarding = false; + + if (!evswitch->show_on_off_events) + return true; + + return false; + } + + if (evswitch->off && !evswitch->discarding) { + if (evswitch->off != evsel) + return false; + + evswitch->discarding = true; + + if (!evswitch->show_on_off_events) + return true; + } + + return false; +} diff --git a/tools/perf/util/evswitch.h b/tools/perf/util/evswitch.h index bb88e8002f39..bae3a22ad719 100644 --- a/tools/perf/util/evswitch.h +++ b/tools/perf/util/evswitch.h @@ -13,4 +13,6 @@ struct evswitch { bool show_on_off_events; }; +bool evswitch__discard(struct evswitch *evswitch, struct evsel *evsel); + #endif /* __PERF_EVSWITCH_H */ -- cgit v1.2.3-59-g8ed1b From 0b495b121585a1b6ca120fe13f950e2f86ca8197 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 15 Aug 2019 11:11:14 -0300 Subject: perf evswitch: Add the names of on/off events So that we can have macros for the OPT_ entries and also for finding those in an evlist, this way other tools will use this very easily. Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-q0og1xoqqi0w38ve5u0a43k2@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 18 ++++++++---------- tools/perf/util/evswitch.h | 1 + 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index e7b950e977a9..177e4e91b199 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -3400,8 +3400,6 @@ int cmd_script(int argc, const char **argv) struct utsname uts; char *script_path = NULL; const char **__argv; - const char *event_switch_on = NULL, - *event_switch_off = NULL; int i, j, err = 0; struct perf_script script = { .tool = { @@ -3545,9 +3543,9 @@ int cmd_script(int argc, const char **argv) "file", "file saving guest os /proc/kallsyms"), OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules, "file", "file saving guest os /proc/modules"), - OPT_STRING(0, "switch-on", &event_switch_on, + OPT_STRING(0, "switch-on", &script.evswitch.on_name, "event", "Consider events after the ocurrence of this event"), - OPT_STRING(0, "switch-off", &event_switch_off, + OPT_STRING(0, "switch-off", &script.evswitch.off_name, "event", "Stop considering events after the ocurrence of this event"), OPT_BOOLEAN(0, "show-on-off-events", &script.evswitch.show_on_off_events, "Show the on/off switch events, used with --switch-on"), @@ -3875,20 +3873,20 @@ int cmd_script(int argc, const char **argv) script.range_num); } - if (event_switch_on) { - script.evswitch.on = perf_evlist__find_evsel_by_str(session->evlist, event_switch_on); + if (script.evswitch.on_name) { + script.evswitch.on = perf_evlist__find_evsel_by_str(session->evlist, script.evswitch.on_name); if (script.evswitch.on == NULL) { - fprintf(stderr, "switch-on event not found (%s)\n", event_switch_on); + fprintf(stderr, "switch-on event not found (%s)\n", script.evswitch.on_name); err = -ENOENT; goto out_delete; } script.evswitch.discarding = true; } - if (event_switch_off) { - script.evswitch.off = perf_evlist__find_evsel_by_str(session->evlist, event_switch_off); + if (script.evswitch.off_name) { + script.evswitch.off = perf_evlist__find_evsel_by_str(session->evlist, script.evswitch.off_name); if (script.evswitch.off == NULL) { - fprintf(stderr, "switch-off event not found (%s)\n", event_switch_off); + fprintf(stderr, "switch-off event not found (%s)\n", script.evswitch.off_name); err = -ENOENT; goto out_delete; } diff --git a/tools/perf/util/evswitch.h b/tools/perf/util/evswitch.h index bae3a22ad719..891164504080 100644 --- a/tools/perf/util/evswitch.h +++ b/tools/perf/util/evswitch.h @@ -9,6 +9,7 @@ struct evsel; struct evswitch { struct evsel *on, *off; + const char *on_name, *off_name; bool discarding; bool show_on_off_events; }; -- cgit v1.2.3-59-g8ed1b From add3a719c95f0443d563889b4af255b78ba54521 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 15 Aug 2019 11:21:21 -0300 Subject: perf evswitch: Introduce OPTS_EVSWITCH() for cmd line processing All tools will want those, so provide a convenient way to get them. Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-v16pe3sbf3wjmn152u18f649@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 7 +------ tools/perf/util/evswitch.h | 8 ++++++++ 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 177e4e91b199..2a5b8af80e6b 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -3543,12 +3543,7 @@ int cmd_script(int argc, const char **argv) "file", "file saving guest os /proc/kallsyms"), OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules, "file", "file saving guest os /proc/modules"), - OPT_STRING(0, "switch-on", &script.evswitch.on_name, - "event", "Consider events after the ocurrence of this event"), - OPT_STRING(0, "switch-off", &script.evswitch.off_name, - "event", "Stop considering events after the ocurrence of this event"), - OPT_BOOLEAN(0, "show-on-off-events", &script.evswitch.show_on_off_events, - "Show the on/off switch events, used with --switch-on"), + OPTS_EVSWITCH(&script.evswitch), OPT_END() }; const char * const script_subcommands[] = { "record", "report", NULL }; diff --git a/tools/perf/util/evswitch.h b/tools/perf/util/evswitch.h index 891164504080..94220d1bb479 100644 --- a/tools/perf/util/evswitch.h +++ b/tools/perf/util/evswitch.h @@ -16,4 +16,12 @@ struct evswitch { bool evswitch__discard(struct evswitch *evswitch, struct evsel *evsel); +#define OPTS_EVSWITCH(evswitch) \ + OPT_STRING(0, "switch-on", &(evswitch)->on_name, \ + "event", "Consider events after the ocurrence of this event"), \ + OPT_STRING(0, "switch-off", &(evswitch)->off_name, \ + "event", "Stop considering events after the ocurrence of this event"), \ + OPT_BOOLEAN(0, "show-on-off-events", &(evswitch)->show_on_off_events, \ + "Show the on/off switch events, used with --switch-on and --switch-off") + #endif /* __PERF_EVSWITCH_H */ -- cgit v1.2.3-59-g8ed1b From 124e02be72fdff05ab5d7f004a3c0d4061569380 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 15 Aug 2019 11:31:29 -0300 Subject: perf evswitch: Introduce init() method to set the on/off evsels from the command line Another step in having all the boilerplate in just one place to then use in the other tools. Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-snreb1wmwyjei3eefwotxp1l@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 21 +++------------------ tools/perf/util/evswitch.c | 23 +++++++++++++++++++++++ tools/perf/util/evswitch.h | 4 ++++ 3 files changed, 30 insertions(+), 18 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 2a5b8af80e6b..1764efd16cd4 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -3868,24 +3868,9 @@ int cmd_script(int argc, const char **argv) script.range_num); } - if (script.evswitch.on_name) { - script.evswitch.on = perf_evlist__find_evsel_by_str(session->evlist, script.evswitch.on_name); - if (script.evswitch.on == NULL) { - fprintf(stderr, "switch-on event not found (%s)\n", script.evswitch.on_name); - err = -ENOENT; - goto out_delete; - } - script.evswitch.discarding = true; - } - - if (script.evswitch.off_name) { - script.evswitch.off = perf_evlist__find_evsel_by_str(session->evlist, script.evswitch.off_name); - if (script.evswitch.off == NULL) { - fprintf(stderr, "switch-off event not found (%s)\n", script.evswitch.off_name); - err = -ENOENT; - goto out_delete; - } - } + err = evswitch__init(&script.evswitch, session->evlist, stderr); + if (err) + goto out_delete; err = __cmd_script(&script); diff --git a/tools/perf/util/evswitch.c b/tools/perf/util/evswitch.c index c87f988d81c8..b57b5f0816f5 100644 --- a/tools/perf/util/evswitch.c +++ b/tools/perf/util/evswitch.c @@ -2,6 +2,7 @@ // Copyright (C) 2019, Red Hat Inc, Arnaldo Carvalho de Melo #include "evswitch.h" +#include "evlist.h" bool evswitch__discard(struct evswitch *evswitch, struct evsel *evsel) { @@ -29,3 +30,25 @@ bool evswitch__discard(struct evswitch *evswitch, struct evsel *evsel) return false; } + +int evswitch__init(struct evswitch *evswitch, struct evlist *evlist, FILE *fp) +{ + if (evswitch->on_name) { + evswitch->on = perf_evlist__find_evsel_by_str(evlist, evswitch->on_name); + if (evswitch->on == NULL) { + fprintf(fp, "switch-on event not found (%s)\n", evswitch->on_name); + return -ENOENT; + } + evswitch->discarding = true; + } + + if (evswitch->off_name) { + evswitch->off = perf_evlist__find_evsel_by_str(evlist, evswitch->off_name); + if (evswitch->off == NULL) { + fprintf(fp, "switch-off event not found (%s)\n", evswitch->off_name); + return -ENOENT; + } + } + + return 0; +} diff --git a/tools/perf/util/evswitch.h b/tools/perf/util/evswitch.h index 94220d1bb479..fd30460b6218 100644 --- a/tools/perf/util/evswitch.h +++ b/tools/perf/util/evswitch.h @@ -4,8 +4,10 @@ #define __PERF_EVSWITCH_H 1 #include +#include struct evsel; +struct evlist; struct evswitch { struct evsel *on, *off; @@ -14,6 +16,8 @@ struct evswitch { bool show_on_off_events; }; +int evswitch__init(struct evswitch *evswitch, struct evlist *evlist, FILE *fp); + bool evswitch__discard(struct evswitch *evswitch, struct evsel *evsel); #define OPTS_EVSWITCH(evswitch) \ -- cgit v1.2.3-59-g8ed1b From c9a4269930dada68971a4a97f3abf079af8cde4e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 15 Aug 2019 11:35:56 -0300 Subject: perf evswitch: Move enoent error message printing to separate function Allows adding hints there, will be done in followup patch. Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-1kvrdi7weuz3hxycwvarcu6v@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evswitch.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/evswitch.c b/tools/perf/util/evswitch.c index b57b5f0816f5..71daed615a2c 100644 --- a/tools/perf/util/evswitch.c +++ b/tools/perf/util/evswitch.c @@ -31,12 +31,17 @@ bool evswitch__discard(struct evswitch *evswitch, struct evsel *evsel) return false; } +static int evswitch__fprintf_enoent(FILE *fp, const char *evtype, const char *evname) +{ + return fprintf(fp, "ERROR: switch-%s event not found (%s)\n", evtype, evname); +} + int evswitch__init(struct evswitch *evswitch, struct evlist *evlist, FILE *fp) { if (evswitch->on_name) { evswitch->on = perf_evlist__find_evsel_by_str(evlist, evswitch->on_name); if (evswitch->on == NULL) { - fprintf(fp, "switch-on event not found (%s)\n", evswitch->on_name); + evswitch__fprintf_enoent(fp, "on", evswitch->on_name); return -ENOENT; } evswitch->discarding = true; @@ -45,7 +50,7 @@ int evswitch__init(struct evswitch *evswitch, struct evlist *evlist, FILE *fp) if (evswitch->off_name) { evswitch->off = perf_evlist__find_evsel_by_str(evlist, evswitch->off_name); if (evswitch->off == NULL) { - fprintf(fp, "switch-off event not found (%s)\n", evswitch->off_name); + evswitch__fprintf_enoent(fp, "off", evswitch->off_name); return -ENOENT; } } -- cgit v1.2.3-59-g8ed1b From 8b3c9ea7bf8f50ead6787c084cfc6d3a0b1e38aa Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 15 Aug 2019 12:02:13 -0300 Subject: perf evswitch: Add hint when not finding specified on/off events If the user specifies a on or off switch event and it isn't in the perf.data file, provide a hint about how to see the events in the perf.data evlist: # perf script --switch-on=syscall:sys_enter_nanosleep --switch-off=syscalls:sys_exit_nanosleep ERROR: event_on event not found (syscall:sys_enter_nanosleep) HINT: use 'perf evlist' to see the available event names # # perf evlist sched:sched_kthread_stop sched:sched_kthread_stop_ret sched:sched_waking sched:sched_wakeup sched:sched_wakeup_new sched:sched_switch sched:sched_migrate_task sched:sched_process_free sched:sched_process_exit sched:sched_wait_task sched:sched_process_wait sched:sched_process_fork sched:sched_process_exec sched:sched_stat_wait sched:sched_stat_sleep sched:sched_stat_iowait sched:sched_stat_blocked sched:sched_stat_runtime sched:sched_pi_setprio sched:sched_move_numa sched:sched_stick_numa sched:sched_swap_numa sched:sched_wake_idle_without_ipi syscalls:sys_enter_clock_nanosleep syscalls:sys_exit_clock_nanosleep syscalls:sys_enter_nanosleep syscalls:sys_exit_nanosleep # Tip: use 'perf evlist --trace-fields' to show fields for tracepoint events # # perf script --switch-on=syscalls:sys_enter_nanosleep --switch-off=syscalls:sys_exit_nanosleep sleep 20919 [001] 109866.144411: sched:sched_stat_runtime: comm=sleep pid=20919 runtime=521249 [ns] vruntime=202919398131 [ns] sleep 20919 [001] 109866.144412: sched:sched_switch: sleep:20919 [120] S ==> swapper/1:0 [120] swapper 0 [001] 109867.144568: sched:sched_waking: comm=sleep pid=20919 prio=120 target_cpu=001 swapper 0 [001] 109867.144586: sched:sched_wakeup: sleep:20919 [120] success=1 CPU:001 # Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-iijjvdlyad973oskdq8gmi5w@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evswitch.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/evswitch.c b/tools/perf/util/evswitch.c index 71daed615a2c..3ba72f743d3c 100644 --- a/tools/perf/util/evswitch.c +++ b/tools/perf/util/evswitch.c @@ -33,7 +33,9 @@ bool evswitch__discard(struct evswitch *evswitch, struct evsel *evsel) static int evswitch__fprintf_enoent(FILE *fp, const char *evtype, const char *evname) { - return fprintf(fp, "ERROR: switch-%s event not found (%s)\n", evtype, evname); + int printed = fprintf(fp, "ERROR: switch-%s event not found (%s)\n", evtype, evname); + + return printed += fprintf(fp, "HINT: use 'perf evlist' to see the available event names\n"); } int evswitch__init(struct evswitch *evswitch, struct evlist *evlist, FILE *fp) -- cgit v1.2.3-59-g8ed1b From 22ac4318ad95847797de99dccaf059c76cd74efe Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 15 Aug 2019 12:15:39 -0300 Subject: perf trace: Add --switch-on/--switch-off events Just like with 'perf script': # perf trace -e sched:*,syscalls:*sleep* sleep 1 0.000 :28345/28345 sched:sched_waking:comm=perf pid=28346 prio=120 target_cpu=005 0.005 :28345/28345 sched:sched_wakeup:perf:28346 [120] success=1 CPU:005 0.383 sleep/28346 sched:sched_process_exec:filename=/usr/bin/sleep pid=28346 old_pid=28346 0.613 sleep/28346 sched:sched_stat_runtime:comm=sleep pid=28346 runtime=607375 [ns] vruntime=23289041218 [ns] 0.689 sleep/28346 syscalls:sys_enter_nanosleep:rqtp: 0x7ffc491789b0 0.693 sleep/28346 sched:sched_stat_runtime:comm=sleep pid=28346 runtime=72021 [ns] vruntime=23289113239 [ns] 0.694 sleep/28346 sched:sched_switch:sleep:28346 [120] S ==> swapper/5:0 [120] 1000.787 :0/0 sched:sched_waking:comm=sleep pid=28346 prio=120 target_cpu=005 1000.824 :0/0 sched:sched_wakeup:sleep:28346 [120] success=1 CPU:005 1000.908 sleep/28346 syscalls:sys_exit_nanosleep:0x0 1001.218 sleep/28346 sched:sched_process_exit:comm=sleep pid=28346 prio=120 # perf trace -e sched:*,syscalls:*sleep* --switch-on=syscalls:sys_enter_nanosleep sleep 1 0.000 sleep/28349 sched:sched_stat_runtime:comm=sleep pid=28349 runtime=603036 [ns] vruntime=23873537697 [ns] 0.001 sleep/28349 sched:sched_switch:sleep:28349 [120] S ==> swapper/4:0 [120] 1000.392 :0/0 sched:sched_waking:comm=sleep pid=28349 prio=120 target_cpu=004 1000.443 :0/0 sched:sched_wakeup:sleep:28349 [120] success=1 CPU:004 1000.540 sleep/28349 syscalls:sys_exit_nanosleep:0x0 1000.852 sleep/28349 sched:sched_process_exit:comm=sleep pid=28349 prio=120 # perf trace -e sched:*,syscalls:*sleep* --switch-on=syscalls:sys_enter_nanosleep --switch-off=syscalls:sys_exit_nanosleep sleep 1 0.000 sleep/28352 sched:sched_stat_runtime:comm=sleep pid=28352 runtime=610543 [ns] vruntime=24811686681 [ns] 0.001 sleep/28352 sched:sched_switch:sleep:28352 [120] S ==> swapper/0:0 [120] 1000.397 :0/0 sched:sched_waking:comm=sleep pid=28352 prio=120 target_cpu=000 1000.440 :0/0 sched:sched_wakeup:sleep:28352 [120] success=1 CPU:000 # # perf trace -e sched:*,syscalls:*sleep* --switch-on=syscalls:sys_enter_nanosleep --switch-off=syscalls:sys_exit_nanosleep --show-on-off sleep 1 0.000 sleep/28367 syscalls:sys_enter_nanosleep:rqtp: 0x7fffd1a25fc0 0.004 sleep/28367 sched:sched_stat_runtime:comm=sleep pid=28367 runtime=628760 [ns] vruntime=22170052672 [ns] 0.005 sleep/28367 sched:sched_switch:sleep:28367 [120] S ==> swapper/2:0 [120] 1000.367 :0/0 sched:sched_waking:comm=sleep pid=28367 prio=120 target_cpu=002 1000.412 :0/0 sched:sched_wakeup:sleep:28367 [120] success=1 CPU:002 1000.512 sleep/28367 syscalls:sys_exit_nanosleep:0x0 # Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-t3ngpt1brcc1fm9gep9gxm4q@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-trace.txt | 9 +++++++++ tools/perf/builtin-trace.c | 10 ++++++++++ 2 files changed, 19 insertions(+) (limited to 'tools') diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index fc6e43262c41..25b74fdb36fa 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt @@ -176,6 +176,15 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs. only at exit time or when a syscall is interrupted, i.e. in those cases this option is equivalent to the number of lines printed. +--switch-on EVENT_NAME:: + Only consider events after this event is found. + +--switch-off EVENT_NAME:: + Stop considering events after this event is found. + +--show-on-off-events:: + Show the --switch-on/off events too. + --max-stack:: Set the stack depth limit when parsing the callchain, anything beyond the specified depth will be ignored. Note that at this point diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index d553d06a9aeb..bc44ed29e05a 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -27,6 +27,7 @@ #include "util/env.h" #include "util/event.h" #include "util/evlist.h" +#include "util/evswitch.h" #include #include "util/machine.h" #include "util/map.h" @@ -106,6 +107,7 @@ struct trace { unsigned long nr_events; unsigned long nr_events_printed; unsigned long max_events; + struct evswitch evswitch; struct strlist *ev_qualifier; struct { size_t nr; @@ -2680,6 +2682,9 @@ static void trace__handle_event(struct trace *trace, union perf_event *event, st return; } + if (evswitch__discard(&trace->evswitch, evsel)) + return; + trace__set_base_time(trace, evsel, sample); if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT && @@ -4157,6 +4162,7 @@ int cmd_trace(int argc, const char **argv) OPT_UINTEGER('D', "delay", &trace.opts.initial_delay, "ms to wait before starting measurement after program " "start"), + OPTS_EVSWITCH(&trace.evswitch), OPT_END() }; bool __maybe_unused max_stack_user_set = true; @@ -4380,6 +4386,10 @@ init_augmented_syscall_tp: } } + err = evswitch__init(&trace.evswitch, trace.evlist, stderr); + if (err) + goto out_close; + err = target__validate(&trace.opts.target); if (err) { target__strerror(&trace.opts.target, err, bf, sizeof(bf)); -- cgit v1.2.3-59-g8ed1b From 2aafdf5a5786ebbd8ccfe132ed6267c6962c5c3c Mon Sep 17 00:00:00 2001 From: Anders Roxell Date: Thu, 15 Aug 2019 09:58:26 +0200 Subject: selftests: net: tcp_fastopen_backup_key.sh: fix shellcheck issue When running tcp_fastopen_backup_key.sh the following issue was seen in a busybox environment. ./tcp_fastopen_backup_key.sh: line 33: [: -ne: unary operator expected Shellcheck showed the following issue. $ shellcheck tools/testing/selftests/net/tcp_fastopen_backup_key.sh In tools/testing/selftests/net/tcp_fastopen_backup_key.sh line 33: if [ $val -ne 0 ]; then ^-- SC2086: Double quote to prevent globbing and word splitting. Rework to do a string comparison instead. Signed-off-by: Anders Roxell Signed-off-by: David S. Miller --- tools/testing/selftests/net/tcp_fastopen_backup_key.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/tcp_fastopen_backup_key.sh b/tools/testing/selftests/net/tcp_fastopen_backup_key.sh index 41476399e184..f6e65674b83c 100755 --- a/tools/testing/selftests/net/tcp_fastopen_backup_key.sh +++ b/tools/testing/selftests/net/tcp_fastopen_backup_key.sh @@ -30,7 +30,7 @@ do_test() { ip netns exec "${NETNS}" ./tcp_fastopen_backup_key "$1" val=$(ip netns exec "${NETNS}" nstat -az | \ grep TcpExtTCPFastOpenPassiveFail | awk '{print $2}') - if [ $val -ne 0 ]; then + if [ "$val" != 0 ]; then echo "FAIL: TcpExtTCPFastOpenPassiveFail non-zero" return 1 fi -- cgit v1.2.3-59-g8ed1b From d87e5edb4cd7c954b71cfcb9fbfce65eac76e141 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 15 Aug 2019 15:42:28 +0200 Subject: selftests: net: push jq workaround into separate helper Push the jq return value workaround code into a separate helper so it could be used by the rest of the code. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- tools/testing/selftests/net/forwarding/lib.sh | 19 +++++++++++++++++++ tools/testing/selftests/net/forwarding/tc_common.sh | 17 ++++------------- 2 files changed, 23 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh index 9385dc971269..85c587a03c8a 100644 --- a/tools/testing/selftests/net/forwarding/lib.sh +++ b/tools/testing/selftests/net/forwarding/lib.sh @@ -250,6 +250,25 @@ setup_wait() sleep $WAIT_TIME } +cmd_jq() +{ + local cmd=$1 + local jq_exp=$2 + local ret + local output + + output="$($cmd)" + # it the command fails, return error right away + ret=$? + if [[ $ret -ne 0 ]]; then + return $ret + fi + output=$(echo $output | jq -r "$jq_exp") + echo $output + # return success only in case of non-empty output + [ ! -z "$output" ] +} + lldpad_app_wait_set() { local dev=$1; shift diff --git a/tools/testing/selftests/net/forwarding/tc_common.sh b/tools/testing/selftests/net/forwarding/tc_common.sh index 9d3b64a2a264..315e934358d4 100644 --- a/tools/testing/selftests/net/forwarding/tc_common.sh +++ b/tools/testing/selftests/net/forwarding/tc_common.sh @@ -8,18 +8,9 @@ tc_check_packets() local id=$1 local handle=$2 local count=$3 - local ret - output="$(tc -j -s filter show $id)" - # workaround the jq bug which causes jq to return 0 in case input is "" - ret=$? - if [[ $ret -ne 0 ]]; then - return $ret - fi - echo $output | \ - jq -e ".[] \ - | select(.options.handle == $handle) \ - | select(.options.actions[0].stats.packets == $count)" \ - &> /dev/null - return $? + cmd_jq "tc -j -s filter show $id" \ + ".[] | select(.options.handle == $handle) | \ + select(.options.actions[0].stats.packets == $count)" \ + &> /dev/null } -- cgit v1.2.3-59-g8ed1b From dc8a670a87e6240d20c27f015b8c30f4ef811041 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 15 Aug 2019 15:42:29 +0200 Subject: selftests: netdevsim: add devlink params tests Test recently added netdevsim devlink param implementation. Signed-off-by: Jiri Pirko Tested-by: Jakub Kicinski Acked-by: Jakub Kicinski Signed-off-by: David S. Miller --- .../selftests/drivers/net/netdevsim/devlink.sh | 62 +++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh index 9d8baf5d14b3..6828e9404460 100755 --- a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh +++ b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh @@ -3,7 +3,7 @@ lib_dir=$(dirname $0)/../../../net/forwarding -ALL_TESTS="fw_flash_test" +ALL_TESTS="fw_flash_test params_test" NUM_NETIFS=0 source $lib_dir/lib.sh @@ -30,6 +30,66 @@ fw_flash_test() log_test "fw flash test" } +param_get() +{ + local name=$1 + + cmd_jq "devlink dev param show $DL_HANDLE name $name -j" \ + '.[][][].values[] | select(.cmode == "driverinit").value' +} + +param_set() +{ + local name=$1 + local value=$2 + + devlink dev param set $DL_HANDLE name $name cmode driverinit value $value +} + +check_value() +{ + local name=$1 + local phase_name=$2 + local expected_param_value=$3 + local expected_debugfs_value=$4 + local value + + value=$(param_get $name) + check_err $? "Failed to get $name param value" + [ "$value" == "$expected_param_value" ] + check_err $? "Unexpected $phase_name $name param value" + value=$(<$DEBUGFS_DIR/$name) + check_err $? "Failed to get $name debugfs value" + [ "$value" == "$expected_debugfs_value" ] + check_err $? "Unexpected $phase_name $name debugfs value" +} + +params_test() +{ + RET=0 + + local max_macs + local test1 + + check_value max_macs initial 32 32 + check_value test1 initial true Y + + param_set max_macs 16 + check_err $? "Failed to set max_macs param value" + param_set test1 false + check_err $? "Failed to set test1 param value" + + check_value max_macs post-set 16 32 + check_value test1 post-set false Y + + devlink dev reload $DL_HANDLE + + check_value max_macs post-reload 16 16 + check_value test1 post-reload false N + + log_test "params test" +} + setup_prepare() { modprobe netdevsim -- cgit v1.2.3-59-g8ed1b From 5156d7ef6d5e29f98f7302a5ea469fd9fa2af4ad Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 15 Aug 2019 15:46:34 +0200 Subject: selftests: netdevsim: add devlink regions tests Test netdevsim devlink region implementation. Signed-off-by: Jiri Pirko Tested-by: Jakub Kicinski Acked-by: Jakub Kicinski Signed-off-by: David S. Miller --- .../selftests/drivers/net/netdevsim/devlink.sh | 54 +++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh index 6828e9404460..115837355eaf 100755 --- a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh +++ b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh @@ -3,7 +3,7 @@ lib_dir=$(dirname $0)/../../../net/forwarding -ALL_TESTS="fw_flash_test params_test" +ALL_TESTS="fw_flash_test params_test regions_test" NUM_NETIFS=0 source $lib_dir/lib.sh @@ -90,6 +90,58 @@ params_test() log_test "params test" } +check_region_size() +{ + local name=$1 + local size + + size=$(devlink region show $DL_HANDLE/$name -j | jq -e -r '.[][].size') + check_err $? "Failed to get $name region size" + [ $size -eq 32768 ] + check_err $? "Invalid $name region size" +} + +check_region_snapshot_count() +{ + local name=$1 + local phase_name=$2 + local expected_count=$3 + local count + + count=$(devlink region show $DL_HANDLE/$name -j | jq -e -r '.[][].snapshot | length') + [ $count -eq $expected_count ] + check_err $? "Unexpected $phase_name snapshot count" +} + +regions_test() +{ + RET=0 + + local count + + check_region_size dummy + check_region_snapshot_count dummy initial 0 + + echo ""> $DEBUGFS_DIR/take_snapshot + check_err $? "Failed to take first dummy region snapshot" + check_region_snapshot_count dummy post-first-snapshot 1 + + echo ""> $DEBUGFS_DIR/take_snapshot + check_err $? "Failed to take second dummy region snapshot" + check_region_snapshot_count dummy post-second-snapshot 2 + + echo ""> $DEBUGFS_DIR/take_snapshot + check_err $? "Failed to take third dummy region snapshot" + check_region_snapshot_count dummy post-third-snapshot 3 + + devlink region del $DL_HANDLE/dummy snapshot 1 + check_err $? "Failed to delete first dummy region snapshot" + + check_region_snapshot_count dummy post-first-delete 2 + + log_test "regions test" +} + setup_prepare() { modprobe netdevsim -- cgit v1.2.3-59-g8ed1b From 2f53ae347f597842683c4bde5b9ce76f5efae247 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 15 Aug 2019 16:03:26 -0300 Subject: perf top: Add --switch-on/--switch-off events Just like 'perf trace' and 'perf script', should be useful for instance to only consider samples after the initialization phase of some workload. The man page has some examples and considerations about its current interface, that still doesn't handle the on/off events in a special way, behaving just like when multiple events are specified, i.e.: - In non-group mode (when the event list is not enclosed in {}) show a a menu to allow choosing which event the user wants to see in the histograms browser - In group mode, be it using {} or asking for --group, show one column per event. Try for instance: # perf top -e '{cycles,instructions,probe:icmp_rcv}' --switch-on=probe:icmp_rcv Replace probe:icmp_rcv, that I put in place using: # perf probe icmp_rcv:59 To hit when broadcast packets arrive, with a probe installed after an initialization phase is over or after some other point of interest, some garbage collection, etc, and also use --switch-off, for instance, on a probe installed after said garbage collection is over. Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-c7q7qjeqtyvc9mkeipxza6ne@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-top.txt | 38 +++++++++++++++++++++++++++++++++++ tools/perf/builtin-top.c | 10 ++++++++- tools/perf/util/top.h | 2 ++ 3 files changed, 49 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt index cfea87c6f38e..5596129a71cf 100644 --- a/tools/perf/Documentation/perf-top.txt +++ b/tools/perf/Documentation/perf-top.txt @@ -266,6 +266,44 @@ Default is to monitor all CPUS. Record events of type PERF_RECORD_NAMESPACES and display it with the 'cgroup_id' sort key. +--switch-on EVENT_NAME:: + Only consider events after this event is found. + + E.g.: + + Find out where broadcast packets are handled + + perf probe -L icmp_rcv + + Insert a probe there: + + perf probe icmp_rcv:59 + + Start perf top and ask it to only consider the cycles events when a + broadcast packet arrives This will show a menu with two entries and + will start counting when a broadcast packet arrives: + + perf top -e cycles,probe:icmp_rcv --switch-on=probe:icmp_rcv + + Alternatively one can ask for --group and then two overhead columns + will appear, the first for cycles and the second for the switch-on event. + + perf top --group -e cycles,probe:icmp_rcv --switch-on=probe:icmp_rcv + + This may be interesting to measure a workload only after some initialization + phase is over, i.e. insert a perf probe at that point and use the above + examples replacing probe:icmp_rcv with the just-after-init probe. + +--switch-off EVENT_NAME:: + Stop considering events after this event is found. + +--show-on-off-events:: + Show the --switch-on/off events too. This has no effect in 'perf top' now + but probably we'll make the default not to show the switch-on/off events + on the --group mode and if there is only one event besides the off/on ones, + go straight to the histogram browser, just like 'perf top' with no events + explicitely specified does. + INTERACTIVE PROMPTING KEYS -------------------------- diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 78e7efc597a6..5970723cd55a 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1148,8 +1148,11 @@ static int deliver_event(struct ordered_events *qe, evsel = perf_evlist__id2evsel(session->evlist, sample.id); assert(evsel != NULL); - if (event->header.type == PERF_RECORD_SAMPLE) + if (event->header.type == PERF_RECORD_SAMPLE) { + if (evswitch__discard(&top->evswitch, evsel)) + return 0; ++top->samples; + } switch (sample.cpumode) { case PERF_RECORD_MISC_USER: @@ -1534,6 +1537,7 @@ int cmd_top(int argc, const char **argv) "number of thread to run event synthesize"), OPT_BOOLEAN(0, "namespaces", &opts->record_namespaces, "Record namespaces events"), + OPTS_EVSWITCH(&top.evswitch), OPT_END() }; struct evlist *sb_evlist = NULL; @@ -1567,6 +1571,10 @@ int cmd_top(int argc, const char **argv) goto out_delete_evlist; } + status = evswitch__init(&top.evswitch, top.evlist, stderr); + if (status) + goto out_delete_evlist; + if (symbol_conf.report_hierarchy) { /* disable incompatible options */ symbol_conf.event_group = false; diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h index 2023e0bf6165..dc4bb6e52a83 100644 --- a/tools/perf/util/top.h +++ b/tools/perf/util/top.h @@ -3,6 +3,7 @@ #define __PERF_TOP_H 1 #include "tool.h" +#include "evswitch.h" #include "annotate.h" #include #include @@ -18,6 +19,7 @@ struct perf_top { struct evlist *evlist; struct record_opts record_opts; struct annotation_options annotation_opts; + struct evswitch evswitch; /* * Symbols will be added here in perf_event__process_sample and will * get out after decayed. -- cgit v1.2.3-59-g8ed1b From 04949ccc273e14d28aa004ac6954af0898ca3d12 Mon Sep 17 00:00:00 2001 From: "Daniel T. Lee" Date: Tue, 13 Aug 2019 11:46:18 +0900 Subject: tools: bpftool: add net attach command to attach XDP on interface By this commit, using `bpftool net attach`, user can attach XDP prog on interface. New type of enum 'net_attach_type' has been made, as stat ted at cover-letter, the meaning of 'attach' is, prog will be attached on interface. With 'overwrite' option at argument, attached XDP program could be replaced. Added new helper 'net_parse_dev' to parse the network device at argument. BPF prog will be attached through libbpf 'bpf_set_link_xdp_fd'. Acked-by: Yonghong Song Signed-off-by: Daniel T. Lee Signed-off-by: Alexei Starovoitov --- tools/bpf/bpftool/net.c | 136 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 129 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c index 67e99c56bc88..33222ca1060e 100644 --- a/tools/bpf/bpftool/net.c +++ b/tools/bpf/bpftool/net.c @@ -55,6 +55,35 @@ struct bpf_attach_info { __u32 flow_dissector_id; }; +enum net_attach_type { + NET_ATTACH_TYPE_XDP, + NET_ATTACH_TYPE_XDP_GENERIC, + NET_ATTACH_TYPE_XDP_DRIVER, + NET_ATTACH_TYPE_XDP_OFFLOAD, +}; + +static const char * const attach_type_strings[] = { + [NET_ATTACH_TYPE_XDP] = "xdp", + [NET_ATTACH_TYPE_XDP_GENERIC] = "xdpgeneric", + [NET_ATTACH_TYPE_XDP_DRIVER] = "xdpdrv", + [NET_ATTACH_TYPE_XDP_OFFLOAD] = "xdpoffload", +}; + +const size_t net_attach_type_size = ARRAY_SIZE(attach_type_strings); + +static enum net_attach_type parse_attach_type(const char *str) +{ + enum net_attach_type type; + + for (type = 0; type < net_attach_type_size; type++) { + if (attach_type_strings[type] && + is_prefix(str, attach_type_strings[type])) + return type; + } + + return net_attach_type_size; +} + static int dump_link_nlmsg(void *cookie, void *msg, struct nlattr **tb) { struct bpf_netdev_t *netinfo = cookie; @@ -223,6 +252,97 @@ static int query_flow_dissector(struct bpf_attach_info *attach_info) return 0; } +static int net_parse_dev(int *argc, char ***argv) +{ + int ifindex; + + if (is_prefix(**argv, "dev")) { + NEXT_ARGP(); + + ifindex = if_nametoindex(**argv); + if (!ifindex) + p_err("invalid devname %s", **argv); + + NEXT_ARGP(); + } else { + p_err("expected 'dev', got: '%s'?", **argv); + return -1; + } + + return ifindex; +} + +static int do_attach_detach_xdp(int progfd, enum net_attach_type attach_type, + int ifindex, bool overwrite) +{ + __u32 flags = 0; + + if (!overwrite) + flags = XDP_FLAGS_UPDATE_IF_NOEXIST; + if (attach_type == NET_ATTACH_TYPE_XDP_GENERIC) + flags |= XDP_FLAGS_SKB_MODE; + if (attach_type == NET_ATTACH_TYPE_XDP_DRIVER) + flags |= XDP_FLAGS_DRV_MODE; + if (attach_type == NET_ATTACH_TYPE_XDP_OFFLOAD) + flags |= XDP_FLAGS_HW_MODE; + + return bpf_set_link_xdp_fd(ifindex, progfd, flags); +} + +static int do_attach(int argc, char **argv) +{ + enum net_attach_type attach_type; + int progfd, ifindex, err = 0; + bool overwrite = false; + + /* parse attach args */ + if (!REQ_ARGS(5)) + return -EINVAL; + + attach_type = parse_attach_type(*argv); + if (attach_type == net_attach_type_size) { + p_err("invalid net attach/detach type: %s", *argv); + return -EINVAL; + } + NEXT_ARG(); + + progfd = prog_parse_fd(&argc, &argv); + if (progfd < 0) + return -EINVAL; + + ifindex = net_parse_dev(&argc, &argv); + if (ifindex < 1) { + close(progfd); + return -EINVAL; + } + + if (argc) { + if (is_prefix(*argv, "overwrite")) { + overwrite = true; + } else { + p_err("expected 'overwrite', got: '%s'?", *argv); + close(progfd); + return -EINVAL; + } + } + + /* attach xdp prog */ + if (is_prefix("xdp", attach_type_strings[attach_type])) + err = do_attach_detach_xdp(progfd, attach_type, ifindex, + overwrite); + + if (err < 0) { + p_err("interface %s attach failed: %s", + attach_type_strings[attach_type], strerror(-err)); + return err; + } + + if (json_output) + jsonw_null(json_wtr); + + return 0; +} + static int do_show(int argc, char **argv) { struct bpf_attach_info attach_info = {}; @@ -232,13 +352,9 @@ static int do_show(int argc, char **argv) char err_buf[256]; if (argc == 2) { - if (strcmp(argv[0], "dev") != 0) - usage(); - filter_idx = if_nametoindex(argv[1]); - if (filter_idx == 0) { - fprintf(stderr, "invalid dev name %s\n", argv[1]); + filter_idx = net_parse_dev(&argc, &argv); + if (filter_idx < 1) return -1; - } } else if (argc != 0) { usage(); } @@ -305,13 +421,18 @@ static int do_help(int argc, char **argv) fprintf(stderr, "Usage: %s %s { show | list } [dev ]\n" + " %s %s attach ATTACH_TYPE PROG dev [ overwrite ]\n" " %s %s help\n" + "\n" + " " HELP_SPEC_PROGRAM "\n" + " ATTACH_TYPE := { xdp | xdpgeneric | xdpdrv | xdpoffload }\n" + "\n" "Note: Only xdp and tc attachments are supported now.\n" " For progs attached to cgroups, use \"bpftool cgroup\"\n" " to dump program attachments. For program types\n" " sk_{filter,skb,msg,reuseport} and lwt/seg6, please\n" " consult iproute2.\n", - bin_name, argv[-2], bin_name, argv[-2]); + bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2]); return 0; } @@ -319,6 +440,7 @@ static int do_help(int argc, char **argv) static const struct cmd cmds[] = { { "show", do_show }, { "list", do_show }, + { "attach", do_attach }, { "help", do_help }, { 0 } }; -- cgit v1.2.3-59-g8ed1b From 37c7f863ba92f0a7aa8bdfde9dfb6c392393fb83 Mon Sep 17 00:00:00 2001 From: "Daniel T. Lee" Date: Tue, 13 Aug 2019 11:46:19 +0900 Subject: tools: bpftool: add net detach command to detach XDP on interface By this commit, using `bpftool net detach`, the attached XDP prog can be detached. Detaching the BPF prog will be done through libbpf 'bpf_set_link_xdp_fd' with the progfd set to -1. Acked-by: Yonghong Song Signed-off-by: Daniel T. Lee Signed-off-by: Alexei Starovoitov --- tools/bpf/bpftool/net.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c index 33222ca1060e..a213a9b7f69c 100644 --- a/tools/bpf/bpftool/net.c +++ b/tools/bpf/bpftool/net.c @@ -343,6 +343,43 @@ static int do_attach(int argc, char **argv) return 0; } +static int do_detach(int argc, char **argv) +{ + enum net_attach_type attach_type; + int progfd, ifindex, err = 0; + + /* parse detach args */ + if (!REQ_ARGS(3)) + return -EINVAL; + + attach_type = parse_attach_type(*argv); + if (attach_type == net_attach_type_size) { + p_err("invalid net attach/detach type: %s", *argv); + return -EINVAL; + } + NEXT_ARG(); + + ifindex = net_parse_dev(&argc, &argv); + if (ifindex < 1) + return -EINVAL; + + /* detach xdp prog */ + progfd = -1; + if (is_prefix("xdp", attach_type_strings[attach_type])) + err = do_attach_detach_xdp(progfd, attach_type, ifindex, NULL); + + if (err < 0) { + p_err("interface %s detach failed: %s", + attach_type_strings[attach_type], strerror(-err)); + return err; + } + + if (json_output) + jsonw_null(json_wtr); + + return 0; +} + static int do_show(int argc, char **argv) { struct bpf_attach_info attach_info = {}; @@ -422,6 +459,7 @@ static int do_help(int argc, char **argv) fprintf(stderr, "Usage: %s %s { show | list } [dev ]\n" " %s %s attach ATTACH_TYPE PROG dev [ overwrite ]\n" + " %s %s detach ATTACH_TYPE dev \n" " %s %s help\n" "\n" " " HELP_SPEC_PROGRAM "\n" @@ -432,7 +470,8 @@ static int do_help(int argc, char **argv) " to dump program attachments. For program types\n" " sk_{filter,skb,msg,reuseport} and lwt/seg6, please\n" " consult iproute2.\n", - bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2]); + bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], + bin_name, argv[-2]); return 0; } @@ -441,6 +480,7 @@ static const struct cmd cmds[] = { { "show", do_show }, { "list", do_show }, { "attach", do_attach }, + { "detach", do_detach }, { "help", do_help }, { 0 } }; -- cgit v1.2.3-59-g8ed1b From 10a708c24a31ae1be1ea23d1c38da2691d1fd65c Mon Sep 17 00:00:00 2001 From: "Daniel T. Lee" Date: Tue, 13 Aug 2019 11:46:20 +0900 Subject: tools: bpftool: add bash-completion for net attach/detach This commit adds bash-completion for new "net attach/detach" subcommand for attaching XDP program on interface. Signed-off-by: Daniel T. Lee Signed-off-by: Alexei Starovoitov --- tools/bpf/bpftool/bash-completion/bpftool | 65 ++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool index df16c5415444..4549fd424069 100644 --- a/tools/bpf/bpftool/bash-completion/bpftool +++ b/tools/bpf/bpftool/bash-completion/bpftool @@ -201,6 +201,10 @@ _bpftool() _bpftool_get_prog_tags return 0 ;; + dev) + _sysfs_get_netdevs + return 0 + ;; file|pinned) _filedir return 0 @@ -399,10 +403,6 @@ _bpftool() _filedir return 0 ;; - dev) - _sysfs_get_netdevs - return 0 - ;; *) COMPREPLY=( $( compgen -W "map" -- "$cur" ) ) _bpftool_once_attr 'type' @@ -498,10 +498,6 @@ _bpftool() key|value|flags|name|entries) return 0 ;; - dev) - _sysfs_get_netdevs - return 0 - ;; *) _bpftool_once_attr 'type' _bpftool_once_attr 'key' @@ -778,18 +774,67 @@ _bpftool() esac ;; net) + local PROG_TYPE='id pinned tag' + local ATTACH_TYPES='xdp xdpgeneric xdpdrv xdpoffload' case $command in + show|list) + [[ $prev != "$command" ]] && return 0 + COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) ) + return 0 + ;; + attach) + case $cword in + 3) + COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- "$cur" ) ) + return 0 + ;; + 4) + COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) ) + return 0 + ;; + 5) + case $prev in + id) + _bpftool_get_prog_ids + ;; + pinned) + _filedir + ;; + esac + return 0 + ;; + 6) + COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) ) + return 0 + ;; + 8) + _bpftool_once_attr 'overwrite' + return 0 + ;; + esac + ;; + detach) + case $cword in + 3) + COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- "$cur" ) ) + return 0 + ;; + 4) + COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) ) + return 0 + ;; + esac + ;; *) [[ $prev == $object ]] && \ COMPREPLY=( $( compgen -W 'help \ - show list' -- "$cur" ) ) + show list attach detach' -- "$cur" ) ) ;; esac ;; feature) case $command in probe) - [[ $prev == "dev" ]] && _sysfs_get_netdevs && return 0 [[ $prev == "prefix" ]] && return 0 if _bpftool_search_list 'macros'; then COMPREPLY+=( $( compgen -W 'prefix' -- "$cur" ) ) -- cgit v1.2.3-59-g8ed1b From cb9d9968661662a9743e50a32006d5e9d732d346 Mon Sep 17 00:00:00 2001 From: "Daniel T. Lee" Date: Tue, 13 Aug 2019 11:46:21 +0900 Subject: tools: bpftool: add documentation for net attach/detach Since, new sub-command 'net attach/detach' has been added for attaching XDP program on interface, this commit documents usage and sample output of `net attach/detach`. Signed-off-by: Daniel T. Lee Signed-off-by: Alexei Starovoitov --- tools/bpf/bpftool/Documentation/bpftool-net.rst | 57 +++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/Documentation/bpftool-net.rst b/tools/bpf/bpftool/Documentation/bpftool-net.rst index d8e5237a2085..8651b00b81ea 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-net.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-net.rst @@ -15,17 +15,22 @@ SYNOPSIS *OPTIONS* := { [{ **-j** | **--json** }] [{ **-p** | **--pretty** }] } *COMMANDS* := - { **show** | **list** } [ **dev** name ] | **help** + { **show** | **list** | **attach** | **detach** | **help** } NET COMMANDS ============ -| **bpftool** **net { show | list } [ dev name ]** +| **bpftool** **net { show | list }** [ **dev** *NAME* ] +| **bpftool** **net attach** *ATTACH_TYPE* *PROG* **dev** *NAME* [ **overwrite** ] +| **bpftool** **net detach** *ATTACH_TYPE* **dev** *NAME* | **bpftool** **net help** +| +| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* } +| *ATTACH_TYPE* := { **xdp** | **xdpgeneric** | **xdpdrv** | **xdpoffload** } DESCRIPTION =========== - **bpftool net { show | list } [ dev name ]** + **bpftool net { show | list }** [ **dev** *NAME* ] List bpf program attachments in the kernel networking subsystem. Currently, only device driver xdp attachments and tc filter @@ -47,6 +52,24 @@ DESCRIPTION all bpf programs attached to non clsact qdiscs, and finally all bpf programs attached to root and clsact qdisc. + **bpftool** **net attach** *ATTACH_TYPE* *PROG* **dev** *NAME* [ **overwrite** ] + Attach bpf program *PROG* to network interface *NAME* with + type specified by *ATTACH_TYPE*. Previously attached bpf program + can be replaced by the command used with **overwrite** option. + Currently, only XDP-related modes are supported for *ATTACH_TYPE*. + + *ATTACH_TYPE* can be of: + **xdp** - try native XDP and fallback to generic XDP if NIC driver does not support it; + **xdpgeneric** - Generic XDP. runs at generic XDP hook when packet already enters receive path as skb; + **xdpdrv** - Native XDP. runs earliest point in driver's receive path; + **xdpoffload** - Offload XDP. runs directly on NIC on each packet reception; + + **bpftool** **net detach** *ATTACH_TYPE* **dev** *NAME* + Detach bpf program attached to network interface *NAME* with + type specified by *ATTACH_TYPE*. To detach bpf program, same + *ATTACH_TYPE* previously used for attach must be specified. + Currently, only XDP-related modes are supported for *ATTACH_TYPE*. + **bpftool net help** Print short help message. @@ -137,6 +160,34 @@ EXAMPLES } ] +| +| **# bpftool net attach xdpdrv id 16 dev enp6s0np0** +| **# bpftool net** + +:: + + xdp: + enp6s0np0(4) driver id 16 + +| +| **# bpftool net attach xdpdrv id 16 dev enp6s0np0** +| **# bpftool net attach xdpdrv id 20 dev enp6s0np0 overwrite** +| **# bpftool net** + +:: + + xdp: + enp6s0np0(4) driver id 20 + +| +| **# bpftool net attach xdpdrv id 16 dev enp6s0np0** +| **# bpftool net detach xdpdrv dev enp6s0np0** +| **# bpftool net** + +:: + + xdp: + SEE ALSO ======== -- cgit v1.2.3-59-g8ed1b From dadb81d0afe732a7670f7c1bd287dada163a9f2f Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 14 Aug 2019 13:05:48 -0700 Subject: libbpf: make libbpf.map source of truth for libbpf version Currently libbpf version is specified in 2 places: libbpf.map and Makefile. They easily get out of sync and it's very easy to update one, but forget to update another one. In addition, Github projection of libbpf has to maintain its own version which has to be remembered to be kept in sync manually, which is very error-prone approach. This patch makes libbpf.map a source of truth for libbpf version and uses shell invocation to parse out correct full and major libbpf version to use during build. Now we need to make sure that once new release cycle starts, we need to add (initially) empty section to libbpf.map with correct latest version. This also will make it possible to keep Github projection consistent with kernel sources version of libbpf by adopting similar parsing of version from libbpf.map. v2->v3: - grep -o + sort -rV (Andrey); v1->v2: - eager version vars evaluation (Jakub); - simplified version regex (Andrey); Cc: Andrey Ignatov Signed-off-by: Andrii Nakryiko Acked-by: Andrey Ignatov Signed-off-by: Alexei Starovoitov --- tools/lib/bpf/Makefile | 20 ++++++++------------ tools/lib/bpf/libbpf.map | 3 +++ 2 files changed, 11 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index 9312066a1ae3..148a27164189 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile @@ -1,9 +1,10 @@ # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) # Most of this file is copied from tools/lib/traceevent/Makefile -BPF_VERSION = 0 -BPF_PATCHLEVEL = 0 -BPF_EXTRAVERSION = 4 +LIBBPF_VERSION := $(shell \ + grep -oE '^LIBBPF_([0-9.]+)' libbpf.map | \ + sort -rV | head -n1 | cut -d'_' -f2) +LIBBPF_MAJOR_VERSION := $(firstword $(subst ., ,$(LIBBPF_VERSION))) MAKEFLAGS += --no-print-directory @@ -79,15 +80,9 @@ export prefix libdir src obj libdir_SQ = $(subst ','\'',$(libdir)) libdir_relative_SQ = $(subst ','\'',$(libdir_relative)) -VERSION = $(BPF_VERSION) -PATCHLEVEL = $(BPF_PATCHLEVEL) -EXTRAVERSION = $(BPF_EXTRAVERSION) - OBJ = $@ N = -LIBBPF_VERSION = $(BPF_VERSION).$(BPF_PATCHLEVEL).$(BPF_EXTRAVERSION) - LIB_TARGET = libbpf.a libbpf.so.$(LIBBPF_VERSION) LIB_FILE = libbpf.a libbpf.so* PC_FILE = libbpf.pc @@ -178,10 +173,10 @@ $(BPF_IN): force elfdep bpfdep $(OUTPUT)libbpf.so: $(OUTPUT)libbpf.so.$(LIBBPF_VERSION) $(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $(BPF_IN) - $(QUIET_LINK)$(CC) --shared -Wl,-soname,libbpf.so.$(VERSION) \ + $(QUIET_LINK)$(CC) --shared -Wl,-soname,libbpf.so.$(LIBBPF_MAJOR_VERSION) \ -Wl,--version-script=$(VERSION_SCRIPT) $^ -lelf -o $@ @ln -sf $(@F) $(OUTPUT)libbpf.so - @ln -sf $(@F) $(OUTPUT)libbpf.so.$(VERSION) + @ln -sf $(@F) $(OUTPUT)libbpf.so.$(LIBBPF_MAJOR_VERSION) $(OUTPUT)libbpf.a: $(BPF_IN) $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ @@ -257,7 +252,8 @@ config-clean: clean: $(call QUIET_CLEAN, libbpf) $(RM) $(TARGETS) $(CXX_TEST_TARGET) \ - *.o *~ *.a *.so *.so.$(VERSION) .*.d .*.cmd *.pc LIBBPF-CFLAGS + *.o *~ *.a *.so *.so.$(LIBBPF_MAJOR_VERSION) .*.d .*.cmd \ + *.pc LIBBPF-CFLAGS $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map index f9d316e873d8..4e72df8e98ba 100644 --- a/tools/lib/bpf/libbpf.map +++ b/tools/lib/bpf/libbpf.map @@ -184,3 +184,6 @@ LIBBPF_0.0.4 { perf_buffer__new_raw; perf_buffer__poll; } LIBBPF_0.0.3; + +LIBBPF_0.0.5 { +} LIBBPF_0.0.4; -- cgit v1.2.3-59-g8ed1b From 9def249dc8409ffc1f5a1d7195f1c462f2b49c07 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Thu, 15 Aug 2019 15:32:15 +0100 Subject: tools: bpftool: fix arguments for p_err() in do_event_pipe() The last argument passed to some calls to the p_err() functions is not correct, it should be "*argv" instead of "**argv". This may lead to a segmentation fault error if CPU IDs or indices from the command line cannot be parsed correctly. Let's fix this. Fixes: f412eed9dfde ("tools: bpftool: add simple perf event output reader") Signed-off-by: Quentin Monnet Reviewed-by: Jakub Kicinski Signed-off-by: Alexei Starovoitov --- tools/bpf/bpftool/map_perf_ring.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/map_perf_ring.c b/tools/bpf/bpftool/map_perf_ring.c index 3f108ab17797..4c5531d1a450 100644 --- a/tools/bpf/bpftool/map_perf_ring.c +++ b/tools/bpf/bpftool/map_perf_ring.c @@ -157,7 +157,7 @@ int do_event_pipe(int argc, char **argv) NEXT_ARG(); ctx.cpu = strtoul(*argv, &endptr, 0); if (*endptr) { - p_err("can't parse %s as CPU ID", **argv); + p_err("can't parse %s as CPU ID", *argv); goto err_close_map; } @@ -168,7 +168,7 @@ int do_event_pipe(int argc, char **argv) NEXT_ARG(); ctx.idx = strtoul(*argv, &endptr, 0); if (*endptr) { - p_err("can't parse %s as index", **argv); + p_err("can't parse %s as index", *argv); goto err_close_map; } -- cgit v1.2.3-59-g8ed1b From 22c349e8db89df86804d3ba23cef037ccd44a8bf Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Thu, 15 Aug 2019 15:32:16 +0100 Subject: tools: bpftool: fix format strings and arguments for jsonw_printf() There are some mismatches between format strings and arguments passed to jsonw_printf() in the BTF dumper for bpftool, which seems harmless but may result in warnings if the "__printf()" attribute is used correctly for jsonw_printf(). Let's fix relevant format strings and type cast. Fixes: b12d6ec09730 ("bpf: btf: add btf print functionality") Signed-off-by: Quentin Monnet Reviewed-by: Jakub Kicinski Signed-off-by: Alexei Starovoitov --- tools/bpf/bpftool/btf_dumper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c index 8cafb9b31467..d66131f69689 100644 --- a/tools/bpf/bpftool/btf_dumper.c +++ b/tools/bpf/bpftool/btf_dumper.c @@ -26,9 +26,9 @@ static void btf_dumper_ptr(const void *data, json_writer_t *jw, bool is_plain_text) { if (is_plain_text) - jsonw_printf(jw, "%p", *(unsigned long *)data); + jsonw_printf(jw, "%p", data); else - jsonw_printf(jw, "%u", *(unsigned long *)data); + jsonw_printf(jw, "%lu", *(unsigned long *)data); } static int btf_dumper_modifier(const struct btf_dumper *d, __u32 type_id, @@ -216,7 +216,7 @@ static int btf_dumper_int(const struct btf_type *t, __u8 bit_offset, switch (BTF_INT_ENCODING(*int_type)) { case 0: if (BTF_INT_BITS(*int_type) == 64) - jsonw_printf(jw, "%lu", *(__u64 *)data); + jsonw_printf(jw, "%llu", *(__u64 *)data); else if (BTF_INT_BITS(*int_type) == 32) jsonw_printf(jw, "%u", *(__u32 *)data); else if (BTF_INT_BITS(*int_type) == 16) @@ -229,7 +229,7 @@ static int btf_dumper_int(const struct btf_type *t, __u8 bit_offset, break; case BTF_INT_SIGNED: if (BTF_INT_BITS(*int_type) == 64) - jsonw_printf(jw, "%ld", *(long long *)data); + jsonw_printf(jw, "%lld", *(long long *)data); else if (BTF_INT_BITS(*int_type) == 32) jsonw_printf(jw, "%d", *(int *)data); else if (BTF_INT_BITS(*int_type) == 16) -- cgit v1.2.3-59-g8ed1b From ed4a3983cd3eb93aaf80de8d8a36efed808acff2 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Thu, 15 Aug 2019 15:32:17 +0100 Subject: tools: bpftool: fix argument for p_err() in BTF do_dump() The last argument passed to one call to the p_err() function is not correct, it should be "*argv" instead of "**argv". This may lead to a segmentation fault error if BTF id cannot be parsed correctly. Let's fix this. Fixes: c93cc69004dt ("bpftool: add ability to dump BTF types") Signed-off-by: Quentin Monnet Reviewed-by: Jakub Kicinski Signed-off-by: Alexei Starovoitov --- tools/bpf/bpftool/btf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c index 1b8ec91899e6..8805637f1a7e 100644 --- a/tools/bpf/bpftool/btf.c +++ b/tools/bpf/bpftool/btf.c @@ -449,7 +449,7 @@ static int do_dump(int argc, char **argv) btf_id = strtoul(*argv, &endptr, 0); if (*endptr) { - p_err("can't parse %s as ID", **argv); + p_err("can't parse %s as ID", *argv); return -1; } NEXT_ARG(); -- cgit v1.2.3-59-g8ed1b From 8a15d5ced8c626c0331974c7281c1d651f7b0d83 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Thu, 15 Aug 2019 15:32:18 +0100 Subject: tools: bpftool: fix format string for p_err() in query_flow_dissector() The format string passed to one call to the p_err() function in query_flow_dissector() does not match the value that should be printed, resulting in some garbage integer being printed instead of strerror(errno) if /proc/self/ns/net cannot be open. Let's fix the format string. Fixes: 7f0c57fec80f ("bpftool: show flow_dissector attachment status") Signed-off-by: Quentin Monnet Reviewed-by: Jakub Kicinski Signed-off-by: Alexei Starovoitov --- tools/bpf/bpftool/net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c index a213a9b7f69c..4f52d3151616 100644 --- a/tools/bpf/bpftool/net.c +++ b/tools/bpf/bpftool/net.c @@ -226,7 +226,7 @@ static int query_flow_dissector(struct bpf_attach_info *attach_info) fd = open("/proc/self/ns/net", O_RDONLY); if (fd < 0) { - p_err("can't open /proc/self/ns/net: %d", + p_err("can't open /proc/self/ns/net: %s", strerror(errno)); return -1; } -- cgit v1.2.3-59-g8ed1b From b0ead6d75a5b335287337e602e6b815e1115481c Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Thu, 15 Aug 2019 15:32:19 +0100 Subject: tools: bpftool: fix format string for p_err() in detect_common_prefix() There is one call to the p_err() function in detect_common_prefix() where the message to print is passed directly as the first argument, without using a format string. This is harmless, but may trigger warnings if the "__printf()" attribute is used correctly for the p_err() function. Let's fix it by using a "%s" format string. Fixes: ba95c7452439 ("tools: bpftool: add "prog run" subcommand to test-run programs") Signed-off-by: Quentin Monnet Reviewed-by: Jakub Kicinski Signed-off-by: Alexei Starovoitov --- tools/bpf/bpftool/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c index e916ff25697f..93d008687020 100644 --- a/tools/bpf/bpftool/main.c +++ b/tools/bpf/bpftool/main.c @@ -139,7 +139,7 @@ int detect_common_prefix(const char *arg, ...) strncat(msg, "'", sizeof(msg) - strlen(msg) - 1); if (count >= 2) { - p_err(msg); + p_err("%s", msg); return -1; } -- cgit v1.2.3-59-g8ed1b From 8918dc42dc85ba6981028f65a989c478eb80bc02 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Thu, 15 Aug 2019 15:32:20 +0100 Subject: tools: bpftool: move "__printf()" attributes to header file Some functions in bpftool have a "__printf()" format attributes to tell the compiler they should expect printf()-like arguments. But because these attributes are not used for the function prototypes in the header files, the compiler does not run the checks everywhere the functions are used, and some mistakes on format string and corresponding arguments slipped in over time. Let's move the __printf() attributes to the correct places. Note: We add guards around the definition of GCC_VERSION in tools/include/linux/compiler-gcc.h to prevent a conflict in jit_disasm.c on GCC_VERSION from headers pulled via libbfd. Fixes: c101189bc968 ("tools: bpftool: fix -Wmissing declaration warnings") Reported-by: Jakub Kicinski Signed-off-by: Quentin Monnet Reviewed-by: Jakub Kicinski Signed-off-by: Alexei Starovoitov --- tools/bpf/bpftool/common.c | 4 ++-- tools/bpf/bpftool/json_writer.c | 6 ++---- tools/bpf/bpftool/json_writer.h | 6 ++++-- tools/bpf/bpftool/main.h | 4 ++-- tools/include/linux/compiler-gcc.h | 2 ++ 5 files changed, 12 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c index 5215e0870bcb..a7036c70db48 100644 --- a/tools/bpf/bpftool/common.c +++ b/tools/bpf/bpftool/common.c @@ -29,7 +29,7 @@ #define BPF_FS_MAGIC 0xcafe4a11 #endif -void __printf(1, 2) p_err(const char *fmt, ...) +void p_err(const char *fmt, ...) { va_list ap; @@ -47,7 +47,7 @@ void __printf(1, 2) p_err(const char *fmt, ...) va_end(ap); } -void __printf(1, 2) p_info(const char *fmt, ...) +void p_info(const char *fmt, ...) { va_list ap; diff --git a/tools/bpf/bpftool/json_writer.c b/tools/bpf/bpftool/json_writer.c index 6046dcab51cc..86501cd3c763 100644 --- a/tools/bpf/bpftool/json_writer.c +++ b/tools/bpf/bpftool/json_writer.c @@ -15,7 +15,6 @@ #include #include #include -#include #include "json_writer.h" @@ -153,8 +152,7 @@ void jsonw_name(json_writer_t *self, const char *name) putc(' ', self->out); } -void __printf(2, 0) -jsonw_vprintf_enquote(json_writer_t *self, const char *fmt, va_list ap) +void jsonw_vprintf_enquote(json_writer_t *self, const char *fmt, va_list ap) { jsonw_eor(self); putc('"', self->out); @@ -162,7 +160,7 @@ jsonw_vprintf_enquote(json_writer_t *self, const char *fmt, va_list ap) putc('"', self->out); } -void __printf(2, 3) jsonw_printf(json_writer_t *self, const char *fmt, ...) +void jsonw_printf(json_writer_t *self, const char *fmt, ...) { va_list ap; diff --git a/tools/bpf/bpftool/json_writer.h b/tools/bpf/bpftool/json_writer.h index cb9a1993681c..35cf1f00f96c 100644 --- a/tools/bpf/bpftool/json_writer.h +++ b/tools/bpf/bpftool/json_writer.h @@ -14,6 +14,7 @@ #include #include #include +#include /* Opaque class structure */ typedef struct json_writer json_writer_t; @@ -30,8 +31,9 @@ void jsonw_pretty(json_writer_t *self, bool on); void jsonw_name(json_writer_t *self, const char *name); /* Add value */ -void jsonw_vprintf_enquote(json_writer_t *self, const char *fmt, va_list ap); -void jsonw_printf(json_writer_t *self, const char *fmt, ...); +void __printf(2, 0) jsonw_vprintf_enquote(json_writer_t *self, const char *fmt, + va_list ap); +void __printf(2, 3) jsonw_printf(json_writer_t *self, const char *fmt, ...); void jsonw_string(json_writer_t *self, const char *value); void jsonw_bool(json_writer_t *self, bool value); void jsonw_float(json_writer_t *self, double number); diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h index 7031a4bf87a0..af9ad56c303a 100644 --- a/tools/bpf/bpftool/main.h +++ b/tools/bpf/bpftool/main.h @@ -98,8 +98,8 @@ extern int bpf_flags; extern struct pinned_obj_table prog_table; extern struct pinned_obj_table map_table; -void p_err(const char *fmt, ...); -void p_info(const char *fmt, ...); +void __printf(1, 2) p_err(const char *fmt, ...); +void __printf(1, 2) p_info(const char *fmt, ...); bool is_prefix(const char *pfx, const char *str); int detect_common_prefix(const char *arg, ...); diff --git a/tools/include/linux/compiler-gcc.h b/tools/include/linux/compiler-gcc.h index 0d35f18006a1..95c072b70d0e 100644 --- a/tools/include/linux/compiler-gcc.h +++ b/tools/include/linux/compiler-gcc.h @@ -6,9 +6,11 @@ /* * Common definitions for all gcc versions go here. */ +#ifndef GCC_VERSION #define GCC_VERSION (__GNUC__ * 10000 \ + __GNUC_MINOR__ * 100 \ + __GNUC_PATCHLEVEL__) +#endif #if GCC_VERSION >= 70000 && !defined(__CHECKER__) # define __fallthrough __attribute__ ((fallthrough)) -- cgit v1.2.3-59-g8ed1b From d34b044038bfb0e19caa8b019910efc465f41d5f Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Thu, 15 Aug 2019 15:22:23 +0100 Subject: tools: bpftool: close prog FD before exit on showing a single program When showing metadata about a single program by invoking "bpftool prog show PROG", the file descriptor referring to the program is not closed before returning from the function. Let's close it. Fixes: 71bb428fe2c1 ("tools: bpf: add bpftool") Signed-off-by: Quentin Monnet Reviewed-by: Jakub Kicinski Acked-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov --- tools/bpf/bpftool/prog.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index 66f04a4846a5..43fdbbfe41bb 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -363,7 +363,9 @@ static int do_show(int argc, char **argv) if (fd < 0) return -1; - return show_prog(fd); + err = show_prog(fd); + close(fd); + return err; } if (argc) -- cgit v1.2.3-59-g8ed1b From ef4b1a539f4b8776701752c5a09ee741a4232ae6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 15 Aug 2019 18:18:58 -0300 Subject: perf report: Add --switch-on/--switch-off events Since 'perf top' shares the histogram browser with 'perf report', then the same explanation in the previous cset applies. An additional example uses a pair of SDT events available for systemtap: # perf probe --exec=/usr/bin/stap '%*:*' Added new events: sdt_stap:benchmark__thread__start (on %* in /usr/bin/stap) sdt_stap:benchmark (on %* in /usr/bin/stap) sdt_stap:benchmark__thread__end (on %* in /usr/bin/stap) sdt_stap:pass6__start (on %* in /usr/bin/stap) sdt_stap:pass6__end (on %* in /usr/bin/stap) sdt_stap:pass5__start (on %* in /usr/bin/stap) sdt_stap:pass5__end (on %* in /usr/bin/stap) sdt_stap:pass0__start (on %* in /usr/bin/stap) sdt_stap:pass0__end (on %* in /usr/bin/stap) sdt_stap:pass1a__start (on %* in /usr/bin/stap) sdt_stap:pass1b__start (on %* in /usr/bin/stap) sdt_stap:pass1__end (on %* in /usr/bin/stap) sdt_stap:pass2__start (on %* in /usr/bin/stap) sdt_stap:pass2__end (on %* in /usr/bin/stap) sdt_stap:pass3__start (on %* in /usr/bin/stap) sdt_stap:pass3__end (on %* in /usr/bin/stap) sdt_stap:pass4__start (on %* in /usr/bin/stap) sdt_stap:pass4__end (on %* in /usr/bin/stap) sdt_stap:benchmark__start (on %* in /usr/bin/stap) sdt_stap:benchmark__end (on %* in /usr/bin/stap) sdt_stap:cache__get (on %* in /usr/bin/stap) sdt_stap:cache__clean (on %* in /usr/bin/stap) sdt_stap:cache__add__module (on %* in /usr/bin/stap) sdt_stap:cache__add__source (on %* in /usr/bin/stap) sdt_stap:stap_system__complete (on %* in /usr/bin/stap) sdt_stap:stap_system__start (on %* in /usr/bin/stap) sdt_stap:stap_system__spawn (on %* in /usr/bin/stap) sdt_stap:stap_system__fork (on %* in /usr/bin/stap) sdt_stap:intern_string (on %* in /usr/bin/stap) sdt_stap:client__start (on %* in /usr/bin/stap) sdt_stap:client__end (on %* in /usr/bin/stap) You can now use it in all perf tools, such as: perf record -e sdt_stap:client__end -aR sleep 1 # From these we're use the two below to run systemtap's test suite: # perf record -e sdt_stap:pass2__*,cycles:P make installcheck > /dev/null ^C[ perf record: Woken up 8 times to write data ] [ perf record: Captured and wrote 2.691 MB perf.data (39638 samples) ] Terminated # perf script | grep sdt_stap stap 28979 [000] 19424.302660: sdt_stap:pass2__start: (561b9a537de3) arg1=140730364262544 stap 28979 [000] 19424.333083: sdt_stap:pass2__end: (561b9a53a9e1) arg1=140730364262544 stap 29045 [006] 19424.933460: sdt_stap:pass2__start: (563edddcede3) arg1=140722674883152 stap 29045 [006] 19424.963794: sdt_stap:pass2__end: (563edddd19e1) arg1=140722674883152 # perf script | grep cycles | wc -l 39634 # Looking at the whole perf.data file: [root@quaco testsuite]# perf report | grep cycles:P -A25 # Samples: 39K of event 'cycles:P' # Event count (approx.): 34044267368 # # Overhead Command Shared Object Symbol # ........ ....... .................... ................................ # 3.50% cc1 cc1 [.] ht_lookup_with_hash 3.04% cc1 cc1 [.] _cpp_lex_token 2.11% cc1 cc1 [.] ggc_internal_alloc 1.83% cc1 cc1 [.] cpp_get_token_with_location 1.68% cc1 libc-2.29.so [.] _int_malloc 1.41% cc1 cc1 [.] linemap_position_for_column 1.25% cc1 cc1 [.] ggc_internal_cleared_alloc 1.20% cc1 cc1 [.] c_lex_with_flags 1.18% cc1 cc1 [.] get_combined_adhoc_loc 1.05% cc1 libc-2.29.so [.] malloc 1.01% cc1 libc-2.29.so [.] _int_free 0.96% stap stap [.] std::_Hashtable, std::allocator >, std::__cxx11::basic_string, std::allocator >, std::allocator, std::allocator > >, std::__detail::_Identity, std::equal_to, std::allocator > >, stringtable_hash, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits >::_M_insert, std::allocator > const&, std::__detail::_AllocNode, std::allocator >, true> > > > 0.78% stap stap [.] lexer::scan 0.74% cc1 cc1 [.] _cpp_lex_direct 0.70% cc1 cc1 [.] pop_scope 0.70% cc1 cc1 [.] c_parser_declspecs 0.69% stap libc-2.29.so [.] _int_malloc 0.68% cc1 cc1 [.] htab_find_slot 0.68% cc1 [kernel.vmlinux] [k] prepare_exit_to_usermode 0.64% cc1 [kernel.vmlinux] [k] clear_page_erms [root@quaco testsuite]# And now only what happens in slices demarcated by those start/end SDT events: [root@quaco testsuite]# perf report --switch-on=sdt_stap:pass2__start --switch-off=sdt_stap:pass2__end | grep cycles:P -A100 # Samples: 240 of event 'cycles:P' # Event count (approx.): 206491934 # # Overhead Command Shared Object Symbol # ........ ....... ................... ................................................ # 38.99% stap stap [.] systemtap_session::register_library_aliases 19.47% stap stap [.] match_key::operator< 15.01% stap libc-2.29.so [.] __memcmp_avx2_movbe 5.19% stap libc-2.29.so [.] _int_malloc 2.50% stap libstdc++.so.6.0.26 [.] std::_Rb_tree_insert_and_rebalance 2.30% stap stap [.] match_node::build_no_more 2.07% stap libc-2.29.so [.] malloc 1.66% stap stap [.] std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::find 1.66% stap stap [.] match_node::bind 1.58% stap [kernel.vmlinux] [k] prepare_exit_to_usermode 1.17% stap [kernel.vmlinux] [k] native_irq_return_iret 0.87% stap stap [.] 0x0000000000032ec4 0.77% stap libstdc++.so.6.0.26 [.] std::_Rb_tree_increment 0.47% stap stap [.] std::vector >::_M_realloc_insert 0.47% stap [kernel.vmlinux] [k] get_page_from_freelist 0.47% stap [kernel.vmlinux] [k] swapgs_restore_regs_and_return_to_usermode 0.47% stap [kernel.vmlinux] [k] do_user_addr_fault 0.46% stap [kernel.vmlinux] [k] __pagevec_lru_add_fn 0.46% stap stap [.] std::_Rb_tree, std::_Select1st >, std::less, std::allocator > >::_M_emplace_unique > 0.42% stap libstdc++.so.6.0.26 [.] 0x00000000000c18fa 0.40% stap [kernel.vmlinux] [k] interrupt_entry 0.40% stap [kernel.vmlinux] [k] update_load_avg 0.40% stap [kernel.vmlinux] [k] __intel_pmu_disable_all 0.40% stap [kernel.vmlinux] [k] clear_page_erms 0.39% stap [kernel.vmlinux] [k] __mod_node_page_state 0.39% stap [kernel.vmlinux] [k] error_entry 0.39% stap [kernel.vmlinux] [k] sync_regs 0.38% stap [kernel.vmlinux] [k] __handle_mm_fault 0.38% stap stap [.] derive_probes # # (Tip: System-wide collection from all CPUs: perf record -a) # [root@quaco testsuite]# Cc: Adrian Hunter Cc: Florian Weimer Cc: Jiri Olsa Cc: Namhyung Kim Cc: William Cohen Link: https://lkml.kernel.org/n/tip-408hvumcnyn93a0auihnawew@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-report.txt | 17 +++++++++++++++++ tools/perf/builtin-report.c | 10 ++++++++++ 2 files changed, 27 insertions(+) (limited to 'tools') diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 987261d158d4..7315f155803f 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -438,6 +438,23 @@ OPTIONS perf report --time 0%-10%,30%-40% +--switch-on EVENT_NAME:: + Only consider events after this event is found. + + This may be interesting to measure a workload only after some initialization + phase is over, i.e. insert a perf probe at that point and then using this + option with that probe. + +--switch-off EVENT_NAME:: + Stop considering events after this event is found. + +--show-on-off-events:: + Show the --switch-on/off events too. This has no effect in 'perf report' now + but probably we'll make the default not to show the switch-on/off events + on the --group mode and if there is only one event besides the off/on ones, + go straight to the histogram browser, just like 'perf report' with no events + explicitely specified does. + --itrace:: Options for decoding instruction tracing data. The options are: diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index d4288dcce156..5e003d02821e 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -25,6 +25,7 @@ #include "util/debug.h" #include "util/evlist.h" #include "util/evsel.h" +#include "util/evswitch.h" #include "util/header.h" #include "util/session.h" #include "util/tool.h" @@ -60,6 +61,7 @@ struct report { struct perf_tool tool; struct perf_session *session; + struct evswitch evswitch; bool use_tui, use_gtk, use_stdio; bool show_full_info; bool show_threads; @@ -243,6 +245,9 @@ static int process_sample_event(struct perf_tool *tool, return 0; } + if (evswitch__discard(&rep->evswitch, evsel)) + return 0; + if (machine__resolve(machine, &al, sample) < 0) { pr_debug("problem processing %d event, skipping it.\n", event->header.type); @@ -1189,6 +1194,7 @@ int cmd_report(int argc, const char **argv) OPT_CALLBACK(0, "time-quantum", &symbol_conf.time_quantum, "time (ms|us|ns|s)", "Set time quantum for time sort key (default 100ms)", parse_time_quantum), + OPTS_EVSWITCH(&report.evswitch), OPT_END() }; struct perf_data data = { @@ -1257,6 +1263,10 @@ repeat: if (session == NULL) return -1; + ret = evswitch__init(&report.evswitch, session->evlist, stderr); + if (ret) + return ret; + if (zstd_init(&(session->zstd_data), 0) < 0) pr_warning("Decompression initialization failed. Reported data may be incomplete.\n"); -- cgit v1.2.3-59-g8ed1b From ab6cd0e5276e24403751e0b3b8ed807738a8571f Mon Sep 17 00:00:00 2001 From: John Keeping Date: Thu, 15 Aug 2019 11:01:44 +0100 Subject: perf map: Use zalloc for map_groups In the next commit we will add new fields to map_groups and we need these to be null if no value is assigned. The simplest way to achieve this is to request zeroed memory from the allocator. Signed-off-by: John Keeping Reviewed-by: Jiri Olsa Cc: Alexander Shishkin Cc: Konstantin Khlebnikov Cc: Namhyung Kim Cc: Peter Zijlstra Cc: john keeping Link: http://lkml.kernel.org/r/20190815100146.28842-1-john@metanate.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 668410b1d426..44b556812e4b 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -636,7 +636,7 @@ bool map_groups__empty(struct map_groups *mg) struct map_groups *map_groups__new(struct machine *machine) { - struct map_groups *mg = malloc(sizeof(*mg)); + struct map_groups *mg = zalloc(sizeof(*mg)); if (mg != NULL) map_groups__init(mg, machine); -- cgit v1.2.3-59-g8ed1b From e8ba2906f6b9054102ad035ac9cafad9d4168589 Mon Sep 17 00:00:00 2001 From: John Keeping Date: Thu, 15 Aug 2019 11:01:45 +0100 Subject: perf unwind: Fix libunwind when tid != pid Commit e5adfc3e7e77 ("perf map: Synthesize maps only for thread group leader") changed the recording side so that we no longer get mmap events for threads other than the thread group leader (when synthesising these events for threads which exist before perf is started). When a file recorded after this change is loaded, the lack of mmap records mean that unwinding is not set up for any other threads. This can be seen in a simple record/report scenario: perf record --call-graph=dwarf -t $TID perf report If $TID is a process ID then the report will show call graphs, but if $TID is a secondary thread the output is as if --call-graph=none was specified. Following the rationale in that commit, move the libunwind fields into struct map_groups and update the libunwind functions to take this instead of the struct thread. This is only required for unwind__finish_access which must now be called from map_groups__delete and the others are changed for symmetry. Note that unwind__get_entries keeps the thread argument since it is required for symbol lookup and the libdw unwind provider uses the thread ID. Signed-off-by: John Keeping Reviewed-by: Jiri Olsa Cc: Alexander Shishkin Cc: Konstantin Khlebnikov Cc: Namhyung Kim Cc: Peter Zijlstra Fixes: e5adfc3e7e77 ("perf map: Synthesize maps only for thread group leader") Link: http://lkml.kernel.org/r/20190815100146.28842-2-john@metanate.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/map.c | 3 ++- tools/perf/util/map_groups.h | 4 ++++ tools/perf/util/thread.c | 7 +++---- tools/perf/util/thread.h | 4 ---- tools/perf/util/unwind-libunwind-local.c | 18 ++++++++--------- tools/perf/util/unwind-libunwind.c | 34 ++++++++++++++++---------------- tools/perf/util/unwind.h | 25 ++++++++++++----------- 7 files changed, 48 insertions(+), 47 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 44b556812e4b..27b7b102e4a2 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -647,6 +647,7 @@ struct map_groups *map_groups__new(struct machine *machine) void map_groups__delete(struct map_groups *mg) { map_groups__exit(mg); + unwind__finish_access(mg); free(mg); } @@ -887,7 +888,7 @@ int map_groups__clone(struct thread *thread, struct map_groups *parent) if (new == NULL) goto out_unlock; - err = unwind__prepare_access(thread, new, NULL); + err = unwind__prepare_access(mg, new, NULL); if (err) goto out_unlock; diff --git a/tools/perf/util/map_groups.h b/tools/perf/util/map_groups.h index 5f25efa6d6bc..77252e14008f 100644 --- a/tools/perf/util/map_groups.h +++ b/tools/perf/util/map_groups.h @@ -31,6 +31,10 @@ struct map_groups { struct maps maps; struct machine *machine; refcount_t refcnt; +#ifdef HAVE_LIBUNWIND_SUPPORT + void *addr_space; + struct unwind_libunwind_ops *unwind_libunwind_ops; +#endif }; #define KMAP_NAME_LEN 256 diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 590793cc5142..bbf7816cba31 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -105,7 +105,6 @@ void thread__delete(struct thread *thread) } up_write(&thread->comm_lock); - unwind__finish_access(thread); nsinfo__zput(thread->nsinfo); srccode_state_free(&thread->srccode_state); @@ -252,7 +251,7 @@ static int ____thread__set_comm(struct thread *thread, const char *str, list_add(&new->list, &thread->comm_list); if (exec) - unwind__flush_access(thread); + unwind__flush_access(thread->mg); } thread->comm_set = true; @@ -332,7 +331,7 @@ int thread__insert_map(struct thread *thread, struct map *map) { int ret; - ret = unwind__prepare_access(thread, map, NULL); + ret = unwind__prepare_access(thread->mg, map, NULL); if (ret) return ret; @@ -352,7 +351,7 @@ static int __thread__prepare_access(struct thread *thread) down_read(&maps->lock); for (map = maps__first(maps); map; map = map__next(map)) { - err = unwind__prepare_access(thread, map, &initialized); + err = unwind__prepare_access(thread->mg, map, &initialized); if (err || initialized) break; } diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index e97ef6977eb9..bf06113be4f3 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -44,10 +44,6 @@ struct thread { struct thread_stack *ts; struct nsinfo *nsinfo; struct srccode_state srccode_state; -#ifdef HAVE_LIBUNWIND_SUPPORT - void *addr_space; - struct unwind_libunwind_ops *unwind_libunwind_ops; -#endif bool filter; int filter_entry_depth; }; diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c index 71a788921b62..ebdbb056510c 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -616,26 +616,26 @@ static unw_accessors_t accessors = { .get_proc_name = get_proc_name, }; -static int _unwind__prepare_access(struct thread *thread) +static int _unwind__prepare_access(struct map_groups *mg) { - thread->addr_space = unw_create_addr_space(&accessors, 0); - if (!thread->addr_space) { + mg->addr_space = unw_create_addr_space(&accessors, 0); + if (!mg->addr_space) { pr_err("unwind: Can't create unwind address space.\n"); return -ENOMEM; } - unw_set_caching_policy(thread->addr_space, UNW_CACHE_GLOBAL); + unw_set_caching_policy(mg->addr_space, UNW_CACHE_GLOBAL); return 0; } -static void _unwind__flush_access(struct thread *thread) +static void _unwind__flush_access(struct map_groups *mg) { - unw_flush_cache(thread->addr_space, 0, 0); + unw_flush_cache(mg->addr_space, 0, 0); } -static void _unwind__finish_access(struct thread *thread) +static void _unwind__finish_access(struct map_groups *mg) { - unw_destroy_addr_space(thread->addr_space); + unw_destroy_addr_space(mg->addr_space); } static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, @@ -660,7 +660,7 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, */ if (max_stack - 1 > 0) { WARN_ONCE(!ui->thread, "WARNING: ui->thread is NULL"); - addr_space = ui->thread->addr_space; + addr_space = ui->thread->mg->addr_space; if (addr_space == NULL) return -1; diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index c0811977d7d5..b843f9d0a9ea 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c @@ -11,13 +11,13 @@ struct unwind_libunwind_ops __weak *local_unwind_libunwind_ops; struct unwind_libunwind_ops __weak *x86_32_unwind_libunwind_ops; struct unwind_libunwind_ops __weak *arm64_unwind_libunwind_ops; -static void unwind__register_ops(struct thread *thread, +static void unwind__register_ops(struct map_groups *mg, struct unwind_libunwind_ops *ops) { - thread->unwind_libunwind_ops = ops; + mg->unwind_libunwind_ops = ops; } -int unwind__prepare_access(struct thread *thread, struct map *map, +int unwind__prepare_access(struct map_groups *mg, struct map *map, bool *initialized) { const char *arch; @@ -28,7 +28,7 @@ int unwind__prepare_access(struct thread *thread, struct map *map, if (!dwarf_callchain_users) return 0; - if (thread->addr_space) { + if (mg->addr_space) { pr_debug("unwind: thread map already set, dso=%s\n", map->dso->name); if (initialized) @@ -37,14 +37,14 @@ int unwind__prepare_access(struct thread *thread, struct map *map, } /* env->arch is NULL for live-mode (i.e. perf top) */ - if (!thread->mg->machine->env || !thread->mg->machine->env->arch) + if (!mg->machine->env || !mg->machine->env->arch) goto out_register; - dso_type = dso__type(map->dso, thread->mg->machine); + dso_type = dso__type(map->dso, mg->machine); if (dso_type == DSO__TYPE_UNKNOWN) return 0; - arch = perf_env__arch(thread->mg->machine->env); + arch = perf_env__arch(mg->machine->env); if (!strcmp(arch, "x86")) { if (dso_type != DSO__TYPE_64BIT) @@ -59,37 +59,37 @@ int unwind__prepare_access(struct thread *thread, struct map *map, return 0; } out_register: - unwind__register_ops(thread, ops); + unwind__register_ops(mg, ops); - err = thread->unwind_libunwind_ops->prepare_access(thread); + err = mg->unwind_libunwind_ops->prepare_access(mg); if (initialized) *initialized = err ? false : true; return err; } -void unwind__flush_access(struct thread *thread) +void unwind__flush_access(struct map_groups *mg) { if (!dwarf_callchain_users) return; - if (thread->unwind_libunwind_ops) - thread->unwind_libunwind_ops->flush_access(thread); + if (mg->unwind_libunwind_ops) + mg->unwind_libunwind_ops->flush_access(mg); } -void unwind__finish_access(struct thread *thread) +void unwind__finish_access(struct map_groups *mg) { if (!dwarf_callchain_users) return; - if (thread->unwind_libunwind_ops) - thread->unwind_libunwind_ops->finish_access(thread); + if (mg->unwind_libunwind_ops) + mg->unwind_libunwind_ops->finish_access(mg); } int unwind__get_entries(unwind_entry_cb_t cb, void *arg, struct thread *thread, struct perf_sample *data, int max_stack) { - if (thread->unwind_libunwind_ops) - return thread->unwind_libunwind_ops->get_entries(cb, arg, thread, data, max_stack); + if (thread->mg->unwind_libunwind_ops) + return thread->mg->unwind_libunwind_ops->get_entries(cb, arg, thread, data, max_stack); return 0; } diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h index 8a44a1569a21..3a7d00c20d86 100644 --- a/tools/perf/util/unwind.h +++ b/tools/perf/util/unwind.h @@ -6,6 +6,7 @@ #include struct map; +struct map_groups; struct perf_sample; struct symbol; struct thread; @@ -19,9 +20,9 @@ struct unwind_entry { typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg); struct unwind_libunwind_ops { - int (*prepare_access)(struct thread *thread); - void (*flush_access)(struct thread *thread); - void (*finish_access)(struct thread *thread); + int (*prepare_access)(struct map_groups *mg); + void (*flush_access)(struct map_groups *mg); + void (*finish_access)(struct map_groups *mg); int (*get_entries)(unwind_entry_cb_t cb, void *arg, struct thread *thread, struct perf_sample *data, int max_stack); @@ -46,20 +47,20 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, #endif int LIBUNWIND__ARCH_REG_ID(int regnum); -int unwind__prepare_access(struct thread *thread, struct map *map, +int unwind__prepare_access(struct map_groups *mg, struct map *map, bool *initialized); -void unwind__flush_access(struct thread *thread); -void unwind__finish_access(struct thread *thread); +void unwind__flush_access(struct map_groups *mg); +void unwind__finish_access(struct map_groups *mg); #else -static inline int unwind__prepare_access(struct thread *thread __maybe_unused, +static inline int unwind__prepare_access(struct map_groups *mg __maybe_unused, struct map *map __maybe_unused, bool *initialized __maybe_unused) { return 0; } -static inline void unwind__flush_access(struct thread *thread __maybe_unused) {} -static inline void unwind__finish_access(struct thread *thread __maybe_unused) {} +static inline void unwind__flush_access(struct map_groups *mg __maybe_unused) {} +static inline void unwind__finish_access(struct map_groups *mg __maybe_unused) {} #endif #else static inline int @@ -72,14 +73,14 @@ unwind__get_entries(unwind_entry_cb_t cb __maybe_unused, return 0; } -static inline int unwind__prepare_access(struct thread *thread __maybe_unused, +static inline int unwind__prepare_access(struct map_groups *mg __maybe_unused, struct map *map __maybe_unused, bool *initialized __maybe_unused) { return 0; } -static inline void unwind__flush_access(struct thread *thread __maybe_unused) {} -static inline void unwind__finish_access(struct thread *thread __maybe_unused) {} +static inline void unwind__flush_access(struct map_groups *mg __maybe_unused) {} +static inline void unwind__finish_access(struct map_groups *mg __maybe_unused) {} #endif /* HAVE_DWARF_UNWIND_SUPPORT */ #endif /* __UNWIND_H */ -- cgit v1.2.3-59-g8ed1b From e2736219e6ca3117e10651e215b96d66775220da Mon Sep 17 00:00:00 2001 From: John Keeping Date: Thu, 15 Aug 2019 11:01:46 +0100 Subject: perf unwind: Remove unnecessary test If dwarf_callchain_users is false, then unwind__prepare_access() will not set unwind_libunwind_ops so the remaining test here is sufficient. Signed-off-by: John Keeping Reviewed-by: Jiri Olsa Cc: Alexander Shishkin Cc: Konstantin Khlebnikov Cc: Namhyung Kim Cc: Peter Zijlstra Cc: john keeping Link: http://lkml.kernel.org/r/20190815100146.28842-3-john@metanate.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/unwind-libunwind.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index b843f9d0a9ea..6499b22b158b 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c @@ -69,18 +69,12 @@ out_register: void unwind__flush_access(struct map_groups *mg) { - if (!dwarf_callchain_users) - return; - if (mg->unwind_libunwind_ops) mg->unwind_libunwind_ops->flush_access(mg); } void unwind__finish_access(struct map_groups *mg) { - if (!dwarf_callchain_users) - return; - if (mg->unwind_libunwind_ops) mg->unwind_libunwind_ops->finish_access(mg); } -- cgit v1.2.3-59-g8ed1b From 87caaaf2d19d4656924241aadb612782c296928f Mon Sep 17 00:00:00 2001 From: David Ahern Date: Wed, 14 Aug 2019 10:11:51 -0700 Subject: selftests: Fix get_ifidx and callers in nettest.c Dan reported: The patch acda655fefae: "selftests: Add nettest" from Aug 1, 2019, leads to the following static checker warning: ./tools/testing/selftests/net/nettest.c:1690 main() warn: unsigned 'tmp' is never less than zero. ./tools/testing/selftests/net/nettest.c 1680 case '1': 1681 args.has_expected_raddr = 1; 1682 if (convert_addr(&args, optarg, 1683 ADDR_TYPE_EXPECTED_REMOTE)) 1684 return 1; 1685 1686 break; 1687 case '2': 1688 if (str_to_uint(optarg, 0, 0x7ffffff, &tmp) != 0) { 1689 tmp = get_ifidx(optarg); 1690 if (tmp < 0) { "tmp" is unsigned so it can't be negative. Also all the callers assume that get_ifidx() returns negatives on error but it looks like it really returns zero on error so it's a bit unclear to me. Update get_ifidx to return -1 on errors and cleanup callers of it. Fixes: acda655fefae ("selftests: Add nettest") Reported-by: Dan Carpenter Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/nettest.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/nettest.c b/tools/testing/selftests/net/nettest.c index 83515e5ea4dc..c08f4db8330d 100644 --- a/tools/testing/selftests/net/nettest.c +++ b/tools/testing/selftests/net/nettest.c @@ -266,7 +266,7 @@ static int get_ifidx(const char *ifname) int sd, rc; if (!ifname || *ifname == '\0') - return 0; + return -1; memset(&ifdata, 0, sizeof(ifdata)); @@ -275,14 +275,14 @@ static int get_ifidx(const char *ifname) sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); if (sd < 0) { log_err_errno("socket failed"); - return 0; + return -1; } rc = ioctl(sd, SIOCGIFINDEX, (char *)&ifdata); close(sd); if (rc != 0) { log_err_errno("ioctl(SIOCGIFINDEX) failed"); - return 0; + return -1; } return ifdata.ifr_ifindex; @@ -419,20 +419,20 @@ static int set_multicast_if(int sd, int ifindex) return rc; } -static int set_membership(int sd, uint32_t grp, uint32_t addr, const char *dev) +static int set_membership(int sd, uint32_t grp, uint32_t addr, int ifindex) { uint32_t if_addr = addr; struct ip_mreqn mreq; int rc; - if (addr == htonl(INADDR_ANY) && !dev) { + if (addr == htonl(INADDR_ANY) && !ifindex) { log_error("Either local address or device needs to be given for multicast membership\n"); return -1; } mreq.imr_multiaddr.s_addr = grp; mreq.imr_address.s_addr = if_addr; - mreq.imr_ifindex = dev ? get_ifidx(dev) : 0; + mreq.imr_ifindex = ifindex; rc = setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); if (rc < 0) { @@ -1048,7 +1048,7 @@ static int msock_init(struct sock_args *args, int server) if (server && set_membership(sd, args->grp.s_addr, - args->local_addr.in.s_addr, args->dev)) + args->local_addr.in.s_addr, args->ifindex)) goto out_err; return sd; @@ -1685,15 +1685,16 @@ int main(int argc, char *argv[]) break; case '2': - if (str_to_uint(optarg, 0, 0x7ffffff, &tmp) != 0) { - tmp = get_ifidx(optarg); - if (tmp < 0) { + if (str_to_uint(optarg, 0, INT_MAX, &tmp) == 0) { + args.expected_ifindex = (int)tmp; + } else { + args.expected_ifindex = get_ifidx(optarg); + if (args.expected_ifindex < 0) { fprintf(stderr, - "Invalid device index\n"); + "Invalid expected device\n"); return 1; } } - args.expected_ifindex = (int)tmp; break; case 'q': quiet = 1; -- cgit v1.2.3-59-g8ed1b From 5912e791f3018de0a007c8cfa9cb38c97d3e5f5c Mon Sep 17 00:00:00 2001 From: Adrian Vladu Date: Mon, 6 May 2019 17:27:37 +0000 Subject: tools: hv: fixed Python pep8/flake8 warnings for lsvmbus Fixed pep8/flake8 python style code for lsvmbus tool. The TAB indentation was on purpose ignored (pep8 rule W191) to make sure the code is complying with the Linux code guideline. The following command doe not show any warnings now: pep8 --ignore=W191 lsvmbus flake8 --ignore=W191 lsvmbus Signed-off-by: Adrian Vladu Cc: "K. Y. Srinivasan" Cc: Haiyang Zhang Cc: Stephen Hemminger Cc: Sasha Levin Cc: Dexuan Cui Cc: Alessandro Pilotti Signed-off-by: Sasha Levin --- tools/hv/lsvmbus | 75 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 33 deletions(-) (limited to 'tools') diff --git a/tools/hv/lsvmbus b/tools/hv/lsvmbus index 55e7374bade0..099f2c44dbed 100644 --- a/tools/hv/lsvmbus +++ b/tools/hv/lsvmbus @@ -4,10 +4,10 @@ import os from optparse import OptionParser +help_msg = "print verbose messages. Try -vv, -vvv for more verbose messages" parser = OptionParser() -parser.add_option("-v", "--verbose", dest="verbose", - help="print verbose messages. Try -vv, -vvv for \ - more verbose messages", action="count") +parser.add_option( + "-v", "--verbose", dest="verbose", help=help_msg, action="count") (options, args) = parser.parse_args() @@ -21,27 +21,28 @@ if not os.path.isdir(vmbus_sys_path): exit(-1) vmbus_dev_dict = { - '{0e0b6031-5213-4934-818b-38d90ced39db}' : '[Operating system shutdown]', - '{9527e630-d0ae-497b-adce-e80ab0175caf}' : '[Time Synchronization]', - '{57164f39-9115-4e78-ab55-382f3bd5422d}' : '[Heartbeat]', - '{a9a0f4e7-5a45-4d96-b827-8a841e8c03e6}' : '[Data Exchange]', - '{35fa2e29-ea23-4236-96ae-3a6ebacba440}' : '[Backup (volume checkpoint)]', - '{34d14be3-dee4-41c8-9ae7-6b174977c192}' : '[Guest services]', - '{525074dc-8985-46e2-8057-a307dc18a502}' : '[Dynamic Memory]', - '{cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a}' : 'Synthetic mouse', - '{f912ad6d-2b17-48ea-bd65-f927a61c7684}' : 'Synthetic keyboard', - '{da0a7802-e377-4aac-8e77-0558eb1073f8}' : 'Synthetic framebuffer adapter', - '{f8615163-df3e-46c5-913f-f2d2f965ed0e}' : 'Synthetic network adapter', - '{32412632-86cb-44a2-9b5c-50d1417354f5}' : 'Synthetic IDE Controller', - '{ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}' : 'Synthetic SCSI Controller', - '{2f9bcc4a-0069-4af3-b76b-6fd0be528cda}' : 'Synthetic fiber channel adapter', - '{8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501}' : 'Synthetic RDMA adapter', - '{44c4f61d-4444-4400-9d52-802e27ede19f}' : 'PCI Express pass-through', - '{276aacf4-ac15-426c-98dd-7521ad3f01fe}' : '[Reserved system device]', - '{f8e65716-3cb3-4a06-9a60-1889c5cccab5}' : '[Reserved system device]', - '{3375baf4-9e15-4b30-b765-67acb10d607b}' : '[Reserved system device]', + '{0e0b6031-5213-4934-818b-38d90ced39db}': '[Operating system shutdown]', + '{9527e630-d0ae-497b-adce-e80ab0175caf}': '[Time Synchronization]', + '{57164f39-9115-4e78-ab55-382f3bd5422d}': '[Heartbeat]', + '{a9a0f4e7-5a45-4d96-b827-8a841e8c03e6}': '[Data Exchange]', + '{35fa2e29-ea23-4236-96ae-3a6ebacba440}': '[Backup (volume checkpoint)]', + '{34d14be3-dee4-41c8-9ae7-6b174977c192}': '[Guest services]', + '{525074dc-8985-46e2-8057-a307dc18a502}': '[Dynamic Memory]', + '{cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a}': 'Synthetic mouse', + '{f912ad6d-2b17-48ea-bd65-f927a61c7684}': 'Synthetic keyboard', + '{da0a7802-e377-4aac-8e77-0558eb1073f8}': 'Synthetic framebuffer adapter', + '{f8615163-df3e-46c5-913f-f2d2f965ed0e}': 'Synthetic network adapter', + '{32412632-86cb-44a2-9b5c-50d1417354f5}': 'Synthetic IDE Controller', + '{ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}': 'Synthetic SCSI Controller', + '{2f9bcc4a-0069-4af3-b76b-6fd0be528cda}': 'Synthetic fiber channel adapter', + '{8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501}': 'Synthetic RDMA adapter', + '{44c4f61d-4444-4400-9d52-802e27ede19f}': 'PCI Express pass-through', + '{276aacf4-ac15-426c-98dd-7521ad3f01fe}': '[Reserved system device]', + '{f8e65716-3cb3-4a06-9a60-1889c5cccab5}': '[Reserved system device]', + '{3375baf4-9e15-4b30-b765-67acb10d607b}': '[Reserved system device]', } + def get_vmbus_dev_attr(dev_name, attr): try: f = open('%s/%s/%s' % (vmbus_sys_path, dev_name, attr), 'r') @@ -52,6 +53,7 @@ def get_vmbus_dev_attr(dev_name, attr): return lines + class VMBus_Dev: pass @@ -66,12 +68,13 @@ for f in os.listdir(vmbus_sys_path): chn_vp_mapping = get_vmbus_dev_attr(f, 'channel_vp_mapping') chn_vp_mapping = [c.strip() for c in chn_vp_mapping] - chn_vp_mapping = sorted(chn_vp_mapping, - key = lambda c : int(c.split(':')[0])) + chn_vp_mapping = sorted( + chn_vp_mapping, key=lambda c: int(c.split(':')[0])) - chn_vp_mapping = ['\tRel_ID=%s, target_cpu=%s' % - (c.split(':')[0], c.split(':')[1]) - for c in chn_vp_mapping] + chn_vp_mapping = [ + '\tRel_ID=%s, target_cpu=%s' % + (c.split(':')[0], c.split(':')[1]) for c in chn_vp_mapping + ] d = VMBus_Dev() d.sysfs_path = '%s/%s' % (vmbus_sys_path, f) d.vmbus_id = vmbus_id @@ -85,7 +88,7 @@ for f in os.listdir(vmbus_sys_path): vmbus_dev_list.append(d) -vmbus_dev_list = sorted(vmbus_dev_list, key = lambda d : int(d.vmbus_id)) +vmbus_dev_list = sorted(vmbus_dev_list, key=lambda d: int(d.vmbus_id)) format0 = '%2s: %s' format1 = '%2s: Class_ID = %s - %s\n%s' @@ -95,9 +98,15 @@ for d in vmbus_dev_list: if verbose == 0: print(('VMBUS ID ' + format0) % (d.vmbus_id, d.dev_desc)) elif verbose == 1: - print (('VMBUS ID ' + format1) % \ - (d.vmbus_id, d.class_id, d.dev_desc, d.chn_vp_mapping)) + print( + ('VMBUS ID ' + format1) % + (d.vmbus_id, d.class_id, d.dev_desc, d.chn_vp_mapping) + ) else: - print (('VMBUS ID ' + format2) % \ - (d.vmbus_id, d.class_id, d.dev_desc, \ - d.device_id, d.sysfs_path, d.chn_vp_mapping)) + print( + ('VMBUS ID ' + format2) % + ( + d.vmbus_id, d.class_id, d.dev_desc, + d.device_id, d.sysfs_path, d.chn_vp_mapping + ) + ) -- cgit v1.2.3-59-g8ed1b From b0995156071b0ff29a5902964a9dc8cfad6f81c0 Mon Sep 17 00:00:00 2001 From: Adrian Vladu Date: Mon, 6 May 2019 16:50:58 +0000 Subject: tools: hv: fix KVP and VSS daemons exit code HyperV KVP and VSS daemons should exit with 0 when the '--help' or '-h' flags are used. Signed-off-by: Adrian Vladu Cc: "K. Y. Srinivasan" Cc: Haiyang Zhang Cc: Stephen Hemminger Cc: Sasha Levin Cc: Alessandro Pilotti Signed-off-by: Sasha Levin --- tools/hv/hv_kvp_daemon.c | 2 ++ tools/hv/hv_vss_daemon.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index d7e06fe0270e..0ce50c319cfd 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -1386,6 +1386,8 @@ int main(int argc, char *argv[]) daemonize = 0; break; case 'h': + print_usage(argv); + exit(0); default: print_usage(argv); exit(EXIT_FAILURE); diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c index efe1e34dd91b..8f813f5233d4 100644 --- a/tools/hv/hv_vss_daemon.c +++ b/tools/hv/hv_vss_daemon.c @@ -218,6 +218,8 @@ int main(int argc, char *argv[]) daemonize = 0; break; case 'h': + print_usage(argv); + exit(0); default: print_usage(argv); exit(EXIT_FAILURE); -- cgit v1.2.3-59-g8ed1b From 2d35c66036b2494c329a32468c85405493370e75 Mon Sep 17 00:00:00 2001 From: Adrian Vladu Date: Mon, 6 May 2019 16:51:24 +0000 Subject: tools: hv: fix typos in toolchain Fix typos in the HyperV toolchain. Signed-off-by: Adrian Vladu Cc: "K. Y. Srinivasan" Cc: Haiyang Zhang Cc: Stephen Hemminger Cc: Sasha Levin Cc: Alessandro Pilotti Signed-off-by: Sasha Levin --- tools/hv/hv_get_dhcp_info.sh | 2 +- tools/hv/hv_kvp_daemon.c | 6 +++--- tools/hv/hv_set_ifconfig.sh | 2 +- tools/hv/hv_vss_daemon.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/hv/hv_get_dhcp_info.sh b/tools/hv/hv_get_dhcp_info.sh index c38686c44656..2f2a3c7df3de 100755 --- a/tools/hv/hv_get_dhcp_info.sh +++ b/tools/hv/hv_get_dhcp_info.sh @@ -13,7 +13,7 @@ # the script prints the string "Disabled" to stdout. # # Each Distro is expected to implement this script in a distro specific -# fashion. For instance on Distros that ship with Network Manager enabled, +# fashion. For instance, on Distros that ship with Network Manager enabled, # this script can be based on the Network Manager APIs for retrieving DHCP # information. diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index 0ce50c319cfd..f5597503c771 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -700,7 +700,7 @@ static void kvp_get_ipconfig_info(char *if_name, /* - * Gather the DNS state. + * Gather the DNS state. * Since there is no standard way to get this information * across various distributions of interest; we just invoke * an external script that needs to be ported across distros @@ -1051,7 +1051,7 @@ static int parse_ip_val_buffer(char *in_buf, int *offset, char *start; /* - * in_buf has sequence of characters that are seperated by + * in_buf has sequence of characters that are separated by * the character ';'. The last sequence does not have the * terminating ";" character. */ @@ -1492,7 +1492,7 @@ int main(int argc, char *argv[]) case KVP_OP_GET_IP_INFO: kvp_ip_val = &hv_msg->body.kvp_ip_val; - error = kvp_mac_to_ip(kvp_ip_val); + error = kvp_mac_to_ip(kvp_ip_val); if (error) hv_msg->error = error; diff --git a/tools/hv/hv_set_ifconfig.sh b/tools/hv/hv_set_ifconfig.sh index 7ed9f85ef908..d10fe35b7f25 100755 --- a/tools/hv/hv_set_ifconfig.sh +++ b/tools/hv/hv_set_ifconfig.sh @@ -12,7 +12,7 @@ # be used to configure the interface. # # Each Distro is expected to implement this script in a distro specific -# fashion. For instance on Distros that ship with Network Manager enabled, +# fashion. For instance, on Distros that ship with Network Manager enabled, # this script can be based on the Network Manager APIs for configuring the # interface. # diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c index 8f813f5233d4..92902a88f671 100644 --- a/tools/hv/hv_vss_daemon.c +++ b/tools/hv/hv_vss_daemon.c @@ -42,7 +42,7 @@ static int vss_do_freeze(char *dir, unsigned int cmd) * If a partition is mounted more than once, only the first * FREEZE/THAW can succeed and the later ones will get * EBUSY/EINVAL respectively: there could be 2 cases: - * 1) a user may mount the same partition to differnt directories + * 1) a user may mount the same partition to different directories * by mistake or on purpose; * 2) The subvolume of btrfs appears to have the same partition * mounted more than once. -- cgit v1.2.3-59-g8ed1b From bc030d9c91c3764a143fc3ac4516bbfd330b41ed Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Sat, 17 Aug 2019 16:28:22 +0300 Subject: selftests: forwarding: devlink_lib: Allow tests to define devlink device For tests that create their network interfaces dynamically or do not use interfaces at all (as with netdevsim) it is useful to define their own devlink device instead of deriving it from the first network interface. Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- .../selftests/net/forwarding/devlink_lib.sh | 26 ++++++++++++---------- 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/forwarding/devlink_lib.sh b/tools/testing/selftests/net/forwarding/devlink_lib.sh index 8553a67a2322..2b9296f6aa07 100644 --- a/tools/testing/selftests/net/forwarding/devlink_lib.sh +++ b/tools/testing/selftests/net/forwarding/devlink_lib.sh @@ -4,19 +4,21 @@ ############################################################################## # Defines -DEVLINK_DEV=$(devlink port show "${NETIFS[p1]}" -j \ - | jq -r '.port | keys[]' | cut -d/ -f-2) -if [ -z "$DEVLINK_DEV" ]; then - echo "SKIP: ${NETIFS[p1]} has no devlink device registered for it" - exit 1 -fi -if [[ "$(echo $DEVLINK_DEV | grep -c pci)" -eq 0 ]]; then - echo "SKIP: devlink device's bus is not PCI" - exit 1 -fi +if [[ ! -v DEVLINK_DEV ]]; then + DEVLINK_DEV=$(devlink port show "${NETIFS[p1]}" -j \ + | jq -r '.port | keys[]' | cut -d/ -f-2) + if [ -z "$DEVLINK_DEV" ]; then + echo "SKIP: ${NETIFS[p1]} has no devlink device registered for it" + exit 1 + fi + if [[ "$(echo $DEVLINK_DEV | grep -c pci)" -eq 0 ]]; then + echo "SKIP: devlink device's bus is not PCI" + exit 1 + fi -DEVLINK_VIDDID=$(lspci -s $(echo $DEVLINK_DEV | cut -d"/" -f2) \ - -n | cut -d" " -f3) + DEVLINK_VIDDID=$(lspci -s $(echo $DEVLINK_DEV | cut -d"/" -f2) \ + -n | cut -d" " -f3) +fi ############################################################################## # Sanity checks -- cgit v1.2.3-59-g8ed1b From a054c8d90bac321d804b789a82f9238f5a80a668 Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Sat, 17 Aug 2019 16:28:23 +0300 Subject: selftests: forwarding: devlink_lib: Add devlink-trap helpers Add helpers to interact with devlink-trap, such as setting the action of a trap and retrieving statistics. Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- .../selftests/net/forwarding/devlink_lib.sh | 163 +++++++++++++++++++++ 1 file changed, 163 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/net/forwarding/devlink_lib.sh b/tools/testing/selftests/net/forwarding/devlink_lib.sh index 2b9296f6aa07..13d03a6d85ba 100644 --- a/tools/testing/selftests/net/forwarding/devlink_lib.sh +++ b/tools/testing/selftests/net/forwarding/devlink_lib.sh @@ -29,6 +29,12 @@ if [ $? -ne 0 ]; then exit 1 fi +devlink help 2>&1 | grep trap &> /dev/null +if [ $? -ne 0 ]; then + echo "SKIP: iproute2 too old, missing devlink trap support" + exit 1 +fi + ############################################################################## # Devlink helpers @@ -192,3 +198,160 @@ devlink_tc_bind_pool_th_restore() devlink sb tc bind set $port tc $tc type $dir \ pool ${orig[0]} th ${orig[1]} } + +devlink_traps_num_get() +{ + devlink -j trap | jq '.[]["'$DEVLINK_DEV'"] | length' +} + +devlink_traps_get() +{ + devlink -j trap | jq -r '.[]["'$DEVLINK_DEV'"][].name' +} + +devlink_trap_type_get() +{ + local trap_name=$1; shift + + devlink -j trap show $DEVLINK_DEV trap $trap_name \ + | jq -r '.[][][].type' +} + +devlink_trap_action_set() +{ + local trap_name=$1; shift + local action=$1; shift + + # Pipe output to /dev/null to avoid expected warnings. + devlink trap set $DEVLINK_DEV trap $trap_name \ + action $action &> /dev/null +} + +devlink_trap_action_get() +{ + local trap_name=$1; shift + + devlink -j trap show $DEVLINK_DEV trap $trap_name \ + | jq -r '.[][][].action' +} + +devlink_trap_group_get() +{ + devlink -j trap show $DEVLINK_DEV trap $trap_name \ + | jq -r '.[][][].group' +} + +devlink_trap_metadata_test() +{ + local trap_name=$1; shift + local metadata=$1; shift + + devlink -jv trap show $DEVLINK_DEV trap $trap_name \ + | jq -e '.[][][].metadata | contains(["'$metadata'"])' \ + &> /dev/null +} + +devlink_trap_rx_packets_get() +{ + local trap_name=$1; shift + + devlink -js trap show $DEVLINK_DEV trap $trap_name \ + | jq '.[][][]["stats"]["rx"]["packets"]' +} + +devlink_trap_rx_bytes_get() +{ + local trap_name=$1; shift + + devlink -js trap show $DEVLINK_DEV trap $trap_name \ + | jq '.[][][]["stats"]["rx"]["bytes"]' +} + +devlink_trap_stats_idle_test() +{ + local trap_name=$1; shift + local t0_packets t0_bytes + local t1_packets t1_bytes + + t0_packets=$(devlink_trap_rx_packets_get $trap_name) + t0_bytes=$(devlink_trap_rx_bytes_get $trap_name) + + sleep 1 + + t1_packets=$(devlink_trap_rx_packets_get $trap_name) + t1_bytes=$(devlink_trap_rx_bytes_get $trap_name) + + if [[ $t0_packets -eq $t1_packets && $t0_bytes -eq $t1_bytes ]]; then + return 0 + else + return 1 + fi +} + +devlink_traps_enable_all() +{ + local trap_name + + for trap_name in $(devlink_traps_get); do + devlink_trap_action_set $trap_name "trap" + done +} + +devlink_traps_disable_all() +{ + for trap_name in $(devlink_traps_get); do + devlink_trap_action_set $trap_name "drop" + done +} + +devlink_trap_groups_get() +{ + devlink -j trap group | jq -r '.[]["'$DEVLINK_DEV'"][].name' +} + +devlink_trap_group_action_set() +{ + local group_name=$1; shift + local action=$1; shift + + # Pipe output to /dev/null to avoid expected warnings. + devlink trap group set $DEVLINK_DEV group $group_name action $action \ + &> /dev/null +} + +devlink_trap_group_rx_packets_get() +{ + local group_name=$1; shift + + devlink -js trap group show $DEVLINK_DEV group $group_name \ + | jq '.[][][]["stats"]["rx"]["packets"]' +} + +devlink_trap_group_rx_bytes_get() +{ + local group_name=$1; shift + + devlink -js trap group show $DEVLINK_DEV group $group_name \ + | jq '.[][][]["stats"]["rx"]["bytes"]' +} + +devlink_trap_group_stats_idle_test() +{ + local group_name=$1; shift + local t0_packets t0_bytes + local t1_packets t1_bytes + + t0_packets=$(devlink_trap_group_rx_packets_get $group_name) + t0_bytes=$(devlink_trap_group_rx_bytes_get $group_name) + + sleep 1 + + t1_packets=$(devlink_trap_group_rx_packets_get $group_name) + t1_bytes=$(devlink_trap_group_rx_bytes_get $group_name) + + if [[ $t0_packets -eq $t1_packets && $t0_bytes -eq $t1_bytes ]]; then + return 0 + else + return 1 + fi +} -- cgit v1.2.3-59-g8ed1b From b3cb7df9ecb5d73a7a116a50a92ad992f20798cf Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Sat, 17 Aug 2019 16:28:24 +0300 Subject: selftests: devlink_trap: Add test cases for devlink-trap Add test cases for devlink-trap on top of the netdevsim implementation. The tests focus on the devlink-trap core infrastructure and user space API. They test both good and bad flows and also dismantle of the netdev and devlink device used to report trapped packets. This allows device drivers to focus their tests on device-specific functionality. Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- .../drivers/net/netdevsim/devlink_trap.sh | 364 +++++++++++++++++++++ 1 file changed, 364 insertions(+) create mode 100755 tools/testing/selftests/drivers/net/netdevsim/devlink_trap.sh (limited to 'tools') diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink_trap.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink_trap.sh new file mode 100755 index 000000000000..f101ab9441e2 --- /dev/null +++ b/tools/testing/selftests/drivers/net/netdevsim/devlink_trap.sh @@ -0,0 +1,364 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# This test is for checking devlink-trap functionality. It makes use of +# netdevsim which implements the required callbacks. + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + init_test + trap_action_test + trap_metadata_test + bad_trap_test + bad_trap_action_test + trap_stats_test + trap_group_action_test + bad_trap_group_test + trap_group_stats_test + port_del_test + dev_del_test +" +NETDEVSIM_PATH=/sys/bus/netdevsim/ +DEV_ADDR=1337 +DEV=netdevsim${DEV_ADDR} +DEVLINK_DEV=netdevsim/${DEV} +SLEEP_TIME=1 +NETDEV="" +NUM_NETIFS=0 +source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh + +require_command udevadm + +modprobe netdevsim &> /dev/null +if [ ! -d "$NETDEVSIM_PATH" ]; then + echo "SKIP: No netdevsim support" + exit 1 +fi + +if [ -d "${NETDEVSIM_PATH}/devices/netdevsim${DEV_ADDR}" ]; then + echo "SKIP: Device netdevsim${DEV_ADDR} already exists" + exit 1 +fi + +init_test() +{ + RET=0 + + test $(devlink_traps_num_get) -ne 0 + check_err $? "No traps were registered" + + log_test "Initialization" +} + +trap_action_test() +{ + local orig_action + local trap_name + local action + + RET=0 + + for trap_name in $(devlink_traps_get); do + # The action of non-drop traps cannot be changed. + if [ $(devlink_trap_type_get $trap_name) = "drop" ]; then + devlink_trap_action_set $trap_name "trap" + action=$(devlink_trap_action_get $trap_name) + if [ $action != "trap" ]; then + check_err 1 "Trap $trap_name did not change action to trap" + fi + + devlink_trap_action_set $trap_name "drop" + action=$(devlink_trap_action_get $trap_name) + if [ $action != "drop" ]; then + check_err 1 "Trap $trap_name did not change action to drop" + fi + else + orig_action=$(devlink_trap_action_get $trap_name) + + devlink_trap_action_set $trap_name "trap" + action=$(devlink_trap_action_get $trap_name) + if [ $action != $orig_action ]; then + check_err 1 "Trap $trap_name changed action when should not" + fi + + devlink_trap_action_set $trap_name "drop" + action=$(devlink_trap_action_get $trap_name) + if [ $action != $orig_action ]; then + check_err 1 "Trap $trap_name changed action when should not" + fi + fi + done + + log_test "Trap action" +} + +trap_metadata_test() +{ + local trap_name + + RET=0 + + for trap_name in $(devlink_traps_get); do + devlink_trap_metadata_test $trap_name "input_port" + check_err $? "Input port not reported as metadata of trap $trap_name" + done + + log_test "Trap metadata" +} + +bad_trap_test() +{ + RET=0 + + devlink_trap_action_set "made_up_trap" "drop" + check_fail $? "Did not get an error for non-existing trap" + + log_test "Non-existing trap" +} + +bad_trap_action_test() +{ + local traps_arr + local trap_name + + RET=0 + + # Pick first trap. + traps_arr=($(devlink_traps_get)) + trap_name=${traps_arr[0]} + + devlink_trap_action_set $trap_name "made_up_action" + check_fail $? "Did not get an error for non-existing trap action" + + log_test "Non-existing trap action" +} + +trap_stats_test() +{ + local trap_name + + RET=0 + + for trap_name in $(devlink_traps_get); do + devlink_trap_stats_idle_test $trap_name + check_err $? "Stats of trap $trap_name not idle when netdev down" + + ip link set dev $NETDEV up + + if [ $(devlink_trap_type_get $trap_name) = "drop" ]; then + devlink_trap_action_set $trap_name "trap" + devlink_trap_stats_idle_test $trap_name + check_fail $? "Stats of trap $trap_name idle when action is trap" + + devlink_trap_action_set $trap_name "drop" + devlink_trap_stats_idle_test $trap_name + check_err $? "Stats of trap $trap_name not idle when action is drop" + else + devlink_trap_stats_idle_test $trap_name + check_fail $? "Stats of non-drop trap $trap_name idle when should not" + fi + + ip link set dev $NETDEV down + done + + log_test "Trap statistics" +} + +trap_group_action_test() +{ + local curr_group group_name + local trap_name + local trap_type + local action + + RET=0 + + for group_name in $(devlink_trap_groups_get); do + devlink_trap_group_action_set $group_name "trap" + + for trap_name in $(devlink_traps_get); do + curr_group=$(devlink_trap_group_get $trap_name) + if [ $curr_group != $group_name ]; then + continue + fi + + trap_type=$(devlink_trap_type_get $trap_name) + if [ $trap_type != "drop" ]; then + continue + fi + + action=$(devlink_trap_action_get $trap_name) + if [ $action != "trap" ]; then + check_err 1 "Trap $trap_name did not change action to trap" + fi + done + + devlink_trap_group_action_set $group_name "drop" + + for trap_name in $(devlink_traps_get); do + curr_group=$(devlink_trap_group_get $trap_name) + if [ $curr_group != $group_name ]; then + continue + fi + + trap_type=$(devlink_trap_type_get $trap_name) + if [ $trap_type != "drop" ]; then + continue + fi + + action=$(devlink_trap_action_get $trap_name) + if [ $action != "drop" ]; then + check_err 1 "Trap $trap_name did not change action to drop" + fi + done + done + + log_test "Trap group action" +} + +bad_trap_group_test() +{ + RET=0 + + devlink_trap_group_action_set "made_up_trap_group" "drop" + check_fail $? "Did not get an error for non-existing trap group" + + log_test "Non-existing trap group" +} + +trap_group_stats_test() +{ + local group_name + + RET=0 + + for group_name in $(devlink_trap_groups_get); do + devlink_trap_group_stats_idle_test $group_name + check_err $? "Stats of trap group $group_name not idle when netdev down" + + ip link set dev $NETDEV up + + devlink_trap_group_action_set $group_name "trap" + devlink_trap_group_stats_idle_test $group_name + check_fail $? "Stats of trap group $group_name idle when action is trap" + + devlink_trap_group_action_set $group_name "drop" + ip link set dev $NETDEV down + done + + log_test "Trap group statistics" +} + +port_del_test() +{ + local group_name + local i + + # The test never fails. It is meant to exercise different code paths + # and make sure we properly dismantle a port while packets are + # in-flight. + RET=0 + + devlink_traps_enable_all + + for i in $(seq 1 10); do + ip link set dev $NETDEV up + + sleep $SLEEP_TIME + + netdevsim_port_destroy + netdevsim_port_create + udevadm settle + done + + devlink_traps_disable_all + + log_test "Port delete" +} + +dev_del_test() +{ + local group_name + local i + + # The test never fails. It is meant to exercise different code paths + # and make sure we properly unregister traps while packets are + # in-flight. + RET=0 + + devlink_traps_enable_all + + for i in $(seq 1 10); do + ip link set dev $NETDEV up + + sleep $SLEEP_TIME + + cleanup + setup_prepare + done + + devlink_traps_disable_all + + log_test "Device delete" +} + +netdevsim_dev_create() +{ + echo "$DEV_ADDR 0" > ${NETDEVSIM_PATH}/new_device +} + +netdevsim_dev_destroy() +{ + echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device +} + +netdevsim_port_create() +{ + echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/new_port +} + +netdevsim_port_destroy() +{ + echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/del_port +} + +setup_prepare() +{ + local netdev + + netdevsim_dev_create + + if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}" ]; then + echo "Failed to create netdevsim device" + exit 1 + fi + + netdevsim_port_create + + if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}/net/" ]; then + echo "Failed to create netdevsim port" + exit 1 + fi + + # Wait for udev to rename newly created netdev. + udevadm settle + + NETDEV=$(ls ${NETDEVSIM_PATH}/devices/${DEV}/net/) +} + +cleanup() +{ + pre_cleanup + netdevsim_port_destroy + netdevsim_dev_destroy +} + +trap cleanup EXIT + +setup_prepare + +tests_run + +exit $EXIT_STATUS -- cgit v1.2.3-59-g8ed1b From a4500432c2587cb2ae7554537886a4516ff2e7aa Mon Sep 17 00:00:00 2001 From: Magnus Karlsson Date: Wed, 14 Aug 2019 09:27:20 +0200 Subject: libbpf: add support for need_wakeup flag in AF_XDP part This commit adds support for the new need_wakeup flag in AF_XDP. The xsk_socket__create function is updated to handle this and a new function is introduced called xsk_ring_prod__needs_wakeup(). This function can be used by the application to check if Rx and/or Tx processing needs to be explicitly woken up. Signed-off-by: Magnus Karlsson Acked-by: Jonathan Lemon Signed-off-by: Daniel Borkmann --- tools/include/uapi/linux/if_xdp.h | 13 +++++++++++++ tools/lib/bpf/xsk.c | 4 ++++ tools/lib/bpf/xsk.h | 6 ++++++ 3 files changed, 23 insertions(+) (limited to 'tools') diff --git a/tools/include/uapi/linux/if_xdp.h b/tools/include/uapi/linux/if_xdp.h index faaa5ca2a117..62b80d57b72a 100644 --- a/tools/include/uapi/linux/if_xdp.h +++ b/tools/include/uapi/linux/if_xdp.h @@ -16,6 +16,15 @@ #define XDP_SHARED_UMEM (1 << 0) #define XDP_COPY (1 << 1) /* Force copy-mode */ #define XDP_ZEROCOPY (1 << 2) /* Force zero-copy mode */ +/* If this option is set, the driver might go sleep and in that case + * the XDP_RING_NEED_WAKEUP flag in the fill and/or Tx rings will be + * set. If it is set, the application need to explicitly wake up the + * driver with a poll() (Rx and Tx) or sendto() (Tx only). If you are + * running the driver and the application on the same core, you should + * use this option so that the kernel will yield to the user space + * application. + */ +#define XDP_USE_NEED_WAKEUP (1 << 3) struct sockaddr_xdp { __u16 sxdp_family; @@ -25,10 +34,14 @@ struct sockaddr_xdp { __u32 sxdp_shared_umem_fd; }; +/* XDP_RING flags */ +#define XDP_RING_NEED_WAKEUP (1 << 0) + struct xdp_ring_offset { __u64 producer; __u64 consumer; __u64 desc; + __u64 flags; }; struct xdp_mmap_offsets { diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c index 680e63066cf3..17e8d79c11a8 100644 --- a/tools/lib/bpf/xsk.c +++ b/tools/lib/bpf/xsk.c @@ -224,6 +224,7 @@ int xsk_umem__create(struct xsk_umem **umem_ptr, void *umem_area, __u64 size, fill->size = umem->config.fill_size; fill->producer = map + off.fr.producer; fill->consumer = map + off.fr.consumer; + fill->flags = map + off.fr.flags; fill->ring = map + off.fr.desc; fill->cached_cons = umem->config.fill_size; @@ -241,6 +242,7 @@ int xsk_umem__create(struct xsk_umem **umem_ptr, void *umem_area, __u64 size, comp->size = umem->config.comp_size; comp->producer = map + off.cr.producer; comp->consumer = map + off.cr.consumer; + comp->flags = map + off.cr.flags; comp->ring = map + off.cr.desc; *umem_ptr = umem; @@ -564,6 +566,7 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname, rx->size = xsk->config.rx_size; rx->producer = rx_map + off.rx.producer; rx->consumer = rx_map + off.rx.consumer; + rx->flags = rx_map + off.rx.flags; rx->ring = rx_map + off.rx.desc; } xsk->rx = rx; @@ -583,6 +586,7 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname, tx->size = xsk->config.tx_size; tx->producer = tx_map + off.tx.producer; tx->consumer = tx_map + off.tx.consumer; + tx->flags = tx_map + off.tx.flags; tx->ring = tx_map + off.tx.desc; tx->cached_cons = xsk->config.tx_size; } diff --git a/tools/lib/bpf/xsk.h b/tools/lib/bpf/xsk.h index 833a6e60d065..aa1d6122b7db 100644 --- a/tools/lib/bpf/xsk.h +++ b/tools/lib/bpf/xsk.h @@ -32,6 +32,7 @@ struct name { \ __u32 *producer; \ __u32 *consumer; \ void *ring; \ + __u32 *flags; \ } DEFINE_XSK_RING(xsk_ring_prod); @@ -76,6 +77,11 @@ xsk_ring_cons__rx_desc(const struct xsk_ring_cons *rx, __u32 idx) return &descs[idx & rx->mask]; } +static inline int xsk_ring_prod__needs_wakeup(const struct xsk_ring_prod *r) +{ + return *r->flags & XDP_RING_NEED_WAKEUP; +} + static inline __u32 xsk_prod_nb_free(struct xsk_ring_prod *r, __u32 nb) { __u32 free_entries = r->cached_cons - r->cached_prod; -- cgit v1.2.3-59-g8ed1b From 929ffa6e9df0832fdf541ff2d9532e209153c0ec Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Thu, 15 Aug 2019 22:45:43 -0700 Subject: libbpf: relicense bpf_helpers.h and bpf_endian.h bpf_helpers.h and bpf_endian.h contain useful macros and BPF helper definitions essential to almost every BPF program. Which makes them useful not just for selftests. To be able to expose them as part of libbpf, though, we need them to be dual-licensed as LGPL-2.1 OR BSD-2-Clause. This patch updates licensing of those two files. Acked-by: Alexei Starovoitov Acked-by: Hechao Li Acked-by: Martin KaFai Lau Acked-by: Andrey Ignatov Acked-by: Yonghong Song Acked-by: Lawrence Brakmo Acked-by: Adam Barth Acked-by: Roman Gushchin Acked-by: Josef Bacik Acked-by: Joe Stringer Acked-by: Daniel Borkmann Acked-by: Joel Fernandes (Google) Acked-by: David Ahern Acked-by: Jesper Dangaard Brouer Acked-by: Ilya Leoshkevich Acked-by: Lorenz Bauer Acked-by: Adrian Ratiu Acked-by: Nikita V. Shirokov Acked-by: Willem de Bruijn Acked-by: Petar Penkov Acked-by: Teng Qin Cc: Michael Holzheu Cc: Naveen N. Rao Cc: David S. Miller Cc: Michal Rostecki Cc: John Fastabend Cc: Sargun Dhillon Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/bpf_endian.h | 2 +- tools/testing/selftests/bpf/bpf_helpers.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/bpf_endian.h b/tools/testing/selftests/bpf/bpf_endian.h index 05f036df8a4c..ff3593b0ae03 100644 --- a/tools/testing/selftests/bpf/bpf_endian.h +++ b/tools/testing/selftests/bpf/bpf_endian.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ #ifndef __BPF_ENDIAN__ #define __BPF_ENDIAN__ diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h index 8b503ea142f0..6c4930bc6e2e 100644 --- a/tools/testing/selftests/bpf/bpf_helpers.h +++ b/tools/testing/selftests/bpf/bpf_helpers.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ #ifndef __BPF_HELPERS_H #define __BPF_HELPERS_H -- cgit v1.2.3-59-g8ed1b From fae55527ac1164b66bee983a4d82ade2bfedb332 Mon Sep 17 00:00:00 2001 From: Petar Penkov Date: Fri, 16 Aug 2019 10:08:25 -0700 Subject: selftests/bpf: fix race in test_tcp_rtt test There is a race in this test between receiving the ACK for the single-byte packet sent in the test, and reading the values from the map. This patch fixes this by having the client wait until there are no more unacknowledged packets. Before: for i in {1..1000}; do ../net/in_netns.sh ./test_tcp_rtt; \ done | grep -c PASSED < trimmed error messages > 993 After: for i in {1..10000}; do ../net/in_netns.sh ./test_tcp_rtt; \ done | grep -c PASSED 10000 Fixes: b55873984dab ("selftests/bpf: test BPF_SOCK_OPS_RTT_CB") Signed-off-by: Petar Penkov Reviewed-by: Stanislav Fomichev Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/test_tcp_rtt.c | 31 ++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_tcp_rtt.c b/tools/testing/selftests/bpf/test_tcp_rtt.c index 90c3862f74a8..93916a69823e 100644 --- a/tools/testing/selftests/bpf/test_tcp_rtt.c +++ b/tools/testing/selftests/bpf/test_tcp_rtt.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -34,6 +35,30 @@ static void send_byte(int fd) error(1, errno, "Failed to send single byte"); } +static int wait_for_ack(int fd, int retries) +{ + struct tcp_info info; + socklen_t optlen; + int i, err; + + for (i = 0; i < retries; i++) { + optlen = sizeof(info); + err = getsockopt(fd, SOL_TCP, TCP_INFO, &info, &optlen); + if (err < 0) { + log_err("Failed to lookup TCP stats"); + return err; + } + + if (info.tcpi_unacked == 0) + return 0; + + usleep(10); + } + + log_err("Did not receive ACK"); + return -1; +} + static int verify_sk(int map_fd, int client_fd, const char *msg, __u32 invoked, __u32 dsack_dups, __u32 delivered, __u32 delivered_ce, __u32 icsk_retransmits) @@ -149,6 +174,11 @@ static int run_test(int cgroup_fd, int server_fd) /*icsk_retransmits=*/0); send_byte(client_fd); + if (wait_for_ack(client_fd, 100) < 0) { + err = -1; + goto close_client_fd; + } + err += verify_sk(map_fd, client_fd, "first payload byte", /*invoked=*/2, @@ -157,6 +187,7 @@ static int run_test(int cgroup_fd, int server_fd) /*delivered_ce=*/0, /*icsk_retransmits=*/0); +close_client_fd: close(client_fd); close_bpf_object: -- cgit v1.2.3-59-g8ed1b From 9e819ffcfe35c3779166d0fc0088215cf4924c33 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Wed, 14 Aug 2019 10:37:50 -0700 Subject: bpf: sync bpf.h to tools/ Sync new sk storage clone flag. Cc: Martin KaFai Lau Cc: Yonghong Song Acked-by: Martin KaFai Lau Acked-by: Yonghong Song Signed-off-by: Stanislav Fomichev Signed-off-by: Daniel Borkmann --- tools/include/uapi/linux/bpf.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 4393bd4b2419..0ef594ac3899 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -337,6 +337,9 @@ enum bpf_attach_type { #define BPF_F_RDONLY_PROG (1U << 7) #define BPF_F_WRONLY_PROG (1U << 8) +/* Clone map from listener for newly accepted socket */ +#define BPF_F_CLONE (1U << 9) + /* flags for BPF_PROG_QUERY */ #define BPF_F_QUERY_EFFECTIVE (1U << 0) -- cgit v1.2.3-59-g8ed1b From c3bbf176fbad5d7470f8a4f311f7c11126ad36c2 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Wed, 14 Aug 2019 10:37:51 -0700 Subject: selftests/bpf: add sockopt clone/inheritance test Add a test that calls setsockopt on the listener socket which triggers BPF program. This BPF program writes to the sk storage and sets clone flag. Make sure that sk storage is cloned for a newly accepted connection. We have two cloned maps in the tests to make sure we hit both cases in bpf_sk_storage_clone: first element (sk_storage_alloc) and non-first element(s) (selem_link_map). Cc: Martin KaFai Lau Cc: Yonghong Song Acked-by: Martin KaFai Lau Acked-by: Yonghong Song Signed-off-by: Stanislav Fomichev Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/.gitignore | 1 + tools/testing/selftests/bpf/Makefile | 3 +- .../testing/selftests/bpf/progs/sockopt_inherit.c | 97 ++++++++ tools/testing/selftests/bpf/test_sockopt_inherit.c | 253 +++++++++++++++++++++ 4 files changed, 353 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/bpf/progs/sockopt_inherit.c create mode 100644 tools/testing/selftests/bpf/test_sockopt_inherit.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore index 90f70d2c7c22..60c9338cd9b4 100644 --- a/tools/testing/selftests/bpf/.gitignore +++ b/tools/testing/selftests/bpf/.gitignore @@ -42,4 +42,5 @@ xdping test_sockopt test_sockopt_sk test_sockopt_multi +test_sockopt_inherit test_tcp_rtt diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 29001f944db7..1faad0c3c3c9 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -29,7 +29,7 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test test_cgroup_storage test_select_reuseport test_section_names \ test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap \ test_btf_dump test_cgroup_attach xdping test_sockopt test_sockopt_sk \ - test_sockopt_multi test_tcp_rtt + test_sockopt_multi test_sockopt_inherit test_tcp_rtt BPF_OBJ_FILES = $(patsubst %.c,%.o, $(notdir $(wildcard progs/*.c))) TEST_GEN_FILES = $(BPF_OBJ_FILES) @@ -111,6 +111,7 @@ $(OUTPUT)/test_cgroup_attach: cgroup_helpers.c $(OUTPUT)/test_sockopt: cgroup_helpers.c $(OUTPUT)/test_sockopt_sk: cgroup_helpers.c $(OUTPUT)/test_sockopt_multi: cgroup_helpers.c +$(OUTPUT)/test_sockopt_inherit: cgroup_helpers.c $(OUTPUT)/test_tcp_rtt: cgroup_helpers.c .PHONY: force diff --git a/tools/testing/selftests/bpf/progs/sockopt_inherit.c b/tools/testing/selftests/bpf/progs/sockopt_inherit.c new file mode 100644 index 000000000000..dede0fcd6102 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/sockopt_inherit.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include "bpf_helpers.h" + +char _license[] SEC("license") = "GPL"; +__u32 _version SEC("version") = 1; + +#define SOL_CUSTOM 0xdeadbeef +#define CUSTOM_INHERIT1 0 +#define CUSTOM_INHERIT2 1 +#define CUSTOM_LISTENER 2 + +struct sockopt_inherit { + __u8 val; +}; + +struct { + __uint(type, BPF_MAP_TYPE_SK_STORAGE); + __uint(map_flags, BPF_F_NO_PREALLOC | BPF_F_CLONE); + __type(key, int); + __type(value, struct sockopt_inherit); +} cloned1_map SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_SK_STORAGE); + __uint(map_flags, BPF_F_NO_PREALLOC | BPF_F_CLONE); + __type(key, int); + __type(value, struct sockopt_inherit); +} cloned2_map SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_SK_STORAGE); + __uint(map_flags, BPF_F_NO_PREALLOC); + __type(key, int); + __type(value, struct sockopt_inherit); +} listener_only_map SEC(".maps"); + +static __inline struct sockopt_inherit *get_storage(struct bpf_sockopt *ctx) +{ + if (ctx->optname == CUSTOM_INHERIT1) + return bpf_sk_storage_get(&cloned1_map, ctx->sk, 0, + BPF_SK_STORAGE_GET_F_CREATE); + else if (ctx->optname == CUSTOM_INHERIT2) + return bpf_sk_storage_get(&cloned2_map, ctx->sk, 0, + BPF_SK_STORAGE_GET_F_CREATE); + else + return bpf_sk_storage_get(&listener_only_map, ctx->sk, 0, + BPF_SK_STORAGE_GET_F_CREATE); +} + +SEC("cgroup/getsockopt") +int _getsockopt(struct bpf_sockopt *ctx) +{ + __u8 *optval_end = ctx->optval_end; + struct sockopt_inherit *storage; + __u8 *optval = ctx->optval; + + if (ctx->level != SOL_CUSTOM) + return 1; /* only interested in SOL_CUSTOM */ + + if (optval + 1 > optval_end) + return 0; /* EPERM, bounds check */ + + storage = get_storage(ctx); + if (!storage) + return 0; /* EPERM, couldn't get sk storage */ + + ctx->retval = 0; /* Reset system call return value to zero */ + + optval[0] = storage->val; + ctx->optlen = 1; + + return 1; +} + +SEC("cgroup/setsockopt") +int _setsockopt(struct bpf_sockopt *ctx) +{ + __u8 *optval_end = ctx->optval_end; + struct sockopt_inherit *storage; + __u8 *optval = ctx->optval; + + if (ctx->level != SOL_CUSTOM) + return 1; /* only interested in SOL_CUSTOM */ + + if (optval + 1 > optval_end) + return 0; /* EPERM, bounds check */ + + storage = get_storage(ctx); + if (!storage) + return 0; /* EPERM, couldn't get sk storage */ + + storage->val = optval[0]; + ctx->optlen = -1; + + return 1; +} diff --git a/tools/testing/selftests/bpf/test_sockopt_inherit.c b/tools/testing/selftests/bpf/test_sockopt_inherit.c new file mode 100644 index 000000000000..1bf699815b9b --- /dev/null +++ b/tools/testing/selftests/bpf/test_sockopt_inherit.c @@ -0,0 +1,253 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "bpf_rlimit.h" +#include "bpf_util.h" +#include "cgroup_helpers.h" + +#define CG_PATH "/sockopt_inherit" +#define SOL_CUSTOM 0xdeadbeef +#define CUSTOM_INHERIT1 0 +#define CUSTOM_INHERIT2 1 +#define CUSTOM_LISTENER 2 + +static int connect_to_server(int server_fd) +{ + struct sockaddr_storage addr; + socklen_t len = sizeof(addr); + int fd; + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) { + log_err("Failed to create client socket"); + return -1; + } + + if (getsockname(server_fd, (struct sockaddr *)&addr, &len)) { + log_err("Failed to get server addr"); + goto out; + } + + if (connect(fd, (const struct sockaddr *)&addr, len) < 0) { + log_err("Fail to connect to server"); + goto out; + } + + return fd; + +out: + close(fd); + return -1; +} + +static int verify_sockopt(int fd, int optname, const char *msg, char expected) +{ + socklen_t optlen = 1; + char buf = 0; + int err; + + err = getsockopt(fd, SOL_CUSTOM, optname, &buf, &optlen); + if (err) { + log_err("%s: failed to call getsockopt", msg); + return 1; + } + + printf("%s %d: got=0x%x ? expected=0x%x\n", msg, optname, buf, expected); + + if (buf != expected) { + log_err("%s: unexpected getsockopt value %d != %d", msg, + buf, expected); + return 1; + } + + return 0; +} + +static void *server_thread(void *arg) +{ + struct sockaddr_storage addr; + socklen_t len = sizeof(addr); + int fd = *(int *)arg; + int client_fd; + int err = 0; + + if (listen(fd, 1) < 0) + error(1, errno, "Failed to listed on socket"); + + err += verify_sockopt(fd, CUSTOM_INHERIT1, "listen", 1); + err += verify_sockopt(fd, CUSTOM_INHERIT2, "listen", 1); + err += verify_sockopt(fd, CUSTOM_LISTENER, "listen", 1); + + client_fd = accept(fd, (struct sockaddr *)&addr, &len); + if (client_fd < 0) + error(1, errno, "Failed to accept client"); + + err += verify_sockopt(client_fd, CUSTOM_INHERIT1, "accept", 1); + err += verify_sockopt(client_fd, CUSTOM_INHERIT2, "accept", 1); + err += verify_sockopt(client_fd, CUSTOM_LISTENER, "accept", 0); + + close(client_fd); + + return (void *)(long)err; +} + +static int start_server(void) +{ + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_addr.s_addr = htonl(INADDR_LOOPBACK), + }; + char buf; + int err; + int fd; + int i; + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) { + log_err("Failed to create server socket"); + return -1; + } + + for (i = CUSTOM_INHERIT1; i <= CUSTOM_LISTENER; i++) { + buf = 0x01; + err = setsockopt(fd, SOL_CUSTOM, i, &buf, 1); + if (err) { + log_err("Failed to call setsockopt(%d)", i); + close(fd); + return -1; + } + } + + if (bind(fd, (const struct sockaddr *)&addr, sizeof(addr)) < 0) { + log_err("Failed to bind socket"); + close(fd); + return -1; + } + + return fd; +} + +static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title) +{ + enum bpf_attach_type attach_type; + enum bpf_prog_type prog_type; + struct bpf_program *prog; + int err; + + err = libbpf_prog_type_by_name(title, &prog_type, &attach_type); + if (err) { + log_err("Failed to deduct types for %s BPF program", title); + return -1; + } + + prog = bpf_object__find_program_by_title(obj, title); + if (!prog) { + log_err("Failed to find %s BPF program", title); + return -1; + } + + err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, + attach_type, 0); + if (err) { + log_err("Failed to attach %s BPF program", title); + return -1; + } + + return 0; +} + +static int run_test(int cgroup_fd) +{ + struct bpf_prog_load_attr attr = { + .file = "./sockopt_inherit.o", + }; + int server_fd = -1, client_fd; + struct bpf_object *obj; + void *server_err; + pthread_t tid; + int ignored; + int err; + + err = bpf_prog_load_xattr(&attr, &obj, &ignored); + if (err) { + log_err("Failed to load BPF object"); + return -1; + } + + err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt"); + if (err) + goto close_bpf_object; + + err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt"); + if (err) + goto close_bpf_object; + + server_fd = start_server(); + if (server_fd < 0) { + err = -1; + goto close_bpf_object; + } + + pthread_create(&tid, NULL, server_thread, (void *)&server_fd); + + client_fd = connect_to_server(server_fd); + if (client_fd < 0) { + err = -1; + goto close_server_fd; + } + + err += verify_sockopt(client_fd, CUSTOM_INHERIT1, "connect", 0); + err += verify_sockopt(client_fd, CUSTOM_INHERIT2, "connect", 0); + err += verify_sockopt(client_fd, CUSTOM_LISTENER, "connect", 0); + + pthread_join(tid, &server_err); + + err += (int)(long)server_err; + + close(client_fd); + +close_server_fd: + close(server_fd); +close_bpf_object: + bpf_object__close(obj); + return err; +} + +int main(int args, char **argv) +{ + int cgroup_fd; + int err = EXIT_SUCCESS; + + if (setup_cgroup_environment()) + return err; + + cgroup_fd = create_and_get_cgroup(CG_PATH); + if (cgroup_fd < 0) + goto cleanup_cgroup_env; + + if (join_cgroup(CG_PATH)) + goto cleanup_cgroup; + + if (run_test(cgroup_fd)) + err = EXIT_FAILURE; + + printf("test_sockopt_inherit: %s\n", + err == EXIT_SUCCESS ? "PASSED" : "FAILED"); + +cleanup_cgroup: + close(cgroup_fd); +cleanup_cgroup_env: + cleanup_cgroup_environment(); + return err; +} -- cgit v1.2.3-59-g8ed1b From a5913d009b28a2386326143c70fdbe577ea9478d Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Mon, 12 Aug 2019 14:41:41 +0200 Subject: tools: iio: add .gitignore The generated files must not be tracked by git. Add a local .gitignore. Signed-off-by: Bartosz Golaszewski Signed-off-by: Jonathan Cameron --- tools/iio/.gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 tools/iio/.gitignore (limited to 'tools') diff --git a/tools/iio/.gitignore b/tools/iio/.gitignore new file mode 100644 index 000000000000..3758202618bd --- /dev/null +++ b/tools/iio/.gitignore @@ -0,0 +1,4 @@ +iio_event_monitor +iio_generic_buffer +lsiio +include/ -- cgit v1.2.3-59-g8ed1b From 74585fcb7b3ccb35135e2418dd66251022a916e5 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Mon, 19 Aug 2019 15:14:42 +0200 Subject: selftests, arm64: fix uninitialized symbol in tags_test.c Fix tagged_ptr not being initialized when TBI is not enabled. Link: https://www.spinics.net/lists/linux-kselftest/msg09446.html Reported-by: Dan Carpenter Signed-off-by: Andrey Konovalov Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/tags_test.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/arm64/tags_test.c b/tools/testing/selftests/arm64/tags_test.c index 22a1b266e373..5701163460ef 100644 --- a/tools/testing/selftests/arm64/tags_test.c +++ b/tools/testing/selftests/arm64/tags_test.c @@ -14,15 +14,17 @@ int main(void) { static int tbi_enabled = 0; - struct utsname *ptr, *tagged_ptr; + unsigned long tag = 0; + struct utsname *ptr; int err; if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == 0) tbi_enabled = 1; ptr = (struct utsname *)malloc(sizeof(*ptr)); if (tbi_enabled) - tagged_ptr = (struct utsname *)SET_TAG(ptr, 0x42); - err = uname(tagged_ptr); + tag = 0x42; + ptr = (struct utsname *)SET_TAG(ptr, tag); + err = uname(ptr); free(ptr); return err; -- cgit v1.2.3-59-g8ed1b From 0ac33e4e9b5e4ccdd43c9d4e77882a1af0e41dec Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Fri, 16 Aug 2019 18:06:04 +0200 Subject: selftests: use "$(MAKE)" instead of "make" When doing "make kselftest TARGETS=bpf -j12", bpf progs end up being compiled sequentially and thus slowly. The reason is that parent make (tools/testing/selftests/Makefile) does not share its jobserver with child make (tools/testing/selftests/bpf/Makefile), therefore the latter runs with -j1. Change all instances of "make" to "$(MAKE)", so that the whole make hierarchy runs using a single jobserver. Signed-off-by: Ilya Leoshkevich Signed-off-by: Shuah Khan --- tools/testing/selftests/Makefile | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 25b43a8c2b15..c3feccb99ff5 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -126,9 +126,9 @@ endif # in the default INSTALL_HDR_PATH usr/include. khdr: ifeq (1,$(DEFAULT_INSTALL_HDR_PATH)) - make --no-builtin-rules ARCH=$(ARCH) -C $(top_srcdir) headers_install + $(MAKE) --no-builtin-rules ARCH=$(ARCH) -C $(top_srcdir) headers_install else - make --no-builtin-rules INSTALL_HDR_PATH=$$BUILD/usr \ + $(MAKE) --no-builtin-rules INSTALL_HDR_PATH=$$BUILD/usr \ ARCH=$(ARCH) -C $(top_srcdir) headers_install endif @@ -136,35 +136,35 @@ all: khdr @for TARGET in $(TARGETS); do \ BUILD_TARGET=$$BUILD/$$TARGET; \ mkdir $$BUILD_TARGET -p; \ - make OUTPUT=$$BUILD_TARGET -C $$TARGET;\ + $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET;\ done; run_tests: all @for TARGET in $(TARGETS); do \ BUILD_TARGET=$$BUILD/$$TARGET; \ - make OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests;\ + $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests;\ done; hotplug: @for TARGET in $(TARGETS_HOTPLUG); do \ BUILD_TARGET=$$BUILD/$$TARGET; \ - make OUTPUT=$$BUILD_TARGET -C $$TARGET;\ + $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET;\ done; run_hotplug: hotplug @for TARGET in $(TARGETS_HOTPLUG); do \ BUILD_TARGET=$$BUILD/$$TARGET; \ - make OUTPUT=$$BUILD_TARGET -C $$TARGET run_full_test;\ + $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_full_test;\ done; clean_hotplug: @for TARGET in $(TARGETS_HOTPLUG); do \ BUILD_TARGET=$$BUILD/$$TARGET; \ - make OUTPUT=$$BUILD_TARGET -C $$TARGET clean;\ + $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean;\ done; run_pstore_crash: - make -C pstore run_crash + $(MAKE) -C pstore run_crash # Use $BUILD as the default install root. $BUILD points to the # right output location for the following cases: @@ -184,7 +184,7 @@ ifdef INSTALL_PATH install -m 744 kselftest/prefix.pl $(INSTALL_PATH)/kselftest/ @for TARGET in $(TARGETS); do \ BUILD_TARGET=$$BUILD/$$TARGET; \ - make OUTPUT=$$BUILD_TARGET -C $$TARGET INSTALL_PATH=$(INSTALL_PATH)/$$TARGET install; \ + $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET INSTALL_PATH=$(INSTALL_PATH)/$$TARGET install; \ done; @# Ask all targets to emit their test scripts @@ -203,7 +203,7 @@ ifdef INSTALL_PATH echo "[ -w /dev/kmsg ] && echo \"kselftest: Running tests in $$TARGET\" >> /dev/kmsg" >> $(ALL_SCRIPT); \ echo "cd $$TARGET" >> $(ALL_SCRIPT); \ echo -n "run_many" >> $(ALL_SCRIPT); \ - make -s --no-print-directory OUTPUT=$$BUILD_TARGET -C $$TARGET emit_tests >> $(ALL_SCRIPT); \ + $(MAKE) -s --no-print-directory OUTPUT=$$BUILD_TARGET -C $$TARGET emit_tests >> $(ALL_SCRIPT); \ echo "" >> $(ALL_SCRIPT); \ echo "cd \$$ROOT" >> $(ALL_SCRIPT); \ done; @@ -216,7 +216,7 @@ endif clean: @for TARGET in $(TARGETS); do \ BUILD_TARGET=$$BUILD/$$TARGET; \ - make OUTPUT=$$BUILD_TARGET -C $$TARGET clean;\ + $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean;\ done; .PHONY: khdr all run_tests hotplug run_hotplug clean_hotplug run_pstore_crash install clean -- cgit v1.2.3-59-g8ed1b From c11a99e7942383a11ef858aa1679a94d6eea5917 Mon Sep 17 00:00:00 2001 From: Vlad Buslov Date: Mon, 19 Aug 2019 10:52:07 +0300 Subject: tc-testing: use dedicated DUMMY interface name for dummy dev A lot of tests reuse $DEV1 veth name for naming dummy device. This causes problem when tdc is invoked without specifying a test group and tries to execute all tests. In this case tdc instantiates ns plugin, which creates veth pair once before running tests. However, if any of the tests that reuse $DEV1 run before test that depend on ns plugin, it will delete $DEV1 as a part of teardown section: =====> Test 3b88: Delete ingress qdisc twice [3770/41080] -----> prepare stage ns/SubPlugin.adjust_command adjust_command: stage is setup; inserting netns stuff in command [/sbin/ip link add dev v0p1 type dummy || /bin/true] list [['/sbin/ip', 'link', 'add', 'dev', 'v0p1', 'type', 'dummy', '||', '/bin/true']] adjust_command: return command [ip netns exec tcut /sbin/ip link add dev v0p1 type dummy || /bin/true] command "ip netns exec tcut /sbin/ip link add dev v0p1 type dummy || /bin/true" ns/SubPlugin.adjust_command adjust_command: stage is setup; inserting netns stuff in command [/sbin/tc qdisc add dev v0p1 ingress] list [['/sbin/tc', 'qdisc', 'add', 'dev', 'v0p1', 'ingress']] adjust_command: return command [ip netns exec tcut /sbin/tc qdisc add dev v0p1 ingress] command "ip netns exec tcut /sbin/tc qdisc add dev v0p1 ingress" ns/SubPlugin.adjust_command adjust_command: stage is setup; inserting netns stuff in command [/sbin/tc qdisc del dev v0p1 ingress] list [['/sbin/tc', 'qdisc', 'del', 'dev', 'v0p1', 'ingress']] adjust_command: return command [ip netns exec tcut /sbin/tc qdisc del dev v0p1 ingress] command "ip netns exec tcut /sbin/tc qdisc del dev v0p1 ingress" -----> execute stage ns/SubPlugin.adjust_command adjust_command: stage is execute; inserting netns stuff in command [/sbin/tc qdisc del dev v0p1 ingress] list [['/sbin/tc', 'qdisc', 'del', 'dev', 'v0p1', 'ingress']] adjust_command: return command [ip netns exec tcut /sbin/tc qdisc del dev v0p1 ingress] command "ip netns exec tcut /sbin/tc qdisc del dev v0p1 ingress" -----> verify stage ns/SubPlugin.adjust_command adjust_command: stage is verify; inserting netns stuff in command [/sbin/tc qdisc show dev v0p1] list [['/sbin/tc', 'qdisc', 'show', 'dev', 'v0p1']] adjust_command: return command [ip netns exec tcut /sbin/tc qdisc show dev v0p1] command "ip netns exec tcut /sbin/tc qdisc show dev v0p1" -----> teardown stage ns/SubPlugin.adjust_command adjust_command: stage is teardown; inserting netns stuff in command [/sbin/ip link del dev v0p1 type dummy] list [['/sbin/ip', 'link', 'del', 'dev', 'v0p1', 'type', 'dummy']] adjust_command: return command [ip netns exec tcut /sbin/ip link del dev v0p1 type dummy] command "ip netns exec tcut /sbin/ip link del dev v0p1 type dummy" After this ns-dependent tests will fail because dev doesn't exist: =====> Test 901f: Add fw filter with prio at 32-bit maxixum -----> prepare stage ns/SubPlugin.adjust_command adjust_command: stage is setup; inserting netns stuff in command [/sbin/tc qdisc add dev v0p1 ingress] list [['/sbin/tc', 'qdisc', 'add', 'dev', 'v0p1', 'ingress']] adjust_command: return command [ip netns exec tcut /sbin/tc qdisc add dev v0p1 ingress] command "ip netns exec tcut /sbin/tc qdisc add dev v0p1 ingress" -----> prepare stage *** Could not execute: "$TC qdisc add dev $DEV1 ingress" -----> prepare stage *** Error message: "Cannot find device "v0p1" " returncode 1; expected [0] -----> prepare stage *** Aborting test run. <_io.BufferedReader name=3> *** stdout *** <_io.BufferedReader name=5> *** stderr *** "-----> prepare stage" did not complete successfully Exception ('setup', None, '"-----> prepare stage" did not complete successfully') (caught in test_runner, running test 477 901f Add fw filter with prio at 32-bit maxixum stage setup) --------------- traceback File "./tdc.py", line 371, in test_runner res = run_one_test(pm, args, index, tidx) File "./tdc.py", line 272, in run_one_test prepare_env(args, pm, 'setup', "-----> prepare stage", tidx["setup"]) File "./tdc.py", line 247, in prepare_env '"{}" did not complete successfully'.format(prefix)) --------------- Fix the issue by introducing standalone $DUMMY config variable and substitute all usage of $DEV1 in tests that don't depend on ns plugin. Fixes: 489ce2f42514 ("tc-testing: Restore original behaviour for namespaces in tdc") Signed-off-by: Vlad Buslov Signed-off-by: David S. Miller --- .../tc-testing/tc-tests/filters/matchall.json | 242 ++++++++++----------- .../selftests/tc-testing/tc-tests/qdiscs/fifo.json | 150 ++++++------- .../tc-testing/tc-tests/qdiscs/ingress.json | 50 ++--- .../selftests/tc-testing/tc-tests/qdiscs/prio.json | 128 +++++------ tools/testing/selftests/tc-testing/tdc_config.py | 1 + 5 files changed, 286 insertions(+), 285 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/tc-testing/tc-tests/filters/matchall.json b/tools/testing/selftests/tc-testing/tc-tests/filters/matchall.json index 5f24c0598624..51799874a972 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/filters/matchall.json +++ b/tools/testing/selftests/tc-testing/tc-tests/filters/matchall.json @@ -7,17 +7,17 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 ingress" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY ingress" ], - "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ip matchall action ok", + "cmdUnderTest": "$TC filter add dev $DUMMY parent ffff: handle 0x1 prio 1 protocol ip matchall action ok", "expExitCode": "0", - "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol ip matchall", + "verifyCmd": "$TC filter get dev $DUMMY parent ffff: handle 1 prio 1 protocol ip matchall", "matchPattern": "^filter parent ffff: protocol ip pref 1 matchall.*handle 0x1.*gact action pass.*ref 1 bind 1", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 ingress", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY ingress", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -28,17 +28,17 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 root handle 1: prio" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY root handle 1: prio" ], - "cmdUnderTest": "$TC filter add dev $DEV1 parent 1: handle 0x1 prio 1 protocol ip matchall action ok", + "cmdUnderTest": "$TC filter add dev $DUMMY parent 1: handle 0x1 prio 1 protocol ip matchall action ok", "expExitCode": "0", - "verifyCmd": "$TC filter get dev $DEV1 parent 1: handle 1 prio 1 protocol ip matchall", + "verifyCmd": "$TC filter get dev $DUMMY parent 1: handle 1 prio 1 protocol ip matchall", "matchPattern": "^filter parent 1: protocol ip pref 1 matchall.*handle 0x1.*gact action pass.*ref 1 bind 1", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 root handle 1: prio", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY root handle 1: prio", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -49,17 +49,17 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 ingress" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY ingress" ], - "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv6 matchall action drop", + "cmdUnderTest": "$TC filter add dev $DUMMY parent ffff: handle 0x1 prio 1 protocol ipv6 matchall action drop", "expExitCode": "0", - "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol ipv6 matchall", + "verifyCmd": "$TC filter get dev $DUMMY parent ffff: handle 1 prio 1 protocol ipv6 matchall", "matchPattern": "^filter parent ffff: protocol ipv6 pref 1 matchall.*handle 0x1.*gact action drop.*ref 1 bind 1", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 ingress", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY ingress", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -70,17 +70,17 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 root handle 1: prio" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY root handle 1: prio" ], - "cmdUnderTest": "$TC filter add dev $DEV1 parent 1: handle 0x1 prio 1 protocol ipv6 matchall action drop", + "cmdUnderTest": "$TC filter add dev $DUMMY parent 1: handle 0x1 prio 1 protocol ipv6 matchall action drop", "expExitCode": "0", - "verifyCmd": "$TC filter get dev $DEV1 parent 1: handle 1 prio 1 protocol ipv6 matchall", + "verifyCmd": "$TC filter get dev $DUMMY parent 1: handle 1 prio 1 protocol ipv6 matchall", "matchPattern": "^filter parent 1: protocol ipv6 pref 1 matchall.*handle 0x1.*gact action drop.*ref 1 bind 1", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 root handle 1: prio", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY root handle 1: prio", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -91,17 +91,17 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 ingress" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY ingress" ], - "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 65535 protocol ipv4 matchall action pass", + "cmdUnderTest": "$TC filter add dev $DUMMY parent ffff: handle 0x1 prio 65535 protocol ipv4 matchall action pass", "expExitCode": "0", - "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 65535 protocol ipv4 matchall", + "verifyCmd": "$TC filter get dev $DUMMY parent ffff: handle 1 prio 65535 protocol ipv4 matchall", "matchPattern": "^filter parent ffff: protocol ip pref 65535 matchall.*handle 0x1.*gact action pass.*ref 1 bind 1", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 ingress", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY ingress", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -112,17 +112,17 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 root handle 1: prio" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY root handle 1: prio" ], - "cmdUnderTest": "$TC filter add dev $DEV1 parent 1: handle 0x1 prio 65535 protocol ipv4 matchall action pass", + "cmdUnderTest": "$TC filter add dev $DUMMY parent 1: handle 0x1 prio 65535 protocol ipv4 matchall action pass", "expExitCode": "0", - "verifyCmd": "$TC filter get dev $DEV1 parent 1: handle 1 prio 65535 protocol ipv4 matchall", + "verifyCmd": "$TC filter get dev $DUMMY parent 1: handle 1 prio 65535 protocol ipv4 matchall", "matchPattern": "^filter parent 1: protocol ip pref 65535 matchall.*handle 0x1.*gact action pass.*ref 1 bind 1", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 root handle 1: prio", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY root handle 1: prio", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -133,17 +133,17 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 ingress" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY ingress" ], - "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 655355 protocol ipv4 matchall action pass", + "cmdUnderTest": "$TC filter add dev $DUMMY parent ffff: handle 0x1 prio 655355 protocol ipv4 matchall action pass", "expExitCode": "255", - "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 655355 protocol ipv4 matchall", + "verifyCmd": "$TC filter get dev $DUMMY parent ffff: handle 1 prio 655355 protocol ipv4 matchall", "matchPattern": "^filter parent ffff: protocol ip pref 655355 matchall.*handle 0x1.*gact action pass.*ref 1 bind 1", "matchCount": "0", "teardown": [ - "$TC qdisc del dev $DEV1 ingress", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY ingress", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -154,17 +154,17 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 root handle 1: prio" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY root handle 1: prio" ], - "cmdUnderTest": "$TC filter add dev $DEV1 parent 1: handle 0x1 prio 655355 protocol ipv4 matchall action pass", + "cmdUnderTest": "$TC filter add dev $DUMMY parent 1: handle 0x1 prio 655355 protocol ipv4 matchall action pass", "expExitCode": "255", - "verifyCmd": "$TC filter get dev $DEV1 parent 1: handle 1 prio 655355 protocol ipv4 matchall", + "verifyCmd": "$TC filter get dev $DUMMY parent 1: handle 1 prio 655355 protocol ipv4 matchall", "matchPattern": "^filter parent 1: protocol ip pref 655355 matchall.*handle 0x1.*gact action pass.*ref 1 bind 1", "matchCount": "0", "teardown": [ - "$TC qdisc del dev $DEV1 root handle 1: prio", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY root handle 1: prio", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -175,17 +175,17 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 ingress" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY ingress" ], - "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0xffffffff prio 1 protocol all matchall action continue", + "cmdUnderTest": "$TC filter add dev $DUMMY parent ffff: handle 0xffffffff prio 1 protocol all matchall action continue", "expExitCode": "0", - "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 0xffffffff prio 1 protocol all matchall", + "verifyCmd": "$TC filter get dev $DUMMY parent ffff: handle 0xffffffff prio 1 protocol all matchall", "matchPattern": "^filter parent ffff: protocol all pref 1 matchall.*handle 0xffffffff.*gact action continue.*ref 1 bind 1", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 ingress", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY ingress", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -196,17 +196,17 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 root handle 1: prio" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY root handle 1: prio" ], - "cmdUnderTest": "$TC filter add dev $DEV1 parent 1: handle 0xffffffff prio 1 protocol all matchall action continue", + "cmdUnderTest": "$TC filter add dev $DUMMY parent 1: handle 0xffffffff prio 1 protocol all matchall action continue", "expExitCode": "0", - "verifyCmd": "$TC filter get dev $DEV1 parent 1: handle 0xffffffff prio 1 protocol all matchall", + "verifyCmd": "$TC filter get dev $DUMMY parent 1: handle 0xffffffff prio 1 protocol all matchall", "matchPattern": "^filter parent 1: protocol all pref 1 matchall.*handle 0xffffffff.*gact action continue.*ref 1 bind 1", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 root handle 1: prio", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY root handle 1: prio", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -217,17 +217,17 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 ingress" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY ingress" ], - "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol all matchall skip_hw action reclassify", + "cmdUnderTest": "$TC filter add dev $DUMMY parent ffff: handle 0x1 prio 1 protocol all matchall skip_hw action reclassify", "expExitCode": "0", - "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 0x1 prio 1 protocol all matchall", + "verifyCmd": "$TC filter get dev $DUMMY parent ffff: handle 0x1 prio 1 protocol all matchall", "matchPattern": "^filter parent ffff: protocol all pref 1 matchall.*handle 0x1.*skip_hw.*not_in_hw.*gact action reclassify.*ref 1 bind 1", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 ingress", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY ingress", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -238,17 +238,17 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 root handle 1: prio" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY root handle 1: prio" ], - "cmdUnderTest": "$TC filter add dev $DEV1 parent 1: handle 0x1 prio 1 protocol all matchall skip_hw action reclassify", + "cmdUnderTest": "$TC filter add dev $DUMMY parent 1: handle 0x1 prio 1 protocol all matchall skip_hw action reclassify", "expExitCode": "0", - "verifyCmd": "$TC filter get dev $DEV1 parent 1: handle 0x1 prio 1 protocol all matchall", + "verifyCmd": "$TC filter get dev $DUMMY parent 1: handle 0x1 prio 1 protocol all matchall", "matchPattern": "^filter parent 1: protocol all pref 1 matchall.*handle 0x1.*skip_hw.*not_in_hw.*gact action reclassify.*ref 1 bind 1", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 root handle 1: prio", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY root handle 1: prio", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -259,17 +259,17 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 ingress" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY ingress" ], - "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv6 matchall classid 1:1 action pass", + "cmdUnderTest": "$TC filter add dev $DUMMY parent ffff: handle 0x1 prio 1 protocol ipv6 matchall classid 1:1 action pass", "expExitCode": "0", - "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv6 matchall", + "verifyCmd": "$TC filter get dev $DUMMY parent ffff: handle 0x1 prio 1 protocol ipv6 matchall", "matchPattern": "^filter parent ffff: protocol ipv6 pref 1 matchall.*handle 0x1.*flowid 1:1.*gact action pass.*ref 1 bind 1", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 ingress", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY ingress", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -280,17 +280,17 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 ingress" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY ingress" ], - "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv6 matchall classid 6789defg action pass", + "cmdUnderTest": "$TC filter add dev $DUMMY parent ffff: handle 0x1 prio 1 protocol ipv6 matchall classid 6789defg action pass", "expExitCode": "1", - "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv6 matchall", + "verifyCmd": "$TC filter get dev $DUMMY parent ffff: handle 0x1 prio 1 protocol ipv6 matchall", "matchPattern": "^filter protocol ipv6 pref 1 matchall.*handle 0x1.*flowid 6789defg.*gact action pass.*ref 1 bind 1", "matchCount": "0", "teardown": [ - "$TC qdisc del dev $DEV1 ingress", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY ingress", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -301,18 +301,18 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 ingress", - "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv6 matchall classid 1:2 action pass" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY ingress", + "$TC filter add dev $DUMMY parent ffff: handle 0x1 prio 1 protocol ipv6 matchall classid 1:2 action pass" ], - "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv6 matchall", + "cmdUnderTest": "$TC filter del dev $DUMMY parent ffff: handle 0x1 prio 1 protocol ipv6 matchall", "expExitCode": "0", - "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv6 matchall", + "verifyCmd": "$TC filter get dev $DUMMY parent ffff: handle 0x1 prio 1 protocol ipv6 matchall", "matchPattern": "^filter protocol ipv6 pref 1 matchall.*handle 0x1.*flowid 1:2.*gact action pass.*ref 1 bind 1", "matchCount": "0", "teardown": [ - "$TC qdisc del dev $DEV1 ingress", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY ingress", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -323,21 +323,21 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 ingress", - "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol all matchall classid 1:2 action pass", - "$TC filter add dev $DEV1 parent ffff: handle 0x2 prio 2 protocol all matchall classid 1:3 action pass", - "$TC filter add dev $DEV1 parent ffff: handle 0x3 prio 3 protocol all matchall classid 1:4 action pass", - "$TC filter add dev $DEV1 parent ffff: handle 0x4 prio 4 protocol all matchall classid 1:5 action pass" - ], - "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff:", + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY ingress", + "$TC filter add dev $DUMMY parent ffff: handle 0x1 prio 1 protocol all matchall classid 1:2 action pass", + "$TC filter add dev $DUMMY parent ffff: handle 0x2 prio 2 protocol all matchall classid 1:3 action pass", + "$TC filter add dev $DUMMY parent ffff: handle 0x3 prio 3 protocol all matchall classid 1:4 action pass", + "$TC filter add dev $DUMMY parent ffff: handle 0x4 prio 4 protocol all matchall classid 1:5 action pass" + ], + "cmdUnderTest": "$TC filter del dev $DUMMY parent ffff:", "expExitCode": "0", - "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", + "verifyCmd": "$TC filter show dev $DUMMY parent ffff:", "matchPattern": "^filter protocol all pref.*matchall.*handle.*flowid.*gact action pass", "matchCount": "0", "teardown": [ - "$TC qdisc del dev $DEV1 ingress", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY ingress", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -348,21 +348,21 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 ingress", - "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol all matchall classid 1:2 action pass", - "$TC filter add dev $DEV1 parent ffff: handle 0x2 prio 2 protocol all matchall classid 1:3 action pass", - "$TC filter add dev $DEV1 parent ffff: handle 0x3 prio 3 protocol all matchall classid 1:4 action pass", - "$TC filter add dev $DEV1 parent ffff: handle 0x4 prio 4 protocol all matchall classid 1:5 action pass" - ], - "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: protocol all handle 0x2 prio 2 matchall", + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY ingress", + "$TC filter add dev $DUMMY parent ffff: handle 0x1 prio 1 protocol all matchall classid 1:2 action pass", + "$TC filter add dev $DUMMY parent ffff: handle 0x2 prio 2 protocol all matchall classid 1:3 action pass", + "$TC filter add dev $DUMMY parent ffff: handle 0x3 prio 3 protocol all matchall classid 1:4 action pass", + "$TC filter add dev $DUMMY parent ffff: handle 0x4 prio 4 protocol all matchall classid 1:5 action pass" + ], + "cmdUnderTest": "$TC filter del dev $DUMMY parent ffff: protocol all handle 0x2 prio 2 matchall", "expExitCode": "0", - "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", + "verifyCmd": "$TC filter show dev $DUMMY parent ffff:", "matchPattern": "^filter protocol all pref 2 matchall.*handle 0x2 flowid 1:2.*gact action pass", "matchCount": "0", "teardown": [ - "$TC qdisc del dev $DEV1 ingress", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY ingress", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -373,19 +373,19 @@ "matchall" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 ingress", - "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol all chain 1 matchall classid 1:1 action pass", - "$TC filter add dev $DEV1 parent ffff: handle 0x1 prio 1 protocol ipv4 chain 2 matchall classid 1:3 action continue" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY ingress", + "$TC filter add dev $DUMMY parent ffff: handle 0x1 prio 1 protocol all chain 1 matchall classid 1:1 action pass", + "$TC filter add dev $DUMMY parent ffff: handle 0x1 prio 1 protocol ipv4 chain 2 matchall classid 1:3 action continue" ], - "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: chain 2", + "cmdUnderTest": "$TC filter del dev $DUMMY parent ffff: chain 2", "expExitCode": "0", - "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", + "verifyCmd": "$TC filter show dev $DUMMY parent ffff:", "matchPattern": "^filter protocol all pref 1 matchall chain 1 handle 0x1 flowid 1:1.*gact action pass", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 ingress", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY ingress", + "$IP link del dev $DUMMY type dummy" ] } ] diff --git a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/fifo.json b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/fifo.json index 9de61fa10878..5ecd93b4c473 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/fifo.json +++ b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/fifo.json @@ -8,16 +8,16 @@ "fifo" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root bfifo", + "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root bfifo", "expExitCode": "0", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc bfifo 1: root.*limit [0-9]+b", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 handle 1: root bfifo", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY handle 1: root bfifo", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -29,16 +29,16 @@ "fifo" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root pfifo", + "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root pfifo", "expExitCode": "0", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc pfifo 1: root.*limit [0-9]+p", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 handle 1: root pfifo", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY handle 1: root pfifo", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -49,16 +49,16 @@ "fifo" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 root handle ffff: bfifo", + "cmdUnderTest": "$TC qdisc add dev $DUMMY root handle ffff: bfifo", "expExitCode": "0", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc bfifo ffff: root.*limit [0-9]+b", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 handle ffff: root bfifo", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY handle ffff: root bfifo", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -69,16 +69,16 @@ "fifo" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root bfifo limit 3000b", + "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root bfifo limit 3000b", "expExitCode": "0", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc bfifo 1: root.*limit 3000b", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 handle 1: root bfifo", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY handle 1: root bfifo", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -89,16 +89,16 @@ "fifo" ], "setup": [ - "$IP link add dev $DEV1 txqueuelen 3000 type dummy || /bin/true" + "$IP link add dev $DUMMY txqueuelen 3000 type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root pfifo limit 3000", + "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root pfifo limit 3000", "expExitCode": "0", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc pfifo 1: root.*limit 3000p", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 handle 1: root pfifo", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY handle 1: root pfifo", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -109,15 +109,15 @@ "fifo" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 root handle 10000: bfifo", + "cmdUnderTest": "$TC qdisc add dev $DUMMY root handle 10000: bfifo", "expExitCode": "255", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc bfifo 10000: root.*limit [0-9]+b", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] }, { @@ -128,15 +128,15 @@ "fifo" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root bfifo foorbar", + "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root bfifo foorbar", "expExitCode": "1", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc bfifo 1: root", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] }, { @@ -147,15 +147,15 @@ "fifo" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root pfifo foorbar", + "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root pfifo foorbar", "expExitCode": "1", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc pfifo 1: root", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] }, { @@ -166,18 +166,18 @@ "fifo" ], "setup": [ - "$IP link del dev $DEV1 type dummy || /bin/true", - "$IP link add dev $DEV1 txqueuelen 1000 type dummy", - "$TC qdisc add dev $DEV1 handle 1: root bfifo" + "$IP link del dev $DUMMY type dummy || /bin/true", + "$IP link add dev $DUMMY txqueuelen 1000 type dummy", + "$TC qdisc add dev $DUMMY handle 1: root bfifo" ], - "cmdUnderTest": "$TC qdisc replace dev $DEV1 handle 1: root bfifo limit 3000b", + "cmdUnderTest": "$TC qdisc replace dev $DUMMY handle 1: root bfifo limit 3000b", "expExitCode": "0", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc bfifo 1: root.*limit 3000b", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 handle 1: root bfifo", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY handle 1: root bfifo", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -188,18 +188,18 @@ "fifo" ], "setup": [ - "$IP link del dev $DEV1 type dummy || /bin/true", - "$IP link add dev $DEV1 txqueuelen 1000 type dummy", - "$TC qdisc add dev $DEV1 handle 1: root pfifo" + "$IP link del dev $DUMMY type dummy || /bin/true", + "$IP link add dev $DUMMY txqueuelen 1000 type dummy", + "$TC qdisc add dev $DUMMY handle 1: root pfifo" ], - "cmdUnderTest": "$TC qdisc replace dev $DEV1 handle 1: root pfifo limit 30", + "cmdUnderTest": "$TC qdisc replace dev $DUMMY handle 1: root pfifo limit 30", "expExitCode": "0", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc pfifo 1: root.*limit 30p", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 handle 1: root pfifo", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY handle 1: root pfifo", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -210,15 +210,15 @@ "fifo" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root bfifo limit foo-bar", + "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root bfifo limit foo-bar", "expExitCode": "1", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc bfifo 1: root.*limit foo-bar", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] }, { @@ -229,17 +229,17 @@ "fifo" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 handle 1: root bfifo" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY handle 1: root bfifo" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root bfifo", + "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root bfifo", "expExitCode": "2", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc bfifo 1: root", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 handle 1: root bfifo", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY handle 1: root bfifo", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -250,15 +250,15 @@ "fifo" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc del dev $DEV1 root handle 1: bfifo", + "cmdUnderTest": "$TC qdisc del dev $DUMMY root handle 1: bfifo", "expExitCode": "2", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc bfifo 1: root", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] }, { @@ -269,15 +269,15 @@ "fifo" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 root handle 123^ bfifo limit 100b", + "cmdUnderTest": "$TC qdisc add dev $DUMMY root handle 123^ bfifo limit 100b", "expExitCode": "255", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc bfifo 123 root", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] }, { @@ -288,17 +288,17 @@ "fifo" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 root handle 1: bfifo", - "$TC qdisc del dev $DEV1 root handle 1: bfifo" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY root handle 1: bfifo", + "$TC qdisc del dev $DUMMY root handle 1: bfifo" ], - "cmdUnderTest": "$TC qdisc del dev $DEV1 handle 1: root bfifo", + "cmdUnderTest": "$TC qdisc del dev $DUMMY handle 1: root bfifo", "expExitCode": "2", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc bfifo 1: root", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] } ] diff --git a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/ingress.json b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/ingress.json index f518c55f468b..d99dba6e2b1a 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/ingress.json +++ b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/ingress.json @@ -7,16 +7,16 @@ "ingress" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 ingress", + "cmdUnderTest": "$TC qdisc add dev $DUMMY ingress", "expExitCode": "0", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc ingress ffff:", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 ingress", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY ingress", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -27,15 +27,15 @@ "ingress" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 ingress foorbar", + "cmdUnderTest": "$TC qdisc add dev $DUMMY ingress foorbar", "expExitCode": "1", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc ingress ffff:", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] }, { @@ -46,17 +46,17 @@ "ingress" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 ingress" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY ingress" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 ingress", + "cmdUnderTest": "$TC qdisc add dev $DUMMY ingress", "expExitCode": "2", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc ingress ffff:", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 ingress", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY ingress", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -67,15 +67,15 @@ "ingress" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc del dev $DEV1 ingress", + "cmdUnderTest": "$TC qdisc del dev $DUMMY ingress", "expExitCode": "2", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc ingress ffff:", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] }, { @@ -86,17 +86,17 @@ "ingress" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 ingress", - "$TC qdisc del dev $DEV1 ingress" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY ingress", + "$TC qdisc del dev $DUMMY ingress" ], - "cmdUnderTest": "$TC qdisc del dev $DEV1 ingress", + "cmdUnderTest": "$TC qdisc del dev $DUMMY ingress", "expExitCode": "2", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc ingress ffff:", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] } ] diff --git a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/prio.json b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/prio.json index 9c792fa8ca23..3076c02d08d6 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/prio.json +++ b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/prio.json @@ -7,16 +7,16 @@ "prio" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root prio", + "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root prio", "expExitCode": "0", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc prio 1: root", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 handle 1: root prio", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY handle 1: root prio", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -27,15 +27,15 @@ "prio" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 root handle ffff: prio", + "cmdUnderTest": "$TC qdisc add dev $DUMMY root handle ffff: prio", "expExitCode": "0", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc prio ffff: root", "matchCount": "1", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] }, { @@ -46,15 +46,15 @@ "prio" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 root handle 10000: prio", + "cmdUnderTest": "$TC qdisc add dev $DUMMY root handle 10000: prio", "expExitCode": "255", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc prio 10000: root", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] }, { @@ -65,15 +65,15 @@ "prio" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root prio foorbar", + "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root prio foorbar", "expExitCode": "1", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc prio 1: root", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] }, { @@ -84,16 +84,16 @@ "prio" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root prio bands 4 priomap 1 1 2 2 3 3 0 0 1 2 3 0 0 0 0 0", + "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root prio bands 4 priomap 1 1 2 2 3 3 0 0 1 2 3 0 0 0 0 0", "expExitCode": "0", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc prio 1: root.*bands 4 priomap.*1 1 2 2 3 3 0 0 1 2 3 0 0 0 0 0", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 handle 1: root prio", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY handle 1: root prio", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -104,15 +104,15 @@ "prio" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root prio bands 4 priomap 1 1 2 2 3 3 0 0 1 2 3 0 0 0 0 0 1 1", + "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root prio bands 4 priomap 1 1 2 2 3 3 0 0 1 2 3 0 0 0 0 0 1 1", "expExitCode": "1", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc prio 1: root.*bands 4 priomap.*1 1 2 2 3 3 0 0 1 2 3 0 0 0 0 0 1 1", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] }, { @@ -123,15 +123,15 @@ "prio" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root prio bands 4 priomap 1 1 2 2 7 5 0 0 1 2 3 0 0 0 0 0", + "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root prio bands 4 priomap 1 1 2 2 7 5 0 0 1 2 3 0 0 0 0 0", "expExitCode": "1", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc prio 1: root.*bands 4 priomap.*1 1 2 2 7 5 0 0 1 2 3 0 0 0 0 0", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] }, { @@ -142,15 +142,15 @@ "prio" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root prio bands 1 priomap 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root prio bands 1 priomap 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "expExitCode": "2", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc prio 1: root.*bands 1 priomap.*0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] }, { @@ -161,15 +161,15 @@ "prio" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root prio bands 1024 priomap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16", + "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root prio bands 1024 priomap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16", "expExitCode": "2", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc prio 1: root.*bands 1024 priomap.*1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] }, { @@ -180,17 +180,17 @@ "prio" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 handle 1: root prio" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY handle 1: root prio" ], - "cmdUnderTest": "$TC qdisc replace dev $DEV1 handle 1: root prio bands 8 priomap 1 1 2 2 3 3 4 4 5 5 6 6 7 7 0 0", + "cmdUnderTest": "$TC qdisc replace dev $DUMMY handle 1: root prio bands 8 priomap 1 1 2 2 3 3 4 4 5 5 6 6 7 7 0 0", "expExitCode": "0", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc prio 1: root.*bands 8 priomap.*1 1 2 2 3 3 4 4 5 5 6 6 7 7 0 0", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 handle 1: root prio", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY handle 1: root prio", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -201,17 +201,17 @@ "prio" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 handle 1: root prio" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY handle 1: root prio" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root prio", + "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root prio", "expExitCode": "2", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc prio 1: root", "matchCount": "1", "teardown": [ - "$TC qdisc del dev $DEV1 handle 1: root prio", - "$IP link del dev $DEV1 type dummy" + "$TC qdisc del dev $DUMMY handle 1: root prio", + "$IP link del dev $DUMMY type dummy" ] }, { @@ -222,15 +222,15 @@ "prio" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc del dev $DEV1 root handle 1: prio", + "cmdUnderTest": "$TC qdisc del dev $DUMMY root handle 1: prio", "expExitCode": "2", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc prio 1: root", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] }, { @@ -241,15 +241,15 @@ "prio" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true" + "$IP link add dev $DUMMY type dummy || /bin/true" ], - "cmdUnderTest": "$TC qdisc add dev $DEV1 root handle 123^ prio", + "cmdUnderTest": "$TC qdisc add dev $DUMMY root handle 123^ prio", "expExitCode": "255", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc prio 123 root", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] }, { @@ -260,17 +260,17 @@ "prio" ], "setup": [ - "$IP link add dev $DEV1 type dummy || /bin/true", - "$TC qdisc add dev $DEV1 root handle 1: prio", - "$TC qdisc del dev $DEV1 root handle 1: prio" + "$IP link add dev $DUMMY type dummy || /bin/true", + "$TC qdisc add dev $DUMMY root handle 1: prio", + "$TC qdisc del dev $DUMMY root handle 1: prio" ], - "cmdUnderTest": "$TC qdisc del dev $DEV1 handle 1: root prio", + "cmdUnderTest": "$TC qdisc del dev $DUMMY handle 1: root prio", "expExitCode": "2", - "verifyCmd": "$TC qdisc show dev $DEV1", + "verifyCmd": "$TC qdisc show dev $DUMMY", "matchPattern": "qdisc ingress ffff:", "matchCount": "0", "teardown": [ - "$IP link del dev $DEV1 type dummy" + "$IP link del dev $DUMMY type dummy" ] } ] diff --git a/tools/testing/selftests/tc-testing/tdc_config.py b/tools/testing/selftests/tc-testing/tdc_config.py index b771d4c89621..080709cc4297 100644 --- a/tools/testing/selftests/tc-testing/tdc_config.py +++ b/tools/testing/selftests/tc-testing/tdc_config.py @@ -16,6 +16,7 @@ NAMES = { 'DEV0': 'v0p0', 'DEV1': 'v0p1', 'DEV2': '', + 'DUMMY': 'dummy1', 'BATCH_FILE': './batch.txt', 'BATCH_DIR': 'tmp', # Length of time in seconds to wait before terminating a command -- cgit v1.2.3-59-g8ed1b From 14b54ac4fbb92f1a52966cc33477436de0f72965 Mon Sep 17 00:00:00 2001 From: Vlad Buslov Date: Mon, 19 Aug 2019 10:52:08 +0300 Subject: tc-testing: concurrency: wrap piped rule update commands Concurrent tests use several commands to update rules in parallel: 'find' prints names of batch files in tmp directory and pipes result to 'xargs' which runs instance of tc per batch file in parallel. This breaks when used with ns plugin that adds 'ip netns exec $NS' prefix to the command, which causes only first command in pipe to be executed in namespace: =====> Test e41d: Add 1M flower filters with 10 parallel tc instances -----> prepare stage ns/SubPlugin.adjust_command adjust_command: stage is setup; inserting netns stuff in command [/bin/mkdir tmp] list [['/bin/mkdir', 'tmp']] adjust_command: return command [ip netns exec tcut /bin/mkdir tmp] command "ip netns exec tcut /bin/mkdir tmp" ns/SubPlugin.adjust_command adjust_command: stage is setup; inserting netns stuff in command [/sbin/tc qdisc add dev ens1f0 ingress] list [['/sbin/tc', 'qdisc', 'add', 'dev', 'ens1f0', 'ingress']] adjust_command: return command [ip netns exec tcut /sbin/tc qdisc add dev ens1f0 ingress] command "ip netns exec tcut /sbin/tc qdisc add dev ens1f0 ingress" ns/SubPlugin.adjust_command adjust_command: stage is setup; inserting netns stuff in command [./tdc_multibatch.py ens1f0 tmp 100000 10 add] list [['./tdc_multibatch.py', 'ens1f0', 'tmp', '100000', '10', 'add']] adjust_command: return command [ip netns exec tcut ./tdc_multibatch.py ens1f0 tmp 100000 10 add] command "ip netns exec tcut ./tdc_multibatch.py ens1f0 tmp 100000 10 add" -----> execute stage ns/SubPlugin.adjust_command adjust_command: stage is execute; inserting netns stuff in command [find tmp/add* -print | xargs -n 1 -P 10 /sbin/tc -b] list [['find', 'tmp/add*', '-print', '|', 'xargs', '-n', '1', '-P', '10', '/sbin/tc', '-b'] ] adjust_command: return command [ip netns exec tcut find tmp/add* -print | xargs -n 1 -P 10 /sbin/tc -b] command "ip netns exec tcut find tmp/add* -print | xargs -n 1 -P 10 /sbin/tc -b" exit: 123 exit: 0 Cannot find device "ens1f0" Cannot find device "ens1f0" Command failed tmp/add_0:1 Command failed tmp/add_1:1 Cannot find device "ens1f0" Command failed tmp/add_2:1 Cannot find device "ens1f0" Command failed tmp/add_4:1 Cannot find device "ens1f0" Command failed tmp/add_3:1 Cannot find device "ens1f0" Command failed tmp/add_5:1 Cannot find device "ens1f0" Command failed tmp/add_6:1 Cannot find device "ens1f0" Command failed tmp/add_8:1 Cannot find device "ens1f0" Command failed tmp/add_7:1 Cannot find device "ens1f0" Command failed tmp/add_9:1 Fix the issue by executing whole compound command in namespace by wrapping it in 'bash -c' invocation. Fixes: 489ce2f42514 ("tc-testing: Restore original behaviour for namespaces in tdc") Signed-off-by: Vlad Buslov Signed-off-by: David S. Miller --- .../tc-testing/tc-tests/filters/concurrency.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/tc-testing/tc-tests/filters/concurrency.json b/tools/testing/selftests/tc-testing/tc-tests/filters/concurrency.json index 9002714b1851..c2a433a4737e 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/filters/concurrency.json +++ b/tools/testing/selftests/tc-testing/tc-tests/filters/concurrency.json @@ -12,7 +12,7 @@ "$TC qdisc add dev $DEV2 ingress", "./tdc_multibatch.py $DEV2 $BATCH_DIR 100000 10 add" ], - "cmdUnderTest": "find $BATCH_DIR/add* -print | xargs -n 1 -P 10 $TC -b", + "cmdUnderTest": "bash -c \"find $BATCH_DIR/add* -print | xargs -n 1 -P 10 $TC -b\"", "expExitCode": "0", "verifyCmd": "$TC -s filter show dev $DEV2 ingress", "matchPattern": "filter protocol ip pref 1 flower chain 0 handle", @@ -37,7 +37,7 @@ "$TC -b $BATCH_DIR/add_0", "./tdc_multibatch.py $DEV2 $BATCH_DIR 100000 10 del" ], - "cmdUnderTest": "find $BATCH_DIR/del* -print | xargs -n 1 -P 10 $TC -b", + "cmdUnderTest": "bash -c \"find $BATCH_DIR/del* -print | xargs -n 1 -P 10 $TC -b\"", "expExitCode": "0", "verifyCmd": "$TC -s filter show dev $DEV2 ingress", "matchPattern": "filter protocol ip pref 1 flower chain 0 handle", @@ -62,7 +62,7 @@ "$TC -b $BATCH_DIR/add_0", "./tdc_multibatch.py $DEV2 $BATCH_DIR 100000 10 replace" ], - "cmdUnderTest": "find $BATCH_DIR/replace* -print | xargs -n 1 -P 10 $TC -b", + "cmdUnderTest": "bash -c \"find $BATCH_DIR/replace* -print | xargs -n 1 -P 10 $TC -b\"", "expExitCode": "0", "verifyCmd": "$TC -s filter show dev $DEV2 ingress", "matchPattern": "filter protocol ip pref 1 flower chain 0 handle", @@ -87,7 +87,7 @@ "$TC -b $BATCH_DIR/add_0", "./tdc_multibatch.py -d $DEV2 $BATCH_DIR 100000 10 replace" ], - "cmdUnderTest": "find $BATCH_DIR/replace* -print | xargs -n 1 -P 10 $TC -b", + "cmdUnderTest": "bash -c \"find $BATCH_DIR/replace* -print | xargs -n 1 -P 10 $TC -b\"", "expExitCode": "0", "verifyCmd": "$TC -s filter show dev $DEV2 ingress", "matchPattern": "filter protocol ip pref 1 flower chain 0 handle", @@ -112,7 +112,7 @@ "$TC -b $BATCH_DIR/add_0", "./tdc_multibatch.py -d $DEV2 $BATCH_DIR 100000 10 del" ], - "cmdUnderTest": "find $BATCH_DIR/del* -print | xargs -n 1 -P 10 $TC -f -b", + "cmdUnderTest": "bash -c \"find $BATCH_DIR/del* -print | xargs -n 1 -P 10 $TC -f -b\"", "expExitCode": "123", "verifyCmd": "$TC -s filter show dev $DEV2 ingress", "matchPattern": "filter protocol ip pref 1 flower chain 0 handle", @@ -134,11 +134,11 @@ "/bin/mkdir $BATCH_DIR", "$TC qdisc add dev $DEV2 ingress", "./tdc_multibatch.py -x init_ $DEV2 $BATCH_DIR 100000 5 add", - "find $BATCH_DIR/init_* -print | xargs -n 1 -P 5 $TC -b", + "bash -c \"find $BATCH_DIR/init_* -print | xargs -n 1 -P 5 $TC -b\"", "./tdc_multibatch.py -x par_ -a 500001 -m 5 $DEV2 $BATCH_DIR 100000 5 add", "./tdc_multibatch.py -x par_ $DEV2 $BATCH_DIR 100000 5 del" ], - "cmdUnderTest": "find $BATCH_DIR/par_* -print | xargs -n 1 -P 10 $TC -b", + "cmdUnderTest": "bash -c \"find $BATCH_DIR/par_* -print | xargs -n 1 -P 10 $TC -b\"", "expExitCode": "0", "verifyCmd": "$TC -s filter show dev $DEV2 ingress", "matchPattern": "filter protocol ip pref 1 flower chain 0 handle", @@ -160,11 +160,11 @@ "/bin/mkdir $BATCH_DIR", "$TC qdisc add dev $DEV2 ingress", "./tdc_multibatch.py -x init_ $DEV2 $BATCH_DIR 100000 10 add", - "find $BATCH_DIR/init_* -print | xargs -n 1 -P 5 $TC -b", + "bash -c \"find $BATCH_DIR/init_* -print | xargs -n 1 -P 5 $TC -b\"", "./tdc_multibatch.py -x par_ -a 500001 -m 5 $DEV2 $BATCH_DIR 100000 5 replace", "./tdc_multibatch.py -x par_ $DEV2 $BATCH_DIR 100000 5 del" ], - "cmdUnderTest": "find $BATCH_DIR/par_* -print | xargs -n 1 -P 10 $TC -b", + "cmdUnderTest": "bash -c \"find $BATCH_DIR/par_* -print | xargs -n 1 -P 10 $TC -b\"", "expExitCode": "0", "verifyCmd": "$TC -s filter show dev $DEV2 ingress", "matchPattern": "filter protocol ip pref 1 flower chain 0 handle", -- cgit v1.2.3-59-g8ed1b From 769a807d0b41df4201dbeb01c22eaeb3e5905532 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Mon, 12 Aug 2019 10:32:13 +0200 Subject: xfrm: policy: avoid warning splat when merging nodes syzbot reported a splat: xfrm_policy_inexact_list_reinsert+0x625/0x6e0 net/xfrm/xfrm_policy.c:877 CPU: 1 PID: 6756 Comm: syz-executor.1 Not tainted 5.3.0-rc2+ #57 Call Trace: xfrm_policy_inexact_node_reinsert net/xfrm/xfrm_policy.c:922 [inline] xfrm_policy_inexact_node_merge net/xfrm/xfrm_policy.c:958 [inline] xfrm_policy_inexact_insert_node+0x537/0xb50 net/xfrm/xfrm_policy.c:1023 xfrm_policy_inexact_alloc_chain+0x62b/0xbd0 net/xfrm/xfrm_policy.c:1139 xfrm_policy_inexact_insert+0xe8/0x1540 net/xfrm/xfrm_policy.c:1182 xfrm_policy_insert+0xdf/0xce0 net/xfrm/xfrm_policy.c:1574 xfrm_add_policy+0x4cf/0x9b0 net/xfrm/xfrm_user.c:1670 xfrm_user_rcv_msg+0x46b/0x720 net/xfrm/xfrm_user.c:2676 netlink_rcv_skb+0x1f0/0x460 net/netlink/af_netlink.c:2477 xfrm_netlink_rcv+0x74/0x90 net/xfrm/xfrm_user.c:2684 netlink_unicast_kernel net/netlink/af_netlink.c:1302 [inline] netlink_unicast+0x809/0x9a0 net/netlink/af_netlink.c:1328 netlink_sendmsg+0xa70/0xd30 net/netlink/af_netlink.c:1917 sock_sendmsg_nosec net/socket.c:637 [inline] sock_sendmsg net/socket.c:657 [inline] There is no reproducer, however, the warning can be reproduced by adding rules with ever smaller prefixes. The sanity check ("does the policy match the node") uses the prefix value of the node before its updated to the smaller value. To fix this, update the prefix earlier. The bug has no impact on tree correctness, this is only to prevent a false warning. Reported-by: syzbot+8cc27ace5f6972910b31@syzkaller.appspotmail.com Signed-off-by: Florian Westphal Signed-off-by: Steffen Klassert --- net/xfrm/xfrm_policy.c | 6 ++++-- tools/testing/selftests/net/xfrm_policy.sh | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 8ca637a72697..0fa7c5ce3b2c 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -912,6 +912,7 @@ restart: } else if (delta > 0) { p = &parent->rb_right; } else { + bool same_prefixlen = node->prefixlen == n->prefixlen; struct xfrm_policy *tmp; hlist_for_each_entry(tmp, &n->hhead, bydst) { @@ -919,9 +920,11 @@ restart: hlist_del_rcu(&tmp->bydst); } + node->prefixlen = prefixlen; + xfrm_policy_inexact_list_reinsert(net, node, family); - if (node->prefixlen == n->prefixlen) { + if (same_prefixlen) { kfree_rcu(n, rcu); return; } @@ -929,7 +932,6 @@ restart: rb_erase(*p, new); kfree_rcu(n, rcu); n = node; - n->prefixlen = prefixlen; goto restart; } } diff --git a/tools/testing/selftests/net/xfrm_policy.sh b/tools/testing/selftests/net/xfrm_policy.sh index 5445943bf07f..7a1bf94c5bd3 100755 --- a/tools/testing/selftests/net/xfrm_policy.sh +++ b/tools/testing/selftests/net/xfrm_policy.sh @@ -106,6 +106,13 @@ do_overlap() # # 10.0.0.0/24 and 10.0.1.0/24 nodes have been merged as 10.0.0.0/23. ip -net $ns xfrm policy add src 10.1.0.0/24 dst 10.0.0.0/23 dir fwd priority 200 action block + + # similar to above: add policies (with partially random address), with shrinking prefixes. + for p in 29 28 27;do + for k in $(seq 1 32); do + ip -net $ns xfrm policy add src 10.253.1.$((RANDOM%255))/$p dst 10.254.1.$((RANDOM%255))/$p dir fwd priority $((200+k)) action block 2>/dev/null + done + done } do_esp_policy_get_check() { -- cgit v1.2.3-59-g8ed1b From fdc029b19dfd190840d23e5c70bd231140b0e4a4 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sun, 18 Aug 2019 11:05:55 +0200 Subject: memremap: remove the dev field in struct dev_pagemap The dev field in struct dev_pagemap is only used to print dev_name in two places, which are at best nice to have. Just remove the field and thus the name in those two messages. Link: https://lore.kernel.org/r/20190818090557.17853-3-hch@lst.de Signed-off-by: Christoph Hellwig Reviewed-by: Ira Weiny Reviewed-by: Dan Williams Tested-by: Bharata B Rao Reviewed-by: Jason Gunthorpe Signed-off-by: Jason Gunthorpe --- include/linux/memremap.h | 1 - kernel/memremap.c | 6 +----- mm/page_alloc.c | 2 +- tools/testing/nvdimm/test/iomap.c | 1 - 4 files changed, 2 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/include/linux/memremap.h b/include/linux/memremap.h index f8a5b2a19945..8f0013e18e14 100644 --- a/include/linux/memremap.h +++ b/include/linux/memremap.h @@ -109,7 +109,6 @@ struct dev_pagemap { struct percpu_ref *ref; struct percpu_ref internal_ref; struct completion done; - struct device *dev; enum memory_type type; unsigned int flags; u64 pci_p2pdma_bus_offset; diff --git a/kernel/memremap.c b/kernel/memremap.c index 6ee03a816d67..600a14cbe663 100644 --- a/kernel/memremap.c +++ b/kernel/memremap.c @@ -96,7 +96,6 @@ static void dev_pagemap_cleanup(struct dev_pagemap *pgmap) static void devm_memremap_pages_release(void *data) { struct dev_pagemap *pgmap = data; - struct device *dev = pgmap->dev; struct resource *res = &pgmap->res; unsigned long pfn; int nid; @@ -123,8 +122,7 @@ static void devm_memremap_pages_release(void *data) untrack_pfn(NULL, PHYS_PFN(res->start), resource_size(res)); pgmap_array_delete(res); - dev_WARN_ONCE(dev, pgmap->altmap.alloc, - "%s: failed to free all reserved pages\n", __func__); + WARN_ONCE(pgmap->altmap.alloc, "failed to free all reserved pages\n"); } static void dev_pagemap_percpu_release(struct percpu_ref *ref) @@ -245,8 +243,6 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap) goto err_array; } - pgmap->dev = dev; - error = xa_err(xa_store_range(&pgmap_array, PHYS_PFN(res->start), PHYS_PFN(res->end), pgmap, GFP_KERNEL)); if (error) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 272c6de1bf4e..b39baa2b1faf 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5982,7 +5982,7 @@ void __ref memmap_init_zone_device(struct zone *zone, } } - pr_info("%s initialised, %lu pages in %ums\n", dev_name(pgmap->dev), + pr_info("%s initialised %lu pages in %ums\n", __func__, size, jiffies_to_msecs(jiffies - start)); } diff --git a/tools/testing/nvdimm/test/iomap.c b/tools/testing/nvdimm/test/iomap.c index cd040b5abffe..3f55f2f99112 100644 --- a/tools/testing/nvdimm/test/iomap.c +++ b/tools/testing/nvdimm/test/iomap.c @@ -132,7 +132,6 @@ void *__wrap_devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap) if (!nfit_res) return devm_memremap_pages(dev, pgmap); - pgmap->dev = dev; if (!pgmap->ref) { if (pgmap->ops && (pgmap->ops->kill || pgmap->ops->cleanup)) return ERR_PTR(-EINVAL); -- cgit v1.2.3-59-g8ed1b From 6e98bc349ea4219e21785d85809b10bd49e722df Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 20 Aug 2019 12:01:38 -0300 Subject: tools headers: Add limits.h to access __WORDSIZE We need to make sure limits.h is included before checking if we can use __WORDSIZE, do it. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-5yfoed4rnsck2n3cwhm9mvth@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/bitops.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/include/linux/bitops.h b/tools/include/linux/bitops.h index 0b0ef3abc966..140c8362f113 100644 --- a/tools/include/linux/bitops.h +++ b/tools/include/linux/bitops.h @@ -3,6 +3,7 @@ #define _TOOLS_LINUX_BITOPS_H_ #include +#include #ifndef __WORDSIZE #define __WORDSIZE (__SIZEOF_LONG__ * 8) #endif -- cgit v1.2.3-59-g8ed1b From 146dc303630aff5fdf006614a67704539c519c33 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 19 Aug 2019 11:11:30 -0300 Subject: perf tools: tools/include should come before tools/uapi/include The next cset will grap const.h copies from the kernel to keep bits.h in sync as it started to use linux/const.h, that in turn includes uapi/linux/const.h. So now we have a file with the same name in tools/include and tools/uapi/include, and one includes the other, we need to have tools/include/uapi/ after tools/include/ for this to work, fix it. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-qzjqxa1wdrt51kwadyqawnuj@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 9a06787fedc6..bf8caa7d17f6 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -280,9 +280,9 @@ endif INC_FLAGS += -I$(src-perf)/lib/include INC_FLAGS += -I$(src-perf)/util/include INC_FLAGS += -I$(src-perf)/arch/$(SRCARCH)/include -INC_FLAGS += -I$(srctree)/tools/include/uapi INC_FLAGS += -I$(srctree)/tools/include/ INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/include/uapi +INC_FLAGS += -I$(srctree)/tools/include/uapi INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/include/ INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/ -- cgit v1.2.3-59-g8ed1b From aaa6ef8aa85f33c6dd593e139b7f7d901bbde0e2 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 19 Aug 2019 11:00:54 -0300 Subject: tools headers: Grab copy of linux/const.h, needed by linux/bits.h So that can update the copy of linux/bits.h that now uses macros defined in const.h and that are not available in older systems. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-c2qfcbl58hxyfb5u5xivp7is@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/const.h | 9 +++++++++ tools/include/uapi/linux/const.h | 31 +++++++++++++++++++++++++++++++ tools/perf/check-headers.sh | 2 ++ 3 files changed, 42 insertions(+) create mode 100644 tools/include/linux/const.h create mode 100644 tools/include/uapi/linux/const.h (limited to 'tools') diff --git a/tools/include/linux/const.h b/tools/include/linux/const.h new file mode 100644 index 000000000000..7b55a55f5911 --- /dev/null +++ b/tools/include/linux/const.h @@ -0,0 +1,9 @@ +#ifndef _LINUX_CONST_H +#define _LINUX_CONST_H + +#include + +#define UL(x) (_UL(x)) +#define ULL(x) (_ULL(x)) + +#endif /* _LINUX_CONST_H */ diff --git a/tools/include/uapi/linux/const.h b/tools/include/uapi/linux/const.h new file mode 100644 index 000000000000..5ed721ad5b19 --- /dev/null +++ b/tools/include/uapi/linux/const.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* const.h: Macros for dealing with constants. */ + +#ifndef _UAPI_LINUX_CONST_H +#define _UAPI_LINUX_CONST_H + +/* Some constant macros are used in both assembler and + * C code. Therefore we cannot annotate them always with + * 'UL' and other type specifiers unilaterally. We + * use the following macros to deal with this. + * + * Similarly, _AT() will cast an expression with a type in C, but + * leave it unchanged in asm. + */ + +#ifdef __ASSEMBLY__ +#define _AC(X,Y) X +#define _AT(T,X) X +#else +#define __AC(X,Y) (X##Y) +#define _AC(X,Y) __AC(X,Y) +#define _AT(T,X) ((T)(X)) +#endif + +#define _UL(x) (_AC(x, UL)) +#define _ULL(x) (_AC(x, ULL)) + +#define _BITUL(x) (_UL(1) << (x)) +#define _BITULL(x) (_ULL(1) << (x)) + +#endif /* _UAPI_LINUX_CONST_H */ diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh index f211c015cb76..5308b3836278 100755 --- a/tools/perf/check-headers.sh +++ b/tools/perf/check-headers.sh @@ -2,6 +2,7 @@ # SPDX-License-Identifier: GPL-2.0 HEADERS=' +include/uapi/linux/const.h include/uapi/drm/drm.h include/uapi/drm/i915_drm.h include/uapi/linux/fadvise.h @@ -19,6 +20,7 @@ include/uapi/linux/usbdevice_fs.h include/uapi/linux/vhost.h include/uapi/sound/asound.h include/linux/bits.h +include/linux/const.h include/linux/hash.h include/uapi/linux/hw_breakpoint.h arch/x86/include/asm/disabled-features.h -- cgit v1.2.3-59-g8ed1b From b658911731d41a91b9de5458d6f38d6e1c90a453 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 19 Aug 2019 11:14:28 -0300 Subject: tools headers: Synchronize linux/bits.h with the kernel sources To pick up the changes in this cset: 95b980d62d52 ("linux/bits.h: make BIT(), GENMASK(), and friends available in assembly") To address this tools/perf build warning: Warning: Kernel ABI header at 'tools/include/linux/bits.h' differs from latest version at 'include/linux/bits.h' diff -u tools/include/linux/bits.h include/linux/bits.h Cc: Adrian Hunter Cc: Jiri Olsa Cc: Masahiro Yamada Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-1if3iga5r3di6oyddgxsr225@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/bits.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/include/linux/bits.h b/tools/include/linux/bits.h index 2b7b532c1d51..669d69441a62 100644 --- a/tools/include/linux/bits.h +++ b/tools/include/linux/bits.h @@ -1,13 +1,15 @@ /* SPDX-License-Identifier: GPL-2.0 */ #ifndef __LINUX_BITS_H #define __LINUX_BITS_H + +#include #include -#define BIT(nr) (1UL << (nr)) -#define BIT_ULL(nr) (1ULL << (nr)) -#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) +#define BIT(nr) (UL(1) << (nr)) +#define BIT_ULL(nr) (ULL(1) << (nr)) +#define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG)) #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) -#define BIT_ULL_MASK(nr) (1ULL << ((nr) % BITS_PER_LONG_LONG)) +#define BIT_ULL_MASK(nr) (ULL(1) << ((nr) % BITS_PER_LONG_LONG)) #define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG) #define BITS_PER_BYTE 8 @@ -17,10 +19,11 @@ * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. */ #define GENMASK(h, l) \ - (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) + (((~UL(0)) - (UL(1) << (l)) + 1) & \ + (~UL(0) >> (BITS_PER_LONG - 1 - (h)))) #define GENMASK_ULL(h, l) \ - (((~0ULL) - (1ULL << (l)) + 1) & \ - (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h)))) + (((~ULL(0)) - (ULL(1) << (l)) + 1) & \ + (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h)))) #endif /* __LINUX_BITS_H */ -- cgit v1.2.3-59-g8ed1b From 0ac10d87a571ae7d68c7f70f1c2229388f1dce9e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 19 Aug 2019 10:53:20 -0300 Subject: tools arch x86: Sync asm/cpufeatures.h with the with the kernel To pick up the changes in: f36cf386e3fe ("x86/speculation/swapgs: Exclude ATOMs from speculation through SWAPGS") 18ec54fdd6d1 ("x86/speculation: Prepare entry code for Spectre v1 swapgs mitigations") That don't affect anything in tools/. This silences this perf build warning: Warning: Kernel ABI header at 'tools/arch/x86/include/asm/cpufeatures.h' differs from latest version at 'arch/x86/include/asm/cpufeatures.h' diff -u tools/arch/x86/include/asm/cpufeatures.h arch/x86/include/asm/cpufeatures.h Cc: Adrian Hunter Cc: Jiri Olsa Cc: Josh Poimboeuf Cc: Namhyung Kim Cc: Thomas Gleixner Link: https://lkml.kernel.org/n/tip-860dq1qie2cpnfghlpcnxrzr@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/x86/include/asm/cpufeatures.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h index 998c2cc08363..e880f2408e29 100644 --- a/tools/arch/x86/include/asm/cpufeatures.h +++ b/tools/arch/x86/include/asm/cpufeatures.h @@ -281,6 +281,8 @@ #define X86_FEATURE_CQM_OCCUP_LLC (11*32+ 1) /* LLC occupancy monitoring */ #define X86_FEATURE_CQM_MBM_TOTAL (11*32+ 2) /* LLC Total MBM monitoring */ #define X86_FEATURE_CQM_MBM_LOCAL (11*32+ 3) /* LLC Local MBM monitoring */ +#define X86_FEATURE_FENCE_SWAPGS_USER (11*32+ 4) /* "" LFENCE in user entry SWAPGS path */ +#define X86_FEATURE_FENCE_SWAPGS_KERNEL (11*32+ 5) /* "" LFENCE in kernel entry SWAPGS path */ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ #define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */ @@ -394,5 +396,6 @@ #define X86_BUG_L1TF X86_BUG(18) /* CPU is affected by L1 Terminal Fault */ #define X86_BUG_MDS X86_BUG(19) /* CPU is affected by Microarchitectural data sampling */ #define X86_BUG_MSBDS_ONLY X86_BUG(20) /* CPU is only affected by the MSDBS variant of BUG_MDS */ +#define X86_BUG_SWAPGS X86_BUG(21) /* CPU is affected by speculation through SWAPGS */ #endif /* _ASM_X86_CPUFEATURES_H */ -- cgit v1.2.3-59-g8ed1b From 3c84e65a533dbaa1a29bfd847deca73704b675eb Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 12 Aug 2019 12:09:35 +0300 Subject: perf evsel: Add comment for 'idx' member in 'struct perf_sample_id The 'idx' member was added as preparation for AUX area sampling. Add a comment to describe why. Signed-off-by: Adrian Hunter Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/83ff264f-84c3-5372-8976-dd9293d20c6f@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'tools') diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 9cd6e3ae479a..efe08065838f 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -23,6 +23,13 @@ struct perf_sample_id { struct hlist_node node; u64 id; struct evsel *evsel; + /* + * 'idx' will be used for AUX area sampling. A sample will have AUX area + * data that will be queued for decoding, where there are separate + * queues for each CPU (per-cpu tracing) or task (per-thread tracing). + * The sample ID can be used to lookup 'idx' which is effectively the + * queue number. + */ int idx; int cpu; pid_t tid; -- cgit v1.2.3-59-g8ed1b From 82a2f88458d70704be843961e10b5cef9a6e95d3 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Mon, 5 Aug 2019 13:01:50 -0400 Subject: tools lib traceevent: Fix "robust" test of do_generate_dynamic_list_file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tools/lib/traceevent/Makefile had a test added to it to detect a failure of the "nm" when making the dynamic list file (whatever that is). The problem is that the test sorts the values "U W w" and some versions of sort will place "w" ahead of "W" (even though it has a higher ASCII value, and break the test. Add 'tr "w" "W"' to merge the two and not worry about the ordering. Reported-by: Tzvetomir Stoyanov Signed-off-by: Steven Rostedt (VMware) Cc: Alexander Shishkin Cc: David Carrillo-Cisneros Cc: He Kuang Cc: Jiri Olsa Cc: Michal rarek Cc: Paul Turner Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Uwe Kleine-König Cc: Wang Nan Cc: stable@vger.kernel.org Fixes: 6467753d61399 ("tools lib traceevent: Robustify do_generate_dynamic_list_file") Link: http://lkml.kernel.org/r/20190805130150.25acfeb1@gandalf.local.home Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index 3292c290654f..8352d53dcb5a 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile @@ -266,8 +266,8 @@ endef define do_generate_dynamic_list_file symbol_type=`$(NM) -u -D $1 | awk 'NF>1 {print $$1}' | \ - xargs echo "U W w" | tr ' ' '\n' | sort -u | xargs echo`;\ - if [ "$$symbol_type" = "U W w" ];then \ + xargs echo "U w W" | tr 'w ' 'W\n' | sort -u | xargs echo`;\ + if [ "$$symbol_type" = "U W" ];then \ (echo '{'; \ $(NM) -u -D $1 | awk 'NF>1 {print "\t"$$2";"}' | sort -u;\ echo '};'; \ -- cgit v1.2.3-59-g8ed1b From 2566349648b40aa3f5edf6af8f7f893ccd6e4eae Mon Sep 17 00:00:00 2001 From: Alexey Budankov Date: Fri, 9 Aug 2019 18:23:58 +0300 Subject: perf record: Enable LBR callstack capture jointly with thread stack Enable '-j stack' applicability together with '--call-graph dwarf' option so thread stack data and LBR call stack could be captured jointly: $ perf record -g --call-graph dwarf,1024 -j stack,u -- stack_test Collected LBR call stack can be used to augment DWARF call stack calculated from the raw thread stack data and to provide more comprehensive call stack information for cases when collected SIZE is not enough to cover complete thread stack. Such cases are typical for workloads that allocate large arrays of data on its threads stacks or the possible SIZE to collect can't be large enough due to workload nature or system configuration and this is where hardware captured LBR call stacks can provide missing stack frames. Possible DWARF plus LBR call stacks consolidation algorithm description follows. With this patch set perf report command UI currently ignores collected LBR call stack data and still provides DWARF based call stacks information. =========================================================================== Overview: Legend: THS - thread stack CTX - thread register context SWS - software stack SSF - skipped stack frames PSS - Perf sample stack ip,sp,bp - HW registers values d - allocated stack regions kip - ip address in the kernel space K - captured thread stack size THS ----- | |<-stack bottom ... |---| |ip4| |---| PSS = SWS(THS(K)) | | --> | | | |d3 | user/ | |---| user PSS kernel PSS | |ip3| ------ ------ | |---| |SSF | |SSF | | | | .... .... | | | ------ ------ | |d2 | | -1 | | -1 | |---| user ------ ------ K |ip2| CTX |ip3 | |ip3 | |---| |----| |----| | |d1 | ... |ip2 | , |ip2 | | |---| |---| |----| |----| | |ip1| |bp0| |ip1 | |ip1 | | |---| |---| |----| |----| | | | |ip0|->|ip0 | |ip0 |<-user stack top | | | |---| ------ ------ | | |<-|sp0|<-stack |kip0|<-kernel stack bottom --> ----- ----- top |----| |kip1| |----| |kip2| |----| .... | |<-kernel stack top ------ Algorithm details: Legend: HWS - hardware stack K-SWS - kernel software stack BRANCH TABLE HWS ip ip from to ------ ----------- |ip7`| |ip7`| | |----| |----|----| |ip6`| |ip6`| | user PSS |----| |----|----| |ip5`| |ip5`| | ------ |----| |----|----| | -1 | |ip4`| |ip4`| | ------ |----| |----|----| |ip3 |~~~|ip3`| |ip3`| | |----| |----| |----|----| |ip2 |~~~|ip2`| |ip2`| | |----| |----| |----|----| |ip1 |~~~|ip1`| |ip1`|ip0`| |----| |----| ----------- |ip0 |~~~|ip0`|<---------' ------ ------ 1. if (sym(ipj) == sym(ipj`)), j=0-3 ===> user PSS 2. ipj` , j=4-7 ===> user PSS Augmented PSS = A_SWS(SWS(THS(K)), HWS): user/ user PSS kernel PSS ------ ------ |ip7`| |ip7`|<-user PSS bottom |----| |----| |ip6`| |ip6`| |----| |----| HWS |ip5`| |ip5`| |----| |----| |ip4`| |ip4`| ------ ------ |ip3 | |ip3 | |----| |----| SWS |ip2 | |ip2 | |----| |----| |ip1 | |ip1 | |----| |----| |ip0 | |ip0 |<-user PSS top ------ ------ |kip0|<-kernel PSS bottom |----| |kip1| K-SWS |----| |kip2| |----| |kip3|<-kernel PSS top ------ APSS Committer testing: Before: # perf record -g --call-graph dwarf,1024 -j stack,u ls > /dev/null unknown branch filter stack, check man page Usage: perf record [] [] or: perf record [] -- [] -j, --branch-filter branch stack filter modes # perf record -g --call-graph dwarf,1024 -j u ls > /dev/null [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.054 MB perf.data (12 samples) ] # perf evlist -v cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|ADDR|CALLCHAIN|PERIOD|BRANCH_STACK|REGS_USER|STACK_USER|DATA_SRC, read_format: ID, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 3, mmap_data: 1, sample_id_all: 1, exclude_guest: 1, exclude_callchain_user: 1, mmap2: 1, comm_exec: 1, ksymbol: 1, bpf_event: 1, branch_sample_type: ANY, sample_regs_user: 0xff0fff, sample_stack_user: 1024 # After: # perf record -g --call-graph dwarf,1024 -j stack,u ls > /dev/null [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.044 MB perf.data (11 samples) ] [root@quaco ~]# perf evlist -v cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|ADDR|CALLCHAIN|PERIOD|BRANCH_STACK|REGS_USER|STACK_USER|DATA_SRC, read_format: ID, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 3, mmap_data: 1, sample_id_all: 1, exclude_guest: 1, exclude_callchain_user: 1, mmap2: 1, comm_exec: 1, ksymbol: 1, bpf_event: 1, branch_sample_type: USER|CALL_STACK, sample_regs_user: 0xff0fff, sample_stack_user: 1024 # Signed-off-by: Alexey Budankov Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Andi Kleen Cc: Jin Yao Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/e9e00090-66fb-d2a4-c90f-1d12344f7788@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/parse-branch-options.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c index 726e8d9e8c54..4ed20c833d44 100644 --- a/tools/perf/util/parse-branch-options.c +++ b/tools/perf/util/parse-branch-options.c @@ -30,6 +30,7 @@ static const struct branch_mode branch_modes[] = { BRANCH_OPT("ind_jmp", PERF_SAMPLE_BRANCH_IND_JUMP), BRANCH_OPT("call", PERF_SAMPLE_BRANCH_CALL), BRANCH_OPT("save_type", PERF_SAMPLE_BRANCH_TYPE_SAVE), + BRANCH_OPT("stack", PERF_SAMPLE_BRANCH_CALL_STACK), BRANCH_END }; -- cgit v1.2.3-59-g8ed1b From d2720c3dad58def723f9617f7cf2a48c752ef50a Mon Sep 17 00:00:00 2001 From: Alexey Budankov Date: Fri, 9 Aug 2019 18:26:30 +0300 Subject: perf report: Dump LBR callstack data by -D jointly with thread stack Make perf report -D command print captured LBR callstack chain when it is collected together with raw thread stack data: 2752673087247083 0x5d10 [0x548]: PERF_RECORD_SAMPLE(IP, 0x4002): 5841/5841: 0x40121f period: 1543862 addr: 0 ... FP chain: nr:0 ... branch callstack: nr:3 ..... 0: 00000000004011d0 ..... 1: 00007f393c388411 ..... 2: 0000000000401098 ... user regs: mask 0xff0fff ABI 64-bit .... AX 0x34e7 .... BX 0x7fff5f6dd3c0 .... CX 0xffffffff .... DX 0x34e6 .... SI 0x7f393c5268d0 .... DI 0x0 .... BP 0x401260 .... SP 0x7fff5f6dd3c0 .... IP 0x40121f .... FLAGS 0x29f .... CS 0x33 .... SS 0x2b .... R8 0x7f393c526800 .... R9 0x7f393c525da0 .... R10 0xfffffffffffff70a .... R11 0x246 .... R12 0x401070 .... R13 0x7fff5f6ddcb0 .... R14 0x0 .... R15 0x0 ... ustack: size 1024, offset 0x130 . data_src: 0x5080021 ... thread: stack_test:5841 ...... dso: /root/abudanko/stacks/stack_test Committer testing: # perf record -g --call-graph dwarf,1024 -j stack,u ls > /dev/null [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.042 MB perf.data (10 samples) ] # Before: # perf report -D |& grep PERF_RECORD_SAMPLE -A28 | tail -29 67538909824483 0xa7a0 [0x560]: PERF_RECORD_SAMPLE(IP, 0x4002): 9721/9721: 0x7f441b2b1e20 period: 1376095 addr: 0 ... FP chain: nr:0 ... user regs: mask 0xff0fff ABI 64-bit .... AX 0x7f441b2b1000 .... BX 0x7f441b55b970 .... CX 0x7fff6e2db218 .... DX 0x7fff6e2db218 .... SI 0x7fff6e2db208 .... DI 0x1 .... BP 0x1 .... SP 0x7fff6e2db178 .... IP 0x7f441b2b1e20 .... FLAGS 0x20a .... CS 0x33 .... SS 0x2b .... R8 0x1 .... R9 0x7f441b371c18 .... R10 0x7f441b5a5f10 .... R11 0x202 .... R12 0x7fff6e2db208 .... R13 0x7fff6e2db218 .... R14 0x7f441b5a7150 .... R15 0x0 ... ustack: size 1024, offset 0x148 . data_src: 0x5080021 ... thread: ls:9721 ...... dso: /usr/lib64/libpthread-2.29.so 0xad00 [0x60]: event: 10 # After: # perf report -D |& grep PERF_RECORD_SAMPLE -A31 | tail -32 67538909824483 0xa7a0 [0x560]: PERF_RECORD_SAMPLE(IP, 0x4002): 9721/9721: 0x7f441b2b1e20 period: 1376095 addr: 0 ... FP chain: nr:0 ... branch callstack: nr:4 ..... 0: 00007f441b2b1e20 ..... 1: 00007f441b58af1a ..... 2: 00007f441b58b0e1 ..... 3: 00007f441b57c145 ... user regs: mask 0xff0fff ABI 64-bit .... AX 0x7f441b2b1000 .... BX 0x7f441b55b970 .... CX 0x7fff6e2db218 .... DX 0x7fff6e2db218 .... SI 0x7fff6e2db208 .... DI 0x1 .... BP 0x1 .... SP 0x7fff6e2db178 .... IP 0x7f441b2b1e20 .... FLAGS 0x20a .... CS 0x33 .... SS 0x2b .... R8 0x1 .... R9 0x7f441b371c18 .... R10 0x7f441b5a5f10 .... R11 0x202 .... R12 0x7fff6e2db208 .... R13 0x7fff6e2db218 .... R14 0x7f441b5a7150 .... R15 0x0 ... ustack: size 1024, offset 0x148 . data_src: 0x5080021 ... thread: ls:9721 ...... dso: /usr/lib64/libpthread-2.29.so # Signed-off-by: Alexey Budankov Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Andi Kleen Cc: Jin Yao Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/aa82e5dd-def2-0ca8-a064-db9e2e8ad076@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index b9fe71d11bf6..82e0438a9160 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1051,23 +1051,30 @@ static void callchain__printf(struct evsel *evsel, i, callchain->ips[i]); } -static void branch_stack__printf(struct perf_sample *sample) +static void branch_stack__printf(struct perf_sample *sample, bool callstack) { uint64_t i; - printf("... branch stack: nr:%" PRIu64 "\n", sample->branch_stack->nr); + printf("%s: nr:%" PRIu64 "\n", + !callstack ? "... branch stack" : "... branch callstack", + sample->branch_stack->nr); for (i = 0; i < sample->branch_stack->nr; i++) { struct branch_entry *e = &sample->branch_stack->entries[i]; - printf("..... %2"PRIu64": %016" PRIx64 " -> %016" PRIx64 " %hu cycles %s%s%s%s %x\n", - i, e->from, e->to, - (unsigned short)e->flags.cycles, - e->flags.mispred ? "M" : " ", - e->flags.predicted ? "P" : " ", - e->flags.abort ? "A" : " ", - e->flags.in_tx ? "T" : " ", - (unsigned)e->flags.reserved); + if (!callstack) { + printf("..... %2"PRIu64": %016" PRIx64 " -> %016" PRIx64 " %hu cycles %s%s%s%s %x\n", + i, e->from, e->to, + (unsigned short)e->flags.cycles, + e->flags.mispred ? "M" : " ", + e->flags.predicted ? "P" : " ", + e->flags.abort ? "A" : " ", + e->flags.in_tx ? "T" : " ", + (unsigned)e->flags.reserved); + } else { + printf("..... %2"PRIu64": %016" PRIx64 "\n", + i, i > 0 ? e->from : e->to); + } } } @@ -1217,8 +1224,8 @@ static void dump_sample(struct evsel *evsel, union perf_event *event, if (evsel__has_callchain(evsel)) callchain__printf(evsel, sample); - if ((sample_type & PERF_SAMPLE_BRANCH_STACK) && !perf_evsel__has_branch_callstack(evsel)) - branch_stack__printf(sample); + if (sample_type & PERF_SAMPLE_BRANCH_STACK) + branch_stack__printf(sample, perf_evsel__has_branch_callstack(evsel)); if (sample_type & PERF_SAMPLE_REGS_USER) regs_user__printf(sample); -- cgit v1.2.3-59-g8ed1b From 10ccbc1cc0b8a05a5c8491630d36d1e2672036c1 Mon Sep 17 00:00:00 2001 From: Alexey Budankov Date: Fri, 9 Aug 2019 18:31:28 +0300 Subject: perf report: Prefer DWARF callstacks to LBR ones when captured both Display DWARF based callchains when the perf.data file contains raw thread stack data as LBR callstack data. Commiter testing: This changes the output from the branch stack based one, i.e. without this patch, for the same file as in the previous csets: # perf report --stdio # To display the perf.data header info, please use --header/--header-only options. # # Total Lost Samples: 0 # # Samples: 13 of event 'cycles' # Event count (approx.): 13 # # Overhead Command Source Shared Object Source Symbol Target Symbol Basic Block Cycles # ........ ....... .................... ........................... ......................................... .................. # 7.69% ls libpthread-2.29.so [.] _init [.] __pthread_initialize_minimal_internal 6827 7.69% ls ld-2.29.so [k] _start [k] _dl_start - 7.69% ls ld-2.29.so [.] _dl_start_user [.] _dl_init -24790 7.69% ls ld-2.29.so [k] _dl_start [k] _dl_sysdep_start 278 7.69% ls ld-2.29.so [k] dl_main [k] _dl_map_object_deps 15581 7.69% ls ld-2.29.so [k] open_verify.constprop.0 [k] lseek64 4228 7.69% ls ld-2.29.so [k] _dl_map_object [k] open_verify.constprop.0 55 7.69% ls ld-2.29.so [k] openaux [k] _dl_map_object 67 7.69% ls ld-2.29.so [k] _dl_map_object_deps [k] 0x00007f441b57c090 112 7.69% ls ld-2.29.so [.] call_init.part.0 [.] _init 334 7.69% ls ld-2.29.so [.] _dl_init [.] call_init.part.0 383 7.69% ls ld-2.29.so [k] _dl_sysdep_start [k] dl_main 45 7.69% ls ld-2.29.so [k] _dl_catch_exception [k] openaux 116 # # (Tip: For memory address profiling, try: perf mem record / perf mem report) # To the one that shows call chains: # perf report --stdio # To display the perf.data header info, please use --header/--header-only options. # # # Total Lost Samples: 0 # # Samples: 10 of event 'cycles' # Event count (approx.): 3204047 # # Children Self Command Shared Object Symbol # ........ ........ ....... .................. ......................................... # 55.01% 0.00% ls [kernel.vmlinux] [k] entry_SYSCALL_64_after_hwframe | ---entry_SYSCALL_64_after_hwframe do_syscall_64 | --16.01%--__x64_sys_execve __do_execve_file.isra.0 search_binary_handler load_elf_binary elf_map vm_mmap_pgoff do_mmap mmap_region perf_event_mmap perf_iterate_sb perf_iterate_ctx perf_event_mmap_output perf_output_copy memcpy_erms 55.01% 39.00% ls [kernel.vmlinux] [k] do_syscall_64 | |--39.00%--0xffffffffffffffff | _dl_map_object | open_verify.constprop.0 | __lseek64 (inlined) | entry_SYSCALL_64_after_hwframe | do_syscall_64 | --16.01%--do_syscall_64 __x64_sys_execve __do_execve_file.isra.0 search_binary_handler load_elf_binary elf_map vm_mmap_pgoff do_mmap mmap_region perf_event_mmap perf_iterate_sb perf_iterate_ctx perf_event_mmap_output perf_output_copy memcpy_erms 42.95% 42.95% ls libpthread-2.29.so [.] __pthread_initialize_minimal_internal | ---_init __pthread_initialize_minimal_internal 42.95% 0.00% ls libpthread-2.29.so [.] _init | ---_init __pthread_initialize_minimal_internal # # (Tip: Profiling branch (mis)predictions with: perf record -b / perf report) # # The branch stack view be explicitely selected using: # perf report -h branch-stack Usage: perf report [] -b, --branch-stack use branch records for per branch histogram filling # I.e. after this patch: # perf report -b --stdio # To display the perf.data header info, please use --header/--header-only options. # # # Total Lost Samples: 0 # # Samples: 13 of event 'cycles' # Event count (approx.): 13 # # Overhead Command Source Shared Object Source Symbol Target Symbol Basic Block Cycles # ........ ....... .................... ........................... ......................................... .................. # 7.69% ls libpthread-2.29.so [.] _init [.] __pthread_initialize_minimal_internal 6827 7.69% ls ld-2.29.so [k] _start [k] _dl_start - 7.69% ls ld-2.29.so [.] _dl_start_user [.] _dl_init -24790 7.69% ls ld-2.29.so [k] _dl_start [k] _dl_sysdep_start 278 7.69% ls ld-2.29.so [k] dl_main [k] _dl_map_object_deps 15581 7.69% ls ld-2.29.so [k] open_verify.constprop.0 [k] lseek64 4228 7.69% ls ld-2.29.so [k] _dl_map_object [k] open_verify.constprop.0 55 7.69% ls ld-2.29.so [k] openaux [k] _dl_map_object 67 7.69% ls ld-2.29.so [k] _dl_map_object_deps [k] 0x00007f441b57c090 112 7.69% ls ld-2.29.so [.] call_init.part.0 [.] _init 334 7.69% ls ld-2.29.so [.] _dl_init [.] call_init.part.0 383 7.69% ls ld-2.29.so [k] _dl_sysdep_start [k] dl_main 45 7.69% ls ld-2.29.so [k] _dl_catch_exception [k] openaux 116 # # (Tip: Show current config key-value pairs: perf config --list) # # Signed-off-by: Alexey Budankov Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Andi Kleen Cc: Jin Yao Cc: Jiri Olsa Cc: Kan Liang Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/ccbd9583-82f4-dec5-7e84-64bf56e351fb@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-report.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 5e003d02821e..79dfb1139f94 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -1281,6 +1281,8 @@ repeat: has_br_stack = perf_header__has_feat(&session->header, HEADER_BRANCH_STACK); + if (perf_evlist__combined_sample_type(session->evlist) & PERF_SAMPLE_STACK_USER) + has_br_stack = false; setup_forced_leader(&report, session->evlist); -- cgit v1.2.3-59-g8ed1b From a4973d8f7bea98a0795ba853e7bd2cef11363824 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Thu, 15 Aug 2019 16:28:54 +0800 Subject: perf cs-etm: Support sample flags 'insn' and 'insnlen' The synthetic branch and instruction samples are missed to set instruction related info, thus the perf tool fails to display samples with flags '-F,+insn,+insnlen'. The CoreSight trace decoder provides sufficient information to decide the instruction size based on the ISA type: A64/A32 instructions are 32-bit size, but one exception is the T32 instruction size, which might be 32-bit or 16-bit. This patch handles these cases and it reads the instruction values from DSO file; thus can support the flags '-F,+insn,+insnlen'. Before: # perf script -F,insn,insnlen,ip,sym 0 [unknown] ilen: 0 ffff97174044 _start ilen: 0 ffff97174938 _dl_start ilen: 0 ffff97174938 _dl_start ilen: 0 ffff97174938 _dl_start ilen: 0 ffff97174938 _dl_start ilen: 0 ffff97174938 _dl_start ilen: 0 ffff97174938 _dl_start ilen: 0 ffff97174938 _dl_start ilen: 0 ffff97174938 _dl_start ilen: 0 [...] After: # perf script -F,insn,insnlen,ip,sym 0 [unknown] ilen: 0 ffff97174044 _start ilen: 4 insn: 2f 02 00 94 ffff97174938 _dl_start ilen: 4 insn: c1 ff ff 54 ffff97174938 _dl_start ilen: 4 insn: c1 ff ff 54 ffff97174938 _dl_start ilen: 4 insn: c1 ff ff 54 ffff97174938 _dl_start ilen: 4 insn: c1 ff ff 54 ffff97174938 _dl_start ilen: 4 insn: c1 ff ff 54 ffff97174938 _dl_start ilen: 4 insn: c1 ff ff 54 ffff97174938 _dl_start ilen: 4 insn: c1 ff ff 54 ffff97174938 _dl_start ilen: 4 insn: c1 ff ff 54 [...] Signed-off-by: Leo Yan Reviewed-by: Mathieu Poirier Tested-by: Mathieu Poirier Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Mike Leach Cc: Namhyung Kim Cc: Robert Walker Cc: Suzuki Poulouse Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/20190815082854.18191-1-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index ed6f7fd5b90b..b3a5daaf1a8f 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -1076,6 +1076,35 @@ bool cs_etm__etmq_is_timeless(struct cs_etm_queue *etmq) return !!etmq->etm->timeless_decoding; } +static void cs_etm__copy_insn(struct cs_etm_queue *etmq, + u64 trace_chan_id, + const struct cs_etm_packet *packet, + struct perf_sample *sample) +{ + /* + * It's pointless to read instructions for the CS_ETM_DISCONTINUITY + * packet, so directly bail out with 'insn_len' = 0. + */ + if (packet->sample_type == CS_ETM_DISCONTINUITY) { + sample->insn_len = 0; + return; + } + + /* + * T32 instruction size might be 32-bit or 16-bit, decide by calling + * cs_etm__t32_instr_size(). + */ + if (packet->isa == CS_ETM_ISA_T32) + sample->insn_len = cs_etm__t32_instr_size(etmq, trace_chan_id, + sample->ip); + /* Otherwise, A64 and A32 instruction size are always 32-bit. */ + else + sample->insn_len = 4; + + cs_etm__mem_access(etmq, trace_chan_id, sample->ip, + sample->insn_len, (void *)sample->insn); +} + static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq, struct cs_etm_traceid_queue *tidq, u64 addr, u64 period) @@ -1097,9 +1126,10 @@ static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq, sample.period = period; sample.cpu = tidq->packet->cpu; sample.flags = tidq->prev_packet->flags; - sample.insn_len = 1; sample.cpumode = event->sample.header.misc; + cs_etm__copy_insn(etmq, tidq->trace_chan_id, tidq->packet, &sample); + if (etm->synth_opts.last_branch) { cs_etm__copy_last_branch_rb(etmq, tidq); sample.branch_stack = tidq->last_branch; @@ -1159,6 +1189,9 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq, sample.flags = tidq->prev_packet->flags; sample.cpumode = event->sample.header.misc; + cs_etm__copy_insn(etmq, tidq->trace_chan_id, tidq->prev_packet, + &sample); + /* * perf report cannot handle events without a branch stack */ -- cgit v1.2.3-59-g8ed1b From 9e79ff77e4195e40e7a47a2001132db66e25d541 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 19 Aug 2019 16:09:50 -0300 Subject: perf ui: Make 'exit_msg' optional in ui__question_window() We will not need it when refactoring this function to be non-interactive, so make it optional. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-pnx1dn17bsz7lqt9ty95nnjx@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/tui/util.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c index fe5e571816fc..5d65ea8b6496 100644 --- a/tools/perf/ui/tui/util.c +++ b/tools/perf/ui/tui/util.c @@ -188,7 +188,9 @@ int ui__question_window(const char *title, const char *text, pthread_mutex_lock(&ui__lock); max_len += 2; - nr_lines += 4; + nr_lines += 2; + if (exit_msg) + nr_lines += 2; y = SLtt_Screen_Rows / 2 - nr_lines / 2, x = SLtt_Screen_Cols / 2 - max_len / 2; @@ -199,14 +201,20 @@ int ui__question_window(const char *title, const char *text, SLsmg_write_string((char *)title); } SLsmg_gotorc(++y, x); - nr_lines -= 2; + if (exit_msg) + nr_lines -= 2; max_len -= 2; SLsmg_write_wrapped_string((unsigned char *)text, y, x, nr_lines, max_len, 1); SLsmg_gotorc(y + nr_lines - 2, x); SLsmg_write_nstring((char *)" ", max_len); SLsmg_gotorc(y + nr_lines - 1, x); - SLsmg_write_nstring((char *)exit_msg, max_len); + if (exit_msg) { + SLsmg_gotorc(y + nr_lines - 2, x); + SLsmg_write_nstring((char *)" ", max_len); + SLsmg_gotorc(y + nr_lines - 1, x); + SLsmg_write_nstring((char *)exit_msg, max_len); + } SLsmg_refresh(); pthread_mutex_unlock(&ui__lock); -- cgit v1.2.3-59-g8ed1b From 9b01611934c045ac7ca71aebf5ee1906951d6bce Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 19 Aug 2019 16:38:24 -0300 Subject: perf ui: Introduce non-interactive ui__info_window() function Sometimes we want just to print a message on the center of the screen, like in 'perf top' while we wait for the minimum amount of samples to be collected before sorting and showing them. Also expose __ui__info_window() as an optimization for cases where such message is to be printed while holding the ui lock. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-uat0f89vfwl2w52kv9wzwd8a@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/tui/util.c | 23 +++++++++++++++-------- tools/perf/ui/util.h | 2 ++ 2 files changed, 17 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c index 5d65ea8b6496..1163df8b6f06 100644 --- a/tools/perf/ui/tui/util.c +++ b/tools/perf/ui/tui/util.c @@ -162,8 +162,7 @@ next_key: return key; } -int ui__question_window(const char *title, const char *text, - const char *exit_msg, int delay_secs) +void __ui__info_window(const char *title, const char *text, const char *exit_msg) { int x, y; int max_len = 0, nr_lines = 0; @@ -185,8 +184,6 @@ int ui__question_window(const char *title, const char *text, t = sep + 1; } - pthread_mutex_lock(&ui__lock); - max_len += 2; nr_lines += 2; if (exit_msg) @@ -206,19 +203,29 @@ int ui__question_window(const char *title, const char *text, max_len -= 2; SLsmg_write_wrapped_string((unsigned char *)text, y, x, nr_lines, max_len, 1); - SLsmg_gotorc(y + nr_lines - 2, x); - SLsmg_write_nstring((char *)" ", max_len); - SLsmg_gotorc(y + nr_lines - 1, x); if (exit_msg) { SLsmg_gotorc(y + nr_lines - 2, x); SLsmg_write_nstring((char *)" ", max_len); SLsmg_gotorc(y + nr_lines - 1, x); SLsmg_write_nstring((char *)exit_msg, max_len); } - SLsmg_refresh(); +} +void ui__info_window(const char *title, const char *text) +{ + pthread_mutex_lock(&ui__lock); + __ui__info_window(title, text, NULL); + SLsmg_refresh(); pthread_mutex_unlock(&ui__lock); +} +int ui__question_window(const char *title, const char *text, + const char *exit_msg, int delay_secs) +{ + pthread_mutex_lock(&ui__lock); + __ui__info_window(title, text, exit_msg); + SLsmg_refresh(); + pthread_mutex_unlock(&ui__lock); return ui__getch(delay_secs); } diff --git a/tools/perf/ui/util.h b/tools/perf/ui/util.h index 5e44223b56fa..40891942f465 100644 --- a/tools/perf/ui/util.h +++ b/tools/perf/ui/util.h @@ -8,6 +8,8 @@ int ui__getch(int delay_secs); int ui__popup_menu(int argc, char * const argv[]); int ui__help_window(const char *text); int ui__dialog_yesno(const char *msg); +void __ui__info_window(const char *title, const char *text, const char *exit_msg); +void ui__info_window(const char *title, const char *text); int ui__question_window(const char *title, const char *text, const char *exit_msg, int delay_secs); -- cgit v1.2.3-59-g8ed1b From 2284cf8074ff12b6304665618f81ced3aa0b41de Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 19 Aug 2019 16:43:58 -0300 Subject: perf ui browser: Allow specifying message to show when no samples are available to display The 'perf top' tool will use that to avoid having a initial blank screen while collecting the minimum number of samples to sort and display. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-89ciceg8cy4442he3t0jzo3f@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browser.c | 2 ++ tools/perf/ui/browser.h | 1 + 2 files changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index d227d74b28f8..c797a853d3a0 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -347,6 +347,8 @@ static int __ui_browser__refresh(struct ui_browser *browser) SLsmg_fill_region(browser->y + row + browser->extra_title_lines, browser->x, browser->rows - row, width, ' '); + if (browser->nr_entries == 0 && browser->no_samples_msg) + __ui__info_window(NULL, browser->no_samples_msg, NULL); return 0; } diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h index dc1444136658..3678eb88f119 100644 --- a/tools/perf/ui/browser.h +++ b/tools/perf/ui/browser.h @@ -23,6 +23,7 @@ struct ui_browser { void *priv; const char *title; char *helpline; + const char *no_samples_msg; void (*refresh_dimensions)(struct ui_browser *browser); unsigned int (*refresh)(struct ui_browser *browser); void (*write)(struct ui_browser *browser, void *entry, int row); -- cgit v1.2.3-59-g8ed1b From 5c959b6d8f9369e42a3cb0423bcce9ac069cee55 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 19 Aug 2019 16:48:25 -0300 Subject: perf top: Show info message while collecting samples Give visual cue about what is happening while initially collecting the minimal set of samples to collect/sort/display. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-xcui60p1v6ozijfam2o89ya8@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/hists.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index b195b1ba625b..30547fdb0787 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -2894,6 +2894,9 @@ static int perf_evsel__hists_browse(struct evsel *evsel, int nr_events, if (symbol_conf.col_width_list_str) perf_hpp__set_user_width(symbol_conf.col_width_list_str); + if (!is_report_browser(hbt)) + browser->b.no_samples_msg = "Collecting samples..."; + while (1) { struct thread *thread = NULL; struct map *map = NULL; -- cgit v1.2.3-59-g8ed1b From 42fc2e9ef9603a7948aaa4ffd8dfb94b30294ad8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 20 Aug 2019 11:45:17 -0300 Subject: tools headers: Fixup bitsperlong per arch includes We were getting the file by luck, from one of the paths in -I, fix it to get it from the proper place: $ cd tools/include/uapi/asm/ [acme@quaco asm]$ grep include bitsperlong.h #include "../../arch/x86/include/uapi/asm/bitsperlong.h" #include "../../arch/arm64/include/uapi/asm/bitsperlong.h" #include "../../arch/powerpc/include/uapi/asm/bitsperlong.h" #include "../../arch/s390/include/uapi/asm/bitsperlong.h" #include "../../arch/sparc/include/uapi/asm/bitsperlong.h" #include "../../arch/mips/include/uapi/asm/bitsperlong.h" #include "../../arch/ia64/include/uapi/asm/bitsperlong.h" #include "../../arch/riscv/include/uapi/asm/bitsperlong.h" #include "../../arch/alpha/include/uapi/asm/bitsperlong.h" #include $ ls -la ../../arch/x86/include/uapi/asm/bitsperlong.h ls: cannot access '../../arch/x86/include/uapi/asm/bitsperlong.h': No such file or directory $ ls -la ../../../arch/*/include/uapi/asm/bitsperlong.h -rw-rw-r--. 1 237 ../../../arch/alpha/include/uapi/asm/bitsperlong.h -rw-rw-r--. 1 841 ../../../arch/arm64/include/uapi/asm/bitsperlong.h -rw-rw-r--. 1 966 ../../../arch/hexagon/include/uapi/asm/bitsperlong.h -rw-rw-r--. 1 234 ../../../arch/ia64/include/uapi/asm/bitsperlong.h -rw-rw-r--. 1 100 ../../../arch/microblaze/include/uapi/asm/bitsperlong.h -rw-rw-r--. 1 244 ../../../arch/mips/include/uapi/asm/bitsperlong.h -rw-rw-r--. 1 352 ../../../arch/parisc/include/uapi/asm/bitsperlong.h -rw-rw-r--. 1 312 ../../../arch/powerpc/include/uapi/asm/bitsperlong.h -rw-rw-r--. 1 353 ../../../arch/riscv/include/uapi/asm/bitsperlong.h -rw-rw-r--. 1 292 ../../../arch/s390/include/uapi/asm/bitsperlong.h -rw-rw-r--. 1 323 ../../../arch/sparc/include/uapi/asm/bitsperlong.h -rw-rw-r--. 1 320 ../../../arch/x86/include/uapi/asm/bitsperlong.h $ Found while fixing some other problem, before it was escaping the tools/ chroot and using stuff in the kernel sources: CC /tmp/build/perf/util/find_bit.o In file included from /git/linux/tools/include/../../arch/x86/include/uapi/asm/bitsperlong.h:11, from /git/linux/tools/include/uapi/asm/bitsperlong.h:3, from /git/linux/tools/include/linux/bits.h:6, from /git/linux/tools/include/linux/bitops.h:13, from ../lib/find_bit.c:17: # cd /git/linux/tools/include/../../arch/x86/include/uapi/asm/ # pwd /git/linux/arch/x86/include/uapi/asm # Now it is getting the one we want it to, i.e. the one inside tools/: CC /tmp/build/perf/util/find_bit.o In file included from /git/linux/tools/arch/x86/include/uapi/asm/bitsperlong.h:11, from /git/linux/tools/include/linux/bits.h:6, from /git/linux/tools/include/linux/bitops.h:13, Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-8f8cfqywmf6jk8a3ucr0ixhu@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/asm/bitsperlong.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/include/uapi/asm/bitsperlong.h b/tools/include/uapi/asm/bitsperlong.h index 57aaeaf8e192..edba4d93e9e6 100644 --- a/tools/include/uapi/asm/bitsperlong.h +++ b/tools/include/uapi/asm/bitsperlong.h @@ -1,22 +1,22 @@ /* SPDX-License-Identifier: GPL-2.0 */ #if defined(__i386__) || defined(__x86_64__) -#include "../../arch/x86/include/uapi/asm/bitsperlong.h" +#include "../../../arch/x86/include/uapi/asm/bitsperlong.h" #elif defined(__aarch64__) -#include "../../arch/arm64/include/uapi/asm/bitsperlong.h" +#include "../../../arch/arm64/include/uapi/asm/bitsperlong.h" #elif defined(__powerpc__) -#include "../../arch/powerpc/include/uapi/asm/bitsperlong.h" +#include "../../../arch/powerpc/include/uapi/asm/bitsperlong.h" #elif defined(__s390__) -#include "../../arch/s390/include/uapi/asm/bitsperlong.h" +#include "../../../arch/s390/include/uapi/asm/bitsperlong.h" #elif defined(__sparc__) -#include "../../arch/sparc/include/uapi/asm/bitsperlong.h" +#include "../../../arch/sparc/include/uapi/asm/bitsperlong.h" #elif defined(__mips__) -#include "../../arch/mips/include/uapi/asm/bitsperlong.h" +#include "../../../arch/mips/include/uapi/asm/bitsperlong.h" #elif defined(__ia64__) -#include "../../arch/ia64/include/uapi/asm/bitsperlong.h" +#include "../../../arch/ia64/include/uapi/asm/bitsperlong.h" #elif defined(__riscv) -#include "../../arch/riscv/include/uapi/asm/bitsperlong.h" +#include "../../../arch/riscv/include/uapi/asm/bitsperlong.h" #elif defined(__alpha__) -#include "../../arch/alpha/include/uapi/asm/bitsperlong.h" +#include "../../../arch/alpha/include/uapi/asm/bitsperlong.h" #else #include #endif -- cgit v1.2.3-59-g8ed1b From b81d39c7a1efb83caa3f4419939a46e96191abb6 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 20 Aug 2019 14:46:24 +0200 Subject: libperf: Fix arch include paths Guenter Roeck reported problem with compilation when the ARCH is specified: $ make ARCH=x86_64 In file included from tools/include/asm/atomic.h:6:0, from include/linux/atomic.h:5, from tools/include/linux/refcount.h:41, from cpumap.c:4: tools/include/asm/../../arch/x86/include/asm/atomic.h:11:10: fatal error: asm/cmpxchg.h: No such file or directory The problem is that we don't use SRCARCH (the sanitized ARCH version) and we don't get the proper include path. Reported-by: Guenter Roeck Signed-off-by: Jiri Olsa Tested-by: Guenter Roeck Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Fixes: 314350491810 ("libperf: Make libperf.a part of the perf build") Link: http://lkml.kernel.org/r/20190820124624.GG24105@krava Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/lib/Makefile b/tools/perf/lib/Makefile index 8a9ae50818e4..a67efb8d9d39 100644 --- a/tools/perf/lib/Makefile +++ b/tools/perf/lib/Makefile @@ -59,7 +59,7 @@ else CFLAGS := -g -Wall endif -INCLUDES = -I$(srctree)/tools/perf/lib/include -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/ -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi +INCLUDES = -I$(srctree)/tools/perf/lib/include -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(SRCARCH)/include/ -I$(srctree)/tools/arch/$(SRCARCH)/include/uapi -I$(srctree)/tools/include/uapi # Append required CFLAGS override CFLAGS += $(EXTRA_WARNINGS) -- cgit v1.2.3-59-g8ed1b From 89eb4d8d25722a0a0194cf7fa47ba602e32a6da7 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 19 Aug 2019 16:44:09 +0200 Subject: Tools: hv: kvp: eliminate 'may be used uninitialized' warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When building hv_kvp_daemon GCC-8.3 complains: hv_kvp_daemon.c: In function ‘kvp_get_ip_info.constprop’: hv_kvp_daemon.c:812:30: warning: ‘ip_buffer’ may be used uninitialized in this function [-Wmaybe-uninitialized] struct hv_kvp_ipaddr_value *ip_buffer; this seems to be a false positive: we only use ip_buffer when op == KVP_OP_GET_IP_INFO and it is only unset when op == KVP_OP_ENUMERATE. Silence the warning by initializing ip_buffer to NULL. Signed-off-by: Vitaly Kuznetsov Signed-off-by: Sasha Levin --- tools/hv/hv_kvp_daemon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index f5597503c771..e9ef4ca6a655 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -809,7 +809,7 @@ kvp_get_ip_info(int family, char *if_name, int op, int sn_offset = 0; int error = 0; char *buffer; - struct hv_kvp_ipaddr_value *ip_buffer; + struct hv_kvp_ipaddr_value *ip_buffer = NULL; char cidr_mask[5]; /* /xyz */ int weight; int i; -- cgit v1.2.3-59-g8ed1b From 9b543419652917f048310d0863c47c107c26fb0c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 19 Aug 2019 15:41:00 +0300 Subject: Tools: hv: move to tools buildsystem There is a nice buildsystem dedicated for userspace tools in Linux kernel tree. Switch Hyper-V daemons to be built by it. Cc: Vitaly Kuznetsov Signed-off-by: Andy Shevchenko Tested-by: Vitaly Kuznetsov Signed-off-by: Sasha Levin --- tools/hv/Build | 3 +++ tools/hv/Makefile | 51 +++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 tools/hv/Build (limited to 'tools') diff --git a/tools/hv/Build b/tools/hv/Build new file mode 100644 index 000000000000..6cf51fa4b306 --- /dev/null +++ b/tools/hv/Build @@ -0,0 +1,3 @@ +hv_kvp_daemon-y += hv_kvp_daemon.o +hv_vss_daemon-y += hv_vss_daemon.o +hv_fcopy_daemon-y += hv_fcopy_daemon.o diff --git a/tools/hv/Makefile b/tools/hv/Makefile index 5db5e62cebda..b57143d9459c 100644 --- a/tools/hv/Makefile +++ b/tools/hv/Makefile @@ -1,28 +1,55 @@ # SPDX-License-Identifier: GPL-2.0 # Makefile for Hyper-V tools - -WARNINGS = -Wall -Wextra -CFLAGS = $(WARNINGS) -g $(shell getconf LFS_CFLAGS) - -CFLAGS += -D__EXPORTED_HEADERS__ -I../../include/uapi -I../../include +include ../scripts/Makefile.include sbindir ?= /usr/sbin libexecdir ?= /usr/libexec sharedstatedir ?= /var/lib -ALL_PROGRAMS := hv_kvp_daemon hv_vss_daemon hv_fcopy_daemon +ifeq ($(srctree),) +srctree := $(patsubst %/,%,$(dir $(CURDIR))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +endif + +# Do not use make's built-in rules +# (this improves performance and avoids hard-to-debug behaviour); +MAKEFLAGS += -r + +override CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include + +ALL_TARGETS := hv_kvp_daemon hv_vss_daemon hv_fcopy_daemon +ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS)) ALL_SCRIPTS := hv_get_dhcp_info.sh hv_get_dns_info.sh hv_set_ifconfig.sh all: $(ALL_PROGRAMS) -%: %.c - $(CC) $(CFLAGS) -o $@ $^ +export srctree OUTPUT CC LD CFLAGS +include $(srctree)/tools/build/Makefile.include + +HV_KVP_DAEMON_IN := $(OUTPUT)hv_kvp_daemon-in.o +$(HV_KVP_DAEMON_IN): FORCE + $(Q)$(MAKE) $(build)=hv_kvp_daemon +$(OUTPUT)hv_kvp_daemon: $(HV_KVP_DAEMON_IN) + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ + +HV_VSS_DAEMON_IN := $(OUTPUT)hv_vss_daemon-in.o +$(HV_VSS_DAEMON_IN): FORCE + $(Q)$(MAKE) $(build)=hv_vss_daemon +$(OUTPUT)hv_vss_daemon: $(HV_VSS_DAEMON_IN) + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ + +HV_FCOPY_DAEMON_IN := $(OUTPUT)hv_fcopy_daemon-in.o +$(HV_FCOPY_DAEMON_IN): FORCE + $(Q)$(MAKE) $(build)=hv_fcopy_daemon +$(OUTPUT)hv_fcopy_daemon: $(HV_FCOPY_DAEMON_IN) + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ clean: - $(RM) hv_kvp_daemon hv_vss_daemon hv_fcopy_daemon + rm -f $(ALL_PROGRAMS) + find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete -install: all +install: $(ALL_PROGRAMS) install -d -m 755 $(DESTDIR)$(sbindir); \ install -d -m 755 $(DESTDIR)$(libexecdir)/hypervkvpd; \ install -d -m 755 $(DESTDIR)$(sharedstatedir); \ @@ -33,3 +60,7 @@ install: all for script in $(ALL_SCRIPTS); do \ install $$script -m 755 $(DESTDIR)$(libexecdir)/hypervkvpd/$${script%.sh}; \ done + +FORCE: + +.PHONY: all install clean FORCE prepare -- cgit v1.2.3-59-g8ed1b From d2648e1ebbceb4da4f2edf5d471963f8831f3554 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Tue, 20 Aug 2019 10:31:51 +0100 Subject: tools: bpf: synchronise BPF UAPI header with tools Synchronise the bpf.h header under tools, to report the addition of the new BPF_BTF_GET_NEXT_ID syscall command for bpf(). Signed-off-by: Quentin Monnet Signed-off-by: Alexei Starovoitov --- tools/include/uapi/linux/bpf.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 0ef594ac3899..8aa6126f0b6e 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -106,6 +106,7 @@ enum bpf_cmd { BPF_TASK_FD_QUERY, BPF_MAP_LOOKUP_AND_DELETE_ELEM, BPF_MAP_FREEZE, + BPF_BTF_GET_NEXT_ID, }; enum bpf_map_type { -- cgit v1.2.3-59-g8ed1b From a6e130c4203bcc73450a00f647d99bd75ded95cb Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Tue, 20 Aug 2019 10:31:52 +0100 Subject: libbpf: refactor bpf_*_get_next_id() functions In preparation for the introduction of a similar function for retrieving the id of the next BTF object, consolidate the code from bpf_prog_get_next_id() and bpf_map_get_next_id() in libbpf. Signed-off-by: Quentin Monnet Reviewed-by: Jakub Kicinski Signed-off-by: Alexei Starovoitov --- tools/lib/bpf/bpf.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index c7d7993c44bb..1439e99c9be5 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c @@ -568,7 +568,7 @@ int bpf_prog_test_run_xattr(struct bpf_prog_test_run_attr *test_attr) return ret; } -int bpf_prog_get_next_id(__u32 start_id, __u32 *next_id) +static int bpf_obj_get_next_id(__u32 start_id, __u32 *next_id, int cmd) { union bpf_attr attr; int err; @@ -576,26 +576,21 @@ int bpf_prog_get_next_id(__u32 start_id, __u32 *next_id) memset(&attr, 0, sizeof(attr)); attr.start_id = start_id; - err = sys_bpf(BPF_PROG_GET_NEXT_ID, &attr, sizeof(attr)); + err = sys_bpf(cmd, &attr, sizeof(attr)); if (!err) *next_id = attr.next_id; return err; } -int bpf_map_get_next_id(__u32 start_id, __u32 *next_id) +int bpf_prog_get_next_id(__u32 start_id, __u32 *next_id) { - union bpf_attr attr; - int err; - - memset(&attr, 0, sizeof(attr)); - attr.start_id = start_id; - - err = sys_bpf(BPF_MAP_GET_NEXT_ID, &attr, sizeof(attr)); - if (!err) - *next_id = attr.next_id; + return bpf_obj_get_next_id(start_id, next_id, BPF_PROG_GET_NEXT_ID); +} - return err; +int bpf_map_get_next_id(__u32 start_id, __u32 *next_id) +{ + return bpf_obj_get_next_id(start_id, next_id, BPF_MAP_GET_NEXT_ID); } int bpf_prog_get_fd_by_id(__u32 id) -- cgit v1.2.3-59-g8ed1b From 09d7c2e32b6e06d58fe7a5aa38847f4719ab4cc7 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Tue, 20 Aug 2019 10:31:53 +0100 Subject: libbpf: add bpf_btf_get_next_id() to cycle through BTF objects Add an API function taking a BTF object id and providing the id of the next BTF object in the kernel. This can be used to list all BTF objects loaded on the system. v2: - Rebase on top of Andrii's changes regarding libbpf versioning. Signed-off-by: Quentin Monnet Reviewed-by: Jakub Kicinski Signed-off-by: Alexei Starovoitov --- tools/lib/bpf/bpf.c | 5 +++++ tools/lib/bpf/bpf.h | 1 + tools/lib/bpf/libbpf.map | 2 ++ 3 files changed, 8 insertions(+) (limited to 'tools') diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index 1439e99c9be5..cbb933532981 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c @@ -593,6 +593,11 @@ int bpf_map_get_next_id(__u32 start_id, __u32 *next_id) return bpf_obj_get_next_id(start_id, next_id, BPF_MAP_GET_NEXT_ID); } +int bpf_btf_get_next_id(__u32 start_id, __u32 *next_id) +{ + return bpf_obj_get_next_id(start_id, next_id, BPF_BTF_GET_NEXT_ID); +} + int bpf_prog_get_fd_by_id(__u32 id) { union bpf_attr attr; diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h index ff42ca043dc8..0db01334740f 100644 --- a/tools/lib/bpf/bpf.h +++ b/tools/lib/bpf/bpf.h @@ -156,6 +156,7 @@ LIBBPF_API int bpf_prog_test_run(int prog_fd, int repeat, void *data, __u32 *retval, __u32 *duration); LIBBPF_API int bpf_prog_get_next_id(__u32 start_id, __u32 *next_id); LIBBPF_API int bpf_map_get_next_id(__u32 start_id, __u32 *next_id); +LIBBPF_API int bpf_btf_get_next_id(__u32 start_id, __u32 *next_id); LIBBPF_API int bpf_prog_get_fd_by_id(__u32 id); LIBBPF_API int bpf_map_get_fd_by_id(__u32 id); LIBBPF_API int bpf_btf_get_fd_by_id(__u32 id); diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map index 4e72df8e98ba..664ce8e7a60e 100644 --- a/tools/lib/bpf/libbpf.map +++ b/tools/lib/bpf/libbpf.map @@ -186,4 +186,6 @@ LIBBPF_0.0.4 { } LIBBPF_0.0.3; LIBBPF_0.0.5 { + global: + bpf_btf_get_next_id; } LIBBPF_0.0.4; -- cgit v1.2.3-59-g8ed1b From 4d374ba0bf30a2a372167ee4b7cdd527e7b47b3b Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Tue, 20 Aug 2019 10:31:54 +0100 Subject: tools: bpftool: implement "bpftool btf show|list" Add a "btf list" (alias: "btf show") subcommand to bpftool in order to dump all BTF objects loaded on a system. When running the command, hash tables are built in bpftool to retrieve all the associations between BTF objects and BPF maps and programs. This allows for printing all such associations when listing the BTF objects. The command is added at the top of the subcommands for "bpftool btf", so that typing only "bpftool btf" also comes down to listing the programs. We could not have this with the previous command ("dump"), which required a BTF object id, so it should not break any previous behaviour. This also makes the "btf" command behaviour consistent with "prog" or "map". Bash completion is updated to use "bpftool btf" instead of "bpftool prog" to list the BTF ids, as it looks more consistent. Example output (plain): # bpftool btf show 9: size 2989B prog_ids 21 map_ids 15 17: size 2847B prog_ids 36 map_ids 30,29,28 26: size 2847B Signed-off-by: Quentin Monnet Reviewed-by: Jakub Kicinski Signed-off-by: Alexei Starovoitov --- tools/bpf/bpftool/Documentation/bpftool-btf.rst | 7 + tools/bpf/bpftool/bash-completion/bpftool | 20 +- tools/bpf/bpftool/btf.c | 342 +++++++++++++++++++++++- 3 files changed, 363 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/Documentation/bpftool-btf.rst b/tools/bpf/bpftool/Documentation/bpftool-btf.rst index 6694a0fc8f99..39615f8e145b 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-btf.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-btf.rst @@ -19,6 +19,7 @@ SYNOPSIS BTF COMMANDS ============= +| **bpftool** **btf** { **show** | **list** } [**id** *BTF_ID*] | **bpftool** **btf dump** *BTF_SRC* [**format** *FORMAT*] | **bpftool** **btf help** | @@ -29,6 +30,12 @@ BTF COMMANDS DESCRIPTION =========== + **bpftool btf { show | list }** [**id** *BTF_ID*] + Show information about loaded BTF objects. If a BTF ID is + specified, show information only about given BTF object, + otherwise list all BTF objects currently loaded on the + system. + **bpftool btf dump** *BTF_SRC* Dump BTF entries from a given *BTF_SRC*. diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool index 4549fd424069..2ffd351f9dbf 100644 --- a/tools/bpf/bpftool/bash-completion/bpftool +++ b/tools/bpf/bpftool/bash-completion/bpftool @@ -73,8 +73,8 @@ _bpftool_get_prog_tags() _bpftool_get_btf_ids() { - COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \ - command sed -n 's/.*"btf_id": \(.*\),\?$/\1/p' )" -- "$cur" ) ) + COMPREPLY+=( $( compgen -W "$( bpftool -jp btf 2>&1 | \ + command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) ) } _bpftool_get_obj_map_names() @@ -670,7 +670,7 @@ _bpftool() map) _bpftool_get_map_ids ;; - dump) + $command) _bpftool_get_btf_ids ;; esac @@ -698,9 +698,21 @@ _bpftool() ;; esac ;; + show|list) + case $prev in + $command) + COMPREPLY+=( $( compgen -W "id" -- "$cur" ) ) + ;; + id) + _bpftool_get_btf_ids + ;; + esac + return 0 + ;; *) [[ $prev == $object ]] && \ - COMPREPLY=( $( compgen -W 'dump help' -- "$cur" ) ) + COMPREPLY=( $( compgen -W 'dump help show list' \ + -- "$cur" ) ) ;; esac ;; diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c index 8805637f1a7e..9a9376d1d3df 100644 --- a/tools/bpf/bpftool/btf.c +++ b/tools/bpf/bpftool/btf.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "btf.h" #include "json_writer.h" @@ -35,6 +36,16 @@ static const char * const btf_kind_str[NR_BTF_KINDS] = { [BTF_KIND_DATASEC] = "DATASEC", }; +struct btf_attach_table { + DECLARE_HASHTABLE(table, 16); +}; + +struct btf_attach_point { + __u32 obj_id; + __u32 btf_id; + struct hlist_node hash; +}; + static const char *btf_int_enc_str(__u8 encoding) { switch (encoding) { @@ -522,6 +533,330 @@ done: return err; } +static int btf_parse_fd(int *argc, char ***argv) +{ + unsigned int id; + char *endptr; + int fd; + + if (!is_prefix(*argv[0], "id")) { + p_err("expected 'id', got: '%s'?", **argv); + return -1; + } + NEXT_ARGP(); + + id = strtoul(**argv, &endptr, 0); + if (*endptr) { + p_err("can't parse %s as ID", **argv); + return -1; + } + NEXT_ARGP(); + + fd = bpf_btf_get_fd_by_id(id); + if (fd < 0) + p_err("can't get BTF object by id (%u): %s", + id, strerror(errno)); + + return fd; +} + +static void delete_btf_table(struct btf_attach_table *tab) +{ + struct btf_attach_point *obj; + struct hlist_node *tmp; + + unsigned int bkt; + + hash_for_each_safe(tab->table, bkt, tmp, obj, hash) { + hash_del(&obj->hash); + free(obj); + } +} + +static int +build_btf_type_table(struct btf_attach_table *tab, enum bpf_obj_type type, + void *info, __u32 *len) +{ + static const char * const names[] = { + [BPF_OBJ_UNKNOWN] = "unknown", + [BPF_OBJ_PROG] = "prog", + [BPF_OBJ_MAP] = "map", + }; + struct btf_attach_point *obj_node; + __u32 btf_id, id = 0; + int err; + int fd; + + while (true) { + switch (type) { + case BPF_OBJ_PROG: + err = bpf_prog_get_next_id(id, &id); + break; + case BPF_OBJ_MAP: + err = bpf_map_get_next_id(id, &id); + break; + default: + err = -1; + p_err("unexpected object type: %d", type); + goto err_free; + } + if (err) { + if (errno == ENOENT) { + err = 0; + break; + } + p_err("can't get next %s: %s%s", names[type], + strerror(errno), + errno == EINVAL ? " -- kernel too old?" : ""); + goto err_free; + } + + switch (type) { + case BPF_OBJ_PROG: + fd = bpf_prog_get_fd_by_id(id); + break; + case BPF_OBJ_MAP: + fd = bpf_map_get_fd_by_id(id); + break; + default: + err = -1; + p_err("unexpected object type: %d", type); + goto err_free; + } + if (fd < 0) { + if (errno == ENOENT) + continue; + p_err("can't get %s by id (%u): %s", names[type], id, + strerror(errno)); + err = -1; + goto err_free; + } + + memset(info, 0, *len); + err = bpf_obj_get_info_by_fd(fd, info, len); + close(fd); + if (err) { + p_err("can't get %s info: %s", names[type], + strerror(errno)); + goto err_free; + } + + switch (type) { + case BPF_OBJ_PROG: + btf_id = ((struct bpf_prog_info *)info)->btf_id; + break; + case BPF_OBJ_MAP: + btf_id = ((struct bpf_map_info *)info)->btf_id; + break; + default: + err = -1; + p_err("unexpected object type: %d", type); + goto err_free; + } + if (!btf_id) + continue; + + obj_node = calloc(1, sizeof(*obj_node)); + if (!obj_node) { + p_err("failed to allocate memory: %s", strerror(errno)); + goto err_free; + } + + obj_node->obj_id = id; + obj_node->btf_id = btf_id; + hash_add(tab->table, &obj_node->hash, obj_node->btf_id); + } + + return 0; + +err_free: + delete_btf_table(tab); + return err; +} + +static int +build_btf_tables(struct btf_attach_table *btf_prog_table, + struct btf_attach_table *btf_map_table) +{ + struct bpf_prog_info prog_info; + __u32 prog_len = sizeof(prog_info); + struct bpf_map_info map_info; + __u32 map_len = sizeof(map_info); + int err = 0; + + err = build_btf_type_table(btf_prog_table, BPF_OBJ_PROG, &prog_info, + &prog_len); + if (err) + return err; + + err = build_btf_type_table(btf_map_table, BPF_OBJ_MAP, &map_info, + &map_len); + if (err) { + delete_btf_table(btf_prog_table); + return err; + } + + return 0; +} + +static void +show_btf_plain(struct bpf_btf_info *info, int fd, + struct btf_attach_table *btf_prog_table, + struct btf_attach_table *btf_map_table) +{ + struct btf_attach_point *obj; + int n; + + printf("%u: ", info->id); + printf("size %uB", info->btf_size); + + n = 0; + hash_for_each_possible(btf_prog_table->table, obj, hash, info->id) { + if (obj->btf_id == info->id) + printf("%s%u", n++ == 0 ? " prog_ids " : ",", + obj->obj_id); + } + + n = 0; + hash_for_each_possible(btf_map_table->table, obj, hash, info->id) { + if (obj->btf_id == info->id) + printf("%s%u", n++ == 0 ? " map_ids " : ",", + obj->obj_id); + } + + printf("\n"); +} + +static void +show_btf_json(struct bpf_btf_info *info, int fd, + struct btf_attach_table *btf_prog_table, + struct btf_attach_table *btf_map_table) +{ + struct btf_attach_point *obj; + + jsonw_start_object(json_wtr); /* btf object */ + jsonw_uint_field(json_wtr, "id", info->id); + jsonw_uint_field(json_wtr, "size", info->btf_size); + + jsonw_name(json_wtr, "prog_ids"); + jsonw_start_array(json_wtr); /* prog_ids */ + hash_for_each_possible(btf_prog_table->table, obj, hash, + info->id) { + if (obj->btf_id == info->id) + jsonw_uint(json_wtr, obj->obj_id); + } + jsonw_end_array(json_wtr); /* prog_ids */ + + jsonw_name(json_wtr, "map_ids"); + jsonw_start_array(json_wtr); /* map_ids */ + hash_for_each_possible(btf_map_table->table, obj, hash, + info->id) { + if (obj->btf_id == info->id) + jsonw_uint(json_wtr, obj->obj_id); + } + jsonw_end_array(json_wtr); /* map_ids */ + jsonw_end_object(json_wtr); /* btf object */ +} + +static int +show_btf(int fd, struct btf_attach_table *btf_prog_table, + struct btf_attach_table *btf_map_table) +{ + struct bpf_btf_info info = {}; + __u32 len = sizeof(info); + int err; + + err = bpf_obj_get_info_by_fd(fd, &info, &len); + if (err) { + p_err("can't get BTF object info: %s", strerror(errno)); + return -1; + } + + if (json_output) + show_btf_json(&info, fd, btf_prog_table, btf_map_table); + else + show_btf_plain(&info, fd, btf_prog_table, btf_map_table); + + return 0; +} + +static int do_show(int argc, char **argv) +{ + struct btf_attach_table btf_prog_table; + struct btf_attach_table btf_map_table; + int err, fd = -1; + __u32 id = 0; + + if (argc == 2) { + fd = btf_parse_fd(&argc, &argv); + if (fd < 0) + return -1; + } + + if (argc) { + if (fd >= 0) + close(fd); + return BAD_ARG(); + } + + hash_init(btf_prog_table.table); + hash_init(btf_map_table.table); + err = build_btf_tables(&btf_prog_table, &btf_map_table); + if (err) { + if (fd >= 0) + close(fd); + return err; + } + + if (fd >= 0) { + err = show_btf(fd, &btf_prog_table, &btf_map_table); + close(fd); + goto exit_free; + } + + if (json_output) + jsonw_start_array(json_wtr); /* root array */ + + while (true) { + err = bpf_btf_get_next_id(id, &id); + if (err) { + if (errno == ENOENT) { + err = 0; + break; + } + p_err("can't get next BTF object: %s%s", + strerror(errno), + errno == EINVAL ? " -- kernel too old?" : ""); + err = -1; + break; + } + + fd = bpf_btf_get_fd_by_id(id); + if (fd < 0) { + if (errno == ENOENT) + continue; + p_err("can't get BTF object by id (%u): %s", + id, strerror(errno)); + err = -1; + break; + } + + err = show_btf(fd, &btf_prog_table, &btf_map_table); + close(fd); + if (err) + break; + } + + if (json_output) + jsonw_end_array(json_wtr); /* root array */ + +exit_free: + delete_btf_table(&btf_prog_table); + delete_btf_table(&btf_map_table); + + return err; +} + static int do_help(int argc, char **argv) { if (json_output) { @@ -530,7 +865,8 @@ static int do_help(int argc, char **argv) } fprintf(stderr, - "Usage: %s btf dump BTF_SRC [format FORMAT]\n" + "Usage: %s btf { show | list } [id BTF_ID]\n" + " %s btf dump BTF_SRC [format FORMAT]\n" " %s btf help\n" "\n" " BTF_SRC := { id BTF_ID | prog PROG | map MAP [{key | value | kv | all}] | file FILE }\n" @@ -539,12 +875,14 @@ static int do_help(int argc, char **argv) " " HELP_SPEC_PROGRAM "\n" " " HELP_SPEC_OPTIONS "\n" "", - bin_name, bin_name); + bin_name, bin_name, bin_name); return 0; } static const struct cmd cmds[] = { + { "show", do_show }, + { "list", do_show }, { "help", do_help }, { "dump", do_dump }, { 0 } -- cgit v1.2.3-59-g8ed1b From 09d2c01ba9e73254e9e6c4fda59d5cf6bd3c89ed Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 16 Aug 2019 14:43:24 -0700 Subject: ACPICA: iASL,acpi_dump: Improve y/n query The y/n query is used for file overwrite. Use fgetc, check for standalone newline. ACPICA commit f9eb60ead76e5b2b6e578b553f592452ccfca47a Link: https://github.com/acpica/acpica/commit/f9eb60ea Signed-off-by: Bob Moore Signed-off-by: Erik Schmauss Signed-off-by: Rafael J. Wysocki --- tools/power/acpi/tools/acpidump/apfiles.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c index a42cfcaa3293..16d919bd133b 100644 --- a/tools/power/acpi/tools/acpidump/apfiles.c +++ b/tools/power/acpi/tools/acpidump/apfiles.c @@ -29,18 +29,24 @@ static int ap_is_existing_file(char *pathname) { #if !defined(_GNU_EFI) && !defined(_EDK2_EFI) struct stat stat_info; + int in_char; if (!stat(pathname, &stat_info)) { fprintf(stderr, "Target path already exists, overwrite? [y|n] "); - if (getchar() != 'y') { + in_char = fgetc(stdin); + if (in_char == '\n') { + in_char = fgetc(stdin); + } + + if (in_char != 'y' && in_char != 'Y') { return (-1); } } #endif - return 0; + return (0); } /****************************************************************************** -- cgit v1.2.3-59-g8ed1b From 1446794a89c13816bd526dcbff4051cac9743db7 Mon Sep 17 00:00:00 2001 From: Todd Brandt Date: Mon, 12 Aug 2019 14:08:44 -0700 Subject: pm-graph v5.5 Upgrade bootgraph/sleepgraph to be able to run on python2 and python3. Both now simply require python, the system can choose which to use. bootgraph python3 update: - add floor function to handle integer arithmetic - change argument loop to use next() instead of args.next() - open dmesg log and popen in binary, use decode(ascii, ignore) - sort all html data to allow diff between python versions - change exception handler to use python3 as instead of comma sleepgraph python3 update: - import configparser not ConfigParser (p2 needs python-configparser) - add floor function to handle integer arithmetic - change argument loop to use next() instead of args.next() - handle popen output in binary, use decode(ascii, ignore) - sort all html/output data to allow diff between python versions - force gzip open to use text mode, same for file open - ensure no binary data is written to logs (ascii convert devprops info) - use codecs library to handle zlib encoding for mcelog data - remove all uses of python3.7 keyword "async" as members or vars - assume all FPDT and DMI data is in binary string form sleepgraph: - turbostat will be used by default if it's found & the mode is freeze - a new option "-noturbostat" will disable its use - fix bug where two callgraphs with the same start time overwrite. - fix s2idle processing where two suspend/resume_machines occur back2back - update getexec function to use which first (assuming PATH exists) - new platforminfo data in log with: lspci, gpe counts, /proc/interrupts - new data is zipped, b64 encoded, and tacked on the end of ftrace Signed-off-by: Todd Brandt Signed-off-by: Rafael J. Wysocki --- tools/power/pm-graph/README | 6 +- tools/power/pm-graph/bootgraph.py | 59 ++-- tools/power/pm-graph/sleepgraph.8 | 8 +- tools/power/pm-graph/sleepgraph.py | 610 ++++++++++++++++++++----------------- 4 files changed, 387 insertions(+), 296 deletions(-) (limited to 'tools') diff --git a/tools/power/pm-graph/README b/tools/power/pm-graph/README index 58a5591e3951..96259f6e5715 100644 --- a/tools/power/pm-graph/README +++ b/tools/power/pm-graph/README @@ -1,7 +1,7 @@ p m - g r a p h pm-graph: suspend/resume/boot timing analysis tools - Version: 5.4 + Version: 5.5 Author: Todd Brandt Home Page: https://01.org/pm-graph @@ -18,6 +18,10 @@ - upstream version in git: https://github.com/intel/pm-graph/ + Requirements: + - runs with python2 or python3, choice is made by /usr/bin/python link + - python2 now requires python-configparser be installed + Table of Contents - Overview - Setup diff --git a/tools/power/pm-graph/bootgraph.py b/tools/power/pm-graph/bootgraph.py index 666bcbda648d..d3b99a1e92d6 100755 --- a/tools/power/pm-graph/bootgraph.py +++ b/tools/power/pm-graph/bootgraph.py @@ -1,9 +1,18 @@ -#!/usr/bin/python2 +#!/usr/bin/python # SPDX-License-Identifier: GPL-2.0-only # # Tool for analyzing boot timing # Copyright (c) 2013, Intel Corporation. # +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# # Authors: # Todd Brandt # @@ -81,7 +90,7 @@ class SystemValues(aslib.SystemValues): cmdline = 'initcall_debug log_buf_len=32M' if self.useftrace: if self.cpucount > 0: - bs = min(self.memtotal / 2, 2*1024*1024) / self.cpucount + bs = min(self.memtotal // 2, 2*1024*1024) // self.cpucount else: bs = 131072 cmdline += ' trace_buf_size=%dK trace_clock=global '\ @@ -137,13 +146,13 @@ class SystemValues(aslib.SystemValues): if arg in ['-h', '-v', '-cronjob', '-reboot', '-verbose']: continue elif arg in ['-o', '-dmesg', '-ftrace', '-func']: - args.next() + next(args) continue elif arg == '-result': - cmdline += ' %s "%s"' % (arg, os.path.abspath(args.next())) + cmdline += ' %s "%s"' % (arg, os.path.abspath(next(args))) continue elif arg == '-cgskip': - file = self.configFile(args.next()) + file = self.configFile(next(args)) cmdline += ' %s "%s"' % (arg, os.path.abspath(file)) continue cmdline += ' '+arg @@ -292,11 +301,11 @@ def parseKernelLog(): tp = aslib.TestProps() devtemp = dict() if(sysvals.dmesgfile): - lf = open(sysvals.dmesgfile, 'r') + lf = open(sysvals.dmesgfile, 'rb') else: lf = Popen('dmesg', stdout=PIPE).stdout for line in lf: - line = line.replace('\r\n', '') + line = aslib.ascii(line).replace('\r\n', '') # grab the stamp and sysinfo if re.match(tp.stampfmt, line): tp.stamp = line @@ -649,7 +658,7 @@ def createBootGraph(data): statinfo += '\t"%s": [\n\t\t"%s",\n' % (n, devstats[n]['info']) if 'fstat' in devstats[n]: funcs = devstats[n]['fstat'] - for f in sorted(funcs, key=funcs.get, reverse=True): + for f in sorted(funcs, key=lambda k:(funcs[k], k), reverse=True): if funcs[f][0] < 0.01 and len(funcs) > 10: break statinfo += '\t\t"%f|%s|%d",\n' % (funcs[f][0], f, funcs[f][1]) @@ -729,7 +738,7 @@ def updateCron(restore=False): op.write('@reboot python %s\n' % sysvals.cronjobCmdString()) op.close() res = call([cmd, cronfile]) - except Exception, e: + except Exception as e: pprint('Exception: %s' % str(e)) shutil.move(backfile, cronfile) res = -1 @@ -745,7 +754,7 @@ def updateGrub(restore=False): try: call(sysvals.blexec, stderr=PIPE, stdout=PIPE, env={'PATH': '.:/sbin:/usr/sbin:/usr/bin:/sbin:/bin'}) - except Exception, e: + except Exception as e: pprint('Exception: %s\n' % str(e)) return # extract the option and create a grub config without it @@ -792,7 +801,7 @@ def updateGrub(restore=False): op.close() res = call(sysvals.blexec) os.remove(grubfile) - except Exception, e: + except Exception as e: pprint('Exception: %s' % str(e)) res = -1 # cleanup @@ -866,6 +875,7 @@ def printHelp(): 'Other commands:\n'\ ' -flistall Print all functions capable of being captured in ftrace\n'\ ' -sysinfo Print out system info extracted from BIOS\n'\ + ' -which exec Print an executable path, should function even without PATH\n'\ ' [redo]\n'\ ' -dmesg file Create HTML output using dmesg input (used with -ftrace)\n'\ ' -ftrace file Create HTML output using ftrace input (used with -dmesg)\n'\ @@ -907,13 +917,13 @@ if __name__ == '__main__': sysvals.mincglen = aslib.getArgFloat('-mincg', args, 0.0, 10000.0) elif(arg == '-cgfilter'): try: - val = args.next() + val = next(args) except: doError('No callgraph functions supplied', True) sysvals.setCallgraphFilter(val) elif(arg == '-cgskip'): try: - val = args.next() + val = next(args) except: doError('No file supplied', True) if val.lower() in switchoff: @@ -924,7 +934,7 @@ if __name__ == '__main__': doError('%s does not exist' % cgskip) elif(arg == '-bl'): try: - val = args.next() + val = next(args) except: doError('No boot loader name supplied', True) if val.lower() not in ['grub']: @@ -937,7 +947,7 @@ if __name__ == '__main__': sysvals.max_graph_depth = aslib.getArgInt('-maxdepth', args, 0, 1000) elif(arg == '-func'): try: - val = args.next() + val = next(args) except: doError('No filter functions supplied', True) sysvals.useftrace = True @@ -946,7 +956,7 @@ if __name__ == '__main__': sysvals.setGraphFilter(val) elif(arg == '-ftrace'): try: - val = args.next() + val = next(args) except: doError('No ftrace file supplied', True) if(os.path.exists(val) == False): @@ -959,7 +969,7 @@ if __name__ == '__main__': sysvals.cgexp = True elif(arg == '-dmesg'): try: - val = args.next() + val = next(args) except: doError('No dmesg file supplied', True) if(os.path.exists(val) == False): @@ -968,13 +978,13 @@ if __name__ == '__main__': sysvals.dmesgfile = val elif(arg == '-o'): try: - val = args.next() + val = next(args) except: doError('No subdirectory name supplied', True) sysvals.testdir = sysvals.setOutputFolder(val) elif(arg == '-result'): try: - val = args.next() + val = next(args) except: doError('No result file supplied', True) sysvals.result = val @@ -986,6 +996,17 @@ if __name__ == '__main__': # remaining options are only for cron job use elif(arg == '-cronjob'): sysvals.iscronjob = True + elif(arg == '-which'): + try: + val = next(args) + except: + doError('No executable supplied', True) + out = sysvals.getExec(val) + if not out: + print('%s not found' % val) + sys.exit(1) + print(out) + sys.exit(0) else: doError('Invalid argument: '+arg, True) diff --git a/tools/power/pm-graph/sleepgraph.8 b/tools/power/pm-graph/sleepgraph.8 index 9648be644d5f..43aee64316df 100644 --- a/tools/power/pm-graph/sleepgraph.8 +++ b/tools/power/pm-graph/sleepgraph.8 @@ -53,10 +53,10 @@ disable rtcwake and require a user keypress to resume. Add the dmesg and ftrace logs to the html output. They will be viewable by clicking buttons in the timeline. .TP -\fB-turbostat\fR -Use turbostat to execute the command in freeze mode (default: disabled). This -will provide turbostat output in the log which will tell you which actual -power modes were entered. +\fB-noturbostat\fR +By default, if turbostat is found and the requested mode is freeze, sleepgraph +will execute the suspend via turbostat and collect data in the timeline log. +This option disables the use of turbostat. .TP \fB-result \fIfile\fR Export a results table to a text file for parsing. diff --git a/tools/power/pm-graph/sleepgraph.py b/tools/power/pm-graph/sleepgraph.py index 4f46a7a1feb6..1794c79a7d1b 100755 --- a/tools/power/pm-graph/sleepgraph.py +++ b/tools/power/pm-graph/sleepgraph.py @@ -1,9 +1,18 @@ -#!/usr/bin/python2 +#!/usr/bin/python # SPDX-License-Identifier: GPL-2.0-only # # Tool for analyzing suspend/resume timing # Copyright (c) 2013, Intel Corporation. # +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# # Authors: # Todd Brandt # @@ -48,9 +57,10 @@ import string import re import platform import signal +import codecs from datetime import datetime import struct -import ConfigParser +import configparser import gzip from threading import Thread from subprocess import call, Popen, PIPE @@ -60,6 +70,9 @@ def pprint(msg): print(msg) sys.stdout.flush() +def ascii(text): + return text.decode('ascii', 'ignore') + # ----------------- CLASSES -------------------- # Class: SystemValues @@ -68,7 +81,7 @@ def pprint(msg): # store system values and test parameters class SystemValues: title = 'SleepGraph' - version = '5.4' + version = '5.5' ansi = False rs = 0 display = '' @@ -78,7 +91,7 @@ class SystemValues: testlog = True dmesglog = True ftracelog = False - tstat = False + tstat = True mindevlen = 0.0 mincglen = 0.0 cgphase = '' @@ -147,6 +160,7 @@ class SystemValues: devdump = False mixedphaseheight = True devprops = dict() + platinfo = [] predelay = 0 postdelay = 0 pmdebug = '' @@ -323,13 +337,20 @@ class SystemValues: sys.exit(1) return False def getExec(self, cmd): - dirlist = ['/sbin', '/bin', '/usr/sbin', '/usr/bin', - '/usr/local/sbin', '/usr/local/bin'] - for path in dirlist: + try: + fp = Popen(['which', cmd], stdout=PIPE, stderr=PIPE).stdout + out = ascii(fp.read()).strip() + fp.close() + except: + out = '' + if out: + return out + for path in ['/sbin', '/bin', '/usr/sbin', '/usr/bin', + '/usr/local/sbin', '/usr/local/bin']: cmdfull = os.path.join(path, cmd) if os.path.exists(cmdfull): return cmdfull - return '' + return out def setPrecision(self, num): if num < 0 or num > 6: return @@ -455,7 +476,7 @@ class SystemValues: fp = Popen('dmesg', stdout=PIPE).stdout ktime = '0' for line in fp: - line = line.replace('\r\n', '') + line = ascii(line).replace('\r\n', '') idx = line.find('[') if idx > 1: line = line[idx:] @@ -469,7 +490,7 @@ class SystemValues: # store all new dmesg lines since initdmesg was called fp = Popen('dmesg', stdout=PIPE).stdout for line in fp: - line = line.replace('\r\n', '') + line = ascii(line).replace('\r\n', '') idx = line.find('[') if idx > 1: line = line[idx:] @@ -501,7 +522,7 @@ class SystemValues: call('cat '+self.tpath+'available_filter_functions', shell=True) return master = self.listFromFile(self.tpath+'available_filter_functions') - for i in self.tracefuncs: + for i in sorted(self.tracefuncs): if 'func' in self.tracefuncs[i]: i = self.tracefuncs[i]['func'] if i in master: @@ -628,7 +649,7 @@ class SystemValues: self.fsetVal(kprobeevents, 'kprobe_events') if output: check = self.fgetVal('kprobe_events') - linesack = (len(check.split('\n')) - 1) / 2 + linesack = (len(check.split('\n')) - 1) // 2 pprint(' kprobe functions enabled: %d/%d' % (linesack, linesout)) self.fsetVal('1', 'events/kprobes/enable') def testKprobe(self, kname, kprobe): @@ -650,7 +671,7 @@ class SystemValues: if not os.path.exists(file): return False try: - fp = open(file, mode, 0) + fp = open(file, mode) fp.write(val) fp.flush() fp.close() @@ -719,7 +740,7 @@ class SystemValues: tgtsize = min(self.memfree, bmax) else: tgtsize = 65536 - while not self.fsetVal('%d' % (tgtsize / cpus), 'buffer_size_kb'): + while not self.fsetVal('%d' % (tgtsize // cpus), 'buffer_size_kb'): # if the size failed to set, lower it and keep trying tgtsize -= 65536 if tgtsize < 65536: @@ -863,14 +884,23 @@ class SystemValues: isgz = self.gzip if mode == 'r': try: - with gzip.open(filename, mode+'b') as fp: + with gzip.open(filename, mode+'t') as fp: test = fp.read(64) isgz = True except: isgz = False if isgz: - return gzip.open(filename, mode+'b') + return gzip.open(filename, mode+'t') return open(filename, mode) + def b64unzip(self, data): + try: + out = codecs.decode(base64.b64decode(data), 'zlib').decode() + except: + out = data + return out + def b64zip(self, data): + out = base64.b64encode(codecs.encode(data.encode(), 'zlib')).decode() + return out def mcelog(self, clear=False): cmd = self.getExec('mcelog') if not cmd: @@ -878,12 +908,124 @@ class SystemValues: if clear: call(cmd+' > /dev/null 2>&1', shell=True) return '' - fp = Popen([cmd], stdout=PIPE, stderr=PIPE).stdout - out = fp.read().strip() - fp.close() + try: + fp = Popen([cmd], stdout=PIPE, stderr=PIPE).stdout + out = ascii(fp.read()).strip() + fp.close() + except: + return '' if not out: return '' - return base64.b64encode(out.encode('zlib')) + return self.b64zip(out) + def platforminfo(self): + # add platform info on to a completed ftrace file + if not os.path.exists(self.ftracefile): + return False + footer = '#\n' + + # add test command string line if need be + if self.suspendmode == 'command' and self.testcommand: + footer += '# platform-testcmd: %s\n' % (self.testcommand) + + # get a list of target devices from the ftrace file + props = dict() + tp = TestProps() + tf = self.openlog(self.ftracefile, 'r') + for line in tf: + # determine the trace data type (required for further parsing) + m = re.match(tp.tracertypefmt, line) + if(m): + tp.setTracerType(m.group('t')) + continue + # parse only valid lines, if this is not one move on + m = re.match(tp.ftrace_line_fmt, line) + if(not m or 'device_pm_callback_start' not in line): + continue + m = re.match('.*: (?P.*) (?P.*), parent: *(?P

.*), .*', m.group('msg')); + if(not m): + continue + dev = m.group('d') + if dev not in props: + props[dev] = DevProps() + tf.close() + + # now get the syspath for each target device + for dirname, dirnames, filenames in os.walk('/sys/devices'): + if(re.match('.*/power', dirname) and 'async' in filenames): + dev = dirname.split('/')[-2] + if dev in props and (not props[dev].syspath or len(dirname) < len(props[dev].syspath)): + props[dev].syspath = dirname[:-6] + + # now fill in the properties for our target devices + for dev in sorted(props): + dirname = props[dev].syspath + if not dirname or not os.path.exists(dirname): + continue + with open(dirname+'/power/async') as fp: + text = fp.read() + props[dev].isasync = False + if 'enabled' in text: + props[dev].isasync = True + fields = os.listdir(dirname) + if 'product' in fields: + with open(dirname+'/product', 'rb') as fp: + props[dev].altname = ascii(fp.read()) + elif 'name' in fields: + with open(dirname+'/name', 'rb') as fp: + props[dev].altname = ascii(fp.read()) + elif 'model' in fields: + with open(dirname+'/model', 'rb') as fp: + props[dev].altname = ascii(fp.read()) + elif 'description' in fields: + with open(dirname+'/description', 'rb') as fp: + props[dev].altname = ascii(fp.read()) + elif 'id' in fields: + with open(dirname+'/id', 'rb') as fp: + props[dev].altname = ascii(fp.read()) + elif 'idVendor' in fields and 'idProduct' in fields: + idv, idp = '', '' + with open(dirname+'/idVendor', 'rb') as fp: + idv = ascii(fp.read()).strip() + with open(dirname+'/idProduct', 'rb') as fp: + idp = ascii(fp.read()).strip() + props[dev].altname = '%s:%s' % (idv, idp) + if props[dev].altname: + out = props[dev].altname.strip().replace('\n', ' ')\ + .replace(',', ' ').replace(';', ' ') + props[dev].altname = out + + # add a devinfo line to the bottom of ftrace + out = '' + for dev in sorted(props): + out += props[dev].out(dev) + footer += '# platform-devinfo: %s\n' % self.b64zip(out) + + # add a line for each of these commands with their outputs + cmds = [ + ['pcidevices', 'lspci', '-tv'], + ['interrupts', 'cat', '/proc/interrupts'], + ['gpecounts', 'sh', '-c', 'grep -v invalid /sys/firmware/acpi/interrupts/gpe*'], + ] + for cargs in cmds: + name = cargs[0] + cmdline = ' '.join(cargs[1:]) + cmdpath = self.getExec(cargs[1]) + if not cmdpath: + continue + cmd = [cmdpath] + cargs[2:] + try: + fp = Popen(cmd, stdout=PIPE, stderr=PIPE).stdout + info = ascii(fp.read()).strip() + fp.close() + except: + continue + if not info: + continue + footer += '# platform-%s: %s | %s\n' % (name, cmdline, self.b64zip(info)) + + with self.openlog(self.ftracefile, 'a') as fp: + fp.write(footer) + return True def haveTurbostat(self): if not self.tstat: return False @@ -891,31 +1033,40 @@ class SystemValues: if not cmd: return False fp = Popen([cmd, '-v'], stdout=PIPE, stderr=PIPE).stderr - out = fp.read().strip() + out = ascii(fp.read()).strip() fp.close() - return re.match('turbostat version [0-9\.]* .*', out) + if re.match('turbostat version [0-9\.]* .*', out): + sysvals.vprint(out) + return True + return False def turbostat(self): cmd = self.getExec('turbostat') - if not cmd: - return 'missing turbostat executable' - text = [] + rawout = keyline = valline = '' fullcmd = '%s -q -S echo freeze > %s' % (cmd, self.powerfile) fp = Popen(['sh', '-c', fullcmd], stdout=PIPE, stderr=PIPE).stderr for line in fp: - if re.match('[0-9.]* sec', line): + line = ascii(line) + rawout += line + if keyline and valline: continue - text.append(line.split()) + if re.match('(?i)Avg_MHz.*', line): + keyline = line.strip().split() + elif keyline: + valline = line.strip().split() fp.close() - if len(text) < 2: - return 'turbostat output format error' + if not keyline or not valline or len(keyline) != len(valline): + errmsg = 'unrecognized turbostat output:\n'+rawout.strip() + sysvals.vprint(errmsg) + if not sysvals.verbose: + pprint(errmsg) + return '' + if sysvals.verbose: + pprint(rawout.strip()) out = [] - for key in text[0]: - values = [] - idx = text[0].index(key) - for line in text[1:]: - if len(line) > idx: - values.append(line[idx]) - out.append('%s=%s' % (key, ','.join(values))) + for key in keyline: + idx = keyline.index(key) + val = valline[idx] + out.append('%s=%s' % (key, val)) return '|'.join(out) def checkWifi(self): out = dict() @@ -924,7 +1075,7 @@ class SystemValues: return out fp = Popen(iwcmd, stdout=PIPE, stderr=PIPE).stdout for line in fp: - m = re.match('(?P\S*) .* ESSID:(?P\S*)', line) + m = re.match('(?P\S*) .* ESSID:(?P\S*)', ascii(line)) if not m: continue out['device'] = m.group('dev') @@ -935,7 +1086,7 @@ class SystemValues: if 'device' in out: fp = Popen([ifcmd, out['device']], stdout=PIPE, stderr=PIPE).stdout for line in fp: - m = re.match('.* inet (?P[0-9\.]*)', line) + m = re.match('.* inet (?P[0-9\.]*)', ascii(line)) if m: out['ip'] = m.group('ip') break @@ -990,13 +1141,13 @@ class DevProps: def __init__(self): self.syspath = '' self.altname = '' - self.async = True + self.isasync = True self.xtraclass = '' self.xtrainfo = '' def out(self, dev): - return '%s,%s,%d;' % (dev, self.altname, self.async) + return '%s,%s,%d;' % (dev, self.altname, self.isasync) def debug(self, dev): - pprint('%s:\n\taltname = %s\n\t async = %s' % (dev, self.altname, self.async)) + pprint('%s:\n\taltname = %s\n\t async = %s' % (dev, self.altname, self.isasync)) def altName(self, dev): if not self.altname or self.altname == dev: return dev @@ -1004,13 +1155,13 @@ class DevProps: def xtraClass(self): if self.xtraclass: return ' '+self.xtraclass - if not self.async: + if not self.isasync: return ' sync' return '' def xtraInfo(self): if self.xtraclass: return ' '+self.xtraclass - if self.async: + if self.isasync: return ' async_device' return ' sync_device' @@ -1108,7 +1259,7 @@ class Data: return sorted(self.dmesg, key=lambda k:self.dmesg[k]['order']) def initDevicegroups(self): # called when phases are all finished being added - for phase in self.dmesg.keys(): + for phase in sorted(self.dmesg.keys()): if '*' in phase: p = phase.split('*') pnew = '%s%d' % (p[0], len(p)) @@ -1430,16 +1581,7 @@ class Data: return phase def sortedDevices(self, phase): list = self.dmesg[phase]['list'] - slist = [] - tmp = dict() - for devname in list: - dev = list[devname] - if dev['length'] == 0: - continue - tmp[dev['start']] = devname - for t in sorted(tmp): - slist.append(tmp[t]) - return slist + return sorted(list, key=lambda k:list[k]['start']) def fixupInitcalls(self, phase): # if any calls never returned, clip them at system resume end phaselist = self.dmesg[phase]['list'] @@ -1576,7 +1718,7 @@ class Data: maxname = '%d' % self.maxDeviceNameSize(phase) fmt = '%3d) %'+maxname+'s - %f - %f' c = 1 - for name in devlist: + for name in sorted(devlist): s = devlist[name]['start'] e = devlist[name]['end'] sysvals.vprint(fmt % (c, name, s, e)) @@ -1588,7 +1730,7 @@ class Data: devlist = [] for phase in self.sortedPhases(): list = self.deviceChildren(devname, phase) - for dev in list: + for dev in sorted(list): if dev not in devlist: devlist.append(dev) return devlist @@ -1628,16 +1770,16 @@ class Data: def rootDeviceList(self): # list of devices graphed real = [] - for phase in self.dmesg: + for phase in self.sortedPhases(): list = self.dmesg[phase]['list'] - for dev in list: + for dev in sorted(list): if list[dev]['pid'] >= 0 and dev not in real: real.append(dev) # list of top-most root devices rootlist = [] - for phase in self.dmesg: + for phase in self.sortedPhases(): list = self.dmesg[phase]['list'] - for dev in list: + for dev in sorted(list): pdev = list[dev]['par'] pid = list[dev]['pid'] if(pid < 0 or re.match('[0-9]*-[0-9]*\.[0-9]*[\.0-9]*\:[\.0-9]*$', pdev)): @@ -1718,9 +1860,9 @@ class Data: def createProcessUsageEvents(self): # get an array of process names proclist = [] - for t in self.pstl: + for t in sorted(self.pstl): pslist = self.pstl[t] - for ps in pslist: + for ps in sorted(pslist): if ps not in proclist: proclist.append(ps) # get a list of data points for suspend and resume @@ -1765,7 +1907,7 @@ class Data: def debugPrint(self): for p in self.sortedPhases(): list = self.dmesg[p]['list'] - for devname in list: + for devname in sorted(list): dev = list[devname] if 'ftrace' in dev: dev['ftrace'].debugPrint(' [%s]' % devname) @@ -2466,7 +2608,7 @@ class Timeline: # if there is 1 line per row, draw them the standard way for t, p in standardphases: for i in sorted(self.rowheight[t][p]): - self.rowheight[t][p][i] = self.bodyH/len(self.rowlines[t][p]) + self.rowheight[t][p][i] = float(self.bodyH)/len(self.rowlines[t][p]) def createZoomBox(self, mode='command', testcount=1): # Create bounding box, add buttons html_zoombox = '

\n' @@ -2537,6 +2679,7 @@ class TestProps: cmdlinefmt = '^# command \| (?P.*)' kparamsfmt = '^# kparams \| (?P.*)' devpropfmt = '# Device Properties: .*' + pinfofmt = '# platform-(?P[a-z,A-Z,0-9]*): (?P.*)' tracertypefmt = '# tracer: (?P.*)' firmwarefmt = '# fwsuspend (?P[0-9]*) fwresume (?P[0-9]*)$' procexecfmt = 'ps - (?P.*)$' @@ -2571,12 +2714,6 @@ class TestProps: self.ftrace_line_fmt = self.ftrace_line_fmt_nop else: doError('Invalid tracer format: [%s]' % tracer) - def decode(self, data): - try: - out = base64.b64decode(data).decode('zlib') - except: - out = data - return out def stampInfo(self, line): if re.match(self.stampfmt, line): self.stamp = line @@ -2660,7 +2797,7 @@ class TestProps: if len(self.mcelog) > data.testnumber: m = re.match(self.mcelogfmt, self.mcelog[data.testnumber]) if m: - data.mcelog = self.decode(m.group('m')) + data.mcelog = sv.b64unzip(m.group('m')) # turbostat data if len(self.turbostat) > data.testnumber: m = re.match(self.tstatfmt, self.turbostat[data.testnumber]) @@ -2681,6 +2818,46 @@ class TestProps: m = re.match(self.testerrfmt, self.testerror[data.testnumber]) if m: data.enterfail = m.group('e') + def devprops(self, data): + props = dict() + devlist = data.split(';') + for dev in devlist: + f = dev.split(',') + if len(f) < 3: + continue + dev = f[0] + props[dev] = DevProps() + props[dev].altname = f[1] + if int(f[2]): + props[dev].isasync = True + else: + props[dev].isasync = False + return props + def parseDevprops(self, line, sv): + idx = line.index(': ') + 2 + if idx >= len(line): + return + props = self.devprops(line[idx:]) + if sv.suspendmode == 'command' and 'testcommandstring' in props: + sv.testcommand = props['testcommandstring'].altname + sv.devprops = props + def parsePlatformInfo(self, line, sv): + m = re.match(self.pinfofmt, line) + if not m: + return + name, info = m.group('val'), m.group('info') + if name == 'devinfo': + sv.devprops = self.devprops(sv.b64unzip(info)) + return + elif name == 'testcmd': + sv.testcommand = info + return + field = info.split('|') + if len(field) < 2: + return + cmdline = field[0].strip() + output = sv.b64unzip(field[1].strip()) + sv.platinfo.append([name, cmdline, output]) # Class: TestRun # Description: @@ -2701,7 +2878,7 @@ class ProcessMonitor: process = Popen(c, shell=True, stdout=PIPE) running = dict() for line in process.stdout: - data = line.split() + data = ascii(line).split() pid = data[0] name = re.sub('[()]', '', data[1]) user = int(data[13]) @@ -2805,7 +2982,11 @@ def appendIncompleteTraceLog(testruns): continue # device properties line if(re.match(tp.devpropfmt, line)): - devProps(line) + tp.parseDevprops(line, sysvals) + continue + # platform info line + if(re.match(tp.pinfofmt, line)): + tp.parsePlatformInfo(line, sysvals) continue # parse only valid lines, if this is not one move on m = re.match(tp.ftrace_line_fmt, line) @@ -2902,7 +3083,7 @@ def parseTraceLog(live=False): sysvals.setupAllKprobes() ksuscalls = ['pm_prepare_console'] krescalls = ['pm_restore_console'] - tracewatch = [] + tracewatch = ['irq_wakeup'] if sysvals.usekprobes: tracewatch += ['sync_filesystems', 'freeze_processes', 'syscore_suspend', 'syscore_resume', 'resume_console', 'thaw_processes', 'CPU_ON', @@ -2928,7 +3109,11 @@ def parseTraceLog(live=False): continue # device properties line if(re.match(tp.devpropfmt, line)): - devProps(line) + tp.parseDevprops(line, sysvals) + continue + # platform info line + if(re.match(tp.pinfofmt, line)): + tp.parsePlatformInfo(line, sysvals) continue # ignore all other commented lines if line[0] == '#': @@ -3001,16 +3186,11 @@ def parseTraceLog(live=False): isbegin = False else: continue - m = re.match('(?P.*)\[(?P[0-9]*)\] .*', t.name) - if(m): - val = m.group('val') - if val == '0': - name = m.group('name') - else: - name = m.group('name')+'['+val+']' + if '[' in t.name: + m = re.match('(?P.*)\[.*', t.name) else: m = re.match('(?P.*) .*', t.name) - name = m.group('name') + name = m.group('name') # ignore these events if(name.split('[')[0] in tracewatch): continue @@ -3045,6 +3225,8 @@ def parseTraceLog(live=False): elif(re.match('machine_suspend\[.*', t.name)): if(isbegin): lp = data.lastPhase() + if lp == 'resume_machine': + data.dmesg[lp]['end'] = t.time phase = data.setPhase('suspend_machine', data.dmesg[lp]['end'], True) data.setPhase(phase, t.time, False) if data.tSuspended == 0: @@ -3213,11 +3395,11 @@ def parseTraceLog(live=False): # add the traceevent data to the device hierarchy if(sysvals.usetraceevents): # add actual trace funcs - for name in test.ttemp: + for name in sorted(test.ttemp): for event in test.ttemp[name]: data.newActionGlobal(name, event['begin'], event['end'], event['pid']) # add the kprobe based virtual tracefuncs as actual devices - for key in tp.ktemp: + for key in sorted(tp.ktemp): name, pid = key if name not in sysvals.tracefuncs: continue @@ -3231,7 +3413,7 @@ def parseTraceLog(live=False): data.newActionGlobal(e['name'], kb, ke, pid, color) # add config base kprobes and dev kprobes if sysvals.usedevsrc: - for key in tp.ktemp: + for key in sorted(tp.ktemp): name, pid = key if name in sysvals.tracefuncs or name not in sysvals.dev_tracefuncs: continue @@ -3244,7 +3426,7 @@ def parseTraceLog(live=False): if sysvals.usecallgraph: # add the callgraph data to the device hierarchy sortlist = dict() - for key in test.ftemp: + for key in sorted(test.ftemp): proc, pid = key for cg in test.ftemp[key]: if len(cg.list) < 1 or cg.invalid or (cg.end - cg.start == 0): @@ -3582,7 +3764,7 @@ def parseKernelLog(data): # if trace events are not available, these are better than nothing if(not sysvals.usetraceevents): # look for known actions - for a in at: + for a in sorted(at): if(re.match(at[a]['smsg'], msg)): if(a not in actions): actions[a] = [] @@ -3641,7 +3823,7 @@ def parseKernelLog(data): data.tResumed = data.tSuspended # fill in any actions we've found - for name in actions: + for name in sorted(actions): for event in actions[name]: data.newActionGlobal(name, event['begin'], event['end']) @@ -3761,7 +3943,7 @@ def createHTMLSummarySimple(testruns, htmlfile, title): if lastmode and lastmode != mode and num > 0: for i in range(2): s = sorted(tMed[i]) - list[lastmode]['med'][i] = s[int(len(s)/2)] + list[lastmode]['med'][i] = s[int(len(s)//2)] iMed[i] = tMed[i][list[lastmode]['med'][i]] list[lastmode]['avg'] = [tAvg[0] / num, tAvg[1] / num] list[lastmode]['min'] = tMin @@ -3803,7 +3985,7 @@ def createHTMLSummarySimple(testruns, htmlfile, title): if lastmode and num > 0: for i in range(2): s = sorted(tMed[i]) - list[lastmode]['med'][i] = s[int(len(s)/2)] + list[lastmode]['med'][i] = s[int(len(s)//2)] iMed[i] = tMed[i][list[lastmode]['med'][i]] list[lastmode]['avg'] = [tAvg[0] / num, tAvg[1] / num] list[lastmode]['min'] = tMin @@ -3845,7 +4027,7 @@ def createHTMLSummarySimple(testruns, htmlfile, title): '\n' headnone = '{0}{1}\n' - for mode in list: + for mode in sorted(list): # header line for each suspend mode num = 0 tAvg, tMin, tMax, tMed = list[mode]['avg'], list[mode]['min'],\ @@ -3944,7 +4126,8 @@ def createHTMLDeviceSummary(testruns, htmlfile, title): th.format('Average Time') + th.format('Count') +\ th.format('Worst Time') + th.format('Host (worst time)') +\ th.format('Link (worst time)') + '\n' - for name in sorted(devlist, key=lambda k:devlist[k]['worst'], reverse=True): + for name in sorted(devlist, key=lambda k:(devlist[k]['worst'], \ + devlist[k]['total'], devlist[k]['name']), reverse=True): data = devall[type][name] data['average'] = data['total'] / data['count'] if data['average'] < limit: @@ -4085,7 +4268,7 @@ def createHTML(testruns, testfail): if(tTotal == 0): doError('No timeline data') if(len(data.tLow) > 0): - low_time = '|'.join(data.tLow) + low_time = '+'.join(data.tLow) if sysvals.suspendmode == 'command': run_time = '%.0f'%((data.end-data.start)*1000) if sysvals.testcommand: @@ -4151,7 +4334,7 @@ def createHTML(testruns, testfail): for group in data.devicegroups: devlist = [] for phase in group: - for devname in data.tdevlist[phase]: + for devname in sorted(data.tdevlist[phase]): d = DevItem(data.testnumber, phase, data.dmesg[phase]['list'][devname]) devlist.append(d) if d.isa('kth'): @@ -4230,7 +4413,7 @@ def createHTML(testruns, testfail): for b in phases[dir]: # draw the devices for this phase phaselist = data.dmesg[b]['list'] - for d in data.tdevlist[b]: + for d in sorted(data.tdevlist[b]): name = d drv = '' dev = phaselist[d] @@ -4971,13 +5154,9 @@ def executeSuspend(): if mode == 'freeze' and sysvals.haveTurbostat(): # execution will pause here turbo = sysvals.turbostat() - if '|' in turbo: + if turbo: tdata['turbo'] = turbo - else: - tdata['error'] = turbo else: - if sysvals.haveTurbostat(): - sysvals.vprint('WARNING: ignoring turbostat in mode "%s"' % mode) pf = open(sysvals.powerfile, 'w') pf.write(mode) # execution will pause here @@ -5024,7 +5203,7 @@ def executeSuspend(): op.write(line) op.close() sysvals.fsetVal('', 'trace') - devProps() + sysvals.platforminfo() return testdata def readFile(file): @@ -5040,9 +5219,9 @@ def readFile(file): # The time string, e.g. "1901m16s" def ms2nice(val): val = int(val) - h = val / 3600000 - m = (val / 60000) % 60 - s = (val / 1000) % 60 + h = val // 3600000 + m = (val // 60000) % 60 + s = (val // 1000) % 60 if h > 0: return '%d:%02d:%02d' % (h, m, s) if m > 0: @@ -5115,127 +5294,6 @@ def deviceInfo(output=''): print(lines[i]) return res -# Function: devProps -# Description: -# Retrieve a list of properties for all devices in the trace log -def devProps(data=0): - props = dict() - - if data: - idx = data.index(': ') + 2 - if idx >= len(data): - return - devlist = data[idx:].split(';') - for dev in devlist: - f = dev.split(',') - if len(f) < 3: - continue - dev = f[0] - props[dev] = DevProps() - props[dev].altname = f[1] - if int(f[2]): - props[dev].async = True - else: - props[dev].async = False - sysvals.devprops = props - if sysvals.suspendmode == 'command' and 'testcommandstring' in props: - sysvals.testcommand = props['testcommandstring'].altname - return - - if(os.path.exists(sysvals.ftracefile) == False): - doError('%s does not exist' % sysvals.ftracefile) - - # first get the list of devices we need properties for - msghead = 'Additional data added by AnalyzeSuspend' - alreadystamped = False - tp = TestProps() - tf = sysvals.openlog(sysvals.ftracefile, 'r') - for line in tf: - if msghead in line: - alreadystamped = True - continue - # determine the trace data type (required for further parsing) - m = re.match(tp.tracertypefmt, line) - if(m): - tp.setTracerType(m.group('t')) - continue - # parse only valid lines, if this is not one move on - m = re.match(tp.ftrace_line_fmt, line) - if(not m or 'device_pm_callback_start' not in line): - continue - m = re.match('.*: (?P.*) (?P.*), parent: *(?P

.*), .*', m.group('msg')); - if(not m): - continue - dev = m.group('d') - if dev not in props: - props[dev] = DevProps() - tf.close() - - if not alreadystamped and sysvals.suspendmode == 'command': - out = '#\n# '+msghead+'\n# Device Properties: ' - out += 'testcommandstring,%s,0;' % (sysvals.testcommand) - with sysvals.openlog(sysvals.ftracefile, 'a') as fp: - fp.write(out+'\n') - sysvals.devprops = props - return - - # now get the syspath for each of our target devices - for dirname, dirnames, filenames in os.walk('/sys/devices'): - if(re.match('.*/power', dirname) and 'async' in filenames): - dev = dirname.split('/')[-2] - if dev in props and (not props[dev].syspath or len(dirname) < len(props[dev].syspath)): - props[dev].syspath = dirname[:-6] - - # now fill in the properties for our target devices - for dev in props: - dirname = props[dev].syspath - if not dirname or not os.path.exists(dirname): - continue - with open(dirname+'/power/async') as fp: - text = fp.read() - props[dev].async = False - if 'enabled' in text: - props[dev].async = True - fields = os.listdir(dirname) - if 'product' in fields: - with open(dirname+'/product') as fp: - props[dev].altname = fp.read() - elif 'name' in fields: - with open(dirname+'/name') as fp: - props[dev].altname = fp.read() - elif 'model' in fields: - with open(dirname+'/model') as fp: - props[dev].altname = fp.read() - elif 'description' in fields: - with open(dirname+'/description') as fp: - props[dev].altname = fp.read() - elif 'id' in fields: - with open(dirname+'/id') as fp: - props[dev].altname = fp.read() - elif 'idVendor' in fields and 'idProduct' in fields: - idv, idp = '', '' - with open(dirname+'/idVendor') as fp: - idv = fp.read().strip() - with open(dirname+'/idProduct') as fp: - idp = fp.read().strip() - props[dev].altname = '%s:%s' % (idv, idp) - - if props[dev].altname: - out = props[dev].altname.strip().replace('\n', ' ') - out = out.replace(',', ' ') - out = out.replace(';', ' ') - props[dev].altname = out - - # and now write the data to the ftrace file - if not alreadystamped: - out = '#\n# '+msghead+'\n# Device Properties: ' - for dev in sorted(props): - out += props[dev].out(dev) - with sysvals.openlog(sysvals.ftracefile, 'a') as fp: - fp.write(out+'\n') - - sysvals.devprops = props - # Function: getModes # Description: # Determine the supported power modes on this system @@ -5339,11 +5397,11 @@ def dmidecode(mempath, fatal=False): # search for either an SM table or DMI table i = base = length = num = 0 while(i < memsize): - if buf[i:i+4] == '_SM_' and i < memsize - 16: + if buf[i:i+4] == b'_SM_' and i < memsize - 16: length = struct.unpack('H', buf[i+22:i+24])[0] base, num = struct.unpack('IH', buf[i+24:i+30]) break - elif buf[i:i+5] == '_DMI_': + elif buf[i:i+5] == b'_DMI_': length = struct.unpack('H', buf[i+6:i+8])[0] base, num = struct.unpack('IH', buf[i+8:i+14]) break @@ -5376,15 +5434,15 @@ def dmidecode(mempath, fatal=False): if 0 == struct.unpack('H', buf[n:n+2])[0]: break n += 1 - data = buf[i+size:n+2].split('\0') + data = buf[i+size:n+2].split(b'\0') for name in info: itype, idxadr = info[name] if itype == type: - idx = struct.unpack('B', buf[i+idxadr])[0] + idx = struct.unpack('B', buf[i+idxadr:i+idxadr+1])[0] if idx > 0 and idx < len(data) - 1: - s = data[idx-1].strip() - if s and s.lower() != 'to be filled by o.e.m.': - out[name] = data[idx-1] + s = data[idx-1].decode('utf-8') + if s.strip() and s.strip().lower() != 'to be filled by o.e.m.': + out[name] = s i = n + 2 count += 1 return out @@ -5409,7 +5467,7 @@ def getBattery(): return (ac, charge) def displayControl(cmd): - xset, ret = 'xset -d :0.0 {0}', 0 + xset, ret = 'timeout 10 xset -d :0.0 {0}', 0 if sysvals.sudouser: xset = 'sudo -u %s %s' % (sysvals.sudouser, xset) if cmd == 'init': @@ -5433,7 +5491,7 @@ def displayControl(cmd): fp = Popen(xset.format('q').split(' '), stdout=PIPE).stdout ret = 'unknown' for line in fp: - m = re.match('[\s]*Monitor is (?P.*)', line) + m = re.match('[\s]*Monitor is (?P.*)', ascii(line)) if(m and len(m.group('m')) >= 2): out = m.group('m').lower() ret = out[3:] if out[0:2] == 'in' else out @@ -5495,10 +5553,11 @@ def getFPDT(output): ' OEM Revision : %u\n'\ ' Creator ID : %s\n'\ ' Creator Revision : 0x%x\n'\ - '' % (table[0], table[0], table[1], table[2], table[3], - table[4], table[5], table[6], table[7], table[8])) + '' % (ascii(table[0]), ascii(table[0]), table[1], table[2], + table[3], ascii(table[4]), ascii(table[5]), table[6], + ascii(table[7]), table[8])) - if(table[0] != 'FPDT'): + if(table[0] != b'FPDT'): if(output): doError('Invalid FPDT table') return False @@ -5530,8 +5589,8 @@ def getFPDT(output): return [0, 0] rechead = struct.unpack('4sI', first) recdata = fp.read(rechead[1]-8) - if(rechead[0] == 'FBPT'): - record = struct.unpack('HBBIQQQQQ', recdata) + if(rechead[0] == b'FBPT'): + record = struct.unpack('HBBIQQQQQ', recdata[:48]) if(output): pprint('%s (%s)\n'\ ' Reset END : %u ns\n'\ @@ -5539,11 +5598,11 @@ def getFPDT(output): ' OS Loader StartImage Start : %u ns\n'\ ' ExitBootServices Entry : %u ns\n'\ ' ExitBootServices Exit : %u ns'\ - '' % (rectype[header[0]], rechead[0], record[4], record[5], + '' % (rectype[header[0]], ascii(rechead[0]), record[4], record[5], record[6], record[7], record[8])) - elif(rechead[0] == 'S3PT'): + elif(rechead[0] == b'S3PT'): if(output): - pprint('%s (%s)' % (rectype[header[0]], rechead[0])) + pprint('%s (%s)' % (rectype[header[0]], ascii(rechead[0]))) j = 0 while(j < len(recdata)): prechead = struct.unpack('HBB', recdata[j:j+4]) @@ -5689,7 +5748,7 @@ def doError(msg, help=False): def getArgInt(name, args, min, max, main=True): if main: try: - arg = args.next() + arg = next(args) except: doError(name+': no argument supplied', True) else: @@ -5708,7 +5767,7 @@ def getArgInt(name, args, min, max, main=True): def getArgFloat(name, args, min, max, main=True): if main: try: - arg = args.next() + arg = next(args) except: doError(name+': no argument supplied', True) else: @@ -5737,9 +5796,12 @@ def processData(live=False): parseKernelLog(data) if(sysvals.ftracefile and (sysvals.usecallgraph or sysvals.usetraceevents)): appendIncompleteTraceLog(testruns) + shown = ['bios', 'biosdate', 'cpu', 'host', 'kernel', 'man', 'memfr', + 'memsz', 'mode', 'numcpu', 'plat', 'time'] sysvals.vprint('System Info:') for key in sorted(sysvals.stamp): - sysvals.vprint(' %-8s : %s' % (key.upper(), sysvals.stamp[key])) + if key in shown: + sysvals.vprint(' %-8s : %s' % (key.upper(), sysvals.stamp[key])) if sysvals.kparams: sysvals.vprint('Kparams:\n %s' % sysvals.kparams) sysvals.vprint('Command:\n %s' % sysvals.cmdline) @@ -5768,6 +5830,12 @@ def processData(live=False): (w[0], w[1]) sysvals.vprint(s) data.printDetails() + if len(sysvals.platinfo) > 0: + sysvals.vprint('\nPlatform Info:') + for info in sysvals.platinfo: + sysvals.vprint(info[0]+' - '+info[1]) + sysvals.vprint(info[2]) + sysvals.vprint('') if sysvals.cgdump: for data in testruns: data.debugPrint() @@ -5951,7 +6019,7 @@ def data_from_html(file, outpath, issues, fulldetail=False): worst[d] = {'name':'', 'time': 0.0} dev = devices[d] if d in devices else 0 if dev and len(dev.keys()) > 0: - n = sorted(dev, key=dev.get, reverse=True)[0] + n = sorted(dev, key=lambda k:(dev[k], k), reverse=True)[0] worst[d]['name'], worst[d]['time'] = n, dev[n] data = { 'mode': stmp[2], @@ -5976,7 +6044,7 @@ def data_from_html(file, outpath, issues, fulldetail=False): data['funclist'] = find_in_html(html, '

Date: Tue, 20 Aug 2019 17:35:52 +0200 Subject: selftests: kvm: fix state save/load on processors without XSAVE state_test and smm_test are failing on older processors that do not have xcr0. This is because on those processor KVM does provide support for KVM_GET/SET_XSAVE (to avoid having to rely on the older KVM_GET/SET_FPU) but not for KVM_GET/SET_XCRS. Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/lib/x86_64/processor.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c index 6cb34a0fa200..0a5e487dbc50 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c @@ -1060,9 +1060,11 @@ struct kvm_x86_state *vcpu_save_state(struct kvm_vm *vm, uint32_t vcpuid) TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_XSAVE, r: %i", r); - r = ioctl(vcpu->fd, KVM_GET_XCRS, &state->xcrs); - TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_XCRS, r: %i", - r); + if (kvm_check_cap(KVM_CAP_XCRS)) { + r = ioctl(vcpu->fd, KVM_GET_XCRS, &state->xcrs); + TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_XCRS, r: %i", + r); + } r = ioctl(vcpu->fd, KVM_GET_SREGS, &state->sregs); TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_SREGS, r: %i", @@ -1103,9 +1105,11 @@ void vcpu_load_state(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_x86_state *s TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_XSAVE, r: %i", r); - r = ioctl(vcpu->fd, KVM_SET_XCRS, &state->xcrs); - TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_XCRS, r: %i", - r); + if (kvm_check_cap(KVM_CAP_XCRS)) { + r = ioctl(vcpu->fd, KVM_SET_XCRS, &state->xcrs); + TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_XCRS, r: %i", + r); + } r = ioctl(vcpu->fd, KVM_SET_SREGS, &state->sregs); TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_SREGS, r: %i", -- cgit v1.2.3-59-g8ed1b From 71dd77fd4bf7d1675a95dfe04a99669ce15b58f8 Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Thu, 15 Aug 2019 15:13:54 +0300 Subject: libbpf: use LFS (_FILE_OFFSET_BITS) instead of direct mmap2 syscall Drop __NR_mmap2 fork in flavor of LFS, that is _FILE_OFFSET_BITS=64 (glibc & bionic) / LARGEFILE64_SOURCE (for musl) decision. It allows mmap() to use 64bit offset that is passed to mmap2 syscall. As result pgoff is not truncated and no need to use direct access to mmap2 for 32 bits systems. Signed-off-by: Ivan Khoronzhuk Acked-by: Yonghong Song Signed-off-by: Daniel Borkmann --- tools/lib/bpf/Makefile | 1 + tools/lib/bpf/xsk.c | 49 ++++++++++++++----------------------------------- 2 files changed, 15 insertions(+), 35 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index 148a27164189..613acb93b144 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile @@ -108,6 +108,7 @@ override CFLAGS += -Werror -Wall override CFLAGS += -fPIC override CFLAGS += $(INCLUDES) override CFLAGS += -fvisibility=hidden +override CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 ifeq ($(VERBOSE),1) Q = diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c index 17e8d79c11a8..12ad78510147 100644 --- a/tools/lib/bpf/xsk.c +++ b/tools/lib/bpf/xsk.c @@ -74,23 +74,6 @@ struct xsk_nl_info { int fd; }; -/* For 32-bit systems, we need to use mmap2 as the offsets are 64-bit. - * Unfortunately, it is not part of glibc. - */ -static inline void *xsk_mmap(void *addr, size_t length, int prot, int flags, - int fd, __u64 offset) -{ -#ifdef __NR_mmap2 - unsigned int page_shift = __builtin_ffs(getpagesize()) - 1; - long ret = syscall(__NR_mmap2, addr, length, prot, flags, fd, - (off_t)(offset >> page_shift)); - - return (void *)ret; -#else - return mmap(addr, length, prot, flags, fd, offset); -#endif -} - int xsk_umem__fd(const struct xsk_umem *umem) { return umem ? umem->fd : -EINVAL; @@ -210,10 +193,9 @@ int xsk_umem__create(struct xsk_umem **umem_ptr, void *umem_area, __u64 size, goto out_socket; } - map = xsk_mmap(NULL, off.fr.desc + - umem->config.fill_size * sizeof(__u64), - PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, - umem->fd, XDP_UMEM_PGOFF_FILL_RING); + map = mmap(NULL, off.fr.desc + umem->config.fill_size * sizeof(__u64), + PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, umem->fd, + XDP_UMEM_PGOFF_FILL_RING); if (map == MAP_FAILED) { err = -errno; goto out_socket; @@ -228,10 +210,9 @@ int xsk_umem__create(struct xsk_umem **umem_ptr, void *umem_area, __u64 size, fill->ring = map + off.fr.desc; fill->cached_cons = umem->config.fill_size; - map = xsk_mmap(NULL, - off.cr.desc + umem->config.comp_size * sizeof(__u64), - PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, - umem->fd, XDP_UMEM_PGOFF_COMPLETION_RING); + map = mmap(NULL, off.cr.desc + umem->config.comp_size * sizeof(__u64), + PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, umem->fd, + XDP_UMEM_PGOFF_COMPLETION_RING); if (map == MAP_FAILED) { err = -errno; goto out_mmap; @@ -552,11 +533,10 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname, } if (rx) { - rx_map = xsk_mmap(NULL, off.rx.desc + - xsk->config.rx_size * sizeof(struct xdp_desc), - PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_POPULATE, - xsk->fd, XDP_PGOFF_RX_RING); + rx_map = mmap(NULL, off.rx.desc + + xsk->config.rx_size * sizeof(struct xdp_desc), + PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, + xsk->fd, XDP_PGOFF_RX_RING); if (rx_map == MAP_FAILED) { err = -errno; goto out_socket; @@ -572,11 +552,10 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname, xsk->rx = rx; if (tx) { - tx_map = xsk_mmap(NULL, off.tx.desc + - xsk->config.tx_size * sizeof(struct xdp_desc), - PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_POPULATE, - xsk->fd, XDP_PGOFF_TX_RING); + tx_map = mmap(NULL, off.tx.desc + + xsk->config.tx_size * sizeof(struct xdp_desc), + PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, + xsk->fd, XDP_PGOFF_TX_RING); if (tx_map == MAP_FAILED) { err = -errno; goto out_mmap_rx; -- cgit v1.2.3-59-g8ed1b From 806ce6e2117a42528e7bb979e04e28229b34a612 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Tue, 20 Aug 2019 16:18:04 +0200 Subject: selftests/bpf: fix test_cgroup_storage on s390 test_cgroup_storage fails on s390 with an assertion failure: packets are dropped when they shouldn't. The problem is that BPF_DW packet count is accessed as BPF_W with an offset of 0, which is not correct on big-endian machines. Since the point of this test is not to verify narrow loads/stores, simply use BPF_DW when working with packet counts. Fixes: 68cfa3ac6b8d ("selftests/bpf: add a cgroup storage test") Fixes: 919646d2a3a9 ("selftests/bpf: extend the storage test to test per-cpu cgroup storage") Signed-off-by: Ilya Leoshkevich Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/test_cgroup_storage.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_cgroup_storage.c b/tools/testing/selftests/bpf/test_cgroup_storage.c index 2fc4625c1a15..655729004391 100644 --- a/tools/testing/selftests/bpf/test_cgroup_storage.c +++ b/tools/testing/selftests/bpf/test_cgroup_storage.c @@ -20,9 +20,9 @@ int main(int argc, char **argv) BPF_MOV64_IMM(BPF_REG_2, 0), /* flags, not used */ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_local_storage), - BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0), + BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0), BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 0x1), - BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0), + BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0), BPF_LD_MAP_FD(BPF_REG_1, 0), /* map fd */ BPF_MOV64_IMM(BPF_REG_2, 0), /* flags, not used */ @@ -30,7 +30,7 @@ int main(int argc, char **argv) BPF_FUNC_get_local_storage), BPF_MOV64_IMM(BPF_REG_1, 1), BPF_STX_XADD(BPF_DW, BPF_REG_0, BPF_REG_1, 0), - BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), + BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0), BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x1), BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), BPF_EXIT_INSN(), -- cgit v1.2.3-59-g8ed1b From e91dcb536ae263ecff07118e36bf820c229a6ecd Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Mon, 19 Aug 2019 14:38:47 +0200 Subject: selftests/bpf: fix test_btf_dump with O= test_btf_dump fails when run with O=, because it needs to access source files and assumes they live in ./progs/, which is not the case in this scenario. Fix by instructing kselftest to copy btf_dump_test_case_*.c files to the test directory. Since kselftest does not preserve directory structure, adjust the test to look in ./progs/ and then in ./. Signed-off-by: Ilya Leoshkevich Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/Makefile | 3 +++ tools/testing/selftests/bpf/test_btf_dump.c | 7 +++++++ 2 files changed, 10 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index c085964e1d05..69b98d8d3b5b 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -34,6 +34,9 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test BPF_OBJ_FILES = $(patsubst %.c,%.o, $(notdir $(wildcard progs/*.c))) TEST_GEN_FILES = $(BPF_OBJ_FILES) +BTF_C_FILES = $(wildcard progs/btf_dump_test_case_*.c) +TEST_FILES = $(BTF_C_FILES) + # Also test sub-register code-gen if LLVM has eBPF v3 processor support which # contains both ALU32 and JMP32 instructions. SUBREG_CODEGEN := $(shell echo "int cal(int a) { return a > 0; }" | \ diff --git a/tools/testing/selftests/bpf/test_btf_dump.c b/tools/testing/selftests/bpf/test_btf_dump.c index 8f850823d35f..6e75dd3cb14f 100644 --- a/tools/testing/selftests/bpf/test_btf_dump.c +++ b/tools/testing/selftests/bpf/test_btf_dump.c @@ -97,6 +97,13 @@ int test_btf_dump_case(int n, struct btf_dump_test_case *test_case) } snprintf(test_file, sizeof(test_file), "progs/%s.c", test_case->name); + if (access(test_file, R_OK) == -1) + /* + * When the test is run with O=, kselftest copies TEST_FILES + * without preserving the directory structure. + */ + snprintf(test_file, sizeof(test_file), "%s.c", + test_case->name); /* * Diff test output and expected test output, contained between * START-EXPECTED-OUTPUT and END-EXPECTED-OUTPUT lines in test case. -- cgit v1.2.3-59-g8ed1b From 0604409df9e04cdec7b08d471c8c1c0c10b5554d Mon Sep 17 00:00:00 2001 From: Anders Roxell Date: Tue, 20 Aug 2019 15:41:34 +0200 Subject: selftests/bpf: add config fragment BPF_JIT When running test_kmod.sh the following shows up # sysctl cannot stat /proc/sys/net/core/bpf_jit_enable No such file or directory cannot: stat_/proc/sys/net/core/bpf_jit_enable # # sysctl cannot stat /proc/sys/net/core/bpf_jit_harden No such file or directory cannot: stat_/proc/sys/net/core/bpf_jit_harden # Rework to enable CONFIG_BPF_JIT to solve "No such file or directory" Signed-off-by: Anders Roxell Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/config | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/config b/tools/testing/selftests/bpf/config index f7a0744db31e..5dc109f4c097 100644 --- a/tools/testing/selftests/bpf/config +++ b/tools/testing/selftests/bpf/config @@ -34,3 +34,4 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_IPV6_SIT=m +CONFIG_BPF_JIT=y -- cgit v1.2.3-59-g8ed1b From 3035bb72ee47d494c041465b4add9c6407c832ed Mon Sep 17 00:00:00 2001 From: Anders Roxell Date: Tue, 20 Aug 2019 15:41:21 +0200 Subject: selftests/bpf: install files test_xdp_vlan.sh When ./test_xdp_vlan_mode_generic.sh runs it complains that it can't find file test_xdp_vlan.sh. # selftests: bpf: test_xdp_vlan_mode_generic.sh # ./test_xdp_vlan_mode_generic.sh: line 9: ./test_xdp_vlan.sh: No such file or directory Rework so that test_xdp_vlan.sh gets installed, added to the variable TEST_PROGS_EXTENDED. Fixes: d35661fcf95d ("selftests/bpf: add wrapper scripts for test_xdp_vlan.sh") Signed-off-by: Anders Roxell Acked-by: Jesper Dangaard Brouer Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 69b98d8d3b5b..96752ebd938f 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -71,7 +71,8 @@ TEST_PROGS := test_kmod.sh \ TEST_PROGS_EXTENDED := with_addr.sh \ with_tunnels.sh \ tcp_client.py \ - tcp_server.py + tcp_server.py \ + test_xdp_vlan.sh # Compile but not part of 'make run_tests' TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr test_skb_cgroup_id_user \ -- cgit v1.2.3-59-g8ed1b From e4427372398c31f57450565de277f861a4db5b3b Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 10 Jun 2019 19:22:55 +0200 Subject: selftests/kvm: make platform_info_test pass on AMD test_msr_platform_info_disabled() generates EXIT_SHUTDOWN but VMCB state is undefined after that so an attempt to launch this guest again from test_msr_platform_info_enabled() fails. Reorder the tests to make test pass. Signed-off-by: Vitaly Kuznetsov Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/x86_64/platform_info_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/x86_64/platform_info_test.c b/tools/testing/selftests/kvm/x86_64/platform_info_test.c index 40050e44ec0a..f9334bd3cce9 100644 --- a/tools/testing/selftests/kvm/x86_64/platform_info_test.c +++ b/tools/testing/selftests/kvm/x86_64/platform_info_test.c @@ -99,8 +99,8 @@ int main(int argc, char *argv[]) msr_platform_info = vcpu_get_msr(vm, VCPU_ID, MSR_PLATFORM_INFO); vcpu_set_msr(vm, VCPU_ID, MSR_PLATFORM_INFO, msr_platform_info | MSR_PLATFORM_INFO_MAX_TURBO_RATIO); - test_msr_platform_info_disabled(vm); test_msr_platform_info_enabled(vm); + test_msr_platform_info_disabled(vm); vcpu_set_msr(vm, VCPU_ID, MSR_PLATFORM_INFO, msr_platform_info); kvm_vm_free(vm); -- cgit v1.2.3-59-g8ed1b From 1f8919b170318e7e13e303eedac363d44057995f Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Wed, 21 Aug 2019 00:09:00 +0100 Subject: bpf: sync bpf.h to tools/ Fix a 'struct pt_reg' typo and clarify when bpf_trace_printk discards lines. Affects documentation only. Signed-off-by: Peter Wu Signed-off-by: Alexei Starovoitov --- tools/include/uapi/linux/bpf.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 8aa6126f0b6e..b5889257cc33 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -580,6 +580,8 @@ union bpf_attr { * limited to five). * * Each time the helper is called, it appends a line to the trace. + * Lines are discarded while *\/sys/kernel/debug/tracing/trace* is + * open, use *\/sys/kernel/debug/tracing/trace_pipe* to avoid this. * The format of the trace is customizable, and the exact output * one will get depends on the options set in * *\/sys/kernel/debug/tracing/trace_options* (see also the @@ -1018,7 +1020,7 @@ union bpf_attr { * The realm of the route for the packet associated to *skb*, or 0 * if none was found. * - * int bpf_perf_event_output(struct pt_reg *ctx, struct bpf_map *map, u64 flags, void *data, u64 size) + * int bpf_perf_event_output(struct pt_regs *ctx, struct bpf_map *map, u64 flags, void *data, u64 size) * Description * Write raw *data* blob into a special BPF perf event held by * *map* of type **BPF_MAP_TYPE_PERF_EVENT_ARRAY**. This perf @@ -1080,7 +1082,7 @@ union bpf_attr { * Return * 0 on success, or a negative error in case of failure. * - * int bpf_get_stackid(struct pt_reg *ctx, struct bpf_map *map, u64 flags) + * int bpf_get_stackid(struct pt_regs *ctx, struct bpf_map *map, u64 flags) * Description * Walk a user or a kernel stack and return its id. To achieve * this, the helper needs *ctx*, which is a pointer to the context @@ -1729,7 +1731,7 @@ union bpf_attr { * Return * 0 on success, or a negative error in case of failure. * - * int bpf_override_return(struct pt_reg *regs, u64 rc) + * int bpf_override_return(struct pt_regs *regs, u64 rc) * Description * Used for error injection, this helper uses kprobes to override * the return value of the probed function, and to set it to *rc*. -- cgit v1.2.3-59-g8ed1b From c354ff2ef233a694d657b03a499c3c3fddbec599 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Wed, 21 Aug 2019 09:52:18 +0100 Subject: tools: bpftool: show frozen status for maps When listing maps, read their "frozen" status from procfs, and tell if maps are frozen. As commit log for map freezing command mentions that the feature might be extended with flags (e.g. for write-only instead of read-only) in the future, use an integer and not a boolean for JSON output. Signed-off-by: Quentin Monnet Reviewed-by: Jakub Kicinski Signed-off-by: Daniel Borkmann --- tools/bpf/bpftool/map.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c index bfbbc6b4cb83..af2e9eb9747b 100644 --- a/tools/bpf/bpftool/map.c +++ b/tools/bpf/bpftool/map.c @@ -481,9 +481,11 @@ static int parse_elem(char **argv, struct bpf_map_info *info, static int show_map_close_json(int fd, struct bpf_map_info *info) { - char *memlock; + char *memlock, *frozen_str; + int frozen = 0; memlock = get_fdinfo(fd, "memlock"); + frozen_str = get_fdinfo(fd, "frozen"); jsonw_start_object(json_wtr); @@ -533,6 +535,12 @@ static int show_map_close_json(int fd, struct bpf_map_info *info) } close(fd); + if (frozen_str) { + frozen = atoi(frozen_str); + free(frozen_str); + } + jsonw_int_field(json_wtr, "frozen", frozen); + if (info->btf_id) jsonw_int_field(json_wtr, "btf_id", info->btf_id); @@ -555,9 +563,11 @@ static int show_map_close_json(int fd, struct bpf_map_info *info) static int show_map_close_plain(int fd, struct bpf_map_info *info) { - char *memlock; + char *memlock, *frozen_str; + int frozen = 0; memlock = get_fdinfo(fd, "memlock"); + frozen_str = get_fdinfo(fd, "frozen"); printf("%u: ", info->id); if (info->type < ARRAY_SIZE(map_type_name)) @@ -610,9 +620,23 @@ static int show_map_close_plain(int fd, struct bpf_map_info *info) printf("\n\tpinned %s", obj->path); } } + printf("\n"); + + if (frozen_str) { + frozen = atoi(frozen_str); + free(frozen_str); + } + + if (!info->btf_id && !frozen) + return 0; + + printf("\t"); if (info->btf_id) - printf("\n\tbtf_id %d", info->btf_id); + printf("btf_id %d", info->btf_id); + + if (frozen) + printf("%sfrozen", info->btf_id ? " " : ""); printf("\n"); return 0; -- cgit v1.2.3-59-g8ed1b From 0bb52b0dfc88a155688f492aba8e686147600278 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Wed, 21 Aug 2019 09:52:19 +0100 Subject: tools: bpftool: add "bpftool map freeze" subcommand Add a new subcommand to freeze maps from user space. Signed-off-by: Quentin Monnet Reviewed-by: Jakub Kicinski Signed-off-by: Daniel Borkmann --- tools/bpf/bpftool/Documentation/bpftool-map.rst | 9 +++++++ tools/bpf/bpftool/bash-completion/bpftool | 4 +-- tools/bpf/bpftool/map.c | 34 ++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/Documentation/bpftool-map.rst b/tools/bpf/bpftool/Documentation/bpftool-map.rst index 61d1d270eb5e..1c0f7146aab0 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-map.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-map.rst @@ -36,6 +36,7 @@ MAP COMMANDS | **bpftool** **map pop** *MAP* | **bpftool** **map enqueue** *MAP* **value** *VALUE* | **bpftool** **map dequeue** *MAP* +| **bpftool** **map freeze** *MAP* | **bpftool** **map help** | | *MAP* := { **id** *MAP_ID* | **pinned** *FILE* } @@ -127,6 +128,14 @@ DESCRIPTION **bpftool map dequeue** *MAP* Dequeue and print **value** from the queue. + **bpftool map freeze** *MAP* + Freeze the map as read-only from user space. Entries from a + frozen map can not longer be updated or deleted with the + **bpf\ ()** system call. This operation is not reversible, + and the map remains immutable from user space until its + destruction. However, read and write permissions for BPF + programs to the map remain unchanged. + **bpftool map help** Print short help message. diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool index 2ffd351f9dbf..70493a6da206 100644 --- a/tools/bpf/bpftool/bash-completion/bpftool +++ b/tools/bpf/bpftool/bash-completion/bpftool @@ -449,7 +449,7 @@ _bpftool() map) local MAP_TYPE='id pinned' case $command in - show|list|dump|peek|pop|dequeue) + show|list|dump|peek|pop|dequeue|freeze) case $prev in $command) COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) ) @@ -638,7 +638,7 @@ _bpftool() [[ $prev == $object ]] && \ COMPREPLY=( $( compgen -W 'delete dump getnext help \ lookup pin event_pipe show list update create \ - peek push enqueue pop dequeue' -- \ + peek push enqueue pop dequeue freeze' -- \ "$cur" ) ) ;; esac diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c index af2e9eb9747b..de61d73b9030 100644 --- a/tools/bpf/bpftool/map.c +++ b/tools/bpf/bpftool/map.c @@ -1262,6 +1262,35 @@ exit_free: return err; } +static int do_freeze(int argc, char **argv) +{ + int err, fd; + + if (!REQ_ARGS(2)) + return -1; + + fd = map_parse_fd(&argc, &argv); + if (fd < 0) + return -1; + + if (argc) { + close(fd); + return BAD_ARG(); + } + + err = bpf_map_freeze(fd); + close(fd); + if (err) { + p_err("failed to freeze map: %s", strerror(errno)); + return err; + } + + if (json_output) + jsonw_null(json_wtr); + + return 0; +} + static int do_help(int argc, char **argv) { if (json_output) { @@ -1286,6 +1315,7 @@ static int do_help(int argc, char **argv) " %s %s pop MAP\n" " %s %s enqueue MAP value VALUE\n" " %s %s dequeue MAP\n" + " %s %s freeze MAP\n" " %s %s help\n" "\n" " " HELP_SPEC_MAP "\n" @@ -1304,7 +1334,8 @@ static int do_help(int argc, char **argv) bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], - bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2]); + bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], + bin_name, argv[-2]); return 0; } @@ -1326,6 +1357,7 @@ static const struct cmd cmds[] = { { "enqueue", do_update }, { "pop", do_pop_dequeue }, { "dequeue", do_pop_dequeue }, + { "freeze", do_freeze }, { 0 } }; -- cgit v1.2.3-59-g8ed1b From 170270329b1b5f854e8a98aea16bfa4af6922146 Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Wed, 21 Aug 2019 10:19:36 +0300 Subject: selftests: mlxsw: Add test cases for devlink-trap L2 drops Test that each supported packet trap is triggered under the right conditions and that packets are indeed dropped and not forwarded. Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- .../drivers/net/mlxsw/devlink_trap_l2_drops.sh | 484 +++++++++++++++++++++ 1 file changed, 484 insertions(+) create mode 100755 tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l2_drops.sh (limited to 'tools') diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l2_drops.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l2_drops.sh new file mode 100755 index 000000000000..5dcdfa20fc6c --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l2_drops.sh @@ -0,0 +1,484 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Test devlink-trap L2 drops functionality over mlxsw. Each registered L2 drop +# packet trap is tested to make sure it is triggered under the right +# conditions. + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + source_mac_is_multicast_test + vlan_tag_mismatch_test + ingress_vlan_filter_test + ingress_stp_filter_test + port_list_is_empty_test + port_loopback_filter_test +" +NUM_NETIFS=4 +source $lib_dir/tc_common.sh +source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh + +h1_create() +{ + simple_if_init $h1 +} + +h1_destroy() +{ + simple_if_fini $h1 +} + +h2_create() +{ + simple_if_init $h2 +} + +h2_destroy() +{ + simple_if_fini $h2 +} + +switch_create() +{ + ip link add dev br0 type bridge vlan_filtering 1 mcast_snooping 0 + + ip link set dev $swp1 master br0 + ip link set dev $swp2 master br0 + + ip link set dev br0 up + ip link set dev $swp1 up + ip link set dev $swp2 up + + tc qdisc add dev $swp2 clsact +} + +switch_destroy() +{ + tc qdisc del dev $swp2 clsact + + ip link set dev $swp2 down + ip link set dev $swp1 down + + ip link del dev br0 +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + swp2=${NETIFS[p3]} + h2=${NETIFS[p4]} + + vrf_prepare + + h1_create + h2_create + + switch_create +} + +cleanup() +{ + pre_cleanup + + switch_destroy + + h2_destroy + h1_destroy + + vrf_cleanup +} + +l2_drops_test() +{ + local trap_name=$1; shift + local group_name=$1; shift + + # This is the common part of all the tests. It checks that stats are + # initially idle, then non-idle after changing the trap action and + # finally idle again. It also makes sure the packets are dropped and + # never forwarded. + devlink_trap_stats_idle_test $trap_name + check_err $? "Trap stats not idle with initial drop action" + devlink_trap_group_stats_idle_test $group_name + check_err $? "Trap group stats not idle with initial drop action" + + devlink_trap_action_set $trap_name "trap" + + devlink_trap_stats_idle_test $trap_name + check_fail $? "Trap stats idle after setting action to trap" + devlink_trap_group_stats_idle_test $group_name + check_fail $? "Trap group stats idle after setting action to trap" + + devlink_trap_action_set $trap_name "drop" + + devlink_trap_stats_idle_test $trap_name + check_err $? "Trap stats not idle after setting action to drop" + devlink_trap_group_stats_idle_test $group_name + check_err $? "Trap group stats not idle after setting action to drop" + + tc_check_packets "dev $swp2 egress" 101 0 + check_err $? "Packets were not dropped" +} + +l2_drops_cleanup() +{ + local mz_pid=$1; shift + + kill $mz_pid && wait $mz_pid &> /dev/null + tc filter del dev $swp2 egress protocol ip pref 1 handle 101 flower +} + +source_mac_is_multicast_test() +{ + local trap_name="source_mac_is_multicast" + local smac=01:02:03:04:05:06 + local group_name="l2_drops" + local mz_pid + + tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ + flower src_mac $smac action drop + + $MZ $h1 -c 0 -p 100 -a $smac -b bcast -t ip -d 1msec -q & + mz_pid=$! + + RET=0 + + l2_drops_test $trap_name $group_name + + log_test "Source MAC is multicast" + + l2_drops_cleanup $mz_pid +} + +__vlan_tag_mismatch_test() +{ + local trap_name="vlan_tag_mismatch" + local dmac=de:ad:be:ef:13:37 + local group_name="l2_drops" + local opt=$1; shift + local mz_pid + + # Remove PVID flag. This should prevent untagged and prio-tagged + # packets from entering the bridge. + bridge vlan add vid 1 dev $swp1 untagged master + + tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ + flower dst_mac $dmac action drop + + $MZ $h1 "$opt" -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q & + mz_pid=$! + + l2_drops_test $trap_name $group_name + + # Add PVID and make sure packets are no longer dropped. + bridge vlan add vid 1 dev $swp1 pvid untagged master + devlink_trap_action_set $trap_name "trap" + + devlink_trap_stats_idle_test $trap_name + check_err $? "Trap stats not idle when packets should not be dropped" + devlink_trap_group_stats_idle_test $group_name + check_err $? "Trap group stats not idle with when packets should not be dropped" + + tc_check_packets "dev $swp2 egress" 101 0 + check_fail $? "Packets not forwarded when should" + + devlink_trap_action_set $trap_name "drop" + + l2_drops_cleanup $mz_pid +} + +vlan_tag_mismatch_untagged_test() +{ + RET=0 + + __vlan_tag_mismatch_test + + log_test "VLAN tag mismatch - untagged packets" +} + +vlan_tag_mismatch_vid_0_test() +{ + RET=0 + + __vlan_tag_mismatch_test "-Q 0" + + log_test "VLAN tag mismatch - prio-tagged packets" +} + +vlan_tag_mismatch_test() +{ + vlan_tag_mismatch_untagged_test + vlan_tag_mismatch_vid_0_test +} + +ingress_vlan_filter_test() +{ + local trap_name="ingress_vlan_filter" + local dmac=de:ad:be:ef:13:37 + local group_name="l2_drops" + local mz_pid + local vid=10 + + bridge vlan add vid $vid dev $swp2 master + # During initialization the firmware enables all the VLAN filters and + # the driver does not turn them off since the traffic will be discarded + # by the STP filter whose default is DISCARD state. Add the VID on the + # ingress bridge port and then remove it to make sure it is not member + # in the VLAN. + bridge vlan add vid $vid dev $swp1 master + bridge vlan del vid $vid dev $swp1 master + + RET=0 + + tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ + flower dst_mac $dmac action drop + + $MZ $h1 -Q $vid -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q & + mz_pid=$! + + l2_drops_test $trap_name $group_name + + # Add the VLAN on the bridge port and make sure packets are no longer + # dropped. + bridge vlan add vid $vid dev $swp1 master + devlink_trap_action_set $trap_name "trap" + + devlink_trap_stats_idle_test $trap_name + check_err $? "Trap stats not idle when packets should not be dropped" + devlink_trap_group_stats_idle_test $group_name + check_err $? "Trap group stats not idle with when packets should not be dropped" + + tc_check_packets "dev $swp2 egress" 101 0 + check_fail $? "Packets not forwarded when should" + + devlink_trap_action_set $trap_name "drop" + + log_test "Ingress VLAN filter" + + l2_drops_cleanup $mz_pid + + bridge vlan del vid $vid dev $swp1 master + bridge vlan del vid $vid dev $swp2 master +} + +__ingress_stp_filter_test() +{ + local trap_name="ingress_spanning_tree_filter" + local dmac=de:ad:be:ef:13:37 + local group_name="l2_drops" + local state=$1; shift + local mz_pid + local vid=20 + + bridge vlan add vid $vid dev $swp2 master + bridge vlan add vid $vid dev $swp1 master + ip link set dev $swp1 type bridge_slave state $state + + tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ + flower dst_mac $dmac action drop + + $MZ $h1 -Q $vid -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q & + mz_pid=$! + + l2_drops_test $trap_name $group_name + + # Change STP state to forwarding and make sure packets are no longer + # dropped. + ip link set dev $swp1 type bridge_slave state 3 + devlink_trap_action_set $trap_name "trap" + + devlink_trap_stats_idle_test $trap_name + check_err $? "Trap stats not idle when packets should not be dropped" + devlink_trap_group_stats_idle_test $group_name + check_err $? "Trap group stats not idle with when packets should not be dropped" + + tc_check_packets "dev $swp2 egress" 101 0 + check_fail $? "Packets not forwarded when should" + + devlink_trap_action_set $trap_name "drop" + + l2_drops_cleanup $mz_pid + + bridge vlan del vid $vid dev $swp1 master + bridge vlan del vid $vid dev $swp2 master +} + +ingress_stp_filter_listening_test() +{ + local state=$1; shift + + RET=0 + + __ingress_stp_filter_test $state + + log_test "Ingress STP filter - listening state" +} + +ingress_stp_filter_learning_test() +{ + local state=$1; shift + + RET=0 + + __ingress_stp_filter_test $state + + log_test "Ingress STP filter - learning state" +} + +ingress_stp_filter_test() +{ + ingress_stp_filter_listening_test 1 + ingress_stp_filter_learning_test 2 +} + +port_list_is_empty_uc_test() +{ + local trap_name="port_list_is_empty" + local dmac=de:ad:be:ef:13:37 + local group_name="l2_drops" + local mz_pid + + # Disable unicast flooding on both ports, so that packets cannot egress + # any port. + ip link set dev $swp1 type bridge_slave flood off + ip link set dev $swp2 type bridge_slave flood off + + RET=0 + + tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ + flower dst_mac $dmac action drop + + $MZ $h1 -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q & + mz_pid=$! + + l2_drops_test $trap_name $group_name + + # Allow packets to be flooded to one port. + ip link set dev $swp2 type bridge_slave flood on + devlink_trap_action_set $trap_name "trap" + + devlink_trap_stats_idle_test $trap_name + check_err $? "Trap stats not idle when packets should not be dropped" + devlink_trap_group_stats_idle_test $group_name + check_err $? "Trap group stats not idle with when packets should not be dropped" + + tc_check_packets "dev $swp2 egress" 101 0 + check_fail $? "Packets not forwarded when should" + + devlink_trap_action_set $trap_name "drop" + + log_test "Port list is empty - unicast" + + l2_drops_cleanup $mz_pid + + ip link set dev $swp1 type bridge_slave flood on +} + +port_list_is_empty_mc_test() +{ + local trap_name="port_list_is_empty" + local dmac=01:00:5e:00:00:01 + local group_name="l2_drops" + local dip=239.0.0.1 + local mz_pid + + # Disable multicast flooding on both ports, so that packets cannot + # egress any port. We also need to flush IP addresses from the bridge + # in order to prevent packets from being flooded to the router port. + ip link set dev $swp1 type bridge_slave mcast_flood off + ip link set dev $swp2 type bridge_slave mcast_flood off + ip address flush dev br0 + + RET=0 + + tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ + flower dst_mac $dmac action drop + + $MZ $h1 -c 0 -p 100 -a own -b $dmac -t ip -B $dip -d 1msec -q & + mz_pid=$! + + l2_drops_test $trap_name $group_name + + # Allow packets to be flooded to one port. + ip link set dev $swp2 type bridge_slave mcast_flood on + devlink_trap_action_set $trap_name "trap" + + devlink_trap_stats_idle_test $trap_name + check_err $? "Trap stats not idle when packets should not be dropped" + devlink_trap_group_stats_idle_test $group_name + check_err $? "Trap group stats not idle with when packets should not be dropped" + + tc_check_packets "dev $swp2 egress" 101 0 + check_fail $? "Packets not forwarded when should" + + devlink_trap_action_set $trap_name "drop" + + log_test "Port list is empty - multicast" + + l2_drops_cleanup $mz_pid + + ip link set dev $swp1 type bridge_slave mcast_flood on +} + +port_list_is_empty_test() +{ + port_list_is_empty_uc_test + port_list_is_empty_mc_test +} + +port_loopback_filter_uc_test() +{ + local trap_name="port_loopback_filter" + local dmac=de:ad:be:ef:13:37 + local group_name="l2_drops" + local mz_pid + + # Make sure packets can only egress the input port. + ip link set dev $swp2 type bridge_slave flood off + + RET=0 + + tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \ + flower dst_mac $dmac action drop + + $MZ $h1 -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q & + mz_pid=$! + + l2_drops_test $trap_name $group_name + + # Allow packets to be flooded. + ip link set dev $swp2 type bridge_slave flood on + devlink_trap_action_set $trap_name "trap" + + devlink_trap_stats_idle_test $trap_name + check_err $? "Trap stats not idle when packets should not be dropped" + devlink_trap_group_stats_idle_test $group_name + check_err $? "Trap group stats not idle with when packets should not be dropped" + + tc_check_packets "dev $swp2 egress" 101 0 + check_fail $? "Packets not forwarded when should" + + devlink_trap_action_set $trap_name "drop" + + log_test "Port loopback filter - unicast" + + l2_drops_cleanup $mz_pid +} + +port_loopback_filter_test() +{ + port_loopback_filter_uc_test +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS -- cgit v1.2.3-59-g8ed1b From 1455865a040a0f632dce5d8f7cb6604517f56c6d Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Wed, 21 Aug 2019 10:19:37 +0300 Subject: selftests: mlxsw: Add a test case for devlink-trap Test generic devlink-trap functionality over mlxsw. These tests are not specific to a single trap, but do not check the devlink-trap common infrastructure either. Currently, the only test case is device deletion (by reloading the driver) while packets are being trapped. Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- .../selftests/drivers/net/mlxsw/devlink_trap.sh | 129 +++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100755 tools/testing/selftests/drivers/net/mlxsw/devlink_trap.sh (limited to 'tools') diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap.sh new file mode 100755 index 000000000000..89b55e946eed --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap.sh @@ -0,0 +1,129 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Test generic devlink-trap functionality over mlxsw. These tests are not +# specific to a single trap, but do not check the devlink-trap common +# infrastructure either. + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + dev_del_test +" +NUM_NETIFS=4 +source $lib_dir/tc_common.sh +source $lib_dir/lib.sh +source $lib_dir/devlink_lib.sh + +h1_create() +{ + simple_if_init $h1 +} + +h1_destroy() +{ + simple_if_fini $h1 +} + +h2_create() +{ + simple_if_init $h2 +} + +h2_destroy() +{ + simple_if_fini $h2 +} + +switch_create() +{ + ip link add dev br0 type bridge vlan_filtering 1 mcast_snooping 0 + + ip link set dev $swp1 master br0 + ip link set dev $swp2 master br0 + + ip link set dev br0 up + ip link set dev $swp1 up + ip link set dev $swp2 up +} + +switch_destroy() +{ + ip link set dev $swp2 down + ip link set dev $swp1 down + + ip link del dev br0 +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + swp2=${NETIFS[p3]} + h2=${NETIFS[p4]} + + vrf_prepare + + h1_create + h2_create + + switch_create +} + +cleanup() +{ + pre_cleanup + + switch_destroy + + h2_destroy + h1_destroy + + vrf_cleanup +} + +dev_del_test() +{ + local trap_name="source_mac_is_multicast" + local smac=01:02:03:04:05:06 + local num_iter=5 + local mz_pid + local i + + $MZ $h1 -c 0 -p 100 -a $smac -b bcast -t ip -q & + mz_pid=$! + + # The purpose of this test is to make sure we correctly dismantle a + # port while packets are trapped from it. This is done by reloading the + # the driver while the 'ingress_smac_mc_drop' trap is triggered. + RET=0 + + for i in $(seq 1 $num_iter); do + log_info "Iteration $i / $num_iter" + + devlink_trap_action_set $trap_name "trap" + sleep 1 + + devlink_reload + # Allow netdevices to be re-created following the reload + sleep 20 + + cleanup + setup_prepare + setup_wait + done + + log_test "Device delete" + + kill $mz_pid && wait $mz_pid &> /dev/null +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS -- cgit v1.2.3-59-g8ed1b From b8baa05a0e505f8311fb03f5c72e75fa0e13fd95 Mon Sep 17 00:00:00 2001 From: Gustavo Romero Date: Wed, 14 Aug 2019 15:56:38 -0500 Subject: selftests/powerpc: Ignore generated files Currently some binary files which are generated when tests are compiled are not ignored by git, so 'git status' catch them. For copyloops test, fix wrong binary names already in .gitignore. For ptrace, security, and stringloops tests add missing binary names to the .gitignore file. Signed-off-by: Gustavo Romero Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20190814205638.25322-2-gromero@linux.ibm.com --- tools/testing/selftests/powerpc/copyloops/.gitignore | 8 ++++---- tools/testing/selftests/powerpc/ptrace/.gitignore | 3 +++ tools/testing/selftests/powerpc/security/.gitignore | 1 + tools/testing/selftests/powerpc/stringloops/.gitignore | 5 ++++- 4 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 tools/testing/selftests/powerpc/security/.gitignore (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/copyloops/.gitignore b/tools/testing/selftests/powerpc/copyloops/.gitignore index ce12cd0e2967..de158104912a 100644 --- a/tools/testing/selftests/powerpc/copyloops/.gitignore +++ b/tools/testing/selftests/powerpc/copyloops/.gitignore @@ -1,13 +1,13 @@ copyuser_64_t0 copyuser_64_t1 copyuser_64_t2 -copyuser_power7_t0 -copyuser_power7_t1 +copyuser_p7_t0 +copyuser_p7_t1 memcpy_64_t0 memcpy_64_t1 memcpy_64_t2 -memcpy_power7_t0 -memcpy_power7_t1 +memcpy_p7_t0 +memcpy_p7_t1 copyuser_64_exc_t0 copyuser_64_exc_t1 copyuser_64_exc_t2 diff --git a/tools/testing/selftests/powerpc/ptrace/.gitignore b/tools/testing/selftests/powerpc/ptrace/.gitignore index 07ec449a2767..dce19f221c46 100644 --- a/tools/testing/selftests/powerpc/ptrace/.gitignore +++ b/tools/testing/selftests/powerpc/ptrace/.gitignore @@ -10,3 +10,6 @@ ptrace-tm-spd-vsx ptrace-tm-spr ptrace-hwbreak perf-hwbreak +core-pkey +ptrace-pkey +ptrace-syscall diff --git a/tools/testing/selftests/powerpc/security/.gitignore b/tools/testing/selftests/powerpc/security/.gitignore new file mode 100644 index 000000000000..0b969fba3beb --- /dev/null +++ b/tools/testing/selftests/powerpc/security/.gitignore @@ -0,0 +1 @@ +rfi_flush diff --git a/tools/testing/selftests/powerpc/stringloops/.gitignore b/tools/testing/selftests/powerpc/stringloops/.gitignore index 0b43da74ee46..31a17e0ba884 100644 --- a/tools/testing/selftests/powerpc/stringloops/.gitignore +++ b/tools/testing/selftests/powerpc/stringloops/.gitignore @@ -1 +1,4 @@ -memcmp +memcmp_64 +memcmp_32 +strlen +strlen_32 -- cgit v1.2.3-59-g8ed1b From db9a5fd02a06113848fd3eabe302f56059d27366 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 22 Aug 2019 13:11:37 +0200 Subject: tools headers: Add missing perf_event.h include We need perf_event.h include for 'struct perf_event_mmap_page'. Link: http://lkml.kernel.org/n/tip-bolqkmqajexhccjb0ib0an8w@git.kernel.org Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190822111141.25823-2-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/ring_buffer.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/include/linux/ring_buffer.h b/tools/include/linux/ring_buffer.h index 9a083ae60473..6c02617377c2 100644 --- a/tools/include/linux/ring_buffer.h +++ b/tools/include/linux/ring_buffer.h @@ -2,6 +2,7 @@ #define _TOOLS_LINUX_RING_BUFFER_H_ #include +#include /* * Contract with kernel for walking the perf ring buffer from -- cgit v1.2.3-59-g8ed1b From 6549cd8f2cc2cdf7e107fbbc3a68ecefb774bb2f Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 22 Aug 2019 13:11:38 +0200 Subject: perf tools: Use perf_cpu_map__nr instead of cpu_map__nr Switch the rest of the perf code to use libperf's perf_cpu_map__nr(), which is the same as current cpu_map__nr() and remove the cpu_map__nr() function. Link: http://lkml.kernel.org/n/tip-6e0guy75clis7nm0xpuz9fga@git.kernel.org Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190822111141.25823-3-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 4 ++-- tools/perf/util/cpumap.h | 5 ----- tools/perf/util/evlist.c | 10 +++++----- tools/perf/util/mmap.c | 2 +- tools/perf/util/stat-display.c | 2 +- 5 files changed, 9 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 5cb07e8cb296..c786ab095d15 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -653,7 +653,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr, cpu_map = online_cpus; } else { /* Make sure all specified CPUs are online */ - for (i = 0; i < cpu_map__nr(event_cpus); i++) { + for (i = 0; i < perf_cpu_map__nr(event_cpus); i++) { if (cpu_map__has(event_cpus, i) && !cpu_map__has(online_cpus, i)) return -EINVAL; @@ -662,7 +662,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr, cpu_map = event_cpus; } - nr_cpu = cpu_map__nr(cpu_map); + nr_cpu = perf_cpu_map__nr(cpu_map); /* Get PMU type as dynamically assigned by the core */ type = cs_etm_pmu->type; diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index a3d27f4131be..77f85e9c88d4 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -49,11 +49,6 @@ static inline int cpu_map__id_to_cpu(int id) return id & 0xffff; } -static inline int cpu_map__nr(const struct perf_cpu_map *map) -{ - return map ? map->nr : 1; -} - static inline bool cpu_map__empty(const struct perf_cpu_map *map) { return map ? map->map[0] == -1 : true; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index c4489a1ad6bc..15d1046014d7 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -370,7 +370,7 @@ static int perf_evlist__enable_event_thread(struct evlist *evlist, int thread) { int cpu; - int nr_cpus = cpu_map__nr(evlist->core.cpus); + int nr_cpus = perf_cpu_map__nr(evlist->core.cpus); if (!evsel->core.fd) return -EINVAL; @@ -396,7 +396,7 @@ int perf_evlist__enable_event_idx(struct evlist *evlist, int perf_evlist__alloc_pollfd(struct evlist *evlist) { - int nr_cpus = cpu_map__nr(evlist->core.cpus); + int nr_cpus = perf_cpu_map__nr(evlist->core.cpus); int nr_threads = thread_map__nr(evlist->core.threads); int nfds = 0; struct evsel *evsel; @@ -692,7 +692,7 @@ static struct perf_mmap *perf_evlist__alloc_mmap(struct evlist *evlist, int i; struct perf_mmap *map; - evlist->nr_mmaps = cpu_map__nr(evlist->core.cpus); + evlist->nr_mmaps = perf_cpu_map__nr(evlist->core.cpus); if (cpu_map__empty(evlist->core.cpus)) evlist->nr_mmaps = thread_map__nr(evlist->core.threads); map = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap)); @@ -807,7 +807,7 @@ static int perf_evlist__mmap_per_cpu(struct evlist *evlist, struct mmap_params *mp) { int cpu, thread; - int nr_cpus = cpu_map__nr(evlist->core.cpus); + int nr_cpus = perf_cpu_map__nr(evlist->core.cpus); int nr_threads = thread_map__nr(evlist->core.threads); pr_debug2("perf event ring buffer mmapped per cpu\n"); @@ -1014,7 +1014,7 @@ int perf_evlist__mmap_ex(struct evlist *evlist, unsigned int pages, evlist__for_each_entry(evlist, evsel) { if ((evsel->core.attr.read_format & PERF_FORMAT_ID) && evsel->sample_id == NULL && - perf_evsel__alloc_id(evsel, cpu_map__nr(cpus), threads->nr) < 0) + perf_evsel__alloc_id(evsel, perf_cpu_map__nr(cpus), threads->nr) < 0) return -ENOMEM; } diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 42a5971146ae..5f3532e51ec9 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -331,7 +331,7 @@ static void build_node_mask(int node, cpu_set_t *mask) if (!cpu_map) return; - nr_cpus = cpu_map__nr(cpu_map); + nr_cpus = perf_cpu_map__nr(cpu_map); for (c = 0; c < nr_cpus; c++) { cpu = cpu_map->map[c]; /* map c index to online cpu index */ if (cpu__get_node(cpu) == node) diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index f7b39f4bc51e..3df0e39ccd52 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -745,7 +745,7 @@ static void print_aggr_thread(struct perf_stat_config *config, { FILE *output = config->output; int nthreads = thread_map__nr(counter->core.threads); - int ncpus = cpu_map__nr(counter->core.cpus); + int ncpus = perf_cpu_map__nr(counter->core.cpus); int thread, sorted_threads, id; struct perf_aggr_thread_value *buf; -- cgit v1.2.3-59-g8ed1b From 315c0a1f0ccdd44c65f80ccbc62202fed8a23050 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 22 Aug 2019 13:11:39 +0200 Subject: libperf: Move perf's cpu_map__empty() to perf_cpu_map__empty() So it's part of the libperf library as one of basic functions operating on the perf_cpu_map class. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190822111141.25823-4-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 8 ++++---- tools/perf/arch/x86/util/intel-bts.c | 4 ++-- tools/perf/arch/x86/util/intel-pt.c | 10 +++++----- tools/perf/builtin-c2c.c | 2 +- tools/perf/builtin-stat.c | 4 ++-- tools/perf/lib/cpumap.c | 5 +++++ tools/perf/lib/include/perf/cpumap.h | 2 ++ tools/perf/lib/libperf.map | 1 + tools/perf/util/cpumap.c | 6 +++--- tools/perf/util/cpumap.h | 7 +------ tools/perf/util/event.c | 2 +- tools/perf/util/evlist.c | 6 +++--- tools/perf/util/record.c | 2 +- tools/perf/util/stat.c | 2 +- 14 files changed, 32 insertions(+), 29 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index c786ab095d15..c73da3245b67 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -396,7 +396,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, * AUX event. We also need the contextID in order to be notified * when a context switch happened. */ - if (!cpu_map__empty(cpus)) { + if (!perf_cpu_map__empty(cpus)) { perf_evsel__set_sample_bit(cs_etm_evsel, CPU); err = cs_etm_set_option(itr, cs_etm_evsel, @@ -420,7 +420,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, tracking_evsel->core.attr.sample_period = 1; /* In per-cpu case, always need the time of mmap events etc */ - if (!cpu_map__empty(cpus)) + if (!perf_cpu_map__empty(cpus)) perf_evsel__set_sample_bit(tracking_evsel, TIME); } @@ -493,7 +493,7 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused, struct perf_cpu_map *online_cpus = perf_cpu_map__new(NULL); /* cpu map is not empty, we have specific CPUs to work with */ - if (!cpu_map__empty(event_cpus)) { + if (!perf_cpu_map__empty(event_cpus)) { for (i = 0; i < cpu__max_cpu(); i++) { if (!cpu_map__has(event_cpus, i) || !cpu_map__has(online_cpus, i)) @@ -649,7 +649,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr, return -EINVAL; /* If the cpu_map is empty all online CPUs are involved */ - if (cpu_map__empty(event_cpus)) { + if (perf_cpu_map__empty(event_cpus)) { cpu_map = online_cpus; } else { /* Make sure all specified CPUs are online */ diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index 7b23318ebd7b..2d5d8a12dd1f 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -133,7 +133,7 @@ static int intel_bts_recording_options(struct auxtrace_record *itr, if (!opts->full_auxtrace) return 0; - if (opts->full_auxtrace && !cpu_map__empty(cpus)) { + if (opts->full_auxtrace && !perf_cpu_map__empty(cpus)) { pr_err(INTEL_BTS_PMU_NAME " does not support per-cpu recording\n"); return -EINVAL; } @@ -214,7 +214,7 @@ static int intel_bts_recording_options(struct auxtrace_record *itr, * In the case of per-cpu mmaps, we need the CPU on the * AUX event. */ - if (!cpu_map__empty(cpus)) + if (!perf_cpu_map__empty(cpus)) perf_evsel__set_sample_bit(intel_bts_evsel, CPU); } diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index a8e633aa278a..c72a77a82b39 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -365,7 +365,7 @@ static int intel_pt_info_fill(struct auxtrace_record *itr, ui__warning("Intel Processor Trace: TSC not available\n"); } - per_cpu_mmaps = !cpu_map__empty(session->evlist->core.cpus); + per_cpu_mmaps = !perf_cpu_map__empty(session->evlist->core.cpus); auxtrace_info->type = PERF_AUXTRACE_INTEL_PT; auxtrace_info->priv[INTEL_PT_PMU_TYPE] = intel_pt_pmu->type; @@ -702,7 +702,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, * Per-cpu recording needs sched_switch events to distinguish different * threads. */ - if (have_timing_info && !cpu_map__empty(cpus)) { + if (have_timing_info && !perf_cpu_map__empty(cpus)) { if (perf_can_record_switch_events()) { bool cpu_wide = !target__none(&opts->target) && !target__has_task(&opts->target); @@ -760,7 +760,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, * In the case of per-cpu mmaps, we need the CPU on the * AUX event. */ - if (!cpu_map__empty(cpus)) + if (!perf_cpu_map__empty(cpus)) perf_evsel__set_sample_bit(intel_pt_evsel, CPU); } @@ -784,7 +784,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, tracking_evsel->immediate = true; /* In per-cpu case, always need the time of mmap events etc */ - if (!cpu_map__empty(cpus)) { + if (!perf_cpu_map__empty(cpus)) { perf_evsel__set_sample_bit(tracking_evsel, TIME); /* And the CPU for switch events */ perf_evsel__set_sample_bit(tracking_evsel, CPU); @@ -796,7 +796,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, * Warn the user when we do not have enough information to decode i.e. * per-cpu with no sched_switch (except workload-only). */ - if (!ptr->have_sched_switch && !cpu_map__empty(cpus) && + if (!ptr->have_sched_switch && !perf_cpu_map__empty(cpus) && !target__none(&opts->target)) ui__warning("Intel Processor Trace decoding will not be possible except for kernel tracing!\n"); diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index f0aae6e13a33..01629f5b6d1f 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -2059,7 +2059,7 @@ static int setup_nodes(struct perf_session *session) nodes[node] = set; /* empty node, skip */ - if (cpu_map__empty(map)) + if (perf_cpu_map__empty(map)) continue; for (cpu = 0; cpu < map->nr; cpu++) { diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index b19df671111e..90636a811b36 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -928,7 +928,7 @@ static int perf_stat_init_aggr_mode(void) * the aggregation translate cpumap. */ nr = cpu_map__get_max(evsel_list->core.cpus); - stat_config.cpus_aggr_map = cpu_map__empty_new(nr + 1); + stat_config.cpus_aggr_map = perf_cpu_map__empty_new(nr + 1); return stat_config.cpus_aggr_map ? 0 : -ENOMEM; } @@ -1493,7 +1493,7 @@ int process_stat_config_event(struct perf_session *session, perf_event__read_stat_config(&stat_config, &event->stat_config); - if (cpu_map__empty(st->cpus)) { + if (perf_cpu_map__empty(st->cpus)) { if (st->aggr_mode != AGGR_UNSET) pr_warning("warning: processing task data, aggregation mode not set\n"); return 0; diff --git a/tools/perf/lib/cpumap.c b/tools/perf/lib/cpumap.c index 1ddb69e796e5..63f7df7e47ff 100644 --- a/tools/perf/lib/cpumap.c +++ b/tools/perf/lib/cpumap.c @@ -237,3 +237,8 @@ int perf_cpu_map__nr(const struct perf_cpu_map *cpus) { return cpus ? cpus->nr : 1; } + +bool perf_cpu_map__empty(const struct perf_cpu_map *map) +{ + return map ? map->map[0] == -1 : true; +} diff --git a/tools/perf/lib/include/perf/cpumap.h b/tools/perf/lib/include/perf/cpumap.h index 1b6e7db3fa2b..8aa995c59498 100644 --- a/tools/perf/lib/include/perf/cpumap.h +++ b/tools/perf/lib/include/perf/cpumap.h @@ -4,6 +4,7 @@ #include #include +#include struct perf_cpu_map; @@ -14,6 +15,7 @@ LIBPERF_API struct perf_cpu_map *perf_cpu_map__get(struct perf_cpu_map *map); LIBPERF_API void perf_cpu_map__put(struct perf_cpu_map *map); LIBPERF_API int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx); LIBPERF_API int perf_cpu_map__nr(const struct perf_cpu_map *cpus); +LIBPERF_API bool perf_cpu_map__empty(const struct perf_cpu_map *map); #define perf_cpu_map__for_each_cpu(cpu, idx, cpus) \ for ((idx) = 0, (cpu) = perf_cpu_map__cpu(cpus, idx); \ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index e24d3cec01c1..3373dd51fcda 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -8,6 +8,7 @@ LIBPERF_0.0.1 { perf_cpu_map__read; perf_cpu_map__nr; perf_cpu_map__cpu; + perf_cpu_map__empty; perf_thread_map__new_dummy; perf_thread_map__set_pid; perf_thread_map__comm; diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index beb3525e9e45..4402e67445a4 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -21,7 +21,7 @@ static struct perf_cpu_map *cpu_map__from_entries(struct cpu_map_entries *cpus) { struct perf_cpu_map *map; - map = cpu_map__empty_new(cpus->nr); + map = perf_cpu_map__empty_new(cpus->nr); if (map) { unsigned i; @@ -48,7 +48,7 @@ static struct perf_cpu_map *cpu_map__from_mask(struct cpu_map_mask *mask) nr = bitmap_weight(mask->mask, nbits); - map = cpu_map__empty_new(nr); + map = perf_cpu_map__empty_new(nr); if (map) { int cpu, i = 0; @@ -77,7 +77,7 @@ size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp) #undef BUFSIZE } -struct perf_cpu_map *cpu_map__empty_new(int nr) +struct perf_cpu_map *perf_cpu_map__empty_new(int nr) { struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + sizeof(int) * nr); diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index 77f85e9c88d4..3e068090612f 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -11,7 +11,7 @@ #include "perf.h" #include "util/debug.h" -struct perf_cpu_map *cpu_map__empty_new(int nr); +struct perf_cpu_map *perf_cpu_map__empty_new(int nr); struct perf_cpu_map *cpu_map__new_data(struct cpu_map_data *data); size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size); size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size); @@ -49,11 +49,6 @@ static inline int cpu_map__id_to_cpu(int id) return id & 0xffff; } -static inline bool cpu_map__empty(const struct perf_cpu_map *map) -{ - return map ? map->map[0] == -1 : true; -} - int cpu__setup_cpunode_map(void); int cpu__max_node(void); diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index f440fdc3e953..f433da85c45e 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1055,7 +1055,7 @@ static size_t mask_size(struct perf_cpu_map *map, int *max) void *cpu_map_data__alloc(struct perf_cpu_map *map, size_t *size, u16 *type, int *max) { size_t size_cpus, size_mask; - bool is_dummy = cpu_map__empty(map); + bool is_dummy = perf_cpu_map__empty(map); /* * Both array and mask data have variable size based diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 15d1046014d7..ba49b5ecffd0 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -386,7 +386,7 @@ static int perf_evlist__enable_event_thread(struct evlist *evlist, int perf_evlist__enable_event_idx(struct evlist *evlist, struct evsel *evsel, int idx) { - bool per_cpu_mmaps = !cpu_map__empty(evlist->core.cpus); + bool per_cpu_mmaps = !perf_cpu_map__empty(evlist->core.cpus); if (per_cpu_mmaps) return perf_evlist__enable_event_cpu(evlist, evsel, idx); @@ -693,7 +693,7 @@ static struct perf_mmap *perf_evlist__alloc_mmap(struct evlist *evlist, struct perf_mmap *map; evlist->nr_mmaps = perf_cpu_map__nr(evlist->core.cpus); - if (cpu_map__empty(evlist->core.cpus)) + if (perf_cpu_map__empty(evlist->core.cpus)) evlist->nr_mmaps = thread_map__nr(evlist->core.threads); map = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap)); if (!map) @@ -1018,7 +1018,7 @@ int perf_evlist__mmap_ex(struct evlist *evlist, unsigned int pages, return -ENOMEM; } - if (cpu_map__empty(cpus)) + if (perf_cpu_map__empty(cpus)) return perf_evlist__mmap_per_thread(evlist, &mp); return perf_evlist__mmap_per_cpu(evlist, &mp); diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index e59382d99196..51bbd0714e6d 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -275,7 +275,7 @@ bool perf_evlist__can_select_event(struct evlist *evlist, const char *str) evsel = perf_evlist__last(temp_evlist); - if (!evlist || cpu_map__empty(evlist->core.cpus)) { + if (!evlist || perf_cpu_map__empty(evlist->core.cpus)) { struct perf_cpu_map *cpus = perf_cpu_map__new(NULL); cpu = cpus ? cpus->map[0] : 0; diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index e4e4e3bf8b2b..2715112290cf 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -223,7 +223,7 @@ static int check_per_pkg(struct evsel *counter, if (!counter->per_pkg) return 0; - if (cpu_map__empty(cpus)) + if (perf_cpu_map__empty(cpus)) return 0; if (!mask) { -- cgit v1.2.3-59-g8ed1b From b4df75de3b3930703415aa053a269ae07c78d9b2 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 22 Aug 2019 13:11:40 +0200 Subject: libperf: Move perf's cpu_map__idx() to perf_cpu_map__idx() As an internal function that will be used by both perf and libperf, but is not exported at this point. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190822111141.25823-5-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/cpumap.c | 12 ++++++++++++ tools/perf/lib/include/internal/cpumap.h | 2 ++ tools/perf/util/cpumap.c | 14 +------------- tools/perf/util/cpumap.h | 1 - tools/perf/util/evlist.c | 2 +- 5 files changed, 16 insertions(+), 15 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/cpumap.c b/tools/perf/lib/cpumap.c index 63f7df7e47ff..2834753576b2 100644 --- a/tools/perf/lib/cpumap.c +++ b/tools/perf/lib/cpumap.c @@ -242,3 +242,15 @@ bool perf_cpu_map__empty(const struct perf_cpu_map *map) { return map ? map->map[0] == -1 : true; } + +int perf_cpu_map__idx(struct perf_cpu_map *cpus, int cpu) +{ + int i; + + for (i = 0; i < cpus->nr; ++i) { + if (cpus->map[i] == cpu) + return i; + } + + return -1; +} diff --git a/tools/perf/lib/include/internal/cpumap.h b/tools/perf/lib/include/internal/cpumap.h index 3306319f7df8..840d4032587b 100644 --- a/tools/perf/lib/include/internal/cpumap.h +++ b/tools/perf/lib/include/internal/cpumap.h @@ -14,4 +14,6 @@ struct perf_cpu_map { #define MAX_NR_CPUS 2048 #endif +int perf_cpu_map__idx(struct perf_cpu_map *cpus, int cpu); + #endif /* __LIBPERF_INTERNAL_CPUMAP_H */ diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 4402e67445a4..8e6c2cbffedc 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -458,19 +458,7 @@ int cpu__setup_cpunode_map(void) bool cpu_map__has(struct perf_cpu_map *cpus, int cpu) { - return cpu_map__idx(cpus, cpu) != -1; -} - -int cpu_map__idx(struct perf_cpu_map *cpus, int cpu) -{ - int i; - - for (i = 0; i < cpus->nr; ++i) { - if (cpus->map[i] == cpu) - return i; - } - - return -1; + return perf_cpu_map__idx(cpus, cpu) != -1; } int cpu_map__cpu(struct perf_cpu_map *cpus, int idx) diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index 3e068090612f..8dbedda7af45 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -62,5 +62,4 @@ int cpu_map__build_map(struct perf_cpu_map *cpus, struct perf_cpu_map **res, int cpu_map__cpu(struct perf_cpu_map *cpus, int idx); bool cpu_map__has(struct perf_cpu_map *cpus, int cpu); -int cpu_map__idx(struct perf_cpu_map *cpus, int cpu); #endif /* __PERF_CPUMAP_H */ diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index ba49b5ecffd0..8582560b59af 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -758,7 +758,7 @@ static int perf_evlist__mmap_per_evsel(struct evlist *evlist, int idx, if (evsel->system_wide && thread) continue; - cpu = cpu_map__idx(evsel->core.cpus, evlist_cpu); + cpu = perf_cpu_map__idx(evsel->core.cpus, evlist_cpu); if (cpu == -1) continue; -- cgit v1.2.3-59-g8ed1b From 45a2c0ccf6b96b046ad167a8c90ceaa5e59d07cb Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 22 Aug 2019 15:03:37 -0300 Subject: perf arm64: Add missing debug.h header This file uses pr_debug() but isn't including debug.h, getting it by luck, fix it. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-t7pisnsdfh88kclpw52jcwl7@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm64/util/header.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/arch/arm64/util/header.c b/tools/perf/arch/arm64/util/header.c index 602caf550e7f..e41defaaa2e6 100644 --- a/tools/perf/arch/arm64/util/header.c +++ b/tools/perf/arch/arm64/util/header.c @@ -1,6 +1,7 @@ #include #include #include +#include "debug.h" #include "header.h" #define MIDR "/regs/identification/midr_el1" -- cgit v1.2.3-59-g8ed1b From e740ca86f354038f55978c8ac7bec69b57f0c8e0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 22 Aug 2019 17:15:42 -0300 Subject: perf kvm s390: Add missing string.h header It uses strstr(), needs to include string.h or its not going to build when we remove string.h from the place it is getting from indirectly, by luck. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-72y0i0uiaqght5b83e3ae7p4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/s390/util/kvm-stat.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/arch/s390/util/kvm-stat.c b/tools/perf/arch/s390/util/kvm-stat.c index dac78441338c..0fd4e9f49ed0 100644 --- a/tools/perf/arch/s390/util/kvm-stat.c +++ b/tools/perf/arch/s390/util/kvm-stat.c @@ -7,6 +7,7 @@ */ #include +#include #include "../../util/kvm-stat.h" #include "../../util/evsel.h" #include -- cgit v1.2.3-59-g8ed1b From 0b8026e8fb0ea3893caa2f1924a2c15fcf6760b3 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 21 Aug 2019 10:54:14 -0300 Subject: perf metricgroup: Remove needless includes from metricgroup.h There we need just some struct forward declarations, do that instead and add the includes needed by metricgroup.c. That should help with needless rebuilds when changing the removed headers from metricgroup.h. Cc: Adrian Hunter Cc: Andi Kleen Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-1fkskjws6imir2hhztqhdyb0@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/metricgroup.c | 3 ++- tools/perf/util/metricgroup.h | 13 ++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index fdb0d1c5c5cf..aaf55444f81b 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -7,18 +7,19 @@ #include "metricgroup.h" #include "evlist.h" +#include "evsel.h" #include "strbuf.h" #include "pmu.h" #include "expr.h" #include "rblist.h" #include -#include #include #include "pmu-events/pmu-events.h" #include "strlist.h" #include #include #include +#include struct metric_event *metricgroup__lookup(struct rblist *metric_events, struct evsel *evsel, diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index 500e828533f8..e5092f6404ae 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -1,11 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-only #ifndef METRICGROUP_H #define METRICGROUP_H 1 -#include "linux/list.h" -#include "rblist.h" -#include -#include "evlist.h" -#include "strbuf.h" +#include +#include +#include + +struct evsel; +struct option; +struct rblist; struct metric_event { struct rb_node nd; -- cgit v1.2.3-59-g8ed1b From 7646602401e6f45e4013ddb7c41f6bc211032d02 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 21 Aug 2019 11:30:29 -0300 Subject: perf evsel: Move xyarray.h from evsel.c to evsel.h to reduce include dep tree All we need in util/evsel.h is the foward declaration of 'struct xyarray', not the internal/xyarray.h, that can be moved to util/evsel.c and then we reduce the header dependency tree. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-wwqce6ixwcyq6yzx3ljrdm80@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 1 + tools/perf/util/evsel.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 0a33f7322ecc..477c47c84971 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -39,6 +39,7 @@ #include "string2.h" #include "memswap.h" #include "util/parse-branch-options.h" +#include #include diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index efe08065838f..2928eee78427 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -8,7 +8,6 @@ #include #include #include -#include #include "symbol_conf.h" #include "cpumap.h" #include "counts.h" @@ -93,6 +92,7 @@ enum perf_tool_event { }; struct bpf_object; +struct xyarray; /** struct evsel - event selector * -- cgit v1.2.3-59-g8ed1b From 2d64ae9b85614dc0fcca68aad5da305dec44a9b1 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 21 Aug 2019 11:56:13 -0300 Subject: perf counts: Add missing headers needed for types used We get these by sheer luck, since we're cleaning unneeded headers use, this needs to be done first to avoid breakage down the line. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-p7bncbi53t4p2kobkbmu86a4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/counts.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/perf/util/counts.h b/tools/perf/util/counts.h index 13430f353c19..92196df4945f 100644 --- a/tools/perf/util/counts.h +++ b/tools/perf/util/counts.h @@ -2,8 +2,12 @@ #ifndef __PERF_COUNTS_H #define __PERF_COUNTS_H +#include #include #include +#include + +struct evsel; struct perf_counts { s8 scaled; -- cgit v1.2.3-59-g8ed1b From 964f384989585bc265fd929b2a7977b83fbe4c3b Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 21 Aug 2019 11:57:50 -0300 Subject: perf bpf: Add missing xyarray.h header This was being obtained indirectly via evsel.h -> counts.h, since we don't need xyarray in counts.h, we need to add it here explicitely before removing it from counts.h. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-jirmxg527i82yz31bwad9we7@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf-loader.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index 9c219d413e57..e20d7c5e1925 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -26,6 +26,8 @@ #include "llvm-utils.h" #include "c++/clang-c.h" +#include + static int libbpf_perf_print(enum libbpf_print_level level __attribute__((unused)), const char *fmt, va_list args) { -- cgit v1.2.3-59-g8ed1b From e14e5497d5253712e1545f79ad93309499ffb544 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 21 Aug 2019 13:58:12 -0300 Subject: perf evlist: Add missing xyarray.h header It gets it very indirectly, via evsel.h -> counts.h, and since counts.h doesn't need xyarray.h at all, add it here before we remove it there. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-hkizv6gojwfklj9ezaiiztll@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 8582560b59af..68b7c949017e 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -37,6 +37,8 @@ #include #include +#include + #ifdef LACKS_SIGQUEUE_PROTOTYPE int sigqueue(pid_t pid, int sig, const union sigval value); #endif -- cgit v1.2.3-59-g8ed1b From 0f31c0195c14cc37b2f2a08e3f4219d69faa1b34 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 21 Aug 2019 14:00:17 -0300 Subject: perf script: Add missing counts.h It is getting this via evsel.h, that don't strictly need counts.h, just forward declarations for some structs, so add it here before we remove it from there. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-q4shpvlxyjqz7val1hyrdak9@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 1764efd16cd4..e957b870869b 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -3,6 +3,7 @@ #include "perf.h" #include "util/cache.h" +#include "util/counts.h" #include "util/debug.h" #include #include "util/header.h" -- cgit v1.2.3-59-g8ed1b From e4aec1b1bdad744f3afc3ebf2b337ac1bcfa9be0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 21 Aug 2019 14:01:24 -0300 Subject: perf tests: Add missing counts.h Those are getting counts.h via evsel.h, that don't strictly need counts.h, just forward declarations for some structs, so add it here before we remove it from there. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-phldqlfxxu563txja7evd4zt@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/openat-syscall-all-cpus.c | 1 + tools/perf/tests/openat-syscall.c | 1 + 2 files changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index 8322b6aa4047..4ae4dea07466 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -16,6 +16,7 @@ #include "cpumap.h" #include "debug.h" #include "stat.h" +#include "util/counts.h" int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int subtest __maybe_unused) { diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c index f217972977e0..58df4bda5e12 100644 --- a/tools/perf/tests/openat-syscall.c +++ b/tools/perf/tests/openat-syscall.c @@ -10,6 +10,7 @@ #include "evsel.h" #include "debug.h" #include "tests.h" +#include "util/counts.h" int test__openat_syscall_event(struct test *test __maybe_unused, int subtest __maybe_unused) { -- cgit v1.2.3-59-g8ed1b From bfc49182c64e9dbdea494a577894194701b61e72 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 21 Aug 2019 14:02:05 -0300 Subject: perf stat: Add missing counts.h It is getting this via evsel.h, that don't strictly need counts.h, just forward declarations for some structs, so add it here before we remove it from there. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-jwcbm9gv9llloe3he5qkdefs@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-display.c | 1 + tools/perf/util/stat.c | 1 + 2 files changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 3df0e39ccd52..605a1fdbda7a 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -4,6 +4,7 @@ #include #include #include "color.h" +#include "counts.h" #include "evlist.h" #include "evsel.h" #include "stat.h" diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 2715112290cf..1e6a25abe00f 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -2,6 +2,7 @@ #include #include #include +#include "counts.h" #include "stat.h" #include "evlist.h" #include "evsel.h" -- cgit v1.2.3-59-g8ed1b From 430482c2e34ea8c164240ce295b5f57f16ab5621 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 21 Aug 2019 14:02:35 -0300 Subject: perf scripting python: Add missing counts.h header It is getting this via evsel.h, that don't strictly need counts.h, just forward declarations for some structs, so add it here before we remove it from there. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-6bxk3ltwkw91qcld2ot86bgg@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/scripting-engines/trace-event-python.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 32c17a727450..51771fc0d0df 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -32,6 +32,7 @@ #include #include "../../perf.h" +#include "../counts.h" #include "../debug.h" #include "../callchain.h" #include "../evsel.h" -- cgit v1.2.3-59-g8ed1b From 69714a4e3959eb051e685c6dce06c6d5a8f27c3c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 21 Aug 2019 14:09:54 -0300 Subject: perf evsel: Add missing perf/evsel.h header in util/evsel.h Since util/evsel.h uses perf_evsel__cpus() that has its prototype in libperf's perf/evsel.h file, we need it explicitely included. This was working by luck as util/evsel.h includes counts.h, but that is not necessary, just some forward declarations, so, before we remove counts.h from util/evsel.h, add what is realli needed. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-nfb9e0t4jm9zhvr0q86hc29d@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 2928eee78427..da91d6f57f44 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "symbol_conf.h" #include "cpumap.h" #include "counts.h" -- cgit v1.2.3-59-g8ed1b From ddee688a83073a9beebc5c86b67c712de5861411 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 21 Aug 2019 14:20:54 -0300 Subject: perf evsel: Remove needless counts.h header from util/evsel.h We need only a struct forward declaration, so prune the header dependency tree a bit more. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-oqvgf04w4ku8xasrz79zquim@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 1 + tools/perf/util/evsel.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 477c47c84971..7b4350681d64 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -26,6 +26,7 @@ #include "asm/bug.h" #include "callchain.h" #include "cgroup.h" +#include "counts.h" #include "event.h" #include "evsel.h" #include "evlist.h" diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index da91d6f57f44..296390541030 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -11,7 +11,6 @@ #include #include "symbol_conf.h" #include "cpumap.h" -#include "counts.h" struct evsel; @@ -93,6 +92,7 @@ enum perf_tool_event { }; struct bpf_object; +struct perf_counts; struct xyarray; /** struct evsel - event selector -- cgit v1.2.3-59-g8ed1b From a06b7f422d6a759b085ab2988d878b70e2dd0064 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 21 Aug 2019 14:24:10 -0300 Subject: perf evsel: Remove needless stddef.h from util/evsel.h We added it in 07ac002f2fcc ("perf evsel: Introduce is_group_member method") but we already ditched that function, and there was nothing else left that needed NULL nor anything else from stddef.h, ditch it. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-1zy0xfsy61x81f3fpyx5znco@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.h | 1 - 1 file changed, 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 296390541030..1f749a783d8f 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -4,7 +4,6 @@ #include #include -#include #include #include #include -- cgit v1.2.3-59-g8ed1b From 43cc5d5ecbd194a730f3045547afc1fa8e694389 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 21 Aug 2019 14:44:25 -0300 Subject: perf evsel: util/evsel.h needs stdio.h as it uses FILE And it was getting it by luck from util/cpumap.h that shouldn't be included in util/evsel.h as it only needs what is in libperf, i.e. struct cpu_map, that is in internal/cpumap.h, so add stdio.h before we fix that. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-2ywx5sl031tj3zske7c7edgv@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 1f749a783d8f..cd336cf2eaa9 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -4,6 +4,7 @@ #include #include +#include #include #include #include -- cgit v1.2.3-59-g8ed1b From 1028f96226b1f4419bd5b56c3d234a83329d4f5b Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 21 Aug 2019 14:48:57 -0300 Subject: perf x86 kvm-stat: Add missing string.h header It uses strcmp(), strstr() and was getting the required string.h header by luck, from evsel.h -> cpumap.h -> debug.h -> string.h, add the missing header. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-qrz8hhvrhwnmt5ocfwk4br5d@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/util/kvm-stat.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/arch/x86/util/kvm-stat.c b/tools/perf/arch/x86/util/kvm-stat.c index 81b531a707bf..c0775c39227f 100644 --- a/tools/perf/arch/x86/util/kvm-stat.c +++ b/tools/perf/arch/x86/util/kvm-stat.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include "../../../util/kvm-stat.h" #include "../../../util/evsel.h" #include -- cgit v1.2.3-59-g8ed1b From f7004f5990e230710112b89f2f11777e5e64e258 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 21 Aug 2019 16:39:29 -0300 Subject: perf evsel: Switch to libperf's cpumap.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't need what is in perf's util/cpumap.h, just the struct cpu_map that is in libperf's internal/cpumap.h file to cover this one case: tools/perf/util/evsel.h:215:27: error: dereferencing pointer to incomplete type ‘struct perf_cpu_map’ 215 | return evsel__cpus(evsel)->nr; So switch to libperf's cpumap.h and add some missing struct foward declarations and include sys/types.h to get pid_t. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-ufjkpohijti05ggk69s91ktf@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index cd336cf2eaa9..5a351cae66df 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -5,14 +5,17 @@ #include #include #include +#include #include #include #include #include #include "symbol_conf.h" -#include "cpumap.h" +#include +struct addr_location; struct evsel; +union perf_event; /* * Per fd, to map back from PERF_SAMPLE_ID to evsel, only used when there are -- cgit v1.2.3-59-g8ed1b From 5e51b0bb245d963f5ce750256c504be95201e38c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 22 Aug 2019 10:48:31 -0300 Subject: perf cpumap: Remove needless includes from cpumap.h The util/cpumap.h file doesn't use anything in refcount.h not in debug.h, it needs just a forward reference to 'struct cpu_map_data', that is defined in util/event.h and cpumap.h was getting indirectly via, of all things, debug.h Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-mtjww98yptt4ppo6g2blavg5@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/util/header.c | 1 + tools/perf/tests/mem2node.c | 1 + tools/perf/util/cpumap.c | 2 ++ tools/perf/util/cpumap.h | 4 ++-- tools/perf/util/cputopo.c | 2 ++ tools/perf/util/env.c | 1 + tools/perf/util/mem2node.c | 1 + tools/perf/util/pmu.c | 1 + tools/perf/util/svghelper.c | 1 + 9 files changed, 12 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/x86/util/header.c b/tools/perf/arch/x86/util/header.c index af9a9f2600be..662ecf84a421 100644 --- a/tools/perf/arch/x86/util/header.c +++ b/tools/perf/arch/x86/util/header.c @@ -6,6 +6,7 @@ #include #include +#include "../../util/debug.h" #include "../../util/header.h" static inline void diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c index 5ec193f7968d..73b2855acaf4 100644 --- a/tools/perf/tests/mem2node.c +++ b/tools/perf/tests/mem2node.c @@ -4,6 +4,7 @@ #include #include #include "cpumap.h" +#include "debug.h" #include "mem2node.h" #include "tests.h" diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 8e6c2cbffedc..f5c21184e1fc 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -2,6 +2,8 @@ #include #include "../perf.h" #include "cpumap.h" +#include "debug.h" +#include "event.h" #include #include #include diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index 8dbedda7af45..d0c5bbfd91af 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -4,12 +4,12 @@ #include #include -#include #include #include #include "perf.h" -#include "util/debug.h" + +struct cpu_map_data; struct perf_cpu_map *perf_cpu_map__empty_new(int nr); struct perf_cpu_map *cpu_map__new_data(struct cpu_map_data *data); diff --git a/tools/perf/util/cputopo.c b/tools/perf/util/cputopo.c index 4f70155eaf83..1b52402a8923 100644 --- a/tools/perf/util/cputopo.c +++ b/tools/perf/util/cputopo.c @@ -3,12 +3,14 @@ #include #include #include +#include #include #include #include #include "cputopo.h" #include "cpumap.h" +#include "debug.h" #include "env.h" #define CORE_SIB_FMT \ diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c index d77912b2b5e7..571efb4f0351 100644 --- a/tools/perf/util/env.c +++ b/tools/perf/util/env.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "cpumap.h" +#include "debug.h" #include "env.h" #include #include diff --git a/tools/perf/util/mem2node.c b/tools/perf/util/mem2node.c index cacc2fc4dcbd..14fb9e72aeeb 100644 --- a/tools/perf/util/mem2node.c +++ b/tools/perf/util/mem2node.c @@ -2,6 +2,7 @@ #include #include #include +#include "debug.h" #include "mem2node.h" struct phys_entry { diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index b7da21a7d627..9807be6f09bb 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -16,6 +16,7 @@ #include #include #include +#include "debug.h" #include "pmu.h" #include "parse-events.h" #include "cpumap.h" diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index ae6a534a7a80..bbdd87163285 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3-59-g8ed1b From a2f354e3abb853f9a40048829e1f839e8f7fada5 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 22 Aug 2019 13:11:41 +0200 Subject: libperf: Add perf_thread_map__nr/perf_thread_map__pid functions So it's part of libperf library as basic functions operating on perf_thread_map objects. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190822111141.25823-6-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-ftrace.c | 2 +- tools/perf/builtin-script.c | 4 ++-- tools/perf/builtin-stat.c | 4 ++-- tools/perf/builtin-trace.c | 4 ++-- tools/perf/lib/include/perf/threadmap.h | 2 ++ tools/perf/lib/libperf.map | 2 ++ tools/perf/lib/threadmap.c | 10 ++++++++++ tools/perf/tests/thread-map.c | 6 +++--- tools/perf/util/auxtrace.c | 4 ++-- tools/perf/util/event.c | 8 ++++---- tools/perf/util/evlist.c | 12 ++++++------ tools/perf/util/evsel.c | 4 ++-- tools/perf/util/scripting-engines/trace-event-python.c | 2 +- tools/perf/util/stat-display.c | 4 ++-- tools/perf/util/stat.c | 4 ++-- tools/perf/util/thread_map.c | 4 ++-- tools/perf/util/thread_map.h | 10 ---------- 17 files changed, 45 insertions(+), 41 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 1367bb5046a7..565db782c1b9 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -158,7 +158,7 @@ static int set_tracing_pid(struct perf_ftrace *ftrace) if (target__has_cpu(&ftrace->target)) return 0; - for (i = 0; i < thread_map__nr(ftrace->evlist->core.threads); i++) { + for (i = 0; i < perf_thread_map__nr(ftrace->evlist->core.threads); i++) { scnprintf(buf, sizeof(buf), "%d", ftrace->evlist->core.threads->map[i]); if (append_tracing_file("set_ftrace_pid", buf) < 0) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index e957b870869b..9b93ddeaeafa 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1906,7 +1906,7 @@ static struct scripting_ops *scripting_ops; static void __process_stat(struct evsel *counter, u64 tstamp) { - int nthreads = thread_map__nr(counter->core.threads); + int nthreads = perf_thread_map__nr(counter->core.threads); int ncpus = perf_evsel__nr_cpus(counter); int cpu, thread; static int header_printed; @@ -1928,7 +1928,7 @@ static void __process_stat(struct evsel *counter, u64 tstamp) printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n", counter->core.cpus->map[cpu], - thread_map__pid(counter->core.threads, thread), + perf_thread_map__pid(counter->core.threads, thread), counts->val, counts->ena, counts->run, diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 90636a811b36..8a4f1a7d0cba 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -264,7 +264,7 @@ static int read_single_counter(struct evsel *counter, int cpu, */ static int read_counter(struct evsel *counter, struct timespec *rs) { - int nthreads = thread_map__nr(evsel_list->core.threads); + int nthreads = perf_thread_map__nr(evsel_list->core.threads); int ncpus, cpu, thread; if (target__has_cpu(&target) && !target__has_per_thread(&target)) @@ -1893,7 +1893,7 @@ int cmd_stat(int argc, const char **argv) thread_map__read_comms(evsel_list->core.threads); if (target.system_wide) { if (runtime_stat_new(&stat_config, - thread_map__nr(evsel_list->core.threads))) { + perf_thread_map__nr(evsel_list->core.threads))) { goto out; } } diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index bc44ed29e05a..de126258ca10 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3188,7 +3188,7 @@ static int trace__set_filter_pids(struct trace *trace) err = bpf_map__set_filter_pids(trace->filter_pids.map, trace->filter_pids.nr, trace->filter_pids.entries); } - } else if (thread_map__pid(trace->evlist->core.threads, 0) == -1) { + } else if (perf_thread_map__pid(trace->evlist->core.threads, 0) == -1) { err = trace__set_filter_loop_pids(trace); } @@ -3417,7 +3417,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) evlist__enable(evlist); } - trace->multiple_threads = thread_map__pid(evlist->core.threads, 0) == -1 || + trace->multiple_threads = perf_thread_map__pid(evlist->core.threads, 0) == -1 || evlist->core.threads->nr > 1 || perf_evlist__first(evlist)->core.attr.inherit; diff --git a/tools/perf/lib/include/perf/threadmap.h b/tools/perf/lib/include/perf/threadmap.h index 456295273daa..a7c50de8d010 100644 --- a/tools/perf/lib/include/perf/threadmap.h +++ b/tools/perf/lib/include/perf/threadmap.h @@ -11,6 +11,8 @@ LIBPERF_API struct perf_thread_map *perf_thread_map__new_dummy(void); LIBPERF_API void perf_thread_map__set_pid(struct perf_thread_map *map, int thread, pid_t pid); LIBPERF_API char *perf_thread_map__comm(struct perf_thread_map *map, int thread); +LIBPERF_API int perf_thread_map__nr(struct perf_thread_map *threads); +LIBPERF_API pid_t perf_thread_map__pid(struct perf_thread_map *map, int thread); LIBPERF_API struct perf_thread_map *perf_thread_map__get(struct perf_thread_map *map); LIBPERF_API void perf_thread_map__put(struct perf_thread_map *map); diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 3373dd51fcda..dc4d66363bc4 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -12,6 +12,8 @@ LIBPERF_0.0.1 { perf_thread_map__new_dummy; perf_thread_map__set_pid; perf_thread_map__comm; + perf_thread_map__nr; + perf_thread_map__pid; perf_thread_map__get; perf_thread_map__put; perf_evsel__new; diff --git a/tools/perf/lib/threadmap.c b/tools/perf/lib/threadmap.c index 4865b73e2586..e92c368b0a6c 100644 --- a/tools/perf/lib/threadmap.c +++ b/tools/perf/lib/threadmap.c @@ -79,3 +79,13 @@ void perf_thread_map__put(struct perf_thread_map *map) if (map && refcount_dec_and_test(&map->refcnt)) perf_thread_map__delete(map); } + +int perf_thread_map__nr(struct perf_thread_map *threads) +{ + return threads ? threads->nr : 1; +} + +pid_t perf_thread_map__pid(struct perf_thread_map *map, int thread) +{ + return map->map[thread].pid; +} diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c index d61773cacf0b..d803eafedc60 100644 --- a/tools/perf/tests/thread-map.c +++ b/tools/perf/tests/thread-map.c @@ -26,7 +26,7 @@ int test__thread_map(struct test *test __maybe_unused, int subtest __maybe_unuse TEST_ASSERT_VAL("wrong nr", map->nr == 1); TEST_ASSERT_VAL("wrong pid", - thread_map__pid(map, 0) == getpid()); + perf_thread_map__pid(map, 0) == getpid()); TEST_ASSERT_VAL("wrong comm", perf_thread_map__comm(map, 0) && !strcmp(perf_thread_map__comm(map, 0), NAME)); @@ -41,7 +41,7 @@ int test__thread_map(struct test *test __maybe_unused, int subtest __maybe_unuse thread_map__read_comms(map); TEST_ASSERT_VAL("wrong nr", map->nr == 1); - TEST_ASSERT_VAL("wrong pid", thread_map__pid(map, 0) == -1); + TEST_ASSERT_VAL("wrong pid", perf_thread_map__pid(map, 0) == -1); TEST_ASSERT_VAL("wrong comm", perf_thread_map__comm(map, 0) && !strcmp(perf_thread_map__comm(map, 0), "dummy")); @@ -68,7 +68,7 @@ static int process_event(struct perf_tool *tool __maybe_unused, TEST_ASSERT_VAL("wrong nr", threads->nr == 1); TEST_ASSERT_VAL("wrong pid", - thread_map__pid(threads, 0) == getpid()); + perf_thread_map__pid(threads, 0) == getpid()); TEST_ASSERT_VAL("wrong comm", perf_thread_map__comm(threads, 0) && !strcmp(perf_thread_map__comm(threads, 0), NAME)); diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 60428576426e..094e6ceb3cf2 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -132,12 +132,12 @@ void auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp, if (per_cpu) { mp->cpu = evlist->core.cpus->map[idx]; if (evlist->core.threads) - mp->tid = thread_map__pid(evlist->core.threads, 0); + mp->tid = perf_thread_map__pid(evlist->core.threads, 0); else mp->tid = -1; } else { mp->cpu = -1; - mp->tid = thread_map__pid(evlist->core.threads, idx); + mp->tid = perf_thread_map__pid(evlist->core.threads, idx); } } diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index f433da85c45e..332edef8d394 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -647,7 +647,7 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool, for (thread = 0; thread < threads->nr; ++thread) { if (__event__synthesize_thread(comm_event, mmap_event, fork_event, namespaces_event, - thread_map__pid(threads, thread), 0, + perf_thread_map__pid(threads, thread), 0, process, tool, machine, mmap_data)) { err = -1; @@ -658,12 +658,12 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool, * comm.pid is set to thread group id by * perf_event__synthesize_comm */ - if ((int) comm_event->comm.pid != thread_map__pid(threads, thread)) { + if ((int) comm_event->comm.pid != perf_thread_map__pid(threads, thread)) { bool need_leader = true; /* is thread group leader in thread_map? */ for (j = 0; j < threads->nr; ++j) { - if ((int) comm_event->comm.pid == thread_map__pid(threads, j)) { + if ((int) comm_event->comm.pid == perf_thread_map__pid(threads, j)) { need_leader = false; break; } @@ -997,7 +997,7 @@ int perf_event__synthesize_thread_map2(struct perf_tool *tool, if (!comm) comm = (char *) ""; - entry->pid = thread_map__pid(threads, i); + entry->pid = perf_thread_map__pid(threads, i); strncpy((char *) &entry->comm, comm, sizeof(entry->comm)); } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 68b7c949017e..ff415680fe0a 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -316,7 +316,7 @@ static int perf_evlist__nr_threads(struct evlist *evlist, if (evsel->system_wide) return 1; else - return thread_map__nr(evlist->core.threads); + return perf_thread_map__nr(evlist->core.threads); } void evlist__disable(struct evlist *evlist) @@ -399,7 +399,7 @@ int perf_evlist__enable_event_idx(struct evlist *evlist, int perf_evlist__alloc_pollfd(struct evlist *evlist) { int nr_cpus = perf_cpu_map__nr(evlist->core.cpus); - int nr_threads = thread_map__nr(evlist->core.threads); + int nr_threads = perf_thread_map__nr(evlist->core.threads); int nfds = 0; struct evsel *evsel; @@ -531,7 +531,7 @@ static void perf_evlist__set_sid_idx(struct evlist *evlist, else sid->cpu = -1; if (!evsel->system_wide && evlist->core.threads && thread >= 0) - sid->tid = thread_map__pid(evlist->core.threads, thread); + sid->tid = perf_thread_map__pid(evlist->core.threads, thread); else sid->tid = -1; } @@ -696,7 +696,7 @@ static struct perf_mmap *perf_evlist__alloc_mmap(struct evlist *evlist, evlist->nr_mmaps = perf_cpu_map__nr(evlist->core.cpus); if (perf_cpu_map__empty(evlist->core.cpus)) - evlist->nr_mmaps = thread_map__nr(evlist->core.threads); + evlist->nr_mmaps = perf_thread_map__nr(evlist->core.threads); map = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap)); if (!map) return NULL; @@ -810,7 +810,7 @@ static int perf_evlist__mmap_per_cpu(struct evlist *evlist, { int cpu, thread; int nr_cpus = perf_cpu_map__nr(evlist->core.cpus); - int nr_threads = thread_map__nr(evlist->core.threads); + int nr_threads = perf_thread_map__nr(evlist->core.threads); pr_debug2("perf event ring buffer mmapped per cpu\n"); for (cpu = 0; cpu < nr_cpus; cpu++) { @@ -838,7 +838,7 @@ static int perf_evlist__mmap_per_thread(struct evlist *evlist, struct mmap_params *mp) { int thread; - int nr_threads = thread_map__nr(evlist->core.threads); + int nr_threads = perf_thread_map__nr(evlist->core.threads); pr_debug2("perf event ring buffer mmapped per thread\n"); for (thread = 0; thread < nr_threads; thread++) { diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 7b4350681d64..e983e721beca 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1653,7 +1653,7 @@ static bool ignore_missing_thread(struct evsel *evsel, struct perf_thread_map *threads, int thread, int err) { - pid_t ignore_pid = thread_map__pid(threads, thread); + pid_t ignore_pid = perf_thread_map__pid(threads, thread); if (!evsel->ignore_missing_thread) return false; @@ -1816,7 +1816,7 @@ retry_sample_id: int fd, group_fd; if (!evsel->cgrp && !evsel->system_wide) - pid = thread_map__pid(threads, thread); + pid = perf_thread_map__pid(threads, thread); group_fd = get_group_fd(evsel, cpu, thread); retry_open: diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 51771fc0d0df..78c8bc9380bd 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -1406,7 +1406,7 @@ static void python_process_stat(struct perf_stat_config *config, for (thread = 0; thread < threads->nr; thread++) { for (cpu = 0; cpu < cpus->nr; cpu++) { process_stat(counter, cpus->map[cpu], - thread_map__pid(threads, thread), tstamp, + perf_thread_map__pid(threads, thread), tstamp, perf_counts(counter->counts, cpu, thread)); } } diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 605a1fdbda7a..51d6781aa90d 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -119,7 +119,7 @@ static void aggr_printout(struct perf_stat_config *config, config->csv_output ? 0 : 16, perf_thread_map__comm(evsel->core.threads, id), config->csv_output ? 0 : -8, - thread_map__pid(evsel->core.threads, id), + perf_thread_map__pid(evsel->core.threads, id), config->csv_sep); break; case AGGR_GLOBAL: @@ -745,7 +745,7 @@ static void print_aggr_thread(struct perf_stat_config *config, struct evsel *counter, char *prefix) { FILE *output = config->output; - int nthreads = thread_map__nr(counter->core.threads); + int nthreads = perf_thread_map__nr(counter->core.threads); int ncpus = perf_cpu_map__nr(counter->core.cpus); int thread, sorted_threads, id; struct perf_aggr_thread_value *buf; diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 1e6a25abe00f..0cbfd1eca1dd 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -159,7 +159,7 @@ static void perf_evsel__free_prev_raw_counts(struct evsel *evsel) static int perf_evsel__alloc_stats(struct evsel *evsel, bool alloc_raw) { int ncpus = perf_evsel__nr_cpus(evsel); - int nthreads = thread_map__nr(evsel->core.threads); + int nthreads = perf_thread_map__nr(evsel->core.threads); if (perf_evsel__alloc_stat_priv(evsel) < 0 || perf_evsel__alloc_counts(evsel, ncpus, nthreads) < 0 || @@ -309,7 +309,7 @@ process_counter_values(struct perf_stat_config *config, struct evsel *evsel, static int process_counter_maps(struct perf_stat_config *config, struct evsel *counter) { - int nthreads = thread_map__nr(counter->core.threads); + int nthreads = perf_thread_map__nr(counter->core.threads); int ncpus = perf_evsel__nr_cpus(counter); int cpu, thread; diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index c58385ea05be..3e64525bf604 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c @@ -310,7 +310,7 @@ size_t thread_map__fprintf(struct perf_thread_map *threads, FILE *fp) size_t printed = fprintf(fp, "%d thread%s: ", threads->nr, threads->nr > 1 ? "s" : ""); for (i = 0; i < threads->nr; ++i) - printed += fprintf(fp, "%s%d", i ? ", " : "", thread_map__pid(threads, i)); + printed += fprintf(fp, "%s%d", i ? ", " : "", perf_thread_map__pid(threads, i)); return printed + fprintf(fp, "\n"); } @@ -341,7 +341,7 @@ static int get_comm(char **comm, pid_t pid) static void comm_init(struct perf_thread_map *map, int i) { - pid_t pid = thread_map__pid(map, i); + pid_t pid = perf_thread_map__pid(map, i); char *comm = NULL; /* dummy pid comm initialization */ diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h index ba45c760be72..ca165fdf6cb0 100644 --- a/tools/perf/util/thread_map.h +++ b/tools/perf/util/thread_map.h @@ -25,16 +25,6 @@ struct perf_thread_map *thread_map__new_by_tid_str(const char *tid_str); size_t thread_map__fprintf(struct perf_thread_map *threads, FILE *fp); -static inline int thread_map__nr(struct perf_thread_map *threads) -{ - return threads ? threads->nr : 1; -} - -static inline pid_t thread_map__pid(struct perf_thread_map *map, int thread) -{ - return map->map[thread].pid; -} - void thread_map__read_comms(struct perf_thread_map *threads); bool thread_map__has(struct perf_thread_map *threads, pid_t pid); int thread_map__remove(struct perf_thread_map *threads, int idx); -- cgit v1.2.3-59-g8ed1b From 1ea770f6c1971bc101b3741f4d88b0b4ea5c4181 Mon Sep 17 00:00:00 2001 From: Ravi Bangoria Date: Thu, 22 Aug 2019 14:20:45 +0530 Subject: perf c2c: Fix report with offline cpus If c2c is recorded on a machine where any cpus are offline, 'perf c2c report' throws an error "node/cpu topology bugFailed setup nodes". It fails because while preparing node-cpu mapping we don't consider offline cpus. Reported-by: Nageswara R Sastry Signed-off-by: Ravi Bangoria Acked-by: Jiri Olsa Fixes: 1e181b92a2da ("perf c2c report: Add 'node' sort key") Link: http://lkml.kernel.org/r/20190822085045.25108-1-ravi.bangoria@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-c2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index 01629f5b6d1f..211143720078 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -2027,7 +2027,7 @@ static int setup_nodes(struct perf_session *session) c2c.node_info = 2; c2c.nodes_cnt = session->header.env.nr_numa_nodes; - c2c.cpus_cnt = session->header.env.nr_cpus_online; + c2c.cpus_cnt = session->header.env.nr_cpus_avail; n = session->header.env.numa_nodes; if (!n) -- cgit v1.2.3-59-g8ed1b From d9c5c083416500e95da098c01be092b937def7fa Mon Sep 17 00:00:00 2001 From: Gerald BAEZA Date: Thu, 22 Aug 2019 09:07:01 +0000 Subject: libperf: Fix alignment trap with xyarray contents in 'perf stat' Following the patch 'perf stat: Fix --no-scale', an alignment trap happens in process_counter_values() on ARMv7 platforms due to the attempt to copy non 64 bits aligned double words (pointed by 'count') via a NEON vectored instruction ('vld1' with 64 bits alignment constraint). This patch sets a 64 bits alignment constraint on 'contents[]' field in 'struct xyarray' since the 'count' pointer used above points to such a structure. Signed-off-by: Gerald Baeza Cc: Alexander Shishkin Cc: Alexandre Torgue Cc: Andi Kleen Cc: Jiri Olsa Cc: Mathieu Poirier Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1566464769-16374-1-git-send-email-gerald.baeza@st.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/internal/xyarray.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/lib/include/internal/xyarray.h b/tools/perf/lib/include/internal/xyarray.h index 3bf70e4d474c..51e35d6c8ec4 100644 --- a/tools/perf/lib/include/internal/xyarray.h +++ b/tools/perf/lib/include/internal/xyarray.h @@ -2,6 +2,7 @@ #ifndef __LIBPERF_INTERNAL_XYARRAY_H #define __LIBPERF_INTERNAL_XYARRAY_H +#include #include struct xyarray { @@ -10,7 +11,7 @@ struct xyarray { size_t entries; size_t max_x; size_t max_y; - char contents[]; + char contents[] __aligned(8); }; struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size); -- cgit v1.2.3-59-g8ed1b From 71e90b4654a9298f9e2375cc733d57b8bf92ce73 Mon Sep 17 00:00:00 2001 From: Daniel Rosenberg Date: Tue, 23 Jul 2019 16:05:27 -0700 Subject: fs: Reserve flag for casefolding In preparation for including the casefold feature within f2fs, elevate the EXT4_CASEFOLD_FL flag to FS_CASEFOLD_FL. Signed-off-by: Daniel Rosenberg Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- include/uapi/linux/fs.h | 1 + tools/include/uapi/linux/fs.h | 1 + 2 files changed, 2 insertions(+) (limited to 'tools') diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index 59c71fa8c553..2a616aa3f686 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -311,6 +311,7 @@ struct fscrypt_key { #define FS_NOCOW_FL 0x00800000 /* Do not cow file */ #define FS_INLINE_DATA_FL 0x10000000 /* Reserved for ext4 */ #define FS_PROJINHERIT_FL 0x20000000 /* Create with parents projid */ +#define FS_CASEFOLD_FL 0x40000000 /* Folder is case insensitive */ #define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */ #define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ diff --git a/tools/include/uapi/linux/fs.h b/tools/include/uapi/linux/fs.h index 59c71fa8c553..2a616aa3f686 100644 --- a/tools/include/uapi/linux/fs.h +++ b/tools/include/uapi/linux/fs.h @@ -311,6 +311,7 @@ struct fscrypt_key { #define FS_NOCOW_FL 0x00800000 /* Do not cow file */ #define FS_INLINE_DATA_FL 0x10000000 /* Reserved for ext4 */ #define FS_PROJINHERIT_FL 0x20000000 /* Create with parents projid */ +#define FS_CASEFOLD_FL 0x40000000 /* Folder is case insensitive */ #define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */ #define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ -- cgit v1.2.3-59-g8ed1b From 9d535e200f09ce347afc38c81ec7f2901187e5f0 Mon Sep 17 00:00:00 2001 From: Gustavo Romero Date: Wed, 14 Aug 2019 15:52:11 -0500 Subject: selftests/powerpc: Fix and enhance TM signal context tests Currently TM signal context tests for GPR, FPR, VMX, and VSX registers print wrong register numbers (wrongly starting from register 0 instead of the first register in the non-volatile subset). Besides it the output when a mismatch happens is poor giving not much information about which context and which register mismatches, because it prints both contexts at the same time and not a comparison between the value that mismatches and the value expected and, moreover, it stops printing on the first mismatch, but it's important to know if there are other mismatches happening beyond the first one. For instance, this is the current output when a mismatch happens: test: tm_signal_context_chk_gpr tags: git_version:v5.2-8249-g02e970fae465-dirty Failed on 0 GPR 1 or 18446744073709551615 failure: tm_signal_context_chk_gpr test: tm_signal_context_chk_fpu tags: git_version:v5.2-8248-g09c289e3ef80 Failed on 0 FP -1 or -1 failure: tm_signal_context_chk_fpu test: tm_signal_context_chk_vmx tags: git_version:v5.2-8248-g09c289e3ef80 Failed on 0 vmx 0xfffffffffffffffefffffffdfffffffc vs 0xfffffffffffffffefffffffdfffffffc failure: tm_signal_context_chk_vmx test: tm_signal_context_chk_vsx tags: git_version:v5.2-8248-g09c289e3ef80 Failed on 0 vsx 0xfffffffffefffffffdfffffffcffffff vs 0xfffffffffefffffffdfffffffcffffff failure: tm_signal_context_chk_vsx This commit fixes the register numbers printed and enhances the error output by providing a full list of mismatching registers separated by the context (non-speculative or speculative context), for example: test: tm_signal_context_chk_gpr tags: git_version:v5.2-8249-g02e970fae465-dirty GPR14 (1st context) == 1 instead of -1 (expected) GPR15 (1st context) == 2 instead of -2 (expected) GPR14 (2nd context) == 0 instead of 18446744073709551615 (expected) GPR15 (2nd context) == 0 instead of 18446744073709551614 (expected) failure: tm_signal_context_chk_gpr test: tm_signal_context_chk_fpu tags: git_version:v5.2-8249-g02e970fae465-dirty FPR14 (1st context) == -1 instead of 1 (expected) FPR15 (1st context) == -2 instead of 2 (expected) failure: tm_signal_context_chk_fpu test: tm_signal_context_chk_vmx tags: git_version:v5.2-8249-g02e970fae465-dirty VMX20 (1st context) == 0xfffffffffffffffefffffffdfffffffc instead of 0x00000001000000020000000300000004 (expected) VMX21 (1st context) == 0xfffffffbfffffffafffffff9fffffff8 instead of 0x00000005000000060000000700000008 (expected) failure: tm_signal_context_chk_vmx test: tm_signal_context_chk_vsx tags: git_version:v5.2-8249-g02e970fae465-dirty VSX20 (1st context) == 0xfffffffffefffffffdfffffffcffffff instead of 0x00000001000000020000000300000004 (expected) VSX21 (1st context) == 0xfbfffffffafffffff9fffffff8ffffff instead of 0x00000005000000060000000700000008 (expected) failure: tm_signal_context_chk_vsx Finally, this commit adds comments to the tests in the hope that it will help people not so familiar with TM understand the tests. Signed-off-by: Gustavo Romero Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20190814205211.24840-1-gromero@linux.ibm.com --- .../powerpc/tm/tm-signal-context-chk-fpu.c | 49 +++++--- .../powerpc/tm/tm-signal-context-chk-gpr.c | 59 +++++++--- .../powerpc/tm/tm-signal-context-chk-vmx.c | 74 ++++++++---- .../powerpc/tm/tm-signal-context-chk-vsx.c | 130 +++++++++++++++------ 4 files changed, 228 insertions(+), 84 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/tm/tm-signal-context-chk-fpu.c b/tools/testing/selftests/powerpc/tm/tm-signal-context-chk-fpu.c index d57c2d2ab6ec..254f912ad611 100644 --- a/tools/testing/selftests/powerpc/tm/tm-signal-context-chk-fpu.c +++ b/tools/testing/selftests/powerpc/tm/tm-signal-context-chk-fpu.c @@ -5,10 +5,11 @@ * Test the kernel's signal frame code. * * The kernel sets up two sets of ucontexts if the signal was to be - * delivered while the thread was in a transaction. + * delivered while the thread was in a transaction (referred too as + * first and second contexts). * Expected behaviour is that the checkpointed state is in the user - * context passed to the signal handler. The speculated state can be - * accessed with the uc_link pointer. + * context passed to the signal handler (first context). The speculated + * state can be accessed with the uc_link pointer (second context). * * The rationale for this is that if TM unaware code (which linked * against TM libs) installs a signal handler it will not know of the @@ -28,17 +29,20 @@ #define MAX_ATTEMPT 500000 -#define NV_FPU_REGS 18 +#define NV_FPU_REGS 18 /* Number of non-volatile FP registers */ +#define FPR14 14 /* First non-volatile FP register to check in f14-31 subset */ long tm_signal_self_context_load(pid_t pid, long *gprs, double *fps, vector int *vms, vector int *vss); -/* Be sure there are 2x as many as there are NV FPU regs (2x18) */ +/* Test only non-volatile registers, i.e. 18 fpr registers from f14 to f31 */ static double fps[] = { + /* First context will be set with these values, i.e. non-speculative */ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + /* Second context will be set with these values, i.e. speculative */ -1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18 }; -static sig_atomic_t fail; +static sig_atomic_t fail, broken; static void signal_usr1(int signum, siginfo_t *info, void *uc) { @@ -46,11 +50,24 @@ static void signal_usr1(int signum, siginfo_t *info, void *uc) ucontext_t *ucp = uc; ucontext_t *tm_ucp = ucp->uc_link; - for (i = 0; i < NV_FPU_REGS && !fail; i++) { - fail = (ucp->uc_mcontext.fp_regs[i + 14] != fps[i]); - fail |= (tm_ucp->uc_mcontext.fp_regs[i + 14] != fps[i + NV_FPU_REGS]); - if (fail) - printf("Failed on %d FP %g or %g\n", i, ucp->uc_mcontext.fp_regs[i + 14], tm_ucp->uc_mcontext.fp_regs[i + 14]); + for (i = 0; i < NV_FPU_REGS; i++) { + /* Check first context. Print all mismatches. */ + fail = (ucp->uc_mcontext.fp_regs[FPR14 + i] != fps[i]); + if (fail) { + broken = 1; + printf("FPR%d (1st context) == %g instead of %g (expected)\n", + FPR14 + i, ucp->uc_mcontext.fp_regs[FPR14 + i], fps[i]); + } + } + + for (i = 0; i < NV_FPU_REGS; i++) { + /* Check second context. Print all mismatches. */ + fail = (tm_ucp->uc_mcontext.fp_regs[FPR14 + i] != fps[NV_FPU_REGS + i]); + if (fail) { + broken = 1; + printf("FPR%d (2nd context) == %g instead of %g (expected)\n", + FPR14 + i, tm_ucp->uc_mcontext.fp_regs[FPR14 + i], fps[NV_FPU_REGS + i]); + } } } @@ -72,13 +89,19 @@ static int tm_signal_context_chk_fpu() } i = 0; - while (i < MAX_ATTEMPT && !fail) { + while (i < MAX_ATTEMPT && !broken) { + /* + * tm_signal_self_context_load will set both first and second + * contexts accordingly to the values passed through non-NULL + * array pointers to it, in that case 'fps', and invoke the + * signal handler installed for SIGUSR1. + */ rc = tm_signal_self_context_load(pid, NULL, fps, NULL, NULL); FAIL_IF(rc != pid); i++; } - return fail; + return (broken); } int main(void) diff --git a/tools/testing/selftests/powerpc/tm/tm-signal-context-chk-gpr.c b/tools/testing/selftests/powerpc/tm/tm-signal-context-chk-gpr.c index 4d05f8b0254c..0cc680f61828 100644 --- a/tools/testing/selftests/powerpc/tm/tm-signal-context-chk-gpr.c +++ b/tools/testing/selftests/powerpc/tm/tm-signal-context-chk-gpr.c @@ -5,10 +5,11 @@ * Test the kernel's signal frame code. * * The kernel sets up two sets of ucontexts if the signal was to be - * delivered while the thread was in a transaction. + * delivered while the thread was in a transaction (referred too as + * first and second contexts). * Expected behaviour is that the checkpointed state is in the user - * context passed to the signal handler. The speculated state can be - * accessed with the uc_link pointer. + * context passed to the signal handler (first context). The speculated + * state can be accessed with the uc_link pointer (second context). * * The rationale for this is that if TM unaware code (which linked * against TM libs) installs a signal handler it will not know of the @@ -28,14 +29,22 @@ #define MAX_ATTEMPT 500000 -#define NV_GPR_REGS 18 +#define NV_GPR_REGS 18 /* Number of non-volatile GPR registers */ +#define R14 14 /* First non-volatile register to check in r14-r31 subset */ long tm_signal_self_context_load(pid_t pid, long *gprs, double *fps, vector int *vms, vector int *vss); -static sig_atomic_t fail; +static sig_atomic_t fail, broken; -static long gps[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - -1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18}; +/* Test only non-volatile general purpose registers, i.e. r14-r31 */ +static long gprs[] = { + /* First context will be set with these values, i.e. non-speculative */ + /* R14, R15, ... */ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + /* Second context will be set with these values, i.e. speculative */ + /* R14, R15, ... */ + -1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18 +}; static void signal_usr1(int signum, siginfo_t *info, void *uc) { @@ -43,12 +52,24 @@ static void signal_usr1(int signum, siginfo_t *info, void *uc) ucontext_t *ucp = uc; ucontext_t *tm_ucp = ucp->uc_link; - for (i = 0; i < NV_GPR_REGS && !fail; i++) { - fail = (ucp->uc_mcontext.gp_regs[i + 14] != gps[i]); - fail |= (tm_ucp->uc_mcontext.gp_regs[i + 14] != gps[i + NV_GPR_REGS]); - if (fail) - printf("Failed on %d GPR %lu or %lu\n", i, - ucp->uc_mcontext.gp_regs[i + 14], tm_ucp->uc_mcontext.gp_regs[i + 14]); + /* Check first context. Print all mismatches. */ + for (i = 0; i < NV_GPR_REGS; i++) { + fail = (ucp->uc_mcontext.gp_regs[R14 + i] != gprs[i]); + if (fail) { + broken = 1; + printf("GPR%d (1st context) == %lu instead of %lu (expected)\n", + R14 + i, ucp->uc_mcontext.gp_regs[R14 + i], gprs[i]); + } + } + + /* Check second context. Print all mismatches. */ + for (i = 0; i < NV_GPR_REGS; i++) { + fail = (tm_ucp->uc_mcontext.gp_regs[R14 + i] != gprs[NV_GPR_REGS + i]); + if (fail) { + broken = 1; + printf("GPR%d (2nd context) == %lu instead of %lu (expected)\n", + R14 + i, tm_ucp->uc_mcontext.gp_regs[R14 + i], gprs[NV_GPR_REGS + i]); + } } } @@ -70,13 +91,19 @@ static int tm_signal_context_chk_gpr() } i = 0; - while (i < MAX_ATTEMPT && !fail) { - rc = tm_signal_self_context_load(pid, gps, NULL, NULL, NULL); + while (i < MAX_ATTEMPT && !broken) { + /* + * tm_signal_self_context_load will set both first and second + * contexts accordingly to the values passed through non-NULL + * array pointers to it, in that case 'gprs', and invoke the + * signal handler installed for SIGUSR1. + */ + rc = tm_signal_self_context_load(pid, gprs, NULL, NULL, NULL); FAIL_IF(rc != pid); i++; } - return fail; + return broken; } int main(void) diff --git a/tools/testing/selftests/powerpc/tm/tm-signal-context-chk-vmx.c b/tools/testing/selftests/powerpc/tm/tm-signal-context-chk-vmx.c index 48ad01499b1a..b6d52730a0d8 100644 --- a/tools/testing/selftests/powerpc/tm/tm-signal-context-chk-vmx.c +++ b/tools/testing/selftests/powerpc/tm/tm-signal-context-chk-vmx.c @@ -5,10 +5,11 @@ * Test the kernel's signal frame code. * * The kernel sets up two sets of ucontexts if the signal was to be - * delivered while the thread was in a transaction. + * delivered while the thread was in a transaction (referred too as + * first and second contexts). * Expected behaviour is that the checkpointed state is in the user - * context passed to the signal handler. The speculated state can be - * accessed with the uc_link pointer. + * context passed to the signal handler (first context). The speculated + * state can be accessed with the uc_link pointer (second context). * * The rationale for this is that if TM unaware code (which linked * against TM libs) installs a signal handler it will not know of the @@ -29,18 +30,24 @@ #define MAX_ATTEMPT 500000 -#define NV_VMX_REGS 12 +#define NV_VMX_REGS 12 /* Number of non-volatile VMX registers */ +#define VMX20 20 /* First non-volatile register to check in vr20-31 subset */ long tm_signal_self_context_load(pid_t pid, long *gprs, double *fps, vector int *vms, vector int *vss); -static sig_atomic_t fail; +static sig_atomic_t fail, broken; +/* Test only non-volatile registers, i.e. 12 vmx registers from vr20 to vr31 */ vector int vms[] = { - {1, 2, 3, 4 },{5, 6, 7, 8 },{9, 10,11,12}, + /* First context will be set with these values, i.e. non-speculative */ + /* VMX20 , VMX21 , ... */ + { 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}, - {-1, -2, -3, -4}, {-5, -6, -7, -8}, {-9, -10,-11,-12}, + /* Second context will be set with these values, i.e. speculative */ + /* VMX20 , VMX21 , ... */ + { -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} @@ -48,26 +55,43 @@ vector int vms[] = { static void signal_usr1(int signum, siginfo_t *info, void *uc) { - int i; + int i, j; ucontext_t *ucp = uc; ucontext_t *tm_ucp = ucp->uc_link; - for (i = 0; i < NV_VMX_REGS && !fail; i++) { - fail = memcmp(ucp->uc_mcontext.v_regs->vrregs[i + 20], + for (i = 0; i < NV_VMX_REGS; i++) { + /* Check first context. Print all mismatches. */ + fail = memcmp(ucp->uc_mcontext.v_regs->vrregs[VMX20 + i], &vms[i], sizeof(vector int)); - fail |= memcmp(tm_ucp->uc_mcontext.v_regs->vrregs[i + 20], - &vms[i + NV_VMX_REGS], sizeof (vector int)); - if (fail) { - int j; + broken = 1; + printf("VMX%d (1st context) == 0x", VMX20 + i); + /* Print actual value in first context. */ + for (j = 0; j < 4; j++) + printf("%08x", ucp->uc_mcontext.v_regs->vrregs[VMX20 + i][j]); + printf(" instead of 0x"); + /* Print expected value. */ + for (j = 0; j < 4; j++) + printf("%08x", vms[i][j]); + printf(" (expected)\n"); + } + } - fprintf(stderr, "Failed on %d vmx 0x", i); + for (i = 0; i < NV_VMX_REGS; i++) { + /* Check second context. Print all mismatches. */ + fail = memcmp(tm_ucp->uc_mcontext.v_regs->vrregs[VMX20 + i], + &vms[NV_VMX_REGS + i], sizeof (vector int)); + if (fail) { + broken = 1; + printf("VMX%d (2nd context) == 0x", NV_VMX_REGS + i); + /* Print actual value in second context. */ + for (j = 0; j < 4; j++) + printf("%08x", tm_ucp->uc_mcontext.v_regs->vrregs[VMX20 + i][j]); + printf(" instead of 0x"); + /* Print expected value. */ for (j = 0; j < 4; j++) - fprintf(stderr, "%04x", ucp->uc_mcontext.v_regs->vrregs[i + 20][j]); - fprintf(stderr, " vs 0x"); - for (j = 0 ; j < 4; j++) - fprintf(stderr, "%04x", tm_ucp->uc_mcontext.v_regs->vrregs[i + 20][j]); - fprintf(stderr, "\n"); + printf("%08x", vms[NV_VMX_REGS + i][j]); + printf(" (expected)\n"); } } } @@ -90,13 +114,19 @@ static int tm_signal_context_chk() } i = 0; - while (i < MAX_ATTEMPT && !fail) { + while (i < MAX_ATTEMPT && !broken) { + /* + * tm_signal_self_context_load will set both first and second + * contexts accordingly to the values passed through non-NULL + * array pointers to it, in that case 'vms', and invoke the + * signal handler installed for SIGUSR1. + */ rc = tm_signal_self_context_load(pid, NULL, NULL, vms, NULL); FAIL_IF(rc != pid); i++; } - return fail; + return (broken); } int main(void) diff --git a/tools/testing/selftests/powerpc/tm/tm-signal-context-chk-vsx.c b/tools/testing/selftests/powerpc/tm/tm-signal-context-chk-vsx.c index 8c8677a408bb..8e25e2072ecd 100644 --- a/tools/testing/selftests/powerpc/tm/tm-signal-context-chk-vsx.c +++ b/tools/testing/selftests/powerpc/tm/tm-signal-context-chk-vsx.c @@ -5,10 +5,11 @@ * Test the kernel's signal frame code. * * The kernel sets up two sets of ucontexts if the signal was to be - * delivered while the thread was in a transaction. + * delivered while the thread was in a transaction (referred too as + * first and second contexts). * Expected behaviour is that the checkpointed state is in the user - * context passed to the signal handler. The speculated state can be - * accessed with the uc_link pointer. + * context passed to the signal handler (first context). The speculated + * state can be accessed with the uc_link pointer (second context). * * The rationale for this is that if TM unaware code (which linked * against TM libs) installs a signal handler it will not know of the @@ -29,17 +30,24 @@ #define MAX_ATTEMPT 500000 -#define NV_VSX_REGS 12 +#define NV_VSX_REGS 12 /* Number of VSX registers to check. */ +#define VSX20 20 /* First VSX register to check in vsr20-vsr31 subset */ +#define FPR20 20 /* FPR20 overlaps VSX20 most significant doubleword */ long tm_signal_self_context_load(pid_t pid, long *gprs, double *fps, vector int *vms, vector int *vss); -static sig_atomic_t fail; +static sig_atomic_t fail, broken; -vector int vss[] = { - {1, 2, 3, 4 },{5, 6, 7, 8 },{9, 10,11,12}, +/* Test only 12 vsx registers from vsr20 to vsr31 */ +vector int vsxs[] = { + /* First context will be set with these values, i.e. non-speculative */ + /* VSX20 , VSX21 , ... */ + { 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}, + /* Second context will be set with these values, i.e. speculative */ + /* VSX20 , VSX21 , ... */ {-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}, @@ -48,41 +56,91 @@ vector int vss[] = { static void signal_usr1(int signum, siginfo_t *info, void *uc) { - int i; - uint8_t vsc[sizeof(vector int)]; - uint8_t vst[sizeof(vector int)]; + int i, j; + uint8_t vsx[sizeof(vector int)]; + uint8_t vsx_tm[sizeof(vector int)]; ucontext_t *ucp = uc; ucontext_t *tm_ucp = ucp->uc_link; /* - * The other half of the VSX regs will be after v_regs. + * FP registers and VMX registers overlap the VSX registers. + * + * FP registers (f0-31) overlap the most significant 64 bits of VSX + * registers vsr0-31, whilst VMX registers vr0-31, being 128-bit like + * the VSX registers, overlap fully the other half of VSX registers, + * i.e. vr0-31 overlaps fully vsr32-63. + * + * Due to compatibility and historical reasons (VMX/Altivec support + * appeared first on the architecture), VMX registers vr0-31 (so VSX + * half vsr32-63 too) are stored right after the v_regs pointer, in an + * area allocated for 'vmx_reverse' array (please see + * arch/powerpc/include/uapi/asm/sigcontext.h for details about the + * mcontext_t structure on Power). + * + * The other VSX half (vsr0-31) is hence stored below vr0-31/vsr32-63 + * registers, but only the least significant 64 bits of vsr0-31. The + * most significant 64 bits of vsr0-31 (f0-31), as it overlaps the FP + * registers, is kept in fp_regs. + * + * v_regs is a 16 byte aligned pointer at the start of vmx_reserve + * (vmx_reserve may or may not be 16 aligned) where the v_regs structure + * exists, so v_regs points to where vr0-31 / vsr32-63 registers are + * fully stored. Since v_regs type is elf_vrregset_t, v_regs + 1 + * skips all the slots used to store vr0-31 / vsr32-64 and points to + * part of one VSX half, i.e. v_regs + 1 points to the least significant + * 64 bits of vsr0-31. The other part of this half (the most significant + * part of vsr0-31) is stored in fp_regs. * - * In short, vmx_reserve array holds everything. v_regs is a 16 - * byte aligned pointer at the start of vmx_reserve (vmx_reserve - * may or may not be 16 aligned) where the v_regs structure exists. - * (half of) The VSX regsters are directly after v_regs so the - * easiest way to find them below. */ + /* Get pointer to least significant doubleword of vsr0-31 */ long *vsx_ptr = (long *)(ucp->uc_mcontext.v_regs + 1); long *tm_vsx_ptr = (long *)(tm_ucp->uc_mcontext.v_regs + 1); - for (i = 0; i < NV_VSX_REGS && !fail; i++) { - memcpy(vsc, &ucp->uc_mcontext.fp_regs[i + 20], 8); - memcpy(vsc + 8, &vsx_ptr[20 + i], 8); - fail = memcmp(vsc, &vss[i], sizeof(vector int)); - memcpy(vst, &tm_ucp->uc_mcontext.fp_regs[i + 20], 8); - memcpy(vst + 8, &tm_vsx_ptr[20 + i], 8); - fail |= memcmp(vst, &vss[i + NV_VSX_REGS], sizeof(vector int)); - if (fail) { - int j; + /* Check first context. Print all mismatches. */ + for (i = 0; i < NV_VSX_REGS; i++) { + /* + * Copy VSX most significant doubleword from fp_regs and + * copy VSX least significant one from 64-bit slots below + * saved VMX registers. + */ + memcpy(vsx, &ucp->uc_mcontext.fp_regs[FPR20 + i], 8); + memcpy(vsx + 8, &vsx_ptr[VSX20 + i], 8); + + fail = memcmp(vsx, &vsxs[i], sizeof(vector int)); - fprintf(stderr, "Failed on %d vsx 0x", i); + if (fail) { + broken = 1; + printf("VSX%d (1st context) == 0x", VSX20 + i); for (j = 0; j < 16; j++) - fprintf(stderr, "%02x", vsc[j]); - fprintf(stderr, " vs 0x"); + printf("%02x", vsx[j]); + printf(" instead of 0x"); + for (j = 0; j < 4; j++) + printf("%08x", vsxs[i][j]); + printf(" (expected)\n"); + } + } + + /* Check second context. Print all mismatches. */ + for (i = 0; i < NV_VSX_REGS; i++) { + /* + * Copy VSX most significant doubleword from fp_regs and + * copy VSX least significant one from 64-bit slots below + * saved VMX registers. + */ + memcpy(vsx_tm, &tm_ucp->uc_mcontext.fp_regs[FPR20 + i], 8); + memcpy(vsx_tm + 8, &tm_vsx_ptr[VSX20 + i], 8); + + fail = memcmp(vsx_tm, &vsxs[NV_VSX_REGS + i], sizeof(vector int)); + + if (fail) { + broken = 1; + printf("VSX%d (2nd context) == 0x", VSX20 + i); for (j = 0; j < 16; j++) - fprintf(stderr, "%02x", vst[j]); - fprintf(stderr, "\n"); + printf("%02x", vsx_tm[j]); + printf(" instead of 0x"); + for (j = 0; j < 4; j++) + printf("%08x", vsxs[NV_VSX_REGS + i][j]); + printf("(expected)\n"); } } } @@ -105,13 +163,19 @@ static int tm_signal_context_chk() } i = 0; - while (i < MAX_ATTEMPT && !fail) { - rc = tm_signal_self_context_load(pid, NULL, NULL, NULL, vss); + while (i < MAX_ATTEMPT && !broken) { + /* + * tm_signal_self_context_load will set both first and second + * contexts accordingly to the values passed through non-NULL + * array pointers to it, in that case 'vsxs', and invoke the + * signal handler installed for SIGUSR1. + */ + rc = tm_signal_self_context_load(pid, NULL, NULL, NULL, vsxs); FAIL_IF(rc != pid); i++; } - return fail; + return (broken); } int main(void) -- cgit v1.2.3-59-g8ed1b From 6652bf6408895b09d31fd4128a1589a1a0672823 Mon Sep 17 00:00:00 2001 From: Gustavo Romero Date: Tue, 20 Aug 2019 18:54:11 -0400 Subject: selftests/powerpc: Retry on host facility unavailable TM test tm-unavailable must take into account aborts due to host aborting a transactin because of a facility unavailable exception, just like it already does for aborts on reschedules (TM_CAUSE_KVM_RESCHED). Reported-by: Desnes A. Nunes do Rosario Tested-by: Desnes A. Nunes do Rosario Signed-off-by: Gustavo Romero Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/1566341651-19747-1-git-send-email-gromero@linux.vnet.ibm.com --- tools/testing/selftests/powerpc/tm/tm.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/tm/tm.h b/tools/testing/selftests/powerpc/tm/tm.h index 97f9f491c541..c402464b038f 100644 --- a/tools/testing/selftests/powerpc/tm/tm.h +++ b/tools/testing/selftests/powerpc/tm/tm.h @@ -55,7 +55,8 @@ static inline bool failure_is_unavailable(void) static inline bool failure_is_reschedule(void) { if ((failure_code() & TM_CAUSE_RESCHED) == TM_CAUSE_RESCHED || - (failure_code() & TM_CAUSE_KVM_RESCHED) == TM_CAUSE_KVM_RESCHED) + (failure_code() & TM_CAUSE_KVM_RESCHED) == TM_CAUSE_KVM_RESCHED || + (failure_code() & TM_CAUSE_KVM_FAC_UNAV) == TM_CAUSE_KVM_FAC_UNAV) return true; return false; -- cgit v1.2.3-59-g8ed1b From 29e331176da121db22daa5dd9d72533b6a1efb33 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 22 Aug 2019 14:26:31 -0300 Subject: perf cpumap: No need to include perf.h, ditch it From a quick look this was never needed and just polluted the build, needlessly making things including cpumap.h to be rebuild if perf.h or anything it includes gets changed. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-x10p8slllqkn3fc3bntjx3n0@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cpumap.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index d0c5bbfd91af..c2519e7ea958 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -7,8 +7,6 @@ #include #include -#include "perf.h" - struct cpu_map_data; struct perf_cpu_map *perf_cpu_map__empty_new(int nr); -- cgit v1.2.3-59-g8ed1b From 38b7b678fe989f9c403c001d96887939aaa1b68a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 22 Aug 2019 14:35:55 -0300 Subject: perf stat: Remove needless headers from stat.h Just a forward declaration for 'struct timespec' is needed, ditch the rest. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-6shdqw801oqe7ax6r307k27r@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index bcb376e1b3a7..9e425ecd82d9 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -5,13 +5,12 @@ #include #include #include -#include #include -#include #include "rblist.h" -#include "perf.h" #include "event.h" +struct timespec; + struct stats { double n, mean, M2; u64 max, min; -- cgit v1.2.3-59-g8ed1b From aeb00b1aeab6dadd72c24f93bea51a46e109c2ba Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 22 Aug 2019 15:40:29 -0300 Subject: perf record: Move record_opts and other record decls out of perf.h And into a separate util/record.h, to better isolate things and make sure that those who use record_opts and the other moved declarations are explicitly including the necessary header. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-31q8mei1qkh74qvkl9nwidfq@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 2 +- tools/perf/arch/arm64/util/arm-spe.c | 1 + tools/perf/arch/s390/util/auxtrace.c | 1 + tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 + tools/perf/arch/x86/util/intel-bts.c | 1 + tools/perf/arch/x86/util/intel-pt.c | 3 +- tools/perf/builtin-record.c | 4 +- tools/perf/builtin-script.c | 2 +- tools/perf/builtin-stat.c | 2 +- tools/perf/builtin-trace.c | 1 + tools/perf/perf.h | 62 ----------------------- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/bpf.c | 1 + tools/perf/tests/code-reading.c | 1 + tools/perf/tests/keep-tracking.c | 1 + tools/perf/tests/openat-syscall-tp-fields.c | 3 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/switch-tracking.c | 1 + tools/perf/tests/task-exit.c | 1 + tools/perf/util/auxtrace.c | 2 +- tools/perf/util/bpf-event.c | 1 + tools/perf/util/evsel.c | 1 + tools/perf/util/kvm-stat.h | 2 +- tools/perf/util/machine.c | 1 + tools/perf/util/machine.h | 1 + tools/perf/util/record.c | 1 + tools/perf/util/record.h | 74 ++++++++++++++++++++++++++++ tools/perf/util/stat.c | 1 + tools/perf/util/stat.h | 2 + tools/perf/util/top.h | 1 + 30 files changed, 107 insertions(+), 73 deletions(-) create mode 100644 tools/perf/util/record.h (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index c73da3245b67..a185dab2d903 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -15,7 +15,7 @@ #include #include "cs-etm.h" -#include "../../perf.h" +#include "../../util/record.h" #include "../../util/auxtrace.h" #include "../../util/cpumap.h" #include "../../util/evlist.h" diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index 00915b8fd05b..cdd5c0c84183 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -19,6 +19,7 @@ #include "../../util/pmu.h" #include "../../util/debug.h" #include "../../util/auxtrace.h" +#include "../../util/record.h" #include "../../util/arm-spe.h" #define KiB(x) ((x) * 1024) diff --git a/tools/perf/arch/s390/util/auxtrace.c b/tools/perf/arch/s390/util/auxtrace.c index cab46f517b83..f32d7a72d039 100644 --- a/tools/perf/arch/s390/util/auxtrace.c +++ b/tools/perf/arch/s390/util/auxtrace.c @@ -8,6 +8,7 @@ #include "../../util/evlist.h" #include "../../util/auxtrace.h" #include "../../util/evsel.h" +#include "../../util/record.h" #define PERF_EVENT_CPUM_SF 0xB0000 /* Event: Basic-sampling */ #define PERF_EVENT_CPUM_SF_DIAG 0xBD000 /* Event: Combined-sampling */ diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index 582182d98a7f..02776109ba46 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include #include #include @@ -13,6 +14,7 @@ #include "evsel.h" #include "thread_map.h" #include "cpumap.h" +#include "record.h" #include "tsc.h" #include "tests/tests.h" diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index 2d5d8a12dd1f..1f2cf612bc9c 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -17,6 +17,7 @@ #include "../../util/session.h" #include "../../util/pmu.h" #include "../../util/debug.h" +#include "../../util/record.h" #include "../../util/tsc.h" #include "../../util/auxtrace.h" #include "../../util/intel-bts.h" diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index c72a77a82b39..44cfe72c1a4c 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -13,7 +13,6 @@ #include #include -#include "../../perf.h" #include "../../util/session.h" #include "../../util/event.h" #include "../../util/evlist.h" @@ -24,6 +23,8 @@ #include "../../util/pmu.h" #include "../../util/debug.h" #include "../../util/auxtrace.h" +#include "../../util/record.h" +#include "../../util/target.h" #include "../../util/tsc.h" #include "../../util/intel-pt.h" diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index f71631f2bcb5..359bb8f33e57 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -8,8 +8,6 @@ */ #include "builtin.h" -#include "perf.h" - #include "util/build-id.h" #include #include "util/parse-events.h" @@ -22,9 +20,11 @@ #include "util/evlist.h" #include "util/evsel.h" #include "util/debug.h" +#include "util/target.h" #include "util/session.h" #include "util/tool.h" #include "util/symbol.h" +#include "util/record.h" #include "util/cpumap.h" #include "util/thread_map.h" #include "util/data.h" diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 9b93ddeaeafa..ee05621d3bd6 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "builtin.h" -#include "perf.h" #include "util/cache.h" #include "util/counts.h" #include "util/debug.h" @@ -51,6 +50,7 @@ #include #include #include +#include "util/record.h" #include diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 8a4f1a7d0cba..6ab13f466827 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -40,7 +40,6 @@ * Jaswinder Singh Rajput */ -#include "perf.h" #include "builtin.h" #include "util/cgroup.h" #include @@ -62,6 +61,7 @@ #include "util/tool.h" #include "util/string2.h" #include "util/metricgroup.h" +#include "util/target.h" #include "util/top.h" #include "asm/bug.h" diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index de126258ca10..8ea62fd2591d 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -14,6 +14,7 @@ * http://lwn.net/Articles/415728/ ("Announcing a new utility: 'trace'") */ +#include "util/record.h" #include #include #include diff --git a/tools/perf/perf.h b/tools/perf/perf.h index dc0a7a237887..d9e6b8b957b6 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -35,63 +35,6 @@ extern const char perf_version_string[]; void pthread__unblock_sigwinch(void); -#include "util/target.h" - -struct record_opts { - struct target target; - bool group; - bool inherit_stat; - bool no_buffering; - bool no_inherit; - bool no_inherit_set; - bool no_samples; - bool raw_samples; - bool sample_address; - bool sample_phys_addr; - bool sample_weight; - bool sample_time; - bool sample_time_set; - bool sample_cpu; - bool period; - bool period_set; - bool running_time; - bool full_auxtrace; - bool auxtrace_snapshot_mode; - bool auxtrace_snapshot_on_exit; - bool record_namespaces; - bool record_switch_events; - bool all_kernel; - bool all_user; - bool kernel_callchains; - bool user_callchains; - bool tail_synthesize; - bool overwrite; - bool ignore_missing_thread; - bool strict_freq; - bool sample_id; - bool no_bpf_event; - unsigned int freq; - unsigned int mmap_pages; - unsigned int auxtrace_mmap_pages; - unsigned int user_freq; - u64 branch_stack; - u64 sample_intr_regs; - u64 sample_user_regs; - u64 default_interval; - u64 user_interval; - size_t auxtrace_snapshot_size; - const char *auxtrace_snapshot_opts; - bool sample_transaction; - unsigned initial_delay; - bool use_clockid; - clockid_t clockid; - u64 clockid_res_ns; - int nr_cblocks; - int affinity; - int mmap_flush; - unsigned int comp_level; -}; - enum perf_affinity { PERF_AFFINITY_SYS = 0, PERF_AFFINITY_NODE, @@ -99,10 +42,5 @@ enum perf_affinity { PERF_AFFINITY_MAX }; -struct option; -extern const char * const *record_usage; -extern struct option *record_options; extern int version_verbose; - -int record__parse_freq(const struct option *opt, const char *str, int unset); #endif diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 9bdf66139099..b6f27ef9fb02 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -4,9 +4,9 @@ * beginning */ -#include #include #include +#include "record.h" #include "tests.h" #include "debug.h" #include diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index e16f927f38b6..98642961fc63 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index e45df0736261..fe671b860086 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -20,6 +20,7 @@ #include "map.h" #include "symbol.h" #include "event.h" +#include "record.h" #include "thread.h" #include "tests.h" diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 0ce5ce33bac4..2af6faf1bbd6 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -8,6 +8,7 @@ #include "parse-events.h" #include "evlist.h" #include "evsel.h" +#include "record.h" #include "thread_map.h" #include "cpumap.h" #include "tests.h" diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index 9c06130d37be..62492106fb5e 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -1,12 +1,13 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include #include #include #include -#include "perf.h" #include "evlist.h" #include "evsel.h" #include "thread_map.h" +#include "record.h" #include "tests.h" #include "debug.h" #include diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 67b388e92cba..3a205f6f9363 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -7,8 +7,8 @@ #include #include "evlist.h" #include "evsel.h" -#include "perf.h" #include "debug.h" +#include "record.h" #include "tests.h" static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp) diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index e3cee69f6ea2..b63f02768724 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -13,6 +13,7 @@ #include "evsel.h" #include "thread_map.h" #include "cpumap.h" +#include "record.h" #include "tests.h" static int spin_sleep(void) diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 4ca38fd0379a..d79a22e2d8be 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "evlist.h" #include "evsel.h" +#include "target.h" #include "thread_map.h" #include "cpumap.h" #include "tests.h" diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 094e6ceb3cf2..12e9b7acbb2c 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -26,7 +26,6 @@ #include #include -#include "../perf.h" #include "evlist.h" #include "dso.h" #include "map.h" @@ -41,6 +40,7 @@ #include #include "event.h" +#include "record.h" #include "session.h" #include "debug.h" #include diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 5a5dcc6d8f85..5c634bcfea7e 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -14,6 +14,7 @@ #include "session.h" #include "map.h" #include "evlist.h" +#include "record.h" #define ptr_to_u64(ptr) ((__u64)(unsigned long)(ptr)) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index e983e721beca..9fadd5857ccc 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -34,6 +34,7 @@ #include "thread_map.h" #include "target.h" #include "perf_regs.h" +#include "record.h" #include "debug.h" #include "trace-event.h" #include "stat.h" diff --git a/tools/perf/util/kvm-stat.h b/tools/perf/util/kvm-stat.h index a09c495f866b..46913637085b 100644 --- a/tools/perf/util/kvm-stat.h +++ b/tools/perf/util/kvm-stat.h @@ -2,9 +2,9 @@ #ifndef __PERF_KVM_STAT_H #define __PERF_KVM_STAT_H -#include "../perf.h" #include "tool.h" #include "stat.h" +#include "record.h" struct evsel; struct evlist; diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 5734460fc89e..f7c1a7e6c4ba 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -13,6 +13,7 @@ #include "symbol.h" #include "sort.h" #include "strlist.h" +#include "target.h" #include "thread.h" #include "vdso.h" #include diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 8b9d7157276d..7d69119d0b5d 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -14,6 +14,7 @@ struct branch_stack; struct evsel; struct perf_sample; struct symbol; +struct target; struct thread; union perf_event; diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 51bbd0714e6d..574507d46c98 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -9,6 +9,7 @@ #include #include "util.h" #include "cloexec.h" +#include "record.h" typedef void (*setup_probe_fn_t)(struct evsel *evsel); diff --git a/tools/perf/util/record.h b/tools/perf/util/record.h new file mode 100644 index 000000000000..00275afc524d --- /dev/null +++ b/tools/perf/util/record.h @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _PERF_RECORD_H +#define _PERF_RECORD_H + +#include +#include +#include +#include +#include +#include "util/target.h" + +struct option; + +struct record_opts { + struct target target; + bool group; + bool inherit_stat; + bool no_buffering; + bool no_inherit; + bool no_inherit_set; + bool no_samples; + bool raw_samples; + bool sample_address; + bool sample_phys_addr; + bool sample_weight; + bool sample_time; + bool sample_time_set; + bool sample_cpu; + bool period; + bool period_set; + bool running_time; + bool full_auxtrace; + bool auxtrace_snapshot_mode; + bool auxtrace_snapshot_on_exit; + bool record_namespaces; + bool record_switch_events; + bool all_kernel; + bool all_user; + bool kernel_callchains; + bool user_callchains; + bool tail_synthesize; + bool overwrite; + bool ignore_missing_thread; + bool strict_freq; + bool sample_id; + bool no_bpf_event; + unsigned int freq; + unsigned int mmap_pages; + unsigned int auxtrace_mmap_pages; + unsigned int user_freq; + u64 branch_stack; + u64 sample_intr_regs; + u64 sample_user_regs; + u64 default_interval; + u64 user_interval; + size_t auxtrace_snapshot_size; + const char *auxtrace_snapshot_opts; + bool sample_transaction; + unsigned initial_delay; + bool use_clockid; + clockid_t clockid; + u64 clockid_res_ns; + int nr_cblocks; + int affinity; + int mmap_flush; + unsigned int comp_level; +}; + +extern const char * const *record_usage; +extern struct option *record_options; + +int record__parse_freq(const struct option *opt, const char *str, int unset); + +#endif // _PERF_RECORD_H diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 0cbfd1eca1dd..f985336b3a22 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -4,6 +4,7 @@ #include #include "counts.h" #include "stat.h" +#include "target.h" #include "evlist.h" #include "evsel.h" #include "thread_map.h" diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 9e425ecd82d9..14fe3e548229 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -198,6 +198,8 @@ int perf_stat_process_counter(struct perf_stat_config *config, struct perf_tool; union perf_event; struct perf_session; +struct target; + int perf_event__process_stat_event(struct perf_session *session, union perf_event *event); diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h index dc4bb6e52a83..7367433e767a 100644 --- a/tools/perf/util/top.h +++ b/tools/perf/util/top.h @@ -5,6 +5,7 @@ #include "tool.h" #include "evswitch.h" #include "annotate.h" +#include "record.h" #include #include #include -- cgit v1.2.3-59-g8ed1b From 125009026bfc9ec929975d35344bf69d2c636e95 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 22 Aug 2019 16:58:29 -0300 Subject: perf cacheline: Move cacheline related routines to separate files To disentangle util/sort.h a bit more. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-6kbf2cauas06rbqp15pyter5@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-c2c.c | 1 + tools/perf/util/Build | 1 + tools/perf/util/cacheline.c | 26 ++++++++++++++++++++++++++ tools/perf/util/cacheline.h | 21 +++++++++++++++++++++ tools/perf/util/sort.c | 1 + tools/perf/util/sort.h | 12 ------------ tools/perf/util/util.c | 20 -------------------- tools/perf/util/util.h | 1 - 8 files changed, 50 insertions(+), 33 deletions(-) create mode 100644 tools/perf/util/cacheline.c create mode 100644 tools/perf/util/cacheline.h (limited to 'tools') diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index 211143720078..73782d99ee5a 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -26,6 +26,7 @@ #include "hist.h" #include "sort.h" #include "tool.h" +#include "cacheline.h" #include "data.h" #include "event.h" #include "evlist.h" diff --git a/tools/perf/util/Build b/tools/perf/util/Build index b922c8c297ca..2e3856471e61 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -1,6 +1,7 @@ perf-y += annotate.o perf-y += block-range.o perf-y += build-id.o +perf-y += cacheline.o perf-y += config.o perf-y += ctype.o perf-y += db-export.o diff --git a/tools/perf/util/cacheline.c b/tools/perf/util/cacheline.c new file mode 100644 index 000000000000..9361d3f61f75 --- /dev/null +++ b/tools/perf/util/cacheline.c @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "cacheline.h" +#include "../perf.h" +#include + +#ifdef _SC_LEVEL1_DCACHE_LINESIZE +#define cache_line_size(cacheline_sizep) *cacheline_sizep = sysconf(_SC_LEVEL1_DCACHE_LINESIZE) +#else +#include +#include "debug.h" +static void cache_line_size(int *cacheline_sizep) +{ + if (sysfs__read_int("devices/system/cpu/cpu0/cache/index0/coherency_line_size", cacheline_sizep)) + pr_debug("cannot determine cache line size"); +} +#endif + +int cacheline_size(void) +{ + static int size; + + if (!size) + cache_line_size(&size); + + return size; +} diff --git a/tools/perf/util/cacheline.h b/tools/perf/util/cacheline.h new file mode 100644 index 000000000000..dec8c0fb1f4a --- /dev/null +++ b/tools/perf/util/cacheline.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef PERF_CACHELINE_H +#define PERF_CACHELINE_H + +#include + +int __pure cacheline_size(void); + +static inline u64 cl_address(u64 address) +{ + /* return the cacheline of the address */ + return (address & ~(cacheline_size() - 1)); +} + +static inline u64 cl_offset(u64 address) +{ + /* return the cacheline of the address */ + return (address & (cacheline_size() - 1)); +} + +#endif // PERF_CACHELINE_H diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index f9a38a1dd4d1..904ff4b2f57f 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -6,6 +6,7 @@ #include #include "sort.h" #include "hist.h" +#include "cacheline.h" #include "comm.h" #include "map.h" #include "symbol.h" diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 5e34676a98e8..4ae155c6a808 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -204,18 +204,6 @@ static inline float hist_entry__get_percent_limit(struct hist_entry *he) return period * 100.0 / total_period; } -static inline u64 cl_address(u64 address) -{ - /* return the cacheline of the address */ - return (address & ~(cacheline_size() - 1)); -} - -static inline u64 cl_offset(u64 address) -{ - /* return the cacheline of the address */ - return (address & (cacheline_size() - 1)); -} - enum sort_mode { SORT_MODE__NORMAL, SORT_MODE__BRANCH, diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 6fd130a5d8f2..44211e483fbf 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -43,26 +43,6 @@ void perf_set_multithreaded(void) unsigned int page_size; -#ifdef _SC_LEVEL1_DCACHE_LINESIZE -#define cache_line_size(cacheline_sizep) *cacheline_sizep = sysconf(_SC_LEVEL1_DCACHE_LINESIZE) -#else -static void cache_line_size(int *cacheline_sizep) -{ - if (sysfs__read_int("devices/system/cpu/cpu0/cache/index0/coherency_line_size", cacheline_sizep)) - pr_debug("cannot determine cache line size"); -} -#endif - -int cacheline_size(void) -{ - static int size; - - if (!size) - cache_line_size(&size); - - return size; -} - int sysctl_perf_event_max_stack = PERF_MAX_STACK_DEPTH; int sysctl_perf_event_max_contexts_per_stack = PERF_MAX_CONTEXTS_PER_STACK; diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 0dab140c6517..45a5c6f20197 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -34,7 +34,6 @@ int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size); size_t hex_width(u64 v); extern unsigned int page_size; -int __pure cacheline_size(void); int sysctl__max_stack(void); -- cgit v1.2.3-59-g8ed1b From 97b9d866a66cf9884cea623cde3300073815873d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 22 Aug 2019 17:10:08 -0300 Subject: perf srcline: Add missing srcline.h header to files needing its defs When srcline was introduced it wrongly added the include to util/sort.h, even with that header not needing the definitions it provides, fix it by adding it to the places that need it as a pre patch to remove srcline.h from sort.h. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-shuebppedtye8hrgxk15qe3x@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-diff.c | 2 ++ tools/perf/builtin-report.c | 1 + tools/perf/builtin-script.c | 1 + tools/perf/util/annotate.c | 2 ++ tools/perf/util/machine.c | 2 ++ tools/perf/util/sort.c | 1 + 6 files changed, 9 insertions(+) (limited to 'tools') diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index e91c0d798181..51c37e53b3d8 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -15,6 +15,7 @@ #include "util/session.h" #include "util/tool.h" #include "util/sort.h" +#include "util/srcline.h" #include "util/symbol.h" #include "util/data.h" #include "util/config.h" @@ -22,6 +23,7 @@ #include "util/annotate.h" #include "util/map.h" #include +#include #include #include diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 79dfb1139f94..318b0b95c14c 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -28,6 +28,7 @@ #include "util/evswitch.h" #include "util/header.h" #include "util/session.h" +#include "util/srcline.h" #include "util/tool.h" #include diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index ee05621d3bd6..6f389b33fbe5 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -11,6 +11,7 @@ #include "util/session.h" #include "util/tool.h" #include "util/map.h" +#include "util/srcline.h" #include "util/symbol.h" #include "util/thread.h" #include "util/trace-event.h" diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index e0518dc4c4d2..3bd1691f0be7 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -22,6 +22,7 @@ #include "cache.h" #include "map.h" #include "symbol.h" +#include "srcline.h" #include "units.h" #include "debug.h" #include "annotate.h" @@ -37,6 +38,7 @@ #include #include #include +#include /* FIXME: For the HE_COLORSET */ #include "ui/browser.h" diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index f7c1a7e6c4ba..47430afd3c2d 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -10,11 +10,13 @@ #include "hist.h" #include "machine.h" #include "map.h" +#include "srcline.h" #include "symbol.h" #include "sort.h" #include "strlist.h" #include "target.h" #include "thread.h" +#include "util.h" #include "vdso.h" #include #include diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 904ff4b2f57f..c522bdde3f71 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -13,6 +13,7 @@ #include "thread.h" #include "evsel.h" #include "evlist.h" +#include "srcline.h" #include "strlist.h" #include "strbuf.h" #include -- cgit v1.2.3-59-g8ed1b From 185bcb92c80eae2d85ec834ea76a144fd163e2af Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 22 Aug 2019 17:11:39 -0300 Subject: perf sort: Remove needless headers from sort.h, provide fwd struct decls Reducing the includes hell a bit more, speeding up the build and avoiding needless rebuilds when just one of those files gets updated. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-u63el2vqsovsmnhebx1rcixo@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/res_sample.c | 2 ++ tools/perf/ui/browsers/scripts.c | 2 ++ tools/perf/ui/stdio/hist.c | 1 + tools/perf/util/callchain.c | 1 + tools/perf/util/sort.h | 15 ++------------- 5 files changed, 8 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/perf/ui/browsers/res_sample.c b/tools/perf/ui/browsers/res_sample.c index 08897bd5eb0f..41a9d8923ec4 100644 --- a/tools/perf/ui/browsers/res_sample.c +++ b/tools/perf/ui/browsers/res_sample.c @@ -6,6 +6,8 @@ #include "sort.h" #include "config.h" #include "time-utils.h" +#include "../util.h" +#include "../../util/util.h" #include #include diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c index 04f9aff5621e..f2fd9f0d7ab5 100644 --- a/tools/perf/ui/browsers/scripts.c +++ b/tools/perf/ui/browsers/scripts.c @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 +#include "../../builtin.h" #include "../../util/sort.h" +#include "../../util/util.h" #include "../../util/hist.h" #include "../../util/debug.h" #include "../../util/symbol.h" diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index ee7ea6deed21..51ed67548b83 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c @@ -3,6 +3,7 @@ #include #include "../../util/callchain.h" +#include "../../util/debug.h" #include "../../util/hist.h" #include "../../util/map.h" #include "../../util/map_groups.h" diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index d077704f9afa..dd6e01000385 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -20,6 +20,7 @@ #include "asm/bug.h" +#include "debug.h" #include "hist.h" #include "sort.h" #include "machine.h" diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 4ae155c6a808..3d7cef73924c 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -1,29 +1,18 @@ /* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_SORT_H #define __PERF_SORT_H -#include "../builtin.h" - #include - -#include "color.h" +#include #include -#include "cache.h" #include #include "map_symbol.h" #include "symbol_conf.h" -#include "string.h" #include "callchain.h" #include "values.h" -#include "../perf.h" -#include "debug.h" -#include "header.h" - -#include -#include "parse-events.h" #include "hist.h" -#include "srcline.h" +struct option; struct thread; extern regex_t parent_regex; -- cgit v1.2.3-59-g8ed1b From d93fc7ac88c7347d1c31ca158d1466d1ce2097e1 Mon Sep 17 00:00:00 2001 From: James Clark Date: Thu, 22 Aug 2019 13:55:15 +0000 Subject: perf tests: Fixes hang in zstd compression test by changing the source of random data Running 'perf test' with zstd compression linked will hang at the test 'Zstd perf.data compression/decompression' because /dev/random blocks reads until there is enough entropy. This means that the test will appear to never complete unless the mouse is continually moved while running it. Signed-off-by: James Clark Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Jeremy Linton Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/3d8cc701-df4e-f949-1715-5118b530e990@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/record+zstd_comp_decomp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/tests/shell/record+zstd_comp_decomp.sh b/tools/perf/tests/shell/record+zstd_comp_decomp.sh index 899604d17b85..63a91ec473bb 100755 --- a/tools/perf/tests/shell/record+zstd_comp_decomp.sh +++ b/tools/perf/tests/shell/record+zstd_comp_decomp.sh @@ -13,7 +13,7 @@ skip_if_no_z_record() { collect_z_record() { echo "Collecting compressed record file:" $perf_tool record -o $trace_file -g -z -F 5000 -- \ - dd count=500 if=/dev/random of=/dev/null + dd count=500 if=/dev/urandom of=/dev/null } check_compressed_stats() { -- cgit v1.2.3-59-g8ed1b From b92675f4a9c02dd78052645597dac9e270679ddf Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 22 Aug 2019 20:36:25 -0700 Subject: perf trace beauty ioctl: Fix off-by-one error in cmd->string table While tracing a program that calls isatty(3), I noticed that strace reported TCGETS for the request argument of the underlying ioctl(2) syscall while perf trace reported TCSETS. strace is corrrect. The bug in perf was due to the tty ioctl beauty table starting at 0x5400 rather than 0x5401. Committer testing: Using augmented_raw_syscalls.o and settings to make 'perf trace' use strace formatting, i.e. with this in ~/.perfconfig # cat ~/.perfconfig [trace] add_events = /home/acme/git/linux/tools/perf/examples/bpf/augmented_raw_syscalls.c show_zeros = yes show_duration = no no_inherit = yes show_timestamp = no show_arg_names = no args_alignment = 40 show_prefix = yes # strace -e ioctl stty > /dev/null ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(1, TIOCGWINSZ, 0x7fff8a9b0860) = -1 ENOTTY (Inappropriate ioctl for device) ioctl(1, TCGETS, 0x7fff8a9b0540) = -1 ENOTTY (Inappropriate ioctl for device) +++ exited with 0 +++ # Before: # perf trace -e ioctl stty > /dev/null ioctl(0, TCSETS, 0x7fff2cf79f20) = 0 ioctl(1, TIOCSWINSZ, 0x7fff2cf79f40) = -1 ENOTTY (Inappropriate ioctl for device) ioctl(1, TCSETS, 0x7fff2cf79c20) = -1 ENOTTY (Inappropriate ioctl for device) # After: # perf trace -e ioctl stty > /dev/null ioctl(0, TCGETS, 0x7ffed0763920) = 0 ioctl(1, TIOCGWINSZ, 0x7ffed0763940) = -1 ENOTTY (Inappropriate ioctl for device) ioctl(1, TCGETS, 0x7ffed0763620) = -1 ENOTTY (Inappropriate ioctl for device) # Signed-off-by: Benjamin Peterson Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Fixes: 1cc47f2d46206d67285aea0ca7e8450af571da13 ("perf trace beauty ioctl: Improve 'cmd' beautifier") Link: http://lkml.kernel.org/r/20190823033625.18814-1-benjamin@python.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/trace/beauty/ioctl.c b/tools/perf/trace/beauty/ioctl.c index 52242fa4072b..e19eb6ea361d 100644 --- a/tools/perf/trace/beauty/ioctl.c +++ b/tools/perf/trace/beauty/ioctl.c @@ -21,7 +21,7 @@ static size_t ioctl__scnprintf_tty_cmd(int nr, int dir, char *bf, size_t size) { static const char *ioctl_tty_cmd[] = { - "TCGETS", "TCSETS", "TCSETSW", "TCSETSF", "TCGETA", "TCSETA", "TCSETAW", + [_IOC_NR(TCGETS)] = "TCGETS", "TCSETS", "TCSETSW", "TCSETSF", "TCGETA", "TCSETA", "TCSETAW", "TCSETAF", "TCSBRK", "TCXONC", "TCFLSH", "TIOCEXCL", "TIOCNXCL", "TIOCSCTTY", "TIOCGPGRP", "TIOCSPGRP", "TIOCOUTQ", "TIOCSTI", "TIOCGWINSZ", "TIOCSWINSZ", "TIOCMGET", "TIOCMBIS", "TIOCMBIC", "TIOCMSET", "TIOCGSOFTCAR", "TIOCSSOFTCAR", -- cgit v1.2.3-59-g8ed1b From 2ad926db78777148b07fced1e4bc88e20ad00268 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 23 Aug 2019 10:37:47 -0300 Subject: perf augmented_raw_syscalls: Rename augmented_filename to augmented_arg Because it is not used only for strings, we already use it for sockaddr structs and will use it for all other types. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-w9nkt3tvmyn5i4qnwng3ap1k@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_raw_syscalls.c | 42 +++++++++++------------- 1 file changed, 20 insertions(+), 22 deletions(-) (limited to 'tools') diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index 79787cf4fce9..b85b177c6726 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -60,7 +60,7 @@ struct syscall_exit_args { long ret; }; -struct augmented_filename { +struct augmented_arg { unsigned int size; int err; char value[PATH_MAX]; @@ -72,8 +72,7 @@ struct augmented_args_payload { struct syscall_enter_args args; union { struct { - struct augmented_filename filename, - filename2; + struct augmented_arg arg, arg2; }; struct sockaddr_storage saddr; }; @@ -82,31 +81,30 @@ struct augmented_args_payload { bpf_map(augmented_args_tmp, PERCPU_ARRAY, int, struct augmented_args_payload, 1); static inline -unsigned int augmented_filename__read(struct augmented_filename *augmented_filename, - const void *filename_arg, unsigned int filename_len) +unsigned int augmented_arg__read_str(struct augmented_arg *augmented_arg, const void *arg, unsigned int arg_len) { - unsigned int len = sizeof(*augmented_filename); - int size = probe_read_str(&augmented_filename->value, filename_len, filename_arg); + unsigned int augmented_len = sizeof(*augmented_arg); + int string_len = probe_read_str(&augmented_arg->value, arg_len, arg); - augmented_filename->size = augmented_filename->err = 0; + augmented_arg->size = augmented_arg->err = 0; /* * probe_read_str may return < 0, e.g. -EFAULT - * So we leave that in the augmented_filename->size that userspace will + * So we leave that in the augmented_arg->size that userspace will */ - if (size > 0) { - len -= sizeof(augmented_filename->value) - size; - len &= sizeof(augmented_filename->value) - 1; - augmented_filename->size = size; + if (string_len > 0) { + augmented_len -= sizeof(augmented_arg->value) - string_len; + augmented_len &= sizeof(augmented_arg->value) - 1; + augmented_arg->size = string_len; } else { /* * So that username notice the error while still being able * to skip this augmented arg record */ - augmented_filename->err = size; - len = offsetof(struct augmented_filename, value); + augmented_arg->err = string_len; + augmented_len = offsetof(struct augmented_arg, value); } - return len; + return augmented_len; } SEC("!raw_syscalls:unaugmented") @@ -174,7 +172,7 @@ int sys_enter_open(struct syscall_enter_args *args) if (augmented_args == NULL) return 1; /* Failure: don't filter */ - len += augmented_filename__read(&augmented_args->filename, filename_arg, sizeof(augmented_args->filename.value)); + len += augmented_arg__read_str(&augmented_args->arg, filename_arg, sizeof(augmented_args->arg.value)); /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); @@ -191,7 +189,7 @@ int sys_enter_openat(struct syscall_enter_args *args) if (augmented_args == NULL) return 1; /* Failure: don't filter */ - len += augmented_filename__read(&augmented_args->filename, filename_arg, sizeof(augmented_args->filename.value)); + len += augmented_arg__read_str(&augmented_args->arg, filename_arg, sizeof(augmented_args->arg.value)); /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); @@ -209,8 +207,8 @@ int sys_enter_rename(struct syscall_enter_args *args) if (augmented_args == NULL) return 1; /* Failure: don't filter */ - oldpath_len = augmented_filename__read(&augmented_args->filename, oldpath_arg, sizeof(augmented_args->filename.value)); - len += oldpath_len + augmented_filename__read((void *)(&augmented_args->filename) + oldpath_len, newpath_arg, sizeof(augmented_args->filename.value)); + oldpath_len = augmented_arg__read_str(&augmented_args->arg, oldpath_arg, sizeof(augmented_args->arg.value)); + len += oldpath_len + augmented_arg__read_str((void *)(&augmented_args->arg) + oldpath_len, newpath_arg, sizeof(augmented_args->arg.value)); /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); @@ -228,8 +226,8 @@ int sys_enter_renameat(struct syscall_enter_args *args) if (augmented_args == NULL) return 1; /* Failure: don't filter */ - oldpath_len = augmented_filename__read(&augmented_args->filename, oldpath_arg, sizeof(augmented_args->filename.value)); - len += oldpath_len + augmented_filename__read((void *)(&augmented_args->filename) + oldpath_len, newpath_arg, sizeof(augmented_args->filename.value)); + oldpath_len = augmented_arg__read_str(&augmented_args->arg, oldpath_arg, sizeof(augmented_args->arg.value)); + len += oldpath_len + augmented_arg__read_str((void *)(&augmented_args->arg) + oldpath_len, newpath_arg, sizeof(augmented_args->arg.value)); /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); -- cgit v1.2.3-59-g8ed1b From 01128065ca5112123e6992dc0522484349c6ced7 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 23 Aug 2019 15:38:08 -0300 Subject: perf augmented_raw_syscalls: Postpone tmp map lookup to after pid_filter No sense in doing that lookup before figuring out if it will be used, i.e. if the pid is being filtered that tmp space lookup will be useless. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-o74yggieorucfg4j74tb6rta@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_raw_syscalls.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index b85b177c6726..0a8d217d65c7 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -250,13 +250,13 @@ int sys_enter(struct syscall_enter_args *args) struct syscall *syscall; int key = 0; + if (pid_filter__has(&pids_filtered, getpid())) + return 0; + augmented_args = bpf_map_lookup_elem(&augmented_args_tmp, &key); if (augmented_args == NULL) return 1; - if (pid_filter__has(&pids_filtered, getpid())) - return 0; - probe_read(&augmented_args->args, sizeof(augmented_args->args), args); /* -- cgit v1.2.3-59-g8ed1b From c265784de7adff9e07934b712204556fb0b3ba43 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 23 Aug 2019 15:45:54 -0300 Subject: perf augmented_raw_syscalls: Introduce helper to get the scratch space We need more than the BPF stack can give us to format the raw_syscalls:sys_enter augmented tracepoint, so we use a PERCPU_ARRAY map for that, use a helper to shorten the sequence to access that area. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_raw_syscalls.c | 32 ++++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index 0a8d217d65c7..8fd5ea059903 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -78,8 +78,15 @@ struct augmented_args_payload { }; }; +// We need more tmp space than the BPF stack can give us bpf_map(augmented_args_tmp, PERCPU_ARRAY, int, struct augmented_args_payload, 1); +static inline struct augmented_args_payload *augmented_args_payload(void) +{ + int key = 0; + return bpf_map_lookup_elem(&augmented_args_tmp, &key); +} + static inline unsigned int augmented_arg__read_str(struct augmented_arg *augmented_arg, const void *arg, unsigned int arg_len) { @@ -122,8 +129,7 @@ int syscall_unaugmented(struct syscall_enter_args *args) SEC("!syscalls:sys_enter_connect") int sys_enter_connect(struct syscall_enter_args *args) { - int key = 0; - struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(&augmented_args_tmp, &key); + struct augmented_args_payload *augmented_args = augmented_args_payload(); const void *sockaddr_arg = (const void *)args->args[1]; unsigned int socklen = args->args[2]; unsigned int len = sizeof(augmented_args->args); @@ -143,8 +149,7 @@ int sys_enter_connect(struct syscall_enter_args *args) SEC("!syscalls:sys_enter_sendto") int sys_enter_sendto(struct syscall_enter_args *args) { - int key = 0; - struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(&augmented_args_tmp, &key); + struct augmented_args_payload *augmented_args = augmented_args_payload(); const void *sockaddr_arg = (const void *)args->args[4]; unsigned int socklen = args->args[5]; unsigned int len = sizeof(augmented_args->args); @@ -164,8 +169,7 @@ int sys_enter_sendto(struct syscall_enter_args *args) SEC("!syscalls:sys_enter_open") int sys_enter_open(struct syscall_enter_args *args) { - int key = 0; - struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(&augmented_args_tmp, &key); + struct augmented_args_payload *augmented_args = augmented_args_payload(); const void *filename_arg = (const void *)args->args[0]; unsigned int len = sizeof(augmented_args->args); @@ -181,8 +185,7 @@ int sys_enter_open(struct syscall_enter_args *args) SEC("!syscalls:sys_enter_openat") int sys_enter_openat(struct syscall_enter_args *args) { - int key = 0; - struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(&augmented_args_tmp, &key); + struct augmented_args_payload *augmented_args = augmented_args_payload(); const void *filename_arg = (const void *)args->args[1]; unsigned int len = sizeof(augmented_args->args); @@ -198,8 +201,7 @@ int sys_enter_openat(struct syscall_enter_args *args) SEC("!syscalls:sys_enter_rename") int sys_enter_rename(struct syscall_enter_args *args) { - int key = 0; - struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(&augmented_args_tmp, &key); + struct augmented_args_payload *augmented_args = augmented_args_payload(); const void *oldpath_arg = (const void *)args->args[0], *newpath_arg = (const void *)args->args[1]; unsigned int len = sizeof(augmented_args->args), oldpath_len; @@ -217,8 +219,7 @@ int sys_enter_rename(struct syscall_enter_args *args) SEC("!syscalls:sys_enter_renameat") int sys_enter_renameat(struct syscall_enter_args *args) { - int key = 0; - struct augmented_args_payload *augmented_args = bpf_map_lookup_elem(&augmented_args_tmp, &key); + struct augmented_args_payload *augmented_args = augmented_args_payload(); const void *oldpath_arg = (const void *)args->args[1], *newpath_arg = (const void *)args->args[3]; unsigned int len = sizeof(augmented_args->args), oldpath_len; @@ -248,14 +249,13 @@ int sys_enter(struct syscall_enter_args *args) */ unsigned int len = sizeof(augmented_args->args); struct syscall *syscall; - int key = 0; if (pid_filter__has(&pids_filtered, getpid())) return 0; - augmented_args = bpf_map_lookup_elem(&augmented_args_tmp, &key); - if (augmented_args == NULL) - return 1; + augmented_args = augmented_args_payload(); + if (augmented_args == NULL) + return 1; probe_read(&augmented_args->args, sizeof(augmented_args->args), args); -- cgit v1.2.3-59-g8ed1b From e051c2f69850e571cb408b555aaffb00c07dbb05 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 23 Aug 2019 15:54:02 -0300 Subject: perf augmented_raw_syscalls: Reduce perf_event_output() boilerplate Add a augmented__output() helper to reduce the boilerplate of sending the augmented tracepoint to the PERF_EVENT_ARRAY BPF map associated with the bpf-output event used to communicate with the userspace perf trace tool. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-ln99gt0j4fv0kw0778h6vphm@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/examples/bpf/augmented_raw_syscalls.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c index 8fd5ea059903..b80437971d80 100644 --- a/tools/perf/examples/bpf/augmented_raw_syscalls.c +++ b/tools/perf/examples/bpf/augmented_raw_syscalls.c @@ -87,6 +87,12 @@ static inline struct augmented_args_payload *augmented_args_payload(void) return bpf_map_lookup_elem(&augmented_args_tmp, &key); } +static inline int augmented__output(void *ctx, struct augmented_args_payload *args, int len) +{ + /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ + return perf_event_output(ctx, &__augmented_syscalls__, BPF_F_CURRENT_CPU, args, len); +} + static inline unsigned int augmented_arg__read_str(struct augmented_arg *augmented_arg, const void *arg, unsigned int arg_len) { @@ -142,8 +148,7 @@ int sys_enter_connect(struct syscall_enter_args *args) probe_read(&augmented_args->saddr, socklen, sockaddr_arg); - /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ - return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len + socklen); + return augmented__output(args, augmented_args, len + socklen); } SEC("!syscalls:sys_enter_sendto") @@ -162,8 +167,7 @@ int sys_enter_sendto(struct syscall_enter_args *args) probe_read(&augmented_args->saddr, socklen, sockaddr_arg); - /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ - return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len + socklen); + return augmented__output(args, augmented_args, len + socklen); } SEC("!syscalls:sys_enter_open") @@ -178,8 +182,7 @@ int sys_enter_open(struct syscall_enter_args *args) len += augmented_arg__read_str(&augmented_args->arg, filename_arg, sizeof(augmented_args->arg.value)); - /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ - return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); + return augmented__output(args, augmented_args, len); } SEC("!syscalls:sys_enter_openat") @@ -194,8 +197,7 @@ int sys_enter_openat(struct syscall_enter_args *args) len += augmented_arg__read_str(&augmented_args->arg, filename_arg, sizeof(augmented_args->arg.value)); - /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ - return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); + return augmented__output(args, augmented_args, len); } SEC("!syscalls:sys_enter_rename") @@ -212,8 +214,7 @@ int sys_enter_rename(struct syscall_enter_args *args) oldpath_len = augmented_arg__read_str(&augmented_args->arg, oldpath_arg, sizeof(augmented_args->arg.value)); len += oldpath_len + augmented_arg__read_str((void *)(&augmented_args->arg) + oldpath_len, newpath_arg, sizeof(augmented_args->arg.value)); - /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ - return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); + return augmented__output(args, augmented_args, len); } SEC("!syscalls:sys_enter_renameat") @@ -230,8 +231,7 @@ int sys_enter_renameat(struct syscall_enter_args *args) oldpath_len = augmented_arg__read_str(&augmented_args->arg, oldpath_arg, sizeof(augmented_args->arg.value)); len += oldpath_len + augmented_arg__read_str((void *)(&augmented_args->arg) + oldpath_len, newpath_arg, sizeof(augmented_args->arg.value)); - /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ - return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, augmented_args, len); + return augmented__output(args, augmented_args, len); } SEC("raw_syscalls:sys_enter") -- cgit v1.2.3-59-g8ed1b From b4de344b25b9fbd4db7b84da43808a6b7daac887 Mon Sep 17 00:00:00 2001 From: Souptick Joarder Date: Sat, 24 Aug 2019 21:45:19 +0530 Subject: perf tools: Remove duplicate headers Removed headers which are included twice. Signed-off-by: Souptick Joarder Reviewed-by: Mukesh Ojha Cc: Andrew Morton Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1566663319-4283-1-git-send-email-jrdr.linux@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/data.c | 1 - tools/perf/util/get_current_dir_name.c | 1 - tools/perf/util/stat-display.c | 1 - 3 files changed, 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c index 1d1b97a92c3f..74aafe0df506 100644 --- a/tools/perf/util/data.c +++ b/tools/perf/util/data.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include "data.h" diff --git a/tools/perf/util/get_current_dir_name.c b/tools/perf/util/get_current_dir_name.c index 01f32f26552d..b205d929245f 100644 --- a/tools/perf/util/get_current_dir_name.c +++ b/tools/perf/util/get_current_dir_name.c @@ -5,7 +5,6 @@ #include "get_current_dir_name.h" #include #include -#include /* Android's 'bionic' library, for one, doesn't have this */ diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 51d6781aa90d..1461dac2322d 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -14,7 +14,6 @@ #include "string2.h" #include #include "cgroup.h" -#include #include #define CNTR_NOT_SUPPORTED "" -- cgit v1.2.3-59-g8ed1b From 092804ae092fc6097348f5c09b62cde040717aa1 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 23 Aug 2019 14:03:37 -0700 Subject: perf report: Use timestamp__scnprintf_nsec() for time sort key Use timestamp__scnprintf_nsec() to print nanoseconds for the time sort key, instead of open coding. Signed-off-by: Andi Kleen Cc: Jiri Olsa Link: http://lkml.kernel.org/r/20190823210338.12360-1-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/sort.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index c522bdde3f71..83eb3fa6f941 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -670,17 +670,11 @@ sort__time_cmp(struct hist_entry *left, struct hist_entry *right) static int hist_entry__time_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { - unsigned long secs; - unsigned long long nsecs; char he_time[32]; - nsecs = he->time; - secs = nsecs / NSEC_PER_SEC; - nsecs -= secs * NSEC_PER_SEC; - if (symbol_conf.nanosecs) - snprintf(he_time, sizeof he_time, "%5lu.%09llu: ", - secs, nsecs); + timestamp__scnprintf_nsec(he->time, he_time, + sizeof(he_time)); else timestamp__scnprintf_usec(he->time, he_time, sizeof(he_time)); -- cgit v1.2.3-59-g8ed1b From 3dab6ac080dcd7f71cb9ceb84ad7dafecd6f7c07 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 23 Aug 2019 14:03:38 -0700 Subject: perf report: Fix --ns time sort key output If the user specified --ns, the column to print the sort time stamp wasn't wide enough to actually print the full nanoseconds. Widen the time key column width when --ns is specified. Before: % perf record -a sleep 1 % perf report --sort time,overhead,symbol --stdio --ns ... 2.39% 187851.10000 [k] smp_call_function_single - - 1.53% 187851.10000 [k] intel_idle - - 0.59% 187851.10000 [.] __wcscmp_ifunc - - 0.33% 187851.10000 [.] 0000000000000000 - - 0.28% 187851.10000 [k] cpuidle_enter_state - - After: % perf report --sort time,overhead,symbol --stdio --ns ... 2.39% 187851.100000000 [k] smp_call_function_single - - 1.53% 187851.100000000 [k] intel_idle - - 0.59% 187851.100000000 [.] __wcscmp_ifunc - - 0.33% 187851.100000000 [.] 0000000000000000 - - 0.28% 187851.100000000 [k] cpuidle_enter_state - - Signed-off-by: Andi Kleen Tested-by: Arnaldo Carvalho de Melo Cc: Jiri Olsa Link: http://lkml.kernel.org/r/20190823210338.12360-2-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 8efbf58dc3d0..33702675073c 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -193,7 +193,10 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) hists__new_col_len(hists, HISTC_MEM_LVL, 21 + 3); hists__new_col_len(hists, HISTC_LOCAL_WEIGHT, 12); hists__new_col_len(hists, HISTC_GLOBAL_WEIGHT, 12); - hists__new_col_len(hists, HISTC_TIME, 12); + if (symbol_conf.nanosecs) + hists__new_col_len(hists, HISTC_TIME, 16); + else + hists__new_col_len(hists, HISTC_TIME, 12); if (h->srcline) { len = MAX(strlen(h->srcline), strlen(sort_srcline.se_header)); -- cgit v1.2.3-59-g8ed1b From 3b4acbb92dbda4829e021e5c6d5410658849fa1c Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Mon, 8 Apr 2019 11:27:48 -0500 Subject: perf script: Fix memory leaks in list_scripts() In case memory resources for *buf* and *paths* were allocated, jump to *out* and release them before return. Signed-off-by: Gustavo A. R. Silva Cc: Alexander Shishkin Cc: Andi Kleen Cc: Gustavo A. R. Silva Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Addresses-Coverity-ID: 1444328 ("Resource leak") Fixes: 6f3da20e151f ("perf report: Support builtin perf script in scripts menu") Link: http://lkml.kernel.org/r/20190408162748.GA21008@embeddedor Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/scripts.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c index f2fd9f0d7ab5..50e0c03171f2 100644 --- a/tools/perf/ui/browsers/scripts.c +++ b/tools/perf/ui/browsers/scripts.c @@ -133,8 +133,10 @@ static int list_scripts(char *script_name, bool *custom, int key = ui_browser__input_window("perf script command", "Enter perf script command line (without perf script prefix)", script_args, "", 0); - if (key != K_ENTER) - return -1; + if (key != K_ENTER) { + ret = -1; + goto out; + } sprintf(script_name, "%s script %s", perf, script_args); } else if (choice < num + max_std) { strcpy(script_name, paths[choice]); -- cgit v1.2.3-59-g8ed1b From 1345e2ee87a83c758f336f03f7fb305bc5e24490 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 25 Aug 2019 20:17:41 +0200 Subject: libperf: Add PERF_RECORD_MMAP 'struct mmap_event' to perf/event.h Move the mmap_event event definition to libperf's event.h header include. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Perf added 'u*' types mainly to ease up printing __u64 values as stated in the linux/types.h comment: /* * We define u64 as uint64_t for every architecture * so that we can print it with "%"PRIx64 without getting warnings. * * typedef __u64 u64; * typedef __s64 s64; */ Add and use new PRI_lu64 and PRI_lx64 macros for that. Use extra '_' to ease up reading and differentiate them from standard PRI*64 macros. Committer notes: Fixup the PRI_l[ux]64 macros on 32-bit arches, conditionally defining it with that extra 'l' modifier only on arches where __u64 is long long, leaving it aside on 32-bit arches. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190825181752.722-2-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 18 ++++++++++++++++++ tools/perf/util/event.c | 2 +- tools/perf/util/event.h | 22 ++++++++++++++-------- tools/perf/util/python.c | 4 ++-- 4 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 tools/perf/lib/include/perf/event.h (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h new file mode 100644 index 000000000000..13fe15a2fe7f --- /dev/null +++ b/tools/perf/lib/include/perf/event.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LIBPERF_EVENT_H +#define __LIBPERF_EVENT_H + +#include +#include +#include + +struct mmap_event { + struct perf_event_header header; + __u32 pid, tid; + __u64 start; + __u64 len; + __u64 pgoff; + char filename[PATH_MAX]; +}; + +#endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 332edef8d394..43c86257e7fa 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1353,7 +1353,7 @@ int perf_event__process_bpf_event(struct perf_tool *tool __maybe_unused, size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) { - return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %c %s\n", + return fprintf(fp, " %d/%d: [%#" PRI_lx64 "(%#" PRI_lx64 ") @ %#" PRI_lx64 "]: %c %s\n", event->mmap.pid, event->mmap.tid, event->mmap.start, event->mmap.len, event->mmap.pgoff, (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x', diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 0e164e8ae28d..f43eff2fba2d 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -7,19 +7,25 @@ #include #include #include +#include #include "../perf.h" #include "build-id.h" #include "perf_regs.h" -struct mmap_event { - struct perf_event_header header; - u32 pid, tid; - u64 start; - u64 len; - u64 pgoff; - char filename[PATH_MAX]; -}; +#ifdef __LP64__ +/* + * /usr/include/inttypes.h uses just 'lu' for PRIu64, but we end up defining + * __u64 as long long unsigned int, and then -Werror=format= kicks in and + * complains of the mismatched types, so use these two special extra PRI + * macros to overcome that. + */ +#define PRI_lu64 "l" PRIu64 +#define PRI_lx64 "l" PRIx64 +#else +#define PRI_lu64 PRIu64 +#define PRI_lx64 PRIx64 +#endif struct mmap2_event { struct perf_event_header header; diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 75ecc32a4427..55ff0c3182d6 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -130,8 +130,8 @@ static PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent) PyObject *ret; char *s; - if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRIx64 ", " - "length: %#" PRIx64 ", offset: %#" PRIx64 ", " + if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRI_lx64 ", " + "length: %#" PRI_lx64 ", offset: %#" PRI_lx64 ", " "filename: %s }", pevent->event.mmap.pid, pevent->event.mmap.tid, pevent->event.mmap.start, pevent->event.mmap.len, -- cgit v1.2.3-59-g8ed1b From b66ced19c9f64dbe707cf318fae9fca82b999564 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 25 Aug 2019 20:17:42 +0200 Subject: libperf: Add PERF_RECORD_MMAP2 'struct mmap2_event' to perf/event.h Moving mmap2_event event definition into libperf's event.h header include. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Perf added 'u*' types mainly to ease up printing __u64 values as stated in the linux/types.h comment: /* * We define u64 as uint64_t for every architecture * so that we can print it with "%"PRIx64 without getting warnings. * * typedef __u64 u64; * typedef __s64 s64; */ Adding and using new PRI_lu64 and PRI_lx64 macros to be used for that. Using extra '_' to ease up the reading and differentiate them from standard PRI*64 macros. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lkml.kernel.org/n/tip-ufs9ityr5w2xqwtd5w3p6dm4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 15 +++++++++++++++ tools/perf/util/event.c | 6 +++--- tools/perf/util/event.h | 15 --------------- 3 files changed, 18 insertions(+), 18 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 13fe15a2fe7f..c82e0c2c004b 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -15,4 +15,19 @@ struct mmap_event { char filename[PATH_MAX]; }; +struct mmap2_event { + struct perf_event_header header; + __u32 pid, tid; + __u64 start; + __u64 len; + __u64 pgoff; + __u32 maj; + __u32 min; + __u64 ino; + __u64 ino_generation; + __u32 prot; + __u32 flags; + char filename[PATH_MAX]; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 43c86257e7fa..0954f980574f 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -387,7 +387,7 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool, strcpy(execname, ""); /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */ - n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %x:%x %u %[^\n]\n", + n = sscanf(bf, "%"PRI_lx64"-%"PRI_lx64" %s %"PRI_lx64" %x:%x %u %[^\n]\n", &event->mmap2.start, &event->mmap2.len, prot, &event->mmap2.pgoff, &event->mmap2.maj, &event->mmap2.min, @@ -1362,8 +1362,8 @@ size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp) { - return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 - " %02x:%02x %"PRIu64" %"PRIu64"]: %c%c%c%c %s\n", + return fprintf(fp, " %d/%d: [%#" PRI_lx64 "(%#" PRI_lx64 ") @ %#" PRI_lx64 + " %02x:%02x %"PRI_lu64" %"PRI_lu64"]: %c%c%c%c %s\n", event->mmap2.pid, event->mmap2.tid, event->mmap2.start, event->mmap2.len, event->mmap2.pgoff, event->mmap2.maj, event->mmap2.min, event->mmap2.ino, diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index f43eff2fba2d..af252be8ca5b 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -27,21 +27,6 @@ #define PRI_lx64 PRIx64 #endif -struct mmap2_event { - struct perf_event_header header; - u32 pid, tid; - u64 start; - u64 len; - u64 pgoff; - u32 maj; - u32 min; - u64 ino; - u64 ino_generation; - u32 prot; - u32 flags; - char filename[PATH_MAX]; -}; - struct comm_event { struct perf_event_header header; u32 pid, tid; -- cgit v1.2.3-59-g8ed1b From 002dda32a831b30d22a3620eb619a0d103e78e81 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 25 Aug 2019 20:17:43 +0200 Subject: libperf: Add PERF_RECORD_COMM 'struct comm_event' to perf/event.h Moving comm_event event definition into libperf's event.h header include. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190825181752.722-4-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 6 ++++++ tools/perf/util/event.h | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index c82e0c2c004b..3729a7d9253e 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -30,4 +30,10 @@ struct mmap2_event { char filename[PATH_MAX]; }; +struct comm_event { + struct perf_event_header header; + __u32 pid, tid; + char comm[16]; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index af252be8ca5b..e8973a783267 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -27,12 +27,6 @@ #define PRI_lx64 PRIx64 #endif -struct comm_event { - struct perf_event_header header; - u32 pid, tid; - char comm[16]; -}; - struct namespaces_event { struct perf_event_header header; u32 pid, tid; -- cgit v1.2.3-59-g8ed1b From 19d1765a3ed9a8f78d93909120f6d39398809f75 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 25 Aug 2019 20:17:44 +0200 Subject: libperf: Add PERF_RECORD_NAMESPACES 'struct namespaces_event' to perf/event.h Move the namespaces_event event definition into libperf's event.h header include. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190825181752.722-5-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 7 +++++++ tools/perf/util/event.h | 7 ------- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 3729a7d9253e..b90a8a21e613 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -36,4 +36,11 @@ struct comm_event { char comm[16]; }; +struct namespaces_event { + struct perf_event_header header; + __u32 pid, tid; + __u64 nr_namespaces; + struct perf_ns_link_info link_info[]; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index e8973a783267..0d3ac4fd3ecf 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -27,13 +27,6 @@ #define PRI_lx64 PRIx64 #endif -struct namespaces_event { - struct perf_event_header header; - u32 pid, tid; - u64 nr_namespaces; - struct perf_ns_link_info link_info[]; -}; - struct fork_event { struct perf_event_header header; u32 pid, ppid; -- cgit v1.2.3-59-g8ed1b From bceb59b1f28d1ca812d816fd8f33c72b1a8378fb Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 25 Aug 2019 20:17:45 +0200 Subject: libperf: Add PERF_RECORD_FORK 'struct fork_event' to perf/event.h Move the fork_event event definition into libperf's event.h header include. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Perf added 'u*' types mainly to ease up printing __u64 values as stated in the linux/types.h comment: /* * We define u64 as uint64_t for every architecture * so that we can print it with "%"PRIx64 without getting warnings. * * typedef __u64 u64; * typedef __s64 s64; */ Add and use new PRI_lu64 and PRI_lx64 macros for that. Using extra '_' to ease up the reading and differentiate them from standard PRI*64 macros. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190825181752.722-6-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 7 +++++++ tools/perf/util/event.h | 7 ------- tools/perf/util/python.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index b90a8a21e613..c7cae58d2535 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -43,4 +43,11 @@ struct namespaces_event { struct perf_ns_link_info link_info[]; }; +struct fork_event { + struct perf_event_header header; + __u32 pid, ppid; + __u32 tid, ptid; + __u64 time; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 0d3ac4fd3ecf..38b258cbbd90 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -27,13 +27,6 @@ #define PRI_lx64 PRIx64 #endif -struct fork_event { - struct perf_event_header header; - u32 pid, ppid; - u32 tid, ptid; - u64 time; -}; - struct lost_event { struct perf_event_header header; u64 id; diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 55ff0c3182d6..8bdadb24f6ba 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -170,7 +170,7 @@ static PyMemberDef pyrf_task_event__members[] = { static PyObject *pyrf_task_event__repr(struct pyrf_event *pevent) { return _PyUnicode_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, " - "ptid: %u, time: %" PRIu64 "}", + "ptid: %u, time: %" PRI_lu64 "}", pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit", pevent->event.fork.pid, pevent->event.fork.ppid, -- cgit v1.2.3-59-g8ed1b From 5290ed6955ebc481d5cd62f7175e8514931058bc Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 25 Aug 2019 20:17:46 +0200 Subject: libperf: Add PERF_RECORD_LOST 'struct lost_event' to perf/event.h Move the lost_event event definition to libperf's event.h header include. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Perf added 'u*' types mainly to ease up printing __u64 values as stated in the linux/types.h comment: /* * We define u64 as uint64_t for every architecture * so that we can print it with "%"PRIx64 without getting warnings. * * typedef __u64 u64; * typedef __s64 s64; */ Add and use new PRI_lu64 and PRI_lx64 macros for that. Use extra '_' to ease up the reading and differentiate them from standard PRI*64 macros. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190825181752.722-7-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-sched.c | 2 +- tools/perf/lib/include/perf/event.h | 6 ++++++ tools/perf/util/event.c | 2 +- tools/perf/util/event.h | 6 ------ tools/perf/util/machine.c | 2 +- tools/perf/util/python.c | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 0d6b4c3b1a51..025151dcb651 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -2643,7 +2643,7 @@ static int process_lost(struct perf_tool *tool __maybe_unused, timestamp__scnprintf_usec(sample->time, tstr, sizeof(tstr)); printf("%15s ", tstr); - printf("lost %" PRIu64 " events on cpu %d\n", event->lost.lost, sample->cpu); + printf("lost %" PRI_lu64 " events on cpu %d\n", event->lost.lost, sample->cpu); return 0; } diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index c7cae58d2535..71045ea8214c 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -50,4 +50,10 @@ struct fork_event { __u64 time; }; +struct lost_event { + struct perf_event_header header; + __u64 id; + __u64 lost; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 0954f980574f..3bd9fc2a3ae8 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1480,7 +1480,7 @@ size_t perf_event__fprintf_switch(union perf_event *event, FILE *fp) static size_t perf_event__fprintf_lost(union perf_event *event, FILE *fp) { - return fprintf(fp, " lost %" PRIu64 "\n", event->lost.lost); + return fprintf(fp, " lost %" PRI_lu64 "\n", event->lost.lost); } size_t perf_event__fprintf_ksymbol(union perf_event *event, FILE *fp) diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 38b258cbbd90..4a3f50203d04 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -27,12 +27,6 @@ #define PRI_lx64 PRIx64 #endif -struct lost_event { - struct perf_event_header header; - u64 id; - u64 lost; -}; - struct lost_samples_event { struct perf_event_header header; u64 lost; diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 47430afd3c2d..1ad6e984c2f5 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -645,7 +645,7 @@ int machine__process_namespaces_event(struct machine *machine __maybe_unused, int machine__process_lost_event(struct machine *machine __maybe_unused, union perf_event *event, struct perf_sample *sample __maybe_unused) { - dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n", + dump_printf(": id:%" PRI_lu64 ": lost:%" PRI_lu64 "\n", event->lost.id, event->lost.lost); return 0; } diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 8bdadb24f6ba..5be85f50cd1c 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -263,8 +263,8 @@ static PyObject *pyrf_lost_event__repr(struct pyrf_event *pevent) PyObject *ret; char *s; - if (asprintf(&s, "{ type: lost, id: %#" PRIx64 ", " - "lost: %#" PRIx64 " }", + if (asprintf(&s, "{ type: lost, id: %#" PRI_lx64 ", " + "lost: %#" PRI_lx64 " }", pevent->event.lost.id, pevent->event.lost.lost) < 0) { ret = PyErr_NoMemory(); } else { -- cgit v1.2.3-59-g8ed1b From a2e254d84172f7eb638261a83024d849f78c89e9 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 25 Aug 2019 20:17:47 +0200 Subject: libperf: Add PERF_RECORD_LOST_SAMPLES 'struct lost_samples_event' to perf/event.h Move the PERF_RECORD_LOST_SAMPLES event definition into libperf's event.h header include. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Perf added 'u*' types mainly to ease up printing __u64 values as stated in the linux/types.h comment: /* * We define u64 as uint64_t for every architecture * so that we can print it with "%"PRIx64 without getting warnings. * * typedef __u64 u64; * typedef __s64 s64; */ Add and use new PRI_lu64 and PRI_lx64 macros for that. Use extra '_' to ease up the reading and differentiate them from standard PRI*64 macros. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190825181752.722-8-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 5 +++++ tools/perf/util/event.h | 5 ----- tools/perf/util/machine.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 71045ea8214c..86a779593405 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -56,4 +56,9 @@ struct lost_event { __u64 lost; }; +struct lost_samples_event { + struct perf_event_header header; + __u64 lost; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 4a3f50203d04..976a8f00d2a2 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -27,11 +27,6 @@ #define PRI_lx64 PRIx64 #endif -struct lost_samples_event { - struct perf_event_header header; - u64 lost; -}; - /* * PERF_FORMAT_ENABLED | PERF_FORMAT_RUNNING | PERF_FORMAT_ID */ diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 1ad6e984c2f5..823aaf7b1b83 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -653,7 +653,7 @@ int machine__process_lost_event(struct machine *machine __maybe_unused, int machine__process_lost_samples_event(struct machine *machine __maybe_unused, union perf_event *event, struct perf_sample *sample) { - dump_printf(": id:%" PRIu64 ": lost samples :%" PRIu64 "\n", + dump_printf(": id:%" PRIu64 ": lost samples :%" PRI_lu64 "\n", sample->id, event->lost_samples.lost); return 0; } -- cgit v1.2.3-59-g8ed1b From 213a6c1d20687d44acaa1cb4f77ce5bae4f1dd8f Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 25 Aug 2019 20:17:48 +0200 Subject: libperf: Add PERF_RECORD_READ 'struct read_event' to perf/event.h Move the PERF_RECORD_READ event definition to libperf's event.h header include. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Perf added 'u*' types mainly to ease up printing __u64 values as stated in the linux/types.h comment: /* * We define u64 as uint64_t for every architecture * so that we can print it with "%"PRIx64 without getting warnings. * * typedef __u64 u64; * typedef __s64 s64; */ Add and use new PRI_lu64 and PRI_lx64 macros for that. Use extra '_' to ease up the reading and differentiate them from standard PRI*64 macros. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190825181752.722-9-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 12 ++++++++++++ tools/perf/util/event.h | 12 ------------ tools/perf/util/session.c | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 86a779593405..f1830702e49a 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -61,4 +61,16 @@ struct lost_samples_event { __u64 lost; }; +/* + * PERF_FORMAT_ENABLED | PERF_FORMAT_RUNNING | PERF_FORMAT_ID + */ +struct read_event { + struct perf_event_header header; + __u32 pid, tid; + __u64 value; + __u64 time_enabled; + __u64 time_running; + __u64 id; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 976a8f00d2a2..008a2839d667 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -27,18 +27,6 @@ #define PRI_lx64 PRIx64 #endif -/* - * PERF_FORMAT_ENABLED | PERF_FORMAT_RUNNING | PERF_FORMAT_ID - */ -struct read_event { - struct perf_event_header header; - u32 pid, tid; - u64 value; - u64 time_enabled; - u64 time_running; - u64 id; -}; - struct throttle_event { struct perf_event_header header; u64 time; diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 82e0438a9160..cb1d8dcd0c19 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1260,7 +1260,7 @@ static void dump_read(struct evsel *evsel, union perf_event *event) if (!dump_trace) return; - printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, + printf(": %d %d %s %" PRI_lu64 "\n", event->read.pid, event->read.tid, perf_evsel__name(evsel), event->read.value); @@ -1270,13 +1270,13 @@ static void dump_read(struct evsel *evsel, union perf_event *event) read_format = evsel->core.attr.read_format; if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) - printf("... time enabled : %" PRIu64 "\n", read_event->time_enabled); + printf("... time enabled : %" PRI_lu64 "\n", read_event->time_enabled); if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) - printf("... time running : %" PRIu64 "\n", read_event->time_running); + printf("... time running : %" PRI_lu64 "\n", read_event->time_running); if (read_format & PERF_FORMAT_ID) - printf("... id : %" PRIu64 "\n", read_event->id); + printf("... id : %" PRI_lu64 "\n", read_event->id); } static struct machine *machines__find_for_cpumode(struct machines *machines, -- cgit v1.2.3-59-g8ed1b From 003c66fec28fea52825b60cad98af8cf11074d76 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 25 Aug 2019 20:17:49 +0200 Subject: libperf: Add PERF_RECORD_THROTTLE 'struct throttle_event' to perf/event.h Move the PERF_RECORD_THROTTLE event definition into libperf's event.h header include. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Perf added 'u*' types mainly to ease up printing __u64 values as stated in the linux/types.h comment: /* * We define u64 as uint64_t for every architecture * so that we can print it with "%"PRIx64 without getting warnings. * * typedef __u64 u64; * typedef __s64 s64; */ Add and use new PRI_lu64 and PRI_lx64 macros for that. Use extra '_' to ease up the reading and differentiate them from standard PRI*64 macros. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190825181752.722-10-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 7 +++++++ tools/perf/util/event.h | 7 ------- tools/perf/util/python.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index f1830702e49a..ef5ec66b566e 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -73,4 +73,11 @@ struct read_event { __u64 id; }; +struct throttle_event { + struct perf_event_header header; + __u64 time; + __u64 id; + __u64 stream_id; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 008a2839d667..40020f5b0484 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -27,13 +27,6 @@ #define PRI_lx64 PRIx64 #endif -struct throttle_event { - struct perf_event_header header; - u64 time; - u64 id; - u64 stream_id; -}; - #ifndef KSYM_NAME_LEN #define KSYM_NAME_LEN 256 #endif diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 5be85f50cd1c..d21e270c7823 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -233,8 +233,8 @@ static PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent) { struct throttle_event *te = (struct throttle_event *)(&pevent->event.header + 1); - return _PyUnicode_FromFormat("{ type: %sthrottle, time: %" PRIu64 ", id: %" PRIu64 - ", stream_id: %" PRIu64 " }", + return _PyUnicode_FromFormat("{ type: %sthrottle, time: %" PRI_lu64 ", id: %" PRI_lu64 + ", stream_id: %" PRI_lu64 " }", pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un", te->time, te->id, te->stream_id); } -- cgit v1.2.3-59-g8ed1b From f15e3c25a1b40794a0ef2647360afe873fe34f54 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 25 Aug 2019 20:17:50 +0200 Subject: libperf: Add PERF_RECORD_KSYMBOL 'struct ksymbol_event' to perf/event.h Move the PERF_RECORD_KSYMBOL event definition into libperf's event.h header include. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Perf added 'u*' types mainly to ease up printing __u64 values as stated in the linux/types.h comment: /* * We define u64 as uint64_t for every architecture * so that we can print it with "%"PRIx64 without getting warnings. * * typedef __u64 u64; * typedef __s64 s64; */ Add and use new PRI_lu64 and PRI_lx64 macros for that. Use extra '_' to ease up the reading and differentiate them from standard PRI*64 macros. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190825181752.722-11-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 13 +++++++++++++ tools/perf/util/event.c | 2 +- tools/perf/util/event.h | 13 ------------- 3 files changed, 14 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index ef5ec66b566e..8c367931cecc 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -80,4 +80,17 @@ struct throttle_event { __u64 stream_id; }; +#ifndef KSYM_NAME_LEN +#define KSYM_NAME_LEN 256 +#endif + +struct ksymbol_event { + struct perf_event_header header; + __u64 addr; + __u32 len; + __u16 ksym_type; + __u16 flags; + char name[KSYM_NAME_LEN]; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 3bd9fc2a3ae8..4447cd25e3f2 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1485,7 +1485,7 @@ static size_t perf_event__fprintf_lost(union perf_event *event, FILE *fp) size_t perf_event__fprintf_ksymbol(union perf_event *event, FILE *fp) { - return fprintf(fp, " addr %" PRIx64 " len %u type %u flags 0x%x name %s\n", + return fprintf(fp, " addr %" PRI_lx64 " len %u type %u flags 0x%x name %s\n", event->ksymbol_event.addr, event->ksymbol_event.len, event->ksymbol_event.ksym_type, event->ksymbol_event.flags, event->ksymbol_event.name); diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 40020f5b0484..c4eec1f164ba 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -27,19 +27,6 @@ #define PRI_lx64 PRIx64 #endif -#ifndef KSYM_NAME_LEN -#define KSYM_NAME_LEN 256 -#endif - -struct ksymbol_event { - struct perf_event_header header; - u64 addr; - u32 len; - u16 ksym_type; - u16 flags; - char name[KSYM_NAME_LEN]; -}; - struct bpf_event { struct perf_event_header header; u16 type; -- cgit v1.2.3-59-g8ed1b From b1b510142283c02991f48b27d399852364f7d89b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 25 Aug 2019 20:17:51 +0200 Subject: libperf: Add PERF_RECORD_BPF_EVENT 'struct bpf_event' to perf/event.h Move the PERF_RECORD_BPF_EVENT event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190825181752.722-12-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 11 +++++++++++ tools/perf/util/event.h | 10 ---------- 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 8c367931cecc..585c9d82dba3 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -5,6 +5,7 @@ #include #include #include +#include struct mmap_event { struct perf_event_header header; @@ -93,4 +94,14 @@ struct ksymbol_event { char name[KSYM_NAME_LEN]; }; +struct bpf_event { + struct perf_event_header header; + __u16 type; + __u16 flags; + __u32 id; + + /* for bpf_prog types */ + __u8 tag[BPF_TAG_SIZE]; // prog tag +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index c4eec1f164ba..091a0690a280 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -27,16 +27,6 @@ #define PRI_lx64 PRIx64 #endif -struct bpf_event { - struct perf_event_header header; - u16 type; - u16 flags; - u32 id; - - /* for bpf_prog types */ - u8 tag[BPF_TAG_SIZE]; // prog tag -}; - #define PERF_SAMPLE_MASK \ (PERF_SAMPLE_IP | PERF_SAMPLE_TID | \ PERF_SAMPLE_TIME | PERF_SAMPLE_ADDR | \ -- cgit v1.2.3-59-g8ed1b From b1fcd190bb3fc1234dca60390d171a4cc75b21b2 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 25 Aug 2019 20:17:52 +0200 Subject: libperf: Add PERF_RECORD_SAMPLE 'struct sample_event' to perf/event.h Move the PERF_RECORD_SAMPLE event definition to libperf's event.h header include. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190825181752.722-13-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 5 +++++ tools/perf/util/event.h | 5 ----- tools/perf/util/evlist.c | 2 +- tools/perf/util/evsel.c | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 585c9d82dba3..e768a2dfbe53 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -104,4 +104,9 @@ struct bpf_event { __u8 tag[BPF_TAG_SIZE]; // prog tag }; +struct sample_event { + struct perf_event_header header; + __u64 array[]; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 091a0690a280..dee0ee57efc2 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -37,11 +37,6 @@ /* perf sample has 16 bits size limit */ #define PERF_SAMPLE_MAX_SIZE (1 << 16) -struct sample_event { - struct perf_event_header header; - u64 array[]; -}; - struct regs_dump { u64 abi; u64 mask; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index ff415680fe0a..47bc54111f57 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -587,7 +587,7 @@ struct evsel *perf_evlist__id2evsel_strict(struct evlist *evlist, static int perf_evlist__event2id(struct evlist *evlist, union perf_event *event, u64 *id) { - const u64 *array = event->sample.array; + const __u64 *array = event->sample.array; ssize_t n; n = (event->header.size - sizeof(event->header)) >> 3; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 9fadd5857ccc..778262f68d5c 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2009,7 +2009,7 @@ static int perf_evsel__parse_id_sample(const struct evsel *evsel, struct perf_sample *sample) { u64 type = evsel->core.attr.sample_type; - const u64 *array = event->sample.array; + const __u64 *array = event->sample.array; bool swapped = evsel->needs_swap; union u64_swap u; @@ -2099,7 +2099,7 @@ int perf_evsel__parse_sample(struct evsel *evsel, union perf_event *event, { u64 type = evsel->core.attr.sample_type; bool swapped = evsel->needs_swap; - const u64 *array; + const __u64 *array; u16 max_size = event->header.size; const void *endp = (void *)event + max_size; u64 sz; @@ -2378,7 +2378,7 @@ int perf_evsel__parse_sample_timestamp(struct evsel *evsel, u64 *timestamp) { u64 type = evsel->core.attr.sample_type; - const u64 *array; + const __u64 *array; if (!(type & PERF_SAMPLE_TIME)) return -1; @@ -2529,7 +2529,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format, const struct perf_sample *sample) { - u64 *array; + __u64 *array; size_t sz; /* * used for cross-endian analysis. See git commit 65014ab3 -- cgit v1.2.3-59-g8ed1b From 69d81f09e1607b577346c0579bf938c1194bff3a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 26 Aug 2019 19:02:31 -0300 Subject: libperf: Rename the PERF_RECORD_ structs to have a "perf" suffix Even more, to have a "perf_record_" prefix, so that they match the PERF_RECORD_ enum they map to. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-qbabmcz2a0pkzt72liyuz3p8@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 24 ++++++++--------- tools/perf/tests/parse-no-sample-id-all.c | 4 +-- tools/perf/util/bpf-event.c | 12 ++++----- tools/perf/util/event.h | 30 ++++++++++----------- tools/perf/util/evsel.c | 4 +-- tools/perf/util/evsel.h | 2 +- tools/perf/util/intel-bts.c | 2 +- tools/perf/util/namespaces.c | 2 +- tools/perf/util/namespaces.h | 4 +-- tools/perf/util/python.c | 44 +++++++++++++++---------------- tools/perf/util/session.c | 2 +- tools/perf/util/thread.c | 4 +-- tools/perf/util/thread.h | 4 +-- 13 files changed, 69 insertions(+), 69 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index e768a2dfbe53..36ad3a4a79e6 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -7,7 +7,7 @@ #include #include -struct mmap_event { +struct perf_record_mmap { struct perf_event_header header; __u32 pid, tid; __u64 start; @@ -16,7 +16,7 @@ struct mmap_event { char filename[PATH_MAX]; }; -struct mmap2_event { +struct perf_record_mmap2 { struct perf_event_header header; __u32 pid, tid; __u64 start; @@ -31,33 +31,33 @@ struct mmap2_event { char filename[PATH_MAX]; }; -struct comm_event { +struct perf_record_comm { struct perf_event_header header; __u32 pid, tid; char comm[16]; }; -struct namespaces_event { +struct perf_record_namespaces { struct perf_event_header header; __u32 pid, tid; __u64 nr_namespaces; struct perf_ns_link_info link_info[]; }; -struct fork_event { +struct perf_record_fork { struct perf_event_header header; __u32 pid, ppid; __u32 tid, ptid; __u64 time; }; -struct lost_event { +struct perf_record_lost { struct perf_event_header header; __u64 id; __u64 lost; }; -struct lost_samples_event { +struct perf_record_lost_samples { struct perf_event_header header; __u64 lost; }; @@ -65,7 +65,7 @@ struct lost_samples_event { /* * PERF_FORMAT_ENABLED | PERF_FORMAT_RUNNING | PERF_FORMAT_ID */ -struct read_event { +struct perf_record_read { struct perf_event_header header; __u32 pid, tid; __u64 value; @@ -74,7 +74,7 @@ struct read_event { __u64 id; }; -struct throttle_event { +struct perf_record_throttle { struct perf_event_header header; __u64 time; __u64 id; @@ -85,7 +85,7 @@ struct throttle_event { #define KSYM_NAME_LEN 256 #endif -struct ksymbol_event { +struct perf_record_ksymbol { struct perf_event_header header; __u64 addr; __u32 len; @@ -94,7 +94,7 @@ struct ksymbol_event { char name[KSYM_NAME_LEN]; }; -struct bpf_event { +struct perf_record_bpf_event { struct perf_event_header header; __u16 type; __u16 flags; @@ -104,7 +104,7 @@ struct bpf_event { __u8 tag[BPF_TAG_SIZE]; // prog tag }; -struct sample_event { +struct perf_record_sample { struct perf_event_header header; __u64 array[]; }; diff --git a/tools/perf/tests/parse-no-sample-id-all.c b/tools/perf/tests/parse-no-sample-id-all.c index 396e40d68922..8284752a60c8 100644 --- a/tools/perf/tests/parse-no-sample-id-all.c +++ b/tools/perf/tests/parse-no-sample-id-all.c @@ -87,10 +87,10 @@ int test__parse_no_sample_id_all(struct test *test __maybe_unused, int subtest _ }, .id = 2, }; - struct mmap_event event3 = { + struct perf_record_mmap event3 = { .header = { .type = PERF_RECORD_MMAP, - .size = sizeof(struct mmap_event), + .size = sizeof(struct perf_record_mmap), }, }; union perf_event *events[] = { diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 5c634bcfea7e..3be8c480fa1f 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -161,8 +161,8 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session, union perf_event *event, struct record_opts *opts) { - struct ksymbol_event *ksymbol_event = &event->ksymbol_event; - struct bpf_event *bpf_event = &event->bpf_event; + struct perf_record_ksymbol *ksymbol_event = &event->ksymbol_event; + struct perf_record_bpf_event *bpf_event = &event->bpf_event; struct bpf_prog_info_linear *info_linear; struct perf_tool *tool = session->tool; struct bpf_prog_info_node *info_node; @@ -230,10 +230,10 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session, __u64 *prog_addrs = (__u64 *)(uintptr_t)(info->jited_ksyms); int name_len; - *ksymbol_event = (struct ksymbol_event){ + *ksymbol_event = (struct perf_record_ksymbol) { .header = { .type = PERF_RECORD_KSYMBOL, - .size = offsetof(struct ksymbol_event, name), + .size = offsetof(struct perf_record_ksymbol, name), }, .addr = prog_addrs[i], .len = prog_lens[i], @@ -254,10 +254,10 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session, if (!opts->no_bpf_event) { /* Synthesize PERF_RECORD_BPF_EVENT */ - *bpf_event = (struct bpf_event){ + *bpf_event = (struct perf_record_bpf_event) { .header = { .type = PERF_RECORD_BPF_EVENT, - .size = sizeof(struct bpf_event), + .size = sizeof(struct perf_record_bpf_event), }, .type = PERF_BPF_EVENT_PROG_LOAD, .flags = 0, diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index dee0ee57efc2..25f5309a3442 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -305,18 +305,18 @@ static inline void *perf_synth__raw_data(void *p) * when possible sends this number in a PERF_RECORD_LOST event. The number of * such "chunks" of lost events is stored in .nr_events[PERF_EVENT_LOST] while * total_lost tells exactly how many events the kernel in fact lost, i.e. it is - * the sum of all struct lost_event.lost fields reported. + * the sum of all struct perf_record_lost.lost fields reported. * * The kernel discards mixed up samples and sends the number in a * PERF_RECORD_LOST_SAMPLES event. The number of lost-samples events is stored * in .nr_events[PERF_RECORD_LOST_SAMPLES] while total_lost_samples tells * exactly how many samples the kernel in fact dropped, i.e. it is the sum of - * all struct lost_samples_event.lost fields reported. + * all struct perf_record_lost_samples.lost fields reported. * * The total_period is needed because by default auto-freq is used, so * multipling nr_events[PERF_EVENT_SAMPLE] by a frequency isn't possible to get * the total number of low level events, it is necessary to to sum all struct - * sample_event.period and stash the result in total_period. + * perf_record_sample.period and stash the result in total_period. */ struct events_stats { u64 total_period; @@ -550,16 +550,18 @@ struct compressed_event { union perf_event { struct perf_event_header header; - struct mmap_event mmap; - struct mmap2_event mmap2; - struct comm_event comm; - struct namespaces_event namespaces; - struct fork_event fork; - struct lost_event lost; - struct lost_samples_event lost_samples; - struct read_event read; - struct throttle_event throttle; - struct sample_event sample; + struct perf_record_mmap mmap; + struct perf_record_mmap2 mmap2; + struct perf_record_comm comm; + struct perf_record_namespaces namespaces; + struct perf_record_fork fork; + struct perf_record_lost lost; + struct perf_record_lost_samples lost_samples; + struct perf_record_read read; + struct perf_record_throttle throttle; + struct perf_record_sample sample; + struct perf_record_bpf_event bpf_event; + struct perf_record_ksymbol ksymbol_event; struct attr_event attr; struct event_update_event event_update; struct event_type_event event_type; @@ -579,8 +581,6 @@ union perf_event { struct stat_round_event stat_round; struct time_conv_event time_conv; struct feature_event feat; - struct ksymbol_event ksymbol_event; - struct bpf_event bpf_event; struct compressed_event pack; }; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 778262f68d5c..b3cfe120d097 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -117,7 +117,7 @@ int __perf_evsel__sample_size(u64 sample_type) * * This function returns the position of the event id (PERF_SAMPLE_ID or * PERF_SAMPLE_IDENTIFIER) in a sample event i.e. in the array of struct - * sample_event. + * perf_record_sample. */ static int __perf_evsel__calc_id_pos(u64 sample_type) { @@ -2420,7 +2420,7 @@ int perf_evsel__parse_sample_timestamp(struct evsel *evsel, size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, u64 read_format) { - size_t sz, result = sizeof(struct sample_event); + size_t sz, result = sizeof(struct perf_record_sample); if (type & PERF_SAMPLE_IDENTIFIER) result += sizeof(u64); diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 5a351cae66df..77e07f2486d3 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -107,7 +107,7 @@ struct xyarray; * show the name used, not some alias. * @id_pos: the position of the event id (PERF_SAMPLE_ID or * PERF_SAMPLE_IDENTIFIER) in a sample event i.e. in the array of - * struct sample_event + * struct perf_record_sample * @is_pos: the position (counting backwards) of the event id (PERF_SAMPLE_ID or * PERF_SAMPLE_IDENTIFIER) in a non-sample event i.e. if sample_id_all * is used there is an id sample appended to non-sample events diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index 7eb9e6dc27dd..8dc6408206b9 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c @@ -818,7 +818,7 @@ static int intel_bts_synth_events(struct intel_bts *bts, * We only use sample types from PERF_SAMPLE_MASK so we can use * __perf_evsel__sample_size() here. */ - bts->branches_event_size = sizeof(struct sample_event) + + bts->branches_event_size = sizeof(struct perf_record_sample) + __perf_evsel__sample_size(attr.sample_type); } diff --git a/tools/perf/util/namespaces.c b/tools/perf/util/namespaces.c index 46d3a7754897..99be15dd2b6b 100644 --- a/tools/perf/util/namespaces.c +++ b/tools/perf/util/namespaces.c @@ -19,7 +19,7 @@ #include #include -struct namespaces *namespaces__new(struct namespaces_event *event) +struct namespaces *namespaces__new(struct perf_record_namespaces *event) { struct namespaces *namespaces; u64 link_info_size = ((event ? event->nr_namespaces : NR_NAMESPACES) * diff --git a/tools/perf/util/namespaces.h b/tools/perf/util/namespaces.h index 004430c0de93..40edef56cb52 100644 --- a/tools/perf/util/namespaces.h +++ b/tools/perf/util/namespaces.h @@ -17,7 +17,7 @@ int setns(int fd, int nstype); #endif -struct namespaces_event; +struct perf_record_namespaces; struct namespaces { struct list_head list; @@ -25,7 +25,7 @@ struct namespaces { struct perf_ns_link_info link_info[]; }; -struct namespaces *namespaces__new(struct namespaces_event *event); +struct namespaces *namespaces__new(struct perf_record_namespaces *event); void namespaces__free(struct namespaces *namespaces); struct nsinfo { diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index d21e270c7823..59974e901232 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -116,12 +116,12 @@ static PyMemberDef pyrf_mmap_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), member_def(perf_event_header, misc, T_UINT, "event misc"), - member_def(mmap_event, pid, T_UINT, "event pid"), - member_def(mmap_event, tid, T_UINT, "event tid"), - member_def(mmap_event, start, T_ULONGLONG, "start of the map"), - member_def(mmap_event, len, T_ULONGLONG, "map length"), - member_def(mmap_event, pgoff, T_ULONGLONG, "page offset"), - member_def(mmap_event, filename, T_STRING_INPLACE, "backing store"), + member_def(perf_record_mmap, pid, T_UINT, "event pid"), + member_def(perf_record_mmap, tid, T_UINT, "event tid"), + member_def(perf_record_mmap, start, T_ULONGLONG, "start of the map"), + member_def(perf_record_mmap, len, T_ULONGLONG, "map length"), + member_def(perf_record_mmap, pgoff, T_ULONGLONG, "page offset"), + member_def(perf_record_mmap, filename, T_STRING_INPLACE, "backing store"), { .name = NULL, }, }; @@ -159,11 +159,11 @@ static char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event obje static PyMemberDef pyrf_task_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), - member_def(fork_event, pid, T_UINT, "event pid"), - member_def(fork_event, ppid, T_UINT, "event ppid"), - member_def(fork_event, tid, T_UINT, "event tid"), - member_def(fork_event, ptid, T_UINT, "event ptid"), - member_def(fork_event, time, T_ULONGLONG, "timestamp"), + member_def(perf_record_fork, pid, T_UINT, "event pid"), + member_def(perf_record_fork, ppid, T_UINT, "event ppid"), + member_def(perf_record_fork, tid, T_UINT, "event tid"), + member_def(perf_record_fork, ptid, T_UINT, "event ptid"), + member_def(perf_record_fork, time, T_ULONGLONG, "timestamp"), { .name = NULL, }, }; @@ -194,9 +194,9 @@ static char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object."); static PyMemberDef pyrf_comm_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), - member_def(comm_event, pid, T_UINT, "event pid"), - member_def(comm_event, tid, T_UINT, "event tid"), - member_def(comm_event, comm, T_STRING_INPLACE, "process name"), + member_def(perf_record_comm, pid, T_UINT, "event pid"), + member_def(perf_record_comm, tid, T_UINT, "event tid"), + member_def(perf_record_comm, comm, T_STRING_INPLACE, "process name"), { .name = NULL, }, }; @@ -223,15 +223,15 @@ static char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object." static PyMemberDef pyrf_throttle_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), - member_def(throttle_event, time, T_ULONGLONG, "timestamp"), - member_def(throttle_event, id, T_ULONGLONG, "event id"), - member_def(throttle_event, stream_id, T_ULONGLONG, "event stream id"), + member_def(perf_record_throttle, time, T_ULONGLONG, "timestamp"), + member_def(perf_record_throttle, id, T_ULONGLONG, "event id"), + member_def(perf_record_throttle, stream_id, T_ULONGLONG, "event stream id"), { .name = NULL, }, }; static PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent) { - struct throttle_event *te = (struct throttle_event *)(&pevent->event.header + 1); + struct perf_record_throttle *te = (struct perf_record_throttle *)(&pevent->event.header + 1); return _PyUnicode_FromFormat("{ type: %sthrottle, time: %" PRI_lu64 ", id: %" PRI_lu64 ", stream_id: %" PRI_lu64 " }", @@ -253,8 +253,8 @@ static char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object."); static PyMemberDef pyrf_lost_event__members[] = { sample_members - member_def(lost_event, id, T_ULONGLONG, "event id"), - member_def(lost_event, lost, T_ULONGLONG, "number of lost events"), + member_def(perf_record_lost, id, T_ULONGLONG, "event id"), + member_def(perf_record_lost, lost, T_ULONGLONG, "number of lost events"), { .name = NULL, }, }; @@ -288,8 +288,8 @@ static char pyrf_read_event__doc[] = PyDoc_STR("perf read event object."); static PyMemberDef pyrf_read_event__members[] = { sample_members - member_def(read_event, pid, T_UINT, "event pid"), - member_def(read_event, tid, T_UINT, "event tid"), + member_def(perf_record_read, pid, T_UINT, "event pid"), + member_def(perf_record_read, tid, T_UINT, "event tid"), { .name = NULL, }, }; diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index cb1d8dcd0c19..4bfec9db36d6 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1254,7 +1254,7 @@ static void dump_sample(struct evsel *evsel, union perf_event *event, static void dump_read(struct evsel *evsel, union perf_event *event) { - struct read_event *read_event = &event->read; + struct perf_record_read *read_event = &event->read; u64 read_format; if (!dump_trace) diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index bbf7816cba31..dbcb9cfb0f2f 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -169,7 +169,7 @@ struct namespaces *thread__namespaces(struct thread *thread) } static int __thread__set_namespaces(struct thread *thread, u64 timestamp, - struct namespaces_event *event) + struct perf_record_namespaces *event) { struct namespaces *new, *curr = __thread__namespaces(thread); @@ -193,7 +193,7 @@ static int __thread__set_namespaces(struct thread *thread, u64 timestamp, } int thread__set_namespaces(struct thread *thread, u64 timestamp, - struct namespaces_event *event) + struct perf_record_namespaces *event) { int ret; diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index bf06113be4f3..51bdb9a7af7f 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -16,7 +16,7 @@ struct addr_location; struct map; -struct namespaces_event; +struct perf_record_namespaces; struct thread_stack; struct unwind_libunwind_ops; @@ -74,7 +74,7 @@ static inline void thread__exited(struct thread *thread) struct namespaces *thread__namespaces(struct thread *thread); int thread__set_namespaces(struct thread *thread, u64 timestamp, - struct namespaces_event *event); + struct perf_record_namespaces *event); int __thread__set_comm(struct thread *thread, const char *comm, u64 timestamp, bool exec); -- cgit v1.2.3-59-g8ed1b From ebdba16e95f728e94dba07fe0f1221b0e8efdb9d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 26 Aug 2019 19:15:18 -0300 Subject: perf tools: Rename perf_event::ksymbol_event to perf_event::ksymbol Just like all the other meta events, that extra _event suffix is just redundant, ditch it. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Song Liu Link: https://lkml.kernel.org/n/tip-0q8b2xnfs17q0g523oej75s0@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf-event.c | 2 +- tools/perf/util/event.c | 6 +++--- tools/perf/util/event.h | 2 +- tools/perf/util/machine.c | 16 ++++++++-------- 4 files changed, 13 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 3be8c480fa1f..69795c32ecf3 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -161,7 +161,7 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session, union perf_event *event, struct record_opts *opts) { - struct perf_record_ksymbol *ksymbol_event = &event->ksymbol_event; + struct perf_record_ksymbol *ksymbol_event = &event->ksymbol; struct perf_record_bpf_event *bpf_event = &event->bpf_event; struct bpf_prog_info_linear *info_linear; struct perf_tool *tool = session->tool; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 4447cd25e3f2..bdeaad434e52 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1486,9 +1486,9 @@ static size_t perf_event__fprintf_lost(union perf_event *event, FILE *fp) size_t perf_event__fprintf_ksymbol(union perf_event *event, FILE *fp) { return fprintf(fp, " addr %" PRI_lx64 " len %u type %u flags 0x%x name %s\n", - event->ksymbol_event.addr, event->ksymbol_event.len, - event->ksymbol_event.ksym_type, - event->ksymbol_event.flags, event->ksymbol_event.name); + event->ksymbol.addr, event->ksymbol.len, + event->ksymbol.ksym_type, + event->ksymbol.flags, event->ksymbol.name); } size_t perf_event__fprintf_bpf_event(union perf_event *event, FILE *fp) diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 25f5309a3442..34190e01f307 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -561,7 +561,7 @@ union perf_event { struct perf_record_throttle throttle; struct perf_record_sample sample; struct perf_record_bpf_event bpf_event; - struct perf_record_ksymbol ksymbol_event; + struct perf_record_ksymbol ksymbol; struct attr_event attr; struct event_update_event event_update; struct event_type_event event_type; diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 823aaf7b1b83..86b7fd24b1e1 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -713,20 +713,20 @@ static int machine__process_ksymbol_register(struct machine *machine, struct symbol *sym; struct map *map; - map = map_groups__find(&machine->kmaps, event->ksymbol_event.addr); + map = map_groups__find(&machine->kmaps, event->ksymbol.addr); if (!map) { - map = dso__new_map(event->ksymbol_event.name); + map = dso__new_map(event->ksymbol.name); if (!map) return -ENOMEM; - map->start = event->ksymbol_event.addr; - map->end = map->start + event->ksymbol_event.len; + map->start = event->ksymbol.addr; + map->end = map->start + event->ksymbol.len; map_groups__insert(&machine->kmaps, map); } sym = symbol__new(map->map_ip(map, map->start), - event->ksymbol_event.len, - 0, 0, event->ksymbol_event.name); + event->ksymbol.len, + 0, 0, event->ksymbol.name); if (!sym) return -ENOMEM; dso__insert_symbol(map->dso, sym); @@ -739,7 +739,7 @@ static int machine__process_ksymbol_unregister(struct machine *machine, { struct map *map; - map = map_groups__find(&machine->kmaps, event->ksymbol_event.addr); + map = map_groups__find(&machine->kmaps, event->ksymbol.addr); if (map) map_groups__remove(&machine->kmaps, map); @@ -753,7 +753,7 @@ int machine__process_ksymbol(struct machine *machine __maybe_unused, if (dump_trace) perf_event__fprintf_ksymbol(event, stdout); - if (event->ksymbol_event.flags & PERF_RECORD_KSYMBOL_FLAGS_UNREGISTER) + if (event->ksymbol.flags & PERF_RECORD_KSYMBOL_FLAGS_UNREGISTER) return machine__process_ksymbol_unregister(machine, event, sample); return machine__process_ksymbol_register(machine, event, sample); -- cgit v1.2.3-59-g8ed1b From 6a1b359821eb8d929c4dd9f53178da84888d79ec Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 26 Aug 2019 19:20:35 -0300 Subject: perf tools: Rename perf_event::bpf_event to perf_event::bpf Just like all the other meta events, that extra _event suffix is just redundant, ditch it. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Song Liu Link: https://lkml.kernel.org/n/tip-505qwpaizq1k0t6pk13v1ibd@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf-event.c | 18 ++++++++---------- tools/perf/util/event.c | 3 +-- tools/perf/util/event.h | 2 +- 3 files changed, 10 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 69795c32ecf3..28fa2b1ce66e 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -35,7 +35,7 @@ static int machine__process_bpf_event_load(struct machine *machine, struct bpf_prog_info_linear *info_linear; struct bpf_prog_info_node *info_node; struct perf_env *env = machine->env; - int id = event->bpf_event.id; + int id = event->bpf.id; unsigned int i; /* perf-record, no need to handle bpf-event */ @@ -71,7 +71,7 @@ int machine__process_bpf_event(struct machine *machine __maybe_unused, if (dump_trace) perf_event__fprintf_bpf_event(event, stdout); - switch (event->bpf_event.type) { + switch (event->bpf.type) { case PERF_BPF_EVENT_PROG_LOAD: return machine__process_bpf_event_load(machine, event, sample); @@ -83,8 +83,7 @@ int machine__process_bpf_event(struct machine *machine __maybe_unused, */ break; default: - pr_debug("unexpected bpf_event type of %d\n", - event->bpf_event.type); + pr_debug("unexpected bpf_event type of %d\n", event->bpf.type); break; } return 0; @@ -162,7 +161,7 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session, struct record_opts *opts) { struct perf_record_ksymbol *ksymbol_event = &event->ksymbol; - struct perf_record_bpf_event *bpf_event = &event->bpf_event; + struct perf_record_bpf_event *bpf_event = &event->bpf; struct bpf_prog_info_linear *info_linear; struct perf_tool *tool = session->tool; struct bpf_prog_info_node *info_node; @@ -302,7 +301,7 @@ int perf_event__synthesize_bpf_events(struct perf_session *session, int err; int fd; - event = malloc(sizeof(event->bpf_event) + KSYM_NAME_LEN + machine->id_hdr_size); + event = malloc(sizeof(event->bpf) + KSYM_NAME_LEN + machine->id_hdr_size); if (!event) return -1; while (true) { @@ -399,9 +398,9 @@ static int bpf_event__sb_cb(union perf_event *event, void *data) if (event->header.type != PERF_RECORD_BPF_EVENT) return -1; - switch (event->bpf_event.type) { + switch (event->bpf.type) { case PERF_BPF_EVENT_PROG_LOAD: - perf_env__add_bpf_info(env, event->bpf_event.id); + perf_env__add_bpf_info(env, event->bpf.id); case PERF_BPF_EVENT_PROG_UNLOAD: /* @@ -411,8 +410,7 @@ static int bpf_event__sb_cb(union perf_event *event, void *data) */ break; default: - pr_debug("unexpected bpf_event type of %d\n", - event->bpf_event.type); + pr_debug("unexpected bpf_event type of %d\n", event->bpf.type); break; } diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index bdeaad434e52..17304df44fc2 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1494,8 +1494,7 @@ size_t perf_event__fprintf_ksymbol(union perf_event *event, FILE *fp) size_t perf_event__fprintf_bpf_event(union perf_event *event, FILE *fp) { return fprintf(fp, " type %u, flags %u, id %u\n", - event->bpf_event.type, event->bpf_event.flags, - event->bpf_event.id); + event->bpf.type, event->bpf.flags, event->bpf.id); } size_t perf_event__fprintf(union perf_event *event, FILE *fp) diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 34190e01f307..7251e2eee441 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -560,7 +560,7 @@ union perf_event { struct perf_record_read read; struct perf_record_throttle throttle; struct perf_record_sample sample; - struct perf_record_bpf_event bpf_event; + struct perf_record_bpf_event bpf; struct perf_record_ksymbol ksymbol; struct attr_event attr; struct event_update_event event_update; -- cgit v1.2.3-59-g8ed1b From 3f604b5f61dbff80725392c99827d6617f7bb180 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 26 Aug 2019 19:28:13 -0300 Subject: perf tool: Rename perf_tool::bpf_event to bpf No need for that _event suffix, do just like all the other meta event handlers and suppress that suffix. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Song Liu Link: https://lkml.kernel.org/n/tip-03spzxtqafbabbbmnm7y4xfx@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 4 ++-- tools/perf/util/bpf-event.c | 11 +++++------ tools/perf/util/bpf-event.h | 10 +++++----- tools/perf/util/event.c | 14 +++++++------- tools/perf/util/event.h | 10 +++++----- tools/perf/util/machine.c | 2 +- tools/perf/util/session.c | 6 +++--- tools/perf/util/tool.h | 2 +- 8 files changed, 29 insertions(+), 30 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 6f389b33fbe5..51e7e6d0eee6 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -2492,8 +2492,8 @@ static int __cmd_script(struct perf_script *script) script->tool.finished_round = process_finished_round_event; } if (script->show_bpf_events) { - script->tool.ksymbol = process_bpf_events; - script->tool.bpf_event = process_bpf_events; + script->tool.ksymbol = process_bpf_events; + script->tool.bpf = process_bpf_events; } if (perf_script__setup_per_event_dump(script)) { diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 28fa2b1ce66e..2d6d500c9af7 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -64,12 +64,11 @@ static int machine__process_bpf_event_load(struct machine *machine, return 0; } -int machine__process_bpf_event(struct machine *machine __maybe_unused, - union perf_event *event, - struct perf_sample *sample __maybe_unused) +int machine__process_bpf(struct machine *machine, union perf_event *event, + struct perf_sample *sample) { if (dump_trace) - perf_event__fprintf_bpf_event(event, stdout); + perf_event__fprintf_bpf(event, stdout); switch (event->bpf.type) { case PERF_BPF_EVENT_PROG_LOAD: @@ -83,7 +82,7 @@ int machine__process_bpf_event(struct machine *machine __maybe_unused, */ break; default: - pr_debug("unexpected bpf_event type of %d\n", event->bpf.type); + pr_debug("unexpected bpf event type of %d\n", event->bpf.type); break; } return 0; @@ -410,7 +409,7 @@ static int bpf_event__sb_cb(union perf_event *event, void *data) */ break; default: - pr_debug("unexpected bpf_event type of %d\n", event->bpf.type); + pr_debug("unexpected bpf event type of %d\n", event->bpf.type); break; } diff --git a/tools/perf/util/bpf-event.h b/tools/perf/util/bpf-event.h index 26ab9239f986..417b78835ea0 100644 --- a/tools/perf/util/bpf-event.h +++ b/tools/perf/util/bpf-event.h @@ -30,8 +30,8 @@ struct btf_node { }; #ifdef HAVE_LIBBPF_SUPPORT -int machine__process_bpf_event(struct machine *machine, union perf_event *event, - struct perf_sample *sample); +int machine__process_bpf(struct machine *machine, union perf_event *event, + struct perf_sample *sample); int perf_event__synthesize_bpf_events(struct perf_session *session, perf_event__handler_t process, @@ -43,9 +43,9 @@ void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info, struct perf_env *env, FILE *fp); #else -static inline int machine__process_bpf_event(struct machine *machine __maybe_unused, - union perf_event *event __maybe_unused, - struct perf_sample *sample __maybe_unused) +static inline int machine__process_bpf(struct machine *machine __maybe_unused, + union perf_event *event __maybe_unused, + struct perf_sample *sample __maybe_unused) { return 0; } diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 17304df44fc2..33616ea62a47 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1343,12 +1343,12 @@ int perf_event__process_ksymbol(struct perf_tool *tool __maybe_unused, return machine__process_ksymbol(machine, event, sample); } -int perf_event__process_bpf_event(struct perf_tool *tool __maybe_unused, - union perf_event *event, - struct perf_sample *sample __maybe_unused, - struct machine *machine) +int perf_event__process_bpf(struct perf_tool *tool __maybe_unused, + union perf_event *event, + struct perf_sample *sample, + struct machine *machine) { - return machine__process_bpf_event(machine, event, sample); + return machine__process_bpf(machine, event, sample); } size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) @@ -1491,7 +1491,7 @@ size_t perf_event__fprintf_ksymbol(union perf_event *event, FILE *fp) event->ksymbol.flags, event->ksymbol.name); } -size_t perf_event__fprintf_bpf_event(union perf_event *event, FILE *fp) +size_t perf_event__fprintf_bpf(union perf_event *event, FILE *fp) { return fprintf(fp, " type %u, flags %u, id %u\n", event->bpf.type, event->bpf.flags, event->bpf.id); @@ -1536,7 +1536,7 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp) ret += perf_event__fprintf_ksymbol(event, fp); break; case PERF_RECORD_BPF_EVENT: - ret += perf_event__fprintf_bpf_event(event, fp); + ret += perf_event__fprintf_bpf(event, fp); break; default: ret += fprintf(fp, "\n"); diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 7251e2eee441..429a3fe52d6c 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -683,10 +683,10 @@ int perf_event__process_ksymbol(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine); -int perf_event__process_bpf_event(struct perf_tool *tool, - union perf_event *event, - struct perf_sample *sample, - struct machine *machine); +int perf_event__process_bpf(struct perf_tool *tool, + union perf_event *event, + struct perf_sample *sample, + struct machine *machine); int perf_tool__process_synth_event(struct perf_tool *tool, union perf_event *event, struct machine *machine, @@ -751,7 +751,7 @@ size_t perf_event__fprintf_thread_map(union perf_event *event, FILE *fp); size_t perf_event__fprintf_cpu_map(union perf_event *event, FILE *fp); size_t perf_event__fprintf_namespaces(union perf_event *event, FILE *fp); size_t perf_event__fprintf_ksymbol(union perf_event *event, FILE *fp); -size_t perf_event__fprintf_bpf_event(union perf_event *event, FILE *fp); +size_t perf_event__fprintf_bpf(union perf_event *event, FILE *fp); size_t perf_event__fprintf(union perf_event *event, FILE *fp); int kallsyms__get_function_start(const char *kallsyms_filename, diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 86b7fd24b1e1..93483f1764d3 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1922,7 +1922,7 @@ int machine__process_event(struct machine *machine, union perf_event *event, case PERF_RECORD_KSYMBOL: ret = machine__process_ksymbol(machine, event, sample); break; case PERF_RECORD_BPF_EVENT: - ret = machine__process_bpf_event(machine, event, sample); break; + ret = machine__process_bpf(machine, event, sample); break; default: ret = -1; break; diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 4bfec9db36d6..5786e9c807c5 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -473,8 +473,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) tool->context_switch = perf_event__process_switch; if (tool->ksymbol == NULL) tool->ksymbol = perf_event__process_ksymbol; - if (tool->bpf_event == NULL) - tool->bpf_event = perf_event__process_bpf_event; + if (tool->bpf == NULL) + tool->bpf = perf_event__process_bpf; if (tool->read == NULL) tool->read = process_event_sample_stub; if (tool->throttle == NULL) @@ -1452,7 +1452,7 @@ static int machines__deliver_event(struct machines *machines, case PERF_RECORD_KSYMBOL: return tool->ksymbol(tool, event, sample, machine); case PERF_RECORD_BPF_EVENT: - return tool->bpf_event(tool, event, sample, machine); + return tool->bpf(tool, event, sample, machine); default: ++evlist->stats.nr_unknown_events; return -1; diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h index 7f95dd1d6883..2abbf668b8de 100644 --- a/tools/perf/util/tool.h +++ b/tools/perf/util/tool.h @@ -56,7 +56,7 @@ struct perf_tool { throttle, unthrottle, ksymbol, - bpf_event; + bpf; event_attr_op attr; event_attr_op event_update; -- cgit v1.2.3-59-g8ed1b From 74a1e863eb73dcc9f069b671dfb40650f3832116 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 26 Aug 2019 19:31:06 -0300 Subject: perf evsel: Rename perf_missing_features::bpf_event to ::bpf No need for that _event suffix, do just like all the other meta events and do away with that. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Song Liu Link: https://lkml.kernel.org/n/tip-bvc83f380dva83wlg52yd10t@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 9 ++++----- tools/perf/util/evsel.h | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index b3cfe120d097..fa676355559e 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1072,8 +1072,7 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts, attr->mmap2 = track && !perf_missing_features.mmap2; attr->comm = track; attr->ksymbol = track && !perf_missing_features.ksymbol; - attr->bpf_event = track && !opts->no_bpf_event && - !perf_missing_features.bpf_event; + attr->bpf_event = track && !opts->no_bpf_event && !perf_missing_features.bpf; if (opts->record_namespaces) attr->namespaces = track; @@ -1803,7 +1802,7 @@ fallback_missing_features: evsel->core.attr.read_format &= ~(PERF_FORMAT_GROUP|PERF_FORMAT_ID); if (perf_missing_features.ksymbol) evsel->core.attr.ksymbol = 0; - if (perf_missing_features.bpf_event) + if (perf_missing_features.bpf) evsel->core.attr.bpf_event = 0; retry_sample_id: if (perf_missing_features.sample_id_all) @@ -1920,8 +1919,8 @@ try_fallback: perf_missing_features.aux_output = true; pr_debug2("Kernel has no attr.aux_output support, bailing out\n"); goto out_close; - } else if (!perf_missing_features.bpf_event && evsel->core.attr.bpf_event) { - perf_missing_features.bpf_event = true; + } else if (!perf_missing_features.bpf && evsel->core.attr.bpf_event) { + perf_missing_features.bpf = true; pr_debug2("switching off bpf_event\n"); goto fallback_missing_features; } else if (!perf_missing_features.ksymbol && evsel->core.attr.ksymbol) { diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 77e07f2486d3..fd60caced4fc 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -194,7 +194,7 @@ struct perf_missing_features { bool write_backward; bool group_read; bool ksymbol; - bool bpf_event; + bool bpf; bool aux_output; }; -- cgit v1.2.3-59-g8ed1b From 0fc2e0b84ba725c5e6ee66059936638389e67c80 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Thu, 22 Aug 2019 22:52:13 -0700 Subject: tools/bpf: sync bpf.h sync bpf.h from kernel/ to tools/ Signed-off-by: Alexei Starovoitov Acked-by: Song Liu Signed-off-by: Daniel Borkmann --- tools/include/uapi/linux/bpf.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index b5889257cc33..5d2fb183ee2d 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -285,6 +285,9 @@ enum bpf_attach_type { */ #define BPF_F_TEST_RND_HI32 (1U << 2) +/* The verifier internal test flag. Behavior is undefined */ +#define BPF_F_TEST_STATE_FREQ (1U << 3) + /* When BPF ldimm64's insn[0].src_reg != 0 then this can have * two extensions: * -- cgit v1.2.3-59-g8ed1b From e8c13c4d9b36065903a025f163db87a7afff7307 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Thu, 22 Aug 2019 22:52:14 -0700 Subject: selftests/bpf: verifier precise tests Use BPF_F_TEST_STATE_FREQ flag to check that precision tracking works as expected by comparing every step it takes. Signed-off-by: Alexei Starovoitov Acked-by: Song Liu Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/test_verifier.c | 68 +++++++++++--- tools/testing/selftests/bpf/verifier/precise.c | 117 +++++++++++++++++++++++++ 2 files changed, 174 insertions(+), 11 deletions(-) create mode 100644 tools/testing/selftests/bpf/verifier/precise.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index 44e2d640b088..d27fd929abb9 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c @@ -61,6 +61,7 @@ #define UNPRIV_SYSCTL "kernel/unprivileged_bpf_disabled" static bool unpriv_disabled = false; static int skips; +static bool verbose = false; struct bpf_test { const char *descr; @@ -92,7 +93,8 @@ struct bpf_test { enum { UNDEF, ACCEPT, - REJECT + REJECT, + VERBOSE_ACCEPT, } result, result_unpriv; enum bpf_prog_type prog_type; uint8_t flags; @@ -859,6 +861,36 @@ static int do_prog_test_run(int fd_prog, bool unpriv, uint32_t expected_val, return 0; } +static bool cmp_str_seq(const char *log, const char *exp) +{ + char needle[80]; + const char *p, *q; + int len; + + do { + p = strchr(exp, '\t'); + if (!p) + p = exp + strlen(exp); + + len = p - exp; + if (len >= sizeof(needle) || !len) { + printf("FAIL\nTestcase bug\n"); + return false; + } + strncpy(needle, exp, len); + needle[len] = 0; + q = strstr(log, needle); + if (!q) { + printf("FAIL\nUnexpected verifier log in successful load!\n" + "EXP: %s\nRES:\n", needle); + return false; + } + log = q + len; + exp = p + 1; + } while (*p); + return true; +} + static void do_test_single(struct bpf_test *test, bool unpriv, int *passes, int *errors) { @@ -897,14 +929,20 @@ static void do_test_single(struct bpf_test *test, bool unpriv, pflags |= BPF_F_STRICT_ALIGNMENT; if (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS) pflags |= BPF_F_ANY_ALIGNMENT; + if (test->flags & ~3) + pflags |= test->flags; + expected_ret = unpriv && test->result_unpriv != UNDEF ? + test->result_unpriv : test->result; + expected_err = unpriv && test->errstr_unpriv ? + test->errstr_unpriv : test->errstr; memset(&attr, 0, sizeof(attr)); attr.prog_type = prog_type; attr.expected_attach_type = test->expected_attach_type; attr.insns = prog; attr.insns_cnt = prog_len; attr.license = "GPL"; - attr.log_level = 4; + attr.log_level = verbose || expected_ret == VERBOSE_ACCEPT ? 1 : 4; attr.prog_flags = pflags; fd_prog = bpf_load_program_xattr(&attr, bpf_vlog, sizeof(bpf_vlog)); @@ -914,14 +952,9 @@ static void do_test_single(struct bpf_test *test, bool unpriv, goto close_fds; } - expected_ret = unpriv && test->result_unpriv != UNDEF ? - test->result_unpriv : test->result; - expected_err = unpriv && test->errstr_unpriv ? - test->errstr_unpriv : test->errstr; - alignment_prevented_execution = 0; - if (expected_ret == ACCEPT) { + if (expected_ret == ACCEPT || expected_ret == VERBOSE_ACCEPT) { if (fd_prog < 0) { printf("FAIL\nFailed to load prog '%s'!\n", strerror(errno)); @@ -932,6 +965,9 @@ static void do_test_single(struct bpf_test *test, bool unpriv, (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS)) alignment_prevented_execution = 1; #endif + if (expected_ret == VERBOSE_ACCEPT && !cmp_str_seq(bpf_vlog, expected_err)) { + goto fail_log; + } } else { if (fd_prog >= 0) { printf("FAIL\nUnexpected success to load!\n"); @@ -957,6 +993,9 @@ static void do_test_single(struct bpf_test *test, bool unpriv, } } + if (verbose) + printf(", verifier log:\n%s", bpf_vlog); + run_errs = 0; run_successes = 0; if (!alignment_prevented_execution && fd_prog >= 0) { @@ -1097,17 +1136,24 @@ int main(int argc, char **argv) { unsigned int from = 0, to = ARRAY_SIZE(tests); bool unpriv = !is_admin(); + int arg = 1; + + if (argc > 1 && strcmp(argv[1], "-v") == 0) { + arg++; + verbose = true; + argc--; + } if (argc == 3) { - unsigned int l = atoi(argv[argc - 2]); - unsigned int u = atoi(argv[argc - 1]); + unsigned int l = atoi(argv[arg]); + unsigned int u = atoi(argv[arg + 1]); if (l < to && u < to) { from = l; to = u + 1; } } else if (argc == 2) { - unsigned int t = atoi(argv[argc - 1]); + unsigned int t = atoi(argv[arg]); if (t < to) { from = t; diff --git a/tools/testing/selftests/bpf/verifier/precise.c b/tools/testing/selftests/bpf/verifier/precise.c new file mode 100644 index 000000000000..a20953c23721 --- /dev/null +++ b/tools/testing/selftests/bpf/verifier/precise.c @@ -0,0 +1,117 @@ +{ + "precise: test 1", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_LD_MAP_FD(BPF_REG_6, 0), + BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), + BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), + BPF_ST_MEM(BPF_DW, BPF_REG_FP, -8, 0), + BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), + BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), + BPF_EXIT_INSN(), + + BPF_MOV64_REG(BPF_REG_9, BPF_REG_0), + + BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), + BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), + BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), + BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), + BPF_EXIT_INSN(), + + BPF_MOV64_REG(BPF_REG_8, BPF_REG_0), + + BPF_ALU64_REG(BPF_SUB, BPF_REG_9, BPF_REG_8), /* map_value_ptr -= map_value_ptr */ + BPF_MOV64_REG(BPF_REG_2, BPF_REG_9), + BPF_JMP_IMM(BPF_JLT, BPF_REG_2, 8, 1), + BPF_EXIT_INSN(), + + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1), /* R2=inv(umin=1, umax=8) */ + BPF_MOV64_REG(BPF_REG_1, BPF_REG_FP), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), + BPF_MOV64_IMM(BPF_REG_3, 0), + BPF_EMIT_CALL(BPF_FUNC_probe_read), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_TRACEPOINT, + .fixup_map_array_48b = { 1 }, + .result = VERBOSE_ACCEPT, + .errstr = + "26: (85) call bpf_probe_read#4\ + last_idx 26 first_idx 20\ + regs=4 stack=0 before 25\ + regs=4 stack=0 before 24\ + regs=4 stack=0 before 23\ + regs=4 stack=0 before 22\ + regs=4 stack=0 before 20\ + parent didn't have regs=4 stack=0 marks\ + last_idx 19 first_idx 10\ + regs=4 stack=0 before 19\ + regs=200 stack=0 before 18\ + regs=300 stack=0 before 17\ + regs=201 stack=0 before 15\ + regs=201 stack=0 before 14\ + regs=200 stack=0 before 13\ + regs=200 stack=0 before 12\ + regs=200 stack=0 before 11\ + regs=200 stack=0 before 10\ + parent already had regs=0 stack=0 marks", +}, +{ + "precise: test 2", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_LD_MAP_FD(BPF_REG_6, 0), + BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), + BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), + BPF_ST_MEM(BPF_DW, BPF_REG_FP, -8, 0), + BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), + BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), + BPF_EXIT_INSN(), + + BPF_MOV64_REG(BPF_REG_9, BPF_REG_0), + + BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), + BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), + BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), + BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), + BPF_EXIT_INSN(), + + BPF_MOV64_REG(BPF_REG_8, BPF_REG_0), + + BPF_ALU64_REG(BPF_SUB, BPF_REG_9, BPF_REG_8), /* map_value_ptr -= map_value_ptr */ + BPF_MOV64_REG(BPF_REG_2, BPF_REG_9), + BPF_JMP_IMM(BPF_JLT, BPF_REG_2, 8, 1), + BPF_EXIT_INSN(), + + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1), /* R2=inv(umin=1, umax=8) */ + BPF_MOV64_REG(BPF_REG_1, BPF_REG_FP), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), + BPF_MOV64_IMM(BPF_REG_3, 0), + BPF_EMIT_CALL(BPF_FUNC_probe_read), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_TRACEPOINT, + .fixup_map_array_48b = { 1 }, + .result = VERBOSE_ACCEPT, + .flags = BPF_F_TEST_STATE_FREQ, + .errstr = + "26: (85) call bpf_probe_read#4\ + last_idx 26 first_idx 22\ + regs=4 stack=0 before 25\ + regs=4 stack=0 before 24\ + regs=4 stack=0 before 23\ + regs=4 stack=0 before 22\ + parent didn't have regs=4 stack=0 marks\ + last_idx 20 first_idx 20\ + regs=4 stack=0 before 20\ + parent didn't have regs=4 stack=0 marks\ + last_idx 19 first_idx 17\ + regs=4 stack=0 before 19\ + regs=200 stack=0 before 18\ + regs=300 stack=0 before 17\ + parent already had regs=0 stack=0 marks", +}, -- cgit v1.2.3-59-g8ed1b From 411cdb4569013cc1089c00b2cd279033d6278f61 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Thu, 22 Aug 2019 22:52:15 -0700 Subject: selftests/bpf: add precision tracking test Copy-paste of existing test "calls: cross frame pruning - liveness propagation" but ran with different parentage chain heuristic which stresses different path in precision tracking logic. Signed-off-by: Alexei Starovoitov Acked-by: Song Liu Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/verifier/precise.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/verifier/precise.c b/tools/testing/selftests/bpf/verifier/precise.c index a20953c23721..a455a4a71f11 100644 --- a/tools/testing/selftests/bpf/verifier/precise.c +++ b/tools/testing/selftests/bpf/verifier/precise.c @@ -115,3 +115,28 @@ regs=300 stack=0 before 17\ parent already had regs=0 stack=0 marks", }, +{ + "precise: cross frame pruning", + .insns = { + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), + BPF_MOV64_IMM(BPF_REG_8, 0), + BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), + BPF_MOV64_IMM(BPF_REG_8, 1), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), + BPF_MOV64_IMM(BPF_REG_9, 0), + BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), + BPF_MOV64_IMM(BPF_REG_9, 1), + BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), + BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 1, 1), + BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_2, 0), + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_XDP, + .flags = BPF_F_TEST_STATE_FREQ, + .errstr = "!read_ok", + .result = REJECT, +}, -- cgit v1.2.3-59-g8ed1b From cd9c21d76879a06216597052d3b45c51be977aaa Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Wed, 21 Aug 2019 16:44:24 -0700 Subject: selftests/bpf: test_progs: test__skip Export test__skip() to indicate skipped tests and use it in test_send_signal_nmi(). Cc: Andrii Nakryiko Signed-off-by: Stanislav Fomichev Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/prog_tests/send_signal.c | 1 + tools/testing/selftests/bpf/test_progs.c | 20 ++++++++++++++++++-- tools/testing/selftests/bpf/test_progs.h | 2 ++ 3 files changed, 21 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c index 1575f0a1f586..40c2c5efdd3e 100644 --- a/tools/testing/selftests/bpf/prog_tests/send_signal.c +++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c @@ -204,6 +204,7 @@ static int test_send_signal_nmi(void) if (errno == ENOENT) { printf("%s:SKIP:no PERF_COUNT_HW_CPU_CYCLES\n", __func__); + test__skip(); return 0; } /* Let the test fail with a more informative message */ diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index 12895d03d58b..e545dfb55872 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -17,6 +17,7 @@ struct prog_test_def { bool force_log; int pass_cnt; int error_cnt; + int skip_cnt; bool tested; const char *subtest_name; @@ -56,6 +57,14 @@ static void dump_test_log(const struct prog_test_def *test, bool failed) fseeko(stdout, 0, SEEK_SET); /* rewind */ } +static void skip_account(void) +{ + if (env.test->skip_cnt) { + env.skip_cnt++; + env.test->skip_cnt = 0; + } +} + void test__end_subtest() { struct prog_test_def *test = env.test; @@ -65,6 +74,7 @@ void test__end_subtest() env.fail_cnt++; else env.sub_succ_cnt++; + skip_account(); dump_test_log(test, sub_error_cnt); @@ -105,6 +115,11 @@ void test__force_log() { env.test->force_log = true; } +void test__skip(void) +{ + env.test->skip_cnt++; +} + struct ipv4_packet pkt_v4 = { .eth.h_proto = __bpf_constant_htons(ETH_P_IP), .iph.ihl = 5, @@ -510,6 +525,7 @@ int main(int argc, char **argv) env.fail_cnt++; else env.succ_cnt++; + skip_account(); dump_test_log(test, test->error_cnt); @@ -518,8 +534,8 @@ int main(int argc, char **argv) test->error_cnt ? "FAIL" : "OK"); } stdio_restore(); - printf("Summary: %d/%d PASSED, %d FAILED\n", - env.succ_cnt, env.sub_succ_cnt, env.fail_cnt); + printf("Summary: %d/%d PASSED, %d SKIPPED, %d FAILED\n", + env.succ_cnt, env.sub_succ_cnt, env.skip_cnt, env.fail_cnt); free(env.test_selector.num_set); free(env.subtest_selector.num_set); diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h index 37d427f5a1e5..9defd35cb6c0 100644 --- a/tools/testing/selftests/bpf/test_progs.h +++ b/tools/testing/selftests/bpf/test_progs.h @@ -64,6 +64,7 @@ struct test_env { int succ_cnt; /* successful tests */ int sub_succ_cnt; /* successful sub-tests */ int fail_cnt; /* total failed tests + sub-tests */ + int skip_cnt; /* skipped tests */ }; extern int error_cnt; @@ -72,6 +73,7 @@ extern struct test_env env; extern void test__force_log(); extern bool test__start_subtest(const char *name); +extern void test__skip(void); #define MAGIC_BYTES 123 -- cgit v1.2.3-59-g8ed1b From d38835b75f67df16cef65c14aa64796a1832e6b4 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Wed, 21 Aug 2019 16:44:25 -0700 Subject: selftests/bpf: test_progs: remove global fail/success counts Now that we have a global per-test/per-environment state, there is no longer need to have global fail/success counters (and there is no need to save/get the diff before/after the test). Introduce CHECK_FAIL macro (suggested by Andrii) and covert existing tests to it. CHECK_FAIL uses new test__fail() to record the failure. Cc: Andrii Nakryiko Signed-off-by: Stanislav Fomichev Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c | 3 +-- .../selftests/bpf/prog_tests/bpf_verif_scale.c | 9 +-------- .../selftests/bpf/prog_tests/flow_dissector.c | 4 +--- .../selftests/bpf/prog_tests/get_stack_raw_tp.c | 3 --- .../testing/selftests/bpf/prog_tests/global_data.c | 20 +++++--------------- tools/testing/selftests/bpf/prog_tests/l4lb_all.c | 9 +++------ tools/testing/selftests/bpf/prog_tests/map_lock.c | 17 ++++++----------- tools/testing/selftests/bpf/prog_tests/pkt_access.c | 4 +--- .../selftests/bpf/prog_tests/pkt_md_access.c | 4 +--- .../selftests/bpf/prog_tests/queue_stack_map.c | 8 ++------ .../selftests/bpf/prog_tests/reference_tracking.c | 4 +--- tools/testing/selftests/bpf/prog_tests/spinlock.c | 6 ++---- .../selftests/bpf/prog_tests/stacktrace_map.c | 17 +++++++---------- .../bpf/prog_tests/stacktrace_map_raw_tp.c | 9 +++------ .../selftests/bpf/prog_tests/task_fd_query_rawtp.c | 3 --- .../selftests/bpf/prog_tests/task_fd_query_tp.c | 5 ----- tools/testing/selftests/bpf/prog_tests/tcp_estats.c | 4 +--- tools/testing/selftests/bpf/prog_tests/xdp.c | 4 +--- .../selftests/bpf/prog_tests/xdp_adjust_tail.c | 4 +--- .../testing/selftests/bpf/prog_tests/xdp_noinline.c | 8 +++----- tools/testing/selftests/bpf/test_progs.c | 21 +++++++++------------ tools/testing/selftests/bpf/test_progs.h | 17 +++++++++++------ 22 files changed, 60 insertions(+), 123 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c b/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c index fb5840a62548..5dd6ca1255d0 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c @@ -48,8 +48,7 @@ void test_bpf_obj_id(void) /* test_obj_id.o is a dumb prog. It should never fail * to load. */ - if (err) - error_cnt++; + CHECK_FAIL(err); assert(!err); /* Insert a magic value to the map */ diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c b/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c index 1a1eae356f81..1c01ee2600a9 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c @@ -28,8 +28,6 @@ static int check_load(const char *file, enum bpf_prog_type type) attr.prog_flags = BPF_F_TEST_RND_HI32; err = bpf_prog_load_xattr(&attr, &obj, &prog_fd); bpf_object__close(obj); - if (err) - error_cnt++; return err; } @@ -105,12 +103,7 @@ void test_bpf_verif_scale(void) continue; err = check_load(test->file, test->attach_type); - if (test->fails) { /* expected to fail */ - if (err) - error_cnt--; - else - error_cnt++; - } + CHECK_FAIL(err && !test->fails); } if (env.verifier_stats) diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c index 6892b88ae065..aee0cda7870b 100644 --- a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c +++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c @@ -452,10 +452,8 @@ void test_flow_dissector(void) err = bpf_flow_load(&obj, "./bpf_flow.o", "flow_dissector", "jmp_table", "last_dissection", &prog_fd, &keys_fd); - if (err) { - error_cnt++; + if (CHECK_FAIL(err)) return; - } for (i = 0; i < ARRAY_SIZE(tests); i++) { struct bpf_flow_keys flow_keys; diff --git a/tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c b/tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c index 3d59b3c841fe..eba9a970703b 100644 --- a/tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c +++ b/tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c @@ -135,10 +135,7 @@ void test_get_stack_raw_tp(void) exp_cnt -= err; } - goto close_prog_noerr; close_prog: - error_cnt++; -close_prog_noerr: if (!IS_ERR_OR_NULL(link)) bpf_link__destroy(link); if (!IS_ERR_OR_NULL(pb)) diff --git a/tools/testing/selftests/bpf/prog_tests/global_data.c b/tools/testing/selftests/bpf/prog_tests/global_data.c index d011079fb0bf..c680926fce73 100644 --- a/tools/testing/selftests/bpf/prog_tests/global_data.c +++ b/tools/testing/selftests/bpf/prog_tests/global_data.c @@ -7,10 +7,8 @@ static void test_global_data_number(struct bpf_object *obj, __u32 duration) uint64_t num; map_fd = bpf_find_map(__func__, obj, "result_number"); - if (map_fd < 0) { - error_cnt++; + if (CHECK_FAIL(map_fd < 0)) return; - } struct { char *name; @@ -44,10 +42,8 @@ static void test_global_data_string(struct bpf_object *obj, __u32 duration) char str[32]; map_fd = bpf_find_map(__func__, obj, "result_string"); - if (map_fd < 0) { - error_cnt++; + if (CHECK_FAIL(map_fd < 0)) return; - } struct { char *name; @@ -81,10 +77,8 @@ static void test_global_data_struct(struct bpf_object *obj, __u32 duration) struct foo val; map_fd = bpf_find_map(__func__, obj, "result_struct"); - if (map_fd < 0) { - error_cnt++; + if (CHECK_FAIL(map_fd < 0)) return; - } struct { char *name; @@ -112,16 +106,12 @@ static void test_global_data_rdonly(struct bpf_object *obj, __u32 duration) __u8 *buff; map = bpf_object__find_map_by_name(obj, "test_glo.rodata"); - if (!map || !bpf_map__is_internal(map)) { - error_cnt++; + if (CHECK_FAIL(!map || !bpf_map__is_internal(map))) return; - } map_fd = bpf_map__fd(map); - if (map_fd < 0) { - error_cnt++; + if (CHECK_FAIL(map_fd < 0)) return; - } buff = malloc(bpf_map__def(map)->value_size); if (buff) diff --git a/tools/testing/selftests/bpf/prog_tests/l4lb_all.c b/tools/testing/selftests/bpf/prog_tests/l4lb_all.c index 20ddca830e68..eaf64595be88 100644 --- a/tools/testing/selftests/bpf/prog_tests/l4lb_all.c +++ b/tools/testing/selftests/bpf/prog_tests/l4lb_all.c @@ -30,10 +30,8 @@ static void test_l4lb(const char *file) u32 *magic = (u32 *)buf; err = bpf_prog_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd); - if (err) { - error_cnt++; + if (CHECK_FAIL(err)) return; - } map_fd = bpf_find_map(__func__, obj, "vip_map"); if (map_fd < 0) @@ -72,10 +70,9 @@ static void test_l4lb(const char *file) bytes += stats[i].bytes; pkts += stats[i].pkts; } - if (bytes != MAGIC_BYTES * NUM_ITER * 2 || pkts != NUM_ITER * 2) { - error_cnt++; + if (CHECK_FAIL(bytes != MAGIC_BYTES * NUM_ITER * 2 || + pkts != NUM_ITER * 2)) printf("test_l4lb:FAIL:stats %lld %lld\n", bytes, pkts); - } out: bpf_object__close(obj); } diff --git a/tools/testing/selftests/bpf/prog_tests/map_lock.c b/tools/testing/selftests/bpf/prog_tests/map_lock.c index ee99368c595c..15993b6a194b 100644 --- a/tools/testing/selftests/bpf/prog_tests/map_lock.c +++ b/tools/testing/selftests/bpf/prog_tests/map_lock.c @@ -8,14 +8,12 @@ static void *parallel_map_access(void *arg) for (i = 0; i < 10000; i++) { err = bpf_map_lookup_elem_flags(map_fd, &key, vars, BPF_F_LOCK); - if (err) { + if (CHECK_FAIL(err)) { printf("lookup failed\n"); - error_cnt++; goto out; } - if (vars[0] != 0) { + if (CHECK_FAIL(vars[0] != 0)) { printf("lookup #%d var[0]=%d\n", i, vars[0]); - error_cnt++; goto out; } rnd = vars[1]; @@ -24,7 +22,7 @@ static void *parallel_map_access(void *arg) continue; printf("lookup #%d var[1]=%d var[%d]=%d\n", i, rnd, j, vars[j]); - error_cnt++; + CHECK_FAIL(vars[j] != rnd); goto out; } } @@ -42,15 +40,15 @@ void test_map_lock(void) void *ret; err = bpf_prog_load(file, BPF_PROG_TYPE_CGROUP_SKB, &obj, &prog_fd); - if (err) { + if (CHECK_FAIL(err)) { printf("test_map_lock:bpf_prog_load errno %d\n", errno); goto close_prog; } map_fd[0] = bpf_find_map(__func__, obj, "hash_map"); - if (map_fd[0] < 0) + if (CHECK_FAIL(map_fd[0] < 0)) goto close_prog; map_fd[1] = bpf_find_map(__func__, obj, "array_map"); - if (map_fd[1] < 0) + if (CHECK_FAIL(map_fd[1] < 0)) goto close_prog; bpf_map_update_elem(map_fd[0], &key, vars, BPF_F_LOCK); @@ -67,9 +65,6 @@ void test_map_lock(void) for (i = 4; i < 6; i++) assert(pthread_join(thread_id[i], &ret) == 0 && ret == (void *)&map_fd[i - 4]); - goto close_prog_noerr; close_prog: - error_cnt++; -close_prog_noerr: bpf_object__close(obj); } diff --git a/tools/testing/selftests/bpf/prog_tests/pkt_access.c b/tools/testing/selftests/bpf/prog_tests/pkt_access.c index 4ecfd721a044..a2537dfa899c 100644 --- a/tools/testing/selftests/bpf/prog_tests/pkt_access.c +++ b/tools/testing/selftests/bpf/prog_tests/pkt_access.c @@ -9,10 +9,8 @@ void test_pkt_access(void) int err, prog_fd; err = bpf_prog_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd); - if (err) { - error_cnt++; + if (CHECK_FAIL(err)) return; - } err = bpf_prog_test_run(prog_fd, 100000, &pkt_v4, sizeof(pkt_v4), NULL, NULL, &retval, &duration); diff --git a/tools/testing/selftests/bpf/prog_tests/pkt_md_access.c b/tools/testing/selftests/bpf/prog_tests/pkt_md_access.c index ac0d43435806..5f7aea605019 100644 --- a/tools/testing/selftests/bpf/prog_tests/pkt_md_access.c +++ b/tools/testing/selftests/bpf/prog_tests/pkt_md_access.c @@ -9,10 +9,8 @@ void test_pkt_md_access(void) int err, prog_fd; err = bpf_prog_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd); - if (err) { - error_cnt++; + if (CHECK_FAIL(err)) return; - } err = bpf_prog_test_run(prog_fd, 10, &pkt_v4, sizeof(pkt_v4), NULL, NULL, &retval, &duration); diff --git a/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c b/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c index e60cd5ff1f55..faccc66f4e39 100644 --- a/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c +++ b/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c @@ -27,10 +27,8 @@ static void test_queue_stack_map_by_type(int type) return; err = bpf_prog_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd); - if (err) { - error_cnt++; + if (CHECK_FAIL(err)) return; - } map_in_fd = bpf_find_map(__func__, obj, "map_in"); if (map_in_fd < 0) @@ -43,10 +41,8 @@ static void test_queue_stack_map_by_type(int type) /* Push 32 elements to the input map */ for (i = 0; i < MAP_SIZE; i++) { err = bpf_map_update_elem(map_in_fd, NULL, &vals[i], 0); - if (err) { - error_cnt++; + if (CHECK_FAIL(err)) goto out; - } } /* The eBPF program pushes iph.saddr in the output map, diff --git a/tools/testing/selftests/bpf/prog_tests/reference_tracking.c b/tools/testing/selftests/bpf/prog_tests/reference_tracking.c index 4a4f428d1a78..5c78e2b5a917 100644 --- a/tools/testing/selftests/bpf/prog_tests/reference_tracking.c +++ b/tools/testing/selftests/bpf/prog_tests/reference_tracking.c @@ -10,10 +10,8 @@ void test_reference_tracking(void) int err = 0; obj = bpf_object__open(file); - if (IS_ERR(obj)) { - error_cnt++; + if (CHECK_FAIL(IS_ERR(obj))) return; - } bpf_object__for_each_program(prog, obj) { const char *title; diff --git a/tools/testing/selftests/bpf/prog_tests/spinlock.c b/tools/testing/selftests/bpf/prog_tests/spinlock.c index 114ebe6a438e..d71fb3dda376 100644 --- a/tools/testing/selftests/bpf/prog_tests/spinlock.c +++ b/tools/testing/selftests/bpf/prog_tests/spinlock.c @@ -11,7 +11,7 @@ void test_spinlock(void) void *ret; err = bpf_prog_load(file, BPF_PROG_TYPE_CGROUP_SKB, &obj, &prog_fd); - if (err) { + if (CHECK_FAIL(err)) { printf("test_spin_lock:bpf_prog_load errno %d\n", errno); goto close_prog; } @@ -21,9 +21,7 @@ void test_spinlock(void) for (i = 0; i < 4; i++) assert(pthread_join(thread_id[i], &ret) == 0 && ret == (void *)&prog_fd); - goto close_prog_noerr; + close_prog: - error_cnt++; -close_prog_noerr: bpf_object__close(obj); } diff --git a/tools/testing/selftests/bpf/prog_tests/stacktrace_map.c b/tools/testing/selftests/bpf/prog_tests/stacktrace_map.c index fc539335c5b3..37269d23df93 100644 --- a/tools/testing/selftests/bpf/prog_tests/stacktrace_map.c +++ b/tools/testing/selftests/bpf/prog_tests/stacktrace_map.c @@ -26,19 +26,19 @@ void test_stacktrace_map(void) /* find map fds */ control_map_fd = bpf_find_map(__func__, obj, "control_map"); - if (control_map_fd < 0) + if (CHECK_FAIL(control_map_fd < 0)) goto disable_pmu; stackid_hmap_fd = bpf_find_map(__func__, obj, "stackid_hmap"); - if (stackid_hmap_fd < 0) + if (CHECK_FAIL(stackid_hmap_fd < 0)) goto disable_pmu; stackmap_fd = bpf_find_map(__func__, obj, "stackmap"); - if (stackmap_fd < 0) + if (CHECK_FAIL(stackmap_fd < 0)) goto disable_pmu; stack_amap_fd = bpf_find_map(__func__, obj, "stack_amap"); - if (stack_amap_fd < 0) + if (CHECK_FAIL(stack_amap_fd < 0)) goto disable_pmu; /* give some time for bpf program run */ @@ -55,23 +55,20 @@ void test_stacktrace_map(void) err = compare_map_keys(stackid_hmap_fd, stackmap_fd); if (CHECK(err, "compare_map_keys stackid_hmap vs. stackmap", "err %d errno %d\n", err, errno)) - goto disable_pmu_noerr; + goto disable_pmu; err = compare_map_keys(stackmap_fd, stackid_hmap_fd); if (CHECK(err, "compare_map_keys stackmap vs. stackid_hmap", "err %d errno %d\n", err, errno)) - goto disable_pmu_noerr; + goto disable_pmu; stack_trace_len = PERF_MAX_STACK_DEPTH * sizeof(__u64); err = compare_stack_ips(stackmap_fd, stack_amap_fd, stack_trace_len); if (CHECK(err, "compare_stack_ips stackmap vs. stack_amap", "err %d errno %d\n", err, errno)) - goto disable_pmu_noerr; + goto disable_pmu; - goto disable_pmu_noerr; disable_pmu: - error_cnt++; -disable_pmu_noerr: bpf_link__destroy(link); close_prog: bpf_object__close(obj); diff --git a/tools/testing/selftests/bpf/prog_tests/stacktrace_map_raw_tp.c b/tools/testing/selftests/bpf/prog_tests/stacktrace_map_raw_tp.c index fbfa8e76cf63..404a5498e1a3 100644 --- a/tools/testing/selftests/bpf/prog_tests/stacktrace_map_raw_tp.c +++ b/tools/testing/selftests/bpf/prog_tests/stacktrace_map_raw_tp.c @@ -26,15 +26,15 @@ void test_stacktrace_map_raw_tp(void) /* find map fds */ control_map_fd = bpf_find_map(__func__, obj, "control_map"); - if (control_map_fd < 0) + if (CHECK_FAIL(control_map_fd < 0)) goto close_prog; stackid_hmap_fd = bpf_find_map(__func__, obj, "stackid_hmap"); - if (stackid_hmap_fd < 0) + if (CHECK_FAIL(stackid_hmap_fd < 0)) goto close_prog; stackmap_fd = bpf_find_map(__func__, obj, "stackmap"); - if (stackmap_fd < 0) + if (CHECK_FAIL(stackmap_fd < 0)) goto close_prog; /* give some time for bpf program run */ @@ -58,10 +58,7 @@ void test_stacktrace_map_raw_tp(void) "err %d errno %d\n", err, errno)) goto close_prog; - goto close_prog_noerr; close_prog: - error_cnt++; -close_prog_noerr: if (!IS_ERR_OR_NULL(link)) bpf_link__destroy(link); bpf_object__close(obj); diff --git a/tools/testing/selftests/bpf/prog_tests/task_fd_query_rawtp.c b/tools/testing/selftests/bpf/prog_tests/task_fd_query_rawtp.c index 958a3d88de99..1bdc1d86a50c 100644 --- a/tools/testing/selftests/bpf/prog_tests/task_fd_query_rawtp.c +++ b/tools/testing/selftests/bpf/prog_tests/task_fd_query_rawtp.c @@ -70,9 +70,6 @@ void test_task_fd_query_rawtp(void) if (CHECK(!err, "check_results", "fd_type %d len %u\n", fd_type, len)) goto close_prog; - goto close_prog_noerr; close_prog: - error_cnt++; -close_prog_noerr: bpf_object__close(obj); } diff --git a/tools/testing/selftests/bpf/prog_tests/task_fd_query_tp.c b/tools/testing/selftests/bpf/prog_tests/task_fd_query_tp.c index f9b70e81682b..3f131b8fe328 100644 --- a/tools/testing/selftests/bpf/prog_tests/task_fd_query_tp.c +++ b/tools/testing/selftests/bpf/prog_tests/task_fd_query_tp.c @@ -62,14 +62,9 @@ static void test_task_fd_query_tp_core(const char *probe_name, fd_type, buf)) goto close_pmu; - close(pmu_fd); - goto close_prog_noerr; - close_pmu: close(pmu_fd); close_prog: - error_cnt++; -close_prog_noerr: bpf_object__close(obj); } diff --git a/tools/testing/selftests/bpf/prog_tests/tcp_estats.c b/tools/testing/selftests/bpf/prog_tests/tcp_estats.c index bb8759d69099..594307dffd13 100644 --- a/tools/testing/selftests/bpf/prog_tests/tcp_estats.c +++ b/tools/testing/selftests/bpf/prog_tests/tcp_estats.c @@ -10,10 +10,8 @@ void test_tcp_estats(void) err = bpf_prog_load(file, BPF_PROG_TYPE_TRACEPOINT, &obj, &prog_fd); CHECK(err, "", "err %d errno %d\n", err, errno); - if (err) { - error_cnt++; + if (err) return; - } bpf_object__close(obj); } diff --git a/tools/testing/selftests/bpf/prog_tests/xdp.c b/tools/testing/selftests/bpf/prog_tests/xdp.c index a74167289545..dcb5ecac778e 100644 --- a/tools/testing/selftests/bpf/prog_tests/xdp.c +++ b/tools/testing/selftests/bpf/prog_tests/xdp.c @@ -16,10 +16,8 @@ void test_xdp(void) int err, prog_fd, map_fd; err = bpf_prog_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); - if (err) { - error_cnt++; + if (CHECK_FAIL(err)) return; - } map_fd = bpf_find_map(__func__, obj, "vip2tnl"); if (map_fd < 0) diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c index 922aa0a19764..3744196d7cba 100644 --- a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c +++ b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c @@ -10,10 +10,8 @@ void test_xdp_adjust_tail(void) int err, prog_fd; err = bpf_prog_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); - if (err) { - error_cnt++; + if (CHECK_FAIL(err)) return; - } err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), buf, &size, &retval, &duration); diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_noinline.c b/tools/testing/selftests/bpf/prog_tests/xdp_noinline.c index 15f7c272edb0..c9404e6b226e 100644 --- a/tools/testing/selftests/bpf/prog_tests/xdp_noinline.c +++ b/tools/testing/selftests/bpf/prog_tests/xdp_noinline.c @@ -31,10 +31,8 @@ void test_xdp_noinline(void) u32 *magic = (u32 *)buf; err = bpf_prog_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); - if (err) { - error_cnt++; + if (CHECK_FAIL(err)) return; - } map_fd = bpf_find_map(__func__, obj, "vip_map"); if (map_fd < 0) @@ -73,8 +71,8 @@ void test_xdp_noinline(void) bytes += stats[i].bytes; pkts += stats[i].pkts; } - if (bytes != MAGIC_BYTES * NUM_ITER * 2 || pkts != NUM_ITER * 2) { - error_cnt++; + if (CHECK_FAIL(bytes != MAGIC_BYTES * NUM_ITER * 2 || + pkts != NUM_ITER * 2)) { printf("test_xdp_noinline:FAIL:stats %lld %lld\n", bytes, pkts); } diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index e545dfb55872..e5892cb60eca 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -8,14 +8,12 @@ /* defined in test_progs.h */ struct test_env env; -int error_cnt, pass_cnt; struct prog_test_def { const char *test_name; int test_num; void (*run_test)(void); bool force_log; - int pass_cnt; int error_cnt; int skip_cnt; bool tested; @@ -24,7 +22,6 @@ struct prog_test_def { int subtest_num; /* store counts before subtest started */ - int old_pass_cnt; int old_error_cnt; }; @@ -68,7 +65,7 @@ static void skip_account(void) void test__end_subtest() { struct prog_test_def *test = env.test; - int sub_error_cnt = error_cnt - test->old_error_cnt; + int sub_error_cnt = test->error_cnt - test->old_error_cnt; if (sub_error_cnt) env.fail_cnt++; @@ -105,8 +102,7 @@ bool test__start_subtest(const char *name) return false; test->subtest_name = name; - env.test->old_pass_cnt = pass_cnt; - env.test->old_error_cnt = error_cnt; + env.test->old_error_cnt = env.test->error_cnt; return true; } @@ -120,6 +116,11 @@ void test__skip(void) env.test->skip_cnt++; } +void test__fail(void) +{ + env.test->error_cnt++; +} + struct ipv4_packet pkt_v4 = { .eth.h_proto = __bpf_constant_htons(ETH_P_IP), .iph.ihl = 5, @@ -144,7 +145,7 @@ int bpf_find_map(const char *test, struct bpf_object *obj, const char *name) map = bpf_object__find_map_by_name(obj, name); if (!map) { printf("%s:FAIL:map '%s' not found\n", test, name); - error_cnt++; + test__fail(); return -1; } return bpf_map__fd(map); @@ -503,8 +504,6 @@ int main(int argc, char **argv) stdio_hijack(); for (i = 0; i < prog_test_cnt; i++) { struct prog_test_def *test = &prog_test_defs[i]; - int old_pass_cnt = pass_cnt; - int old_error_cnt = error_cnt; env.test = test; test->test_num = i + 1; @@ -519,8 +518,6 @@ int main(int argc, char **argv) test__end_subtest(); test->tested = true; - test->pass_cnt = pass_cnt - old_pass_cnt; - test->error_cnt = error_cnt - old_error_cnt; if (test->error_cnt) env.fail_cnt++; else @@ -540,5 +537,5 @@ int main(int argc, char **argv) free(env.test_selector.num_set); free(env.subtest_selector.num_set); - return error_cnt ? EXIT_FAILURE : EXIT_SUCCESS; + return env.fail_cnt ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h index 9defd35cb6c0..33da849cb765 100644 --- a/tools/testing/selftests/bpf/test_progs.h +++ b/tools/testing/selftests/bpf/test_progs.h @@ -38,8 +38,6 @@ typedef __u16 __sum16; #include "trace_helpers.h" #include "flow_dissector_load.h" -struct prog_test_def; - struct test_selector { const char *name; bool *num_set; @@ -67,13 +65,12 @@ struct test_env { int skip_cnt; /* skipped tests */ }; -extern int error_cnt; -extern int pass_cnt; extern struct test_env env; extern void test__force_log(); extern bool test__start_subtest(const char *name); extern void test__skip(void); +extern void test__fail(void); #define MAGIC_BYTES 123 @@ -96,17 +93,25 @@ extern struct ipv6_packet pkt_v6; #define _CHECK(condition, tag, duration, format...) ({ \ int __ret = !!(condition); \ if (__ret) { \ - error_cnt++; \ + test__fail(); \ printf("%s:FAIL:%s ", __func__, tag); \ printf(format); \ } else { \ - pass_cnt++; \ printf("%s:PASS:%s %d nsec\n", \ __func__, tag, duration); \ } \ __ret; \ }) +#define CHECK_FAIL(condition) ({ \ + int __ret = !!(condition); \ + if (__ret) { \ + test__fail(); \ + printf("%s:FAIL:%d ", __func__, __LINE__); \ + } \ + __ret; \ +}) + #define CHECK(condition, tag, format...) \ _CHECK(condition, tag, duration, format) #define CHECK_ATTR(condition, tag, format...) \ -- cgit v1.2.3-59-g8ed1b From 62d69f24fe5eca23410b6a21334a7267b0c8838b Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Wed, 21 Aug 2019 16:44:26 -0700 Subject: selftests/bpf: test_progs: remove asserts from subtests Otherwise they can bring the whole process down. Cc: Andrii Nakryiko Signed-off-by: Stanislav Fomichev Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c | 19 ++++++++++++------- tools/testing/selftests/bpf/prog_tests/map_lock.c | 21 +++++++++++++-------- tools/testing/selftests/bpf/prog_tests/spinlock.c | 12 +++++++----- .../selftests/bpf/prog_tests/stacktrace_build_id.c | 7 ++++--- .../bpf/prog_tests/stacktrace_build_id_nmi.c | 7 ++++--- 5 files changed, 40 insertions(+), 26 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c b/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c index 5dd6ca1255d0..f10029821e16 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c @@ -48,15 +48,17 @@ void test_bpf_obj_id(void) /* test_obj_id.o is a dumb prog. It should never fail * to load. */ - CHECK_FAIL(err); - assert(!err); + if (CHECK_FAIL(err)) + continue; /* Insert a magic value to the map */ map_fds[i] = bpf_find_map(__func__, objs[i], "test_map_id"); - assert(map_fds[i] >= 0); + if (CHECK_FAIL(map_fds[i] < 0)) + goto done; err = bpf_map_update_elem(map_fds[i], &array_key, &array_magic_value, 0); - assert(!err); + if (CHECK_FAIL(err)) + goto done; /* Check getting map info */ info_len = sizeof(struct bpf_map_info) * 2; @@ -95,9 +97,11 @@ void test_bpf_obj_id(void) prog_infos[i].map_ids = ptr_to_u64(map_ids + i); prog_infos[i].nr_map_ids = 2; err = clock_gettime(CLOCK_REALTIME, &real_time_ts); - assert(!err); + if (CHECK_FAIL(err)) + goto done; err = clock_gettime(CLOCK_BOOTTIME, &boot_time_ts); - assert(!err); + if (CHECK_FAIL(err)) + goto done; err = bpf_obj_get_info_by_fd(prog_fds[i], &prog_infos[i], &info_len); load_time = (real_time_ts.tv_sec - boot_time_ts.tv_sec) @@ -223,7 +227,8 @@ void test_bpf_obj_id(void) nr_id_found++; err = bpf_map_lookup_elem(map_fd, &array_key, &array_value); - assert(!err); + if (CHECK_FAIL(err)) + goto done; err = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len); CHECK(err || info_len != sizeof(struct bpf_map_info) || diff --git a/tools/testing/selftests/bpf/prog_tests/map_lock.c b/tools/testing/selftests/bpf/prog_tests/map_lock.c index 15993b6a194b..8f91f1881d11 100644 --- a/tools/testing/selftests/bpf/prog_tests/map_lock.c +++ b/tools/testing/selftests/bpf/prog_tests/map_lock.c @@ -54,17 +54,22 @@ void test_map_lock(void) bpf_map_update_elem(map_fd[0], &key, vars, BPF_F_LOCK); for (i = 0; i < 4; i++) - assert(pthread_create(&thread_id[i], NULL, - &spin_lock_thread, &prog_fd) == 0); + if (CHECK_FAIL(pthread_create(&thread_id[i], NULL, + &spin_lock_thread, &prog_fd))) + goto close_prog; for (i = 4; i < 6; i++) - assert(pthread_create(&thread_id[i], NULL, - ¶llel_map_access, &map_fd[i - 4]) == 0); + if (CHECK_FAIL(pthread_create(&thread_id[i], NULL, + ¶llel_map_access, + &map_fd[i - 4]))) + goto close_prog; for (i = 0; i < 4; i++) - assert(pthread_join(thread_id[i], &ret) == 0 && - ret == (void *)&prog_fd); + if (CHECK_FAIL(pthread_join(thread_id[i], &ret) || + ret != (void *)&prog_fd)) + goto close_prog; for (i = 4; i < 6; i++) - assert(pthread_join(thread_id[i], &ret) == 0 && - ret == (void *)&map_fd[i - 4]); + if (CHECK_FAIL(pthread_join(thread_id[i], &ret) || + ret != (void *)&map_fd[i - 4])) + goto close_prog; close_prog: bpf_object__close(obj); } diff --git a/tools/testing/selftests/bpf/prog_tests/spinlock.c b/tools/testing/selftests/bpf/prog_tests/spinlock.c index d71fb3dda376..1ae00cd3174e 100644 --- a/tools/testing/selftests/bpf/prog_tests/spinlock.c +++ b/tools/testing/selftests/bpf/prog_tests/spinlock.c @@ -16,12 +16,14 @@ void test_spinlock(void) goto close_prog; } for (i = 0; i < 4; i++) - assert(pthread_create(&thread_id[i], NULL, - &spin_lock_thread, &prog_fd) == 0); - for (i = 0; i < 4; i++) - assert(pthread_join(thread_id[i], &ret) == 0 && - ret == (void *)&prog_fd); + if (CHECK_FAIL(pthread_create(&thread_id[i], NULL, + &spin_lock_thread, &prog_fd))) + goto close_prog; + for (i = 0; i < 4; i++) + if (CHECK_FAIL(pthread_join(thread_id[i], &ret) || + ret != (void *)&prog_fd)) + goto close_prog; close_prog: bpf_object__close(obj); } diff --git a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c index ac44fda84833..d841dced971f 100644 --- a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c +++ b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c @@ -51,9 +51,10 @@ retry: "err %d errno %d\n", err, errno)) goto disable_pmu; - assert(system("dd if=/dev/urandom of=/dev/zero count=4 2> /dev/null") - == 0); - assert(system("./urandom_read") == 0); + if (CHECK_FAIL(system("dd if=/dev/urandom of=/dev/zero count=4 2> /dev/null"))) + goto disable_pmu; + if (CHECK_FAIL(system("./urandom_read"))) + goto disable_pmu; /* disable stack trace collection */ key = 0; val = 1; diff --git a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c index 9557b7dfb782..f62aa0eb959b 100644 --- a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c +++ b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c @@ -82,9 +82,10 @@ retry: "err %d errno %d\n", err, errno)) goto disable_pmu; - assert(system("dd if=/dev/urandom of=/dev/zero count=4 2> /dev/null") - == 0); - assert(system("taskset 0x1 ./urandom_read 100000") == 0); + if (CHECK_FAIL(system("dd if=/dev/urandom of=/dev/zero count=4 2> /dev/null"))) + goto disable_pmu; + if (CHECK_FAIL(system("taskset 0x1 ./urandom_read 100000"))) + goto disable_pmu; /* disable stack trace collection */ key = 0; val = 1; -- cgit v1.2.3-59-g8ed1b From 86ccc384cfcac22f45b1158b57d9ef5b4079e027 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Wed, 21 Aug 2019 16:44:27 -0700 Subject: selftests/bpf: test_progs: remove unused ret send_signal test returns static codes from the subtests which nobody looks at, let's rely on the CHECK macros instead. Signed-off-by: Stanislav Fomichev Signed-off-by: Daniel Borkmann --- .../testing/selftests/bpf/prog_tests/send_signal.c | 42 ++++++++++------------ 1 file changed, 19 insertions(+), 23 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c index 40c2c5efdd3e..b607112c64e7 100644 --- a/tools/testing/selftests/bpf/prog_tests/send_signal.c +++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c @@ -8,7 +8,7 @@ static void sigusr1_handler(int signum) sigusr1_received++; } -static int test_send_signal_common(struct perf_event_attr *attr, +static void test_send_signal_common(struct perf_event_attr *attr, int prog_type, const char *test_name) { @@ -23,13 +23,13 @@ static int test_send_signal_common(struct perf_event_attr *attr, if (CHECK(pipe(pipe_c2p), test_name, "pipe pipe_c2p error: %s\n", strerror(errno))) - goto no_fork_done; + return; if (CHECK(pipe(pipe_p2c), test_name, "pipe pipe_p2c error: %s\n", strerror(errno))) { close(pipe_c2p[0]); close(pipe_c2p[1]); - goto no_fork_done; + return; } pid = fork(); @@ -38,7 +38,7 @@ static int test_send_signal_common(struct perf_event_attr *attr, close(pipe_c2p[1]); close(pipe_p2c[0]); close(pipe_p2c[1]); - goto no_fork_done; + return; } if (pid == 0) { @@ -125,7 +125,7 @@ static int test_send_signal_common(struct perf_event_attr *attr, goto disable_pmu; } - err = CHECK(buf[0] != '2', test_name, "incorrect result\n"); + CHECK(buf[0] != '2', test_name, "incorrect result\n"); /* notify child safe to exit */ write(pipe_p2c[1], buf, 1); @@ -138,11 +138,9 @@ prog_load_failure: close(pipe_c2p[0]); close(pipe_p2c[1]); wait(NULL); -no_fork_done: - return err; } -static int test_send_signal_tracepoint(void) +static void test_send_signal_tracepoint(void) { const char *id_path = "/sys/kernel/debug/tracing/events/syscalls/sys_enter_nanosleep/id"; struct perf_event_attr attr = { @@ -159,21 +157,21 @@ static int test_send_signal_tracepoint(void) if (CHECK(efd < 0, "tracepoint", "open syscalls/sys_enter_nanosleep/id failure: %s\n", strerror(errno))) - return -1; + return; bytes = read(efd, buf, sizeof(buf)); close(efd); if (CHECK(bytes <= 0 || bytes >= sizeof(buf), "tracepoint", "read syscalls/sys_enter_nanosleep/id failure: %s\n", strerror(errno))) - return -1; + return; attr.config = strtol(buf, NULL, 0); - return test_send_signal_common(&attr, BPF_PROG_TYPE_TRACEPOINT, "tracepoint"); + test_send_signal_common(&attr, BPF_PROG_TYPE_TRACEPOINT, "tracepoint"); } -static int test_send_signal_perf(void) +static void test_send_signal_perf(void) { struct perf_event_attr attr = { .sample_period = 1, @@ -181,11 +179,11 @@ static int test_send_signal_perf(void) .config = PERF_COUNT_SW_CPU_CLOCK, }; - return test_send_signal_common(&attr, BPF_PROG_TYPE_PERF_EVENT, - "perf_sw_event"); + test_send_signal_common(&attr, BPF_PROG_TYPE_PERF_EVENT, + "perf_sw_event"); } -static int test_send_signal_nmi(void) +static void test_send_signal_nmi(void) { struct perf_event_attr attr = { .sample_freq = 50, @@ -205,25 +203,23 @@ static int test_send_signal_nmi(void) printf("%s:SKIP:no PERF_COUNT_HW_CPU_CYCLES\n", __func__); test__skip(); - return 0; + return; } /* Let the test fail with a more informative message */ } else { close(pmu_fd); } - return test_send_signal_common(&attr, BPF_PROG_TYPE_PERF_EVENT, - "perf_hw_event"); + test_send_signal_common(&attr, BPF_PROG_TYPE_PERF_EVENT, + "perf_hw_event"); } void test_send_signal(void) { - int ret = 0; - if (test__start_subtest("send_signal_tracepoint")) - ret |= test_send_signal_tracepoint(); + test_send_signal_tracepoint(); if (test__start_subtest("send_signal_perf")) - ret |= test_send_signal_perf(); + test_send_signal_perf(); if (test__start_subtest("send_signal_nmi")) - ret |= test_send_signal_nmi(); + test_send_signal_nmi(); } -- cgit v1.2.3-59-g8ed1b From 47ee6e86e0a3e3a15fbdd6d94aab39e46013c961 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Mon, 26 Aug 2019 15:27:12 -0700 Subject: selftests/bpf: remove wrong nhoff in flow dissector test .nhoff = 0 is (correctly) reset to ETH_HLEN on the next line so let's drop it. Signed-off-by: Stanislav Fomichev Acked-by: Song Liu Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/prog_tests/flow_dissector.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c index aee0cda7870b..92563898867c 100644 --- a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c +++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c @@ -344,7 +344,6 @@ struct test tests[] = { .tcp.dest = 8080, }, .keys = { - .nhoff = 0, .nhoff = ETH_HLEN, .thoff = ETH_HLEN + sizeof(struct iphdr) + sizeof(struct iphdr), -- cgit v1.2.3-59-g8ed1b From c66f78a6de4de6cb520b15cf6a1b586617b9add5 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 27 Aug 2019 21:48:21 +0200 Subject: x86/intel: Aggregate big core client naming Currently the big core client models either have: - no OPTDIFF - _CORE - _DESKTOP Make it uniformly: 'no OPTDIFF'. for i in `git grep -l "\(INTEL_FAM6_\|VULNWL_INTEL\|INTEL_CPU_FAM6\).*_\(CORE\|DESKTOP\)"` do sed -i -e 's/\(\(INTEL_FAM6_\|VULNWL_INTEL\|INTEL_CPU_FAM6\).*\)_\(CORE\|DESKTOP\)/\1/g' ${i} done Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Tony Luck Cc: x86@kernel.org Cc: Dave Hansen Cc: Borislav Petkov Cc: Thomas Gleixner Link: https://lkml.kernel.org/r/20190827195122.513945586@infradead.org --- arch/x86/events/intel/core.c | 26 +++++++++++++------------- arch/x86/events/intel/cstate.c | 22 +++++++++++----------- arch/x86/events/intel/pt.c | 2 +- arch/x86/events/intel/rapl.c | 10 +++++----- arch/x86/events/intel/uncore.c | 12 ++++++------ arch/x86/events/msr.c | 8 ++++---- arch/x86/include/asm/intel-family.h | 10 +++++----- arch/x86/kernel/apic/apic.c | 8 ++++---- arch/x86/kernel/cpu/bugs.c | 8 ++++---- arch/x86/kernel/cpu/intel.c | 10 +++++----- drivers/cpufreq/intel_pstate.c | 12 ++++++------ drivers/idle/intel_idle.c | 10 +++++----- drivers/platform/x86/intel_pmc_core.c | 4 ++-- drivers/platform/x86/intel_pmc_core_pltdrv.c | 4 ++-- drivers/powercap/intel_rapl_common.c | 10 +++++----- tools/power/x86/turbostat/turbostat.c | 28 ++++++++++++++-------------- 16 files changed, 92 insertions(+), 92 deletions(-) (limited to 'tools') diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 648260b5f367..76bff3a33725 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -3964,12 +3964,12 @@ static __init void intel_clovertown_quirk(void) } static const struct x86_cpu_desc isolation_ucodes[] = { - INTEL_CPU_DESC(INTEL_FAM6_HASWELL_CORE, 3, 0x0000001f), + INTEL_CPU_DESC(INTEL_FAM6_HASWELL, 3, 0x0000001f), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_ULT, 1, 0x0000001e), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_GT3E, 1, 0x00000015), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 2, 0x00000037), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 4, 0x0000000a), - INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_CORE, 4, 0x00000023), + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL, 4, 0x00000023), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_GT3E, 1, 0x00000014), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 2, 0x00000010), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 3, 0x07000009), @@ -3979,16 +3979,16 @@ static const struct x86_cpu_desc isolation_ucodes[] = { INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 3, 0x00000021), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 4, 0x00000000), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_MOBILE, 3, 0x0000007c), - INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_DESKTOP, 3, 0x0000007c), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_DESKTOP, 9, 0x0000004e), + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE, 3, 0x0000007c), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 9, 0x0000004e), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 9, 0x0000004e), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 10, 0x0000004e), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 11, 0x0000004e), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 12, 0x0000004e), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_DESKTOP, 10, 0x0000004e), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_DESKTOP, 11, 0x0000004e), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_DESKTOP, 12, 0x0000004e), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_DESKTOP, 13, 0x0000004e), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 10, 0x0000004e), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 11, 0x0000004e), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 12, 0x0000004e), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 13, 0x0000004e), {} }; @@ -4857,7 +4857,7 @@ __init int intel_pmu_init(void) break; - case INTEL_FAM6_HASWELL_CORE: + case INTEL_FAM6_HASWELL: case INTEL_FAM6_HASWELL_X: case INTEL_FAM6_HASWELL_ULT: case INTEL_FAM6_HASWELL_GT3E: @@ -4890,7 +4890,7 @@ __init int intel_pmu_init(void) name = "haswell"; break; - case INTEL_FAM6_BROADWELL_CORE: + case INTEL_FAM6_BROADWELL: case INTEL_FAM6_BROADWELL_XEON_D: case INTEL_FAM6_BROADWELL_GT3E: case INTEL_FAM6_BROADWELL_X: @@ -4956,9 +4956,9 @@ __init int intel_pmu_init(void) pmem = true; /* fall through */ case INTEL_FAM6_SKYLAKE_MOBILE: - case INTEL_FAM6_SKYLAKE_DESKTOP: + case INTEL_FAM6_SKYLAKE: case INTEL_FAM6_KABYLAKE_MOBILE: - case INTEL_FAM6_KABYLAKE_DESKTOP: + case INTEL_FAM6_KABYLAKE: x86_add_quirk(intel_pebs_isolation_quirk); x86_pmu.late_ack = true; memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids)); @@ -5006,7 +5006,7 @@ __init int intel_pmu_init(void) pmem = true; /* fall through */ case INTEL_FAM6_ICELAKE_MOBILE: - case INTEL_FAM6_ICELAKE_DESKTOP: + case INTEL_FAM6_ICELAKE: x86_pmu.late_ack = true; memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids)); memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c index 688592b34564..3854400ad8ff 100644 --- a/arch/x86/events/intel/cstate.c +++ b/arch/x86/events/intel/cstate.c @@ -593,40 +593,40 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { X86_CSTATES_MODEL(INTEL_FAM6_IVYBRIDGE, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_IVYBRIDGE_X, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_CORE, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_HASWELL, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_X, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_GT3E, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_ULT, hswult_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_ATOM_SILVERMONT, slm_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_SILVERMONT, slm_cstates), X86_CSTATES_MODEL(INTEL_FAM6_ATOM_SILVERMONT_X, slm_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_ATOM_AIRMONT, slm_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_AIRMONT, slm_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_CORE, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_XEON_D, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_GT3E, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_X, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_MOBILE, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_DESKTOP, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_X, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_MOBILE, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_X, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_MOBILE, hswult_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_DESKTOP, hswult_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_MOBILE, hswult_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE, hswult_cstates), X86_CSTATES_MODEL(INTEL_FAM6_CANNONLAKE_MOBILE, cnl_cstates), X86_CSTATES_MODEL(INTEL_FAM6_XEON_PHI_KNL, knl_cstates), X86_CSTATES_MODEL(INTEL_FAM6_XEON_PHI_KNM, knl_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT, glm_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT, glm_cstates), X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_X, glm_cstates), X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_PLUS, glm_cstates), X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE_MOBILE, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE_DESKTOP, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE, snb_cstates), { }, }; MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match); diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index d3dc2274ddd4..8cb9626e6277 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -204,7 +204,7 @@ static int __init pt_pmu_hw_init(void) /* model-specific quirks */ switch (boot_cpu_data.x86_model) { - case INTEL_FAM6_BROADWELL_CORE: + case INTEL_FAM6_BROADWELL: case INTEL_FAM6_BROADWELL_XEON_D: case INTEL_FAM6_BROADWELL_GT3E: case INTEL_FAM6_BROADWELL_X: diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c index 64ab51ffdf06..c1278e2764f4 100644 --- a/arch/x86/events/intel/rapl.c +++ b/arch/x86/events/intel/rapl.c @@ -720,27 +720,27 @@ static const struct x86_cpu_id rapl_model_match[] __initconst = { X86_RAPL_MODEL_MATCH(INTEL_FAM6_SANDYBRIDGE_X, model_snbep), X86_RAPL_MODEL_MATCH(INTEL_FAM6_IVYBRIDGE, model_snb), X86_RAPL_MODEL_MATCH(INTEL_FAM6_IVYBRIDGE_X, model_snbep), - X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_CORE, model_hsw), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_X, model_hsx), X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_ULT, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_GT3E, model_hsw), - X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_CORE, model_hsw), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_GT3E, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_X, model_hsx), X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_XEON_D, model_hsx), X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNL, model_knl), X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNM, model_knl), X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_MOBILE, model_skl), - X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_DESKTOP, model_skl), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE, model_skl), X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_X, model_hsx), X86_RAPL_MODEL_MATCH(INTEL_FAM6_KABYLAKE_MOBILE, model_skl), - X86_RAPL_MODEL_MATCH(INTEL_FAM6_KABYLAKE_DESKTOP, model_skl), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_KABYLAKE, model_skl), X86_RAPL_MODEL_MATCH(INTEL_FAM6_CANNONLAKE_MOBILE, model_skl), X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT_X, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT_PLUS, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_ICELAKE_MOBILE, model_skl), - X86_RAPL_MODEL_MATCH(INTEL_FAM6_ICELAKE_DESKTOP, model_skl), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_ICELAKE, model_skl), {}, }; diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c index 3694a5d0703d..d5e091586242 100644 --- a/arch/x86/events/intel/uncore.c +++ b/arch/x86/events/intel/uncore.c @@ -1451,10 +1451,10 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = { X86_UNCORE_MODEL_MATCH(INTEL_FAM6_WESTMERE_EP, nhm_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SANDYBRIDGE, snb_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_IVYBRIDGE, ivb_uncore_init), - X86_UNCORE_MODEL_MATCH(INTEL_FAM6_HASWELL_CORE, hsw_uncore_init), + X86_UNCORE_MODEL_MATCH(INTEL_FAM6_HASWELL, hsw_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_HASWELL_ULT, hsw_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_HASWELL_GT3E, hsw_uncore_init), - X86_UNCORE_MODEL_MATCH(INTEL_FAM6_BROADWELL_CORE, bdw_uncore_init), + X86_UNCORE_MODEL_MATCH(INTEL_FAM6_BROADWELL, bdw_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_BROADWELL_GT3E, bdw_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SANDYBRIDGE_X, snbep_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_NEHALEM_EX, nhmex_uncore_init), @@ -1465,14 +1465,14 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = { X86_UNCORE_MODEL_MATCH(INTEL_FAM6_BROADWELL_XEON_D, bdx_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNL, knl_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNM, knl_uncore_init), - X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE_DESKTOP,skl_uncore_init), + X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE, skl_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE_MOBILE, skl_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE_X, skx_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_KABYLAKE_MOBILE, skl_uncore_init), - X86_UNCORE_MODEL_MATCH(INTEL_FAM6_KABYLAKE_DESKTOP, skl_uncore_init), + X86_UNCORE_MODEL_MATCH(INTEL_FAM6_KABYLAKE, skl_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_MOBILE, icl_uncore_init), - X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_NNPI, icl_uncore_init), - X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_DESKTOP, icl_uncore_init), + X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_NNPI, icl_uncore_init), + X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE, icl_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ATOM_TREMONT_X, snr_uncore_init), {}, }; diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c index 9431447541e9..08d320a39dff 100644 --- a/arch/x86/events/msr.c +++ b/arch/x86/events/msr.c @@ -59,12 +59,12 @@ static bool test_intel(int idx, void *data) case INTEL_FAM6_IVYBRIDGE: case INTEL_FAM6_IVYBRIDGE_X: - case INTEL_FAM6_HASWELL_CORE: + case INTEL_FAM6_HASWELL: case INTEL_FAM6_HASWELL_X: case INTEL_FAM6_HASWELL_ULT: case INTEL_FAM6_HASWELL_GT3E: - case INTEL_FAM6_BROADWELL_CORE: + case INTEL_FAM6_BROADWELL: case INTEL_FAM6_BROADWELL_XEON_D: case INTEL_FAM6_BROADWELL_GT3E: case INTEL_FAM6_BROADWELL_X: @@ -85,10 +85,10 @@ static bool test_intel(int idx, void *data) break; case INTEL_FAM6_SKYLAKE_MOBILE: - case INTEL_FAM6_SKYLAKE_DESKTOP: + case INTEL_FAM6_SKYLAKE: case INTEL_FAM6_SKYLAKE_X: case INTEL_FAM6_KABYLAKE_MOBILE: - case INTEL_FAM6_KABYLAKE_DESKTOP: + case INTEL_FAM6_KABYLAKE: case INTEL_FAM6_ICELAKE_MOBILE: if (idx == PERF_MSR_SMI || idx == PERF_MSR_PPERF) return true; diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h index fe7c205233f1..800dd17e61c4 100644 --- a/arch/x86/include/asm/intel-family.h +++ b/arch/x86/include/asm/intel-family.h @@ -49,27 +49,27 @@ #define INTEL_FAM6_IVYBRIDGE 0x3A #define INTEL_FAM6_IVYBRIDGE_X 0x3E -#define INTEL_FAM6_HASWELL_CORE 0x3C +#define INTEL_FAM6_HASWELL 0x3C #define INTEL_FAM6_HASWELL_X 0x3F #define INTEL_FAM6_HASWELL_ULT 0x45 #define INTEL_FAM6_HASWELL_GT3E 0x46 -#define INTEL_FAM6_BROADWELL_CORE 0x3D +#define INTEL_FAM6_BROADWELL 0x3D #define INTEL_FAM6_BROADWELL_GT3E 0x47 #define INTEL_FAM6_BROADWELL_X 0x4F #define INTEL_FAM6_BROADWELL_XEON_D 0x56 #define INTEL_FAM6_SKYLAKE_MOBILE 0x4E -#define INTEL_FAM6_SKYLAKE_DESKTOP 0x5E +#define INTEL_FAM6_SKYLAKE 0x5E #define INTEL_FAM6_SKYLAKE_X 0x55 #define INTEL_FAM6_KABYLAKE_MOBILE 0x8E -#define INTEL_FAM6_KABYLAKE_DESKTOP 0x9E +#define INTEL_FAM6_KABYLAKE 0x9E #define INTEL_FAM6_CANNONLAKE_MOBILE 0x66 #define INTEL_FAM6_ICELAKE_X 0x6A #define INTEL_FAM6_ICELAKE_XEON_D 0x6C -#define INTEL_FAM6_ICELAKE_DESKTOP 0x7D +#define INTEL_FAM6_ICELAKE 0x7D #define INTEL_FAM6_ICELAKE_MOBILE 0x7E #define INTEL_FAM6_ICELAKE_NNPI 0x9D diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index aa5495d0f478..0527465e1c98 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -593,18 +593,18 @@ static const struct x86_cpu_id deadline_match[] = { DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_BROADWELL_XEON_D, bdx_deadline_rev), DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_SKYLAKE_X, skx_deadline_rev), - DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_CORE, 0x22), + DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL, 0x22), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_ULT, 0x20), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_GT3E, 0x17), - DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_CORE, 0x25), + DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL, 0x25), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_GT3E, 0x17), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE_MOBILE, 0xb2), - DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE_DESKTOP, 0xb2), + DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE, 0xb2), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_KABYLAKE_MOBILE, 0x52), - DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_KABYLAKE_DESKTOP, 0x52), + DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_KABYLAKE, 0x52), {}, }; diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index c6fa3ef10b4e..6c611abd6cdd 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -1184,15 +1184,15 @@ static void override_cache_bits(struct cpuinfo_x86 *c) case INTEL_FAM6_WESTMERE: case INTEL_FAM6_SANDYBRIDGE: case INTEL_FAM6_IVYBRIDGE: - case INTEL_FAM6_HASWELL_CORE: + case INTEL_FAM6_HASWELL: case INTEL_FAM6_HASWELL_ULT: case INTEL_FAM6_HASWELL_GT3E: - case INTEL_FAM6_BROADWELL_CORE: + case INTEL_FAM6_BROADWELL: case INTEL_FAM6_BROADWELL_GT3E: case INTEL_FAM6_SKYLAKE_MOBILE: - case INTEL_FAM6_SKYLAKE_DESKTOP: + case INTEL_FAM6_SKYLAKE: case INTEL_FAM6_KABYLAKE_MOBILE: - case INTEL_FAM6_KABYLAKE_DESKTOP: + case INTEL_FAM6_KABYLAKE: if (c->x86_cache_bits < 44) c->x86_cache_bits = 44; break; diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 8d6d92ebeb54..ca62563c1bb3 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -142,21 +142,21 @@ struct sku_microcode { u32 microcode; }; static const struct sku_microcode spectre_bad_microcodes[] = { - { INTEL_FAM6_KABYLAKE_DESKTOP, 0x0B, 0x80 }, - { INTEL_FAM6_KABYLAKE_DESKTOP, 0x0A, 0x80 }, - { INTEL_FAM6_KABYLAKE_DESKTOP, 0x09, 0x80 }, + { INTEL_FAM6_KABYLAKE, 0x0B, 0x80 }, + { INTEL_FAM6_KABYLAKE, 0x0A, 0x80 }, + { INTEL_FAM6_KABYLAKE, 0x09, 0x80 }, { INTEL_FAM6_KABYLAKE_MOBILE, 0x0A, 0x80 }, { INTEL_FAM6_KABYLAKE_MOBILE, 0x09, 0x80 }, { INTEL_FAM6_SKYLAKE_X, 0x03, 0x0100013e }, { INTEL_FAM6_SKYLAKE_X, 0x04, 0x0200003c }, - { INTEL_FAM6_BROADWELL_CORE, 0x04, 0x28 }, + { INTEL_FAM6_BROADWELL, 0x04, 0x28 }, { INTEL_FAM6_BROADWELL_GT3E, 0x01, 0x1b }, { INTEL_FAM6_BROADWELL_XEON_D, 0x02, 0x14 }, { INTEL_FAM6_BROADWELL_XEON_D, 0x03, 0x07000011 }, { INTEL_FAM6_BROADWELL_X, 0x01, 0x0b000025 }, { INTEL_FAM6_HASWELL_ULT, 0x01, 0x21 }, { INTEL_FAM6_HASWELL_GT3E, 0x01, 0x18 }, - { INTEL_FAM6_HASWELL_CORE, 0x03, 0x23 }, + { INTEL_FAM6_HASWELL, 0x03, 0x23 }, { INTEL_FAM6_HASWELL_X, 0x02, 0x3b }, { INTEL_FAM6_HASWELL_X, 0x04, 0x10 }, { INTEL_FAM6_IVYBRIDGE_X, 0x04, 0x42a }, diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index cc27d4c59dca..17cb9af25328 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -1867,12 +1867,12 @@ static const struct pstate_funcs knl_funcs = { (unsigned long)&policy } static const struct x86_cpu_id intel_pstate_cpu_ids[] = { - ICPU(INTEL_FAM6_SANDYBRIDGE, core_funcs), + ICPU(INTEL_FAM6_SANDYBRIDGE, core_funcs), ICPU(INTEL_FAM6_SANDYBRIDGE_X, core_funcs), ICPU(INTEL_FAM6_ATOM_SILVERMONT, silvermont_funcs), ICPU(INTEL_FAM6_IVYBRIDGE, core_funcs), - ICPU(INTEL_FAM6_HASWELL_CORE, core_funcs), - ICPU(INTEL_FAM6_BROADWELL_CORE, core_funcs), + ICPU(INTEL_FAM6_HASWELL, core_funcs), + ICPU(INTEL_FAM6_BROADWELL, core_funcs), ICPU(INTEL_FAM6_IVYBRIDGE_X, core_funcs), ICPU(INTEL_FAM6_HASWELL_X, core_funcs), ICPU(INTEL_FAM6_HASWELL_ULT, core_funcs), @@ -1881,7 +1881,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { ICPU(INTEL_FAM6_ATOM_AIRMONT, airmont_funcs), ICPU(INTEL_FAM6_SKYLAKE_MOBILE, core_funcs), ICPU(INTEL_FAM6_BROADWELL_X, core_funcs), - ICPU(INTEL_FAM6_SKYLAKE_DESKTOP, core_funcs), + ICPU(INTEL_FAM6_SKYLAKE, core_funcs), ICPU(INTEL_FAM6_BROADWELL_XEON_D, core_funcs), ICPU(INTEL_FAM6_XEON_PHI_KNL, knl_funcs), ICPU(INTEL_FAM6_XEON_PHI_KNM, knl_funcs), @@ -1900,13 +1900,13 @@ static const struct x86_cpu_id intel_pstate_cpu_oob_ids[] __initconst = { }; static const struct x86_cpu_id intel_pstate_cpu_ee_disable_ids[] = { - ICPU(INTEL_FAM6_KABYLAKE_DESKTOP, core_funcs), + ICPU(INTEL_FAM6_KABYLAKE, core_funcs), {} }; static const struct x86_cpu_id intel_pstate_hwp_boost_ids[] = { ICPU(INTEL_FAM6_SKYLAKE_X, core_funcs), - ICPU(INTEL_FAM6_SKYLAKE_DESKTOP, core_funcs), + ICPU(INTEL_FAM6_SKYLAKE, core_funcs), {} }; diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index fa5ff77b8fe4..f45898965fe1 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -1072,19 +1072,19 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = { INTEL_CPU_FAM6(ATOM_AIRMONT, idle_cpu_cht), INTEL_CPU_FAM6(IVYBRIDGE, idle_cpu_ivb), INTEL_CPU_FAM6(IVYBRIDGE_X, idle_cpu_ivt), - INTEL_CPU_FAM6(HASWELL_CORE, idle_cpu_hsw), + INTEL_CPU_FAM6(HASWELL, idle_cpu_hsw), INTEL_CPU_FAM6(HASWELL_X, idle_cpu_hsw), INTEL_CPU_FAM6(HASWELL_ULT, idle_cpu_hsw), INTEL_CPU_FAM6(HASWELL_GT3E, idle_cpu_hsw), INTEL_CPU_FAM6(ATOM_SILVERMONT_X, idle_cpu_avn), - INTEL_CPU_FAM6(BROADWELL_CORE, idle_cpu_bdw), + INTEL_CPU_FAM6(BROADWELL, idle_cpu_bdw), INTEL_CPU_FAM6(BROADWELL_GT3E, idle_cpu_bdw), INTEL_CPU_FAM6(BROADWELL_X, idle_cpu_bdw), INTEL_CPU_FAM6(BROADWELL_XEON_D, idle_cpu_bdw), INTEL_CPU_FAM6(SKYLAKE_MOBILE, idle_cpu_skl), - INTEL_CPU_FAM6(SKYLAKE_DESKTOP, idle_cpu_skl), + INTEL_CPU_FAM6(SKYLAKE, idle_cpu_skl), INTEL_CPU_FAM6(KABYLAKE_MOBILE, idle_cpu_skl), - INTEL_CPU_FAM6(KABYLAKE_DESKTOP, idle_cpu_skl), + INTEL_CPU_FAM6(KABYLAKE, idle_cpu_skl), INTEL_CPU_FAM6(SKYLAKE_X, idle_cpu_skx), INTEL_CPU_FAM6(XEON_PHI_KNL, idle_cpu_knl), INTEL_CPU_FAM6(XEON_PHI_KNM, idle_cpu_knl), @@ -1311,7 +1311,7 @@ static void intel_idle_state_table_update(void) case INTEL_FAM6_ATOM_GOLDMONT_PLUS: bxt_idle_state_table_update(); break; - case INTEL_FAM6_SKYLAKE_DESKTOP: + case INTEL_FAM6_SKYLAKE: sklh_idle_state_table_update(); break; } diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c index c510d0d72475..3a82df45bced 100644 --- a/drivers/platform/x86/intel_pmc_core.c +++ b/drivers/platform/x86/intel_pmc_core.c @@ -807,9 +807,9 @@ static inline void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev) static const struct x86_cpu_id intel_pmc_core_ids[] = { INTEL_CPU_FAM6(SKYLAKE_MOBILE, spt_reg_map), - INTEL_CPU_FAM6(SKYLAKE_DESKTOP, spt_reg_map), + INTEL_CPU_FAM6(SKYLAKE, spt_reg_map), INTEL_CPU_FAM6(KABYLAKE_MOBILE, spt_reg_map), - INTEL_CPU_FAM6(KABYLAKE_DESKTOP, spt_reg_map), + INTEL_CPU_FAM6(KABYLAKE, spt_reg_map), INTEL_CPU_FAM6(CANNONLAKE_MOBILE, cnp_reg_map), INTEL_CPU_FAM6(ICELAKE_MOBILE, icl_reg_map), INTEL_CPU_FAM6(ICELAKE_NNPI, icl_reg_map), diff --git a/drivers/platform/x86/intel_pmc_core_pltdrv.c b/drivers/platform/x86/intel_pmc_core_pltdrv.c index a8754a6db1b8..52f5bcb88011 100644 --- a/drivers/platform/x86/intel_pmc_core_pltdrv.c +++ b/drivers/platform/x86/intel_pmc_core_pltdrv.c @@ -31,9 +31,9 @@ static struct platform_device pmc_core_device = { */ static const struct x86_cpu_id intel_pmc_core_platform_ids[] = { INTEL_CPU_FAM6(SKYLAKE_MOBILE, pmc_core_device), - INTEL_CPU_FAM6(SKYLAKE_DESKTOP, pmc_core_device), + INTEL_CPU_FAM6(SKYLAKE, pmc_core_device), INTEL_CPU_FAM6(KABYLAKE_MOBILE, pmc_core_device), - INTEL_CPU_FAM6(KABYLAKE_DESKTOP, pmc_core_device), + INTEL_CPU_FAM6(KABYLAKE, pmc_core_device), INTEL_CPU_FAM6(CANNONLAKE_MOBILE, pmc_core_device), INTEL_CPU_FAM6(ICELAKE_MOBILE, pmc_core_device), {} diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c index 6df481896b5f..7c9eb78d3471 100644 --- a/drivers/powercap/intel_rapl_common.c +++ b/drivers/powercap/intel_rapl_common.c @@ -957,24 +957,24 @@ static const struct x86_cpu_id rapl_ids[] __initconst = { INTEL_CPU_FAM6(IVYBRIDGE, rapl_defaults_core), INTEL_CPU_FAM6(IVYBRIDGE_X, rapl_defaults_core), - INTEL_CPU_FAM6(HASWELL_CORE, rapl_defaults_core), + INTEL_CPU_FAM6(HASWELL, rapl_defaults_core), INTEL_CPU_FAM6(HASWELL_ULT, rapl_defaults_core), INTEL_CPU_FAM6(HASWELL_GT3E, rapl_defaults_core), INTEL_CPU_FAM6(HASWELL_X, rapl_defaults_hsw_server), - INTEL_CPU_FAM6(BROADWELL_CORE, rapl_defaults_core), + INTEL_CPU_FAM6(BROADWELL, rapl_defaults_core), INTEL_CPU_FAM6(BROADWELL_GT3E, rapl_defaults_core), INTEL_CPU_FAM6(BROADWELL_XEON_D, rapl_defaults_core), INTEL_CPU_FAM6(BROADWELL_X, rapl_defaults_hsw_server), - INTEL_CPU_FAM6(SKYLAKE_DESKTOP, rapl_defaults_core), + INTEL_CPU_FAM6(SKYLAKE, rapl_defaults_core), INTEL_CPU_FAM6(SKYLAKE_MOBILE, rapl_defaults_core), INTEL_CPU_FAM6(SKYLAKE_X, rapl_defaults_hsw_server), INTEL_CPU_FAM6(KABYLAKE_MOBILE, rapl_defaults_core), - INTEL_CPU_FAM6(KABYLAKE_DESKTOP, rapl_defaults_core), + INTEL_CPU_FAM6(KABYLAKE, rapl_defaults_core), INTEL_CPU_FAM6(CANNONLAKE_MOBILE, rapl_defaults_core), INTEL_CPU_FAM6(ICELAKE_MOBILE, rapl_defaults_core), - INTEL_CPU_FAM6(ICELAKE_DESKTOP, rapl_defaults_core), + INTEL_CPU_FAM6(ICELAKE, rapl_defaults_core), INTEL_CPU_FAM6(ICELAKE_NNPI, rapl_defaults_core), INTEL_CPU_FAM6(ICELAKE_X, rapl_defaults_hsw_server), INTEL_CPU_FAM6(ICELAKE_XEON_D, rapl_defaults_hsw_server), diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 75fc4fb9901c..8083a354ae7f 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -3207,10 +3207,10 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) pkg_cstate_limits = snb_pkg_cstate_limits; has_misc_feature_control = 1; break; - case INTEL_FAM6_HASWELL_CORE: /* HSW */ + case INTEL_FAM6_HASWELL: /* HSW */ case INTEL_FAM6_HASWELL_X: /* HSX */ case INTEL_FAM6_HASWELL_GT3E: /* HSW */ - case INTEL_FAM6_BROADWELL_CORE: /* BDW */ + case INTEL_FAM6_BROADWELL: /* BDW */ case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ case INTEL_FAM6_BROADWELL_X: /* BDX */ case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ @@ -3403,10 +3403,10 @@ int has_config_tdp(unsigned int family, unsigned int model) switch (model) { case INTEL_FAM6_IVYBRIDGE: /* IVB */ - case INTEL_FAM6_HASWELL_CORE: /* HSW */ + case INTEL_FAM6_HASWELL: /* HSW */ case INTEL_FAM6_HASWELL_X: /* HSX */ case INTEL_FAM6_HASWELL_GT3E: /* HSW */ - case INTEL_FAM6_BROADWELL_CORE: /* BDW */ + case INTEL_FAM6_BROADWELL: /* BDW */ case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ case INTEL_FAM6_BROADWELL_X: /* BDX */ case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ @@ -3840,9 +3840,9 @@ void rapl_probe_intel(unsigned int family, unsigned int model) switch (model) { case INTEL_FAM6_SANDYBRIDGE: case INTEL_FAM6_IVYBRIDGE: - case INTEL_FAM6_HASWELL_CORE: /* HSW */ + case INTEL_FAM6_HASWELL: /* HSW */ case INTEL_FAM6_HASWELL_GT3E: /* HSW */ - case INTEL_FAM6_BROADWELL_CORE: /* BDW */ + case INTEL_FAM6_BROADWELL: /* BDW */ case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO; if (rapl_joules) { @@ -4031,7 +4031,7 @@ void perf_limit_reasons_probe(unsigned int family, unsigned int model) return; switch (model) { - case INTEL_FAM6_HASWELL_CORE: /* HSW */ + case INTEL_FAM6_HASWELL: /* HSW */ case INTEL_FAM6_HASWELL_GT3E: /* HSW */ do_gfx_perf_limit_reasons = 1; case INTEL_FAM6_HASWELL_X: /* HSX */ @@ -4249,10 +4249,10 @@ int has_snb_msrs(unsigned int family, unsigned int model) case INTEL_FAM6_SANDYBRIDGE_X: case INTEL_FAM6_IVYBRIDGE: /* IVB */ case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */ - case INTEL_FAM6_HASWELL_CORE: /* HSW */ + case INTEL_FAM6_HASWELL: /* HSW */ case INTEL_FAM6_HASWELL_X: /* HSW */ case INTEL_FAM6_HASWELL_GT3E: /* HSW */ - case INTEL_FAM6_BROADWELL_CORE: /* BDW */ + case INTEL_FAM6_BROADWELL: /* BDW */ case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ case INTEL_FAM6_BROADWELL_X: /* BDX */ case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ @@ -4284,8 +4284,8 @@ int has_hsw_msrs(unsigned int family, unsigned int model) return 0; switch (model) { - case INTEL_FAM6_HASWELL_CORE: - case INTEL_FAM6_BROADWELL_CORE: /* BDW */ + case INTEL_FAM6_HASWELL: + case INTEL_FAM6_BROADWELL: /* BDW */ case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ @@ -4569,16 +4569,16 @@ unsigned int intel_model_duplicates(unsigned int model) return INTEL_FAM6_XEON_PHI_KNL; case INTEL_FAM6_HASWELL_ULT: - return INTEL_FAM6_HASWELL_CORE; + return INTEL_FAM6_HASWELL; case INTEL_FAM6_BROADWELL_X: case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ return INTEL_FAM6_BROADWELL_X; case INTEL_FAM6_SKYLAKE_MOBILE: - case INTEL_FAM6_SKYLAKE_DESKTOP: + case INTEL_FAM6_SKYLAKE: case INTEL_FAM6_KABYLAKE_MOBILE: - case INTEL_FAM6_KABYLAKE_DESKTOP: + case INTEL_FAM6_KABYLAKE: return INTEL_FAM6_SKYLAKE_MOBILE; case INTEL_FAM6_ICELAKE_MOBILE: -- cgit v1.2.3-59-g8ed1b From af239c44e3f976762e9bc052f0d5796b90ea530b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 27 Aug 2019 21:48:22 +0200 Subject: x86/intel: Aggregate big core mobile naming Currently big core mobile chips have either: - _L - _ULT - _MOBILE Make it uniformly: _L. for i in `git grep -l "\(INTEL_FAM6_\|VULNWL_INTEL\|INTEL_CPU_FAM6\).*_\(MOBILE\|ULT\)"` do sed -i -e 's/\(\(INTEL_FAM6_\|VULNWL_INTEL\|INTEL_CPU_FAM6\).*\)_\(MOBILE\|ULT\)/\1_L/g' ${i} done Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Tony Luck Cc: x86@kernel.org Cc: Dave Hansen Cc: Borislav Petkov Cc: Thomas Gleixner Link: https://lkml.kernel.org/r/20190827195122.568978530@infradead.org --- arch/x86/events/intel/core.c | 20 +++++++------- arch/x86/events/intel/cstate.c | 18 ++++++------- arch/x86/events/intel/rapl.c | 10 +++---- arch/x86/events/intel/uncore.c | 8 +++--- arch/x86/events/msr.c | 8 +++--- arch/x86/include/asm/intel-family.h | 10 +++---- arch/x86/kernel/apic/apic.c | 6 ++--- arch/x86/kernel/cpu/bugs.c | 6 ++--- arch/x86/kernel/cpu/intel.c | 6 ++--- drivers/acpi/x86/utils.c | 4 +-- drivers/cpufreq/intel_pstate.c | 4 +-- drivers/idle/intel_idle.c | 6 ++--- drivers/platform/x86/intel_pmc_core.c | 8 +++--- drivers/platform/x86/intel_pmc_core_pltdrv.c | 8 +++--- drivers/powercap/intel_rapl_common.c | 10 +++---- tools/power/x86/turbostat/turbostat.c | 40 ++++++++++++++-------------- 16 files changed, 86 insertions(+), 86 deletions(-) (limited to 'tools') diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 76bff3a33725..22ef9ccaf45c 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -3965,7 +3965,7 @@ static __init void intel_clovertown_quirk(void) static const struct x86_cpu_desc isolation_ucodes[] = { INTEL_CPU_DESC(INTEL_FAM6_HASWELL, 3, 0x0000001f), - INTEL_CPU_DESC(INTEL_FAM6_HASWELL_ULT, 1, 0x0000001e), + INTEL_CPU_DESC(INTEL_FAM6_HASWELL_L, 1, 0x0000001e), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_GT3E, 1, 0x00000015), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 2, 0x00000037), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 4, 0x0000000a), @@ -3978,13 +3978,13 @@ static const struct x86_cpu_desc isolation_ucodes[] = { INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_X, 2, 0x0b000014), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 3, 0x00000021), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 4, 0x00000000), - INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_MOBILE, 3, 0x0000007c), + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_L, 3, 0x0000007c), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE, 3, 0x0000007c), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 9, 0x0000004e), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 9, 0x0000004e), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 10, 0x0000004e), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 11, 0x0000004e), - INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 12, 0x0000004e), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_L, 9, 0x0000004e), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_L, 10, 0x0000004e), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_L, 11, 0x0000004e), + INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_L, 12, 0x0000004e), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 10, 0x0000004e), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 11, 0x0000004e), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 12, 0x0000004e), @@ -4859,7 +4859,7 @@ __init int intel_pmu_init(void) case INTEL_FAM6_HASWELL: case INTEL_FAM6_HASWELL_X: - case INTEL_FAM6_HASWELL_ULT: + case INTEL_FAM6_HASWELL_L: case INTEL_FAM6_HASWELL_GT3E: x86_add_quirk(intel_ht_bug); x86_add_quirk(intel_pebs_isolation_quirk); @@ -4955,9 +4955,9 @@ __init int intel_pmu_init(void) case INTEL_FAM6_SKYLAKE_X: pmem = true; /* fall through */ - case INTEL_FAM6_SKYLAKE_MOBILE: + case INTEL_FAM6_SKYLAKE_L: case INTEL_FAM6_SKYLAKE: - case INTEL_FAM6_KABYLAKE_MOBILE: + case INTEL_FAM6_KABYLAKE_L: case INTEL_FAM6_KABYLAKE: x86_add_quirk(intel_pebs_isolation_quirk); x86_pmu.late_ack = true; @@ -5005,7 +5005,7 @@ __init int intel_pmu_init(void) case INTEL_FAM6_ICELAKE_XEON_D: pmem = true; /* fall through */ - case INTEL_FAM6_ICELAKE_MOBILE: + case INTEL_FAM6_ICELAKE_L: case INTEL_FAM6_ICELAKE: x86_pmu.late_ack = true; memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids)); diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c index 3854400ad8ff..9b014e813626 100644 --- a/arch/x86/events/intel/cstate.c +++ b/arch/x86/events/intel/cstate.c @@ -597,7 +597,7 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_X, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_GT3E, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_ULT, hswult_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_L, hswult_cstates), X86_CSTATES_MODEL(INTEL_FAM6_ATOM_SILVERMONT, slm_cstates), X86_CSTATES_MODEL(INTEL_FAM6_ATOM_SILVERMONT_X, slm_cstates), @@ -608,14 +608,14 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_GT3E, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_X, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_MOBILE, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_X, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_L, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_X, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_MOBILE, hswult_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE, hswult_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_L, hswult_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE, hswult_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_CANNONLAKE_MOBILE, cnl_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_CANNONLAKE_L, cnl_cstates), X86_CSTATES_MODEL(INTEL_FAM6_XEON_PHI_KNL, knl_cstates), X86_CSTATES_MODEL(INTEL_FAM6_XEON_PHI_KNM, knl_cstates), @@ -625,8 +625,8 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_PLUS, glm_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE_MOBILE, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE_L, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE, snb_cstates), { }, }; MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match); diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c index c1278e2764f4..70dcfe9312b0 100644 --- a/arch/x86/events/intel/rapl.c +++ b/arch/x86/events/intel/rapl.c @@ -722,7 +722,7 @@ static const struct x86_cpu_id rapl_model_match[] __initconst = { X86_RAPL_MODEL_MATCH(INTEL_FAM6_IVYBRIDGE_X, model_snbep), X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_X, model_hsx), - X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_ULT, model_hsw), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_L, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_GT3E, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_GT3E, model_hsw), @@ -730,16 +730,16 @@ static const struct x86_cpu_id rapl_model_match[] __initconst = { X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_XEON_D, model_hsx), X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNL, model_knl), X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNM, model_knl), - X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_MOBILE, model_skl), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_L, model_skl), X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE, model_skl), X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_X, model_hsx), - X86_RAPL_MODEL_MATCH(INTEL_FAM6_KABYLAKE_MOBILE, model_skl), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_KABYLAKE_L, model_skl), X86_RAPL_MODEL_MATCH(INTEL_FAM6_KABYLAKE, model_skl), - X86_RAPL_MODEL_MATCH(INTEL_FAM6_CANNONLAKE_MOBILE, model_skl), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_CANNONLAKE_L, model_skl), X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT_X, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT_PLUS, model_hsw), - X86_RAPL_MODEL_MATCH(INTEL_FAM6_ICELAKE_MOBILE, model_skl), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_ICELAKE_L, model_skl), X86_RAPL_MODEL_MATCH(INTEL_FAM6_ICELAKE, model_skl), {}, }; diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c index d5e091586242..8428e28c9625 100644 --- a/arch/x86/events/intel/uncore.c +++ b/arch/x86/events/intel/uncore.c @@ -1452,7 +1452,7 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = { X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SANDYBRIDGE, snb_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_IVYBRIDGE, ivb_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_HASWELL, hsw_uncore_init), - X86_UNCORE_MODEL_MATCH(INTEL_FAM6_HASWELL_ULT, hsw_uncore_init), + X86_UNCORE_MODEL_MATCH(INTEL_FAM6_HASWELL_L, hsw_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_HASWELL_GT3E, hsw_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_BROADWELL, bdw_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_BROADWELL_GT3E, bdw_uncore_init), @@ -1466,11 +1466,11 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = { X86_UNCORE_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNL, knl_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNM, knl_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE, skl_uncore_init), - X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE_MOBILE, skl_uncore_init), + X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE_L, skl_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE_X, skx_uncore_init), - X86_UNCORE_MODEL_MATCH(INTEL_FAM6_KABYLAKE_MOBILE, skl_uncore_init), + X86_UNCORE_MODEL_MATCH(INTEL_FAM6_KABYLAKE_L, skl_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_KABYLAKE, skl_uncore_init), - X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_MOBILE, icl_uncore_init), + X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_L, icl_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_NNPI, icl_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE, icl_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ATOM_TREMONT_X, snr_uncore_init), diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c index 08d320a39dff..12265c14e60d 100644 --- a/arch/x86/events/msr.c +++ b/arch/x86/events/msr.c @@ -61,7 +61,7 @@ static bool test_intel(int idx, void *data) case INTEL_FAM6_HASWELL: case INTEL_FAM6_HASWELL_X: - case INTEL_FAM6_HASWELL_ULT: + case INTEL_FAM6_HASWELL_L: case INTEL_FAM6_HASWELL_GT3E: case INTEL_FAM6_BROADWELL: @@ -84,12 +84,12 @@ static bool test_intel(int idx, void *data) return true; break; - case INTEL_FAM6_SKYLAKE_MOBILE: + case INTEL_FAM6_SKYLAKE_L: case INTEL_FAM6_SKYLAKE: case INTEL_FAM6_SKYLAKE_X: - case INTEL_FAM6_KABYLAKE_MOBILE: + case INTEL_FAM6_KABYLAKE_L: case INTEL_FAM6_KABYLAKE: - case INTEL_FAM6_ICELAKE_MOBILE: + case INTEL_FAM6_ICELAKE_L: if (idx == PERF_MSR_SMI || idx == PERF_MSR_PPERF) return true; break; diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h index 800dd17e61c4..25b71d4e9224 100644 --- a/arch/x86/include/asm/intel-family.h +++ b/arch/x86/include/asm/intel-family.h @@ -51,7 +51,7 @@ #define INTEL_FAM6_HASWELL 0x3C #define INTEL_FAM6_HASWELL_X 0x3F -#define INTEL_FAM6_HASWELL_ULT 0x45 +#define INTEL_FAM6_HASWELL_L 0x45 #define INTEL_FAM6_HASWELL_GT3E 0x46 #define INTEL_FAM6_BROADWELL 0x3D @@ -59,18 +59,18 @@ #define INTEL_FAM6_BROADWELL_X 0x4F #define INTEL_FAM6_BROADWELL_XEON_D 0x56 -#define INTEL_FAM6_SKYLAKE_MOBILE 0x4E +#define INTEL_FAM6_SKYLAKE_L 0x4E #define INTEL_FAM6_SKYLAKE 0x5E #define INTEL_FAM6_SKYLAKE_X 0x55 -#define INTEL_FAM6_KABYLAKE_MOBILE 0x8E +#define INTEL_FAM6_KABYLAKE_L 0x8E #define INTEL_FAM6_KABYLAKE 0x9E -#define INTEL_FAM6_CANNONLAKE_MOBILE 0x66 +#define INTEL_FAM6_CANNONLAKE_L 0x66 #define INTEL_FAM6_ICELAKE_X 0x6A #define INTEL_FAM6_ICELAKE_XEON_D 0x6C #define INTEL_FAM6_ICELAKE 0x7D -#define INTEL_FAM6_ICELAKE_MOBILE 0x7E +#define INTEL_FAM6_ICELAKE_L 0x7E #define INTEL_FAM6_ICELAKE_NNPI 0x9D /* "Small Core" Processors (Atom) */ diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 0527465e1c98..adf001d30b47 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -594,16 +594,16 @@ static const struct x86_cpu_id deadline_match[] = { DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_SKYLAKE_X, skx_deadline_rev), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL, 0x22), - DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_ULT, 0x20), + DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_L, 0x20), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_GT3E, 0x17), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL, 0x25), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_GT3E, 0x17), - DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE_MOBILE, 0xb2), + DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE_L, 0xb2), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE, 0xb2), - DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_KABYLAKE_MOBILE, 0x52), + DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_KABYLAKE_L, 0x52), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_KABYLAKE, 0x52), {}, diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 6c611abd6cdd..f435780fe45e 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -1185,13 +1185,13 @@ static void override_cache_bits(struct cpuinfo_x86 *c) case INTEL_FAM6_SANDYBRIDGE: case INTEL_FAM6_IVYBRIDGE: case INTEL_FAM6_HASWELL: - case INTEL_FAM6_HASWELL_ULT: + case INTEL_FAM6_HASWELL_L: case INTEL_FAM6_HASWELL_GT3E: case INTEL_FAM6_BROADWELL: case INTEL_FAM6_BROADWELL_GT3E: - case INTEL_FAM6_SKYLAKE_MOBILE: + case INTEL_FAM6_SKYLAKE_L: case INTEL_FAM6_SKYLAKE: - case INTEL_FAM6_KABYLAKE_MOBILE: + case INTEL_FAM6_KABYLAKE_L: case INTEL_FAM6_KABYLAKE: if (c->x86_cache_bits < 44) c->x86_cache_bits = 44; diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index ca62563c1bb3..bafa2735f541 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -145,8 +145,8 @@ static const struct sku_microcode spectre_bad_microcodes[] = { { INTEL_FAM6_KABYLAKE, 0x0B, 0x80 }, { INTEL_FAM6_KABYLAKE, 0x0A, 0x80 }, { INTEL_FAM6_KABYLAKE, 0x09, 0x80 }, - { INTEL_FAM6_KABYLAKE_MOBILE, 0x0A, 0x80 }, - { INTEL_FAM6_KABYLAKE_MOBILE, 0x09, 0x80 }, + { INTEL_FAM6_KABYLAKE_L, 0x0A, 0x80 }, + { INTEL_FAM6_KABYLAKE_L, 0x09, 0x80 }, { INTEL_FAM6_SKYLAKE_X, 0x03, 0x0100013e }, { INTEL_FAM6_SKYLAKE_X, 0x04, 0x0200003c }, { INTEL_FAM6_BROADWELL, 0x04, 0x28 }, @@ -154,7 +154,7 @@ static const struct sku_microcode spectre_bad_microcodes[] = { { INTEL_FAM6_BROADWELL_XEON_D, 0x02, 0x14 }, { INTEL_FAM6_BROADWELL_XEON_D, 0x03, 0x07000011 }, { INTEL_FAM6_BROADWELL_X, 0x01, 0x0b000025 }, - { INTEL_FAM6_HASWELL_ULT, 0x01, 0x21 }, + { INTEL_FAM6_HASWELL_L, 0x01, 0x21 }, { INTEL_FAM6_HASWELL_GT3E, 0x01, 0x18 }, { INTEL_FAM6_HASWELL, 0x03, 0x23 }, { INTEL_FAM6_HASWELL_X, 0x02, 0x3b }, diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c index ba277cd5c7fa..697a6b12d6b9 100644 --- a/drivers/acpi/x86/utils.c +++ b/drivers/acpi/x86/utils.c @@ -69,11 +69,11 @@ static const struct always_present_id always_present_ids[] = { * after _SB.PCI0.GFX0.LCD.LCD1._ON gets called has passed * *and* _STA has been called at least 3 times since. */ - ENTRY("SYNA7500", "1", ICPU(INTEL_FAM6_HASWELL_ULT), { + ENTRY("SYNA7500", "1", ICPU(INTEL_FAM6_HASWELL_L), { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7130"), }), - ENTRY("SYNA7500", "1", ICPU(INTEL_FAM6_HASWELL_ULT), { + ENTRY("SYNA7500", "1", ICPU(INTEL_FAM6_HASWELL_L), { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7139"), }), diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 17cb9af25328..6e393aabdc13 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -1875,11 +1875,11 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { ICPU(INTEL_FAM6_BROADWELL, core_funcs), ICPU(INTEL_FAM6_IVYBRIDGE_X, core_funcs), ICPU(INTEL_FAM6_HASWELL_X, core_funcs), - ICPU(INTEL_FAM6_HASWELL_ULT, core_funcs), + ICPU(INTEL_FAM6_HASWELL_L, core_funcs), ICPU(INTEL_FAM6_HASWELL_GT3E, core_funcs), ICPU(INTEL_FAM6_BROADWELL_GT3E, core_funcs), ICPU(INTEL_FAM6_ATOM_AIRMONT, airmont_funcs), - ICPU(INTEL_FAM6_SKYLAKE_MOBILE, core_funcs), + ICPU(INTEL_FAM6_SKYLAKE_L, core_funcs), ICPU(INTEL_FAM6_BROADWELL_X, core_funcs), ICPU(INTEL_FAM6_SKYLAKE, core_funcs), ICPU(INTEL_FAM6_BROADWELL_XEON_D, core_funcs), diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index f45898965fe1..d0e4f16b8f06 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -1074,16 +1074,16 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = { INTEL_CPU_FAM6(IVYBRIDGE_X, idle_cpu_ivt), INTEL_CPU_FAM6(HASWELL, idle_cpu_hsw), INTEL_CPU_FAM6(HASWELL_X, idle_cpu_hsw), - INTEL_CPU_FAM6(HASWELL_ULT, idle_cpu_hsw), + INTEL_CPU_FAM6(HASWELL_L, idle_cpu_hsw), INTEL_CPU_FAM6(HASWELL_GT3E, idle_cpu_hsw), INTEL_CPU_FAM6(ATOM_SILVERMONT_X, idle_cpu_avn), INTEL_CPU_FAM6(BROADWELL, idle_cpu_bdw), INTEL_CPU_FAM6(BROADWELL_GT3E, idle_cpu_bdw), INTEL_CPU_FAM6(BROADWELL_X, idle_cpu_bdw), INTEL_CPU_FAM6(BROADWELL_XEON_D, idle_cpu_bdw), - INTEL_CPU_FAM6(SKYLAKE_MOBILE, idle_cpu_skl), + INTEL_CPU_FAM6(SKYLAKE_L, idle_cpu_skl), INTEL_CPU_FAM6(SKYLAKE, idle_cpu_skl), - INTEL_CPU_FAM6(KABYLAKE_MOBILE, idle_cpu_skl), + INTEL_CPU_FAM6(KABYLAKE_L, idle_cpu_skl), INTEL_CPU_FAM6(KABYLAKE, idle_cpu_skl), INTEL_CPU_FAM6(SKYLAKE_X, idle_cpu_skx), INTEL_CPU_FAM6(XEON_PHI_KNL, idle_cpu_knl), diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c index 3a82df45bced..fd1bfd5d2689 100644 --- a/drivers/platform/x86/intel_pmc_core.c +++ b/drivers/platform/x86/intel_pmc_core.c @@ -806,12 +806,12 @@ static inline void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev) #endif /* CONFIG_DEBUG_FS */ static const struct x86_cpu_id intel_pmc_core_ids[] = { - INTEL_CPU_FAM6(SKYLAKE_MOBILE, spt_reg_map), + INTEL_CPU_FAM6(SKYLAKE_L, spt_reg_map), INTEL_CPU_FAM6(SKYLAKE, spt_reg_map), - INTEL_CPU_FAM6(KABYLAKE_MOBILE, spt_reg_map), + INTEL_CPU_FAM6(KABYLAKE_L, spt_reg_map), INTEL_CPU_FAM6(KABYLAKE, spt_reg_map), - INTEL_CPU_FAM6(CANNONLAKE_MOBILE, cnp_reg_map), - INTEL_CPU_FAM6(ICELAKE_MOBILE, icl_reg_map), + INTEL_CPU_FAM6(CANNONLAKE_L, cnp_reg_map), + INTEL_CPU_FAM6(ICELAKE_L, icl_reg_map), INTEL_CPU_FAM6(ICELAKE_NNPI, icl_reg_map), {} }; diff --git a/drivers/platform/x86/intel_pmc_core_pltdrv.c b/drivers/platform/x86/intel_pmc_core_pltdrv.c index 52f5bcb88011..5977e0d66624 100644 --- a/drivers/platform/x86/intel_pmc_core_pltdrv.c +++ b/drivers/platform/x86/intel_pmc_core_pltdrv.c @@ -30,12 +30,12 @@ static struct platform_device pmc_core_device = { * other list may grow, but this list should not. */ static const struct x86_cpu_id intel_pmc_core_platform_ids[] = { - INTEL_CPU_FAM6(SKYLAKE_MOBILE, pmc_core_device), + INTEL_CPU_FAM6(SKYLAKE_L, pmc_core_device), INTEL_CPU_FAM6(SKYLAKE, pmc_core_device), - INTEL_CPU_FAM6(KABYLAKE_MOBILE, pmc_core_device), + INTEL_CPU_FAM6(KABYLAKE_L, pmc_core_device), INTEL_CPU_FAM6(KABYLAKE, pmc_core_device), - INTEL_CPU_FAM6(CANNONLAKE_MOBILE, pmc_core_device), - INTEL_CPU_FAM6(ICELAKE_MOBILE, pmc_core_device), + INTEL_CPU_FAM6(CANNONLAKE_L, pmc_core_device), + INTEL_CPU_FAM6(ICELAKE_L, pmc_core_device), {} }; MODULE_DEVICE_TABLE(x86cpu, intel_pmc_core_platform_ids); diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c index 7c9eb78d3471..ac52a6ec4931 100644 --- a/drivers/powercap/intel_rapl_common.c +++ b/drivers/powercap/intel_rapl_common.c @@ -958,7 +958,7 @@ static const struct x86_cpu_id rapl_ids[] __initconst = { INTEL_CPU_FAM6(IVYBRIDGE_X, rapl_defaults_core), INTEL_CPU_FAM6(HASWELL, rapl_defaults_core), - INTEL_CPU_FAM6(HASWELL_ULT, rapl_defaults_core), + INTEL_CPU_FAM6(HASWELL_L, rapl_defaults_core), INTEL_CPU_FAM6(HASWELL_GT3E, rapl_defaults_core), INTEL_CPU_FAM6(HASWELL_X, rapl_defaults_hsw_server), @@ -968,12 +968,12 @@ static const struct x86_cpu_id rapl_ids[] __initconst = { INTEL_CPU_FAM6(BROADWELL_X, rapl_defaults_hsw_server), INTEL_CPU_FAM6(SKYLAKE, rapl_defaults_core), - INTEL_CPU_FAM6(SKYLAKE_MOBILE, rapl_defaults_core), + INTEL_CPU_FAM6(SKYLAKE_L, rapl_defaults_core), INTEL_CPU_FAM6(SKYLAKE_X, rapl_defaults_hsw_server), - INTEL_CPU_FAM6(KABYLAKE_MOBILE, rapl_defaults_core), + INTEL_CPU_FAM6(KABYLAKE_L, rapl_defaults_core), INTEL_CPU_FAM6(KABYLAKE, rapl_defaults_core), - INTEL_CPU_FAM6(CANNONLAKE_MOBILE, rapl_defaults_core), - INTEL_CPU_FAM6(ICELAKE_MOBILE, rapl_defaults_core), + INTEL_CPU_FAM6(CANNONLAKE_L, rapl_defaults_core), + INTEL_CPU_FAM6(ICELAKE_L, rapl_defaults_core), INTEL_CPU_FAM6(ICELAKE, rapl_defaults_core), INTEL_CPU_FAM6(ICELAKE_NNPI, rapl_defaults_core), INTEL_CPU_FAM6(ICELAKE_X, rapl_defaults_hsw_server), diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 8083a354ae7f..bb1bef6bf0b9 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -3213,8 +3213,8 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) case INTEL_FAM6_BROADWELL: /* BDW */ case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ case INTEL_FAM6_BROADWELL_X: /* BDX */ - case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ - case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ + case INTEL_FAM6_SKYLAKE_L: /* SKL */ + case INTEL_FAM6_CANNONLAKE_L: /* CNL */ pkg_cstate_limits = hsw_pkg_cstate_limits; has_misc_feature_control = 1; break; @@ -3409,8 +3409,8 @@ int has_config_tdp(unsigned int family, unsigned int model) case INTEL_FAM6_BROADWELL: /* BDW */ case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ case INTEL_FAM6_BROADWELL_X: /* BDX */ - case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ - case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ + case INTEL_FAM6_SKYLAKE_L: /* SKL */ + case INTEL_FAM6_CANNONLAKE_L: /* CNL */ case INTEL_FAM6_SKYLAKE_X: /* SKX */ case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */ @@ -3863,8 +3863,8 @@ void rapl_probe_intel(unsigned int family, unsigned int model) else BIC_PRESENT(BIC_PkgWatt); break; - case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ - case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ + case INTEL_FAM6_SKYLAKE_L: /* SKL */ + case INTEL_FAM6_CANNONLAKE_L: /* CNL */ do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_GFX | RAPL_PKG_POWER_INFO; BIC_PRESENT(BIC_PKG__); BIC_PRESENT(BIC_RAM__); @@ -4255,8 +4255,8 @@ int has_snb_msrs(unsigned int family, unsigned int model) case INTEL_FAM6_BROADWELL: /* BDW */ case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ case INTEL_FAM6_BROADWELL_X: /* BDX */ - case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ - case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ + case INTEL_FAM6_SKYLAKE_L: /* SKL */ + case INTEL_FAM6_CANNONLAKE_L: /* CNL */ case INTEL_FAM6_SKYLAKE_X: /* SKX */ case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ case INTEL_FAM6_ATOM_GOLDMONT_PLUS: @@ -4286,8 +4286,8 @@ int has_hsw_msrs(unsigned int family, unsigned int model) switch (model) { case INTEL_FAM6_HASWELL: case INTEL_FAM6_BROADWELL: /* BDW */ - case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ - case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ + case INTEL_FAM6_SKYLAKE_L: /* SKL */ + case INTEL_FAM6_CANNONLAKE_L: /* CNL */ case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ case INTEL_FAM6_ATOM_GOLDMONT_PLUS: return 1; @@ -4309,8 +4309,8 @@ int has_skl_msrs(unsigned int family, unsigned int model) return 0; switch (model) { - case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ - case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ + case INTEL_FAM6_SKYLAKE_L: /* SKL */ + case INTEL_FAM6_CANNONLAKE_L: /* CNL */ return 1; } return 0; @@ -4345,7 +4345,7 @@ int is_cnl(unsigned int family, unsigned int model) return 0; switch (model) { - case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ + case INTEL_FAM6_CANNONLAKE_L: /* CNL */ return 1; } @@ -4568,21 +4568,21 @@ unsigned int intel_model_duplicates(unsigned int model) case INTEL_FAM6_XEON_PHI_KNM: return INTEL_FAM6_XEON_PHI_KNL; - case INTEL_FAM6_HASWELL_ULT: + case INTEL_FAM6_HASWELL_L: return INTEL_FAM6_HASWELL; case INTEL_FAM6_BROADWELL_X: case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ return INTEL_FAM6_BROADWELL_X; - case INTEL_FAM6_SKYLAKE_MOBILE: + case INTEL_FAM6_SKYLAKE_L: case INTEL_FAM6_SKYLAKE: - case INTEL_FAM6_KABYLAKE_MOBILE: + case INTEL_FAM6_KABYLAKE_L: case INTEL_FAM6_KABYLAKE: - return INTEL_FAM6_SKYLAKE_MOBILE; + return INTEL_FAM6_SKYLAKE_L; - case INTEL_FAM6_ICELAKE_MOBILE: - return INTEL_FAM6_CANNONLAKE_MOBILE; + case INTEL_FAM6_ICELAKE_L: + return INTEL_FAM6_CANNONLAKE_L; } return model; } @@ -4731,7 +4731,7 @@ void process_cpuid() if (crystal_hz == 0) switch(model) { - case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ + case INTEL_FAM6_SKYLAKE_L: /* SKL */ crystal_hz = 24000000; /* 24.0 MHz */ break; case INTEL_FAM6_ATOM_GOLDMONT_X: /* DNV */ -- cgit v1.2.3-59-g8ed1b From 5e741407eab7c602ee5a2b06afb0070a02f4412f Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 27 Aug 2019 21:48:23 +0200 Subject: x86/intel: Aggregate big core graphics naming Currently big core clients with extra graphics on have: - _G - _GT3E Make it uniformly: _G for i in `git grep -l "\(INTEL_FAM6_\|VULNWL_INTEL\|INTEL_CPU_FAM6\).*_GT3E"` do sed -i -e 's/\(\(INTEL_FAM6_\|VULNWL_INTEL\|INTEL_CPU_FAM6\).*\)_GT3E/\1_G/g' ${i} done Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Tony Luck Cc: x86@kernel.org Cc: Dave Hansen Cc: Thomas Gleixner Cc: Borislav Petkov Link: https://lkml.kernel.org/r/20190827195122.622802314@infradead.org --- arch/x86/events/intel/core.c | 8 ++++---- arch/x86/events/intel/cstate.c | 8 ++++---- arch/x86/events/intel/pt.c | 2 +- arch/x86/events/intel/rapl.c | 4 ++-- arch/x86/events/intel/uncore.c | 4 ++-- arch/x86/events/msr.c | 4 ++-- arch/x86/include/asm/intel-family.h | 4 ++-- arch/x86/kernel/apic/apic.c | 4 ++-- arch/x86/kernel/cpu/bugs.c | 4 ++-- arch/x86/kernel/cpu/intel.c | 4 ++-- drivers/cpufreq/intel_pstate.c | 4 ++-- drivers/idle/intel_idle.c | 4 ++-- drivers/powercap/intel_rapl_common.c | 4 ++-- tools/power/x86/turbostat/turbostat.c | 18 +++++++++--------- 14 files changed, 38 insertions(+), 38 deletions(-) (limited to 'tools') diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 22ef9ccaf45c..472b45c3eeb1 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -3966,11 +3966,11 @@ static __init void intel_clovertown_quirk(void) static const struct x86_cpu_desc isolation_ucodes[] = { INTEL_CPU_DESC(INTEL_FAM6_HASWELL, 3, 0x0000001f), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_L, 1, 0x0000001e), - INTEL_CPU_DESC(INTEL_FAM6_HASWELL_GT3E, 1, 0x00000015), + INTEL_CPU_DESC(INTEL_FAM6_HASWELL_G, 1, 0x00000015), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 2, 0x00000037), INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 4, 0x0000000a), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL, 4, 0x00000023), - INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_GT3E, 1, 0x00000014), + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_G, 1, 0x00000014), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 2, 0x00000010), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 3, 0x07000009), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 4, 0x0f000009), @@ -4860,7 +4860,7 @@ __init int intel_pmu_init(void) case INTEL_FAM6_HASWELL: case INTEL_FAM6_HASWELL_X: case INTEL_FAM6_HASWELL_L: - case INTEL_FAM6_HASWELL_GT3E: + case INTEL_FAM6_HASWELL_G: x86_add_quirk(intel_ht_bug); x86_add_quirk(intel_pebs_isolation_quirk); x86_pmu.late_ack = true; @@ -4892,7 +4892,7 @@ __init int intel_pmu_init(void) case INTEL_FAM6_BROADWELL: case INTEL_FAM6_BROADWELL_XEON_D: - case INTEL_FAM6_BROADWELL_GT3E: + case INTEL_FAM6_BROADWELL_G: case INTEL_FAM6_BROADWELL_X: x86_add_quirk(intel_pebs_isolation_quirk); x86_pmu.late_ack = true; diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c index 9b014e813626..03d7a4042bc5 100644 --- a/arch/x86/events/intel/cstate.c +++ b/arch/x86/events/intel/cstate.c @@ -593,9 +593,9 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { X86_CSTATES_MODEL(INTEL_FAM6_IVYBRIDGE, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_IVYBRIDGE_X, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_HASWELL, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_X, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_GT3E, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_HASWELL, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_X, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_G, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_L, hswult_cstates), @@ -605,7 +605,7 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_XEON_D, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_GT3E, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_G, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_X, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_L, snb_cstates), diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index 8cb9626e6277..d0195d151938 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -206,7 +206,7 @@ static int __init pt_pmu_hw_init(void) switch (boot_cpu_data.x86_model) { case INTEL_FAM6_BROADWELL: case INTEL_FAM6_BROADWELL_XEON_D: - case INTEL_FAM6_BROADWELL_GT3E: + case INTEL_FAM6_BROADWELL_G: case INTEL_FAM6_BROADWELL_X: /* not setting BRANCH_EN will #GP, erratum BDM106 */ pt_pmu.branch_en_always_on = true; diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c index 70dcfe9312b0..82e2c0ea99e4 100644 --- a/arch/x86/events/intel/rapl.c +++ b/arch/x86/events/intel/rapl.c @@ -723,9 +723,9 @@ static const struct x86_cpu_id rapl_model_match[] __initconst = { X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_X, model_hsx), X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_L, model_hsw), - X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_GT3E, model_hsw), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_G, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL, model_hsw), - X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_GT3E, model_hsw), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_G, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_X, model_hsx), X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_XEON_D, model_hsx), X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNL, model_knl), diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c index 8428e28c9625..5a2f237707b8 100644 --- a/arch/x86/events/intel/uncore.c +++ b/arch/x86/events/intel/uncore.c @@ -1453,9 +1453,9 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = { X86_UNCORE_MODEL_MATCH(INTEL_FAM6_IVYBRIDGE, ivb_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_HASWELL, hsw_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_HASWELL_L, hsw_uncore_init), - X86_UNCORE_MODEL_MATCH(INTEL_FAM6_HASWELL_GT3E, hsw_uncore_init), + X86_UNCORE_MODEL_MATCH(INTEL_FAM6_HASWELL_G, hsw_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_BROADWELL, bdw_uncore_init), - X86_UNCORE_MODEL_MATCH(INTEL_FAM6_BROADWELL_GT3E, bdw_uncore_init), + X86_UNCORE_MODEL_MATCH(INTEL_FAM6_BROADWELL_G, bdw_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SANDYBRIDGE_X, snbep_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_NEHALEM_EX, nhmex_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_WESTMERE_EX, nhmex_uncore_init), diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c index 12265c14e60d..e11fbdb3a035 100644 --- a/arch/x86/events/msr.c +++ b/arch/x86/events/msr.c @@ -62,11 +62,11 @@ static bool test_intel(int idx, void *data) case INTEL_FAM6_HASWELL: case INTEL_FAM6_HASWELL_X: case INTEL_FAM6_HASWELL_L: - case INTEL_FAM6_HASWELL_GT3E: + case INTEL_FAM6_HASWELL_G: case INTEL_FAM6_BROADWELL: case INTEL_FAM6_BROADWELL_XEON_D: - case INTEL_FAM6_BROADWELL_GT3E: + case INTEL_FAM6_BROADWELL_G: case INTEL_FAM6_BROADWELL_X: case INTEL_FAM6_ATOM_SILVERMONT: diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h index 25b71d4e9224..0bc7f397b4a6 100644 --- a/arch/x86/include/asm/intel-family.h +++ b/arch/x86/include/asm/intel-family.h @@ -52,10 +52,10 @@ #define INTEL_FAM6_HASWELL 0x3C #define INTEL_FAM6_HASWELL_X 0x3F #define INTEL_FAM6_HASWELL_L 0x45 -#define INTEL_FAM6_HASWELL_GT3E 0x46 +#define INTEL_FAM6_HASWELL_G 0x46 #define INTEL_FAM6_BROADWELL 0x3D -#define INTEL_FAM6_BROADWELL_GT3E 0x47 +#define INTEL_FAM6_BROADWELL_G 0x47 #define INTEL_FAM6_BROADWELL_X 0x4F #define INTEL_FAM6_BROADWELL_XEON_D 0x56 diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index adf001d30b47..c297e6d6b915 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -595,10 +595,10 @@ static const struct x86_cpu_id deadline_match[] = { DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL, 0x22), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_L, 0x20), - DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_GT3E, 0x17), + DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_G, 0x17), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL, 0x25), - DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_GT3E, 0x17), + DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_G, 0x17), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE_L, 0xb2), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE, 0xb2), diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index f435780fe45e..0b569f10d4a0 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -1186,9 +1186,9 @@ static void override_cache_bits(struct cpuinfo_x86 *c) case INTEL_FAM6_IVYBRIDGE: case INTEL_FAM6_HASWELL: case INTEL_FAM6_HASWELL_L: - case INTEL_FAM6_HASWELL_GT3E: + case INTEL_FAM6_HASWELL_G: case INTEL_FAM6_BROADWELL: - case INTEL_FAM6_BROADWELL_GT3E: + case INTEL_FAM6_BROADWELL_G: case INTEL_FAM6_SKYLAKE_L: case INTEL_FAM6_SKYLAKE: case INTEL_FAM6_KABYLAKE_L: diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index bafa2735f541..1d2c64bcf6ab 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -150,12 +150,12 @@ static const struct sku_microcode spectre_bad_microcodes[] = { { INTEL_FAM6_SKYLAKE_X, 0x03, 0x0100013e }, { INTEL_FAM6_SKYLAKE_X, 0x04, 0x0200003c }, { INTEL_FAM6_BROADWELL, 0x04, 0x28 }, - { INTEL_FAM6_BROADWELL_GT3E, 0x01, 0x1b }, + { INTEL_FAM6_BROADWELL_G, 0x01, 0x1b }, { INTEL_FAM6_BROADWELL_XEON_D, 0x02, 0x14 }, { INTEL_FAM6_BROADWELL_XEON_D, 0x03, 0x07000011 }, { INTEL_FAM6_BROADWELL_X, 0x01, 0x0b000025 }, { INTEL_FAM6_HASWELL_L, 0x01, 0x21 }, - { INTEL_FAM6_HASWELL_GT3E, 0x01, 0x18 }, + { INTEL_FAM6_HASWELL_G, 0x01, 0x18 }, { INTEL_FAM6_HASWELL, 0x03, 0x23 }, { INTEL_FAM6_HASWELL_X, 0x02, 0x3b }, { INTEL_FAM6_HASWELL_X, 0x04, 0x10 }, diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 6e393aabdc13..99b9c01f8c1a 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -1876,8 +1876,8 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { ICPU(INTEL_FAM6_IVYBRIDGE_X, core_funcs), ICPU(INTEL_FAM6_HASWELL_X, core_funcs), ICPU(INTEL_FAM6_HASWELL_L, core_funcs), - ICPU(INTEL_FAM6_HASWELL_GT3E, core_funcs), - ICPU(INTEL_FAM6_BROADWELL_GT3E, core_funcs), + ICPU(INTEL_FAM6_HASWELL_G, core_funcs), + ICPU(INTEL_FAM6_BROADWELL_G, core_funcs), ICPU(INTEL_FAM6_ATOM_AIRMONT, airmont_funcs), ICPU(INTEL_FAM6_SKYLAKE_L, core_funcs), ICPU(INTEL_FAM6_BROADWELL_X, core_funcs), diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index d0e4f16b8f06..c4081324a02b 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -1075,10 +1075,10 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = { INTEL_CPU_FAM6(HASWELL, idle_cpu_hsw), INTEL_CPU_FAM6(HASWELL_X, idle_cpu_hsw), INTEL_CPU_FAM6(HASWELL_L, idle_cpu_hsw), - INTEL_CPU_FAM6(HASWELL_GT3E, idle_cpu_hsw), + INTEL_CPU_FAM6(HASWELL_G, idle_cpu_hsw), INTEL_CPU_FAM6(ATOM_SILVERMONT_X, idle_cpu_avn), INTEL_CPU_FAM6(BROADWELL, idle_cpu_bdw), - INTEL_CPU_FAM6(BROADWELL_GT3E, idle_cpu_bdw), + INTEL_CPU_FAM6(BROADWELL_G, idle_cpu_bdw), INTEL_CPU_FAM6(BROADWELL_X, idle_cpu_bdw), INTEL_CPU_FAM6(BROADWELL_XEON_D, idle_cpu_bdw), INTEL_CPU_FAM6(SKYLAKE_L, idle_cpu_skl), diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c index ac52a6ec4931..07af068f6ab6 100644 --- a/drivers/powercap/intel_rapl_common.c +++ b/drivers/powercap/intel_rapl_common.c @@ -959,11 +959,11 @@ static const struct x86_cpu_id rapl_ids[] __initconst = { INTEL_CPU_FAM6(HASWELL, rapl_defaults_core), INTEL_CPU_FAM6(HASWELL_L, rapl_defaults_core), - INTEL_CPU_FAM6(HASWELL_GT3E, rapl_defaults_core), + INTEL_CPU_FAM6(HASWELL_G, rapl_defaults_core), INTEL_CPU_FAM6(HASWELL_X, rapl_defaults_hsw_server), INTEL_CPU_FAM6(BROADWELL, rapl_defaults_core), - INTEL_CPU_FAM6(BROADWELL_GT3E, rapl_defaults_core), + INTEL_CPU_FAM6(BROADWELL_G, rapl_defaults_core), INTEL_CPU_FAM6(BROADWELL_XEON_D, rapl_defaults_core), INTEL_CPU_FAM6(BROADWELL_X, rapl_defaults_hsw_server), diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index bb1bef6bf0b9..271cf18efbab 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -3209,9 +3209,9 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) break; case INTEL_FAM6_HASWELL: /* HSW */ case INTEL_FAM6_HASWELL_X: /* HSX */ - case INTEL_FAM6_HASWELL_GT3E: /* HSW */ + case INTEL_FAM6_HASWELL_G: /* HSW */ case INTEL_FAM6_BROADWELL: /* BDW */ - case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ + case INTEL_FAM6_BROADWELL_G: /* BDW */ case INTEL_FAM6_BROADWELL_X: /* BDX */ case INTEL_FAM6_SKYLAKE_L: /* SKL */ case INTEL_FAM6_CANNONLAKE_L: /* CNL */ @@ -3405,9 +3405,9 @@ int has_config_tdp(unsigned int family, unsigned int model) case INTEL_FAM6_IVYBRIDGE: /* IVB */ case INTEL_FAM6_HASWELL: /* HSW */ case INTEL_FAM6_HASWELL_X: /* HSX */ - case INTEL_FAM6_HASWELL_GT3E: /* HSW */ + case INTEL_FAM6_HASWELL_G: /* HSW */ case INTEL_FAM6_BROADWELL: /* BDW */ - case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ + case INTEL_FAM6_BROADWELL_G: /* BDW */ case INTEL_FAM6_BROADWELL_X: /* BDX */ case INTEL_FAM6_SKYLAKE_L: /* SKL */ case INTEL_FAM6_CANNONLAKE_L: /* CNL */ @@ -3841,9 +3841,9 @@ void rapl_probe_intel(unsigned int family, unsigned int model) case INTEL_FAM6_SANDYBRIDGE: case INTEL_FAM6_IVYBRIDGE: case INTEL_FAM6_HASWELL: /* HSW */ - case INTEL_FAM6_HASWELL_GT3E: /* HSW */ + case INTEL_FAM6_HASWELL_G: /* HSW */ case INTEL_FAM6_BROADWELL: /* BDW */ - case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ + case INTEL_FAM6_BROADWELL_G: /* BDW */ do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO; if (rapl_joules) { BIC_PRESENT(BIC_Pkg_J); @@ -4032,7 +4032,7 @@ void perf_limit_reasons_probe(unsigned int family, unsigned int model) switch (model) { case INTEL_FAM6_HASWELL: /* HSW */ - case INTEL_FAM6_HASWELL_GT3E: /* HSW */ + case INTEL_FAM6_HASWELL_G: /* HSW */ do_gfx_perf_limit_reasons = 1; case INTEL_FAM6_HASWELL_X: /* HSX */ do_core_perf_limit_reasons = 1; @@ -4251,9 +4251,9 @@ int has_snb_msrs(unsigned int family, unsigned int model) case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */ case INTEL_FAM6_HASWELL: /* HSW */ case INTEL_FAM6_HASWELL_X: /* HSW */ - case INTEL_FAM6_HASWELL_GT3E: /* HSW */ + case INTEL_FAM6_HASWELL_G: /* HSW */ case INTEL_FAM6_BROADWELL: /* BDW */ - case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ + case INTEL_FAM6_BROADWELL_G: /* BDW */ case INTEL_FAM6_BROADWELL_X: /* BDX */ case INTEL_FAM6_SKYLAKE_L: /* SKL */ case INTEL_FAM6_CANNONLAKE_L: /* CNL */ -- cgit v1.2.3-59-g8ed1b From 5ebb34edbefa8ea6a7e109179d5fc7b3529dbeba Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 27 Aug 2019 21:48:24 +0200 Subject: x86/intel: Aggregate microserver naming Currently big microservers have _XEON_D while small microservers have _X, Make it uniformly: _D. for i in `git grep -l "\(INTEL_FAM6_\|VULNWL_INTEL\|INTEL_CPU_FAM6\).*_\(X\|XEON_D\)"` do sed -i -e 's/\(\(INTEL_FAM6_\|VULNWL_INTEL\|INTEL_CPU_FAM6\).*ATOM.*\)_X/\1_D/g' \ -e 's/\(\(INTEL_FAM6_\|VULNWL_INTEL\|INTEL_CPU_FAM6\).*\)_XEON_D/\1_D/g' ${i} done Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Tony Luck Cc: x86@kernel.org Cc: Dave Hansen Cc: Thomas Gleixner Cc: Borislav Petkov Link: https://lkml.kernel.org/r/20190827195122.677152989@infradead.org --- arch/x86/events/intel/core.c | 20 ++++++++++---------- arch/x86/events/intel/cstate.c | 12 ++++++------ arch/x86/events/intel/pt.c | 2 +- arch/x86/events/intel/rapl.c | 4 ++-- arch/x86/events/intel/uncore.c | 4 ++-- arch/x86/events/msr.c | 6 +++--- arch/x86/include/asm/intel-family.h | 10 +++++----- arch/x86/kernel/apic/apic.c | 2 +- arch/x86/kernel/cpu/common.c | 4 ++-- arch/x86/kernel/cpu/intel.c | 4 ++-- arch/x86/kernel/cpu/mce/intel.c | 2 +- arch/x86/kernel/tsc.c | 2 +- drivers/cpufreq/intel_pstate.c | 6 +++--- drivers/edac/i10nm_base.c | 4 ++-- drivers/edac/pnd2_edac.c | 2 +- drivers/edac/sb_edac.c | 2 +- drivers/idle/intel_idle.c | 8 ++++---- drivers/powercap/intel_rapl_common.c | 8 ++++---- tools/power/x86/turbostat/turbostat.c | 22 +++++++++++----------- 19 files changed, 62 insertions(+), 62 deletions(-) (limited to 'tools') diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 472b45c3eeb1..dce329c5725d 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -3971,10 +3971,10 @@ static const struct x86_cpu_desc isolation_ucodes[] = { INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 4, 0x0000000a), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL, 4, 0x00000023), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_G, 1, 0x00000014), - INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 2, 0x00000010), - INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 3, 0x07000009), - INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 4, 0x0f000009), - INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 5, 0x0e000002), + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 2, 0x00000010), + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 3, 0x07000009), + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 4, 0x0f000009), + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 5, 0x0e000002), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_X, 2, 0x0b000014), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 3, 0x00000021), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 4, 0x00000000), @@ -4146,7 +4146,7 @@ static const struct x86_cpu_desc counter_freezing_ucodes[] = { INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT, 2, 0x0000000e), INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT, 9, 0x0000002e), INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT, 10, 0x00000008), - INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT_X, 1, 0x00000028), + INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT_D, 1, 0x00000028), INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT_PLUS, 1, 0x00000028), INTEL_CPU_DESC(INTEL_FAM6_ATOM_GOLDMONT_PLUS, 8, 0x00000006), {} @@ -4643,7 +4643,7 @@ __init int intel_pmu_init(void) break; case INTEL_FAM6_ATOM_SILVERMONT: - case INTEL_FAM6_ATOM_SILVERMONT_X: + case INTEL_FAM6_ATOM_SILVERMONT_D: case INTEL_FAM6_ATOM_SILVERMONT_MID: case INTEL_FAM6_ATOM_AIRMONT: case INTEL_FAM6_ATOM_AIRMONT_MID: @@ -4665,7 +4665,7 @@ __init int intel_pmu_init(void) break; case INTEL_FAM6_ATOM_GOLDMONT: - case INTEL_FAM6_ATOM_GOLDMONT_X: + case INTEL_FAM6_ATOM_GOLDMONT_D: x86_add_quirk(intel_counter_freezing_quirk); memcpy(hw_cache_event_ids, glm_hw_cache_event_ids, sizeof(hw_cache_event_ids)); @@ -4721,7 +4721,7 @@ __init int intel_pmu_init(void) name = "goldmont_plus"; break; - case INTEL_FAM6_ATOM_TREMONT_X: + case INTEL_FAM6_ATOM_TREMONT_D: x86_pmu.late_ack = true; memcpy(hw_cache_event_ids, glp_hw_cache_event_ids, sizeof(hw_cache_event_ids)); @@ -4891,7 +4891,7 @@ __init int intel_pmu_init(void) break; case INTEL_FAM6_BROADWELL: - case INTEL_FAM6_BROADWELL_XEON_D: + case INTEL_FAM6_BROADWELL_D: case INTEL_FAM6_BROADWELL_G: case INTEL_FAM6_BROADWELL_X: x86_add_quirk(intel_pebs_isolation_quirk); @@ -5002,7 +5002,7 @@ __init int intel_pmu_init(void) break; case INTEL_FAM6_ICELAKE_X: - case INTEL_FAM6_ICELAKE_XEON_D: + case INTEL_FAM6_ICELAKE_D: pmem = true; /* fall through */ case INTEL_FAM6_ICELAKE_L: diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c index 03d7a4042bc5..104c093b282b 100644 --- a/arch/x86/events/intel/cstate.c +++ b/arch/x86/events/intel/cstate.c @@ -600,13 +600,13 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { X86_CSTATES_MODEL(INTEL_FAM6_HASWELL_L, hswult_cstates), X86_CSTATES_MODEL(INTEL_FAM6_ATOM_SILVERMONT, slm_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_ATOM_SILVERMONT_X, slm_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_SILVERMONT_D, slm_cstates), X86_CSTATES_MODEL(INTEL_FAM6_ATOM_AIRMONT, slm_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_XEON_D, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_G, snb_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_X, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_D, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_G, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_BROADWELL_X, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_L, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE, snb_cstates), @@ -621,7 +621,7 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { X86_CSTATES_MODEL(INTEL_FAM6_XEON_PHI_KNM, knl_cstates), X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT, glm_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_X, glm_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_D, glm_cstates), X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_PLUS, glm_cstates), diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index d0195d151938..26af1f19f153 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -205,7 +205,7 @@ static int __init pt_pmu_hw_init(void) /* model-specific quirks */ switch (boot_cpu_data.x86_model) { case INTEL_FAM6_BROADWELL: - case INTEL_FAM6_BROADWELL_XEON_D: + case INTEL_FAM6_BROADWELL_D: case INTEL_FAM6_BROADWELL_G: case INTEL_FAM6_BROADWELL_X: /* not setting BRANCH_EN will #GP, erratum BDM106 */ diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c index 82e2c0ea99e4..22f5843ef406 100644 --- a/arch/x86/events/intel/rapl.c +++ b/arch/x86/events/intel/rapl.c @@ -727,7 +727,7 @@ static const struct x86_cpu_id rapl_model_match[] __initconst = { X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_G, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_X, model_hsx), - X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_XEON_D, model_hsx), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_D, model_hsx), X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNL, model_knl), X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNM, model_knl), X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_L, model_skl), @@ -737,7 +737,7 @@ static const struct x86_cpu_id rapl_model_match[] __initconst = { X86_RAPL_MODEL_MATCH(INTEL_FAM6_KABYLAKE, model_skl), X86_RAPL_MODEL_MATCH(INTEL_FAM6_CANNONLAKE_L, model_skl), X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT, model_hsw), - X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT_X, model_hsw), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT_D, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT_PLUS, model_hsw), X86_RAPL_MODEL_MATCH(INTEL_FAM6_ICELAKE_L, model_skl), X86_RAPL_MODEL_MATCH(INTEL_FAM6_ICELAKE, model_skl), diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c index 5a2f237707b8..6fc2e06ab4c6 100644 --- a/arch/x86/events/intel/uncore.c +++ b/arch/x86/events/intel/uncore.c @@ -1462,7 +1462,7 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = { X86_UNCORE_MODEL_MATCH(INTEL_FAM6_IVYBRIDGE_X, ivbep_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_HASWELL_X, hswep_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_BROADWELL_X, bdx_uncore_init), - X86_UNCORE_MODEL_MATCH(INTEL_FAM6_BROADWELL_XEON_D, bdx_uncore_init), + X86_UNCORE_MODEL_MATCH(INTEL_FAM6_BROADWELL_D, bdx_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNL, knl_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNM, knl_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE, skl_uncore_init), @@ -1473,7 +1473,7 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = { X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_L, icl_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_NNPI, icl_uncore_init), X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE, icl_uncore_init), - X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ATOM_TREMONT_X, snr_uncore_init), + X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ATOM_TREMONT_D, snr_uncore_init), {}, }; diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c index e11fbdb3a035..ab79d3100241 100644 --- a/arch/x86/events/msr.c +++ b/arch/x86/events/msr.c @@ -65,16 +65,16 @@ static bool test_intel(int idx, void *data) case INTEL_FAM6_HASWELL_G: case INTEL_FAM6_BROADWELL: - case INTEL_FAM6_BROADWELL_XEON_D: + case INTEL_FAM6_BROADWELL_D: case INTEL_FAM6_BROADWELL_G: case INTEL_FAM6_BROADWELL_X: case INTEL_FAM6_ATOM_SILVERMONT: - case INTEL_FAM6_ATOM_SILVERMONT_X: + case INTEL_FAM6_ATOM_SILVERMONT_D: case INTEL_FAM6_ATOM_AIRMONT: case INTEL_FAM6_ATOM_GOLDMONT: - case INTEL_FAM6_ATOM_GOLDMONT_X: + case INTEL_FAM6_ATOM_GOLDMONT_D: case INTEL_FAM6_ATOM_GOLDMONT_PLUS: diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h index 0bc7f397b4a6..76dc9abb53e9 100644 --- a/arch/x86/include/asm/intel-family.h +++ b/arch/x86/include/asm/intel-family.h @@ -57,7 +57,7 @@ #define INTEL_FAM6_BROADWELL 0x3D #define INTEL_FAM6_BROADWELL_G 0x47 #define INTEL_FAM6_BROADWELL_X 0x4F -#define INTEL_FAM6_BROADWELL_XEON_D 0x56 +#define INTEL_FAM6_BROADWELL_D 0x56 #define INTEL_FAM6_SKYLAKE_L 0x4E #define INTEL_FAM6_SKYLAKE 0x5E @@ -68,7 +68,7 @@ #define INTEL_FAM6_CANNONLAKE_L 0x66 #define INTEL_FAM6_ICELAKE_X 0x6A -#define INTEL_FAM6_ICELAKE_XEON_D 0x6C +#define INTEL_FAM6_ICELAKE_D 0x6C #define INTEL_FAM6_ICELAKE 0x7D #define INTEL_FAM6_ICELAKE_L 0x7E #define INTEL_FAM6_ICELAKE_NNPI 0x9D @@ -83,17 +83,17 @@ #define INTEL_FAM6_ATOM_SALTWELL_TABLET 0x35 /* Cloverview */ #define INTEL_FAM6_ATOM_SILVERMONT 0x37 /* Bay Trail, Valleyview */ -#define INTEL_FAM6_ATOM_SILVERMONT_X 0x4D /* Avaton, Rangely */ +#define INTEL_FAM6_ATOM_SILVERMONT_D 0x4D /* Avaton, Rangely */ #define INTEL_FAM6_ATOM_SILVERMONT_MID 0x4A /* Merriefield */ #define INTEL_FAM6_ATOM_AIRMONT 0x4C /* Cherry Trail, Braswell */ #define INTEL_FAM6_ATOM_AIRMONT_MID 0x5A /* Moorefield */ #define INTEL_FAM6_ATOM_GOLDMONT 0x5C /* Apollo Lake */ -#define INTEL_FAM6_ATOM_GOLDMONT_X 0x5F /* Denverton */ +#define INTEL_FAM6_ATOM_GOLDMONT_D 0x5F /* Denverton */ #define INTEL_FAM6_ATOM_GOLDMONT_PLUS 0x7A /* Gemini Lake */ -#define INTEL_FAM6_ATOM_TREMONT_X 0x86 /* Jacobsville */ +#define INTEL_FAM6_ATOM_TREMONT_D 0x86 /* Jacobsville */ /* Xeon Phi */ diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index c297e6d6b915..1026138eb830 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -590,7 +590,7 @@ static u32 skx_deadline_rev(void) static const struct x86_cpu_id deadline_match[] = { DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_HASWELL_X, hsx_deadline_rev), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_X, 0x0b000020), - DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_BROADWELL_XEON_D, bdx_deadline_rev), + DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_BROADWELL_D, bdx_deadline_rev), DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_SKYLAKE_X, skx_deadline_rev), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL, 0x22), diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index f125bf7ecb6f..b6a9e27755d7 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1050,7 +1050,7 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { VULNWL_INTEL(ATOM_BONNELL_MID, NO_SPECULATION), VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), - VULNWL_INTEL(ATOM_SILVERMONT_X, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), + VULNWL_INTEL(ATOM_SILVERMONT_D, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), @@ -1061,7 +1061,7 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS), VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS), - VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF | NO_SWAPGS), + VULNWL_INTEL(ATOM_GOLDMONT_D, NO_MDS | NO_L1TF | NO_SWAPGS), VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS), /* diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 1d2c64bcf6ab..f4b795ab1a9b 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -151,8 +151,8 @@ static const struct sku_microcode spectre_bad_microcodes[] = { { INTEL_FAM6_SKYLAKE_X, 0x04, 0x0200003c }, { INTEL_FAM6_BROADWELL, 0x04, 0x28 }, { INTEL_FAM6_BROADWELL_G, 0x01, 0x1b }, - { INTEL_FAM6_BROADWELL_XEON_D, 0x02, 0x14 }, - { INTEL_FAM6_BROADWELL_XEON_D, 0x03, 0x07000011 }, + { INTEL_FAM6_BROADWELL_D, 0x02, 0x14 }, + { INTEL_FAM6_BROADWELL_D, 0x03, 0x07000011 }, { INTEL_FAM6_BROADWELL_X, 0x01, 0x0b000025 }, { INTEL_FAM6_HASWELL_L, 0x01, 0x21 }, { INTEL_FAM6_HASWELL_G, 0x01, 0x18 }, diff --git a/arch/x86/kernel/cpu/mce/intel.c b/arch/x86/kernel/cpu/mce/intel.c index e43eb6732630..88cd9598fa57 100644 --- a/arch/x86/kernel/cpu/mce/intel.c +++ b/arch/x86/kernel/cpu/mce/intel.c @@ -479,7 +479,7 @@ static void intel_ppin_init(struct cpuinfo_x86 *c) switch (c->x86_model) { case INTEL_FAM6_IVYBRIDGE_X: case INTEL_FAM6_HASWELL_X: - case INTEL_FAM6_BROADWELL_XEON_D: + case INTEL_FAM6_BROADWELL_D: case INTEL_FAM6_BROADWELL_X: case INTEL_FAM6_SKYLAKE_X: case INTEL_FAM6_XEON_PHI_KNL: diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 57d87f79558f..c59454c382fd 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -638,7 +638,7 @@ unsigned long native_calibrate_tsc(void) * clock. */ if (crystal_khz == 0 && - boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT_X) + boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT_D) crystal_khz = 25000; /* diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 99b9c01f8c1a..886324041add 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -1882,7 +1882,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { ICPU(INTEL_FAM6_SKYLAKE_L, core_funcs), ICPU(INTEL_FAM6_BROADWELL_X, core_funcs), ICPU(INTEL_FAM6_SKYLAKE, core_funcs), - ICPU(INTEL_FAM6_BROADWELL_XEON_D, core_funcs), + ICPU(INTEL_FAM6_BROADWELL_D, core_funcs), ICPU(INTEL_FAM6_XEON_PHI_KNL, knl_funcs), ICPU(INTEL_FAM6_XEON_PHI_KNM, knl_funcs), ICPU(INTEL_FAM6_ATOM_GOLDMONT, core_funcs), @@ -1893,7 +1893,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); static const struct x86_cpu_id intel_pstate_cpu_oob_ids[] __initconst = { - ICPU(INTEL_FAM6_BROADWELL_XEON_D, core_funcs), + ICPU(INTEL_FAM6_BROADWELL_D, core_funcs), ICPU(INTEL_FAM6_BROADWELL_X, core_funcs), ICPU(INTEL_FAM6_SKYLAKE_X, core_funcs), {} @@ -2624,7 +2624,7 @@ static inline void intel_pstate_request_control_from_smm(void) {} static const struct x86_cpu_id hwp_support_ids[] __initconst = { ICPU_HWP(INTEL_FAM6_BROADWELL_X, INTEL_PSTATE_HWP_BROADWELL), - ICPU_HWP(INTEL_FAM6_BROADWELL_XEON_D, INTEL_PSTATE_HWP_BROADWELL), + ICPU_HWP(INTEL_FAM6_BROADWELL_D, INTEL_PSTATE_HWP_BROADWELL), ICPU_HWP(X86_MODEL_ANY, 0), {} }; diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c index 83392f2841de..c370d5457e6b 100644 --- a/drivers/edac/i10nm_base.c +++ b/drivers/edac/i10nm_base.c @@ -123,9 +123,9 @@ static int i10nm_get_all_munits(void) } static const struct x86_cpu_id i10nm_cpuids[] = { - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_TREMONT_X, 0, 0 }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_TREMONT_D, 0, 0 }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_X, 0, 0 }, - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_XEON_D, 0, 0 }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_D, 0, 0 }, { } }; MODULE_DEVICE_TABLE(x86cpu, i10nm_cpuids); diff --git a/drivers/edac/pnd2_edac.c b/drivers/edac/pnd2_edac.c index ca25f8fe57ef..a6846be0d2eb 100644 --- a/drivers/edac/pnd2_edac.c +++ b/drivers/edac/pnd2_edac.c @@ -1533,7 +1533,7 @@ static struct dunit_ops dnv_ops = { static const struct x86_cpu_id pnd2_cpuids[] = { { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_GOLDMONT, 0, (kernel_ulong_t)&apl_ops }, - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_GOLDMONT_X, 0, (kernel_ulong_t)&dnv_ops }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_GOLDMONT_D, 0, (kernel_ulong_t)&dnv_ops }, { } }; MODULE_DEVICE_TABLE(x86cpu, pnd2_cpuids); diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index 37746b045e18..f743502ca9b7 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -3429,7 +3429,7 @@ static const struct x86_cpu_id sbridge_cpuids[] = { INTEL_CPU_FAM6(IVYBRIDGE_X, pci_dev_descr_ibridge_table), INTEL_CPU_FAM6(HASWELL_X, pci_dev_descr_haswell_table), INTEL_CPU_FAM6(BROADWELL_X, pci_dev_descr_broadwell_table), - INTEL_CPU_FAM6(BROADWELL_XEON_D, pci_dev_descr_broadwell_table), + INTEL_CPU_FAM6(BROADWELL_D, pci_dev_descr_broadwell_table), INTEL_CPU_FAM6(XEON_PHI_KNL, pci_dev_descr_knl_table), INTEL_CPU_FAM6(XEON_PHI_KNM, pci_dev_descr_knl_table), { } diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index c4081324a02b..347b08b56042 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -1076,11 +1076,11 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = { INTEL_CPU_FAM6(HASWELL_X, idle_cpu_hsw), INTEL_CPU_FAM6(HASWELL_L, idle_cpu_hsw), INTEL_CPU_FAM6(HASWELL_G, idle_cpu_hsw), - INTEL_CPU_FAM6(ATOM_SILVERMONT_X, idle_cpu_avn), + INTEL_CPU_FAM6(ATOM_SILVERMONT_D, idle_cpu_avn), INTEL_CPU_FAM6(BROADWELL, idle_cpu_bdw), INTEL_CPU_FAM6(BROADWELL_G, idle_cpu_bdw), INTEL_CPU_FAM6(BROADWELL_X, idle_cpu_bdw), - INTEL_CPU_FAM6(BROADWELL_XEON_D, idle_cpu_bdw), + INTEL_CPU_FAM6(BROADWELL_D, idle_cpu_bdw), INTEL_CPU_FAM6(SKYLAKE_L, idle_cpu_skl), INTEL_CPU_FAM6(SKYLAKE, idle_cpu_skl), INTEL_CPU_FAM6(KABYLAKE_L, idle_cpu_skl), @@ -1090,8 +1090,8 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = { INTEL_CPU_FAM6(XEON_PHI_KNM, idle_cpu_knl), INTEL_CPU_FAM6(ATOM_GOLDMONT, idle_cpu_bxt), INTEL_CPU_FAM6(ATOM_GOLDMONT_PLUS, idle_cpu_bxt), - INTEL_CPU_FAM6(ATOM_GOLDMONT_X, idle_cpu_dnv), - INTEL_CPU_FAM6(ATOM_TREMONT_X, idle_cpu_dnv), + INTEL_CPU_FAM6(ATOM_GOLDMONT_D, idle_cpu_dnv), + INTEL_CPU_FAM6(ATOM_TREMONT_D, idle_cpu_dnv), {} }; diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c index 07af068f6ab6..94ddd7d659c8 100644 --- a/drivers/powercap/intel_rapl_common.c +++ b/drivers/powercap/intel_rapl_common.c @@ -964,7 +964,7 @@ static const struct x86_cpu_id rapl_ids[] __initconst = { INTEL_CPU_FAM6(BROADWELL, rapl_defaults_core), INTEL_CPU_FAM6(BROADWELL_G, rapl_defaults_core), - INTEL_CPU_FAM6(BROADWELL_XEON_D, rapl_defaults_core), + INTEL_CPU_FAM6(BROADWELL_D, rapl_defaults_core), INTEL_CPU_FAM6(BROADWELL_X, rapl_defaults_hsw_server), INTEL_CPU_FAM6(SKYLAKE, rapl_defaults_core), @@ -977,7 +977,7 @@ static const struct x86_cpu_id rapl_ids[] __initconst = { INTEL_CPU_FAM6(ICELAKE, rapl_defaults_core), INTEL_CPU_FAM6(ICELAKE_NNPI, rapl_defaults_core), INTEL_CPU_FAM6(ICELAKE_X, rapl_defaults_hsw_server), - INTEL_CPU_FAM6(ICELAKE_XEON_D, rapl_defaults_hsw_server), + INTEL_CPU_FAM6(ICELAKE_D, rapl_defaults_hsw_server), INTEL_CPU_FAM6(ATOM_SILVERMONT, rapl_defaults_byt), INTEL_CPU_FAM6(ATOM_AIRMONT, rapl_defaults_cht), @@ -985,8 +985,8 @@ static const struct x86_cpu_id rapl_ids[] __initconst = { INTEL_CPU_FAM6(ATOM_AIRMONT_MID, rapl_defaults_ann), INTEL_CPU_FAM6(ATOM_GOLDMONT, rapl_defaults_core), INTEL_CPU_FAM6(ATOM_GOLDMONT_PLUS, rapl_defaults_core), - INTEL_CPU_FAM6(ATOM_GOLDMONT_X, rapl_defaults_core), - INTEL_CPU_FAM6(ATOM_TREMONT_X, rapl_defaults_core), + INTEL_CPU_FAM6(ATOM_GOLDMONT_D, rapl_defaults_core), + INTEL_CPU_FAM6(ATOM_TREMONT_D, rapl_defaults_core), INTEL_CPU_FAM6(XEON_PHI_KNL, rapl_defaults_hsw_server), INTEL_CPU_FAM6(XEON_PHI_KNM, rapl_defaults_hsw_server), diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 271cf18efbab..6eef0cee6d75 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -2150,7 +2150,7 @@ int has_turbo_ratio_group_limits(int family, int model) switch (model) { case INTEL_FAM6_ATOM_GOLDMONT: case INTEL_FAM6_SKYLAKE_X: - case INTEL_FAM6_ATOM_GOLDMONT_X: + case INTEL_FAM6_ATOM_GOLDMONT_D: return 1; } return 0; @@ -3224,7 +3224,7 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) break; case INTEL_FAM6_ATOM_SILVERMONT: /* BYT */ no_MSR_MISC_PWR_MGMT = 1; - case INTEL_FAM6_ATOM_SILVERMONT_X: /* AVN */ + case INTEL_FAM6_ATOM_SILVERMONT_D: /* AVN */ pkg_cstate_limits = slv_pkg_cstate_limits; break; case INTEL_FAM6_ATOM_AIRMONT: /* AMT */ @@ -3236,7 +3236,7 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) break; case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ case INTEL_FAM6_ATOM_GOLDMONT_PLUS: - case INTEL_FAM6_ATOM_GOLDMONT_X: /* DNV */ + case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ pkg_cstate_limits = glm_pkg_cstate_limits; break; default: @@ -3279,7 +3279,7 @@ int is_dnv(unsigned int family, unsigned int model) return 0; switch (model) { - case INTEL_FAM6_ATOM_GOLDMONT_X: + case INTEL_FAM6_ATOM_GOLDMONT_D: return 1; } return 0; @@ -3792,7 +3792,7 @@ double get_tdp_intel(unsigned int model) switch (model) { case INTEL_FAM6_ATOM_SILVERMONT: - case INTEL_FAM6_ATOM_SILVERMONT_X: + case INTEL_FAM6_ATOM_SILVERMONT_D: return 30.0; default: return 135.0; @@ -3911,7 +3911,7 @@ void rapl_probe_intel(unsigned int family, unsigned int model) } break; case INTEL_FAM6_ATOM_SILVERMONT: /* BYT */ - case INTEL_FAM6_ATOM_SILVERMONT_X: /* AVN */ + case INTEL_FAM6_ATOM_SILVERMONT_D: /* AVN */ do_rapl = RAPL_PKG | RAPL_CORES; if (rapl_joules) { BIC_PRESENT(BIC_Pkg_J); @@ -3921,7 +3921,7 @@ void rapl_probe_intel(unsigned int family, unsigned int model) BIC_PRESENT(BIC_CorWatt); } break; - case INTEL_FAM6_ATOM_GOLDMONT_X: /* DNV */ + case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO | RAPL_CORES_ENERGY_STATUS; BIC_PRESENT(BIC_PKG__); BIC_PRESENT(BIC_RAM__); @@ -4260,7 +4260,7 @@ int has_snb_msrs(unsigned int family, unsigned int model) case INTEL_FAM6_SKYLAKE_X: /* SKX */ case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ case INTEL_FAM6_ATOM_GOLDMONT_PLUS: - case INTEL_FAM6_ATOM_GOLDMONT_X: /* DNV */ + case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ return 1; } return 0; @@ -4322,7 +4322,7 @@ int is_slm(unsigned int family, unsigned int model) return 0; switch (model) { case INTEL_FAM6_ATOM_SILVERMONT: /* BYT */ - case INTEL_FAM6_ATOM_SILVERMONT_X: /* AVN */ + case INTEL_FAM6_ATOM_SILVERMONT_D: /* AVN */ return 1; } return 0; @@ -4572,7 +4572,7 @@ unsigned int intel_model_duplicates(unsigned int model) return INTEL_FAM6_HASWELL; case INTEL_FAM6_BROADWELL_X: - case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ + case INTEL_FAM6_BROADWELL_D: /* BDX-DE */ return INTEL_FAM6_BROADWELL_X; case INTEL_FAM6_SKYLAKE_L: @@ -4734,7 +4734,7 @@ void process_cpuid() case INTEL_FAM6_SKYLAKE_L: /* SKL */ crystal_hz = 24000000; /* 24.0 MHz */ break; - case INTEL_FAM6_ATOM_GOLDMONT_X: /* DNV */ + case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ crystal_hz = 25000000; /* 25.0 MHz */ break; case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ -- cgit v1.2.3-59-g8ed1b From 0a56e0603fa13af08816d673f6f71b68cda2fb2e Mon Sep 17 00:00:00 2001 From: "Naveen N. Rao" Date: Tue, 27 Aug 2019 12:44:58 +0530 Subject: perf arch powerpc: Sync powerpc syscall.tbl Copy over powerpc syscall.tbl to grab changes from the below commits: commit cee3536d24a1 ("powerpc: Wire up clone3 syscall") commit 1a271a68e030 ("arch: mark syscall number 435 reserved for clone3") commit 7615d9e1780e ("arch: wire-up pidfd_open()") commit d8076bdb56af ("uapi: Wire up the mount API syscalls on non-x86 arches [ver #2]") commit 39036cd27273 ("arch: add pidfd and io_uring syscalls everywhere") commit 48166e6ea47d ("y2038: add 64-bit time_t syscalls to all 32-bit architectures") commit d33c577cccd0 ("y2038: rename old time and utime syscalls") commit 00bf25d693e7 ("y2038: use time32 syscall names on 32-bit") commit 8dabe7245bbc ("y2038: syscalls: rename y2038 compat syscalls") commit 0d6040d46817 ("arch: add split IPC system calls where needed") Reported-by: Nicholas Piggin Signed-off-by: Naveen N. Rao Cc: Ravi Bangoria Cc: linuxppc-dev@lists.ozlabs.org Link: http://lkml.kernel.org/r/20190827071458.19897-1-naveen.n.rao@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/powerpc/entry/syscalls/syscall.tbl | 146 +++++++++++++++++---- 1 file changed, 119 insertions(+), 27 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl b/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl index db3bbb8744af..43f736ed47f2 100644 --- a/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl +++ b/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl @@ -20,7 +20,9 @@ 10 common unlink sys_unlink 11 nospu execve sys_execve compat_sys_execve 12 common chdir sys_chdir -13 common time sys_time compat_sys_time +13 32 time sys_time32 +13 64 time sys_time +13 spu time sys_time 14 common mknod sys_mknod 15 common chmod sys_chmod 16 common lchown sys_lchown @@ -36,14 +38,17 @@ 22 spu umount sys_ni_syscall 23 common setuid sys_setuid 24 common getuid sys_getuid -25 common stime sys_stime compat_sys_stime +25 32 stime sys_stime32 +25 64 stime sys_stime +25 spu stime sys_stime 26 nospu ptrace sys_ptrace compat_sys_ptrace 27 common alarm sys_alarm 28 32 oldfstat sys_fstat sys_ni_syscall 28 64 oldfstat sys_ni_syscall 28 spu oldfstat sys_ni_syscall 29 nospu pause sys_pause -30 nospu utime sys_utime compat_sys_utime +30 32 utime sys_utime32 +30 64 utime sys_utime 31 common stty sys_ni_syscall 32 common gtty sys_ni_syscall 33 common access sys_access @@ -157,7 +162,9 @@ 121 common setdomainname sys_setdomainname 122 common uname sys_newuname 123 common modify_ldt sys_ni_syscall -124 common adjtimex sys_adjtimex compat_sys_adjtimex +124 32 adjtimex sys_adjtimex_time32 +124 64 adjtimex sys_adjtimex +124 spu adjtimex sys_adjtimex 125 common mprotect sys_mprotect 126 32 sigprocmask sys_sigprocmask compat_sys_sigprocmask 126 64 sigprocmask sys_ni_syscall @@ -198,8 +205,12 @@ 158 common sched_yield sys_sched_yield 159 common sched_get_priority_max sys_sched_get_priority_max 160 common sched_get_priority_min sys_sched_get_priority_min -161 common sched_rr_get_interval sys_sched_rr_get_interval compat_sys_sched_rr_get_interval -162 common nanosleep sys_nanosleep compat_sys_nanosleep +161 32 sched_rr_get_interval sys_sched_rr_get_interval_time32 +161 64 sched_rr_get_interval sys_sched_rr_get_interval +161 spu sched_rr_get_interval sys_sched_rr_get_interval +162 32 nanosleep sys_nanosleep_time32 +162 64 nanosleep sys_nanosleep +162 spu nanosleep sys_nanosleep 163 common mremap sys_mremap 164 common setresuid sys_setresuid 165 common getresuid sys_getresuid @@ -213,7 +224,8 @@ 173 nospu rt_sigaction sys_rt_sigaction compat_sys_rt_sigaction 174 nospu rt_sigprocmask sys_rt_sigprocmask compat_sys_rt_sigprocmask 175 nospu rt_sigpending sys_rt_sigpending compat_sys_rt_sigpending -176 nospu rt_sigtimedwait sys_rt_sigtimedwait compat_sys_rt_sigtimedwait +176 32 rt_sigtimedwait sys_rt_sigtimedwait_time32 compat_sys_rt_sigtimedwait_time32 +176 64 rt_sigtimedwait sys_rt_sigtimedwait 177 nospu rt_sigqueueinfo sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo 178 nospu rt_sigsuspend sys_rt_sigsuspend compat_sys_rt_sigsuspend 179 common pread64 sys_pread64 compat_sys_pread64 @@ -260,7 +272,9 @@ 218 common removexattr sys_removexattr 219 common lremovexattr sys_lremovexattr 220 common fremovexattr sys_fremovexattr -221 common futex sys_futex compat_sys_futex +221 32 futex sys_futex_time32 +221 64 futex sys_futex +221 spu futex sys_futex 222 common sched_setaffinity sys_sched_setaffinity compat_sys_sched_setaffinity 223 common sched_getaffinity sys_sched_getaffinity compat_sys_sched_getaffinity # 224 unused @@ -268,7 +282,9 @@ 226 32 sendfile64 sys_sendfile64 compat_sys_sendfile64 227 common io_setup sys_io_setup compat_sys_io_setup 228 common io_destroy sys_io_destroy -229 common io_getevents sys_io_getevents compat_sys_io_getevents +229 32 io_getevents sys_io_getevents_time32 +229 64 io_getevents sys_io_getevents +229 spu io_getevents sys_io_getevents 230 common io_submit sys_io_submit compat_sys_io_submit 231 common io_cancel sys_io_cancel 232 nospu set_tid_address sys_set_tid_address @@ -280,19 +296,33 @@ 238 common epoll_wait sys_epoll_wait 239 common remap_file_pages sys_remap_file_pages 240 common timer_create sys_timer_create compat_sys_timer_create -241 common timer_settime sys_timer_settime compat_sys_timer_settime -242 common timer_gettime sys_timer_gettime compat_sys_timer_gettime +241 32 timer_settime sys_timer_settime32 +241 64 timer_settime sys_timer_settime +241 spu timer_settime sys_timer_settime +242 32 timer_gettime sys_timer_gettime32 +242 64 timer_gettime sys_timer_gettime +242 spu timer_gettime sys_timer_gettime 243 common timer_getoverrun sys_timer_getoverrun 244 common timer_delete sys_timer_delete -245 common clock_settime sys_clock_settime compat_sys_clock_settime -246 common clock_gettime sys_clock_gettime compat_sys_clock_gettime -247 common clock_getres sys_clock_getres compat_sys_clock_getres -248 common clock_nanosleep sys_clock_nanosleep compat_sys_clock_nanosleep +245 32 clock_settime sys_clock_settime32 +245 64 clock_settime sys_clock_settime +245 spu clock_settime sys_clock_settime +246 32 clock_gettime sys_clock_gettime32 +246 64 clock_gettime sys_clock_gettime +246 spu clock_gettime sys_clock_gettime +247 32 clock_getres sys_clock_getres_time32 +247 64 clock_getres sys_clock_getres +247 spu clock_getres sys_clock_getres +248 32 clock_nanosleep sys_clock_nanosleep_time32 +248 64 clock_nanosleep sys_clock_nanosleep +248 spu clock_nanosleep sys_clock_nanosleep 249 32 swapcontext ppc_swapcontext ppc32_swapcontext 249 64 swapcontext ppc64_swapcontext 249 spu swapcontext sys_ni_syscall 250 common tgkill sys_tgkill -251 common utimes sys_utimes compat_sys_utimes +251 32 utimes sys_utimes_time32 +251 64 utimes sys_utimes +251 spu utimes sys_utimes 252 common statfs64 sys_statfs64 compat_sys_statfs64 253 common fstatfs64 sys_fstatfs64 compat_sys_fstatfs64 254 32 fadvise64_64 ppc_fadvise64_64 @@ -308,8 +338,10 @@ 261 nospu set_mempolicy sys_set_mempolicy compat_sys_set_mempolicy 262 nospu mq_open sys_mq_open compat_sys_mq_open 263 nospu mq_unlink sys_mq_unlink -264 nospu mq_timedsend sys_mq_timedsend compat_sys_mq_timedsend -265 nospu mq_timedreceive sys_mq_timedreceive compat_sys_mq_timedreceive +264 32 mq_timedsend sys_mq_timedsend_time32 +264 64 mq_timedsend sys_mq_timedsend +265 32 mq_timedreceive sys_mq_timedreceive_time32 +265 64 mq_timedreceive sys_mq_timedreceive 266 nospu mq_notify sys_mq_notify compat_sys_mq_notify 267 nospu mq_getsetattr sys_mq_getsetattr compat_sys_mq_getsetattr 268 nospu kexec_load sys_kexec_load compat_sys_kexec_load @@ -324,8 +356,10 @@ 277 nospu inotify_rm_watch sys_inotify_rm_watch 278 nospu spu_run sys_spu_run 279 nospu spu_create sys_spu_create -280 nospu pselect6 sys_pselect6 compat_sys_pselect6 -281 nospu ppoll sys_ppoll compat_sys_ppoll +280 32 pselect6 sys_pselect6_time32 compat_sys_pselect6_time32 +280 64 pselect6 sys_pselect6 +281 32 ppoll sys_ppoll_time32 compat_sys_ppoll_time32 +281 64 ppoll sys_ppoll 282 common unshare sys_unshare 283 common splice sys_splice 284 common tee sys_tee @@ -334,7 +368,9 @@ 287 common mkdirat sys_mkdirat 288 common mknodat sys_mknodat 289 common fchownat sys_fchownat -290 common futimesat sys_futimesat compat_sys_futimesat +290 32 futimesat sys_futimesat_time32 +290 64 futimesat sys_futimesat +290 spu utimesat sys_futimesat 291 32 fstatat64 sys_fstatat64 291 64 newfstatat sys_newfstatat 291 spu newfstatat sys_newfstatat @@ -350,15 +386,21 @@ 301 common move_pages sys_move_pages compat_sys_move_pages 302 common getcpu sys_getcpu 303 nospu epoll_pwait sys_epoll_pwait compat_sys_epoll_pwait -304 common utimensat sys_utimensat compat_sys_utimensat +304 32 utimensat sys_utimensat_time32 +304 64 utimensat sys_utimensat +304 spu utimensat sys_utimensat 305 common signalfd sys_signalfd compat_sys_signalfd 306 common timerfd_create sys_timerfd_create 307 common eventfd sys_eventfd 308 common sync_file_range2 sys_sync_file_range2 compat_sys_sync_file_range2 309 nospu fallocate sys_fallocate compat_sys_fallocate 310 nospu subpage_prot sys_subpage_prot -311 common timerfd_settime sys_timerfd_settime compat_sys_timerfd_settime -312 common timerfd_gettime sys_timerfd_gettime compat_sys_timerfd_gettime +311 32 timerfd_settime sys_timerfd_settime32 +311 64 timerfd_settime sys_timerfd_settime +311 spu timerfd_settime sys_timerfd_settime +312 32 timerfd_gettime sys_timerfd_gettime32 +312 64 timerfd_gettime sys_timerfd_gettime +312 spu timerfd_gettime sys_timerfd_gettime 313 common signalfd4 sys_signalfd4 compat_sys_signalfd4 314 common eventfd2 sys_eventfd2 315 common epoll_create1 sys_epoll_create1 @@ -389,11 +431,15 @@ 340 common getsockopt sys_getsockopt compat_sys_getsockopt 341 common sendmsg sys_sendmsg compat_sys_sendmsg 342 common recvmsg sys_recvmsg compat_sys_recvmsg -343 common recvmmsg sys_recvmmsg compat_sys_recvmmsg +343 32 recvmmsg sys_recvmmsg_time32 compat_sys_recvmmsg_time32 +343 64 recvmmsg sys_recvmmsg +343 spu recvmmsg sys_recvmmsg 344 common accept4 sys_accept4 345 common name_to_handle_at sys_name_to_handle_at 346 common open_by_handle_at sys_open_by_handle_at compat_sys_open_by_handle_at -347 common clock_adjtime sys_clock_adjtime compat_sys_clock_adjtime +347 32 clock_adjtime sys_clock_adjtime32 +347 64 clock_adjtime sys_clock_adjtime +347 spu clock_adjtime sys_clock_adjtime 348 common syncfs sys_syncfs 349 common sendmmsg sys_sendmmsg compat_sys_sendmmsg 350 common setns sys_setns @@ -414,6 +460,7 @@ 363 spu switch_endian sys_ni_syscall 364 common userfaultfd sys_userfaultfd 365 common membarrier sys_membarrier +# 366-377 originally left for IPC, now unused 378 nospu mlock2 sys_mlock2 379 nospu copy_file_range sys_copy_file_range 380 common preadv2 sys_preadv2 compat_sys_preadv2 @@ -424,4 +471,49 @@ 385 nospu pkey_free sys_pkey_free 386 nospu pkey_mprotect sys_pkey_mprotect 387 nospu rseq sys_rseq -388 nospu io_pgetevents sys_io_pgetevents compat_sys_io_pgetevents +388 32 io_pgetevents sys_io_pgetevents_time32 compat_sys_io_pgetevents +388 64 io_pgetevents sys_io_pgetevents +# room for arch specific syscalls +392 64 semtimedop sys_semtimedop +393 common semget sys_semget +394 common semctl sys_semctl compat_sys_semctl +395 common shmget sys_shmget +396 common shmctl sys_shmctl compat_sys_shmctl +397 common shmat sys_shmat compat_sys_shmat +398 common shmdt sys_shmdt +399 common msgget sys_msgget +400 common msgsnd sys_msgsnd compat_sys_msgsnd +401 common msgrcv sys_msgrcv compat_sys_msgrcv +402 common msgctl sys_msgctl compat_sys_msgctl +403 32 clock_gettime64 sys_clock_gettime sys_clock_gettime +404 32 clock_settime64 sys_clock_settime sys_clock_settime +405 32 clock_adjtime64 sys_clock_adjtime sys_clock_adjtime +406 32 clock_getres_time64 sys_clock_getres sys_clock_getres +407 32 clock_nanosleep_time64 sys_clock_nanosleep sys_clock_nanosleep +408 32 timer_gettime64 sys_timer_gettime sys_timer_gettime +409 32 timer_settime64 sys_timer_settime sys_timer_settime +410 32 timerfd_gettime64 sys_timerfd_gettime sys_timerfd_gettime +411 32 timerfd_settime64 sys_timerfd_settime sys_timerfd_settime +412 32 utimensat_time64 sys_utimensat sys_utimensat +413 32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64 +414 32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64 +416 32 io_pgetevents_time64 sys_io_pgetevents sys_io_pgetevents +417 32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64 +418 32 mq_timedsend_time64 sys_mq_timedsend sys_mq_timedsend +419 32 mq_timedreceive_time64 sys_mq_timedreceive sys_mq_timedreceive +420 32 semtimedop_time64 sys_semtimedop sys_semtimedop +421 32 rt_sigtimedwait_time64 sys_rt_sigtimedwait compat_sys_rt_sigtimedwait_time64 +422 32 futex_time64 sys_futex sys_futex +423 32 sched_rr_get_interval_time64 sys_sched_rr_get_interval sys_sched_rr_get_interval +424 common pidfd_send_signal sys_pidfd_send_signal +425 common io_uring_setup sys_io_uring_setup +426 common io_uring_enter sys_io_uring_enter +427 common io_uring_register sys_io_uring_register +428 common open_tree sys_open_tree +429 common move_mount sys_move_mount +430 common fsopen sys_fsopen +431 common fsconfig sys_fsconfig +432 common fsmount sys_fsmount +433 common fspick sys_fspick +434 common pidfd_open sys_pidfd_open +435 nospu clone3 ppc_clone3 -- cgit v1.2.3-59-g8ed1b From e9a6882f267a8105461066e3ea6b4b6b9be1b807 Mon Sep 17 00:00:00 2001 From: Igor Lubashev Date: Mon, 26 Aug 2019 21:39:12 -0400 Subject: perf event: Check ref_reloc_sym before using it Check for ref_reloc_sym before using it instead of checking symbol_conf.kptr_restrict and relying solely on that check. Reported-by: Mathieu Poirier Signed-off-by: Igor Lubashev Tested-by: Mathieu Poirier Cc: Alexander Shishkin Cc: Alexey Budankov Cc: James Morris Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Suzuki Poulouse Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1566869956-7154-2-git-send-email-ilubashe@akamai.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/event.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 33616ea62a47..e33dd1a040cc 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -913,11 +913,13 @@ static int __perf_event__synthesize_kernel_mmap(struct perf_tool *tool, int err; union perf_event *event; - if (symbol_conf.kptr_restrict) - return -1; if (map == NULL) return -1; + kmap = map__kmap(map); + if (!kmap->ref_reloc_sym) + return -1; + /* * We should get this from /sys/kernel/sections/.text, but till that is * available use this, and after it is use this as a fallback for older @@ -940,7 +942,6 @@ static int __perf_event__synthesize_kernel_mmap(struct perf_tool *tool, event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; } - kmap = map__kmap(map); size = snprintf(event->mmap.filename, sizeof(event->mmap.filename), "%s%s", machine->mmap_name, kmap->ref_reloc_sym->name) + 1; size = PERF_ALIGN(size, sizeof(u64)); -- cgit v1.2.3-59-g8ed1b From dda1bf8ea78add78739d128a20b555c4a1a19c27 Mon Sep 17 00:00:00 2001 From: Igor Lubashev Date: Mon, 26 Aug 2019 21:39:13 -0400 Subject: perf tools: Use CAP_SYS_ADMIN with perf_event_paranoid checks The kernel is using CAP_SYS_ADMIN instead of euid==0 to override perf_event_paranoid check. Make perf do the same. Signed-off-by: Arnaldo Carvalho de Melo Acked-by: Jiri Olsa Tested-by: Mathieu Poirier Reviewed-by: Mathieu Poirier # coresight part Cc: Alexander Shishkin Cc: Alexey Budankov Cc: James Morris Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Suzuki Poulouse Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1566869956-7154-3-git-send-email-ilubashe@akamai.com Signed-off-by: Igor Lubashev Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 3 ++- tools/perf/arch/arm64/util/arm-spe.c | 3 ++- tools/perf/arch/x86/util/intel-bts.c | 3 ++- tools/perf/arch/x86/util/intel-pt.c | 2 +- tools/perf/util/evsel.c | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index a185dab2d903..5d856edc412b 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -18,6 +18,7 @@ #include "../../util/record.h" #include "../../util/auxtrace.h" #include "../../util/cpumap.h" +#include "../../util/event.h" #include "../../util/evlist.h" #include "../../util/evsel.h" #include "../../util/pmu.h" @@ -254,7 +255,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu; struct evsel *evsel, *cs_etm_evsel = NULL; struct perf_cpu_map *cpus = evlist->core.cpus; - bool privileged = (geteuid() == 0 || perf_event_paranoid() < 0); + bool privileged = perf_event_paranoid_check(-1); int err = 0; ptr->evlist = evlist; diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index cdd5c0c84183..c7b38f09260f 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -12,6 +12,7 @@ #include #include "../../util/cpumap.h" +#include "../../util/event.h" #include "../../util/evsel.h" #include "../../util/evlist.h" #include "../../util/session.h" @@ -67,7 +68,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr, container_of(itr, struct arm_spe_recording, itr); struct perf_pmu *arm_spe_pmu = sper->arm_spe_pmu; struct evsel *evsel, *arm_spe_evsel = NULL; - bool privileged = geteuid() == 0 || perf_event_paranoid() < 0; + bool privileged = perf_event_paranoid_check(-1); struct evsel *tracking_evsel; int err; diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index 1f2cf612bc9c..16d26ea701ad 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -12,6 +12,7 @@ #include #include "../../util/cpumap.h" +#include "../../util/event.h" #include "../../util/evsel.h" #include "../../util/evlist.h" #include "../../util/session.h" @@ -108,7 +109,7 @@ static int intel_bts_recording_options(struct auxtrace_record *itr, struct perf_pmu *intel_bts_pmu = btsr->intel_bts_pmu; struct evsel *evsel, *intel_bts_evsel = NULL; const struct perf_cpu_map *cpus = evlist->core.cpus; - bool privileged = geteuid() == 0 || perf_event_paranoid() < 0; + bool privileged = perf_event_paranoid_check(-1); btsr->evlist = evlist; btsr->snapshot_mode = opts->auxtrace_snapshot_mode; diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 44cfe72c1a4c..746981c82a16 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -579,7 +579,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, bool have_timing_info, need_immediate = false; struct evsel *evsel, *intel_pt_evsel = NULL; const struct perf_cpu_map *cpus = evlist->core.cpus; - bool privileged = geteuid() == 0 || perf_event_paranoid() < 0; + bool privileged = perf_event_paranoid_check(-1); u64 tsc_bit; int err; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index fa676355559e..7c704b8f0e5c 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -282,7 +282,7 @@ struct evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) static bool perf_event_can_profile_kernel(void) { - return geteuid() == 0 || perf_event_paranoid() == -1; + return perf_event_paranoid_check(-1); } struct evsel *perf_evsel__new_cycles(bool precise) -- cgit v1.2.3-59-g8ed1b From aa97293ff129f504e7c8589e56007ecfe3e3e835 Mon Sep 17 00:00:00 2001 From: Igor Lubashev Date: Mon, 26 Aug 2019 21:39:14 -0400 Subject: perf evsel: Kernel profiling is disallowed only when perf_event_paranoid > 1 Perf was too restrictive about sysctl kernel.perf_event_paranoid. The kernel only disallows profiling when perf_event_paranoid > 1. Make perf do the same. Committer testing: For a non-root user: $ id uid=1000(acme) gid=1000(acme) groups=1000(acme),10(wheel) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 $ Before: We were restricting it to just userspace (:u suffix) even for a workload started by the user: $ perf record sleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.001 MB perf.data (8 samples) ] $ perf evlist cycles:u $ perf evlist -v cycles:u: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, read_format: ID, disabled: 1, inherit: 1, exclude_kernel: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 3, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, ksymbol: 1, bpf_event: 1 $ perf report --stdio # To display the perf.data header info, please use --header/--header-only options. # # Total Lost Samples: 0 # # Samples: 8 of event 'cycles:u' # Event count (approx.): 1040396 # # Overhead Command Shared Object Symbol # ........ ....... ................ ...................... # 68.36% sleep libc-2.29.so [.] _dl_addr 27.33% sleep ld-2.29.so [.] dl_main 3.80% sleep ld-2.29.so [.] _dl_setup_hash # # (Tip: Order by the overhead of source file name and line number: perf report -s srcline) # $ $ After: When the kernel allows profiling the kernel in that scenario: $ perf record sleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.023 MB perf.data (11 samples) ] $ perf evlist cycles $ perf evlist -v cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD, read_format: ID, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 3, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, ksymbol: 1, bpf_event: 1 $ $ perf report --stdio # To display the perf.data header info, please use --header/--header-only options. # # Total Lost Samples: 0 # # Samples: 11 of event 'cycles' # Event count (approx.): 1601964 # # Overhead Command Shared Object Symbol # ........ ....... ................ .......................... # 28.14% sleep [kernel.vmlinux] [k] __rb_erase_color 27.21% sleep [kernel.vmlinux] [k] unmap_page_range 27.20% sleep ld-2.29.so [.] __tunable_get_val 15.24% sleep [kernel.vmlinux] [k] thp_get_unmapped_area 1.96% perf [kernel.vmlinux] [k] perf_event_exec 0.22% perf [kernel.vmlinux] [k] native_sched_clock 0.02% perf [kernel.vmlinux] [k] intel_bts_enable_local 0.00% perf [kernel.vmlinux] [k] native_write_msr # # (Tip: Boolean options have negative forms, e.g.: perf report --no-children) # $ Reported-by: Arnaldo Carvalho de Melo Signed-off-by: Igor Lubashev Tested-by: Arnaldo Carvalho de Melo Tested-by: Mathieu Poirier Cc: Alexander Shishkin Cc: Alexey Budankov Cc: James Morris Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Suzuki Poulouse Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1566869956-7154-4-git-send-email-ilubashe@akamai.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 7c704b8f0e5c..d4540bfe4574 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -282,7 +282,7 @@ struct evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) static bool perf_event_can_profile_kernel(void) { - return perf_event_paranoid_check(-1); + return perf_event_paranoid_check(1); } struct evsel *perf_evsel__new_cycles(bool precise) -- cgit v1.2.3-59-g8ed1b From 8859aedefefe7eeea5e67968b7fe39c828d589a0 Mon Sep 17 00:00:00 2001 From: Igor Lubashev Date: Mon, 26 Aug 2019 21:39:15 -0400 Subject: perf symbols: Use CAP_SYSLOG with kptr_restrict checks The kernel is using CAP_SYSLOG capability instead of uid==0 and euid==0 when checking kptr_restrict. Make perf do the same. Also, the kernel is a more restrictive than "no restrictions" in case of kptr_restrict==0, so add the same logic to perf. Signed-off-by: Igor Lubashev Tested-by: Mathieu Poirier Cc: Alexander Shishkin Cc: Alexey Budankov Cc: James Morris Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Suzuki Poulouse Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1566869956-7154-5-git-send-email-ilubashe@akamai.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 4efde7879474..035f2e75728c 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -15,8 +16,10 @@ #include #include "annotate.h" #include "build-id.h" +#include "cap.h" #include "util.h" #include "debug.h" +#include "event.h" #include "machine.h" #include "map.h" #include "symbol.h" @@ -2195,13 +2198,19 @@ static bool symbol__read_kptr_restrict(void) char line[8]; if (fgets(line, sizeof(line), fp) != NULL) - value = ((geteuid() != 0) || (getuid() != 0)) ? - (atoi(line) != 0) : - (atoi(line) == 2); + value = perf_cap__capable(CAP_SYSLOG) ? + (atoi(line) >= 2) : + (atoi(line) != 0); fclose(fp); } + /* Per kernel/kallsyms.c: + * we also restrict when perf_event_paranoid > 1 w/o CAP_SYSLOG + */ + if (perf_event_paranoid() > 1 && !perf_cap__capable(CAP_SYSLOG)) + value = true; + return value; } -- cgit v1.2.3-59-g8ed1b From d06e5fad8c4692c6e5f1bd626056f23716bfe4a6 Mon Sep 17 00:00:00 2001 From: Igor Lubashev Date: Mon, 26 Aug 2019 21:39:16 -0400 Subject: perf tools: Warn that perf_event_paranoid can restrict kernel symbols Warn that /proc/sys/kernel/perf_event_paranoid can also restrict kernel symbols. Signed-off-by: Igor Lubashev Tested-by: Mathieu Poirier Cc: Alexander Shishkin Cc: Alexey Budankov Cc: James Morris Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Suzuki Poulouse Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1566869956-7154-6-git-send-email-ilubashe@akamai.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 359bb8f33e57..afe558449677 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -2372,7 +2372,7 @@ int cmd_record(int argc, const char **argv) if (symbol_conf.kptr_restrict && !perf_evlist__exclude_kernel(rec->evlist)) pr_warning( "WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n" -"check /proc/sys/kernel/kptr_restrict.\n\n" +"check /proc/sys/kernel/kptr_restrict and /proc/sys/kernel/perf_event_paranoid.\n\n" "Samples in kernel functions may not be resolved if a suitable vmlinux\n" "file is not found in the buildid cache or in the vmlinux path.\n\n" "Samples in kernel modules won't be resolved at all.\n\n" diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 5970723cd55a..29e910fb2d9a 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -770,7 +770,7 @@ static void perf_event__process_sample(struct perf_tool *tool, if (!perf_evlist__exclude_kernel(top->session->evlist)) { ui__warning( "Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n" -"Check /proc/sys/kernel/kptr_restrict.\n\n" +"Check /proc/sys/kernel/kptr_restrict and /proc/sys/kernel/perf_event_paranoid.\n\n" "Kernel%s samples will not be resolved.\n", al.map && map__has_symbols(al.map) ? " modules" : ""); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 8ea62fd2591d..58a75dd3a571 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1382,7 +1382,7 @@ static char *trace__machine__resolve_kernel_addr(void *vmachine, unsigned long l if (symbol_conf.kptr_restrict) { pr_warning("Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n" - "Check /proc/sys/kernel/kptr_restrict.\n\n" + "Check /proc/sys/kernel/kptr_restrict and /proc/sys/kernel/perf_event_paranoid.\n\n" "Kernel samples will not be resolved.\n"); machine->kptr_restrict_warned = true; return NULL; -- cgit v1.2.3-59-g8ed1b From efa73d37c11af5082a5605665186c368f1196381 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 27 Aug 2019 11:32:09 -0300 Subject: perf tools: Remove needless util.h include from builtin.h And fix up places where util.h is needed but was obtained indirectly via builtin.h. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-a01ig3c4t76ye5wkqmtgk9qn@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-buildid-cache.c | 1 + tools/perf/builtin.h | 2 -- tools/perf/perf.c | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index 10457b10e568..7dde3ef0398f 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -25,6 +25,7 @@ #include "util/session.h" #include "util/symbol.h" #include "util/time-utils.h" +#include "util/util.h" #include "util/probe-file.h" static int build_id_cache__kcore_buildid(const char *proc_dir, char *sbuildid) diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h index 999fe9170122..14a2db622a7b 100644 --- a/tools/perf/builtin.h +++ b/tools/perf/builtin.h @@ -2,8 +2,6 @@ #ifndef BUILTIN_H #define BUILTIN_H -#include "util/util.h" - extern const char perf_usage_string[]; extern const char perf_more_info_string[]; diff --git a/tools/perf/perf.c b/tools/perf/perf.c index d4e4d53e8b44..34763a9b873d 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -18,6 +18,7 @@ #include "util/bpf-loader.h" #include "util/debug.h" #include "util/event.h" +#include "util/util.h" #include #include #include -- cgit v1.2.3-59-g8ed1b From 2da39f1cc36bff4cc53dc32a4afb3def488cc766 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 27 Aug 2019 11:51:18 -0300 Subject: perf evlist: Remove needless util.h from evlist.h There is no need for that util/util.h include there and, remove it, pruning the include tree, fix the fallout by adding necessary headers to places that were getting needed includes indirectly from evlist.h -> util.h. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-s9f7uve8wvykr5itcm7m7d8q@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/util/intel-bts.c | 1 + tools/perf/arch/x86/util/intel-pt.c | 1 + tools/perf/builtin-report.c | 1 + tools/perf/builtin-script.c | 1 + tools/perf/builtin-top.c | 1 + tools/perf/builtin-trace.c | 1 + tools/perf/tests/sdt.c | 1 + tools/perf/util/auxtrace.c | 1 + tools/perf/util/evlist.c | 1 + tools/perf/util/evlist.h | 1 - tools/perf/util/evsel.c | 1 + tools/perf/util/header.c | 1 + tools/perf/util/session.c | 1 + 13 files changed, 12 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index 16d26ea701ad..e4bb5df9b731 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -22,6 +22,7 @@ #include "../../util/tsc.h" #include "../../util/auxtrace.h" #include "../../util/intel-bts.h" +#include "../../util/util.h" #define KiB(x) ((x) * 1024) #define MiB(x) ((x) * 1024 * 1024) diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 746981c82a16..04b424ad4d99 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -26,6 +26,7 @@ #include "../../util/record.h" #include "../../util/target.h" #include "../../util/tsc.h" +#include "../../util/util.h" #include "../../util/intel-pt.h" #define KiB(x) ((x) * 1024) diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 318b0b95c14c..0338916af4bf 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -44,6 +44,7 @@ #include "util/auxtrace.h" #include "util/units.h" #include "util/branch.h" +#include "util/util.h" #include #include diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 51e7e6d0eee6..e005be0d359f 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -52,6 +52,7 @@ #include #include #include "util/record.h" +#include "util/util.h" #include diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 29e910fb2d9a..42ba733c9045 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -34,6 +34,7 @@ #include "util/thread.h" #include "util/thread_map.h" #include "util/top.h" +#include "util/util.h" #include #include #include "util/parse-events.h" diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 58a75dd3a571..6d9805a8791b 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -41,6 +41,7 @@ #include "util/intlist.h" #include "util/thread_map.h" #include "util/stat.h" +#include "util/util.h" #include "trace/beauty/beauty.h" #include "trace-event.h" #include "util/parse-events.h" diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c index 8bfaa630389c..dbc35a8912ed 100644 --- a/tools/perf/tests/sdt.c +++ b/tools/perf/tests/sdt.c @@ -9,6 +9,7 @@ #include "debug.h" #include "probe-file.h" #include "build-id.h" +#include "util.h" /* To test SDT event, we need libelf support to scan elf binary */ #if defined(HAVE_SDT_EVENT) && defined(HAVE_LIBELF_SUPPORT) diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 12e9b7acbb2c..112c24aa2cf2 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -50,6 +50,7 @@ #include "intel-bts.h" #include "arm-spe.h" #include "s390-cpumsf.h" +#include "util.h" #include #include "symbol/kallsyms.h" diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 47bc54111f57..5ad92fa72e78 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -16,6 +16,7 @@ #include "evsel.h" #include "debug.h" #include "units.h" +#include "util.h" #include "asm/bug.h" #include "bpf-event.h" #include diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index e31ddcc058f2..16796de7af3f 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -13,7 +13,6 @@ #include "event.h" #include "evsel.h" #include "mmap.h" -#include "util.h" #include #include diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index d4540bfe4574..dbc04e1053a9 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -40,6 +40,7 @@ #include "stat.h" #include "string2.h" #include "memswap.h" +#include "util.h" #include "util/parse-branch-options.h" #include diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 1f2965a07bef..8e67faf4fe88 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -42,6 +42,7 @@ #include "tool.h" #include "time-utils.h" #include "units.h" +#include "util.h" #include "cputopo.h" #include "bpf-event.h" diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 5786e9c807c5..a275f2e15b94 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -29,6 +29,7 @@ #include "thread-stack.h" #include "sample-raw.h" #include "stat.h" +#include "util.h" #include "arch/common.h" #ifdef HAVE_ZSTD_SUPPORT -- cgit v1.2.3-59-g8ed1b From 630aec1a7fd60ac355d5f2d67b5454912c5971a6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 28 Aug 2019 09:59:10 -0300 Subject: perf clang: Delete needless util-cxx.h header It was put in place just to make sure the 'new' C++ operator wouldn't clash with some argument name in util.h, but there is not anymore any such argument and also the reason stated for util.h to be included there was to get the __maybe_unused definition, that is in linux/compiler.h, so use that instead and nuke util-cxx.h. Cc: Adrian Hunter Cc: He Kuang Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-1r5tvfnwiydjxhukgqs6bi11@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf-loader.c | 1 + tools/perf/util/c++/clang-c.h | 2 +- tools/perf/util/c++/clang-test.cpp | 4 +++- tools/perf/util/util-cxx.h | 27 --------------------------- 4 files changed, 5 insertions(+), 29 deletions(-) delete mode 100644 tools/perf/util/util-cxx.h (limited to 'tools') diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index e20d7c5e1925..80a828e75cf6 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -23,6 +23,7 @@ #include "probe-finder.h" // for MAX_PROBES #include "parse-events.h" #include "strfilter.h" +#include "util.h" #include "llvm-utils.h" #include "c++/clang-c.h" diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h index e513366f2ee0..2df8a45bd088 100644 --- a/tools/perf/util/c++/clang-c.h +++ b/tools/perf/util/c++/clang-c.h @@ -3,7 +3,6 @@ #define PERF_UTIL_CLANG_C_H #include /* for size_t */ -#include /* for __maybe_unused */ #ifdef __cplusplus extern "C" { @@ -22,6 +21,7 @@ extern int perf_clang__compile_bpf(const char *filename, #else #include +#include /* for __maybe_unused */ static inline void perf_clang__init(void) { } static inline void perf_clang__cleanup(void) { } diff --git a/tools/perf/util/c++/clang-test.cpp b/tools/perf/util/c++/clang-test.cpp index 7b042a5ebc68..21b23605f78b 100644 --- a/tools/perf/util/c++/clang-test.cpp +++ b/tools/perf/util/c++/clang-test.cpp @@ -1,10 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 #include "clang.h" #include "clang-c.h" +extern "C" { +#include "../util.h" +} #include "llvm/IR/Function.h" #include "llvm/IR/LLVMContext.h" -#include #include #include diff --git a/tools/perf/util/util-cxx.h b/tools/perf/util/util-cxx.h deleted file mode 100644 index 80a99e458d4e..000000000000 --- a/tools/perf/util/util-cxx.h +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Support C++ source use utilities defined in util.h - */ - -#ifndef PERF_UTIL_UTIL_CXX_H -#define PERF_UTIL_UTIL_CXX_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Now 'new' is the only C++ keyword found in util.h: - * in tools/include/linux/rbtree.h - * - * Other keywords, like class and delete, should be - * redefined if necessary. - */ -#define new _new -#include "util.h" -#undef new - -#ifdef __cplusplus -} -#endif -#endif -- cgit v1.2.3-59-g8ed1b From ea4385f804eadce3f4fd8698d4ffd9e85fb6d5e0 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 28 Aug 2019 08:15:54 +0900 Subject: perf top: Decay all events in the evlist Currently perf top only decays entries in a selected evsel. I don't know whether it's intended (maybe due to performance reason?) but anyway it might show incorrect output when event group is used since users will see leader event is decayed but others are not. This patch moves the decay code into perf_top__resort_hists() so that stdio and TUI code shared the logic. Signed-off-by: Namhyung Kim Cc: Jiri Olsa Link: http://lkml.kernel.org/r/20190827231555.121411-1-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 42ba733c9045..104dbb1095c5 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -265,13 +265,23 @@ out_unlock: pthread_mutex_unlock(¬es->lock); } -static void evlist__resort_hists(struct evlist *evlist) +static void perf_top__resort_hists(struct perf_top *t) { + struct evlist *evlist = t->evlist; struct evsel *pos; evlist__for_each_entry(evlist, pos) { struct hists *hists = evsel__hists(pos); + if (evlist->enabled) { + if (t->zero) { + hists__delete_entries(hists); + } else { + hists__decay_entries(hists, t->hide_user_symbols, + t->hide_kernel_symbols); + } + } + hists__collapse_resort(hists, NULL); /* Non-group events are considered as leader */ @@ -320,16 +330,7 @@ static void perf_top__print_sym_table(struct perf_top *top) return; } - if (top->evlist->enabled) { - if (top->zero) { - hists__delete_entries(hists); - } else { - hists__decay_entries(hists, top->hide_user_symbols, - top->hide_kernel_symbols); - } - } - - evlist__resort_hists(top->evlist); + perf_top__resort_hists(top); hists__output_recalc_col_len(hists, top->print_entries - printed); putchar('\n'); @@ -577,24 +578,11 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c) static void perf_top__sort_new_samples(void *arg) { struct perf_top *t = arg; - struct evsel *evsel = t->sym_evsel; - struct hists *hists; if (t->evlist->selected != NULL) t->sym_evsel = t->evlist->selected; - hists = evsel__hists(evsel); - - if (t->evlist->enabled) { - if (t->zero) { - hists__delete_entries(hists); - } else { - hists__decay_entries(hists, t->hide_user_symbols, - t->hide_kernel_symbols); - } - } - - evlist__resort_hists(t->evlist); + perf_top__resort_hists(t); if (t->lost || t->drop) pr_warning("Too slow to read ring buffer (change period (-c/-F) or limit CPUs (-C)\n"); -- cgit v1.2.3-59-g8ed1b From be5863b7d9281bbb932542d16b7d758357fde267 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 28 Aug 2019 08:15:55 +0900 Subject: perf top: Fix event group with more than two events The event group feature links relevant hist entries among events so that they can be displayed together. During the link process, each hist entry in non-leader events is connected to a hist entry in the leader event. This is done in order of events specified in the command line so it assumes that events are linked in the order. But 'perf top' can break the assumption since it does the link process multiple times. For example, a hist entry can be in the third event only at first so it's linked after the leader. Some time later, second event has a hist entry for it and it'll be linked after the entry of the third event. This makes the code compilicated to deal with such unordered entries. This patch simply unlink all the entries after it's printed so that they can assume the correct order after the repeated link process. Also it'd be easy to deal with decaying old entries IMHO. Signed-off-by: Namhyung Kim Reported-by: Arnaldo Carvalho de Melo Tested-by: Arnaldo Carvalho de Melo Cc: Jiri Olsa Link: http://lkml.kernel.org/r/20190827231555.121411-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 6 ++++++ tools/perf/util/hist.c | 39 +++++++++++++++++++++------------------ tools/perf/util/hist.h | 1 + 3 files changed, 28 insertions(+), 18 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 104dbb1095c5..c3f95440e99c 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -273,6 +273,12 @@ static void perf_top__resort_hists(struct perf_top *t) evlist__for_each_entry(evlist, pos) { struct hists *hists = evsel__hists(pos); + /* + * unlink existing entries so that they can be linked + * in a correct order in hists__match() below. + */ + hists__unlink(hists); + if (evlist->enabled) { if (t->zero) { hists__delete_entries(hists); diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 33702675073c..e0b149673a88 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -2439,7 +2439,7 @@ void hists__match(struct hists *leader, struct hists *other) { struct rb_root_cached *root; struct rb_node *nd; - struct hist_entry *pos, *pair, *pos_pair, *tmp_pair; + struct hist_entry *pos, *pair; if (symbol_conf.report_hierarchy) { /* hierarchy report always collapses entries */ @@ -2456,24 +2456,8 @@ void hists__match(struct hists *leader, struct hists *other) pos = rb_entry(nd, struct hist_entry, rb_node_in); pair = hists__find_entry(other, pos); - if (pair && list_empty(&pair->pairs.node)) { - list_for_each_entry_safe(pos_pair, tmp_pair, &pos->pairs.head, pairs.node) { - if (pos_pair->hists == other) { - /* - * XXX maybe decayed entries can appear - * here? but then we would have use - * after free, as decayed entries are - * freed see hists__delete_entry - */ - BUG_ON(!pos_pair->dummy); - list_del_init(&pos_pair->pairs.node); - hist_entry__delete(pos_pair); - break; - } - } - + if (pair) hist_entry__add_pair(pair, pos); - } } } @@ -2558,6 +2542,25 @@ int hists__link(struct hists *leader, struct hists *other) return 0; } +int hists__unlink(struct hists *hists) +{ + struct rb_root_cached *root; + struct rb_node *nd; + struct hist_entry *pos; + + if (hists__has(hists, need_collapse)) + root = &hists->entries_collapsed; + else + root = hists->entries_in; + + for (nd = rb_first_cached(root); nd; nd = rb_next(nd)) { + pos = rb_entry(nd, struct hist_entry, rb_node_in); + list_del_init(&pos->pairs.node); + } + + return 0; +} + void hist__account_cycles(struct branch_stack *bs, struct addr_location *al, struct perf_sample *sample, bool nonany_branch_mode) { diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 83d5fc15429c..7b9267ebebeb 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -217,6 +217,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *he); void hists__match(struct hists *leader, struct hists *other); int hists__link(struct hists *leader, struct hists *other); +int hists__unlink(struct hists *hists); struct hists_evsel { struct evsel evsel; -- cgit v1.2.3-59-g8ed1b From c78ad994ad99a4e03ecefe446d39dced48ba254f Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:56:55 +0200 Subject: libperf: Add PERF_RECORD_HEADER_ATTR 'struct attr_event' to perf/event.h Move the PERF_RECORD_HEADER_ATTR event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-2-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 6 ++++++ tools/perf/util/event.h | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 36ad3a4a79e6..bb66da57d366 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -109,4 +109,10 @@ struct perf_record_sample { __u64 array[]; }; +struct attr_event { + struct perf_event_header header; + struct perf_event_attr attr; + __u64 id[]; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 429a3fe52d6c..21fa6c2acea4 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -363,12 +363,6 @@ struct cpu_map_event { struct cpu_map_data data; }; -struct attr_event { - struct perf_event_header header; - struct perf_event_attr attr; - u64 id[]; -}; - enum { PERF_EVENT_UPDATE__UNIT = 0, PERF_EVENT_UPDATE__SCALE = 1, -- cgit v1.2.3-59-g8ed1b From 78e5ea1620964c4e34e9bf43e98a3def77e6bcde Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:56:56 +0200 Subject: libperf: Add PERF_RECORD_CPU_MAP 'struct cpu_map_event' to perf/event.h Move the PERF_RECORD_CPU_MAP event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-3-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 26 ++++++++++++++++++++++++++ tools/perf/util/event.h | 26 -------------------------- 2 files changed, 26 insertions(+), 26 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index bb66da57d366..469be778fdc1 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -115,4 +115,30 @@ struct attr_event { __u64 id[]; }; +enum { + PERF_CPU_MAP__CPUS = 0, + PERF_CPU_MAP__MASK = 1, +}; + +struct cpu_map_entries { + __u16 nr; + __u16 cpu[]; +}; + +struct cpu_map_mask { + __u16 nr; + __u16 long_size; + unsigned long mask[]; +}; + +struct cpu_map_data { + __u16 type; + char data[]; +}; + +struct cpu_map_event { + struct perf_event_header header; + struct cpu_map_data data; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 21fa6c2acea4..84bf67353635 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -337,32 +337,6 @@ struct events_stats { u32 nr_proc_map_timeout; }; -enum { - PERF_CPU_MAP__CPUS = 0, - PERF_CPU_MAP__MASK = 1, -}; - -struct cpu_map_entries { - u16 nr; - u16 cpu[]; -}; - -struct cpu_map_mask { - u16 nr; - u16 long_size; - unsigned long mask[]; -}; - -struct cpu_map_data { - u16 type; - char data[]; -}; - -struct cpu_map_event { - struct perf_event_header header; - struct cpu_map_data data; -}; - enum { PERF_EVENT_UPDATE__UNIT = 0, PERF_EVENT_UPDATE__SCALE = 1, -- cgit v1.2.3-59-g8ed1b From 5ded068e923837068e39c0fd4ab40c0dacaa08e8 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:56:57 +0200 Subject: libperf: Add PERF_RECORD_EVENT_UPDATE 'struct event_update_event' to perf/event.h Move the PERF_RECORD_EVENT_UPDATE event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-4-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 22 ++++++++++++++++++++++ tools/perf/util/event.h | 23 ----------------------- tools/perf/util/header.c | 2 +- 3 files changed, 23 insertions(+), 24 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 469be778fdc1..3d99818077d8 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -141,4 +141,26 @@ struct cpu_map_event { struct cpu_map_data data; }; +enum { + PERF_EVENT_UPDATE__UNIT = 0, + PERF_EVENT_UPDATE__SCALE = 1, + PERF_EVENT_UPDATE__NAME = 2, + PERF_EVENT_UPDATE__CPUS = 3, +}; + +struct event_update_event_cpus { + struct cpu_map_data cpus; +}; + +struct event_update_event_scale { + double scale; +}; + +struct event_update_event { + struct perf_event_header header; + __u64 type; + __u64 id; + char data[]; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 84bf67353635..a579e6b439d6 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -337,29 +337,6 @@ struct events_stats { u32 nr_proc_map_timeout; }; -enum { - PERF_EVENT_UPDATE__UNIT = 0, - PERF_EVENT_UPDATE__SCALE = 1, - PERF_EVENT_UPDATE__NAME = 2, - PERF_EVENT_UPDATE__CPUS = 3, -}; - -struct event_update_event_cpus { - struct cpu_map_data cpus; -}; - -struct event_update_event_scale { - double scale; -}; - -struct event_update_event { - struct perf_event_header header; - u64 type; - u64 id; - - char data[]; -}; - #define MAX_EVENT_NAME 64 struct perf_trace_event_type { diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 8e67faf4fe88..629bdb150cb9 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -3893,7 +3893,7 @@ size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp) struct perf_cpu_map *map; size_t ret; - ret = fprintf(fp, "\n... id: %" PRIu64 "\n", ev->id); + ret = fprintf(fp, "\n... id: %" PRI_lu64 "\n", ev->id); switch (ev->type) { case PERF_EVENT_UPDATE__SCALE: -- cgit v1.2.3-59-g8ed1b From 0f5b1a28c03d416f7a66d47a9b2f18942e334fc6 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:56:58 +0200 Subject: libperf: Add PERF_RECORD_HEADER_EVENT_TYPE 'struct event_type_event' to perf/event.h Move the PERF_RECORD_HEADER_EVENT_TYPE event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-5-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 12 ++++++++++++ tools/perf/util/event.h | 12 ------------ 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 3d99818077d8..ecd1536a3a0c 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -163,4 +163,16 @@ struct event_update_event { char data[]; }; +#define MAX_EVENT_NAME 64 + +struct perf_trace_event_type { + __u64 event_id; + char name[MAX_EVENT_NAME]; +}; + +struct event_type_event { + struct perf_event_header header; + struct perf_trace_event_type event_type; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index a579e6b439d6..00725a1b602b 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -337,18 +337,6 @@ struct events_stats { u32 nr_proc_map_timeout; }; -#define MAX_EVENT_NAME 64 - -struct perf_trace_event_type { - u64 event_id; - char name[MAX_EVENT_NAME]; -}; - -struct event_type_event { - struct perf_event_header header; - struct perf_trace_event_type event_type; -}; - struct tracing_data_event { struct perf_event_header header; u32 size; -- cgit v1.2.3-59-g8ed1b From 4fd7a4d220421bc6b63a6f693e45d4397d4da055 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:56:59 +0200 Subject: libperf: Add PERF_RECORD_HEADER_TRACING_DATA 'struct tracing_data_event' to perf/event.h Move the PERF_RECORD_HEADER_TRACING_DATA event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-6-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 5 +++++ tools/perf/util/event.h | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index ecd1536a3a0c..fa81fea8dc02 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -175,4 +175,9 @@ struct event_type_event { struct perf_trace_event_type event_type; }; +struct tracing_data_event { + struct perf_event_header header; + __u32 size; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 00725a1b602b..67f6a67ad3b4 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -337,11 +337,6 @@ struct events_stats { u32 nr_proc_map_timeout; }; -struct tracing_data_event { - struct perf_event_header header; - u32 size; -}; - struct id_index_entry { u64 id; u64 idx; -- cgit v1.2.3-59-g8ed1b From ffd337b45b1aedc86b1de3cf8de9a79c10fd3810 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:00 +0200 Subject: libperf: Add PERF_RECORD_HEADER_BUILD_ID 'struct build_id_event' to perf/event.h Move the PERF_RECORD_HEADER_BUILD_ID event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Adding the fix value for build_id variable, because it will never change. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-7-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 8 ++++++++ tools/perf/util/event.h | 7 ------- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index fa81fea8dc02..5e6b6d16793c 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -6,6 +6,7 @@ #include #include #include +#include /* pid_t */ struct perf_record_mmap { struct perf_event_header header; @@ -180,4 +181,11 @@ struct tracing_data_event { __u32 size; }; +struct build_id_event { + struct perf_event_header header; + pid_t pid; + __u8 build_id[24]; + char filename[]; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 67f6a67ad3b4..4b6cf89f31db 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -144,13 +144,6 @@ struct perf_sample { PERF_MEM_S(LOCK, NA) |\ PERF_MEM_S(TLB, NA)) -struct build_id_event { - struct perf_event_header header; - pid_t pid; - u8 build_id[PERF_ALIGN(BUILD_ID_SIZE, sizeof(u64))]; - char filename[]; -}; - enum perf_user_event_type { /* above any possible kernel type */ PERF_RECORD_USER_TYPE_START = 64, PERF_RECORD_HEADER_ATTR = 64, -- cgit v1.2.3-59-g8ed1b From fecb410030628d70401e06a98a585d735f61d7e2 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:01 +0200 Subject: libperf: Add PERF_RECORD_ID_INDEX 'struct id_index_event' to perf/event.h Move the PERF_RECORD_ID_INDEX event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Add the PRI_ld64 define, so we can use it in printf output. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-8-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 13 +++++++++++++ tools/perf/util/event.h | 15 ++------------- tools/perf/util/session.c | 8 ++++---- 3 files changed, 19 insertions(+), 17 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 5e6b6d16793c..c68523c4fa01 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -188,4 +188,17 @@ struct build_id_event { char filename[]; }; +struct id_index_entry { + __u64 id; + __u64 idx; + __u64 cpu; + __u64 tid; +}; + +struct id_index_event { + struct perf_event_header header; + __u64 nr; + struct id_index_entry entries[0]; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 4b6cf89f31db..82315d2845fe 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -22,9 +22,11 @@ */ #define PRI_lu64 "l" PRIu64 #define PRI_lx64 "l" PRIx64 +#define PRI_ld64 "l" PRId64 #else #define PRI_lu64 PRIu64 #define PRI_lx64 PRIx64 +#define PRI_ld64 PRId64 #endif #define PERF_SAMPLE_MASK \ @@ -330,19 +332,6 @@ struct events_stats { u32 nr_proc_map_timeout; }; -struct id_index_entry { - u64 id; - u64 idx; - u64 cpu; - u64 tid; -}; - -struct id_index_event { - struct perf_event_header header; - u64 nr; - struct id_index_entry entries[0]; -}; - struct auxtrace_info_event { struct perf_event_header header; u32 type; diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index a275f2e15b94..aa9667424c1c 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -2393,10 +2393,10 @@ int perf_event__process_id_index(struct perf_session *session, struct perf_sample_id *sid; if (dump_trace) { - fprintf(stdout, " ... id: %"PRIu64, e->id); - fprintf(stdout, " idx: %"PRIu64, e->idx); - fprintf(stdout, " cpu: %"PRId64, e->cpu); - fprintf(stdout, " tid: %"PRId64"\n", e->tid); + fprintf(stdout, " ... id: %"PRI_lu64, e->id); + fprintf(stdout, " idx: %"PRI_lu64, e->idx); + fprintf(stdout, " cpu: %"PRI_ld64, e->cpu); + fprintf(stdout, " tid: %"PRI_ld64"\n", e->tid); } sid = perf_evlist__id2sid(evlist, e->id); -- cgit v1.2.3-59-g8ed1b From 6954ff185ee0811cdd2e0f388ff4dd7df17f11af Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 28 Aug 2019 15:05:59 -0700 Subject: blkcg: add tools/cgroup/iocost_monitor.py Instead of mucking with debugfs and ->pd_stat(), add drgn based monitoring script. Signed-off-by: Tejun Heo Cc: Omar Sandoval Signed-off-by: Jens Axboe --- block/blk-iocost.c | 21 ++++ tools/cgroup/iocost_monitor.py | 270 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 291 insertions(+) create mode 100644 tools/cgroup/iocost_monitor.py (limited to 'tools') diff --git a/block/blk-iocost.c b/block/blk-iocost.c index 680815620095..3208d2fdc55e 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -149,6 +149,27 @@ * donate and should take back how much requires hweight propagations * anyway making it easier to implement and understand as a separate * mechanism. + * + * 3. Monitoring + * + * Instead of debugfs or other clumsy monitoring mechanisms, this + * controller uses a drgn based monitoring script - + * tools/cgroup/iocost_monitor.py. For details on drgn, please see + * https://github.com/osandov/drgn. The ouput looks like the following. + * + * sdb RUN per=300ms cur_per=234.218:v203.695 busy= +1 vrate= 62.12% + * active weight hweight% inflt% del_ms usages% + * test/a * 50/ 50 33.33/ 33.33 27.65 0*041 033:033:033 + * test/b * 100/ 100 66.67/ 66.67 17.56 0*000 066:079:077 + * + * - per : Timer period + * - cur_per : Internal wall and device vtime clock + * - vrate : Device virtual time rate against wall clock + * - weight : Surplus-adjusted and configured weights + * - hweight : Surplus-adjusted and configured hierarchical weights + * - inflt : The percentage of in-flight IO cost at the end of last period + * - del_ms : Deferred issuer delay induction level and duration + * - usages : Usage history */ #include diff --git a/tools/cgroup/iocost_monitor.py b/tools/cgroup/iocost_monitor.py new file mode 100644 index 000000000000..2c9445e966d8 --- /dev/null +++ b/tools/cgroup/iocost_monitor.py @@ -0,0 +1,270 @@ +#!/usr/bin/env drgn +# +# Copyright (C) 2019 Tejun Heo +# Copyright (C) 2019 Facebook + +desc = """ +This is a drgn script to monitor the blk-iocost cgroup controller. +See the comment at the top of block/blk-iocost.c for more details. +For drgn, visit https://github.com/osandov/drgn. +""" + +import sys +import re +import time +import json + +import drgn +from drgn import container_of +from drgn.helpers.linux.list import list_for_each_entry,list_empty +from drgn.helpers.linux.radixtree import radix_tree_for_each,radix_tree_lookup + +import argparse +parser = argparse.ArgumentParser(description=desc, + formatter_class=argparse.RawTextHelpFormatter) +parser.add_argument('devname', metavar='DEV', + help='Target block device name (e.g. sda)') +parser.add_argument('--cgroup', action='append', metavar='REGEX', + help='Regex for target cgroups, ') +parser.add_argument('--interval', '-i', metavar='SECONDS', type=float, default=1, + help='Monitoring interval in seconds') +parser.add_argument('--json', action='store_true', + help='Output in json') +args = parser.parse_args() + +def err(s): + print(s, file=sys.stderr, flush=True) + sys.exit(1) + +try: + blkcg_root = prog['blkcg_root'] + plid = prog['blkcg_policy_iocost'].plid.value_() +except: + err('The kernel does not have iocost enabled') + +IOC_RUNNING = prog['IOC_RUNNING'].value_() +NR_USAGE_SLOTS = prog['NR_USAGE_SLOTS'].value_() +HWEIGHT_WHOLE = prog['HWEIGHT_WHOLE'].value_() +VTIME_PER_SEC = prog['VTIME_PER_SEC'].value_() +VTIME_PER_USEC = prog['VTIME_PER_USEC'].value_() +AUTOP_SSD_FAST = prog['AUTOP_SSD_FAST'].value_() +AUTOP_SSD_DFL = prog['AUTOP_SSD_DFL'].value_() +AUTOP_SSD_QD1 = prog['AUTOP_SSD_QD1'].value_() +AUTOP_HDD = prog['AUTOP_HDD'].value_() + +autop_names = { + AUTOP_SSD_FAST: 'ssd_fast', + AUTOP_SSD_DFL: 'ssd_dfl', + AUTOP_SSD_QD1: 'ssd_qd1', + AUTOP_HDD: 'hdd', +} + +class BlkgIterator: + def blkcg_name(blkcg): + return blkcg.css.cgroup.kn.name.string_().decode('utf-8') + + def walk(self, blkcg, q_id, parent_path): + if not self.include_dying and \ + not (blkcg.css.flags.value_() & prog['CSS_ONLINE'].value_()): + return + + name = BlkgIterator.blkcg_name(blkcg) + path = parent_path + '/' + name if parent_path else name + blkg = drgn.Object(prog, 'struct blkcg_gq', + address=radix_tree_lookup(blkcg.blkg_tree, q_id)) + if not blkg.address_: + return + + self.blkgs.append((path if path else '/', blkg)) + + for c in list_for_each_entry('struct blkcg', + blkcg.css.children.address_of_(), 'css.sibling'): + self.walk(c, q_id, path) + + def __init__(self, root_blkcg, q_id, include_dying=False): + self.include_dying = include_dying + self.blkgs = [] + self.walk(root_blkcg, q_id, '') + + def __iter__(self): + return iter(self.blkgs) + +class IocStat: + def __init__(self, ioc): + global autop_names + + self.enabled = ioc.enabled.value_() + self.running = ioc.running.value_() == IOC_RUNNING + self.period_ms = round(ioc.period_us.value_() / 1_000) + self.period_at = ioc.period_at.value_() / 1_000_000 + self.vperiod_at = ioc.period_at_vtime.value_() / VTIME_PER_SEC + self.vrate_pct = ioc.vtime_rate.counter.value_() * 100 / VTIME_PER_USEC + self.busy_level = ioc.busy_level.value_() + self.autop_idx = ioc.autop_idx.value_() + self.user_cost_model = ioc.user_cost_model.value_() + self.user_qos_params = ioc.user_qos_params.value_() + + if self.autop_idx in autop_names: + self.autop_name = autop_names[self.autop_idx] + else: + self.autop_name = '?' + + def dict(self, now): + return { 'device' : devname, + 'timestamp' : now, + 'enabled' : self.enabled, + 'running' : self.running, + 'period_ms' : self.period_ms, + 'period_at' : self.period_at, + 'period_vtime_at' : self.vperiod_at, + 'busy_level' : self.busy_level, + 'vrate_pct' : self.vrate_pct, } + + def table_preamble_str(self): + state = ('RUN' if self.running else 'IDLE') if self.enabled else 'OFF' + output = f'{devname} {state:4} ' \ + f'per={self.period_ms}ms ' \ + f'cur_per={self.period_at:.3f}:v{self.vperiod_at:.3f} ' \ + f'busy={self.busy_level:+3} ' \ + f'vrate={self.vrate_pct:6.2f}% ' \ + f'params={self.autop_name}' + if self.user_cost_model or self.user_qos_params: + output += f'({"C" if self.user_cost_model else ""}{"Q" if self.user_qos_params else ""})' + return output + + def table_header_str(self): + return f'{"":25} active {"weight":>9} {"hweight%":>13} {"inflt%":>6} ' \ + f'{"del_ms":>6} {"usages%"}' + +class IocgStat: + def __init__(self, iocg): + ioc = iocg.ioc + blkg = iocg.pd.blkg + + self.is_active = not list_empty(iocg.active_list.address_of_()) + self.weight = iocg.weight.value_() + self.active = iocg.active.value_() + self.inuse = iocg.inuse.value_() + self.hwa_pct = iocg.hweight_active.value_() * 100 / HWEIGHT_WHOLE + self.hwi_pct = iocg.hweight_inuse.value_() * 100 / HWEIGHT_WHOLE + + vdone = iocg.done_vtime.counter.value_() + vtime = iocg.vtime.counter.value_() + vrate = ioc.vtime_rate.counter.value_() + period_vtime = ioc.period_us.value_() * vrate + if period_vtime: + self.inflight_pct = (vtime - vdone) * 100 / period_vtime + else: + self.inflight_pct = 0 + + self.use_delay = min(blkg.use_delay.counter.value_(), 99) + self.delay_ms = min(round(blkg.delay_nsec.counter.value_() / 1_000_000), 999) + + usage_idx = iocg.usage_idx.value_() + self.usages = [] + self.usage = 0 + for i in range(NR_USAGE_SLOTS): + usage = iocg.usages[(usage_idx + i) % NR_USAGE_SLOTS].value_() + upct = min(usage * 100 / HWEIGHT_WHOLE, 999) + self.usages.append(upct) + self.usage = max(self.usage, upct) + + def dict(self, now, path): + out = { 'cgroup' : path, + 'timestamp' : now, + 'is_active' : self.is_active, + 'weight' : self.weight, + 'weight_active' : self.active, + 'weight_inuse' : self.inuse, + 'hweight_active_pct' : self.hwa_pct, + 'hweight_inuse_pct' : self.hwi_pct, + 'inflight_pct' : self.inflight_pct, + 'use_delay' : self.use_delay, + 'delay_ms' : self.delay_ms, + 'usage_pct' : self.usage } + for i in range(len(self.usages)): + out[f'usage_pct_{i}'] = f'{self.usages[i]}' + return out + + def table_row_str(self, path): + out = f'{path[-28:]:28} ' \ + f'{"*" if self.is_active else " "} ' \ + f'{self.inuse:5}/{self.active:5} ' \ + f'{self.hwi_pct:6.2f}/{self.hwa_pct:6.2f} ' \ + f'{self.inflight_pct:6.2f} ' \ + f'{self.use_delay:2}*{self.delay_ms:03} ' + for u in self.usages: + out += f'{round(u):03d}:' + out = out.rstrip(':') + return out + +# handle args +table_fmt = not args.json +interval = args.interval +devname = args.devname + +if args.json: + table_fmt = False + +re_str = None +if args.cgroup: + for r in args.cgroup: + if re_str is None: + re_str = r + else: + re_str += '|' + r + +filter_re = re.compile(re_str) if re_str else None + +# Locate the roots +q_id = None +root_iocg = None +ioc = None + +for i, ptr in radix_tree_for_each(blkcg_root.blkg_tree): + blkg = drgn.Object(prog, 'struct blkcg_gq', address=ptr) + try: + if devname == blkg.q.kobj.parent.name.string_().decode('utf-8'): + q_id = blkg.q.id.value_() + if blkg.pd[plid]: + root_iocg = container_of(blkg.pd[plid], 'struct ioc_gq', 'pd') + ioc = root_iocg.ioc + break + except: + pass + +if ioc is None: + err(f'Could not find ioc for {devname}'); + +# Keep printing +while True: + now = time.time() + iocstat = IocStat(ioc) + output = '' + + if table_fmt: + output += '\n' + iocstat.table_preamble_str() + output += '\n' + iocstat.table_header_str() + else: + output += json.dumps(iocstat.dict(now)) + + for path, blkg in BlkgIterator(blkcg_root, q_id): + if filter_re and not filter_re.match(path): + continue + if not blkg.pd[plid]: + continue + + iocg = container_of(blkg.pd[plid], 'struct ioc_gq', 'pd') + iocg_stat = IocgStat(iocg) + + if not filter_re and not iocg_stat.is_active: + continue + + if table_fmt: + output += '\n' + iocg_stat.table_row_str(path) + else: + output += '\n' + json.dumps(iocg_stat.dict(now, path)) + + print(output) + sys.stdout.flush() + time.sleep(interval) -- cgit v1.2.3-59-g8ed1b From 8504dea783b044cab620acbaef87b86ee84646fe Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 28 Aug 2019 15:06:00 -0700 Subject: blkcg: add tools/cgroup/iocost_coef_gen.py Add a script which can be used to generate device-specific iocost linear model coefficients. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- Documentation/admin-guide/cgroup-v2.rst | 3 + block/blk-iocost.c | 3 + tools/cgroup/iocost_coef_gen.py | 178 ++++++++++++++++++++++++++++++++ 3 files changed, 184 insertions(+) create mode 100644 tools/cgroup/iocost_coef_gen.py (limited to 'tools') diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst index 1521c7e554f5..3deacdc5e6d2 100644 --- a/Documentation/admin-guide/cgroup-v2.rst +++ b/Documentation/admin-guide/cgroup-v2.rst @@ -1529,6 +1529,9 @@ IO Interface Files The IO cost model isn't expected to be accurate in absolute sense and is scaled to the device behavior dynamically. + If needed, tools/cgroup/iocost_coef_gen.py can be used to + generate device-specific coefficients. + io.weight A read-write flat-keyed file which exists on non-root cgroups. The default is "default 100". diff --git a/block/blk-iocost.c b/block/blk-iocost.c index 3208d2fdc55e..f04a4ed1cb45 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -46,6 +46,9 @@ * If needed, tools/cgroup/iocost_coef_gen.py can be used to generate * device-specific coefficients. * + * If needed, tools/cgroup/iocost_coef_gen.py can be used to generate + * device-specific coefficients. + * * 2. Control Strategy * * The device virtual time (vtime) is used as the primary control metric. diff --git a/tools/cgroup/iocost_coef_gen.py b/tools/cgroup/iocost_coef_gen.py new file mode 100644 index 000000000000..df17a2ae80e5 --- /dev/null +++ b/tools/cgroup/iocost_coef_gen.py @@ -0,0 +1,178 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2019 Tejun Heo +# Copyright (C) 2019 Andy Newell +# Copyright (C) 2019 Facebook + +desc = """ +Generate linear IO cost model coefficients used by the blk-iocost +controller. If the target raw testdev is specified, destructive tests +are performed against the whole device; otherwise, on +./iocost-coef-fio.testfile. The result can be written directly to +/sys/fs/cgroup/io.cost.model. + +On high performance devices, --numjobs > 1 is needed to achieve +saturation. + +See Documentation/admin-guide/cgroup-v2.rst and block/blk-iocost.c +for more details. +""" + +import argparse +import re +import json +import glob +import os +import sys +import atexit +import shutil +import tempfile +import subprocess + +parser = argparse.ArgumentParser(description=desc, + formatter_class=argparse.RawTextHelpFormatter) +parser.add_argument('--testdev', metavar='DEV', + help='Raw block device to use for testing, ignores --testfile-size') +parser.add_argument('--testfile-size-gb', type=float, metavar='GIGABYTES', default=16, + help='Testfile size in gigabytes (default: %(default)s)') +parser.add_argument('--duration', type=int, metavar='SECONDS', default=120, + help='Individual test run duration in seconds (default: %(default)s)') +parser.add_argument('--seqio-block-mb', metavar='MEGABYTES', type=int, default=128, + help='Sequential test block size in megabytes (default: %(default)s)') +parser.add_argument('--seq-depth', type=int, metavar='DEPTH', default=64, + help='Sequential test queue depth (default: %(default)s)') +parser.add_argument('--rand-depth', type=int, metavar='DEPTH', default=64, + help='Random test queue depth (default: %(default)s)') +parser.add_argument('--numjobs', type=int, metavar='JOBS', default=1, + help='Number of parallel fio jobs to run (default: %(default)s)') +parser.add_argument('--quiet', action='store_true') +parser.add_argument('--verbose', action='store_true') + +def info(msg): + if not args.quiet: + print(msg) + +def dbg(msg): + if args.verbose and not args.quiet: + print(msg) + +# determine ('DEVNAME', 'MAJ:MIN') for @path +def dir_to_dev(path): + # find the block device the current directory is on + devname = subprocess.run(f'findmnt -nvo SOURCE -T{path}', + stdout=subprocess.PIPE, shell=True).stdout + devname = os.path.basename(devname).decode('utf-8').strip() + + # partition -> whole device + parents = glob.glob('/sys/block/*/' + devname) + if len(parents): + devname = os.path.basename(os.path.dirname(parents[0])) + rdev = os.stat(f'/dev/{devname}').st_rdev + return (devname, f'{os.major(rdev)}:{os.minor(rdev)}') + +def create_testfile(path, size): + global args + + if os.path.isfile(path) and os.stat(path).st_size == size: + return + + info(f'Creating testfile {path}') + subprocess.check_call(f'rm -f {path}', shell=True) + subprocess.check_call(f'touch {path}', shell=True) + subprocess.call(f'chattr +C {path}', shell=True) + subprocess.check_call( + f'pv -s {size} -pr /dev/urandom {"-q" if args.quiet else ""} | ' + f'dd of={path} count={size} ' + f'iflag=count_bytes,fullblock oflag=direct bs=16M status=none', + shell=True) + +def run_fio(testfile, duration, iotype, iodepth, blocksize, jobs): + global args + + eta = 'never' if args.quiet else 'always' + outfile = tempfile.NamedTemporaryFile() + cmd = (f'fio --direct=1 --ioengine=libaio --name=coef ' + f'--filename={testfile} --runtime={round(duration)} ' + f'--readwrite={iotype} --iodepth={iodepth} --blocksize={blocksize} ' + f'--eta={eta} --output-format json --output={outfile.name} ' + f'--time_based --numjobs={jobs}') + if args.verbose: + dbg(f'Running {cmd}') + subprocess.check_call(cmd, shell=True) + with open(outfile.name, 'r') as f: + d = json.loads(f.read()) + return sum(j['read']['bw_bytes'] + j['write']['bw_bytes'] for j in d['jobs']) + +def restore_elevator_nomerges(): + global elevator_path, nomerges_path, elevator, nomerges + + info(f'Restoring elevator to {elevator} and nomerges to {nomerges}') + with open(elevator_path, 'w') as f: + f.write(elevator) + with open(nomerges_path, 'w') as f: + f.write(nomerges) + + +args = parser.parse_args() + +missing = False +for cmd in [ 'findmnt', 'pv', 'dd', 'fio' ]: + if not shutil.which(cmd): + print(f'Required command "{cmd}" is missing', file=sys.stderr) + missing = True +if missing: + sys.exit(1) + +if args.testdev: + devname = os.path.basename(args.testdev) + rdev = os.stat(f'/dev/{devname}').st_rdev + devno = f'{os.major(rdev)}:{os.minor(rdev)}' + testfile = f'/dev/{devname}' + info(f'Test target: {devname}({devno})') +else: + devname, devno = dir_to_dev('.') + testfile = 'iocost-coef-fio.testfile' + testfile_size = int(args.testfile_size_gb * 2 ** 30) + create_testfile(testfile, testfile_size) + info(f'Test target: {testfile} on {devname}({devno})') + +elevator_path = f'/sys/block/{devname}/queue/scheduler' +nomerges_path = f'/sys/block/{devname}/queue/nomerges' + +with open(elevator_path, 'r') as f: + elevator = re.sub(r'.*\[(.*)\].*', r'\1', f.read().strip()) +with open(nomerges_path, 'r') as f: + nomerges = f.read().strip() + +info(f'Temporarily disabling elevator and merges') +atexit.register(restore_elevator_nomerges) +with open(elevator_path, 'w') as f: + f.write('none') +with open(nomerges_path, 'w') as f: + f.write('1') + +info('Determining rbps...') +rbps = run_fio(testfile, args.duration, 'read', + 1, args.seqio_block_mb * (2 ** 20), args.numjobs) +info(f'\nrbps={rbps}, determining rseqiops...') +rseqiops = round(run_fio(testfile, args.duration, 'read', + args.seq_depth, 4096, args.numjobs) / 4096) +info(f'\nrseqiops={rseqiops}, determining rrandiops...') +rrandiops = round(run_fio(testfile, args.duration, 'randread', + args.rand_depth, 4096, args.numjobs) / 4096) +info(f'\nrrandiops={rrandiops}, determining wbps...') +wbps = run_fio(testfile, args.duration, 'write', + 1, args.seqio_block_mb * (2 ** 20), args.numjobs) +info(f'\nwbps={wbps}, determining wseqiops...') +wseqiops = round(run_fio(testfile, args.duration, 'write', + args.seq_depth, 4096, args.numjobs) / 4096) +info(f'\nwseqiops={wseqiops}, determining wrandiops...') +wrandiops = round(run_fio(testfile, args.duration, 'randwrite', + args.rand_depth, 4096, args.numjobs) / 4096) +info(f'\nwrandiops={wrandiops}') +restore_elevator_nomerges() +atexit.unregister(restore_elevator_nomerges) +info('') + +print(f'{devno} rbps={rbps} rseqiops={rseqiops} rrandiops={rrandiops} ' + f'wbps={wbps} wseqiops={wseqiops} wrandiops={wrandiops}') -- cgit v1.2.3-59-g8ed1b From 9a8dad0419552934573ddf94d11146faeda465b5 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:02 +0200 Subject: libperf: Add PERF_RECORD_AUXTRACE_INFO 'struct auxtrace_info_event' to perf/event.h Move the PERF_RECORD_AUXTRACE_INFO event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-9-jolsa@kernel.org [ Fix cs_etm__print_auxtrace_info() arg to be __u64 too to fix the CORESIGHT=1 build ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/util/intel-pt.c | 2 +- tools/perf/lib/include/perf/event.h | 7 +++++++ tools/perf/util/arm-spe.c | 2 +- tools/perf/util/cs-etm.c | 2 +- tools/perf/util/event.h | 7 ------- tools/perf/util/intel-bts.c | 2 +- tools/perf/util/intel-pt.c | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 04b424ad4d99..89fe30d3310f 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -328,7 +328,7 @@ static int intel_pt_info_fill(struct auxtrace_record *itr, unsigned long max_non_turbo_ratio; size_t filter_str_len; const char *filter; - u64 *info; + __u64 *info; int err; if (priv_size != ptr->priv_size) diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index c68523c4fa01..02da73491451 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -201,4 +201,11 @@ struct id_index_event { struct id_index_entry entries[0]; }; +struct auxtrace_info_event { + struct perf_event_header header; + __u32 type; + __u32 reserved__; /* For alignment */ + __u64 priv[]; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c index a314e5b26e9d..cd26315bc9aa 100644 --- a/tools/perf/util/arm-spe.c +++ b/tools/perf/util/arm-spe.c @@ -181,7 +181,7 @@ static const char * const arm_spe_info_fmts[] = { [ARM_SPE_PMU_TYPE] = " PMU Type %"PRId64"\n", }; -static void arm_spe_print_info(u64 *arr) +static void arm_spe_print_info(__u64 *arr) { if (!dump_trace) return; diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index b3a5daaf1a8f..e210c1dde964 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -2370,7 +2370,7 @@ static const char * const cs_etmv4_priv_fmts[] = { [CS_ETMV4_TRCAUTHSTATUS] = " TRCAUTHSTATUS %llx\n", }; -static void cs_etm__print_auxtrace_info(u64 *val, int num) +static void cs_etm__print_auxtrace_info(__u64 *val, int num) { int i, j, cpu = 0; diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 82315d2845fe..ca2cae332c43 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -332,13 +332,6 @@ struct events_stats { u32 nr_proc_map_timeout; }; -struct auxtrace_info_event { - struct perf_event_header header; - u32 type; - u32 reserved__; /* For alignment */ - u64 priv[]; -}; - struct auxtrace_event { struct perf_event_header header; u64 size; diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index 8dc6408206b9..03c581a0d5d0 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c @@ -834,7 +834,7 @@ static const char * const intel_bts_info_fmts[] = { [INTEL_BTS_SNAPSHOT_MODE] = " Snapshot mode %"PRId64"\n", }; -static void intel_bts_print_info(u64 *arr, int start, int finish) +static void intel_bts_print_info(__u64 *arr, int start, int finish) { int i; diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index ea504fa9b623..c83a9a718c03 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -3044,7 +3044,7 @@ static const char * const intel_pt_info_fmts[] = { [INTEL_PT_FILTER_STR_LEN] = " Filter string len. %"PRIu64"\n", }; -static void intel_pt_print_info(u64 *arr, int start, int finish) +static void intel_pt_print_info(__u64 *arr, int start, int finish) { int i; @@ -3076,7 +3076,7 @@ int intel_pt_process_auxtrace_info(union perf_event *event, size_t min_sz = sizeof(u64) * INTEL_PT_PER_CPU_MMAPS; struct intel_pt *pt; void *info_end; - u64 *info; + __u64 *info; int err; if (auxtrace_info->header.size < sizeof(struct auxtrace_info_event) + -- cgit v1.2.3-59-g8ed1b From 306c9d24c09d84d80ae54b36f7f907c8b8fa537a Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:03 +0200 Subject: libperf: Add PERF_RECORD_AUXTRACE 'struct auxtrace_event' to perf/event.h Move the PERF_RECORD_AUXTRACE event definition to libperf's event.h. Ipn order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-10-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 11 +++++++++++ tools/perf/util/auxtrace.c | 2 +- tools/perf/util/event.h | 11 ----------- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 02da73491451..78001c2973b6 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -208,4 +208,15 @@ struct auxtrace_info_event { __u64 priv[]; }; +struct auxtrace_event { + struct perf_event_header header; + __u64 size; + __u64 offset; + __u64 reference; + __u32 idx; + __u32 tid; + __u32 cpu; + __u32 reserved__; /* For alignment */ +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 112c24aa2cf2..5edec7123328 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -943,7 +943,7 @@ s64 perf_event__process_auxtrace(struct perf_session *session, s64 err; if (dump_trace) - fprintf(stdout, " size: %#"PRIx64" offset: %#"PRIx64" ref: %#"PRIx64" idx: %u tid: %d cpu: %d\n", + fprintf(stdout, " size: %#"PRI_lx64" offset: %#"PRI_lx64" ref: %#"PRI_lx64" idx: %u tid: %d cpu: %d\n", event->auxtrace.size, event->auxtrace.offset, event->auxtrace.reference, event->auxtrace.idx, event->auxtrace.tid, event->auxtrace.cpu); diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index ca2cae332c43..60895a3b2c85 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -332,17 +332,6 @@ struct events_stats { u32 nr_proc_map_timeout; }; -struct auxtrace_event { - struct perf_event_header header; - u64 size; - u64 offset; - u64 reference; - u32 idx; - u32 tid; - u32 cpu; - u32 reserved__; /* For alignment */ -}; - #define MAX_AUXTRACE_ERROR_MSG 64 struct auxtrace_error_event { -- cgit v1.2.3-59-g8ed1b From 3460efb2e842cccc4566756f194a1be0547f7098 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:04 +0200 Subject: libperf: Add PERF_RECORD_AUXTRACE_ERROR 'struct auxtrace_error_event' to perf/event.h Move the PERF_RECORD_AUXTRACE_ERROR event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-11-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 15 +++++++++++++++ tools/perf/util/auxtrace.c | 2 +- tools/perf/util/event.h | 15 --------------- 3 files changed, 16 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 78001c2973b6..6292b7c41bac 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -219,4 +219,19 @@ struct auxtrace_event { __u32 reserved__; /* For alignment */ }; +#define MAX_AUXTRACE_ERROR_MSG 64 + +struct auxtrace_error_event { + struct perf_event_header header; + __u32 type; + __u32 code; + __u32 cpu; + __u32 pid; + __u32 tid; + __u32 fmt; + __u64 ip; + __u64 time; + char msg[MAX_AUXTRACE_ERROR_MSG]; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 5edec7123328..c3da8a0e66b2 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -1189,7 +1189,7 @@ size_t perf_event__fprintf_auxtrace_error(union perf_event *event, FILE *fp) if (!e->fmt) msg = (const char *)&e->time; - ret += fprintf(fp, " cpu %d pid %d tid %d ip %#"PRIx64" code %u: %s\n", + ret += fprintf(fp, " cpu %d pid %d tid %d ip %#"PRI_lx64" code %u: %s\n", e->cpu, e->pid, e->tid, e->ip, e->code, msg); return ret; } diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 60895a3b2c85..e334ecbe50a0 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -332,21 +332,6 @@ struct events_stats { u32 nr_proc_map_timeout; }; -#define MAX_AUXTRACE_ERROR_MSG 64 - -struct auxtrace_error_event { - struct perf_event_header header; - u32 type; - u32 code; - u32 cpu; - u32 pid; - u32 tid; - u32 fmt; - u64 ip; - u64 time; - char msg[MAX_AUXTRACE_ERROR_MSG]; -}; - struct aux_event { struct perf_event_header header; u64 aux_offset; -- cgit v1.2.3-59-g8ed1b From aedebdca09ca6efa7efbc0bf26d94cb235120ee4 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:05 +0200 Subject: libperf: Add PERF_RECORD_AUX 'struct aux_event' to perf/event.h Move the PERF_RECORD_AUX event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-12-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 7 +++++++ tools/perf/util/event.c | 2 +- tools/perf/util/event.h | 7 ------- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 6292b7c41bac..d453ac833a58 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -234,4 +234,11 @@ struct auxtrace_error_event { char msg[MAX_AUXTRACE_ERROR_MSG]; }; +struct aux_event { + struct perf_event_header header; + __u64 aux_offset; + __u64 aux_size; + __u64 flags; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index e33dd1a040cc..b048e6084612 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1449,7 +1449,7 @@ int perf_event__process_exit(struct perf_tool *tool __maybe_unused, size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp) { - return fprintf(fp, " offset: %#"PRIx64" size: %#"PRIx64" flags: %#"PRIx64" [%s%s%s]\n", + return fprintf(fp, " offset: %#"PRI_lx64" size: %#"PRI_lx64" flags: %#"PRI_lx64" [%s%s%s]\n", event->aux.aux_offset, event->aux.aux_size, event->aux.flags, event->aux.flags & PERF_AUX_FLAG_TRUNCATED ? "T" : "", diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index e334ecbe50a0..db901aea33af 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -332,13 +332,6 @@ struct events_stats { u32 nr_proc_map_timeout; }; -struct aux_event { - struct perf_event_header header; - u64 aux_offset; - u64 aux_size; - u64 flags; -}; - struct itrace_start_event { struct perf_event_header header; u32 pid, tid; -- cgit v1.2.3-59-g8ed1b From f279ad63a09da65766dfeaf03cfd659f95414936 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:06 +0200 Subject: libperf: Add PERF_RECORD_ITRACE_START 'struct itrace_start_event' to perf/event.h Move the PERF_RECORD_ITRACE_START event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-13-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 6 ++++++ tools/perf/util/event.h | 5 ----- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index d453ac833a58..3bcbc1eaeb35 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -241,4 +241,10 @@ struct aux_event { __u64 flags; }; +struct itrace_start_event { + struct perf_event_header header; + __u32 pid; + __u32 tid; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index db901aea33af..f89e8ddadd46 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -332,11 +332,6 @@ struct events_stats { u32 nr_proc_map_timeout; }; -struct itrace_start_event { - struct perf_event_header header; - u32 pid, tid; -}; - struct context_switch_event { struct perf_event_header header; u32 next_prev_pid; -- cgit v1.2.3-59-g8ed1b From 6b49aaebd05fdbb29a4ab6e28b4fa91539c64877 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:07 +0200 Subject: libperf: Add PERF_RECORD_SWITCH 'struct context_switch_event' to perf/event.h Move the PERF_RECORD_SWITCH event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-14-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 6 ++++++ tools/perf/util/event.h | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 3bcbc1eaeb35..a7b0344bb8b4 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -110,6 +110,12 @@ struct perf_record_sample { __u64 array[]; }; +struct context_switch_event { + struct perf_event_header header; + __u32 next_prev_pid; + __u32 next_prev_tid; +}; + struct attr_event { struct perf_event_header header; struct perf_event_attr attr; diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index f89e8ddadd46..012b2ba9a9a8 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -332,12 +332,6 @@ struct events_stats { u32 nr_proc_map_timeout; }; -struct context_switch_event { - struct perf_event_header header; - u32 next_prev_pid; - u32 next_prev_tid; -}; - struct thread_map_event_entry { u64 pid; char comm[16]; -- cgit v1.2.3-59-g8ed1b From 3e4c453f5cbac75afec37eedd0ffcd8dac82e23e Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:08 +0200 Subject: libperf: Add PERF_RECORD_THREAD_MAP 'struct thread_map_event' to perf/event.h Move the PERF_RECORD_THREAD_MAP event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-15-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 11 +++++++++++ tools/perf/util/event.h | 11 ----------- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index a7b0344bb8b4..fe0ce655af17 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -253,4 +253,15 @@ struct itrace_start_event { __u32 tid; }; +struct thread_map_event_entry { + __u64 pid; + char comm[16]; +}; + +struct thread_map_event { + struct perf_event_header header; + __u64 nr; + struct thread_map_event_entry entries[]; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 012b2ba9a9a8..3a856696c6b1 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -332,17 +332,6 @@ struct events_stats { u32 nr_proc_map_timeout; }; -struct thread_map_event_entry { - u64 pid; - char comm[16]; -}; - -struct thread_map_event { - struct perf_event_header header; - u64 nr; - struct thread_map_event_entry entries[]; -}; - enum { PERF_STAT_CONFIG_TERM__AGGR_MODE = 0, PERF_STAT_CONFIG_TERM__INTERVAL = 1, -- cgit v1.2.3-59-g8ed1b From c5f416e6c69e333207666a1ddab0b41c6f12e588 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:09 +0200 Subject: libperf: Add PERF_RECORD_STAT_CONFIG 'struct stat_config_event' to perf/event.h Move the PERF_RECORD_STAT_CONFIG event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-16-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 18 ++++++++++++++++++ tools/perf/util/event.c | 2 +- tools/perf/util/event.h | 18 ------------------ 3 files changed, 19 insertions(+), 19 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index fe0ce655af17..ba6ed243a31f 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -264,4 +264,22 @@ struct thread_map_event { struct thread_map_event_entry entries[]; }; +enum { + PERF_STAT_CONFIG_TERM__AGGR_MODE = 0, + PERF_STAT_CONFIG_TERM__INTERVAL = 1, + PERF_STAT_CONFIG_TERM__SCALE = 2, + PERF_STAT_CONFIG_TERM__MAX = 3, +}; + +struct stat_config_event_entry { + __u64 tag; + __u64 val; +}; + +struct stat_config_event { + struct perf_event_header header; + __u64 nr; + struct stat_config_event_entry data[]; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index b048e6084612..b711019a9ed2 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1235,7 +1235,7 @@ void perf_event__read_stat_config(struct perf_stat_config *config, CASE(INTERVAL, interval) #undef CASE default: - pr_warning("unknown stat config term %" PRIu64 "\n", + pr_warning("unknown stat config term %" PRI_lu64 "\n", event->data[i].tag); } } diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 3a856696c6b1..68531d08dcec 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -332,24 +332,6 @@ struct events_stats { u32 nr_proc_map_timeout; }; -enum { - PERF_STAT_CONFIG_TERM__AGGR_MODE = 0, - PERF_STAT_CONFIG_TERM__INTERVAL = 1, - PERF_STAT_CONFIG_TERM__SCALE = 2, - PERF_STAT_CONFIG_TERM__MAX = 3, -}; - -struct stat_config_event_entry { - u64 tag; - u64 val; -}; - -struct stat_config_event { - struct perf_event_header header; - u64 nr; - struct stat_config_event_entry data[]; -}; - struct stat_event { struct perf_event_header header; -- cgit v1.2.3-59-g8ed1b From 18a13a60f6f50f2fb1f7354f6d0b2ded01995443 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:10 +0200 Subject: libperf: Add PERF_RECORD_STAT 'struct stat_event' to perf/event.h Move the PERF_RECORD_STAT event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-17-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 17 +++++++++++++++++ tools/perf/util/event.h | 17 ----------------- tools/perf/util/stat.c | 4 ++-- 3 files changed, 19 insertions(+), 19 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index ba6ed243a31f..7d1834f558d6 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -282,4 +282,21 @@ struct stat_config_event { struct stat_config_event_entry data[]; }; +struct stat_event { + struct perf_event_header header; + + __u64 id; + __u32 cpu; + __u32 thread; + + union { + struct { + __u64 val; + __u64 ena; + __u64 run; + }; + __u64 values[3]; + }; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 68531d08dcec..f3a02e01852a 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -332,23 +332,6 @@ struct events_stats { u32 nr_proc_map_timeout; }; -struct stat_event { - struct perf_event_header header; - - u64 id; - u32 cpu; - u32 thread; - - union { - struct { - u64 val; - u64 ena; - u64 run; - }; - u64 values[3]; - }; -}; - enum { PERF_STAT_ROUND_TYPE__INTERVAL = 0, PERF_STAT_ROUND_TYPE__FINAL = 1, diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index f985336b3a22..c0cd9f9bb0ea 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -405,9 +405,9 @@ size_t perf_event__fprintf_stat(union perf_event *event, FILE *fp) struct stat_event *st = (struct stat_event *) event; size_t ret; - ret = fprintf(fp, "\n... id %" PRIu64 ", cpu %d, thread %d\n", + ret = fprintf(fp, "\n... id %" PRI_lu64 ", cpu %d, thread %d\n", st->id, st->cpu, st->thread); - ret += fprintf(fp, "... value %" PRIu64 ", enabled %" PRIu64 ", running %" PRIu64 "\n", + ret += fprintf(fp, "... value %" PRI_lu64 ", enabled %" PRI_lu64 ", running %" PRI_lu64 "\n", st->val, st->ena, st->run); return ret; -- cgit v1.2.3-59-g8ed1b From 782adbe2964953803ea1a38b80f6255c336cdd7b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:11 +0200 Subject: libperf: Add PERF_RECORD_STAT_ROUND 'struct stat_round_event' to perf/event.h Move the PERF_RECORD_STAT_ROUND event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-18-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 6 ++++++ tools/perf/util/event.h | 6 ------ tools/perf/util/stat.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 7d1834f558d6..34d365bd2c5c 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -299,4 +299,10 @@ struct stat_event { }; }; +struct stat_round_event { + struct perf_event_header header; + __u64 type; + __u64 time; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index f3a02e01852a..ec76412afba1 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -337,12 +337,6 @@ enum { PERF_STAT_ROUND_TYPE__FINAL = 1, }; -struct stat_round_event { - struct perf_event_header header; - u64 type; - u64 time; -}; - struct time_conv_event { struct perf_event_header header; u64 time_shift; diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index c0cd9f9bb0ea..4c7957496e7c 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -418,7 +418,7 @@ size_t perf_event__fprintf_stat_round(union perf_event *event, FILE *fp) struct stat_round_event *rd = (struct stat_round_event *)event; size_t ret; - ret = fprintf(fp, "\n... time %" PRIu64 ", type %s\n", rd->time, + ret = fprintf(fp, "\n... time %" PRI_lu64 ", type %s\n", rd->time, rd->type == PERF_STAT_ROUND_TYPE__FINAL ? "FINAL" : "INTERVAL"); return ret; -- cgit v1.2.3-59-g8ed1b From bfd922d8f09a692f2a952a67451bc3eeaad3fb73 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:12 +0200 Subject: libperf: Add PERF_RECORD_TIME_CONV 'struct time_conv_event' to perf/event.h Move the PERF_RECORD_TIME_CONV event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-19-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 7 +++++++ tools/perf/util/event.h | 7 ------- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 34d365bd2c5c..7600f53f6ad1 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -305,4 +305,11 @@ struct stat_round_event { __u64 time; }; +struct time_conv_event { + struct perf_event_header header; + __u64 time_shift; + __u64 time_mult; + __u64 time_zero; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index ec76412afba1..d758485956b3 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -337,13 +337,6 @@ enum { PERF_STAT_ROUND_TYPE__FINAL = 1, }; -struct time_conv_event { - struct perf_event_header header; - u64 time_shift; - u64 time_mult; - u64 time_zero; -}; - struct feature_event { struct perf_event_header header; u64 feat_id; -- cgit v1.2.3-59-g8ed1b From 1b8896fb296f4087c45c997c4b212544c639e272 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:13 +0200 Subject: libperf: Add PERF_RECORD_HEADER_FEATURE 'struct feature_event' to perf/event.h Move the PERF_RECORD_HEADER_FEATURE event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-20-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-report.c | 2 +- tools/perf/lib/include/perf/event.h | 6 ++++++ tools/perf/util/event.h | 6 ------ 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 0338916af4bf..33c20e26b290 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -212,7 +212,7 @@ static int process_feature_event(struct perf_session *session, return perf_event__process_feature(session, event); if (event->feat.feat_id != HEADER_LAST_FEATURE) { - pr_err("failed: wrong feature ID: %" PRIu64 "\n", + pr_err("failed: wrong feature ID: %" PRI_lu64 "\n", event->feat.feat_id); return -1; } diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 7600f53f6ad1..ed1c22e650e2 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -312,4 +312,10 @@ struct time_conv_event { __u64 time_zero; }; +struct feature_event { + struct perf_event_header header; + __u64 feat_id; + char data[]; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index d758485956b3..94777ee435c2 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -337,12 +337,6 @@ enum { PERF_STAT_ROUND_TYPE__FINAL = 1, }; -struct feature_event { - struct perf_event_header header; - u64 feat_id; - char data[]; -}; - struct compressed_event { struct perf_event_header header; char data[]; -- cgit v1.2.3-59-g8ed1b From f5f684321791eb5ebb8c56d7d223e71fe08b5dd9 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:14 +0200 Subject: libperf: Add PERF_RECORD_COMPRESSED 'struct compressed_event' to perf/event.h Move the PERF_RECORD_COMPRESSED event definition to libperf's event.h. In order to keep libperf simple, we switch 'u64/u32/u16/u8' types used events to their generic '__u*' versions. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-21-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 5 +++++ tools/perf/util/event.h | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index ed1c22e650e2..ef7a46e82a6d 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -318,4 +318,9 @@ struct feature_event { char data[]; }; +struct compressed_event { + struct perf_event_header header; + char data[]; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 94777ee435c2..ee2ee23e4c46 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -337,11 +337,6 @@ enum { PERF_STAT_ROUND_TYPE__FINAL = 1, }; -struct compressed_event { - struct perf_event_header header; - char data[]; -}; - union perf_event { struct perf_event_header header; struct perf_record_mmap mmap; -- cgit v1.2.3-59-g8ed1b From 7510410a38c71eb5d45217a4934e60eef88c04e1 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:15 +0200 Subject: libperf: Add 'union perf_event' to perf/event.h So it's available for libperf's users. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-22-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 36 ++++++++++++++++++++++++++++++++++++ tools/perf/util/event.h | 36 ------------------------------------ 2 files changed, 36 insertions(+), 36 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index ef7a46e82a6d..a5b08ef118a7 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -323,4 +323,40 @@ struct compressed_event { char data[]; }; +union perf_event { + struct perf_event_header header; + struct perf_record_mmap mmap; + struct perf_record_mmap2 mmap2; + struct perf_record_comm comm; + struct perf_record_namespaces namespaces; + struct perf_record_fork fork; + struct perf_record_lost lost; + struct perf_record_lost_samples lost_samples; + struct perf_record_read read; + struct perf_record_throttle throttle; + struct perf_record_sample sample; + struct perf_record_bpf_event bpf; + struct perf_record_ksymbol ksymbol; + struct attr_event attr; + struct event_update_event event_update; + struct event_type_event event_type; + struct tracing_data_event tracing_data; + struct build_id_event build_id; + struct id_index_event id_index; + struct auxtrace_info_event auxtrace_info; + struct auxtrace_event auxtrace; + struct auxtrace_error_event auxtrace_error; + struct aux_event aux; + struct itrace_start_event itrace_start; + struct context_switch_event context_switch; + struct thread_map_event thread_map; + struct cpu_map_event cpu_map; + struct stat_config_event stat_config; + struct stat_event stat; + struct stat_round_event stat_round; + struct time_conv_event time_conv; + struct feature_event feat; + struct compressed_event pack; +}; + #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index ee2ee23e4c46..e15eed53ce90 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -337,42 +337,6 @@ enum { PERF_STAT_ROUND_TYPE__FINAL = 1, }; -union perf_event { - struct perf_event_header header; - struct perf_record_mmap mmap; - struct perf_record_mmap2 mmap2; - struct perf_record_comm comm; - struct perf_record_namespaces namespaces; - struct perf_record_fork fork; - struct perf_record_lost lost; - struct perf_record_lost_samples lost_samples; - struct perf_record_read read; - struct perf_record_throttle throttle; - struct perf_record_sample sample; - struct perf_record_bpf_event bpf; - struct perf_record_ksymbol ksymbol; - struct attr_event attr; - struct event_update_event event_update; - struct event_type_event event_type; - struct tracing_data_event tracing_data; - struct build_id_event build_id; - struct id_index_event id_index; - struct auxtrace_info_event auxtrace_info; - struct auxtrace_event auxtrace; - struct auxtrace_error_event auxtrace_error; - struct aux_event aux; - struct itrace_start_event itrace_start; - struct context_switch_event context_switch; - struct thread_map_event thread_map; - struct cpu_map_event cpu_map; - struct stat_config_event stat_config; - struct stat_event stat; - struct stat_round_event stat_round; - struct time_conv_event time_conv; - struct feature_event feat; - struct compressed_event pack; -}; - void perf_event__print_totals(void); struct perf_tool; -- cgit v1.2.3-59-g8ed1b From 72932371e78012cea96edb9e833d81f1c32dd892 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:16 +0200 Subject: libperf: Rename the PERF_RECORD_ structs to have a "perf" prefix Even more, to have a "perf_record_" prefix, so that they match the PERF_RECORD_ enum they map to. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-23-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 4 +- tools/perf/arch/arm64/util/arm-spe.c | 2 +- tools/perf/arch/s390/util/auxtrace.c | 2 +- tools/perf/arch/x86/util/intel-bts.c | 2 +- tools/perf/arch/x86/util/intel-pt.c | 2 +- tools/perf/arch/x86/util/tsc.c | 2 +- tools/perf/builtin-record.c | 4 +- tools/perf/builtin-script.c | 2 +- tools/perf/builtin-stat.c | 2 +- tools/perf/lib/include/perf/event.h | 136 +++++++++++++++++------------------ tools/perf/tests/cpumap.c | 12 ++-- tools/perf/tests/event_update.c | 16 ++--- tools/perf/tests/stat.c | 8 +-- tools/perf/tests/thread-map.c | 2 +- tools/perf/util/arm-spe.c | 4 +- tools/perf/util/auxtrace.c | 16 ++--- tools/perf/util/auxtrace.h | 8 +-- tools/perf/util/build-id.c | 2 +- tools/perf/util/cpumap.c | 6 +- tools/perf/util/cpumap.h | 4 +- tools/perf/util/cs-etm.c | 2 +- tools/perf/util/event.c | 34 ++++----- tools/perf/util/event.h | 4 +- tools/perf/util/header.c | 54 +++++++------- tools/perf/util/intel-bts.c | 4 +- tools/perf/util/intel-pt.c | 8 +-- tools/perf/util/python.c | 4 +- tools/perf/util/s390-cpumsf.c | 4 +- tools/perf/util/session.c | 20 +++--- tools/perf/util/session.h | 2 +- tools/perf/util/stat.c | 6 +- tools/perf/util/thread_map.c | 4 +- tools/perf/util/thread_map.h | 4 +- 33 files changed, 193 insertions(+), 193 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 5d856edc412b..9644e2d405f7 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -565,7 +565,7 @@ static int cs_etm_get_ro(struct perf_pmu *pmu, int cpu, const char *path) static void cs_etm_get_metadata(int cpu, u32 *offset, struct auxtrace_record *itr, - struct auxtrace_info_event *info) + struct perf_record_auxtrace_info *info) { u32 increment; u64 magic; @@ -630,7 +630,7 @@ static void cs_etm_get_metadata(int cpu, u32 *offset, static int cs_etm_info_fill(struct auxtrace_record *itr, struct perf_session *session, - struct auxtrace_info_event *info, + struct perf_record_auxtrace_info *info, size_t priv_size) { int i; diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index c7b38f09260f..4b364692da67 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -41,7 +41,7 @@ arm_spe_info_priv_size(struct auxtrace_record *itr __maybe_unused, static int arm_spe_info_fill(struct auxtrace_record *itr, struct perf_session *session, - struct auxtrace_info_event *auxtrace_info, + struct perf_record_auxtrace_info *auxtrace_info, size_t priv_size) { struct arm_spe_recording *sper = diff --git a/tools/perf/arch/s390/util/auxtrace.c b/tools/perf/arch/s390/util/auxtrace.c index f32d7a72d039..b0fb70e38960 100644 --- a/tools/perf/arch/s390/util/auxtrace.c +++ b/tools/perf/arch/s390/util/auxtrace.c @@ -29,7 +29,7 @@ static size_t cpumsf_info_priv_size(struct auxtrace_record *itr __maybe_unused, static int cpumsf_info_fill(struct auxtrace_record *itr __maybe_unused, struct perf_session *session __maybe_unused, - struct auxtrace_info_event *auxtrace_info __maybe_unused, + struct perf_record_auxtrace_info *auxtrace_info __maybe_unused, size_t priv_size __maybe_unused) { auxtrace_info->type = PERF_AUXTRACE_S390_CPUMSF; diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index e4bb5df9b731..d263430c045f 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -60,7 +60,7 @@ intel_bts_info_priv_size(struct auxtrace_record *itr __maybe_unused, static int intel_bts_info_fill(struct auxtrace_record *itr, struct perf_session *session, - struct auxtrace_info_event *auxtrace_info, + struct perf_record_auxtrace_info *auxtrace_info, size_t priv_size) { struct intel_bts_recording *btsr = diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 89fe30d3310f..cb7cf16af79c 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -314,7 +314,7 @@ static void intel_pt_tsc_ctc_ratio(u32 *n, u32 *d) static int intel_pt_info_fill(struct auxtrace_record *itr, struct perf_session *session, - struct auxtrace_info_event *auxtrace_info, + struct perf_record_auxtrace_info *auxtrace_info, size_t priv_size) { struct intel_pt_recording *ptr = diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c index b1eb963b4a6e..81720e27f8a3 100644 --- a/tools/perf/arch/x86/util/tsc.c +++ b/tools/perf/arch/x86/util/tsc.c @@ -57,7 +57,7 @@ int perf_event__synth_time_conv(const struct perf_event_mmap_page *pc, .time_conv = { .header = { .type = PERF_RECORD_TIME_CONV, - .size = sizeof(struct time_conv_event), + .size = sizeof(struct perf_record_time_conv), }, }, }; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index afe558449677..bd2a0cc6eb52 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -898,7 +898,7 @@ static void record__adjust_affinity(struct record *rec, struct perf_mmap *map) static size_t process_comp_header(void *record, size_t increment) { - struct compressed_event *event = record; + struct perf_record_compressed *event = record; size_t size = sizeof(*event); if (increment) { @@ -916,7 +916,7 @@ static size_t zstd_compress(struct perf_session *session, void *dst, size_t dst_ void *src, size_t src_size) { size_t compressed; - size_t max_record_size = PERF_SAMPLE_MAX_SIZE - sizeof(struct compressed_event) - 1; + size_t max_record_size = PERF_SAMPLE_MAX_SIZE - sizeof(struct perf_record_compressed) - 1; compressed = zstd_compress_stream_to_records(&session->zstd_data, dst, dst_size, src, src_size, max_record_size, process_comp_header); diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index e005be0d359f..37297b67905d 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -3244,7 +3244,7 @@ static void script__setup_sample_type(struct perf_script *script) static int process_stat_round_event(struct perf_session *session, union perf_event *event) { - struct stat_round_event *round = &event->stat_round; + struct perf_record_stat_round *round = &event->stat_round; struct evsel *counter; evlist__for_each_entry(session->evlist, counter) { diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 6ab13f466827..a7e8c26635db 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1462,7 +1462,7 @@ static int __cmd_record(int argc, const char **argv) static int process_stat_round_event(struct perf_session *session, union perf_event *event) { - struct stat_round_event *stat_round = &event->stat_round; + struct perf_record_stat_round *stat_round = &event->stat_round; struct evsel *counter; struct timespec tsh, *ts = NULL; const char **argv = session->header.env.cmdline_argv; diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index a5b08ef118a7..1655c744ec2b 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -110,13 +110,13 @@ struct perf_record_sample { __u64 array[]; }; -struct context_switch_event { +struct perf_record_switch { struct perf_event_header header; __u32 next_prev_pid; __u32 next_prev_tid; }; -struct attr_event { +struct perf_record_header_attr { struct perf_event_header header; struct perf_event_attr attr; __u64 id[]; @@ -132,20 +132,20 @@ struct cpu_map_entries { __u16 cpu[]; }; -struct cpu_map_mask { +struct perf_record_record_cpu_map { __u16 nr; __u16 long_size; unsigned long mask[]; }; -struct cpu_map_data { +struct perf_record_cpu_map_data { __u16 type; char data[]; }; -struct cpu_map_event { - struct perf_event_header header; - struct cpu_map_data data; +struct perf_record_cpu_map { + struct perf_event_header header; + struct perf_record_cpu_map_data data; }; enum { @@ -155,15 +155,15 @@ enum { PERF_EVENT_UPDATE__CPUS = 3, }; -struct event_update_event_cpus { - struct cpu_map_data cpus; +struct perf_record_event_update_cpus { + struct perf_record_cpu_map_data cpus; }; -struct event_update_event_scale { +struct perf_record_event_update_scale { double scale; }; -struct event_update_event { +struct perf_record_event_update { struct perf_event_header header; __u64 type; __u64 id; @@ -177,17 +177,17 @@ struct perf_trace_event_type { char name[MAX_EVENT_NAME]; }; -struct event_type_event { +struct perf_record_header_event_type { struct perf_event_header header; struct perf_trace_event_type event_type; }; -struct tracing_data_event { +struct perf_record_header_tracing_data { struct perf_event_header header; __u32 size; }; -struct build_id_event { +struct perf_record_header_build_id { struct perf_event_header header; pid_t pid; __u8 build_id[24]; @@ -201,20 +201,20 @@ struct id_index_entry { __u64 tid; }; -struct id_index_event { +struct perf_record_id_index { struct perf_event_header header; __u64 nr; struct id_index_entry entries[0]; }; -struct auxtrace_info_event { +struct perf_record_auxtrace_info { struct perf_event_header header; __u32 type; __u32 reserved__; /* For alignment */ __u64 priv[]; }; -struct auxtrace_event { +struct perf_record_auxtrace { struct perf_event_header header; __u64 size; __u64 offset; @@ -227,7 +227,7 @@ struct auxtrace_event { #define MAX_AUXTRACE_ERROR_MSG 64 -struct auxtrace_error_event { +struct perf_record_auxtrace_error { struct perf_event_header header; __u32 type; __u32 code; @@ -240,28 +240,28 @@ struct auxtrace_error_event { char msg[MAX_AUXTRACE_ERROR_MSG]; }; -struct aux_event { +struct perf_record_aux { struct perf_event_header header; __u64 aux_offset; __u64 aux_size; __u64 flags; }; -struct itrace_start_event { +struct perf_record_itrace_start { struct perf_event_header header; __u32 pid; __u32 tid; }; -struct thread_map_event_entry { +struct perf_record_thread_map_entry { __u64 pid; char comm[16]; }; -struct thread_map_event { - struct perf_event_header header; - __u64 nr; - struct thread_map_event_entry entries[]; +struct perf_record_thread_map { + struct perf_event_header header; + __u64 nr; + struct perf_record_thread_map_entry entries[]; }; enum { @@ -271,18 +271,18 @@ enum { PERF_STAT_CONFIG_TERM__MAX = 3, }; -struct stat_config_event_entry { +struct perf_record_stat_config_entry { __u64 tag; __u64 val; }; -struct stat_config_event { - struct perf_event_header header; - __u64 nr; - struct stat_config_event_entry data[]; +struct perf_record_stat_config { + struct perf_event_header header; + __u64 nr; + struct perf_record_stat_config_entry data[]; }; -struct stat_event { +struct perf_record_stat { struct perf_event_header header; __u64 id; @@ -299,64 +299,64 @@ struct stat_event { }; }; -struct stat_round_event { +struct perf_record_stat_round { struct perf_event_header header; __u64 type; __u64 time; }; -struct time_conv_event { +struct perf_record_time_conv { struct perf_event_header header; __u64 time_shift; __u64 time_mult; __u64 time_zero; }; -struct feature_event { +struct perf_record_header_feature { struct perf_event_header header; __u64 feat_id; char data[]; }; -struct compressed_event { +struct perf_record_compressed { struct perf_event_header header; char data[]; }; union perf_event { - struct perf_event_header header; - struct perf_record_mmap mmap; - struct perf_record_mmap2 mmap2; - struct perf_record_comm comm; - struct perf_record_namespaces namespaces; - struct perf_record_fork fork; - struct perf_record_lost lost; - struct perf_record_lost_samples lost_samples; - struct perf_record_read read; - struct perf_record_throttle throttle; - struct perf_record_sample sample; - struct perf_record_bpf_event bpf; - struct perf_record_ksymbol ksymbol; - struct attr_event attr; - struct event_update_event event_update; - struct event_type_event event_type; - struct tracing_data_event tracing_data; - struct build_id_event build_id; - struct id_index_event id_index; - struct auxtrace_info_event auxtrace_info; - struct auxtrace_event auxtrace; - struct auxtrace_error_event auxtrace_error; - struct aux_event aux; - struct itrace_start_event itrace_start; - struct context_switch_event context_switch; - struct thread_map_event thread_map; - struct cpu_map_event cpu_map; - struct stat_config_event stat_config; - struct stat_event stat; - struct stat_round_event stat_round; - struct time_conv_event time_conv; - struct feature_event feat; - struct compressed_event pack; + struct perf_event_header header; + struct perf_record_mmap mmap; + struct perf_record_mmap2 mmap2; + struct perf_record_comm comm; + struct perf_record_namespaces namespaces; + struct perf_record_fork fork; + struct perf_record_lost lost; + struct perf_record_lost_samples lost_samples; + struct perf_record_read read; + struct perf_record_throttle throttle; + struct perf_record_sample sample; + struct perf_record_bpf_event bpf; + struct perf_record_ksymbol ksymbol; + struct perf_record_header_attr attr; + struct perf_record_event_update event_update; + struct perf_record_header_event_type event_type; + struct perf_record_header_tracing_data tracing_data; + struct perf_record_header_build_id build_id; + struct perf_record_id_index id_index; + struct perf_record_auxtrace_info auxtrace_info; + struct perf_record_auxtrace auxtrace; + struct perf_record_auxtrace_error auxtrace_error; + struct perf_record_aux aux; + struct perf_record_itrace_start itrace_start; + struct perf_record_switch context_switch; + struct perf_record_thread_map thread_map; + struct perf_record_cpu_map cpu_map; + struct perf_record_stat_config stat_config; + struct perf_record_stat stat; + struct perf_record_stat_round stat_round; + struct perf_record_time_conv time_conv; + struct perf_record_header_feature feat; + struct perf_record_compressed pack; }; #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index b71fe09a8087..39493de50117 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -15,9 +15,9 @@ static int process_event_mask(struct perf_tool *tool __maybe_unused, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused) { - struct cpu_map_event *map_event = &event->cpu_map; - struct cpu_map_mask *mask; - struct cpu_map_data *data; + struct perf_record_cpu_map *map_event = &event->cpu_map; + struct perf_record_record_cpu_map *mask; + struct perf_record_cpu_map_data *data; struct perf_cpu_map *map; int i; @@ -25,7 +25,7 @@ static int process_event_mask(struct perf_tool *tool __maybe_unused, TEST_ASSERT_VAL("wrong type", data->type == PERF_CPU_MAP__MASK); - mask = (struct cpu_map_mask *)data->data; + mask = (struct perf_record_record_cpu_map *)data->data; TEST_ASSERT_VAL("wrong nr", mask->nr == 1); @@ -49,9 +49,9 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused) { - struct cpu_map_event *map_event = &event->cpu_map; + struct perf_record_cpu_map *map_event = &event->cpu_map; struct cpu_map_entries *cpus; - struct cpu_map_data *data; + struct perf_record_cpu_map_data *data; struct perf_cpu_map *map; data = &map_event->data; diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index c37ff49c07c7..1411155597b8 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -12,7 +12,7 @@ static int process_event_unit(struct perf_tool *tool __maybe_unused, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused) { - struct event_update_event *ev = (struct event_update_event *) event; + struct perf_record_event_update *ev = (struct perf_record_event_update *)event; TEST_ASSERT_VAL("wrong id", ev->id == 123); TEST_ASSERT_VAL("wrong id", ev->type == PERF_EVENT_UPDATE__UNIT); @@ -25,10 +25,10 @@ static int process_event_scale(struct perf_tool *tool __maybe_unused, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused) { - struct event_update_event *ev = (struct event_update_event *) event; - struct event_update_event_scale *ev_data; + struct perf_record_event_update *ev = (struct perf_record_event_update *)event; + struct perf_record_event_update_scale *ev_data; - ev_data = (struct event_update_event_scale *) ev->data; + ev_data = (struct perf_record_event_update_scale *)ev->data; TEST_ASSERT_VAL("wrong id", ev->id == 123); TEST_ASSERT_VAL("wrong id", ev->type == PERF_EVENT_UPDATE__SCALE); @@ -47,7 +47,7 @@ static int process_event_name(struct perf_tool *tool, struct machine *machine __maybe_unused) { struct event_name *tmp = container_of(tool, struct event_name, tool); - struct event_update_event *ev = (struct event_update_event*) event; + struct perf_record_event_update *ev = (struct perf_record_event_update *)event; TEST_ASSERT_VAL("wrong id", ev->id == 123); TEST_ASSERT_VAL("wrong id", ev->type == PERF_EVENT_UPDATE__NAME); @@ -60,11 +60,11 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused) { - struct event_update_event *ev = (struct event_update_event*) event; - struct event_update_event_cpus *ev_data; + struct perf_record_event_update *ev = (struct perf_record_event_update *)event; + struct perf_record_event_update_cpus *ev_data; struct perf_cpu_map *map; - ev_data = (struct event_update_event_cpus*) ev->data; + ev_data = (struct perf_record_event_update_cpus *) ev->data; map = cpu_map__new_data(&ev_data->cpus); diff --git a/tools/perf/tests/stat.c b/tools/perf/tests/stat.c index 94250024684a..cc10b4116c9f 100644 --- a/tools/perf/tests/stat.c +++ b/tools/perf/tests/stat.c @@ -6,7 +6,7 @@ #include "counts.h" #include "debug.h" -static bool has_term(struct stat_config_event *config, +static bool has_term(struct perf_record_stat_config *config, u64 tag, u64 val) { unsigned i; @@ -25,7 +25,7 @@ static int process_stat_config_event(struct perf_tool *tool __maybe_unused, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused) { - struct stat_config_event *config = &event->stat_config; + struct perf_record_stat_config *config = &event->stat_config; struct perf_stat_config stat_config; #define HAS(term, val) \ @@ -65,7 +65,7 @@ static int process_stat_event(struct perf_tool *tool __maybe_unused, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused) { - struct stat_event *st = &event->stat; + struct perf_record_stat *st = &event->stat; TEST_ASSERT_VAL("wrong cpu", st->cpu == 1); TEST_ASSERT_VAL("wrong thread", st->thread == 2); @@ -95,7 +95,7 @@ static int process_stat_round_event(struct perf_tool *tool __maybe_unused, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused) { - struct stat_round_event *stat_round = &event->stat_round; + struct perf_record_stat_round *stat_round = &event->stat_round; TEST_ASSERT_VAL("wrong time", stat_round->time == 0xdeadbeef); TEST_ASSERT_VAL("wrong type", stat_round->type == PERF_STAT_ROUND_TYPE__INTERVAL); diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c index d803eafedc60..c19ec8849e77 100644 --- a/tools/perf/tests/thread-map.c +++ b/tools/perf/tests/thread-map.c @@ -56,7 +56,7 @@ static int process_event(struct perf_tool *tool __maybe_unused, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused) { - struct thread_map_event *map = &event->thread_map; + struct perf_record_thread_map *map = &event->thread_map; struct perf_thread_map *threads; TEST_ASSERT_VAL("wrong nr", map->nr == 1); diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c index cd26315bc9aa..d7c3fbb3694f 100644 --- a/tools/perf/util/arm-spe.c +++ b/tools/perf/util/arm-spe.c @@ -192,12 +192,12 @@ static void arm_spe_print_info(__u64 *arr) int arm_spe_process_auxtrace_info(union perf_event *event, struct perf_session *session) { - struct auxtrace_info_event *auxtrace_info = &event->auxtrace_info; + struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info; size_t min_sz = sizeof(u64) * ARM_SPE_PMU_TYPE; struct arm_spe *spe; int err; - if (auxtrace_info->header.size < sizeof(struct auxtrace_info_event) + + if (auxtrace_info->header.size < sizeof(struct perf_record_auxtrace_info) + min_sz) return -EINVAL; diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index c3da8a0e66b2..10c707724035 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -386,7 +386,7 @@ static int auxtrace_queues__add_indexed_event(struct auxtrace_queues *queues, return err; if (event->header.type == PERF_RECORD_AUXTRACE) { - if (event->header.size < sizeof(struct auxtrace_event) || + if (event->header.size < sizeof(struct perf_record_auxtrace) || event->header.size != sz) { err = -EINVAL; goto out; @@ -519,7 +519,7 @@ static int auxtrace_not_supported(void) int auxtrace_record__info_fill(struct auxtrace_record *itr, struct perf_session *session, - struct auxtrace_info_event *auxtrace_info, + struct perf_record_auxtrace_info *auxtrace_info, size_t priv_size) { if (itr) @@ -859,13 +859,13 @@ void auxtrace_buffer__free(struct auxtrace_buffer *buffer) free(buffer); } -void auxtrace_synth_error(struct auxtrace_error_event *auxtrace_error, int type, +void auxtrace_synth_error(struct perf_record_auxtrace_error *auxtrace_error, int type, int code, int cpu, pid_t pid, pid_t tid, u64 ip, const char *msg, u64 timestamp) { size_t size; - memset(auxtrace_error, 0, sizeof(struct auxtrace_error_event)); + memset(auxtrace_error, 0, sizeof(struct perf_record_auxtrace_error)); auxtrace_error->header.type = PERF_RECORD_AUXTRACE_ERROR; auxtrace_error->type = type; @@ -894,12 +894,12 @@ int perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr, pr_debug2("Synthesizing auxtrace information\n"); priv_size = auxtrace_record__info_priv_size(itr, session->evlist); - ev = zalloc(sizeof(struct auxtrace_info_event) + priv_size); + ev = zalloc(sizeof(struct perf_record_auxtrace_info) + priv_size); if (!ev) return -ENOMEM; ev->auxtrace_info.header.type = PERF_RECORD_AUXTRACE_INFO; - ev->auxtrace_info.header.size = sizeof(struct auxtrace_info_event) + + ev->auxtrace_info.header.size = sizeof(struct perf_record_auxtrace_info) + priv_size; err = auxtrace_record__info_fill(itr, session, &ev->auxtrace_info, priv_size); @@ -1169,7 +1169,7 @@ static const char *auxtrace_error_name(int type) size_t perf_event__fprintf_auxtrace_error(union perf_event *event, FILE *fp) { - struct auxtrace_error_event *e = &event->auxtrace_error; + struct perf_record_auxtrace_error *e = &event->auxtrace_error; unsigned long long nsecs = e->time; const char *msg = e->msg; int ret; @@ -1197,7 +1197,7 @@ size_t perf_event__fprintf_auxtrace_error(union perf_event *event, FILE *fp) void perf_session__auxtrace_error_inc(struct perf_session *session, union perf_event *event) { - struct auxtrace_error_event *e = &event->auxtrace_error; + struct perf_record_auxtrace_error *e = &event->auxtrace_error; if (e->type < PERF_AUXTRACE_ERROR_MAX) session->evlist->stats.nr_auxtrace_errors[e->type] += 1; diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index 8e637ac3918e..b213e6431d88 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -28,7 +28,7 @@ struct perf_tool; struct perf_mmap; struct option; struct record_opts; -struct auxtrace_info_event; +struct perf_record_auxtrace_info; struct events_stats; /* Auxtrace records must have the same alignment as perf event records */ @@ -318,7 +318,7 @@ struct auxtrace_record { struct evlist *evlist); int (*info_fill)(struct auxtrace_record *itr, struct perf_session *session, - struct auxtrace_info_event *auxtrace_info, + struct perf_record_auxtrace_info *auxtrace_info, size_t priv_size); void (*free)(struct auxtrace_record *itr); int (*snapshot_start)(struct auxtrace_record *itr); @@ -498,7 +498,7 @@ size_t auxtrace_record__info_priv_size(struct auxtrace_record *itr, struct evlist *evlist); int auxtrace_record__info_fill(struct auxtrace_record *itr, struct perf_session *session, - struct auxtrace_info_event *auxtrace_info, + struct perf_record_auxtrace_info *auxtrace_info, size_t priv_size); void auxtrace_record__free(struct auxtrace_record *itr); int auxtrace_record__snapshot_start(struct auxtrace_record *itr); @@ -515,7 +515,7 @@ int auxtrace_index__process(int fd, u64 size, struct perf_session *session, bool needs_swap); void auxtrace_index__free(struct list_head *head); -void auxtrace_synth_error(struct auxtrace_error_event *auxtrace_error, int type, +void auxtrace_synth_error(struct perf_record_auxtrace_error *auxtrace_error, int type, int code, int cpu, pid_t pid, pid_t tid, u64 ip, const char *msg, u64 timestamp); diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index b98754863de9..4c96a33b09ff 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -295,7 +295,7 @@ static int write_buildid(const char *name, size_t name_len, u8 *build_id, pid_t pid, u16 misc, struct feat_fd *fd) { int err; - struct build_id_event b; + struct perf_record_header_build_id b; size_t len; len = name_len + 1; diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index f5c21184e1fc..b9301e7e9c76 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -43,7 +43,7 @@ static struct perf_cpu_map *cpu_map__from_entries(struct cpu_map_entries *cpus) return map; } -static struct perf_cpu_map *cpu_map__from_mask(struct cpu_map_mask *mask) +static struct perf_cpu_map *cpu_map__from_mask(struct perf_record_record_cpu_map *mask) { struct perf_cpu_map *map; int nr, nbits = mask->nr * mask->long_size * BITS_PER_BYTE; @@ -61,12 +61,12 @@ static struct perf_cpu_map *cpu_map__from_mask(struct cpu_map_mask *mask) } -struct perf_cpu_map *cpu_map__new_data(struct cpu_map_data *data) +struct perf_cpu_map *cpu_map__new_data(struct perf_record_cpu_map_data *data) { if (data->type == PERF_CPU_MAP__CPUS) return cpu_map__from_entries((struct cpu_map_entries *)data->data); else - return cpu_map__from_mask((struct cpu_map_mask *)data->data); + return cpu_map__from_mask((struct perf_record_record_cpu_map *)data->data); } size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp) diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index c2519e7ea958..2553bef1279d 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -7,10 +7,10 @@ #include #include -struct cpu_map_data; +struct perf_record_cpu_map_data; struct perf_cpu_map *perf_cpu_map__empty_new(int nr); -struct perf_cpu_map *cpu_map__new_data(struct cpu_map_data *data); +struct perf_cpu_map *cpu_map__new_data(struct perf_record_cpu_map_data *data); size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size); size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size); size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp); diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index e210c1dde964..d6de3834865e 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -2393,7 +2393,7 @@ static void cs_etm__print_auxtrace_info(__u64 *val, int num) int cs_etm__process_auxtrace_info(union perf_event *event, struct perf_session *session) { - struct auxtrace_info_event *auxtrace_info = &event->auxtrace_info; + struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info; struct cs_etm_auxtrace *etm = NULL; struct int_node *inode; unsigned int pmu_type; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index b711019a9ed2..c9d1f83c747a 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -992,7 +992,7 @@ int perf_event__synthesize_thread_map2(struct perf_tool *tool, event->thread_map.nr = threads->nr; for (i = 0; i < threads->nr; i++) { - struct thread_map_event_entry *entry = &event->thread_map.entries[i]; + struct perf_record_thread_map_entry *entry = &event->thread_map.entries[i]; char *comm = perf_thread_map__comm(threads, i); if (!comm) @@ -1019,7 +1019,7 @@ static void synthesize_cpus(struct cpu_map_entries *cpus, cpus->cpu[i] = map->map[i]; } -static void synthesize_mask(struct cpu_map_mask *mask, +static void synthesize_mask(struct perf_record_record_cpu_map *mask, struct perf_cpu_map *map, int max) { int i; @@ -1050,7 +1050,7 @@ static size_t mask_size(struct perf_cpu_map *map, int *max) *max = bit; } - return sizeof(struct cpu_map_mask) + BITS_TO_LONGS(*max) * sizeof(long); + return sizeof(struct perf_record_record_cpu_map) + BITS_TO_LONGS(*max) * sizeof(long); } void *cpu_map_data__alloc(struct perf_cpu_map *map, size_t *size, u16 *type, int *max) @@ -1061,15 +1061,15 @@ void *cpu_map_data__alloc(struct perf_cpu_map *map, size_t *size, u16 *type, int /* * Both array and mask data have variable size based * on the number of cpus and their actual values. - * The size of the 'struct cpu_map_data' is: + * The size of the 'struct perf_record_cpu_map_data' is: * * array = size of 'struct cpu_map_entries' + * number of cpus * sizeof(u64) * - * mask = size of 'struct cpu_map_mask' + + * mask = size of 'struct perf_record_record_cpu_map' + * maximum cpu bit converted to size of longs * - * and finaly + the size of 'struct cpu_map_data'. + * and finaly + the size of 'struct perf_record_cpu_map_data'. */ size_cpus = cpus_size(map); size_mask = mask_size(map, max); @@ -1082,12 +1082,12 @@ void *cpu_map_data__alloc(struct perf_cpu_map *map, size_t *size, u16 *type, int *type = PERF_CPU_MAP__MASK; } - *size += sizeof(struct cpu_map_data); + *size += sizeof(struct perf_record_cpu_map_data); *size = PERF_ALIGN(*size, sizeof(u64)); return zalloc(*size); } -void cpu_map_data__synthesize(struct cpu_map_data *data, struct perf_cpu_map *map, +void cpu_map_data__synthesize(struct perf_record_cpu_map_data *data, struct perf_cpu_map *map, u16 type, int max) { data->type = type; @@ -1097,16 +1097,16 @@ void cpu_map_data__synthesize(struct cpu_map_data *data, struct perf_cpu_map *ma synthesize_cpus((struct cpu_map_entries *) data->data, map); break; case PERF_CPU_MAP__MASK: - synthesize_mask((struct cpu_map_mask *) data->data, map, max); + synthesize_mask((struct perf_record_record_cpu_map *)data->data, map, max); default: break; }; } -static struct cpu_map_event* cpu_map_event__new(struct perf_cpu_map *map) +static struct perf_record_cpu_map *cpu_map_event__new(struct perf_cpu_map *map) { - size_t size = sizeof(struct cpu_map_event); - struct cpu_map_event *event; + size_t size = sizeof(struct perf_record_cpu_map); + struct perf_record_cpu_map *event; int max; u16 type; @@ -1127,7 +1127,7 @@ int perf_event__synthesize_cpu_map(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine) { - struct cpu_map_event *event; + struct perf_record_cpu_map *event; int err; event = cpu_map_event__new(map); @@ -1145,7 +1145,7 @@ int perf_event__synthesize_stat_config(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine) { - struct stat_config_event *event; + struct perf_record_stat_config *event; int size, i = 0, err; size = sizeof(*event); @@ -1184,7 +1184,7 @@ int perf_event__synthesize_stat(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine) { - struct stat_event event; + struct perf_record_stat event; event.header.type = PERF_RECORD_STAT; event.header.size = sizeof(event); @@ -1205,7 +1205,7 @@ int perf_event__synthesize_stat_round(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine) { - struct stat_round_event event; + struct perf_record_stat_round event; event.header.type = PERF_RECORD_STAT_ROUND; event.header.size = sizeof(event); @@ -1218,7 +1218,7 @@ int perf_event__synthesize_stat_round(struct perf_tool *tool, } void perf_event__read_stat_config(struct perf_stat_config *config, - struct stat_config_event *event) + struct perf_record_stat_config *event) { unsigned i; diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index e15eed53ce90..a7341e14eb48 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -374,7 +374,7 @@ int perf_event__synthesize_stat_config(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine); void perf_event__read_stat_config(struct perf_stat_config *config, - struct stat_config_event *event); + struct perf_record_stat_config *event); int perf_event__synthesize_stat(struct perf_tool *tool, u32 cpu, u32 thread, u64 id, struct perf_counts_values *count, @@ -511,7 +511,7 @@ int kallsyms__get_function_start(const char *kallsyms_filename, const char *symbol_name, u64 *addr); void *cpu_map_data__alloc(struct perf_cpu_map *map, size_t *size, u16 *type, int *max); -void cpu_map_data__synthesize(struct cpu_map_data *data, struct perf_cpu_map *map, +void cpu_map_data__synthesize(struct perf_record_cpu_map_data *data, struct perf_cpu_map *map, u16 type, int max); void event_attr_init(struct perf_event_attr *attr); diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 629bdb150cb9..0a842d9eff22 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1878,7 +1878,7 @@ static void print_mem_topology(struct feat_fd *ff, FILE *fp) } } -static int __event_process_build_id(struct build_id_event *bev, +static int __event_process_build_id(struct perf_record_header_build_id *bev, char *filename, struct perf_session *session) { @@ -1947,7 +1947,7 @@ static int perf_header__read_build_ids_abi_quirk(struct perf_header *header, u8 build_id[PERF_ALIGN(BUILD_ID_SIZE, sizeof(u64))]; char filename[0]; } old_bev; - struct build_id_event bev; + struct perf_record_header_build_id bev; char filename[PATH_MAX]; u64 limit = offset + size; @@ -1988,7 +1988,7 @@ static int perf_header__read_build_ids(struct perf_header *header, int input, u64 offset, u64 size) { struct perf_session *session = container_of(header, struct perf_session, header); - struct build_id_event bev; + struct perf_record_header_build_id bev; char filename[PATH_MAX]; u64 limit = offset + size, orig_offset = offset; int err = -1; @@ -2010,7 +2010,7 @@ static int perf_header__read_build_ids(struct perf_header *header, * * "perf: 'perf kvm' tool for monitoring guest performance from host" * - * Added a field to struct build_id_event that broke the file + * Added a field to struct perf_record_header_build_id that broke the file * format. * * Since the kernel build-id is the first entry, process the @@ -3678,7 +3678,7 @@ int perf_event__synthesize_features(struct perf_tool *tool, { struct perf_header *header = &session->header; struct feat_fd ff; - struct feature_event *fe; + struct perf_record_header_feature *fe; size_t sz, sz_hdr; int feat, ret; @@ -3741,7 +3741,7 @@ int perf_event__process_feature(struct perf_session *session, { struct perf_tool *tool = session->tool; struct feat_fd ff = { .fd = 0 }; - struct feature_event *fe = (struct feature_event *)event; + struct perf_record_header_feature *fe = (struct perf_record_header_feature *)event; int type = fe->header.type; u64 feat = fe->feat_id; @@ -3778,10 +3778,10 @@ int perf_event__process_feature(struct perf_session *session, return 0; } -static struct event_update_event * +static struct perf_record_event_update * event_update_event__new(size_t size, u64 type, u64 id) { - struct event_update_event *ev; + struct perf_record_event_update *ev; size += sizeof(*ev); size = PERF_ALIGN(size, sizeof(u64)); @@ -3801,7 +3801,7 @@ perf_event__synthesize_event_update_unit(struct perf_tool *tool, struct evsel *evsel, perf_event__handler_t process) { - struct event_update_event *ev; + struct perf_record_event_update *ev; size_t size = strlen(evsel->unit); int err; @@ -3820,15 +3820,15 @@ perf_event__synthesize_event_update_scale(struct perf_tool *tool, struct evsel *evsel, perf_event__handler_t process) { - struct event_update_event *ev; - struct event_update_event_scale *ev_data; + struct perf_record_event_update *ev; + struct perf_record_event_update_scale *ev_data; int err; ev = event_update_event__new(sizeof(*ev_data), PERF_EVENT_UPDATE__SCALE, evsel->id[0]); if (ev == NULL) return -ENOMEM; - ev_data = (struct event_update_event_scale *) ev->data; + ev_data = (struct perf_record_event_update_scale *)ev->data; ev_data->scale = evsel->scale; err = process(tool, (union perf_event*) ev, NULL, NULL); free(ev); @@ -3840,7 +3840,7 @@ perf_event__synthesize_event_update_name(struct perf_tool *tool, struct evsel *evsel, perf_event__handler_t process) { - struct event_update_event *ev; + struct perf_record_event_update *ev; size_t len = strlen(evsel->name); int err; @@ -3859,8 +3859,8 @@ perf_event__synthesize_event_update_cpus(struct perf_tool *tool, struct evsel *evsel, perf_event__handler_t process) { - size_t size = sizeof(struct event_update_event); - struct event_update_event *ev; + size_t size = sizeof(struct perf_record_event_update); + struct perf_record_event_update *ev; int max, err; u16 type; @@ -3876,7 +3876,7 @@ perf_event__synthesize_event_update_cpus(struct perf_tool *tool, ev->type = PERF_EVENT_UPDATE__CPUS; ev->id = evsel->id[0]; - cpu_map_data__synthesize((struct cpu_map_data *) ev->data, + cpu_map_data__synthesize((struct perf_record_cpu_map_data *)ev->data, evsel->core.own_cpus, type, max); @@ -3887,9 +3887,9 @@ perf_event__synthesize_event_update_cpus(struct perf_tool *tool, size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp) { - struct event_update_event *ev = &event->event_update; - struct event_update_event_scale *ev_scale; - struct event_update_event_cpus *ev_cpus; + struct perf_record_event_update *ev = &event->event_update; + struct perf_record_event_update_scale *ev_scale; + struct perf_record_event_update_cpus *ev_cpus; struct perf_cpu_map *map; size_t ret; @@ -3897,7 +3897,7 @@ size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp) switch (ev->type) { case PERF_EVENT_UPDATE__SCALE: - ev_scale = (struct event_update_event_scale *) ev->data; + ev_scale = (struct perf_record_event_update_scale *)ev->data; ret += fprintf(fp, "... scale: %f\n", ev_scale->scale); break; case PERF_EVENT_UPDATE__UNIT: @@ -3907,7 +3907,7 @@ size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp) ret += fprintf(fp, "... name: %s\n", ev->data); break; case PERF_EVENT_UPDATE__CPUS: - ev_cpus = (struct event_update_event_cpus *) ev->data; + ev_cpus = (struct perf_record_event_update_cpus *)ev->data; ret += fprintf(fp, "... "); map = cpu_map__new_data(&ev_cpus->cpus); @@ -4053,9 +4053,9 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused, union perf_event *event, struct evlist **pevlist) { - struct event_update_event *ev = &event->event_update; - struct event_update_event_scale *ev_scale; - struct event_update_event_cpus *ev_cpus; + struct perf_record_event_update *ev = &event->event_update; + struct perf_record_event_update_scale *ev_scale; + struct perf_record_event_update_cpus *ev_cpus; struct evlist *evlist; struct evsel *evsel; struct perf_cpu_map *map; @@ -4077,11 +4077,11 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused, evsel->name = strdup(ev->data); break; case PERF_EVENT_UPDATE__SCALE: - ev_scale = (struct event_update_event_scale *) ev->data; + ev_scale = (struct perf_record_event_update_scale *)ev->data; evsel->scale = ev_scale->scale; break; case PERF_EVENT_UPDATE__CPUS: - ev_cpus = (struct event_update_event_cpus *) ev->data; + ev_cpus = (struct perf_record_event_update_cpus *)ev->data; map = cpu_map__new_data(&ev_cpus->cpus); if (map) @@ -4153,7 +4153,7 @@ int perf_event__process_tracing_data(struct perf_session *session, char buf[BUFSIZ]; /* setup for reading amidst mmap */ - lseek(fd, offset + sizeof(struct tracing_data_event), + lseek(fd, offset + sizeof(struct perf_record_header_tracing_data), SEEK_SET); size_read = trace_report(fd, &session->tevent, diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index 03c581a0d5d0..99dddb63dac1 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c @@ -848,12 +848,12 @@ static void intel_bts_print_info(__u64 *arr, int start, int finish) int intel_bts_process_auxtrace_info(union perf_event *event, struct perf_session *session) { - struct auxtrace_info_event *auxtrace_info = &event->auxtrace_info; + struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info; size_t min_sz = sizeof(u64) * INTEL_BTS_SNAPSHOT_MODE; struct intel_bts *bts; int err; - if (auxtrace_info->header.size < sizeof(struct auxtrace_info_event) + + if (auxtrace_info->header.size < sizeof(struct perf_record_auxtrace_info) + min_sz) return -EINVAL; diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index c83a9a718c03..825a6a3b03a1 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -3063,23 +3063,23 @@ static void intel_pt_print_info_str(const char *name, const char *str) fprintf(stdout, " %-20s%s\n", name, str ? str : ""); } -static bool intel_pt_has(struct auxtrace_info_event *auxtrace_info, int pos) +static bool intel_pt_has(struct perf_record_auxtrace_info *auxtrace_info, int pos) { return auxtrace_info->header.size >= - sizeof(struct auxtrace_info_event) + (sizeof(u64) * (pos + 1)); + sizeof(struct perf_record_auxtrace_info) + (sizeof(u64) * (pos + 1)); } int intel_pt_process_auxtrace_info(union perf_event *event, struct perf_session *session) { - struct auxtrace_info_event *auxtrace_info = &event->auxtrace_info; + struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info; size_t min_sz = sizeof(u64) * INTEL_PT_PER_CPU_MMAPS; struct intel_pt *pt; void *info_end; __u64 *info; int err; - if (auxtrace_info->header.size < sizeof(struct auxtrace_info_event) + + if (auxtrace_info->header.size < sizeof(struct perf_record_auxtrace_info) + min_sz) return -EINVAL; diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 59974e901232..11479a7ad1c7 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -431,8 +431,8 @@ static char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch ev static PyMemberDef pyrf_context_switch_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), - member_def(context_switch_event, next_prev_pid, T_UINT, "next/prev pid"), - member_def(context_switch_event, next_prev_tid, T_UINT, "next/prev tid"), + member_def(perf_record_switch, next_prev_pid, T_UINT, "next/prev pid"), + member_def(perf_record_switch, next_prev_tid, T_UINT, "next/prev tid"), { .name = NULL, }, }; diff --git a/tools/perf/util/s390-cpumsf.c b/tools/perf/util/s390-cpumsf.c index d078ae8353c8..4f6c1465998f 100644 --- a/tools/perf/util/s390-cpumsf.c +++ b/tools/perf/util/s390-cpumsf.c @@ -1109,11 +1109,11 @@ static int s390_cpumsf__config(const char *var, const char *value, void *cb) int s390_cpumsf_process_auxtrace_info(union perf_event *event, struct perf_session *session) { - struct auxtrace_info_event *auxtrace_info = &event->auxtrace_info; + struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info; struct s390_cpumsf *sf; int err; - if (auxtrace_info->header.size < sizeof(struct auxtrace_info_event)) + if (auxtrace_info->header.size < sizeof(struct perf_record_auxtrace_info)) return -EINVAL; sf = zalloc(sizeof(struct s390_cpumsf)); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index aa9667424c1c..7350b0dfbc1e 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -64,8 +64,8 @@ static int perf_session__process_compressed_event(struct perf_session *session, decomp->size = decomp_last_rem; } - src = (void *)event + sizeof(struct compressed_event); - src_size = event->pack.header.size - sizeof(struct compressed_event); + src = (void *)event + sizeof(struct perf_record_compressed); + src_size = event->pack.header.size - sizeof(struct perf_record_compressed); decomp_size = zstd_decompress_stream(&(session->zstd_data), src, src_size, &(decomp->data[decomp_last_rem]), decomp_len - decomp_last_rem); @@ -836,9 +836,9 @@ static void perf_event__thread_map_swap(union perf_event *event, static void perf_event__cpu_map_swap(union perf_event *event, bool sample_id_all __maybe_unused) { - struct cpu_map_data *data = &event->cpu_map.data; + struct perf_record_cpu_map_data *data = &event->cpu_map.data; struct cpu_map_entries *cpus; - struct cpu_map_mask *mask; + struct perf_record_record_cpu_map *mask; unsigned i; data->type = bswap_64(data->type); @@ -853,7 +853,7 @@ static void perf_event__cpu_map_swap(union perf_event *event, cpus->cpu[i] = bswap_16(cpus->cpu[i]); break; case PERF_CPU_MAP__MASK: - mask = (struct cpu_map_mask *) data->data; + mask = (struct perf_record_record_cpu_map *)data->data; mask->nr = bswap_16(mask->nr); mask->long_size = bswap_16(mask->long_size); @@ -2376,10 +2376,10 @@ int perf_event__process_id_index(struct perf_session *session, union perf_event *event) { struct evlist *evlist = session->evlist; - struct id_index_event *ie = &event->id_index; + struct perf_record_id_index *ie = &event->id_index; size_t i, nr, max_nr; - max_nr = (ie->header.size - sizeof(struct id_index_event)) / + max_nr = (ie->header.size - sizeof(struct perf_record_id_index)) / sizeof(struct id_index_entry); nr = ie->nr; if (nr > max_nr) @@ -2421,14 +2421,14 @@ int perf_event__synthesize_id_index(struct perf_tool *tool, pr_debug2("Synthesizing id index\n"); - max_nr = (UINT16_MAX - sizeof(struct id_index_event)) / + max_nr = (UINT16_MAX - sizeof(struct perf_record_id_index)) / sizeof(struct id_index_entry); evlist__for_each_entry(evlist, evsel) nr += evsel->ids; n = nr > max_nr ? max_nr : nr; - sz = sizeof(struct id_index_event) + n * sizeof(struct id_index_entry); + sz = sizeof(struct perf_record_id_index) + n * sizeof(struct id_index_entry); ev = zalloc(sz); if (!ev) return -ENOMEM; @@ -2468,7 +2468,7 @@ int perf_event__synthesize_id_index(struct perf_tool *tool, } } - sz = sizeof(struct id_index_event) + nr * sizeof(struct id_index_entry); + sz = sizeof(struct perf_record_id_index) + nr * sizeof(struct id_index_entry); ev->id_index.header.size = sz; ev->id_index.nr = nr; diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 79e97d17ea04..b7aa076ab6fd 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -28,7 +28,7 @@ struct perf_session { struct itrace_synth_opts *itrace_synth_opts; struct list_head auxtrace_index; struct trace_event tevent; - struct time_conv_event time_conv; + struct perf_record_time_conv time_conv; bool repipe; bool one_mmap; void *one_mmap_addr; diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 4c7957496e7c..66f8808e57d3 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -382,7 +382,7 @@ int perf_event__process_stat_event(struct perf_session *session, union perf_event *event) { struct perf_counts_values count; - struct stat_event *st = &event->stat; + struct perf_record_stat *st = &event->stat; struct evsel *counter; count.val = st->val; @@ -402,7 +402,7 @@ int perf_event__process_stat_event(struct perf_session *session, size_t perf_event__fprintf_stat(union perf_event *event, FILE *fp) { - struct stat_event *st = (struct stat_event *) event; + struct perf_record_stat *st = (struct perf_record_stat *)event; size_t ret; ret = fprintf(fp, "\n... id %" PRI_lu64 ", cpu %d, thread %d\n", @@ -415,7 +415,7 @@ size_t perf_event__fprintf_stat(union perf_event *event, FILE *fp) size_t perf_event__fprintf_stat_round(union perf_event *event, FILE *fp) { - struct stat_round_event *rd = (struct stat_round_event *)event; + struct perf_record_stat_round *rd = (struct perf_record_stat_round *)event; size_t ret; ret = fprintf(fp, "\n... time %" PRI_lu64 ", type %s\n", rd->time, diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index 3e64525bf604..c9bfe4696943 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c @@ -369,7 +369,7 @@ void thread_map__read_comms(struct perf_thread_map *threads) } static void thread_map__copy_event(struct perf_thread_map *threads, - struct thread_map_event *event) + struct perf_record_thread_map *event) { unsigned i; @@ -383,7 +383,7 @@ static void thread_map__copy_event(struct perf_thread_map *threads, refcount_set(&threads->refcnt, 1); } -struct perf_thread_map *thread_map__new_event(struct thread_map_event *event) +struct perf_thread_map *thread_map__new_event(struct perf_record_thread_map *event) { struct perf_thread_map *threads; diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h index ca165fdf6cb0..3bb860a32b8e 100644 --- a/tools/perf/util/thread_map.h +++ b/tools/perf/util/thread_map.h @@ -8,7 +8,7 @@ #include #include -struct thread_map_event; +struct perf_record_thread_map; struct perf_thread_map *thread_map__new_dummy(void); struct perf_thread_map *thread_map__new_by_pid(pid_t pid); @@ -16,7 +16,7 @@ struct perf_thread_map *thread_map__new_by_tid(pid_t tid); struct perf_thread_map *thread_map__new_by_uid(uid_t uid); struct perf_thread_map *thread_map__new_all_cpus(void); struct perf_thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid); -struct perf_thread_map *thread_map__new_event(struct thread_map_event *event); +struct perf_thread_map *thread_map__new_event(struct perf_record_thread_map *event); struct perf_thread_map *thread_map__new_str(const char *pid, const char *tid, uid_t uid, bool all_threads); -- cgit v1.2.3-59-g8ed1b From 653dd8e6e8e46591f864b7ad98e10819079d5a88 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Aug 2019 15:57:17 +0200 Subject: libperf: Move 'enum perf_user_event_type' to perf/event.h So it's available for libperf's users. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20190828135717.7245-24-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/perf/event.h | 23 +++++++++++++++++++++++ tools/perf/util/event.h | 23 ----------------------- 2 files changed, 23 insertions(+), 23 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h index 1655c744ec2b..18106899cb4e 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/perf/lib/include/perf/event.h @@ -323,6 +323,29 @@ struct perf_record_compressed { char data[]; }; +enum perf_user_event_type { /* above any possible kernel type */ + PERF_RECORD_USER_TYPE_START = 64, + PERF_RECORD_HEADER_ATTR = 64, + PERF_RECORD_HEADER_EVENT_TYPE = 65, /* deprecated */ + PERF_RECORD_HEADER_TRACING_DATA = 66, + PERF_RECORD_HEADER_BUILD_ID = 67, + PERF_RECORD_FINISHED_ROUND = 68, + PERF_RECORD_ID_INDEX = 69, + PERF_RECORD_AUXTRACE_INFO = 70, + PERF_RECORD_AUXTRACE = 71, + PERF_RECORD_AUXTRACE_ERROR = 72, + PERF_RECORD_THREAD_MAP = 73, + PERF_RECORD_CPU_MAP = 74, + PERF_RECORD_STAT_CONFIG = 75, + PERF_RECORD_STAT = 76, + PERF_RECORD_STAT_ROUND = 77, + PERF_RECORD_EVENT_UPDATE = 78, + PERF_RECORD_TIME_CONV = 79, + PERF_RECORD_HEADER_FEATURE = 80, + PERF_RECORD_COMPRESSED = 81, + PERF_RECORD_HEADER_MAX +}; + union perf_event { struct perf_event_header header; struct perf_record_mmap mmap; diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index a7341e14eb48..4c0c5232bd41 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -146,29 +146,6 @@ struct perf_sample { PERF_MEM_S(LOCK, NA) |\ PERF_MEM_S(TLB, NA)) -enum perf_user_event_type { /* above any possible kernel type */ - PERF_RECORD_USER_TYPE_START = 64, - PERF_RECORD_HEADER_ATTR = 64, - PERF_RECORD_HEADER_EVENT_TYPE = 65, /* deprecated */ - PERF_RECORD_HEADER_TRACING_DATA = 66, - PERF_RECORD_HEADER_BUILD_ID = 67, - PERF_RECORD_FINISHED_ROUND = 68, - PERF_RECORD_ID_INDEX = 69, - PERF_RECORD_AUXTRACE_INFO = 70, - PERF_RECORD_AUXTRACE = 71, - PERF_RECORD_AUXTRACE_ERROR = 72, - PERF_RECORD_THREAD_MAP = 73, - PERF_RECORD_CPU_MAP = 74, - PERF_RECORD_STAT_CONFIG = 75, - PERF_RECORD_STAT = 76, - PERF_RECORD_STAT_ROUND = 77, - PERF_RECORD_EVENT_UPDATE = 78, - PERF_RECORD_TIME_CONV = 79, - PERF_RECORD_HEADER_FEATURE = 80, - PERF_RECORD_COMPRESSED = 81, - PERF_RECORD_HEADER_MAX -}; - enum auxtrace_error_type { PERF_AUXTRACE_ERROR_ITRACE = 1, PERF_AUXTRACE_ERROR_MAX -- cgit v1.2.3-59-g8ed1b From b397f8468fa27f08b83b348ffa56a226f72453af Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 28 Aug 2019 16:48:50 -0300 Subject: perf evlist: Use unshare(CLONE_FS) in sb threads to let setns(CLONE_NEWNS) work When we started using a thread to catch the PERF_RECORD_BPF_EVENT meta data events to then ask the kernel for further info (BTF, etc) for BPF programs shortly after they get loaded, we forgot to use unshare(CLONE_FS) as was done in: 868a832918f6 ("perf top: Support lookup of symbols in other mount namespaces.") Do it so that we can enter the namespaces to read the build-ids at the end of a 'perf record' session for the DSOs that had hits. Before: Starting a 'stress-ng --cpus 8' inside a container and then, outside the container running: # perf record -a --namespaces sleep 5 # perf buildid-list | grep stress-ng # We would end up with a 'perf.data' file that had no entry in its build-id table for the /usr/bin/stress-ng binary inside the container that got tons of PERF_RECORD_SAMPLEs. After: # perf buildid-list | grep stress-ng f2ed02c68341183a124b9b0f6e2e6c493c465b29 /usr/bin/stress-ng # Then its just a matter of making sure that that binary debuginfo package gets available in a place that 'perf report' will look at build-id keyed ELF files, which, in my case, on a f30 notebook, was a matter of installing the debuginfo file for the distro used in the container, fedora 31: # rpm -ivh http://fedora.c3sl.ufpr.br/linux/development/31/Everything/x86_64/debug/tree/Packages/s/stress-ng-debuginfo-0.07.29-10.fc31.x86_64.rpm Then, because perf currently looks for those debuginfo files (richer ELF symtab) inside that namespace (look at the setns calls): openat(AT_FDCWD, "/proc/self/ns/mnt", O_RDONLY) = 137 openat(AT_FDCWD, "/proc/13169/ns/mnt", O_RDONLY) = 139 setns(139, CLONE_NEWNS) = 0 stat("/usr/bin/stress-ng", {st_mode=S_IFREG|0755, st_size=3065416, ...}) = 0 openat(AT_FDCWD, "/usr/bin/stress-ng", O_RDONLY) = 140 fcntl(140, F_GETFD) = 0 fstat(140, {st_mode=S_IFREG|0755, st_size=3065416, ...}) = 0 mmap(NULL, 3065416, PROT_READ, MAP_PRIVATE, 140, 0) = 0x7ff2fdc5b000 munmap(0x7ff2fdc5b000, 3065416) = 0 close(140) = 0 stat("stress-ng-0.07.29-10.fc31.x86_64.debug", 0x7fff45d71260) = -1 ENOENT (No such file or directory) stat("/usr/bin/stress-ng-0.07.29-10.fc31.x86_64.debug", 0x7fff45d71260) = -1 ENOENT (No such file or directory) stat("/usr/bin/.debug/stress-ng-0.07.29-10.fc31.x86_64.debug", 0x7fff45d71260) = -1 ENOENT (No such file or directory) stat("/usr/lib/debug/usr/bin/stress-ng-0.07.29-10.fc31.x86_64.debug", 0x7fff45d71260) = -1 ENOENT (No such file or directory) stat("/root/.debug/.build-id/f2/ed02c68341183a124b9b0f6e2e6c493c465b29", 0x7fff45d711e0) = -1 ENOENT (No such file or directory) To only then go back to the "host" namespace to look just in the users's ~/.debug cache: setns(137, CLONE_NEWNS) = 0 chdir("/root") = 0 close(137) = 0 close(139) = 0 stat("/root/.debug/.build-id/f2/ed02c68341183a124b9b0f6e2e6c493c465b29/elf", 0x7fff45d732e0) = -1 ENOENT (No such file or directory) It continues to fail to resolve symbols: # perf report | grep stress-ng | head -5 9.50% stress-ng-cpu stress-ng [.] 0x0000000000021ac1 8.58% stress-ng-cpu stress-ng [.] 0x0000000000021ab4 8.51% stress-ng-cpu stress-ng [.] 0x0000000000021489 7.17% stress-ng-cpu stress-ng [.] 0x00000000000219b6 3.93% stress-ng-cpu stress-ng [.] 0x0000000000021478 # To overcome that we use: # perf buildid-cache -v --add /usr/lib/debug/usr/bin/stress-ng-0.07.29-10.fc31.x86_64.debug Adding f2ed02c68341183a124b9b0f6e2e6c493c465b29 /usr/lib/debug/usr/bin/stress-ng-0.07.29-10.fc31.x86_64.debug: Ok # # ls -la /root/.debug/.build-id/f2/ed02c68341183a124b9b0f6e2e6c493c465b29/elf -rw-r--r--. 3 root root 2401184 Jul 27 07:03 /root/.debug/.build-id/f2/ed02c68341183a124b9b0f6e2e6c493c465b29/elf # file /root/.debug/.build-id/f2/ed02c68341183a124b9b0f6e2e6c493c465b29/elf /root/.debug/.build-id/f2/ed02c68341183a124b9b0f6e2e6c493c465b29/elf: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter \004, BuildID[sha1]=f2ed02c68341183a124b9b0f6e2e6c493c465b29, for GNU/Linux 3.2.0, with debug_info, not stripped, too many notes (256) # Now it finally works: # perf report | grep stress-ng | head -5 23.59% stress-ng-cpu stress-ng [.] ackermann 23.33% stress-ng-cpu stress-ng [.] is_prime 17.36% stress-ng-cpu stress-ng [.] stress_cpu_sieve 6.08% stress-ng-cpu stress-ng [.] stress_cpu_correlate 3.55% stress-ng-cpu stress-ng [.] queens_try # I'll make sure that it looks for the build-id keyed files in both the "host" namespace (the namespace the user running 'perf record' was a the time of the recording) and in the container namespace, as it shouldn't matter where a content based key lookup finds the ELF file to use in resolving symbols, etc. Reported-by: Karl Rister Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Brendan Gregg Cc: Daniel Borkmann Cc: Krister Johansen Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Song Liu Cc: Stanislav Fomichev Cc: Thomas-Mich Richter Fixes: 657ee5531903 ("perf evlist: Introduce side band thread") Link: https://lkml.kernel.org/n/tip-g79k0jz41adiaeuqud742t2l@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'tools') diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 5ad92fa72e78..253dd8dd0e12 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -21,6 +21,7 @@ #include "bpf-event.h" #include #include +#include #include "parse-events.h" #include @@ -1824,6 +1825,14 @@ static void *perf_evlist__poll_thread(void *arg) struct evlist *evlist = arg; bool draining = false; int i, done = 0; + /* + * In order to read symbols from other namespaces perf to needs to call + * setns(2). This isn't permitted if the struct_fs has multiple users. + * unshare(2) the fs so that we may continue to setns into namespaces + * that we're observing when, for instance, reading the build-ids at + * the end of a 'perf record' session. + */ + unshare(CLONE_FS); while (!done) { bool got_data = false; -- cgit v1.2.3-59-g8ed1b From b0215e2d6a18d8331b2d4a8b38ccf3eff783edb1 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Wed, 28 Aug 2019 15:05:28 -0400 Subject: tools lib traceevent: Do not free tep->cmdlines in add_new_comm() on failure If the re-allocation of tep->cmdlines succeeds, then the previous allocation of tep->cmdlines will be freed. If we later fail in add_new_comm(), we must not free cmdlines, and also should assign tep->cmdlines to the new allocation. Otherwise when freeing tep, the tep->cmdlines will be pointing to garbage. Fixes: a6d2a61ac653a ("tools lib traceevent: Remove some die() calls") Signed-off-by: Steven Rostedt (VMware) Cc: Andrew Morton Cc: Jiri Olsa Cc: Namhyung Kim Cc: linux-trace-devel@vger.kernel.org Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20190828191819.970121417@goodmis.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index b36b536a9fcb..13fd9fdf91e0 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -269,10 +269,10 @@ static int add_new_comm(struct tep_handle *tep, errno = ENOMEM; return -1; } + tep->cmdlines = cmdlines; cmdlines[tep->cmdline_count].comm = strdup(comm); if (!cmdlines[tep->cmdline_count].comm) { - free(cmdlines); errno = ENOMEM; return -1; } @@ -283,7 +283,6 @@ static int add_new_comm(struct tep_handle *tep, tep->cmdline_count++; qsort(cmdlines, tep->cmdline_count, sizeof(*cmdlines), cmdline_cmp); - tep->cmdlines = cmdlines; return 0; } -- cgit v1.2.3-59-g8ed1b From 301011ba622513cb41ced59973972204e0da2f71 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Wed, 28 Aug 2019 15:05:29 -0400 Subject: tools lib traceevent: Remove unneeded qsort and uses memmove instead While reading a trace data file that had 100,000s of tasks, the process took an extremely long time. I profiled it down to add_new_comm(), which was doing a qsort() call on an array that was pretty much already sorted (all but the last element. qsort() isn't very efficient when dealing with mostly sorted arrays, and this definitely showed its issues. When adding a new task to the task list, instead of using qsort(), do another bsearch() with a function that will find the element before where the new task will be inserted in. Then simply shift the rest of the array, and insert the task where it belongs. Fixes: f7d82350e597d ("tools/events: Add files to create libtraceevent.a") Signed-off-by: Steven Rostedt (VMware) Cc: Andrew Morton Cc: Jiri Olsa Cc: Namhyung Kim Cc: linux-trace-devel@vger.kernel.org Link: http://lkml.kernel.org/r/20190828191820.127233764@goodmis.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 55 +++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 13fd9fdf91e0..3e83636076b2 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -142,6 +142,25 @@ static int cmdline_cmp(const void *a, const void *b) return 0; } +/* Looking for where to place the key */ +static int cmdline_slot_cmp(const void *a, const void *b) +{ + const struct tep_cmdline *ca = a; + const struct tep_cmdline *cb = b; + const struct tep_cmdline *cb1 = cb + 1; + + if (ca->pid < cb->pid) + return -1; + + if (ca->pid > cb->pid) { + if (ca->pid <= cb1->pid) + return 0; + return 1; + } + + return 0; +} + struct cmdline_list { struct cmdline_list *next; char *comm; @@ -239,6 +258,7 @@ static int add_new_comm(struct tep_handle *tep, struct tep_cmdline *cmdline; struct tep_cmdline key; char *new_comm; + int cnt; if (!pid) return 0; @@ -271,18 +291,41 @@ static int add_new_comm(struct tep_handle *tep, } tep->cmdlines = cmdlines; - cmdlines[tep->cmdline_count].comm = strdup(comm); - if (!cmdlines[tep->cmdline_count].comm) { + key.comm = strdup(comm); + if (!key.comm) { errno = ENOMEM; return -1; } - cmdlines[tep->cmdline_count].pid = pid; - - if (cmdlines[tep->cmdline_count].comm) + if (!tep->cmdline_count) { + /* no entries yet */ + tep->cmdlines[0] = key; tep->cmdline_count++; + return 0; + } - qsort(cmdlines, tep->cmdline_count, sizeof(*cmdlines), cmdline_cmp); + /* Now find where we want to store the new cmdline */ + cmdline = bsearch(&key, tep->cmdlines, tep->cmdline_count - 1, + sizeof(*tep->cmdlines), cmdline_slot_cmp); + + cnt = tep->cmdline_count; + if (cmdline) { + /* cmdline points to the one before the spot we want */ + cmdline++; + cnt -= cmdline - tep->cmdlines; + + } else { + /* The new entry is either before or after the list */ + if (key.pid > tep->cmdlines[tep->cmdline_count - 1].pid) { + tep->cmdlines[tep->cmdline_count++] = key; + return 0; + } + cmdline = &tep->cmdlines[0]; + } + memmove(cmdline + 1, cmdline, (cnt * sizeof(*cmdline))); + *cmdline = key; + + tep->cmdline_count++; return 0; } -- cgit v1.2.3-59-g8ed1b From be6f55a60d28fb31864d3aab011cf4e1fc0dba04 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 29 Aug 2019 15:07:32 +0200 Subject: KVM: selftests: Add a test for the KVM_S390_MEM_OP ioctl Check that we can write and read the guest memory with this s390x ioctl, and that some error cases are handled correctly. Signed-off-by: Thomas Huth Link: https://lkml.kernel.org/r/20190829130732.580-1-thuth@redhat.com Signed-off-by: Christian Borntraeger --- tools/testing/selftests/kvm/Makefile | 1 + tools/testing/selftests/kvm/s390x/memop.c | 166 ++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 tools/testing/selftests/kvm/s390x/memop.c (limited to 'tools') diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 1b48a94b4350..62c591f87dab 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -32,6 +32,7 @@ TEST_GEN_PROGS_aarch64 += clear_dirty_log_test TEST_GEN_PROGS_aarch64 += dirty_log_test TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus +TEST_GEN_PROGS_s390x = s390x/memop TEST_GEN_PROGS_s390x += s390x/sync_regs_test TEST_GEN_PROGS_s390x += dirty_log_test TEST_GEN_PROGS_s390x += kvm_create_max_vcpus diff --git a/tools/testing/selftests/kvm/s390x/memop.c b/tools/testing/selftests/kvm/s390x/memop.c new file mode 100644 index 000000000000..9edaa9a134ce --- /dev/null +++ b/tools/testing/selftests/kvm/s390x/memop.c @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Test for s390x KVM_S390_MEM_OP + * + * Copyright (C) 2019, Red Hat, Inc. + */ + +#include +#include +#include +#include + +#include "test_util.h" +#include "kvm_util.h" + +#define VCPU_ID 1 + +static uint8_t mem1[65536]; +static uint8_t mem2[65536]; + +static void guest_code(void) +{ + int i; + + for (;;) { + for (i = 0; i < sizeof(mem2); i++) + mem2[i] = mem1[i]; + GUEST_SYNC(0); + } +} + +int main(int argc, char *argv[]) +{ + struct kvm_vm *vm; + struct kvm_run *run; + struct kvm_s390_mem_op ksmo; + int rv, i, maxsize; + + setbuf(stdout, NULL); /* Tell stdout not to buffer its content */ + + maxsize = kvm_check_cap(KVM_CAP_S390_MEM_OP); + if (!maxsize) { + fprintf(stderr, "CAP_S390_MEM_OP not supported -> skip test\n"); + exit(KSFT_SKIP); + } + if (maxsize > sizeof(mem1)) + maxsize = sizeof(mem1); + + /* Create VM */ + vm = vm_create_default(VCPU_ID, 0, guest_code); + run = vcpu_state(vm, VCPU_ID); + + for (i = 0; i < sizeof(mem1); i++) + mem1[i] = i * i + i; + + /* Set the first array */ + ksmo.gaddr = addr_gva2gpa(vm, (uintptr_t)mem1); + ksmo.flags = 0; + ksmo.size = maxsize; + ksmo.op = KVM_S390_MEMOP_LOGICAL_WRITE; + ksmo.buf = (uintptr_t)mem1; + ksmo.ar = 0; + vcpu_ioctl(vm, VCPU_ID, KVM_S390_MEM_OP, &ksmo); + + /* Let the guest code copy the first array to the second */ + vcpu_run(vm, VCPU_ID); + TEST_ASSERT(run->exit_reason == KVM_EXIT_S390_SIEIC, + "Unexpected exit reason: %u (%s)\n", + run->exit_reason, + exit_reason_str(run->exit_reason)); + + memset(mem2, 0xaa, sizeof(mem2)); + + /* Get the second array */ + ksmo.gaddr = (uintptr_t)mem2; + ksmo.flags = 0; + ksmo.size = maxsize; + ksmo.op = KVM_S390_MEMOP_LOGICAL_READ; + ksmo.buf = (uintptr_t)mem2; + ksmo.ar = 0; + vcpu_ioctl(vm, VCPU_ID, KVM_S390_MEM_OP, &ksmo); + + TEST_ASSERT(!memcmp(mem1, mem2, maxsize), + "Memory contents do not match!"); + + /* Check error conditions - first bad size: */ + ksmo.gaddr = (uintptr_t)mem1; + ksmo.flags = 0; + ksmo.size = -1; + ksmo.op = KVM_S390_MEMOP_LOGICAL_WRITE; + ksmo.buf = (uintptr_t)mem1; + ksmo.ar = 0; + rv = _vcpu_ioctl(vm, VCPU_ID, KVM_S390_MEM_OP, &ksmo); + TEST_ASSERT(rv == -1 && errno == E2BIG, "ioctl allows insane sizes"); + + /* Zero size: */ + ksmo.gaddr = (uintptr_t)mem1; + ksmo.flags = 0; + ksmo.size = 0; + ksmo.op = KVM_S390_MEMOP_LOGICAL_WRITE; + ksmo.buf = (uintptr_t)mem1; + ksmo.ar = 0; + rv = _vcpu_ioctl(vm, VCPU_ID, KVM_S390_MEM_OP, &ksmo); + TEST_ASSERT(rv == -1 && (errno == EINVAL || errno == ENOMEM), + "ioctl allows 0 as size"); + + /* Bad flags: */ + ksmo.gaddr = (uintptr_t)mem1; + ksmo.flags = -1; + ksmo.size = maxsize; + ksmo.op = KVM_S390_MEMOP_LOGICAL_WRITE; + ksmo.buf = (uintptr_t)mem1; + ksmo.ar = 0; + rv = _vcpu_ioctl(vm, VCPU_ID, KVM_S390_MEM_OP, &ksmo); + TEST_ASSERT(rv == -1 && errno == EINVAL, "ioctl allows all flags"); + + /* Bad operation: */ + ksmo.gaddr = (uintptr_t)mem1; + ksmo.flags = 0; + ksmo.size = maxsize; + ksmo.op = -1; + ksmo.buf = (uintptr_t)mem1; + ksmo.ar = 0; + rv = _vcpu_ioctl(vm, VCPU_ID, KVM_S390_MEM_OP, &ksmo); + TEST_ASSERT(rv == -1 && errno == EINVAL, "ioctl allows bad operations"); + + /* Bad guest address: */ + ksmo.gaddr = ~0xfffUL; + ksmo.flags = KVM_S390_MEMOP_F_CHECK_ONLY; + ksmo.size = maxsize; + ksmo.op = KVM_S390_MEMOP_LOGICAL_WRITE; + ksmo.buf = (uintptr_t)mem1; + ksmo.ar = 0; + rv = _vcpu_ioctl(vm, VCPU_ID, KVM_S390_MEM_OP, &ksmo); + TEST_ASSERT(rv > 0, "ioctl does not report bad guest memory access"); + + /* Bad host address: */ + ksmo.gaddr = (uintptr_t)mem1; + ksmo.flags = 0; + ksmo.size = maxsize; + ksmo.op = KVM_S390_MEMOP_LOGICAL_WRITE; + ksmo.buf = 0; + ksmo.ar = 0; + rv = _vcpu_ioctl(vm, VCPU_ID, KVM_S390_MEM_OP, &ksmo); + TEST_ASSERT(rv == -1 && errno == EFAULT, + "ioctl does not report bad host memory address"); + + /* Bad access register: */ + run->psw_mask &= ~(3UL << (63 - 17)); + run->psw_mask |= 1UL << (63 - 17); /* Enable AR mode */ + vcpu_run(vm, VCPU_ID); /* To sync new state to SIE block */ + ksmo.gaddr = (uintptr_t)mem1; + ksmo.flags = 0; + ksmo.size = maxsize; + ksmo.op = KVM_S390_MEMOP_LOGICAL_WRITE; + ksmo.buf = (uintptr_t)mem1; + ksmo.ar = 17; + rv = _vcpu_ioctl(vm, VCPU_ID, KVM_S390_MEM_OP, &ksmo); + TEST_ASSERT(rv == -1 && errno == EINVAL, "ioctl allows ARs > 15"); + run->psw_mask &= ~(3UL << (63 - 17)); /* Disable AR mode */ + vcpu_run(vm, VCPU_ID); /* Run to sync new state */ + + kvm_vm_free(vm); + + return 0; +} -- cgit v1.2.3-59-g8ed1b From 828f369d76d16bffa97133f6f63a64c13a401953 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 17 Jun 2019 16:51:15 +0200 Subject: cpupower: Add missing newline at end of file "git diff" says: \ No newline at end of file after modifying the files. Signed-off-by: Geert Uytterhoeven Signed-off-by: Shuah Khan --- tools/power/cpupower/bench/cpufreq-bench_plot.sh | 2 +- tools/power/cpupower/bench/cpufreq-bench_script.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/power/cpupower/bench/cpufreq-bench_plot.sh b/tools/power/cpupower/bench/cpufreq-bench_plot.sh index 9061b4f1244e..f5f8b3c8f062 100644 --- a/tools/power/cpupower/bench/cpufreq-bench_plot.sh +++ b/tools/power/cpupower/bench/cpufreq-bench_plot.sh @@ -88,4 +88,4 @@ done echo >> $dir/plot_script.gpl gnuplot $dir/plot_script.gpl -rm -r $dir \ No newline at end of file +rm -r $dir diff --git a/tools/power/cpupower/bench/cpufreq-bench_script.sh b/tools/power/cpupower/bench/cpufreq-bench_script.sh index 4e9714b876d2..785a3679c704 100644 --- a/tools/power/cpupower/bench/cpufreq-bench_script.sh +++ b/tools/power/cpupower/bench/cpufreq-bench_script.sh @@ -85,4 +85,4 @@ function create_plots() } measure -create_plots \ No newline at end of file +create_plots -- cgit v1.2.3-59-g8ed1b From a73f6e2fbe8077811ea9546e0d44a7533111f0ba Mon Sep 17 00:00:00 2001 From: Sébastien Szymanski Date: Fri, 7 Jun 2019 17:02:55 +0200 Subject: tools/power/cpupower: fix 64bit detection when cross-compiling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When cross-compiling cpupower, 64bit detection is done with the host compiler instead of the cross-compiler and libcpupower.so.0 ends up in /usr/lib64 instead of /usr/lib for 32bit target. Fix this by moving 64bit detection after CC is defined. Signed-off-by: Sébastien Szymanski Signed-off-by: Shuah Khan --- tools/power/cpupower/Makefile | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile index 9063fca480b3..c8622497ef23 100644 --- a/tools/power/cpupower/Makefile +++ b/tools/power/cpupower/Makefile @@ -18,7 +18,6 @@ OUTDIR := $(shell cd $(OUTPUT) && pwd) $(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist)) endif -include ../../scripts/Makefile.arch # --- CONFIGURATION BEGIN --- @@ -69,11 +68,6 @@ bindir ?= /usr/bin sbindir ?= /usr/sbin mandir ?= /usr/man includedir ?= /usr/include -ifeq ($(IS_64_BIT), 1) -libdir ?= /usr/lib64 -else -libdir ?= /usr/lib -endif localedir ?= /usr/share/locale docdir ?= /usr/share/doc/packages/cpupower confdir ?= /etc/ @@ -100,6 +94,14 @@ RANLIB = $(CROSS)ranlib HOSTCC = gcc MKDIR = mkdir +# 64bit library detection +include ../../scripts/Makefile.arch + +ifeq ($(IS_64_BIT), 1) +libdir ?= /usr/lib64 +else +libdir ?= /usr/lib +endif # Now we set up the build system # -- cgit v1.2.3-59-g8ed1b From 87ce243206944a57383309dcbcdcc5750e6c905b Mon Sep 17 00:00:00 2001 From: Benjamin Weis Date: Mon, 24 Jun 2019 15:31:50 +0200 Subject: cpupower: update German translation Update the German translation of cpupower, and change the encoding to UTF-8. [skhan@linuxfoundation.org: fix merge conflicts] Signed-off-by: Benjamin Weis Acked-by: Dominik Brodowski Signed-off-by: Shuah Khan --- tools/power/cpupower/po/de.po | 344 ++++++++++++++++++++++-------------------- 1 file changed, 180 insertions(+), 164 deletions(-) (limited to 'tools') diff --git a/tools/power/cpupower/po/de.po b/tools/power/cpupower/po/de.po index 70887bb8ba95..9780a447bb55 100644 --- a/tools/power/cpupower/po/de.po +++ b/tools/power/cpupower/po/de.po @@ -8,66 +8,66 @@ msgstr "" "Project-Id-Version: cpufrequtils 006\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-03-08 17:03+0100\n" -"PO-Revision-Date: 2009-08-08 17:18+0100\n" -"Last-Translator: \n" +"PO-Revision-Date: 2019-06-02 15:23+0200\n" +"Last-Translator: Benjamin Weis \n" "Language-Team: NONE\n" "Language: \n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=ISO-8859-1\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: utils/idle_monitor/nhm_idle.c:36 msgid "Processor Core C3" -msgstr "" +msgstr "Prozessorkern C3" #: utils/idle_monitor/nhm_idle.c:43 msgid "Processor Core C6" -msgstr "" +msgstr "Prozessorkern C6" #: utils/idle_monitor/nhm_idle.c:51 msgid "Processor Package C3" -msgstr "" +msgstr "Prozessorpaket C3" #: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70 msgid "Processor Package C6" -msgstr "" +msgstr "Prozessorpaket C6" #: utils/idle_monitor/snb_idle.c:33 msgid "Processor Core C7" -msgstr "" +msgstr "Prozessorkern C7" #: utils/idle_monitor/snb_idle.c:40 msgid "Processor Package C2" -msgstr "" +msgstr "Prozessorpaket C2" #: utils/idle_monitor/snb_idle.c:47 msgid "Processor Package C7" -msgstr "" +msgstr "Prozessorpaket C7" #: utils/idle_monitor/amd_fam14h_idle.c:56 msgid "Package in sleep state (PC1 or deeper)" -msgstr "" +msgstr "Paket in Schlafzustand (PC1 oder tiefer)" #: utils/idle_monitor/amd_fam14h_idle.c:63 msgid "Processor Package C1" -msgstr "" +msgstr "Prozessorpaket C1" #: utils/idle_monitor/amd_fam14h_idle.c:77 msgid "North Bridge P1 boolean counter (returns 0 or 1)" -msgstr "" +msgstr "North Bridge P1 boolescher Zähler (gibt 0 oder 1 zurück)" #: utils/idle_monitor/mperf_monitor.c:35 msgid "Processor Core not idle" -msgstr "" +msgstr "Prozessorkern ist nicht im Leerlauf" #: utils/idle_monitor/mperf_monitor.c:42 msgid "Processor Core in an idle state" -msgstr "" +msgstr "Prozessorkern ist in einem Ruhezustand" #: utils/idle_monitor/mperf_monitor.c:50 msgid "Average Frequency (including boost) in MHz" -msgstr "" +msgstr "Durchschnittliche Frequenz (einschließlich Boost) in MHz" #: utils/idle_monitor/cpupower-monitor.c:66 #, c-format @@ -75,6 +75,8 @@ msgid "" "cpupower monitor: [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " "interval_sec | -c command ...]\n" msgstr "" +"cpupower monitor: [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c Befehl ...]\n" #: utils/idle_monitor/cpupower-monitor.c:69 #, c-format @@ -82,36 +84,40 @@ msgid "" "cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " "interval_sec | -c command ...]\n" msgstr "" +"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c Befehl ...]\n" #: utils/idle_monitor/cpupower-monitor.c:71 #, c-format msgid "\t -v: be more verbose\n" -msgstr "" +msgstr "\t -v: ausführlicher\n" #: utils/idle_monitor/cpupower-monitor.c:73 #, c-format msgid "\t -h: print this help\n" -msgstr "" +msgstr "\t -h: diese Hilfe ausgeben\n" #: utils/idle_monitor/cpupower-monitor.c:74 #, c-format msgid "\t -i: time interval to measure for in seconds (default 1)\n" -msgstr "" +msgstr "\t -i: Zeitintervall für die Messung in Sekunden (Standard 1)\n" #: utils/idle_monitor/cpupower-monitor.c:75 #, c-format msgid "\t -t: show CPU topology/hierarchy\n" -msgstr "" +msgstr "\t -t: CPU-Topologie/Hierarchie anzeigen\n" #: utils/idle_monitor/cpupower-monitor.c:76 #, c-format msgid "\t -l: list available CPU sleep monitors (for use with -m)\n" msgstr "" +"\t -l: verfügbare CPU-Schlafwächter auflisten (für Verwendung mit -m)\n" #: utils/idle_monitor/cpupower-monitor.c:77 #, c-format msgid "\t -m: show specific CPU sleep monitors only (in same order)\n" msgstr "" +"\t -m: spezifische CPU-Schlafwächter anzeigen (in gleicher Reihenfolge)\n" #: utils/idle_monitor/cpupower-monitor.c:79 #, c-format @@ -119,71 +125,73 @@ msgid "" "only one of: -t, -l, -m are allowed\n" "If none of them is passed," msgstr "" +"nur einer von: -t, -l, -m ist erlaubt\n" +"Wenn keiner von ihnen übergeben wird," #: utils/idle_monitor/cpupower-monitor.c:80 #, c-format msgid " all supported monitors are shown\n" -msgstr "" +msgstr " werden alle unterstützten Wächter angezeigt\n" #: utils/idle_monitor/cpupower-monitor.c:197 #, c-format msgid "Monitor %s, Counter %s has no count function. Implementation error\n" -msgstr "" +msgstr "Wächter %s, Zähler %s hat keine Zählfunktion. Implementierungsfehler\n" #: utils/idle_monitor/cpupower-monitor.c:207 #, c-format msgid " *is offline\n" -msgstr "" +msgstr " *ist offline\n" #: utils/idle_monitor/cpupower-monitor.c:236 #, c-format msgid "%s: max monitor name length (%d) exceeded\n" -msgstr "" +msgstr "%s: max. Wächternamenslänge (%d) überschritten\n" #: utils/idle_monitor/cpupower-monitor.c:250 #, c-format msgid "No matching monitor found in %s, try -l option\n" -msgstr "" +msgstr "Kein passender Wächter in %s gefunden, versuchen Sie die Option -l\n" #: utils/idle_monitor/cpupower-monitor.c:266 #, c-format msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n" -msgstr "" +msgstr "Wächter \"%s\" (%d Zustände) - Könnte nach %u s überlaufen\n" #: utils/idle_monitor/cpupower-monitor.c:319 #, c-format msgid "%s took %.5f seconds and exited with status %d\n" -msgstr "" +msgstr "%s hat %.5f Sekunden gedauert und hat sich mit Status %d beendet\n" #: utils/idle_monitor/cpupower-monitor.c:406 #, c-format msgid "Cannot read number of available processors\n" -msgstr "" +msgstr "Anzahl der verfügbaren Prozessoren kann nicht gelesen werden\n" #: utils/idle_monitor/cpupower-monitor.c:417 #, c-format msgid "Available monitor %s needs root access\n" -msgstr "" +msgstr "Verfügbarer Wächter %s benötigt root-Zugriff\n" #: utils/idle_monitor/cpupower-monitor.c:428 #, c-format msgid "No HW Cstate monitors found\n" -msgstr "" +msgstr "Keine HW C-Zustandswächter gefunden\n" #: utils/cpupower.c:78 #, c-format msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n" -msgstr "" +msgstr "cpupower [ -c cpulist ] Unterbefehl [ARGS]\n" #: utils/cpupower.c:79 #, c-format msgid "cpupower --version\n" -msgstr "" +msgstr "cpupower --version\n" #: utils/cpupower.c:80 #, c-format msgid "Supported subcommands are:\n" -msgstr "" +msgstr "Unterstützte Unterbefehle sind:\n" #: utils/cpupower.c:83 #, c-format @@ -191,11 +199,15 @@ msgid "" "\n" "Some subcommands can make use of the -c cpulist option.\n" msgstr "" +"\n" +"Einige Unterbefehle können die Option -c cpulist verwenden.\n" #: utils/cpupower.c:84 #, c-format msgid "Look at the general cpupower manpage how to use it\n" msgstr "" +"Schauen Sie sich die allgemeine cpupower manpage an, um zu erfahren, wie man " +"es benutzt\n" #: utils/cpupower.c:85 #, c-format @@ -217,30 +229,31 @@ msgstr "Bitte melden Sie Fehler an %s.\n" #: utils/cpupower.c:114 #, c-format msgid "Error parsing cpu list\n" -msgstr "" +msgstr "Fehler beim Parsen der CPU-Liste\n" #: utils/cpupower.c:172 #, c-format msgid "Subcommand %s needs root privileges\n" -msgstr "" +msgstr "Unterbefehl %s benötigt root-Rechte\n" #: utils/cpufreq-info.c:31 #, c-format msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n" msgstr "" -"Konnte nicht die Anzahl der CPUs herausfinden (%s : %s), nehme daher 1 an.\n" +"Anzahl der CPUs konnte nicht herausgefinden werden (%s: %s), es wird daher 1 " +"angenommen\n" #: utils/cpufreq-info.c:63 #, c-format msgid "" " minimum CPU frequency - maximum CPU frequency - governor\n" -msgstr "" -" minimale CPU-Taktfreq. - maximale CPU-Taktfreq. - Regler \n" +msgstr " minimale CPU-Frequenz - maximale CPU-Frequenz - Regler\n" #: utils/cpufreq-info.c:151 #, c-format msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n" msgstr "" +"Fehler beim Evaluieren der Boost-Fähigkeiten bei CPU %d -- sind Sie root?\n" #. P state changes via MSR are identified via cpuid 80000007 #. on Intel and AMD, but we assume boost capable machines can do that @@ -250,50 +263,50 @@ msgstr "" #: utils/cpufreq-info.c:161 #, c-format msgid " boost state support: \n" -msgstr "" +msgstr " Boost-Zustand-Unterstützung: \n" #: utils/cpufreq-info.c:163 #, c-format msgid " Supported: %s\n" -msgstr "" +msgstr " Unterstützt: %s\n" #: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164 msgid "yes" -msgstr "" +msgstr "ja" #: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164 msgid "no" -msgstr "" +msgstr "nein" #: utils/cpufreq-info.c:164 -#, fuzzy, c-format +#, c-format msgid " Active: %s\n" -msgstr " Treiber: %s\n" +msgstr " Aktiv: %s\n" #: utils/cpufreq-info.c:177 #, c-format msgid " Boost States: %d\n" -msgstr "" +msgstr " Boost-Zustände: %d\n" #: utils/cpufreq-info.c:178 #, c-format msgid " Total States: %d\n" -msgstr "" +msgstr " Gesamtzustände: %d\n" #: utils/cpufreq-info.c:181 #, c-format msgid " Pstate-Pb%d: %luMHz (boost state)\n" -msgstr "" +msgstr " Pstate-Pb%d: %luMHz (Boost-Zustand)\n" #: utils/cpufreq-info.c:184 #, c-format msgid " Pstate-P%d: %luMHz\n" -msgstr "" +msgstr " Pstate-P%d: %luMHz\n" #: utils/cpufreq-info.c:211 #, c-format msgid " no or unknown cpufreq driver is active on this CPU\n" -msgstr " kein oder nicht bestimmbarer cpufreq-Treiber aktiv\n" +msgstr " kein oder ein unbekannter cpufreq-Treiber ist auf dieser CPU aktiv\n" #: utils/cpufreq-info.c:213 #, c-format @@ -303,12 +316,12 @@ msgstr " Treiber: %s\n" #: utils/cpufreq-info.c:219 #, c-format msgid " CPUs which run at the same hardware frequency: " -msgstr " Folgende CPUs laufen mit der gleichen Hardware-Taktfrequenz: " +msgstr " CPUs, die mit der gleichen Hardwarefrequenz laufen: " #: utils/cpufreq-info.c:230 #, c-format msgid " CPUs which need to have their frequency coordinated by software: " -msgstr " Die Taktfrequenz folgender CPUs werden per Software koordiniert: " +msgstr " CPUs, die ihre Frequenz mit Software koordinieren müssen: " #: utils/cpufreq-info.c:241 #, c-format @@ -318,22 +331,22 @@ msgstr " Maximale Dauer eines Taktfrequenzwechsels: " #: utils/cpufreq-info.c:247 #, c-format msgid " hardware limits: " -msgstr " Hardwarebedingte Grenzen der Taktfrequenz: " +msgstr " Hardwarebegrenzungen: " #: utils/cpufreq-info.c:256 #, c-format msgid " available frequency steps: " -msgstr " mögliche Taktfrequenzen: " +msgstr " verfügbare Frequenzschritte: " #: utils/cpufreq-info.c:269 #, c-format msgid " available cpufreq governors: " -msgstr " mögliche Regler: " +msgstr " verfügbare cpufreq-Regler: " #: utils/cpufreq-info.c:280 #, c-format msgid " current policy: frequency should be within " -msgstr " momentane Taktik: die Frequenz soll innerhalb " +msgstr " momentane Richtlinie: Frequenz sollte innerhalb " #: utils/cpufreq-info.c:282 #, c-format @@ -346,29 +359,28 @@ msgid "" "The governor \"%s\" may decide which speed to use\n" " within this range.\n" msgstr "" -" liegen. Der Regler \"%s\" kann frei entscheiden,\n" -" welche Taktfrequenz innerhalb dieser Grenze verwendet " -"wird.\n" +" sein. Der Regler \"%s\" kann frei entscheiden,\n" +" welche Geschwindigkeit er in diesem Bereich verwendet.\n" #: utils/cpufreq-info.c:293 #, c-format msgid " current CPU frequency is " -msgstr " momentane Taktfrequenz ist " +msgstr " momentane CPU-Frequenz ist " #: utils/cpufreq-info.c:296 #, c-format msgid " (asserted by call to hardware)" -msgstr " (verifiziert durch Nachfrage bei der Hardware)" +msgstr " (durch Aufruf der Hardware sichergestellt)" #: utils/cpufreq-info.c:304 #, c-format msgid " cpufreq stats: " -msgstr " Statistik:" +msgstr " cpufreq-Statistiken: " #: utils/cpufreq-info.c:472 -#, fuzzy, c-format +#, c-format msgid "Usage: cpupower freqinfo [options]\n" -msgstr "Aufruf: cpufreq-info [Optionen]\n" +msgstr "Aufruf: cpupower freqinfo [Optionen]\n" #: utils/cpufreq-info.c:473 utils/cpufreq-set.c:26 utils/cpupower-set.c:23 #: utils/cpupower-info.c:22 utils/cpuidle-info.c:148 @@ -377,11 +389,9 @@ msgid "Options:\n" msgstr "Optionen:\n" #: utils/cpufreq-info.c:474 -#, fuzzy, c-format +#, c-format msgid " -e, --debug Prints out debug information [default]\n" -msgstr "" -" -e, --debug Erzeugt detaillierte Informationen, hilfreich\n" -" zum Aufspüren von Fehlern\n" +msgstr " -e, --debug Gibt Debug-Informationen aus [Standard]\n" #: utils/cpufreq-info.c:475 #, c-format @@ -424,7 +434,7 @@ msgstr " -p, --policy Findet die momentane Taktik heraus *\n" #: utils/cpufreq-info.c:482 #, c-format msgid " -g, --governors Determines available cpufreq governors *\n" -msgstr " -g, --governors Erzeugt eine Liste mit verfügbaren Reglern *\n" +msgstr " -g, --governors Ermittelt verfügbare cpufreq-Regler *\n" #: utils/cpufreq-info.c:483 #, c-format @@ -449,8 +459,7 @@ msgstr "" #: utils/cpufreq-info.c:486 #, c-format msgid " -s, --stats Shows cpufreq statistics if available\n" -msgstr "" -" -s, --stats Zeigt, sofern möglich, Statistiken über cpufreq an.\n" +msgstr " -s, --stats Zeigt cpufreq-Statistiken an, falls vorhanden\n" #: utils/cpufreq-info.c:487 #, c-format @@ -464,13 +473,13 @@ msgstr "" #: utils/cpufreq-info.c:488 #, c-format msgid " -b, --boost Checks for turbo or boost modes *\n" -msgstr "" +msgstr " -b, --boost Prüft auf Turbo- oder Boost-Modi *\n" #: utils/cpufreq-info.c:489 #, c-format msgid "" -" -o, --proc Prints out information like provided by the /proc/" -"cpufreq\n" +" -o, --proc Prints out information like provided by the " +"/proc/cpufreq\n" " interface in 2.4. and early 2.6. kernels\n" msgstr "" " -o, --proc Erzeugt Informationen in einem ähnlichem Format zu " @@ -509,8 +518,8 @@ msgid "" "For the arguments marked with *, omitting the -c or --cpu argument is\n" "equivalent to setting it to zero\n" msgstr "" -"Bei den mit * markierten Parametern wird '--cpu 0' angenommen, soweit nicht\n" -"mittels -c oder --cpu etwas anderes angegeben wird\n" +"Für die mit * markierten Argumente ist das Weglassen des Arguments\n" +"-c oder --cpu gleichbedeutend mit der Einstellung auf Null\n" #: utils/cpufreq-info.c:580 #, c-format @@ -525,8 +534,8 @@ msgid "" "You can't specify more than one --cpu parameter and/or\n" "more than one output-specific argument\n" msgstr "" -"Man kann nicht mehr als einen --cpu-Parameter und/oder mehr als einen\n" -"informationsspezifischen Parameter gleichzeitig angeben\n" +"Sie können nicht mehr als einen Parameter --cpu und/oder\n" +"mehr als ein ausgabespezifisches Argument angeben\n" #: utils/cpufreq-info.c:600 utils/cpufreq-set.c:82 utils/cpupower-set.c:42 #: utils/cpupower-info.c:42 utils/cpuidle-info.c:213 @@ -538,17 +547,17 @@ msgstr "unbekannter oder falscher Parameter\n" #, c-format msgid "couldn't analyze CPU %d as it doesn't seem to be present\n" msgstr "" -"Konnte nicht die CPU %d analysieren, da sie (scheinbar?) nicht existiert.\n" +"CPU %d konnte nicht analysiert werden, da sie scheinbar nicht existiert\n" #: utils/cpufreq-info.c:620 utils/cpupower-info.c:142 #, c-format msgid "analyzing CPU %d:\n" -msgstr "analysiere CPU %d:\n" +msgstr "CPU %d wird analysiert:\n" #: utils/cpufreq-set.c:25 -#, fuzzy, c-format +#, c-format msgid "Usage: cpupower frequency-set [options]\n" -msgstr "Aufruf: cpufreq-set [Optionen]\n" +msgstr "Aufruf: cpupower frequency-set [Optionen]\n" #: utils/cpufreq-set.c:27 #, c-format @@ -556,7 +565,7 @@ msgid "" " -d FREQ, --min FREQ new minimum CPU frequency the governor may " "select\n" msgstr "" -" -d FREQ, --min FREQ neue minimale Taktfrequenz, die der Regler\n" +" -d FREQ, --min FREQ neue minimale CPU-Frequenz, die der Regler\n" " auswählen darf\n" #: utils/cpufreq-set.c:28 @@ -571,7 +580,7 @@ msgstr "" #: utils/cpufreq-set.c:29 #, c-format msgid " -g GOV, --governor GOV new cpufreq governor\n" -msgstr " -g GOV, --governors GOV wechsle zu Regler GOV\n" +msgstr " -g GOV, --governors GOV neuer cpufreq-Regler\n" #: utils/cpufreq-set.c:30 #, c-format @@ -579,29 +588,29 @@ msgid "" " -f FREQ, --freq FREQ specific frequency to be set. Requires userspace\n" " governor to be available and loaded\n" msgstr "" -" -f FREQ, --freq FREQ setze exakte Taktfrequenz. Benötigt den Regler\n" -" 'userspace'.\n" +" -f FREQ, --freq FREQ bestimmte Frequenz, die eingestellt werden soll.\n" +" Erfordert einen verfügbaren und geladenen " +"userspace-Regler\n" #: utils/cpufreq-set.c:32 #, c-format msgid " -r, --related Switches all hardware-related CPUs\n" -msgstr "" -" -r, --related Setze Werte für alle CPUs, deren Taktfrequenz\n" -" hardwarebedingt identisch ist.\n" +msgstr " -r, --related Schaltet alle hardwarebezogenen CPUs um\n" #: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27 #, c-format msgid " -h, --help Prints out this screen\n" -msgstr " -h, --help Gibt diese Kurzübersicht aus\n" +msgstr " -h, --help Gibt diesen Bildschirm aus\n" #: utils/cpufreq-set.c:35 -#, fuzzy, c-format +#, c-format msgid "" "Notes:\n" "1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n" msgstr "" -"Bei den mit * markierten Parametern wird '--cpu 0' angenommen, soweit nicht\n" -"mittels -c oder --cpu etwas anderes angegeben wird\n" +"Hinweis:\n" +"1. Das Weglassen des Arguments -c oder --cpu ist gleichbedeutend mit der " +"Einstellung auf \"all\"\n" #: utils/cpufreq-set.c:37 #, fuzzy, c-format @@ -636,17 +645,21 @@ msgid "" "frequency\n" " or because the userspace governor isn't loaded?\n" msgstr "" -"Beim Einstellen ist ein Fehler aufgetreten. Typische Fehlerquellen sind:\n" -"- nicht ausreichende Rechte (Administrator)\n" -"- der Regler ist nicht verfügbar bzw. nicht geladen\n" -"- die angegebene Taktik ist inkorrekt\n" -"- eine spezifische Frequenz wurde angegeben, aber der Regler 'userspace'\n" -" kann entweder hardwarebedingt nicht genutzt werden oder ist nicht geladen\n" +"Fehler beim Festlegen neuer Werte. Häufige Fehler:\n" +"- Verfügen Sie über die erforderlichen Administrationsrechte? (Superuser?)\n" +"- Ist der von Ihnen gewünschte Regler verfügbar und mittels modprobe " +"geladen?\n" +"- Versuchen Sie eine ungültige Richtlinie festzulegen?\n" +"- Versuchen Sie eine bestimmte Frequenz festzulegen, aber der " +"userspace-Regler ist nicht verfügbar,\n" +" z.B. wegen Hardware, die nicht auf eine bestimmte Frequenz eingestellt " +"werden kann\n" +" oder weil der userspace-Regler nicht geladen ist?\n" #: utils/cpufreq-set.c:170 #, c-format msgid "wrong, unknown or unhandled CPU?\n" -msgstr "unbekannte oder nicht regelbare CPU\n" +msgstr "falsche, unbekannte oder nicht regelbare CPU?\n" #: utils/cpufreq-set.c:302 #, c-format @@ -654,8 +667,8 @@ msgid "" "the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n" "-g/--governor parameters\n" msgstr "" -"Der -f bzw. --freq-Parameter kann nicht mit den Parametern -d/--min, -u/--" -"max\n" +"Der -f bzw. --freq-Parameter kann nicht mit den Parametern -d/--min, " +"-u/--max\n" "oder -g/--governor kombiniert werden\n" #: utils/cpufreq-set.c:308 @@ -664,18 +677,18 @@ msgid "" "At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n" "-g/--governor must be passed\n" msgstr "" -"Es muss mindestens ein Parameter aus -f/--freq, -d/--min, -u/--max oder\n" -"-g/--governor angegeben werden.\n" +"Mindestens ein Parameter aus -f/--freq, -d/--min, -u/--max und\n" +"-g/--governor muss übergeben werden\n" #: utils/cpufreq-set.c:347 #, c-format msgid "Setting cpu: %d\n" -msgstr "" +msgstr "CPU einstellen: %d\n" #: utils/cpupower-set.c:22 #, c-format msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n" -msgstr "" +msgstr "Aufruf: cpupower set [ -b val ] [ -m val ] [ -s val ]\n" #: utils/cpupower-set.c:24 #, c-format @@ -689,6 +702,8 @@ msgstr "" msgid "" " -m, --sched-mc [VAL] Sets the kernel's multi core scheduler policy.\n" msgstr "" +" -m, --sched-mc [VAL] Legt die Mehrkern-Scheduler-Richtlinie des " +"Kernels fest.\n" #: utils/cpupower-set.c:27 #, c-format @@ -700,37 +715,37 @@ msgstr "" #: utils/cpupower-set.c:80 #, c-format msgid "--perf-bias param out of range [0-%d]\n" -msgstr "" +msgstr "--perf-bias-Parameter außerhalb des Bereichs [0-%d]\n" #: utils/cpupower-set.c:91 #, c-format msgid "--sched-mc param out of range [0-%d]\n" -msgstr "" +msgstr "Parameter --sched-mc außerhalb des Bereichs [0-%d]\n" #: utils/cpupower-set.c:102 #, c-format msgid "--sched-smt param out of range [0-%d]\n" -msgstr "" +msgstr "Parameter --sched-smt außerhalb des Bereichs [0-%d]\n" #: utils/cpupower-set.c:121 #, c-format msgid "Error setting sched-mc %s\n" -msgstr "" +msgstr "Fehler beim Einstellen von sched-mc %s\n" #: utils/cpupower-set.c:127 #, c-format msgid "Error setting sched-smt %s\n" -msgstr "" +msgstr "Fehler beim Einstellen von sched-smt %s\n" #: utils/cpupower-set.c:146 #, c-format msgid "Error setting perf-bias value on CPU %d\n" -msgstr "" +msgstr "Fehler beim Einstellen des perf-bias-Wertes auf der CPU %d\n" #: utils/cpupower-info.c:21 #, c-format msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n" -msgstr "" +msgstr "Aufruf: cpupower info [ -b ] [ -m ] [ -s ]\n" #: utils/cpupower-info.c:23 #, c-format @@ -740,9 +755,10 @@ msgid "" msgstr "" #: utils/cpupower-info.c:25 -#, fuzzy, c-format +#, c-format msgid " -m, --sched-mc Gets the kernel's multi core scheduler policy.\n" -msgstr " -p, --policy Findet die momentane Taktik heraus *\n" +msgstr "" +" -m, --sched-mc Ruft die Mehrkern-Scheduler-Richtlinie des Kernels ab.\n" #: utils/cpupower-info.c:26 #, c-format @@ -756,17 +772,20 @@ msgid "" "\n" "Passing no option will show all info, by default only on core 0\n" msgstr "" +"\n" +"Wenn Sie keine Option übergeben, werden alle Informationen angezeigt, " +"standardmäßig nur auf Kern 0\n" #: utils/cpupower-info.c:102 #, c-format msgid "System's multi core scheduler setting: " -msgstr "" +msgstr "Mehrkern-Scheduler-Einstellung des Systems: " #. if sysfs file is missing it's: errno == ENOENT #: utils/cpupower-info.c:105 utils/cpupower-info.c:114 #, c-format msgid "not supported\n" -msgstr "" +msgstr "nicht unterstützt\n" #: utils/cpupower-info.c:111 #, c-format @@ -786,164 +805,161 @@ msgstr "" #: utils/cpupower-info.c:147 #, c-format msgid "Could not read perf-bias value\n" -msgstr "" +msgstr "perf-bias-Wert konnte nicht gelesen werden\n" #: utils/cpupower-info.c:150 #, c-format msgid "perf-bias: %d\n" -msgstr "" +msgstr "perf-bias: %d\n" #: utils/cpuidle-info.c:28 -#, fuzzy, c-format +#, c-format msgid "Analyzing CPU %d:\n" -msgstr "analysiere CPU %d:\n" +msgstr "CPU %d wird analysiert:\n" #: utils/cpuidle-info.c:32 #, c-format msgid "CPU %u: No idle states\n" -msgstr "" +msgstr "CPU %u: Keine Ruhezustände\n" #: utils/cpuidle-info.c:36 #, c-format msgid "CPU %u: Can't read idle state info\n" -msgstr "" +msgstr "CPU %u: Ruhezustands-Informationen können nicht gelesen werden\n" #: utils/cpuidle-info.c:41 #, c-format msgid "Could not determine max idle state %u\n" -msgstr "" +msgstr "Max. Ruhezustand %u konnte nicht bestimmt werden\n" #: utils/cpuidle-info.c:46 #, c-format msgid "Number of idle states: %d\n" -msgstr "" +msgstr "Anzahl der Ruhezustände: %d\n" #: utils/cpuidle-info.c:48 -#, fuzzy, c-format +#, c-format msgid "Available idle states:" -msgstr " mögliche Taktfrequenzen: " +msgstr "Verfügbare Ruhezustände:" #: utils/cpuidle-info.c:71 #, c-format msgid "Flags/Description: %s\n" -msgstr "" +msgstr "Merker/Beschreibung: %s\n" #: utils/cpuidle-info.c:74 #, c-format msgid "Latency: %lu\n" -msgstr "" +msgstr "Latenz: %lu\n" #: utils/cpuidle-info.c:76 #, c-format msgid "Usage: %lu\n" -msgstr "" +msgstr "Aufruf: %lu\n" #: utils/cpuidle-info.c:78 #, c-format msgid "Duration: %llu\n" -msgstr "" +msgstr "Dauer: %llu\n" #: utils/cpuidle-info.c:90 #, c-format msgid "Could not determine cpuidle driver\n" -msgstr "" +msgstr "cpuidle-Treiber konnte nicht bestimmt werden\n" #: utils/cpuidle-info.c:94 -#, fuzzy, c-format +#, c-format msgid "CPUidle driver: %s\n" -msgstr " Treiber: %s\n" +msgstr "CPUidle-Treiber: %s\n" #: utils/cpuidle-info.c:99 #, c-format msgid "Could not determine cpuidle governor\n" -msgstr "" +msgstr "cpuidle-Regler konnte nicht bestimmt werden\n" #: utils/cpuidle-info.c:103 #, c-format msgid "CPUidle governor: %s\n" -msgstr "" +msgstr "CPUidle-Regler: %s\n" #: utils/cpuidle-info.c:122 #, c-format msgid "CPU %u: Can't read C-state info\n" -msgstr "" +msgstr "CPU %u: C-Zustands-Informationen können nicht gelesen werden\n" #. printf("Cstates: %d\n", cstates); #: utils/cpuidle-info.c:127 #, c-format msgid "active state: C0\n" -msgstr "" +msgstr "aktiver Zustand: C0\n" #: utils/cpuidle-info.c:128 #, c-format msgid "max_cstate: C%u\n" -msgstr "" +msgstr "max_cstate: C%u\n" #: utils/cpuidle-info.c:129 -#, fuzzy, c-format +#, c-format msgid "maximum allowed latency: %lu usec\n" -msgstr " Maximale Dauer eines Taktfrequenzwechsels: " +msgstr "maximal erlaubte Latenz: %lu usec\n" #: utils/cpuidle-info.c:130 #, c-format msgid "states:\t\n" -msgstr "" +msgstr "Zustände:\t\n" #: utils/cpuidle-info.c:132 #, c-format msgid " C%d: type[C%d] " -msgstr "" +msgstr " C%d: Typ[C%d] " #: utils/cpuidle-info.c:134 #, c-format msgid "promotion[--] demotion[--] " -msgstr "" +msgstr "promotion[--] demotion[--] " #: utils/cpuidle-info.c:135 #, c-format msgid "latency[%03lu] " -msgstr "" +msgstr "Latenz[%03lu] " #: utils/cpuidle-info.c:137 #, c-format msgid "usage[%08lu] " -msgstr "" +msgstr "Aufruf[%08lu] " #: utils/cpuidle-info.c:139 #, c-format msgid "duration[%020Lu] \n" -msgstr "" +msgstr "Dauer[%020Lu] \n" #: utils/cpuidle-info.c:147 -#, fuzzy, c-format +#, c-format msgid "Usage: cpupower idleinfo [options]\n" -msgstr "Aufruf: cpufreq-info [Optionen]\n" +msgstr "Aufruf: cpupower idleinfo [Optionen]\n" #: utils/cpuidle-info.c:149 -#, fuzzy, c-format +#, c-format msgid " -s, --silent Only show general C-state information\n" msgstr "" -" -e, --debug Erzeugt detaillierte Informationen, hilfreich\n" -" zum Aufspüren von Fehlern\n" +" -s, --silent Nur allgemeine C-Zustands-Informationen anzeigen\n" #: utils/cpuidle-info.c:150 -#, fuzzy, c-format +#, c-format msgid "" -" -o, --proc Prints out information like provided by the /proc/" -"acpi/processor/*/power\n" +" -o, --proc Prints out information like provided by the " +"/proc/acpi/processor/*/power\n" " interface in older kernels\n" msgstr "" -" -o, --proc Erzeugt Informationen in einem ähnlichem Format zu " -"dem\n" -" der /proc/cpufreq-Datei in 2.4. und frühen 2.6.\n" -" Kernel-Versionen\n" +" -o, --proc Gibt Informationen so aus, wie sie von der " +"Schnittstelle\n" +" /proc/acpi/processor/*/power in älteren Kerneln " +"bereitgestellt werden\n" #: utils/cpuidle-info.c:209 -#, fuzzy, c-format +#, c-format msgid "You can't specify more than one output-specific argument\n" -msgstr "" -"Man kann nicht mehr als einen --cpu-Parameter und/oder mehr als einen\n" -"informationsspezifischen Parameter gleichzeitig angeben\n" +msgstr "Sie können nicht mehr als ein ausgabenspezifisches Argument angeben\n" #~ msgid "" #~ " -c CPU, --cpu CPU CPU number which information shall be determined " @@ -956,6 +972,6 @@ msgstr "" #~ " -c CPU, --cpu CPU number of CPU where cpufreq settings shall be " #~ "modified\n" #~ msgstr "" -#~ " -c CPU, --cpu CPU Nummer der CPU, deren Taktfrequenz-" -#~ "Einstellung\n" +#~ " -c CPU, --cpu CPU Nummer der CPU, deren " +#~ "Taktfrequenz-Einstellung\n" #~ " werden soll\n" -- cgit v1.2.3-59-g8ed1b From cbc0425d3dd370a6f0bf23589dc7b6955a53a9ce Mon Sep 17 00:00:00 2001 From: Mimi Zohar Date: Sun, 25 Aug 2019 09:58:16 -0400 Subject: sefltest/ima: support appended signatures (modsig) In addition to the PE/COFF and IMA xattr signatures, the kexec kernel image can be signed with an appended signature, using the same scripts/sign-file tool that is used to sign kernel modules. This patch adds support for detecting a kernel image signed with an appended signature and updates the existing test messages appropriately. Reviewed-by: Petr Vorel Acked-by: Shuah Khan Reviewed-by: Thiago Jung Bauermann Reviewed-by: Jordan Hand (x86_64 QEMU) Tested-by: Jordan Hand (x86_64 QEMU) Signed-off-by: Mimi Zohar --- .../selftests/kexec/test_kexec_file_load.sh | 38 +++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kexec/test_kexec_file_load.sh b/tools/testing/selftests/kexec/test_kexec_file_load.sh index fa7c24e8eefb..2ff600388c30 100755 --- a/tools/testing/selftests/kexec/test_kexec_file_load.sh +++ b/tools/testing/selftests/kexec/test_kexec_file_load.sh @@ -37,11 +37,20 @@ is_ima_sig_required() # sequentially. As a result, a policy rule may be defined, but # might not necessarily be used. This test assumes if a policy # rule is specified, that is the intent. + + # First check for appended signature (modsig), then xattr if [ $ima_read_policy -eq 1 ]; then check_ima_policy "appraise" "func=KEXEC_KERNEL_CHECK" \ - "appraise_type=imasig" + "appraise_type=imasig|modsig" ret=$? - [ $ret -eq 1 ] && log_info "IMA signature required"; + if [ $ret -eq 1 ]; then + log_info "IMA or appended(modsig) signature required" + else + check_ima_policy "appraise" "func=KEXEC_KERNEL_CHECK" \ + "appraise_type=imasig" + ret=$? + [ $ret -eq 1 ] && log_info "IMA signature required"; + fi fi return $ret } @@ -84,6 +93,22 @@ check_for_imasig() return $ret } +# Return 1 for appended signature (modsig) found and 0 for not found. +check_for_modsig() +{ + local module_sig_string="~Module signature appended~" + local sig="$(tail --bytes $((${#module_sig_string} + 1)) $KERNEL_IMAGE)" + local ret=0 + + if [ "$sig" == "$module_sig_string" ]; then + ret=1 + log_info "kexec kernel image modsig signed" + else + log_info "kexec kernel image not modsig signed" + fi + return $ret +} + kexec_file_load_test() { local succeed_msg="kexec_file_load succeeded" @@ -98,7 +123,8 @@ kexec_file_load_test() # In secureboot mode with an architecture specific # policy, make sure either an IMA or PE signature exists. if [ $secureboot -eq 1 ] && [ $arch_policy -eq 1 ] && \ - [ $ima_signed -eq 0 ] && [ $pe_signed -eq 0 ]; then + [ $ima_signed -eq 0 ] && [ $pe_signed -eq 0 ] \ + && [ $ima_modsig -eq 0 ]; then log_fail "$succeed_msg (missing sig)" fi @@ -107,7 +133,8 @@ kexec_file_load_test() log_fail "$succeed_msg (missing PE sig)" fi - if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ]; then + if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ] \ + && [ $ima_modsig -eq 0 ]; then log_fail "$succeed_msg (missing IMA sig)" fi @@ -204,5 +231,8 @@ pe_signed=$? check_for_imasig ima_signed=$? +check_for_modsig +ima_modsig=$? + # Test loading the kernel image via kexec_file_load syscall kexec_file_load_test -- cgit v1.2.3-59-g8ed1b From 67260e8c0e681a9bb9ed861514b4c80c2d0eb2e5 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 20 Aug 2019 16:02:19 +0200 Subject: perf c2c: Display proper cpu count in nodes column There's wrong bitmap considered when checking for cpu count of specific node. We do the needed computation for 'set' variable, but at the end we use the 'c2c_he->cpuset' weight, which shows misleading numbers. Fixes: 1e181b92a2da ("perf c2c report: Add 'node' sort key") Reported-by: Joe Mario Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190820140219.28338-1-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-c2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index 73782d99ee5a..8335a4076a5a 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -1107,7 +1107,7 @@ node_entry(struct perf_hpp_fmt *fmt __maybe_unused, struct perf_hpp *hpp, break; case 1: { - int num = bitmap_weight(c2c_he->cpuset, c2c.cpus_cnt); + int num = bitmap_weight(set, c2c.cpus_cnt); struct c2c_stats *stats = &c2c_he->node_stats[node]; ret = scnprintf(hpp->buf, hpp->size, "%2d{%2d ", node, num); -- cgit v1.2.3-59-g8ed1b From 0ac1dd5b4a70cfc8591dd9426f800b484765badb Mon Sep 17 00:00:00 2001 From: Kyle Meyer Date: Tue, 27 Aug 2019 16:43:46 -0500 Subject: perf timechart: Refactor svg_build_topology_map() Exchange the parameters of svg_build_topology_map() with 'struct perf_env *env' and adjust the function accordingly. This patch should not change any behavior, it is merely refactoring for the following patch. Committer notes: No need to include env.h from svghelper.h, all it needs is a forward declaration for 'struct perf_env', so move the include directive to svghelper.c, where it is really needed. Signed-off-by: Kyle Meyer Reviewed-by: Jiri Olsa Cc: Alexander Shishkin Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Russ Anderson Link: http://lore.kernel.org/lkml/20190827214352.94272-2-meyerk@stormcage.eag.rdlabs.hpecorp.net Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-timechart.c | 5 +---- tools/perf/util/svghelper.c | 20 ++++++++++++-------- tools/perf/util/svghelper.h | 4 +++- 3 files changed, 16 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 7d6a6ecf4e02..1ff81a790931 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -1518,10 +1518,7 @@ static int process_header(struct perf_file_section *section __maybe_unused, if (!tchart->topology) break; - if (svg_build_topology_map(ph->env.sibling_cores, - ph->env.nr_sibling_cores, - ph->env.sibling_threads, - ph->env.nr_sibling_threads)) + if (svg_build_topology_map(&ph->env)) fprintf(stderr, "problem building topology\n"); break; diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index bbdd87163285..2e9971590590 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c @@ -19,6 +19,7 @@ #include #include +#include "env.h" #include "perf.h" #include "svghelper.h" #include "cpumap.h" @@ -752,23 +753,26 @@ static int str_to_bitmap(char *s, cpumask_t *b) return ret; } -int svg_build_topology_map(char *sib_core, int sib_core_nr, - char *sib_thr, int sib_thr_nr) +int svg_build_topology_map(struct perf_env *env) { int i; struct topology t; + char *sib_core, *sib_thr; - t.sib_core_nr = sib_core_nr; - t.sib_thr_nr = sib_thr_nr; - t.sib_core = calloc(sib_core_nr, sizeof(cpumask_t)); - t.sib_thr = calloc(sib_thr_nr, sizeof(cpumask_t)); + t.sib_core_nr = env->nr_sibling_cores; + t.sib_thr_nr = env->nr_sibling_threads; + t.sib_core = calloc(env->nr_sibling_cores, sizeof(cpumask_t)); + t.sib_thr = calloc(env->nr_sibling_threads, sizeof(cpumask_t)); + + sib_core = env->sibling_cores; + sib_thr = env->sibling_threads; if (!t.sib_core || !t.sib_thr) { fprintf(stderr, "topology: no memory\n"); goto exit; } - for (i = 0; i < sib_core_nr; i++) { + for (i = 0; i < env->nr_sibling_cores; i++) { if (str_to_bitmap(sib_core, &t.sib_core[i])) { fprintf(stderr, "topology: can't parse siblings map\n"); goto exit; @@ -777,7 +781,7 @@ int svg_build_topology_map(char *sib_core, int sib_core_nr, sib_core += strlen(sib_core) + 1; } - for (i = 0; i < sib_thr_nr; i++) { + for (i = 0; i < env->nr_sibling_threads; i++) { if (str_to_bitmap(sib_thr, &t.sib_thr[i])) { fprintf(stderr, "topology: can't parse siblings map\n"); goto exit; diff --git a/tools/perf/util/svghelper.h b/tools/perf/util/svghelper.h index e55338d5c3bd..81823e8bae3e 100644 --- a/tools/perf/util/svghelper.h +++ b/tools/perf/util/svghelper.h @@ -4,6 +4,8 @@ #include +struct perf_env; + void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end); void svg_ubox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges); void svg_lbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges); @@ -28,7 +30,7 @@ void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc void svg_interrupt(u64 start, int row, const char *backtrace); void svg_text(int Yslot, u64 start, const char *text); void svg_close(void); -int svg_build_topology_map(char *sib_core, int sib_core_nr, char *sib_thr, int sib_thr_nr); +int svg_build_topology_map(struct perf_env *env); extern int svg_page_width; extern u64 svg_highlight; -- cgit v1.2.3-59-g8ed1b From f78f96676a256d7fa171a54b271a2ad2c6555c9c Mon Sep 17 00:00:00 2001 From: Kyle Meyer Date: Tue, 27 Aug 2019 16:43:47 -0500 Subject: perf svghelper: Replace MAX_NR_CPUS with perf_env::nr_cpus_online 'nr_cpus', the number of CPUs online during a record session bound by MAX_NR_CPUS, can be used as a dynamic alternative for MAX_NR_CPUS in svg_build_topology_map(). The value of nr_cpus can be passed into str_to_bitmap(), scan_core_topology(), and svg_build_topology_map() to replace MAX_NR_CPUS as well. Signed-off-by: Kyle Meyer Reviewed-by: Jiri Olsa Cc: Alexander Shishkin Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Russ Anderson Link: http://lore.kernel.org/lkml/20190827214352.94272-3-meyerk@stormcage.eag.rdlabs.hpecorp.net Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/svghelper.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index 2e9971590590..fef0f8a40e2f 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c @@ -697,7 +697,8 @@ struct topology { int sib_thr_nr; }; -static void scan_thread_topology(int *map, struct topology *t, int cpu, int *pos) +static void scan_thread_topology(int *map, struct topology *t, int cpu, + int *pos, int nr_cpus) { int i; int thr; @@ -706,28 +707,24 @@ static void scan_thread_topology(int *map, struct topology *t, int cpu, int *pos if (!test_bit(cpu, cpumask_bits(&t->sib_thr[i]))) continue; - for_each_set_bit(thr, - cpumask_bits(&t->sib_thr[i]), - MAX_NR_CPUS) + for_each_set_bit(thr, cpumask_bits(&t->sib_thr[i]), nr_cpus) if (map[thr] == -1) map[thr] = (*pos)++; } } -static void scan_core_topology(int *map, struct topology *t) +static void scan_core_topology(int *map, struct topology *t, int nr_cpus) { int pos = 0; int i; int cpu; for (i = 0; i < t->sib_core_nr; i++) - for_each_set_bit(cpu, - cpumask_bits(&t->sib_core[i]), - MAX_NR_CPUS) - scan_thread_topology(map, t, cpu, &pos); + for_each_set_bit(cpu, cpumask_bits(&t->sib_core[i]), nr_cpus) + scan_thread_topology(map, t, cpu, &pos, nr_cpus); } -static int str_to_bitmap(char *s, cpumask_t *b) +static int str_to_bitmap(char *s, cpumask_t *b, int nr_cpus) { int i; int ret = 0; @@ -740,7 +737,7 @@ static int str_to_bitmap(char *s, cpumask_t *b) for (i = 0; i < m->nr; i++) { c = m->map[i]; - if (c >= MAX_NR_CPUS) { + if (c >= nr_cpus) { ret = -1; break; } @@ -755,10 +752,12 @@ static int str_to_bitmap(char *s, cpumask_t *b) int svg_build_topology_map(struct perf_env *env) { - int i; + int i, nr_cpus; struct topology t; char *sib_core, *sib_thr; + nr_cpus = min(env->nr_cpus_online, MAX_NR_CPUS); + t.sib_core_nr = env->nr_sibling_cores; t.sib_thr_nr = env->nr_sibling_threads; t.sib_core = calloc(env->nr_sibling_cores, sizeof(cpumask_t)); @@ -773,7 +772,7 @@ int svg_build_topology_map(struct perf_env *env) } for (i = 0; i < env->nr_sibling_cores; i++) { - if (str_to_bitmap(sib_core, &t.sib_core[i])) { + if (str_to_bitmap(sib_core, &t.sib_core[i], nr_cpus)) { fprintf(stderr, "topology: can't parse siblings map\n"); goto exit; } @@ -782,7 +781,7 @@ int svg_build_topology_map(struct perf_env *env) } for (i = 0; i < env->nr_sibling_threads; i++) { - if (str_to_bitmap(sib_thr, &t.sib_thr[i])) { + if (str_to_bitmap(sib_thr, &t.sib_thr[i], nr_cpus)) { fprintf(stderr, "topology: can't parse siblings map\n"); goto exit; } @@ -790,16 +789,16 @@ int svg_build_topology_map(struct perf_env *env) sib_thr += strlen(sib_thr) + 1; } - topology_map = malloc(sizeof(int) * MAX_NR_CPUS); + topology_map = malloc(sizeof(int) * nr_cpus); if (!topology_map) { fprintf(stderr, "topology: no memory\n"); goto exit; } - for (i = 0; i < MAX_NR_CPUS; i++) + for (i = 0; i < nr_cpus; i++) topology_map[i] = -1; - scan_core_topology(topology_map, &t); + scan_core_topology(topology_map, &t, nr_cpus); return 0; -- cgit v1.2.3-59-g8ed1b From 92b5a1545ad51e8225e691e9a29ba33cc9fe37bc Mon Sep 17 00:00:00 2001 From: Kyle Meyer Date: Tue, 27 Aug 2019 16:43:48 -0500 Subject: perf stat: Replace MAX_NR_CPUS with cpu__max_cpu() The function cpu__max_cpu() returns the possible number of CPUs as defined in the sysfs and can be used as an alternative for MAX_NR_CPUS in zero_per_pkg() and check_per_pkg(). Signed-off-by: Kyle Meyer Reviewed-by: Jiri Olsa Cc: Alexander Shishkin Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Russ Anderson Link: http://lore.kernel.org/lkml/20190827214352.94272-4-meyerk@stormcage.eag.rdlabs.hpecorp.net Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 66f8808e57d3..f6eb6af5f151 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -210,7 +210,7 @@ void perf_evlist__reset_stats(struct evlist *evlist) static void zero_per_pkg(struct evsel *counter) { if (counter->per_pkg_mask) - memset(counter->per_pkg_mask, 0, MAX_NR_CPUS); + memset(counter->per_pkg_mask, 0, cpu__max_cpu()); } static int check_per_pkg(struct evsel *counter, @@ -229,7 +229,7 @@ static int check_per_pkg(struct evsel *counter, return 0; if (!mask) { - mask = zalloc(MAX_NR_CPUS); + mask = zalloc(cpu__max_cpu()); if (!mask) return -ENOMEM; -- cgit v1.2.3-59-g8ed1b From 7df4e36a4785618f0c63f3dc2bacb164780ab0f6 Mon Sep 17 00:00:00 2001 From: Kyle Meyer Date: Tue, 27 Aug 2019 16:43:49 -0500 Subject: perf session: Replace MAX_NR_CPUS with perf_env::nr_cpus_online nr_cpus, the number of CPUs online during a record session bound by MAX_NR_CPUS, can be used as a dynamic alternative for MAX_NR_CPUS in perf_session__cpu_bitmap. Signed-off-by: Kyle Meyer Reviewed-by: Jiri Olsa Cc: Alexander Shishkin Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Russ Anderson Link: http://lore.kernel.org/lkml/20190827214352.94272-5-meyerk@stormcage.eag.rdlabs.hpecorp.net Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 7350b0dfbc1e..13486bcf74a0 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -2292,6 +2292,7 @@ int perf_session__cpu_bitmap(struct perf_session *session, { int i, err = -1; struct perf_cpu_map *map; + int nr_cpus = min(session->header.env.nr_cpus_online, MAX_NR_CPUS); for (i = 0; i < PERF_TYPE_MAX; ++i) { struct evsel *evsel; @@ -2316,7 +2317,7 @@ int perf_session__cpu_bitmap(struct perf_session *session, for (i = 0; i < map->nr; i++) { int cpu = map->map[i]; - if (cpu >= MAX_NR_CPUS) { + if (cpu >= nr_cpus) { pr_err("Requested CPU %d too large. " "Consider raising MAX_NR_CPUS\n", cpu); goto out_delete_map; -- cgit v1.2.3-59-g8ed1b From 8c7274691f0de5fb56f3b9fe9208ce7e515a2d2c Mon Sep 17 00:00:00 2001 From: Kyle Meyer Date: Tue, 27 Aug 2019 16:43:50 -0500 Subject: perf machine: Replace MAX_NR_CPUS with perf_env::nr_cpus_online nr_cpus, the number of CPUs online during a record session bound by MAX_NR_CPUS, can be used as a dynamic alternative for MAX_NR_CPUS in __machine__synthesize_threads and machine__set_current_tid. Signed-off-by: Kyle Meyer Reviewed-by: Jiri Olsa Cc: Alexander Shishkin Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Russ Anderson Link: http://lore.kernel.org/lkml/20190827214352.94272-6-meyerk@stormcage.eag.rdlabs.hpecorp.net Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/machine.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 93483f1764d3..a1542b4c047b 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -2619,7 +2619,9 @@ int __machine__synthesize_threads(struct machine *machine, struct perf_tool *too pid_t machine__get_current_tid(struct machine *machine, int cpu) { - if (cpu < 0 || cpu >= MAX_NR_CPUS || !machine->current_tid) + int nr_cpus = min(machine->env->nr_cpus_online, MAX_NR_CPUS); + + if (cpu < 0 || cpu >= nr_cpus || !machine->current_tid) return -1; return machine->current_tid[cpu]; @@ -2629,6 +2631,7 @@ int machine__set_current_tid(struct machine *machine, int cpu, pid_t pid, pid_t tid) { struct thread *thread; + int nr_cpus = min(machine->env->nr_cpus_online, MAX_NR_CPUS); if (cpu < 0) return -EINVAL; @@ -2636,14 +2639,14 @@ int machine__set_current_tid(struct machine *machine, int cpu, pid_t pid, if (!machine->current_tid) { int i; - machine->current_tid = calloc(MAX_NR_CPUS, sizeof(pid_t)); + machine->current_tid = calloc(nr_cpus, sizeof(pid_t)); if (!machine->current_tid) return -ENOMEM; - for (i = 0; i < MAX_NR_CPUS; i++) + for (i = 0; i < nr_cpus; i++) machine->current_tid[i] = -1; } - if (cpu >= MAX_NR_CPUS) { + if (cpu >= nr_cpus) { pr_err("Requested CPU %d too large. ", cpu); pr_err("Consider raising MAX_NR_CPUS\n"); return -EINVAL; -- cgit v1.2.3-59-g8ed1b From dc84187f32a3e8eb86bd97f3b10494e1f1fe5e7f Mon Sep 17 00:00:00 2001 From: Kyle Meyer Date: Tue, 27 Aug 2019 16:43:51 -0500 Subject: perf header: Replace MAX_NR_CPUS with cpu__max_cpu() The function cpu__max_cpu() returns the possible number of CPUs as defined in the sysfs and can be used as an alternative for MAX_NR_CPUS in write_cache. MAX_CACHES is replaced by cpu__max_cpu() * MAX_CACHE_LVL. Signed-off-by: Kyle Meyer Reviewed-by: Jiri Olsa Cc: Alexander Shishkin Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Russ Anderson Link: http://lore.kernel.org/lkml/20190827214352.94272-7-meyerk@stormcage.eag.rdlabs.hpecorp.net Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/header.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 0a842d9eff22..dd2bb0861ab1 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1122,16 +1122,17 @@ static int build_caches(struct cpu_cache_level caches[], u32 size, u32 *cntp) return 0; } -#define MAX_CACHES (MAX_NR_CPUS * 4) +#define MAX_CACHE_LVL 4 static int write_cache(struct feat_fd *ff, struct evlist *evlist __maybe_unused) { - struct cpu_cache_level caches[MAX_CACHES]; + u32 max_caches = cpu__max_cpu() * MAX_CACHE_LVL; + struct cpu_cache_level caches[max_caches]; u32 cnt = 0, i, version = 1; int ret; - ret = build_caches(caches, MAX_CACHES, &cnt); + ret = build_caches(caches, max_caches, &cnt); if (ret) goto out; -- cgit v1.2.3-59-g8ed1b From df552793493ff83b2b7289389d29d417b3ef6d6d Mon Sep 17 00:00:00 2001 From: Kyle Meyer Date: Tue, 27 Aug 2019 16:43:52 -0500 Subject: libperf: Warn when exceeding MAX_NR_CPUS in cpumap Display a warning when attempting to profile more than MAX_NR_CPU CPUs. This patch should not change any behavior. Signed-off-by: Kyle Meyer Reviewed-by: Jiri Olsa Cc: Alexander Shishkin Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Russ Anderson Link: http://lore.kernel.org/lkml/20190827214352.94272-8-meyerk@stormcage.eag.rdlabs.hpecorp.net Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/cpumap.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tools') diff --git a/tools/perf/lib/cpumap.c b/tools/perf/lib/cpumap.c index 2834753576b2..1f0e6f334237 100644 --- a/tools/perf/lib/cpumap.c +++ b/tools/perf/lib/cpumap.c @@ -100,6 +100,9 @@ struct perf_cpu_map *perf_cpu_map__read(FILE *file) if (prev >= 0) { int new_max = nr_cpus + cpu - prev - 1; + WARN_ONCE(new_max >= MAX_NR_CPUS, "Perf can support %d CPUs. " + "Consider raising MAX_NR_CPUS\n", MAX_NR_CPUS); + if (new_max >= max_entries) { max_entries = new_max + MAX_NR_CPUS / 2; tmp = realloc(tmp_cpus, max_entries * sizeof(int)); @@ -192,6 +195,9 @@ struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list) end_cpu = start_cpu; } + WARN_ONCE(end_cpu >= MAX_NR_CPUS, "Perf can support %d CPUs. " + "Consider raising MAX_NR_CPUS\n", MAX_NR_CPUS); + for (; start_cpu <= end_cpu; start_cpu++) { /* check for duplicates */ for (i = 0; i < nr_cpus; i++) -- cgit v1.2.3-59-g8ed1b From 108a1bb9d1d88bff47d5eccd2cf18dc09a04fb9f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 29 Aug 2019 13:00:28 -0300 Subject: perf tools: Remove needless libtraceevent include directives Remove traceevent/event-parse.h and traceevent/trace-seq.h from places where it is not needed. Should avoid rebuilding those files when these traceevent headers get changed. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Steven Rostedt (VMware) Cc: Tzvetomir Stoyanov Link: https://lkml.kernel.org/n/tip-26hn75jn9rdealn4uqtzend6@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-timechart.c | 1 - tools/perf/util/session.c | 1 - tools/perf/util/trace-event.h | 1 - 3 files changed, 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 1ff81a790931..1a74499f3311 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -10,7 +10,6 @@ #include #include -#include #include "builtin.h" #include "util/color.h" diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 13486bcf74a0..9eb843e5e6f0 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 258d79071d81..2e158387b3d7 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h @@ -3,7 +3,6 @@ #define _PERF_UTIL_TRACE_EVENT_H #include -#include #include "parse-events.h" struct machine; -- cgit v1.2.3-59-g8ed1b From a77494026309711a5f1e4b078e353cd46c2dad9f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 29 Aug 2019 14:40:28 -0300 Subject: perf header: Move CPUINFO_PROC to the only file where it is used To reduce perf-sys.h and eventually nuke it. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-ars2j5m3if3gypsvkbbijucq@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/perf-sys.h | 44 -------------------------------------------- tools/perf/util/header.c | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 44 deletions(-) (limited to 'tools') diff --git a/tools/perf/perf-sys.h b/tools/perf/perf-sys.h index 3eb7a39169f6..6ffb0fbd6237 100644 --- a/tools/perf/perf-sys.h +++ b/tools/perf/perf-sys.h @@ -10,50 +10,6 @@ #include #include -#ifdef __powerpc__ -#define CPUINFO_PROC {"cpu"} -#endif - -#ifdef __s390__ -#define CPUINFO_PROC {"vendor_id"} -#endif - -#ifdef __sh__ -#define CPUINFO_PROC {"cpu type"} -#endif - -#ifdef __hppa__ -#define CPUINFO_PROC {"cpu"} -#endif - -#ifdef __sparc__ -#define CPUINFO_PROC {"cpu"} -#endif - -#ifdef __alpha__ -#define CPUINFO_PROC {"cpu model"} -#endif - -#ifdef __arm__ -#define CPUINFO_PROC {"model name", "Processor"} -#endif - -#ifdef __mips__ -#define CPUINFO_PROC {"cpu model"} -#endif - -#ifdef __arc__ -#define CPUINFO_PROC {"Processor"} -#endif - -#ifdef __xtensa__ -#define CPUINFO_PROC {"core ID"} -#endif - -#ifndef CPUINFO_PROC -#define CPUINFO_PROC { "model name", } -#endif - static inline int sys_perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu, int group_fd, diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index dd2bb0861ab1..d252124f926d 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -436,7 +436,25 @@ done: static int write_cpudesc(struct feat_fd *ff, struct evlist *evlist __maybe_unused) { +#if defined(__powerpc__) || defined(__hppa__) || defined(__sparc__) +#define CPUINFO_PROC { "cpu", } +#elif defined(__s390__) +#define CPUINFO_PROC { "vendor_id", } +#elif defined(__sh__) +#define CPUINFO_PROC { "cpu type", } +#elif defined(__alpha__) || defined(__mips__) +#define CPUINFO_PROC { "cpu model", } +#elif defined(__arm__) +#define CPUINFO_PROC { "model name", "Processor", } +#elif defined(__arc__) +#define CPUINFO_PROC { "Processor", } +#elif defined(__xtensa__) +#define CPUINFO_PROC { "core ID", } +#else +#define CPUINFO_PROC { "model name", } +#endif const char *cpuinfo_procs[] = CPUINFO_PROC; +#undef CPUINFO_PROC unsigned int i; for (i = 0; i < ARRAY_SIZE(cpuinfo_procs); i++) { -- cgit v1.2.3-59-g8ed1b From 91854f9a077e18e43ed30ebe9c61f8089bec9166 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 29 Aug 2019 14:59:50 -0300 Subject: perf tools: Move everything related to sys_perf_event_open() to perf-sys.h And remove unneeded include directives from perf-sys.h to prune the header dependency tree. Fixup the fallout in places where definitions were being used without the needed include directives that were being satisfied because they were in perf-sys.h. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-7b1zvugiwak4ibfa3j6ott7f@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/common.c | 1 + tools/perf/arch/x86/tests/rdpmc.c | 2 +- tools/perf/arch/x86/util/perf_regs.c | 2 +- tools/perf/arch/x86/util/tsc.c | 1 + tools/perf/bench/epoll-ctl.c | 1 + tools/perf/bench/epoll-wait.c | 1 + tools/perf/bench/mem-functions.c | 3 ++- tools/perf/builtin-sched.c | 1 + tools/perf/perf-sys.h | 13 ++++++++++--- tools/perf/perf.c | 1 + tools/perf/perf.h | 12 ------------ tools/perf/tests/attr.c | 2 +- tools/perf/tests/bp_account.c | 2 +- tools/perf/tests/bp_signal.c | 2 +- tools/perf/tests/bp_signal_overflow.c | 2 +- tools/perf/tests/wp.c | 2 ++ tools/perf/util/auxtrace.h | 1 + tools/perf/util/cloexec.c | 2 +- tools/perf/util/evsel.c | 1 + tools/perf/util/genelf.c | 2 ++ tools/perf/util/python.c | 1 + tools/perf/util/record.c | 1 + tools/perf/util/strbuf.c | 1 + 23 files changed, 34 insertions(+), 23 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c index 1a9e22f78c22..a769382fb644 100644 --- a/tools/perf/arch/common.c +++ b/tools/perf/arch/common.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include "common.h" #include "../util/env.h" #include "../util/debug.h" diff --git a/tools/perf/arch/x86/tests/rdpmc.c b/tools/perf/arch/x86/tests/rdpmc.c index 7a11f02d6c6c..345a6a0a328b 100644 --- a/tools/perf/arch/x86/tests/rdpmc.c +++ b/tools/perf/arch/x86/tests/rdpmc.c @@ -7,7 +7,7 @@ #include #include #include -#include "perf.h" +#include "perf-sys.h" #include "debug.h" #include "tests/tests.h" #include "cloexec.h" diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c index 0d7b77ff0ae6..74a606ea42d3 100644 --- a/tools/perf/arch/x86/util/perf_regs.c +++ b/tools/perf/arch/x86/util/perf_regs.c @@ -4,7 +4,7 @@ #include #include -#include "../../perf.h" +#include "../../perf-sys.h" #include "../../util/perf_regs.h" #include "../../util/debug.h" diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c index 81720e27f8a3..a6ba45d0db6e 100644 --- a/tools/perf/arch/x86/util/tsc.c +++ b/tools/perf/arch/x86/util/tsc.c @@ -7,6 +7,7 @@ #include "../../../perf.h" #include +#include #include "../../../util/debug.h" #include "../../../util/tsc.h" diff --git a/tools/perf/bench/epoll-ctl.c b/tools/perf/bench/epoll-ctl.c index 84658d45f349..d1caa4a0a12a 100644 --- a/tools/perf/bench/epoll-ctl.c +++ b/tools/perf/bench/epoll-ctl.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/bench/epoll-wait.c b/tools/perf/bench/epoll-wait.c index c27a65639cfb..f6b4472847d2 100644 --- a/tools/perf/bench/epoll-wait.c +++ b/tools/perf/bench/epoll-wait.c @@ -63,6 +63,7 @@ /* For the CLR_() macros */ #include #include +#include #include #include diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c index 64dc994c72ea..9235b76501be 100644 --- a/tools/perf/bench/mem-functions.c +++ b/tools/perf/bench/mem-functions.c @@ -8,7 +8,7 @@ */ #include "debug.h" -#include "../perf.h" +#include "../perf-sys.h" #include #include "../util/header.h" #include "../util/cloexec.h" @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 025151dcb651..91d0a9b10581 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "builtin.h" #include "perf.h" +#include "perf-sys.h" #include "util/evlist.h" #include "util/cache.h" diff --git a/tools/perf/perf-sys.h b/tools/perf/perf-sys.h index 6ffb0fbd6237..63e4349a772a 100644 --- a/tools/perf/perf-sys.h +++ b/tools/perf/perf-sys.h @@ -5,10 +5,17 @@ #include #include #include -#include #include -#include -#include + +struct perf_event_attr; + +extern bool test_attr__enabled; +void test_attr__ready(void); +void test_attr__init(void); +void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, + int fd, int group_fd, unsigned long flags); + +#define HAVE_ATTR_TEST static inline int sys_perf_event_open(struct perf_event_attr *attr, diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 34763a9b873d..a95a248a7421 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -19,6 +19,7 @@ #include "util/debug.h" #include "util/event.h" #include "util/util.h" +#include "perf-sys.h" #include #include #include diff --git a/tools/perf/perf.h b/tools/perf/perf.h index d9e6b8b957b6..7a1a92127b9b 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -4,18 +4,6 @@ #include #include -#include -#include -#include - -extern bool test_attr__enabled; -void test_attr__ready(void); -void test_attr__init(void); -void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, - int fd, int group_fd, unsigned long flags); - -#define HAVE_ATTR_TEST -#include "perf-sys.h" static inline unsigned long long rdclock(void) { diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c index d8426547219b..87dc3e1174af 100644 --- a/tools/perf/tests/attr.c +++ b/tools/perf/tests/attr.c @@ -30,7 +30,7 @@ #include #include #include -#include "../perf.h" +#include "../perf-sys.h" #include #include "tests.h" diff --git a/tools/perf/tests/bp_account.c b/tools/perf/tests/bp_account.c index 153624e2d0f5..c4a30318d7e0 100644 --- a/tools/perf/tests/bp_account.c +++ b/tools/perf/tests/bp_account.c @@ -19,7 +19,7 @@ #include "tests.h" #include "debug.h" -#include "perf.h" +#include "../perf-sys.h" #include "cloexec.h" volatile long the_var; diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c index 910e25e64188..2d292f8fb3dd 100644 --- a/tools/perf/tests/bp_signal.c +++ b/tools/perf/tests/bp_signal.c @@ -25,7 +25,7 @@ #include "tests.h" #include "debug.h" -#include "perf.h" +#include "perf-sys.h" #include "cloexec.h" static int fd1; diff --git a/tools/perf/tests/bp_signal_overflow.c b/tools/perf/tests/bp_signal_overflow.c index ca962559e845..101315a3b34f 100644 --- a/tools/perf/tests/bp_signal_overflow.c +++ b/tools/perf/tests/bp_signal_overflow.c @@ -24,7 +24,7 @@ #include "tests.h" #include "debug.h" -#include "perf.h" +#include "../perf-sys.h" #include "cloexec.h" static int overflows; diff --git a/tools/perf/tests/wp.c b/tools/perf/tests/wp.c index f89e6806557b..982ac55d69ea 100644 --- a/tools/perf/tests/wp.c +++ b/tools/perf/tests/wp.c @@ -1,10 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include #include "tests.h" #include "debug.h" #include "cloexec.h" +#include "../perf-sys.h" #define WP_TEST_ASSERT_VAL(fd, text, val) \ do { \ diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index b213e6431d88..1fa8a965b03f 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -15,6 +15,7 @@ #include #include #include +#include #include "../perf.h" #include "event.h" diff --git a/tools/perf/util/cloexec.c b/tools/perf/util/cloexec.c index 06f48312c5ed..92d08198e64a 100644 --- a/tools/perf/util/cloexec.c +++ b/tools/perf/util/cloexec.c @@ -2,7 +2,7 @@ #include #include #include "util.h" -#include "../perf.h" +#include "../perf-sys.h" #include "cloexec.h" #include "asm/bug.h" #include "debug.h" diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index dbc04e1053a9..b6b406a1678f 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -41,6 +41,7 @@ #include "string2.h" #include "memswap.h" #include "util.h" +#include "../perf-sys.h" #include "util/parse-branch-options.h" #include diff --git a/tools/perf/util/genelf.c b/tools/perf/util/genelf.c index 7001247ebbd6..bc32f405b26e 100644 --- a/tools/perf/util/genelf.c +++ b/tools/perf/util/genelf.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,7 @@ #include "perf.h" #include "genelf.h" #include "../util/jitdump.h" +#include #ifndef NT_GNU_BUILD_ID #define NT_GNU_BUILD_ID 3 diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 11479a7ad1c7..9dd83871aafe 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -14,6 +14,7 @@ #include "thread_map.h" #include "mmap.h" #include "util.h" +#include "../perf-sys.h" #if PY_MAJOR_VERSION < 3 #define _PyUnicode_FromString(arg) \ diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 574507d46c98..c67a51397bc7 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -10,6 +10,7 @@ #include "util.h" #include "cloexec.h" #include "record.h" +#include "../perf-sys.h" typedef void (*setup_probe_fn_t)(struct evsel *evsel); diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c index 2ce0dc887364..0afdbf38a2b2 100644 --- a/tools/perf/util/strbuf.c +++ b/tools/perf/util/strbuf.c @@ -4,6 +4,7 @@ #include #include #include +#include /* * Used as the default ->buf value, so that people can always assume -- cgit v1.2.3-59-g8ed1b From f37110205c3065546d6995b1463751c7bbb50e89 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 29 Aug 2019 15:16:27 -0300 Subject: perf time-utils: Adopt rdclock() from perf.h Seems to be a better place for this function to live, further shrinking the hodge-podge that perf.h was. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-0zzt1u9rpyjukdy1ccr2u5r9@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 1 + tools/perf/perf.h | 9 --------- tools/perf/util/event.c | 1 + tools/perf/util/time-utils.h | 9 +++++++++ 4 files changed, 11 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index a7e8c26635db..2741bcb049fb 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -62,6 +62,7 @@ #include "util/string2.h" #include "util/metricgroup.h" #include "util/target.h" +#include "util/time-utils.h" #include "util/top.h" #include "asm/bug.h" diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 7a1a92127b9b..74014033df60 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -2,17 +2,8 @@ #ifndef _PERF_PERF_H #define _PERF_PERF_H -#include #include -static inline unsigned long long rdclock(void) -{ - struct timespec ts; - - clock_gettime(CLOCK_MONOTONIC, &ts); - return ts.tv_sec * 1000000000ULL + ts.tv_nsec; -} - #ifndef MAX_NR_CPUS #define MAX_NR_CPUS 2048 #endif diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index c9d1f83c747a..7fa7a303e476 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -21,6 +21,7 @@ #include "strlist.h" #include "thread.h" #include "thread_map.h" +#include "time-utils.h" #include #include "map.h" #include "symbol.h" diff --git a/tools/perf/util/time-utils.h b/tools/perf/util/time-utils.h index 72a42ea1d513..4f42988eb2f7 100644 --- a/tools/perf/util/time-utils.h +++ b/tools/perf/util/time-utils.h @@ -3,6 +3,7 @@ #define _TIME_UTILS_H_ #include +#include #include struct perf_time_interval { @@ -34,4 +35,12 @@ int timestamp__scnprintf_nsec(u64 timestamp, char *buf, size_t sz); int fetch_current_timestamp(char *buf, size_t sz); +static inline unsigned long long rdclock(void) +{ + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + return ts.tv_sec * 1000000000ULL + ts.tv_nsec; +} + #endif -- cgit v1.2.3-59-g8ed1b From c1a604dff486399ae0be95e6396e0158df95ad5d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 29 Aug 2019 15:20:59 -0300 Subject: perf tools: Remove needless perf.h include directive from headers Its not needed there, add it to the places that need it and were getting it via those headers. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-5yulx1u16vyd0zmrbg1tjhju@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-c2c.c | 1 + tools/perf/builtin-diff.c | 1 + tools/perf/builtin-record.c | 1 + tools/perf/builtin-script.c | 1 + tools/perf/builtin-stat.c | 1 + tools/perf/builtin-trace.c | 1 + tools/perf/perf.c | 1 + tools/perf/ui/browsers/hists.c | 1 + tools/perf/ui/browsers/res_sample.c | 1 + tools/perf/ui/browsers/scripts.c | 1 + tools/perf/ui/hist.c | 1 + tools/perf/ui/tui/setup.c | 1 + tools/perf/util/auxtrace.h | 1 - tools/perf/util/callchain.c | 1 + tools/perf/util/event.c | 1 + tools/perf/util/event.h | 1 - tools/perf/util/evlist.c | 1 + tools/perf/util/evlist.h | 1 - tools/perf/util/mmap.c | 1 + tools/perf/util/session.c | 1 + tools/perf/util/top.c | 1 + 21 files changed, 18 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index 8335a4076a5a..25a5f186dfde 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -35,6 +35,7 @@ #include "thread.h" #include "mem2node.h" #include "symbol.h" +#include "../perf.h" struct c2c_hists { struct hists hists; diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 51c37e53b3d8..ae4a8ebf90d2 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -6,6 +6,7 @@ * DSOs and symbol information, sort them and produce a diff. */ #include "builtin.h" +#include "perf.h" #include "util/debug.h" #include "util/event.h" diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index bd2a0cc6eb52..56705d2a6bec 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -42,6 +42,7 @@ #include "util/units.h" #include "util/bpf-event.h" #include "asm/bug.h" +#include "perf.h" #include #include diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 37297b67905d..f3b31c6ed15f 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -53,6 +53,7 @@ #include #include "util/record.h" #include "util/util.h" +#include "perf.h" #include diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 2741bcb049fb..fa4212dac9bb 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -41,6 +41,7 @@ */ #include "builtin.h" +#include "perf.h" #include "util/cgroup.h" #include #include "util/parse-events.h" diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 6d9805a8791b..105695033ebc 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -51,6 +51,7 @@ #include "string2.h" #include "syscalltbl.h" #include "rb_resort.h" +#include "../perf.h" #include #include diff --git a/tools/perf/perf.c b/tools/perf/perf.c index a95a248a7421..237b9b3a1bf1 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -8,6 +8,7 @@ * perf top, perf record, perf report, etc.) are started. */ #include "builtin.h" +#include "perf.h" #include "util/env.h" #include diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 30547fdb0787..ccc37284860b 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -22,6 +22,7 @@ #include "../../util/top.h" #include "../../util/thread.h" #include "../../arch/common.h" +#include "../../perf.h" #include "../browsers/hists.h" #include "../helpline.h" diff --git a/tools/perf/ui/browsers/res_sample.c b/tools/perf/ui/browsers/res_sample.c index 41a9d8923ec4..db3954fea74c 100644 --- a/tools/perf/ui/browsers/res_sample.c +++ b/tools/perf/ui/browsers/res_sample.c @@ -8,6 +8,7 @@ #include "time-utils.h" #include "../util.h" #include "../../util/util.h" +#include "../../perf.h" #include #include diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c index 50e0c03171f2..e63f3778d75c 100644 --- a/tools/perf/ui/browsers/scripts.c +++ b/tools/perf/ui/browsers/scripts.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "../../builtin.h" +#include "../../perf.h" #include "../../util/sort.h" #include "../../util/util.h" #include "../../util/hist.h" diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index e5fb64347b2c..ae29f16979ac 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -9,6 +9,7 @@ #include "../util/sort.h" #include "../util/evsel.h" #include "../util/evlist.h" +#include "../perf.h" /* hist period print (hpp) functions */ diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c index 3ad0d3363ac6..2881982b483c 100644 --- a/tools/perf/ui/tui/setup.c +++ b/tools/perf/ui/tui/setup.c @@ -11,6 +11,7 @@ #include "../../util/cache.h" #include "../../util/debug.h" #include "../../util/util.h" +#include "../../perf.h" #include "../browser.h" #include "../helpline.h" #include "../ui.h" diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index 1fa8a965b03f..bc39cc5610a8 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -17,7 +17,6 @@ #include #include -#include "../perf.h" #include "event.h" #include "session.h" #include "debug.h" diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index dd6e01000385..a47d0e8c2434 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -28,6 +28,7 @@ #include "callchain.h" #include "branch.h" #include "symbol.h" +#include "../perf.h" #define CALLCHAIN_PARAM_DEFAULT \ .mode = CHAIN_GRAPH_ABS, \ diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 7fa7a303e476..ef7fc574f701 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -30,6 +30,7 @@ #include "stat.h" #include "session.h" #include "bpf-event.h" +#include "../perf.h" #define DEFAULT_PROC_MAP_PARSE_TIMEOUT 500 diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 4c0c5232bd41..f56d268f06e3 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -9,7 +9,6 @@ #include #include -#include "../perf.h" #include "build-id.h" #include "perf_regs.h" diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 253dd8dd0e12..71b231c7097f 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -17,6 +17,7 @@ #include "debug.h" #include "units.h" #include "util.h" +#include "../perf.h" #include "asm/bug.h" #include "bpf-event.h" #include diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 16796de7af3f..ee288644e9e4 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -9,7 +9,6 @@ #include #include #include -#include "../perf.h" #include "event.h" #include "evsel.h" #include "mmap.h" diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 5f3532e51ec9..28477ff5114e 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -16,6 +16,7 @@ #include "debug.h" #include "event.h" #include "mmap.h" +#include "../perf.h" #include "util.h" /* page_size */ size_t perf_mmap__mmap_len(struct perf_mmap *map) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 9eb843e5e6f0..82bd5d4361f0 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -29,6 +29,7 @@ #include "sample-raw.h" #include "stat.h" #include "util.h" +#include "../perf.h" #include "arch/common.h" #ifdef HAVE_ZSTD_SUPPORT diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c index e5b690cf2898..51fb574998bb 100644 --- a/tools/perf/util/top.c +++ b/tools/perf/util/top.c @@ -12,6 +12,7 @@ #include "parse-events.h" #include "symbol.h" #include "top.h" +#include "../perf.h" #include #define SNPRINTF(buf, size, fmt, args...) \ -- cgit v1.2.3-59-g8ed1b From 0ac25fd0a04d8bd52ceac2476e71a4e497489987 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 29 Aug 2019 15:42:40 -0300 Subject: perf tools: Remove perf.h from source files not needing it With the movement of lots of stuff out of perf.h to other headers we ended up not needing it in lots of places, remove it from those places. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-c718m0sxxwp73lp9d8vpihb4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/powerpc/util/perf_regs.c | 1 - tools/perf/arch/x86/tests/intel-cqm.c | 1 - tools/perf/arch/x86/util/archinsn.c | 1 - tools/perf/arch/x86/util/tsc.c | 1 - tools/perf/bench/numa.c | 1 - tools/perf/bench/sched-messaging.c | 1 - tools/perf/bench/sched-pipe.c | 1 - tools/perf/builtin-bench.c | 1 - tools/perf/builtin-buildid-cache.c | 1 - tools/perf/builtin-buildid-list.c | 1 - tools/perf/builtin-config.c | 2 -- tools/perf/builtin-ftrace.c | 1 - tools/perf/builtin-help.c | 1 - tools/perf/builtin-inject.c | 1 - tools/perf/builtin-list.c | 2 -- tools/perf/builtin-probe.c | 1 - tools/perf/scripts/perl/Perf-Trace-Util/Context.c | 1 - tools/perf/scripts/python/Perf-Trace-Util/Context.c | 1 - tools/perf/tests/hists_common.c | 1 - tools/perf/tests/hists_cumulate.c | 1 - tools/perf/tests/hists_filter.c | 1 - tools/perf/tests/hists_link.c | 1 - tools/perf/tests/hists_output.c | 1 - tools/perf/ui/browser.c | 1 - tools/perf/util/bpf-loader.c | 1 - tools/perf/util/bpf-prologue.c | 1 - tools/perf/util/branch.c | 1 - tools/perf/util/cacheline.c | 1 - tools/perf/util/cgroup.c | 1 - tools/perf/util/cpumap.c | 1 - tools/perf/util/debug.c | 2 -- tools/perf/util/event.c | 1 - tools/perf/util/genelf.c | 1 - tools/perf/util/genelf_debug.c | 1 - tools/perf/util/header.c | 1 - tools/perf/util/intel-pt.c | 1 - tools/perf/util/parse-branch-options.c | 1 - tools/perf/util/parse-events.c | 1 - tools/perf/util/scripting-engines/trace-event-perl.c | 1 - tools/perf/util/scripting-engines/trace-event-python.c | 1 - tools/perf/util/svghelper.c | 1 - tools/perf/util/thread.c | 1 - tools/perf/util/time-utils.c | 1 - tools/perf/util/trace-event-info.c | 1 - tools/perf/util/trace-event-parse.c | 1 - tools/perf/util/trace-event-read.c | 1 - tools/perf/util/trace-event-scripting.c | 1 - tools/perf/util/util.c | 1 - 48 files changed, 51 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/powerpc/util/perf_regs.c b/tools/perf/arch/powerpc/util/perf_regs.c index f14102b85509..e9c436eeffc9 100644 --- a/tools/perf/arch/powerpc/util/perf_regs.c +++ b/tools/perf/arch/powerpc/util/perf_regs.c @@ -4,7 +4,6 @@ #include #include -#include "../../perf.h" #include "../../util/perf_regs.h" #include "../../util/debug.h" diff --git a/tools/perf/arch/x86/tests/intel-cqm.c b/tools/perf/arch/x86/tests/intel-cqm.c index 2a105e3b2ad1..3b5cc3373821 100644 --- a/tools/perf/arch/x86/tests/intel-cqm.c +++ b/tools/perf/arch/x86/tests/intel-cqm.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 #include "tests/tests.h" -#include "perf.h" #include "cloexec.h" #include "debug.h" #include "evlist.h" diff --git a/tools/perf/arch/x86/util/archinsn.c b/tools/perf/arch/x86/util/archinsn.c index 4237bb2e7fa2..62e8e1820132 100644 --- a/tools/perf/arch/x86/util/archinsn.c +++ b/tools/perf/arch/x86/util/archinsn.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#include "perf.h" #include "archinsn.h" #include "util/intel-pt-decoder/insn.h" #include "machine.h" diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c index a6ba45d0db6e..c5197a15119b 100644 --- a/tools/perf/arch/x86/util/tsc.c +++ b/tools/perf/arch/x86/util/tsc.c @@ -5,7 +5,6 @@ #include #include -#include "../../../perf.h" #include #include #include "../../../util/debug.h" diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index 513cb2f2fa32..62b8ef4bcb1f 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c @@ -9,7 +9,6 @@ /* For the CLR_() macros */ #include -#include "../perf.h" #include "../builtin.h" #include #include "../util/cloexec.h" diff --git a/tools/perf/bench/sched-messaging.c b/tools/perf/bench/sched-messaging.c index f9d7641ae833..c63eb9a46346 100644 --- a/tools/perf/bench/sched-messaging.c +++ b/tools/perf/bench/sched-messaging.c @@ -10,7 +10,6 @@ * */ -#include "../perf.h" #include "../util/util.h" #include #include "../builtin.h" diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c index 0591be008f2a..35b07f197d48 100644 --- a/tools/perf/bench/sched-pipe.c +++ b/tools/perf/bench/sched-pipe.c @@ -9,7 +9,6 @@ * http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c * Ported to perf by Hitoshi Mitake */ -#include "../perf.h" #include "../util/util.h" #include #include "../builtin.h" diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c index b8e7c38ef221..c06fe21c8613 100644 --- a/tools/perf/builtin-bench.c +++ b/tools/perf/builtin-bench.c @@ -16,7 +16,6 @@ * futex ... Futex performance * epoll ... Event poll performance */ -#include "perf.h" #include #include "builtin.h" #include "bench/bench.h" diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index 7dde3ef0398f..9e756004ef28 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -14,7 +14,6 @@ #include #include #include "builtin.h" -#include "perf.h" #include "namespaces.h" #include "util/cache.h" #include "util/debug.h" diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index f403e19488b5..72bdc0eba990 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -1,4 +1,3 @@ -// SPDX-License-Identifier: GPL-2.0 /* * builtin-buildid-list.c * diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index 6c1284c87aaa..edfc8f76f1bd 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -7,8 +7,6 @@ */ #include "builtin.h" -#include "perf.h" - #include "util/cache.h" #include #include "util/util.h" diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 565db782c1b9..7374f86833fd 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -6,7 +6,6 @@ */ #include "builtin.h" -#include "perf.h" #include #include diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c index a83af92fb0d1..641d4a3f93c3 100644 --- a/tools/perf/builtin-help.c +++ b/tools/perf/builtin-help.c @@ -4,7 +4,6 @@ * * Builtin help command */ -#include "perf.h" #include "util/config.h" #include "builtin.h" #include diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 040142581d20..ae46de46e826 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -8,7 +8,6 @@ */ #include "builtin.h" -#include "perf.h" #include "util/color.h" #include "util/evlist.h" #include "util/evsel.h" diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index e0312a1c4792..dca0d33c1343 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -10,8 +10,6 @@ */ #include "builtin.h" -#include "perf.h" - #include "util/parse-events.h" #include "util/cache.h" #include "util/pmu.h" diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 3d0ffd41fb55..f45fd7e9723e 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -16,7 +16,6 @@ #include #include -#include "perf.h" #include "builtin.h" #include "namespaces.h" #include "util/strlist.h" diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Context.c b/tools/perf/scripts/perl/Perf-Trace-Util/Context.c index ead521dd8d79..25c47d23a130 100644 --- a/tools/perf/scripts/perl/Perf-Trace-Util/Context.c +++ b/tools/perf/scripts/perl/Perf-Trace-Util/Context.c @@ -19,7 +19,6 @@ #include "EXTERN.h" #include "perl.h" #include "XSUB.h" -#include "../../../perf.h" #include "../../../util/trace-event.h" #ifndef PERL_UNUSED_VAR diff --git a/tools/perf/scripts/python/Perf-Trace-Util/Context.c b/tools/perf/scripts/python/Perf-Trace-Util/Context.c index 217568bc29ce..0b7096847991 100644 --- a/tools/perf/scripts/python/Perf-Trace-Util/Context.c +++ b/tools/perf/scripts/python/Perf-Trace-Util/Context.c @@ -6,7 +6,6 @@ */ #include -#include "../../../perf.h" #include "../../../util/trace-event.h" #if PY_MAJOR_VERSION < 3 diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c index 469958cd7fe0..96ad95d3f338 100644 --- a/tools/perf/tests/hists_common.c +++ b/tools/perf/tests/hists_common.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 #include -#include "perf.h" #include "util/debug.h" #include "util/map.h" #include "util/symbol.h" diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index 1f3de85ae18b..93af420ad2e4 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#include "perf.h" #include "util/debug.h" #include "util/event.h" #include "util/map.h" diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index a274716fc438..41dede2f40d8 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#include "perf.h" #include "util/debug.h" #include "util/map.h" #include "util/symbol.h" diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index b25383aa2e6e..012fe8ac0b24 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#include "perf.h" #include "tests.h" #include "debug.h" #include "symbol.h" diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index 009888adf4b3..07f4ca0704fb 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#include "perf.h" #include "util/debug.h" #include "util/event.h" #include "util/map.h" diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index c797a853d3a0..f93d40b1c203 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -2,7 +2,6 @@ #include "../util/util.h" #include "../util/string2.h" #include "../util/config.h" -#include "../perf.h" #include "libslang.h" #include "ui.h" #include "util.h" diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index 80a828e75cf6..c1a57323e25d 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -14,7 +14,6 @@ #include #include #include -#include "perf.h" #include "debug.h" #include "evlist.h" #include "bpf-loader.h" diff --git a/tools/perf/util/bpf-prologue.c b/tools/perf/util/bpf-prologue.c index 77e4891e17b0..09e6c76e1c3b 100644 --- a/tools/perf/util/bpf-prologue.c +++ b/tools/perf/util/bpf-prologue.c @@ -8,7 +8,6 @@ */ #include -#include "perf.h" #include "debug.h" #include "bpf-loader.h" #include "bpf-prologue.h" diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c index a4fce2729e50..02d6d839ff24 100644 --- a/tools/perf/util/branch.c +++ b/tools/perf/util/branch.c @@ -1,4 +1,3 @@ -#include "perf.h" #include "util/util.h" #include "util/debug.h" #include "util/branch.h" diff --git a/tools/perf/util/cacheline.c b/tools/perf/util/cacheline.c index 9361d3f61f75..e98b5250a517 100644 --- a/tools/perf/util/cacheline.c +++ b/tools/perf/util/cacheline.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 #include "cacheline.h" -#include "../perf.h" #include #ifdef _SC_LEVEL1_DCACHE_LINESIZE diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index f73599f271ff..96a931c6f728 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#include "../perf.h" #include #include "evsel.h" #include "cgroup.h" diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index b9301e7e9c76..a22c1114e880 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 #include -#include "../perf.h" #include "cpumap.h" #include "debug.h" #include "event.h" diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index 3780fe42453b..c822c5943340 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c @@ -1,8 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* For general debugging purposes */ -#include "../perf.h" - #include #include #include diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index ef7fc574f701..54169ad335c7 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1,4 +1,3 @@ -// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/util/genelf.c b/tools/perf/util/genelf.c index bc32f405b26e..f9f18b8b1df9 100644 --- a/tools/perf/util/genelf.c +++ b/tools/perf/util/genelf.c @@ -23,7 +23,6 @@ #include #endif -#include "perf.h" #include "genelf.h" #include "../util/jitdump.h" #include diff --git a/tools/perf/util/genelf_debug.c b/tools/perf/util/genelf_debug.c index 995e490c17fa..30e9f618f6cd 100644 --- a/tools/perf/util/genelf_debug.c +++ b/tools/perf/util/genelf_debug.c @@ -24,7 +24,6 @@ #include #include -#include "perf.h" #include "genelf.h" #include "../util/jitdump.h" diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index d252124f926d..20fb06162fd4 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -26,7 +26,6 @@ #include "evsel.h" #include "header.h" #include "memswap.h" -#include "../perf.h" #include "trace-event.h" #include "session.h" #include "symbol.h" diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 825a6a3b03a1..825e3690940d 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -12,7 +12,6 @@ #include #include -#include "../perf.h" #include "session.h" #include "machine.h" #include "memswap.h" diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c index 4ed20c833d44..1430437b9d51 100644 --- a/tools/perf/util/parse-branch-options.c +++ b/tools/perf/util/parse-branch-options.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#include "perf.h" #include "util/debug.h" #include #include "util/parse-branch-options.h" diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 9101568946d2..5f1ba6820cdd 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -10,7 +10,6 @@ #include #include #include "term.h" -#include "../perf.h" #include "evlist.h" #include "evsel.h" #include diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index 01ebf10b8bf4..800e82d35230 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c @@ -34,7 +34,6 @@ #include #include -#include "../../perf.h" #include "../callchain.h" #include "../machine.h" #include "../map.h" diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 78c8bc9380bd..abfde356be18 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -31,7 +31,6 @@ #include #include -#include "../../perf.h" #include "../counts.h" #include "../debug.h" #include "../callchain.h" diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index fef0f8a40e2f..582f4a69cd48 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c @@ -20,7 +20,6 @@ #include #include "env.h" -#include "perf.h" #include "svghelper.h" #include "cpumap.h" diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index dbcb9cfb0f2f..5ba1601e8860 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#include "../perf.h" #include #include #include diff --git a/tools/perf/util/time-utils.c b/tools/perf/util/time-utils.c index c2abc259b51d..9796a2e43f67 100644 --- a/tools/perf/util/time-utils.c +++ b/tools/perf/util/time-utils.c @@ -10,7 +10,6 @@ #include #include -#include "perf.h" #include "debug.h" #include "time-utils.h" #include "session.h" diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index 2f8a0601a546..d63d542b2cde 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c @@ -20,7 +20,6 @@ #include #include -#include "../perf.h" #include "trace-event.h" #include #include "evsel.h" diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index b3982e1bb4c5..8e31a63045c3 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c @@ -7,7 +7,6 @@ #include #include -#include "../perf.h" #include "debug.h" #include "trace-event.h" diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c index 13c1cf60d1bc..b6c0db068be0 100644 --- a/tools/perf/util/trace-event-read.c +++ b/tools/perf/util/trace-event-read.c @@ -15,7 +15,6 @@ #include #include -#include "../perf.h" #include "util.h" #include "trace-event.h" #include "debug.h" diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c index dfd2640c763a..714581b0de65 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c @@ -10,7 +10,6 @@ #include #include -#include "../perf.h" #include "debug.h" #include "trace-event.h" #include diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 44211e483fbf..607daec22943 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#include "../perf.h" #include "util.h" #include "debug.h" #include "namespaces.h" -- cgit v1.2.3-59-g8ed1b From b42090256fba05dce1a0482a4ccd9bb6464cc499 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 29 Aug 2019 15:56:40 -0300 Subject: perf tools: Remove debug.h from header files not needing it And fix the fallout, adding it to places that must have it since they use its definitions. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-1s3jel4i26chq2g0lydoz7i3@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/auxtrace.c | 1 + tools/perf/arch/arm/util/cs-etm.c | 1 + tools/perf/arch/x86/tests/perf-time-to-tsc.c | 1 + tools/perf/tests/code-reading.c | 1 + tools/perf/tests/keep-tracking.c | 1 + tools/perf/tests/mmap-basic.c | 1 + tools/perf/tests/sw-clock.c | 2 ++ tools/perf/tests/switch-tracking.c | 1 + tools/perf/tests/task-exit.c | 1 + tools/perf/ui/browsers/annotate.c | 1 + tools/perf/ui/browsers/hists.c | 1 + tools/perf/ui/hist.c | 1 + tools/perf/util/auxtrace.h | 2 +- tools/perf/util/config.c | 1 + tools/perf/util/hist.c | 1 + tools/perf/util/llvm-utils.h | 2 +- tools/perf/util/metricgroup.c | 2 ++ tools/perf/util/python.c | 1 + tools/perf/util/record.c | 1 + tools/perf/util/session.c | 1 + tools/perf/util/sort.c | 1 + tools/perf/util/stat.c | 1 + tools/perf/util/trigger.h | 1 - 23 files changed, 24 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c index 41b78f74599f..0a6e75b8777a 100644 --- a/tools/perf/arch/arm/util/auxtrace.c +++ b/tools/perf/arch/arm/util/auxtrace.c @@ -9,6 +9,7 @@ #include #include "../../util/auxtrace.h" +#include "../../util/debug.h" #include "../../util/evlist.h" #include "../../util/pmu.h" #include "cs-etm.h" diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 9644e2d405f7..b74fd408d496 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -15,6 +15,7 @@ #include #include "cs-etm.h" +#include "../../util/debug.h" #include "../../util/record.h" #include "../../util/auxtrace.h" #include "../../util/cpumap.h" diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index 02776109ba46..2d1f4713b728 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -9,6 +9,7 @@ #include #include +#include "debug.h" #include "parse-events.h" #include "evlist.h" #include "evsel.h" diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index fe671b860086..c4b73bb4b113 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -11,6 +11,7 @@ #include #include +#include "debug.h" #include "parse-events.h" #include "evlist.h" #include "evsel.h" diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 2af6faf1bbd6..c758798d3774 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -5,6 +5,7 @@ #include #include +#include "debug.h" #include "parse-events.h" #include "evlist.h" #include "evsel.h" diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 7327694fbde0..fe91350fd5ab 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -5,6 +5,7 @@ #include #include +#include "debug.h" #include "evlist.h" #include "evsel.h" #include "thread_map.h" diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index c5f1a9f83380..97694a040986 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -5,8 +5,10 @@ #include #include #include +#include #include "tests.h" +#include "util/debug.h" #include "util/evsel.h" #include "util/evlist.h" #include "util/cpumap.h" diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index b63f02768724..4bed15aee1a8 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -8,6 +8,7 @@ #include #include +#include "debug.h" #include "parse-events.h" #include "evlist.h" #include "evsel.h" diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index d79a22e2d8be..0e0e0627184e 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include "debug.h" #include "evlist.h" #include "evsel.h" #include "target.h" diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index e633eb42550d..715601f5fce3 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -4,6 +4,7 @@ #include "../ui.h" #include "../util.h" #include "../../util/annotate.h" +#include "../../util/debug.h" #include "../../util/hist.h" #include "../../util/sort.h" #include "../../util/map.h" diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index ccc37284860b..a14dda74f43a 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -11,6 +11,7 @@ #include #include +#include "../../util/debug.h" #include "../../util/callchain.h" #include "../../util/evsel.h" #include "../../util/evlist.h" diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index ae29f16979ac..bf90ce5b2cdf 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -4,6 +4,7 @@ #include #include "../util/callchain.h" +#include "../util/debug.h" #include "../util/hist.h" #include "../util/util.h" #include "../util/sort.h" diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index bc39cc5610a8..b5ac24c770d4 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -19,7 +19,6 @@ #include "event.h" #include "session.h" -#include "debug.h" union perf_event; struct perf_session; @@ -614,6 +613,7 @@ void itrace_synth_opts__clear_time_range(struct itrace_synth_opts *opts) } #else +#include "debug.h" static inline struct auxtrace_record * auxtrace_record__init(struct evlist *evlist __maybe_unused, diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 042ffbc8c53f..eb5308c41ed1 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -18,6 +18,7 @@ #include "util/hist.h" /* perf_hist_config */ #include "util/llvm-utils.h" /* perf_llvm_config */ #include "config.h" +#include "debug.h" #include #include #include diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index e0b149673a88..adae4134e972 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "callchain.h" +#include "debug.h" #include "build-id.h" #include "hist.h" #include "map.h" diff --git a/tools/perf/util/llvm-utils.h b/tools/perf/util/llvm-utils.h index bf3f3f4c4fe2..7878a0e3fa98 100644 --- a/tools/perf/util/llvm-utils.h +++ b/tools/perf/util/llvm-utils.h @@ -6,7 +6,7 @@ #ifndef __LLVM_UTILS_H #define __LLVM_UTILS_H -#include "debug.h" +#include struct llvm_param { /* Path of clang executable */ diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index aaf55444f81b..33f5e2101874 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -6,6 +6,7 @@ /* Manage metrics and groups of metrics from JSON files */ #include "metricgroup.h" +#include "debug.h" #include "evlist.h" #include "evsel.h" #include "strbuf.h" @@ -18,6 +19,7 @@ #include "strlist.h" #include #include +#include #include #include diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 9dd83871aafe..9b350482c403 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -5,6 +5,7 @@ #include #include #include +#include "debug.h" #include "evlist.h" #include "callchain.h" #include "evsel.h" diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index c67a51397bc7..ccad796bce5f 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include "debug.h" #include "evlist.h" #include "evsel.h" #include "cpumap.h" diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 82bd5d4361f0..a72774e4463f 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -12,6 +12,7 @@ #include #include +#include "debug.h" #include "evlist.h" #include "evsel.h" #include "memswap.h" diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 83eb3fa6f941..23d0ab7c801c 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -4,6 +4,7 @@ #include #include #include +#include "debug.h" #include "sort.h" #include "hist.h" #include "cacheline.h" diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index f6eb6af5f151..f4a1edcec7b2 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -3,6 +3,7 @@ #include #include #include "counts.h" +#include "debug.h" #include "stat.h" #include "target.h" #include "evlist.h" diff --git a/tools/perf/util/trigger.h b/tools/perf/util/trigger.h index 88223bc7c82b..33e997f9ccc8 100644 --- a/tools/perf/util/trigger.h +++ b/tools/perf/util/trigger.h @@ -2,7 +2,6 @@ #ifndef __TRIGGER_H_ #define __TRIGGER_H_ 1 -#include "util/debug.h" #include "asm/bug.h" /* -- cgit v1.2.3-59-g8ed1b From d78c620a2e824d7b01a6e991208a8aa2c938cabe Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 26 Aug 2019 17:54:54 -0700 Subject: libnvdimm/security: Introduce a 'frozen' attribute In the process of debugging a system with an NVDIMM that was failing to unlock it was found that the kernel is reporting 'locked' while the DIMM security interface is 'frozen'. Unfortunately the security state is tracked internally as an enum which prevents it from communicating the difference between 'locked' and 'locked + frozen'. It follows that the enum also prevents the kernel from communicating 'unlocked + frozen' which would be useful for debugging why security operations like 'change passphrase' are disabled. Ditch the security state enum for a set of flags and introduce a new sysfs attribute explicitly for the 'frozen' state. The regression risk is low because the 'frozen' state was already blocked behind the 'locked' state, but will need to revisit if there were cases where applications need 'frozen' to show up in the primary 'security' attribute. The expectation is that communicating 'frozen' is mostly a helper for debug and status monitoring. Reviewed-by: Dave Jiang Reported-by: Jeff Moyer Reviewed-by: Jeff Moyer Link: https://lore.kernel.org/r/156686729474.184120.5835135644278860826.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams --- drivers/acpi/nfit/intel.c | 59 +++++++++++++----------- drivers/nvdimm/bus.c | 2 +- drivers/nvdimm/dimm_devs.c | 59 ++++++++++++++---------- drivers/nvdimm/nd-core.h | 21 +++++++-- drivers/nvdimm/security.c | 99 +++++++++++++++++++--------------------- include/linux/libnvdimm.h | 9 ++-- tools/testing/nvdimm/dimm_devs.c | 19 ++------ 7 files changed, 141 insertions(+), 127 deletions(-) (limited to 'tools') diff --git a/drivers/acpi/nfit/intel.c b/drivers/acpi/nfit/intel.c index cddd0fcf622c..1113b679cd7b 100644 --- a/drivers/acpi/nfit/intel.c +++ b/drivers/acpi/nfit/intel.c @@ -7,10 +7,11 @@ #include "intel.h" #include "nfit.h" -static enum nvdimm_security_state intel_security_state(struct nvdimm *nvdimm, +static unsigned long intel_security_flags(struct nvdimm *nvdimm, enum nvdimm_passphrase_type ptype) { struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); + unsigned long security_flags = 0; struct { struct nd_cmd_pkg pkg; struct nd_intel_get_security_state cmd; @@ -27,7 +28,7 @@ static enum nvdimm_security_state intel_security_state(struct nvdimm *nvdimm, int rc; if (!test_bit(NVDIMM_INTEL_GET_SECURITY_STATE, &nfit_mem->dsm_mask)) - return -ENXIO; + return 0; /* * Short circuit the state retrieval while we are doing overwrite. @@ -35,38 +36,42 @@ static enum nvdimm_security_state intel_security_state(struct nvdimm *nvdimm, * until the overwrite DSM completes. */ if (nvdimm_in_overwrite(nvdimm) && ptype == NVDIMM_USER) - return NVDIMM_SECURITY_OVERWRITE; + return BIT(NVDIMM_SECURITY_OVERWRITE); rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); - if (rc < 0) - return rc; - if (nd_cmd.cmd.status) - return -EIO; + if (rc < 0 || nd_cmd.cmd.status) { + pr_err("%s: security state retrieval failed (%d:%#x)\n", + nvdimm_name(nvdimm), rc, nd_cmd.cmd.status); + return 0; + } /* check and see if security is enabled and locked */ if (ptype == NVDIMM_MASTER) { if (nd_cmd.cmd.extended_state & ND_INTEL_SEC_ESTATE_ENABLED) - return NVDIMM_SECURITY_UNLOCKED; - else if (nd_cmd.cmd.extended_state & - ND_INTEL_SEC_ESTATE_PLIMIT) - return NVDIMM_SECURITY_FROZEN; - } else { - if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_UNSUPPORTED) - return -ENXIO; - else if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_ENABLED) { - if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_LOCKED) - return NVDIMM_SECURITY_LOCKED; - else if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_FROZEN - || nd_cmd.cmd.state & - ND_INTEL_SEC_STATE_PLIMIT) - return NVDIMM_SECURITY_FROZEN; - else - return NVDIMM_SECURITY_UNLOCKED; - } + set_bit(NVDIMM_SECURITY_UNLOCKED, &security_flags); + else + set_bit(NVDIMM_SECURITY_DISABLED, &security_flags); + if (nd_cmd.cmd.extended_state & ND_INTEL_SEC_ESTATE_PLIMIT) + set_bit(NVDIMM_SECURITY_FROZEN, &security_flags); + return security_flags; } - /* this should cover master security disabled as well */ - return NVDIMM_SECURITY_DISABLED; + if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_UNSUPPORTED) + return 0; + + if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_ENABLED) { + if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_FROZEN || + nd_cmd.cmd.state & ND_INTEL_SEC_STATE_PLIMIT) + set_bit(NVDIMM_SECURITY_FROZEN, &security_flags); + + if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_LOCKED) + set_bit(NVDIMM_SECURITY_LOCKED, &security_flags); + else + set_bit(NVDIMM_SECURITY_UNLOCKED, &security_flags); + } else + set_bit(NVDIMM_SECURITY_DISABLED, &security_flags); + + return security_flags; } static int intel_security_freeze(struct nvdimm *nvdimm) @@ -371,7 +376,7 @@ static void nvdimm_invalidate_cache(void) #endif static const struct nvdimm_security_ops __intel_security_ops = { - .state = intel_security_state, + .get_flags = intel_security_flags, .freeze = intel_security_freeze, .change_key = intel_security_change_key, .disable = intel_security_disable, diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index 798c5c4aea9c..29479d3b01b0 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c @@ -400,7 +400,7 @@ static int child_unregister(struct device *dev, void *data) /* We are shutting down. Make state frozen artificially. */ nvdimm_bus_lock(dev); - nvdimm->sec.state = NVDIMM_SECURITY_FROZEN; + set_bit(NVDIMM_SECURITY_FROZEN, &nvdimm->sec.flags); if (test_and_clear_bit(NDD_WORK_PENDING, &nvdimm->flags)) dev_put = true; nvdimm_bus_unlock(dev); diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c index 29a065e769ea..53330625fe07 100644 --- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c @@ -372,24 +372,27 @@ __weak ssize_t security_show(struct device *dev, { struct nvdimm *nvdimm = to_nvdimm(dev); - switch (nvdimm->sec.state) { - case NVDIMM_SECURITY_DISABLED: + if (test_bit(NVDIMM_SECURITY_DISABLED, &nvdimm->sec.flags)) return sprintf(buf, "disabled\n"); - case NVDIMM_SECURITY_UNLOCKED: + if (test_bit(NVDIMM_SECURITY_UNLOCKED, &nvdimm->sec.flags)) return sprintf(buf, "unlocked\n"); - case NVDIMM_SECURITY_LOCKED: + if (test_bit(NVDIMM_SECURITY_LOCKED, &nvdimm->sec.flags)) return sprintf(buf, "locked\n"); - case NVDIMM_SECURITY_FROZEN: - return sprintf(buf, "frozen\n"); - case NVDIMM_SECURITY_OVERWRITE: + if (test_bit(NVDIMM_SECURITY_OVERWRITE, &nvdimm->sec.flags)) return sprintf(buf, "overwrite\n"); - default: - return -ENOTTY; - } - return -ENOTTY; } +static ssize_t frozen_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nvdimm *nvdimm = to_nvdimm(dev); + + return sprintf(buf, "%d\n", test_bit(NVDIMM_SECURITY_FROZEN, + &nvdimm->sec.flags)); +} +static DEVICE_ATTR_RO(frozen); + #define OPS \ C( OP_FREEZE, "freeze", 1), \ C( OP_DISABLE, "disable", 2), \ @@ -501,6 +504,7 @@ static struct attribute *nvdimm_attributes[] = { &dev_attr_commands.attr, &dev_attr_available_slots.attr, &dev_attr_security.attr, + &dev_attr_frozen.attr, NULL, }; @@ -509,17 +513,24 @@ static umode_t nvdimm_visible(struct kobject *kobj, struct attribute *a, int n) struct device *dev = container_of(kobj, typeof(*dev), kobj); struct nvdimm *nvdimm = to_nvdimm(dev); - if (a != &dev_attr_security.attr) + if (a != &dev_attr_security.attr && a != &dev_attr_frozen.attr) return a->mode; - if (nvdimm->sec.state < 0) + if (!nvdimm->sec.flags) return 0; - /* Are there any state mutation ops? */ - if (nvdimm->sec.ops->freeze || nvdimm->sec.ops->disable - || nvdimm->sec.ops->change_key - || nvdimm->sec.ops->erase - || nvdimm->sec.ops->overwrite) + + if (a == &dev_attr_security.attr) { + /* Are there any state mutation ops (make writable)? */ + if (nvdimm->sec.ops->freeze || nvdimm->sec.ops->disable + || nvdimm->sec.ops->change_key + || nvdimm->sec.ops->erase + || nvdimm->sec.ops->overwrite) + return a->mode; + return 0444; + } + + if (nvdimm->sec.ops->freeze) return a->mode; - return 0444; + return 0; } struct attribute_group nvdimm_attribute_group = { @@ -569,8 +580,8 @@ struct nvdimm *__nvdimm_create(struct nvdimm_bus *nvdimm_bus, * attribute visibility. */ /* get security state and extended (master) state */ - nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER); - nvdimm->sec.ext_state = nvdimm_security_state(nvdimm, NVDIMM_MASTER); + nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER); + nvdimm->sec.ext_flags = nvdimm_security_flags(nvdimm, NVDIMM_MASTER); nd_device_register(dev); return nvdimm; @@ -588,7 +599,7 @@ int nvdimm_security_setup_events(struct device *dev) { struct nvdimm *nvdimm = to_nvdimm(dev); - if (nvdimm->sec.state < 0 || !nvdimm->sec.ops + if (!nvdimm->sec.flags || !nvdimm->sec.ops || !nvdimm->sec.ops->overwrite) return 0; nvdimm->sec.overwrite_state = sysfs_get_dirent(dev->kobj.sd, "security"); @@ -614,7 +625,7 @@ int nvdimm_security_freeze(struct nvdimm *nvdimm) if (!nvdimm->sec.ops || !nvdimm->sec.ops->freeze) return -EOPNOTSUPP; - if (nvdimm->sec.state < 0) + if (!nvdimm->sec.flags) return -EIO; if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) { @@ -623,7 +634,7 @@ int nvdimm_security_freeze(struct nvdimm *nvdimm) } rc = nvdimm->sec.ops->freeze(nvdimm); - nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER); + nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER); return rc; } diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h index 0ac52b6eb00e..da2bbfd56d9f 100644 --- a/drivers/nvdimm/nd-core.h +++ b/drivers/nvdimm/nd-core.h @@ -39,21 +39,32 @@ struct nvdimm { const char *dimm_id; struct { const struct nvdimm_security_ops *ops; - enum nvdimm_security_state state; - enum nvdimm_security_state ext_state; + unsigned long flags; + unsigned long ext_flags; unsigned int overwrite_tmo; struct kernfs_node *overwrite_state; } sec; struct delayed_work dwork; }; -static inline enum nvdimm_security_state nvdimm_security_state( +static inline unsigned long nvdimm_security_flags( struct nvdimm *nvdimm, enum nvdimm_passphrase_type ptype) { + u64 flags; + const u64 state_flags = 1UL << NVDIMM_SECURITY_DISABLED + | 1UL << NVDIMM_SECURITY_LOCKED + | 1UL << NVDIMM_SECURITY_UNLOCKED + | 1UL << NVDIMM_SECURITY_OVERWRITE; + if (!nvdimm->sec.ops) - return -ENXIO; + return 0; - return nvdimm->sec.ops->state(nvdimm, ptype); + flags = nvdimm->sec.ops->get_flags(nvdimm, ptype); + /* disabled, locked, unlocked, and overwrite are mutually exclusive */ + dev_WARN_ONCE(&nvdimm->dev, hweight64(flags & state_flags) > 1, + "reported invalid security state: %#llx\n", + (unsigned long long) flags); + return flags; } int nvdimm_security_freeze(struct nvdimm *nvdimm); #if IS_ENABLED(CONFIG_NVDIMM_KEYS) diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c index a570f2263a42..5862d0eee9db 100644 --- a/drivers/nvdimm/security.c +++ b/drivers/nvdimm/security.c @@ -158,7 +158,7 @@ static int nvdimm_key_revalidate(struct nvdimm *nvdimm) } nvdimm_put_key(key); - nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER); + nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER); return 0; } @@ -174,7 +174,7 @@ static int __nvdimm_security_unlock(struct nvdimm *nvdimm) lockdep_assert_held(&nvdimm_bus->reconfig_mutex); if (!nvdimm->sec.ops || !nvdimm->sec.ops->unlock - || nvdimm->sec.state < 0) + || !nvdimm->sec.flags) return -EIO; if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) { @@ -189,7 +189,7 @@ static int __nvdimm_security_unlock(struct nvdimm *nvdimm) * freeze of the security configuration. I.e. if the OS does not * have the key, security is being managed pre-OS. */ - if (nvdimm->sec.state == NVDIMM_SECURITY_UNLOCKED) { + if (test_bit(NVDIMM_SECURITY_UNLOCKED, &nvdimm->sec.flags)) { if (!key_revalidate) return 0; @@ -202,7 +202,7 @@ static int __nvdimm_security_unlock(struct nvdimm *nvdimm) rc == 0 ? "success" : "fail"); nvdimm_put_key(key); - nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER); + nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER); return rc; } @@ -217,6 +217,24 @@ int nvdimm_security_unlock(struct device *dev) return rc; } +static int check_security_state(struct nvdimm *nvdimm) +{ + struct device *dev = &nvdimm->dev; + + if (test_bit(NVDIMM_SECURITY_FROZEN, &nvdimm->sec.flags)) { + dev_dbg(dev, "Incorrect security state: %#lx\n", + nvdimm->sec.flags); + return -EIO; + } + + if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) { + dev_dbg(dev, "Security operation in progress.\n"); + return -EBUSY; + } + + return 0; +} + int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid) { struct device *dev = &nvdimm->dev; @@ -229,19 +247,12 @@ int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid) lockdep_assert_held(&nvdimm_bus->reconfig_mutex); if (!nvdimm->sec.ops || !nvdimm->sec.ops->disable - || nvdimm->sec.state < 0) + || !nvdimm->sec.flags) return -EOPNOTSUPP; - if (nvdimm->sec.state >= NVDIMM_SECURITY_FROZEN) { - dev_dbg(dev, "Incorrect security state: %d\n", - nvdimm->sec.state); - return -EIO; - } - - if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) { - dev_dbg(dev, "Security operation in progress.\n"); - return -EBUSY; - } + rc = check_security_state(nvdimm); + if (rc) + return rc; data = nvdimm_get_user_key_payload(nvdimm, keyid, NVDIMM_BASE_KEY, &key); @@ -253,7 +264,7 @@ int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid) rc == 0 ? "success" : "fail"); nvdimm_put_key(key); - nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER); + nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER); return rc; } @@ -271,14 +282,12 @@ int nvdimm_security_update(struct nvdimm *nvdimm, unsigned int keyid, lockdep_assert_held(&nvdimm_bus->reconfig_mutex); if (!nvdimm->sec.ops || !nvdimm->sec.ops->change_key - || nvdimm->sec.state < 0) + || !nvdimm->sec.flags) return -EOPNOTSUPP; - if (nvdimm->sec.state >= NVDIMM_SECURITY_FROZEN) { - dev_dbg(dev, "Incorrect security state: %d\n", - nvdimm->sec.state); - return -EIO; - } + rc = check_security_state(nvdimm); + if (rc) + return rc; data = nvdimm_get_user_key_payload(nvdimm, keyid, NVDIMM_BASE_KEY, &key); @@ -301,10 +310,10 @@ int nvdimm_security_update(struct nvdimm *nvdimm, unsigned int keyid, nvdimm_put_key(newkey); nvdimm_put_key(key); if (pass_type == NVDIMM_MASTER) - nvdimm->sec.ext_state = nvdimm_security_state(nvdimm, + nvdimm->sec.ext_flags = nvdimm_security_flags(nvdimm, NVDIMM_MASTER); else - nvdimm->sec.state = nvdimm_security_state(nvdimm, + nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER); return rc; } @@ -322,7 +331,7 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid, lockdep_assert_held(&nvdimm_bus->reconfig_mutex); if (!nvdimm->sec.ops || !nvdimm->sec.ops->erase - || nvdimm->sec.state < 0) + || !nvdimm->sec.flags) return -EOPNOTSUPP; if (atomic_read(&nvdimm->busy)) { @@ -330,18 +339,11 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid, return -EBUSY; } - if (nvdimm->sec.state >= NVDIMM_SECURITY_FROZEN) { - dev_dbg(dev, "Incorrect security state: %d\n", - nvdimm->sec.state); - return -EIO; - } - - if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) { - dev_dbg(dev, "Security operation in progress.\n"); - return -EBUSY; - } + rc = check_security_state(nvdimm); + if (rc) + return rc; - if (nvdimm->sec.ext_state != NVDIMM_SECURITY_UNLOCKED + if (!test_bit(NVDIMM_SECURITY_UNLOCKED, &nvdimm->sec.ext_flags) && pass_type == NVDIMM_MASTER) { dev_dbg(dev, "Attempt to secure erase in wrong master state.\n"); @@ -359,7 +361,7 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid, rc == 0 ? "success" : "fail"); nvdimm_put_key(key); - nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER); + nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER); return rc; } @@ -375,7 +377,7 @@ int nvdimm_security_overwrite(struct nvdimm *nvdimm, unsigned int keyid) lockdep_assert_held(&nvdimm_bus->reconfig_mutex); if (!nvdimm->sec.ops || !nvdimm->sec.ops->overwrite - || nvdimm->sec.state < 0) + || !nvdimm->sec.flags) return -EOPNOTSUPP; if (atomic_read(&nvdimm->busy)) { @@ -388,16 +390,9 @@ int nvdimm_security_overwrite(struct nvdimm *nvdimm, unsigned int keyid) return -EINVAL; } - if (nvdimm->sec.state >= NVDIMM_SECURITY_FROZEN) { - dev_dbg(dev, "Incorrect security state: %d\n", - nvdimm->sec.state); - return -EIO; - } - - if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) { - dev_dbg(dev, "Security operation in progress.\n"); - return -EBUSY; - } + rc = check_security_state(nvdimm); + if (rc) + return rc; data = nvdimm_get_user_key_payload(nvdimm, keyid, NVDIMM_BASE_KEY, &key); @@ -412,7 +407,7 @@ int nvdimm_security_overwrite(struct nvdimm *nvdimm, unsigned int keyid) if (rc == 0) { set_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags); set_bit(NDD_WORK_PENDING, &nvdimm->flags); - nvdimm->sec.state = NVDIMM_SECURITY_OVERWRITE; + set_bit(NVDIMM_SECURITY_OVERWRITE, &nvdimm->sec.flags); /* * Make sure we don't lose device while doing overwrite * query. @@ -443,7 +438,7 @@ void __nvdimm_security_overwrite_query(struct nvdimm *nvdimm) tmo = nvdimm->sec.overwrite_tmo; if (!nvdimm->sec.ops || !nvdimm->sec.ops->query_overwrite - || nvdimm->sec.state < 0) + || !nvdimm->sec.flags) return; rc = nvdimm->sec.ops->query_overwrite(nvdimm); @@ -467,8 +462,8 @@ void __nvdimm_security_overwrite_query(struct nvdimm *nvdimm) clear_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags); clear_bit(NDD_WORK_PENDING, &nvdimm->flags); put_device(&nvdimm->dev); - nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER); - nvdimm->sec.ext_state = nvdimm_security_state(nvdimm, NVDIMM_MASTER); + nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER); + nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_MASTER); } void nvdimm_security_overwrite_query(struct work_struct *work) diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index 7a64b3ddb408..b6eddf912568 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h @@ -160,8 +160,11 @@ static inline struct nd_blk_region_desc *to_blk_region_desc( } -enum nvdimm_security_state { - NVDIMM_SECURITY_ERROR = -1, +/* + * Note that separate bits for locked + unlocked are defined so that + * 'flags == 0' corresponds to an error / not-supported state. + */ +enum nvdimm_security_bits { NVDIMM_SECURITY_DISABLED, NVDIMM_SECURITY_UNLOCKED, NVDIMM_SECURITY_LOCKED, @@ -182,7 +185,7 @@ enum nvdimm_passphrase_type { }; struct nvdimm_security_ops { - enum nvdimm_security_state (*state)(struct nvdimm *nvdimm, + unsigned long (*get_flags)(struct nvdimm *nvdimm, enum nvdimm_passphrase_type pass_type); int (*freeze)(struct nvdimm *nvdimm); int (*change_key)(struct nvdimm *nvdimm, diff --git a/tools/testing/nvdimm/dimm_devs.c b/tools/testing/nvdimm/dimm_devs.c index 2d4baf57822f..57bd27dedf1f 100644 --- a/tools/testing/nvdimm/dimm_devs.c +++ b/tools/testing/nvdimm/dimm_devs.c @@ -18,24 +18,13 @@ ssize_t security_show(struct device *dev, * For the test version we need to poll the "hardware" in order * to get the updated status for unlock testing. */ - nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER); - nvdimm->sec.ext_state = nvdimm_security_state(nvdimm, NVDIMM_MASTER); + nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER); - switch (nvdimm->sec.state) { - case NVDIMM_SECURITY_DISABLED: + if (test_bit(NVDIMM_SECURITY_DISABLED, &nvdimm->sec.flags)) return sprintf(buf, "disabled\n"); - case NVDIMM_SECURITY_UNLOCKED: + if (test_bit(NVDIMM_SECURITY_UNLOCKED, &nvdimm->sec.flags)) return sprintf(buf, "unlocked\n"); - case NVDIMM_SECURITY_LOCKED: + if (test_bit(NVDIMM_SECURITY_LOCKED, &nvdimm->sec.flags)) return sprintf(buf, "locked\n"); - case NVDIMM_SECURITY_FROZEN: - return sprintf(buf, "frozen\n"); - case NVDIMM_SECURITY_OVERWRITE: - return sprintf(buf, "overwrite\n"); - default: - return -ENOTTY; - } - return -ENOTTY; } - -- cgit v1.2.3-59-g8ed1b From e0a43aa3e4a40fb88d3fa75397da0bf1e60a6c45 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Fri, 30 Aug 2019 12:00:37 +0100 Subject: tools: bpftool: ignore make built-in rules for getting kernel version Bpftool calls the toplevel Makefile to get the kernel version for the sources it is built from. But when the utility is built from the top of the kernel repository, it may dump the following error message for certain architectures (including x86): $ make tools/bpf [...] make[3]: *** [checkbin] Error 1 [...] This does not prevent bpftool compilation, but may feel disconcerting. The "checkbin" arch-dependent target is not supposed to be called for target "kernelversion", which is a simple "echo" of the version number. It turns out this is caused by the make invocation in tools/bpf/bpftool, which attempts to find implicit rules to apply. Extract from debug output: Reading makefiles... Reading makefile 'Makefile'... Reading makefile 'scripts/Kbuild.include' (search path) (no ~ expansion)... Reading makefile 'scripts/subarch.include' (search path) (no ~ expansion)... Reading makefile 'arch/x86/Makefile' (search path) (no ~ expansion)... Reading makefile 'scripts/Makefile.kcov' (search path) (no ~ expansion)... Reading makefile 'scripts/Makefile.gcc-plugins' (search path) (no ~ expansion)... Reading makefile 'scripts/Makefile.kasan' (search path) (no ~ expansion)... Reading makefile 'scripts/Makefile.extrawarn' (search path) (no ~ expansion)... Reading makefile 'scripts/Makefile.ubsan' (search path) (no ~ expansion)... Updating makefiles.... Considering target file 'scripts/Makefile.ubsan'. Looking for an implicit rule for 'scripts/Makefile.ubsan'. Trying pattern rule with stem 'Makefile.ubsan'. [...] Trying pattern rule with stem 'Makefile.ubsan'. Trying implicit prerequisite 'scripts/Makefile.ubsan.o'. Looking for a rule with intermediate file 'scripts/Makefile.ubsan.o'. Avoiding implicit rule recursion. Trying pattern rule with stem 'Makefile.ubsan'. Trying rule prerequisite 'prepare'. Trying rule prerequisite 'FORCE'. Found an implicit rule for 'scripts/Makefile.ubsan'. Considering target file 'prepare'. File 'prepare' does not exist. Considering target file 'prepare0'. File 'prepare0' does not exist. Considering target file 'archprepare'. File 'archprepare' does not exist. Considering target file 'archheaders'. File 'archheaders' does not exist. Finished prerequisites of target file 'archheaders'. Must remake target 'archheaders'. Putting child 0x55976f4f6980 (archheaders) PID 31743 on the chain. To avoid that, pass the -r and -R flags to eliminate the use of make built-in rules (and while at it, built-in variables) when running command "make kernelversion" from bpftool's Makefile. Signed-off-by: Quentin Monnet Reviewed-by: Jakub Kicinski Signed-off-by: Daniel Borkmann --- tools/bpf/bpftool/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile index f284c207765a..cd0fc05464e7 100644 --- a/tools/bpf/bpftool/Makefile +++ b/tools/bpf/bpftool/Makefile @@ -24,7 +24,7 @@ endif LIBBPF = $(BPF_PATH)libbpf.a -BPFTOOL_VERSION := $(shell make --no-print-directory -sC ../../.. kernelversion) +BPFTOOL_VERSION := $(shell make -rR --no-print-directory -sC ../../.. kernelversion) $(LIBBPF): FORCE $(Q)$(MAKE) -C $(BPF_DIR) OUTPUT=$(OUTPUT) $(OUTPUT)libbpf.a -- cgit v1.2.3-59-g8ed1b From 45c5589d07158eb1d0b5b313314706024bf451c5 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Fri, 30 Aug 2019 12:00:38 +0100 Subject: tools: bpftool: improve and check builds for different make invocations There are a number of alternative "make" invocations that can be used to compile bpftool. The following invocations are expected to work: - through the kbuild system, from the top of the repository (make tools/bpf) - by telling make to change to the bpftool directory (make -C tools/bpf/bpftool) - by building the BPF tools from tools/ (cd tools && make bpf) - by running make from bpftool directory (cd tools/bpf/bpftool && make) Additionally, setting the O or OUTPUT variables should tell the build system to use a custom output path, for each of these alternatives. The following patch fixes the following invocations: $ make tools/bpf $ make tools/bpf O= $ make -C tools/bpf/bpftool OUTPUT= $ make -C tools/bpf/bpftool O= $ cd tools/ && make bpf O= $ cd tools/bpf/bpftool && make OUTPUT= $ cd tools/bpf/bpftool && make O= After this commit, the build still fails for two variants when passing the OUTPUT variable: $ make tools/bpf OUTPUT= $ cd tools/ && make bpf OUTPUT= In order to remember and check what make invocations are supposed to work, and to document the ones which do not, a new script is added to the BPF selftests. Note that some invocations require the kernel to be configured, so the script skips them if no .config file is found. v2: - In make_and_clean(), set $ERROR to 1 when "make" returns non-zero, even if the binary was produced. - Run "make clean" from the correct directory (bpf/ instead of bpftool/, when relevant). Reported-by: Lorenz Bauer Signed-off-by: Quentin Monnet Reviewed-by: Jakub Kicinski Signed-off-by: Daniel Borkmann --- tools/bpf/bpftool/Makefile | 12 +- tools/testing/selftests/bpf/Makefile | 3 +- tools/testing/selftests/bpf/test_bpftool_build.sh | 143 ++++++++++++++++++++++ 3 files changed, 152 insertions(+), 6 deletions(-) create mode 100755 tools/testing/selftests/bpf/test_bpftool_build.sh (limited to 'tools') diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile index cd0fc05464e7..3fc82ff9b52c 100644 --- a/tools/bpf/bpftool/Makefile +++ b/tools/bpf/bpftool/Makefile @@ -17,21 +17,23 @@ endif BPF_DIR = $(srctree)/tools/lib/bpf/ ifneq ($(OUTPUT),) - BPF_PATH = $(OUTPUT) + LIBBPF_OUTPUT = $(OUTPUT)/libbpf/ + LIBBPF_PATH = $(LIBBPF_OUTPUT) else - BPF_PATH = $(BPF_DIR) + LIBBPF_PATH = $(BPF_DIR) endif -LIBBPF = $(BPF_PATH)libbpf.a +LIBBPF = $(LIBBPF_PATH)libbpf.a BPFTOOL_VERSION := $(shell make -rR --no-print-directory -sC ../../.. kernelversion) $(LIBBPF): FORCE - $(Q)$(MAKE) -C $(BPF_DIR) OUTPUT=$(OUTPUT) $(OUTPUT)libbpf.a + $(if $(LIBBPF_OUTPUT),@mkdir -p $(LIBBPF_OUTPUT)) + $(Q)$(MAKE) -C $(BPF_DIR) OUTPUT=$(LIBBPF_OUTPUT) $(LIBBPF_OUTPUT)libbpf.a $(LIBBPF)-clean: $(call QUIET_CLEAN, libbpf) - $(Q)$(MAKE) -C $(BPF_DIR) OUTPUT=$(OUTPUT) clean >/dev/null + $(Q)$(MAKE) -C $(BPF_DIR) OUTPUT=$(LIBBPF_OUTPUT) clean >/dev/null prefix ?= /usr/local bash_compdir ?= /usr/share/bash-completion/completions diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 1faad0c3c3c9..c7595b4ed55d 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -63,7 +63,8 @@ TEST_PROGS := test_kmod.sh \ test_tcp_check_syncookie.sh \ test_tc_tunnel.sh \ test_tc_edt.sh \ - test_xdping.sh + test_xdping.sh \ + test_bpftool_build.sh TEST_PROGS_EXTENDED := with_addr.sh \ with_tunnels.sh \ diff --git a/tools/testing/selftests/bpf/test_bpftool_build.sh b/tools/testing/selftests/bpf/test_bpftool_build.sh new file mode 100755 index 000000000000..4ba5a34bff56 --- /dev/null +++ b/tools/testing/selftests/bpf/test_bpftool_build.sh @@ -0,0 +1,143 @@ +#!/bin/bash +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + +ERROR=0 +TMPDIR= + +# If one build fails, continue but return non-0 on exit. +return_value() { + if [ -d "$TMPDIR" ] ; then + rm -rf -- $TMPDIR + fi + exit $ERROR +} +trap return_value EXIT + +case $1 in + -h|--help) + echo -e "$0 [-j ]" + echo -e "\tTest the different ways of building bpftool." + echo -e "" + echo -e "\tOptions:" + echo -e "\t\t-j :\tPass -j flag to 'make'." + exit + ;; +esac + +J=$* + +# Assume script is located under tools/testing/selftests/bpf/. We want to start +# build attempts from the top of kernel repository. +SCRIPT_REL_PATH=$(realpath --relative-to=$PWD $0) +SCRIPT_REL_DIR=$(dirname $SCRIPT_REL_PATH) +KDIR_ROOT_DIR=$(realpath $PWD/$SCRIPT_REL_DIR/../../../../) +cd $KDIR_ROOT_DIR + +check() { + local dir=$(realpath $1) + + echo -n "binary: " + # Returns non-null if file is found (and "false" is run) + find $dir -type f -executable -name bpftool -print -exec false {} + && \ + ERROR=1 && printf "FAILURE: Did not find bpftool\n" +} + +make_and_clean() { + echo -e "\$PWD: $PWD" + echo -e "command: make -s $* >/dev/null" + make $J -s $* >/dev/null + if [ $? -ne 0 ] ; then + ERROR=1 + fi + if [ $# -ge 1 ] ; then + check ${@: -1} + else + check . + fi + ( + if [ $# -ge 1 ] ; then + cd ${@: -1} + fi + make -s clean + ) + echo +} + +make_with_tmpdir() { + local ARGS + + TMPDIR=$(mktemp -d) + if [ $# -ge 2 ] ; then + ARGS=${@:1:(($# - 1))} + fi + echo -e "\$PWD: $PWD" + echo -e "command: make -s $ARGS ${@: -1}=$TMPDIR/ >/dev/null" + make $J -s $ARGS ${@: -1}=$TMPDIR/ >/dev/null + if [ $? -ne 0 ] ; then + ERROR=1 + fi + check $TMPDIR + rm -rf -- $TMPDIR + echo +} + +echo "Trying to build bpftool" +echo -e "... through kbuild\n" + +if [ -f ".config" ] ; then + make_and_clean tools/bpf + + ## $OUTPUT is overwritten in kbuild Makefile, and thus cannot be passed + ## down from toplevel Makefile to bpftool's Makefile. + + # make_with_tmpdir tools/bpf OUTPUT + echo -e "skip: make tools/bpf OUTPUT= (not supported)\n" + + make_with_tmpdir tools/bpf O +else + echo -e "skip: make tools/bpf (no .config found)\n" + echo -e "skip: make tools/bpf OUTPUT= (not supported)\n" + echo -e "skip: make tools/bpf O= (no .config found)\n" +fi + +echo -e "... from kernel source tree\n" + +make_and_clean -C tools/bpf/bpftool + +make_with_tmpdir -C tools/bpf/bpftool OUTPUT + +make_with_tmpdir -C tools/bpf/bpftool O + +echo -e "... from tools/\n" +cd tools/ + +make_and_clean bpf + +## In tools/bpf/Makefile, function "descend" is called and passes $(O) and +## $(OUTPUT). We would like $(OUTPUT) to have "bpf/bpftool/" appended before +## calling bpftool's Makefile, but this is not the case as the "descend" +## function focuses on $(O)/$(subdir). However, in the present case, updating +## $(O) to have $(OUTPUT) recomputed from it in bpftool's Makefile does not +## work, because $(O) is not defined from command line and $(OUTPUT) is not +## updated in tools/scripts/Makefile.include. +## +## Workarounds would require to a) edit "descend" or use an alternative way to +## call bpftool's Makefile, b) modify the conditions to update $(OUTPUT) and +## other variables in tools/scripts/Makefile.include (at the risk of breaking +## the build of other tools), or c) append manually the "bpf/bpftool" suffix to +## $(OUTPUT) in bpf's Makefile, which may break if targets for other directories +## use "descend" in the future. + +# make_with_tmpdir bpf OUTPUT +echo -e "skip: make bpf OUTPUT= (not supported)\n" + +make_with_tmpdir bpf O + +echo -e "... from bpftool's dir\n" +cd bpf/bpftool + +make_and_clean + +make_with_tmpdir OUTPUT + +make_with_tmpdir O -- cgit v1.2.3-59-g8ed1b From fbdb620b7c674928a5713dbad9b07252ff929d0a Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Fri, 30 Aug 2019 12:00:39 +0100 Subject: tools: bpf: account for generated feature/ and libbpf/ directories When building "tools/bpf" from the top of the Linux repository, the build system passes a value for the $(OUTPUT) Makefile variable to tools/bpf/Makefile and tools/bpf/bpftool/Makefile, which results in generating "libbpf/" (for bpftool) and "feature/" (bpf and bpftool) directories inside the tree. This commit adds such directories to the relevant .gitignore files, and edits the Makefiles to ensure they are removed on "make clean". The use of "rm" is also made consistent throughout those Makefiles (relies on the $(RM) variable, use "--" to prevent interpreting $(OUTPUT)/$(DESTDIR) as options. v2: - New patch. Signed-off-by: Quentin Monnet Signed-off-by: Daniel Borkmann --- tools/bpf/.gitignore | 1 + tools/bpf/Makefile | 5 +++-- tools/bpf/bpftool/.gitignore | 2 ++ tools/bpf/bpftool/Makefile | 10 ++++++---- 4 files changed, 12 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/bpf/.gitignore b/tools/bpf/.gitignore index dfe2bd5a4b95..59024197e71d 100644 --- a/tools/bpf/.gitignore +++ b/tools/bpf/.gitignore @@ -1,4 +1,5 @@ FEATURE-DUMP.bpf +feature bpf_asm bpf_dbg bpf_exp.yacc.* diff --git a/tools/bpf/Makefile b/tools/bpf/Makefile index 53b60ad452f5..fbf5e4a0cb9c 100644 --- a/tools/bpf/Makefile +++ b/tools/bpf/Makefile @@ -81,10 +81,11 @@ $(OUTPUT)bpf_exp.lex.o: $(OUTPUT)bpf_exp.lex.c clean: bpftool_clean $(call QUIET_CLEAN, bpf-progs) - $(Q)rm -rf $(OUTPUT)*.o $(OUTPUT)bpf_jit_disasm $(OUTPUT)bpf_dbg \ + $(Q)$(RM) -r -- $(OUTPUT)*.o $(OUTPUT)bpf_jit_disasm $(OUTPUT)bpf_dbg \ $(OUTPUT)bpf_asm $(OUTPUT)bpf_exp.yacc.* $(OUTPUT)bpf_exp.lex.* $(call QUIET_CLEAN, core-gen) - $(Q)rm -f $(OUTPUT)FEATURE-DUMP.bpf + $(Q)$(RM) -- $(OUTPUT)FEATURE-DUMP.bpf + $(Q)$(RM) -r -- $(OUTPUT)feature install: $(PROGS) bpftool_install $(call QUIET_INSTALL, bpf_jit_disasm) diff --git a/tools/bpf/bpftool/.gitignore b/tools/bpf/bpftool/.gitignore index 8248b8dd89d4..b13926432b84 100644 --- a/tools/bpf/bpftool/.gitignore +++ b/tools/bpf/bpftool/.gitignore @@ -3,3 +3,5 @@ bpftool*.8 bpf-helpers.* FEATURE-DUMP.bpftool +feature +libbpf diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile index 3fc82ff9b52c..b0c5a369f54a 100644 --- a/tools/bpf/bpftool/Makefile +++ b/tools/bpf/bpftool/Makefile @@ -124,9 +124,11 @@ $(OUTPUT)%.o: %.c clean: $(LIBBPF)-clean $(call QUIET_CLEAN, bpftool) - $(Q)$(RM) $(OUTPUT)bpftool $(OUTPUT)*.o $(OUTPUT)*.d + $(Q)$(RM) -- $(OUTPUT)bpftool $(OUTPUT)*.o $(OUTPUT)*.d + $(Q)$(RM) -r -- $(OUTPUT)libbpf/ $(call QUIET_CLEAN, core-gen) - $(Q)$(RM) $(OUTPUT)FEATURE-DUMP.bpftool + $(Q)$(RM) -- $(OUTPUT)FEATURE-DUMP.bpftool + $(Q)$(RM) -r -- $(OUTPUT)feature/ install: $(OUTPUT)bpftool $(call QUIET_INSTALL, bpftool) @@ -137,8 +139,8 @@ install: $(OUTPUT)bpftool uninstall: $(call QUIET_UNINST, bpftool) - $(Q)$(RM) $(DESTDIR)$(prefix)/sbin/bpftool - $(Q)$(RM) $(DESTDIR)$(bash_compdir)/bpftool + $(Q)$(RM) -- $(DESTDIR)$(prefix)/sbin/bpftool + $(Q)$(RM) -- $(DESTDIR)$(bash_compdir)/bpftool doc: $(call descend,Documentation) -- cgit v1.2.3-59-g8ed1b From 5b84ad2e89215835ea6476ba05295e849b30886b Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Fri, 30 Aug 2019 12:00:40 +0100 Subject: tools: bpftool: do not link twice against libbpf.a in Makefile In bpftool's Makefile, $(LIBS) includes $(LIBBPF), therefore the library is used twice in the linking command. No need to have $(LIBBPF) (from $^) on that command, let's do with "$(OBJS) $(LIBS)" (but move $(LIBBPF) _before_ the -l flags in $(LIBS)). Signed-off-by: Ilya Leoshkevich Signed-off-by: Quentin Monnet Reviewed-by: Jakub Kicinski Signed-off-by: Daniel Borkmann --- tools/bpf/bpftool/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile index b0c5a369f54a..39bc6f0f4f0b 100644 --- a/tools/bpf/bpftool/Makefile +++ b/tools/bpf/bpftool/Makefile @@ -55,7 +55,7 @@ ifneq ($(EXTRA_LDFLAGS),) LDFLAGS += $(EXTRA_LDFLAGS) endif -LIBS = -lelf -lz $(LIBBPF) +LIBS = $(LIBBPF) -lelf -lz INSTALL ?= install RM ?= rm -f @@ -117,7 +117,7 @@ $(OUTPUT)disasm.o: $(srctree)/kernel/bpf/disasm.c $(OUTPUT)feature.o: | zdep $(OUTPUT)bpftool: $(OBJS) $(LIBBPF) - $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(OUTPUT)%.o: %.c $(QUIET_CC)$(COMPILE.c) -MMD -o $@ $< -- cgit v1.2.3-59-g8ed1b From 1c6d6e021c452ac15ce034e6762f0477f1cf7f19 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Thu, 29 Aug 2019 09:01:30 +0900 Subject: selftests/bpf: Fix a typo in test_offload.py This patch fix a spelling typo in test_offload.py Signed-off-by: Masanari Iida Acked-by: Jakub Kicinski Acked-by: Song Liu Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/test_offload.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_offload.py b/tools/testing/selftests/bpf/test_offload.py index 425f9ed27c3b..15a666329a34 100755 --- a/tools/testing/selftests/bpf/test_offload.py +++ b/tools/testing/selftests/bpf/test_offload.py @@ -1353,7 +1353,7 @@ try: bpftool_prog_list_wait(expected=1) ifnameB = bpftool("prog show %s" % (progB))[1]["dev"]["ifname"] - fail(ifnameB != simB1['ifname'], "program not bound to originial device") + fail(ifnameB != simB1['ifname'], "program not bound to original device") simB1.remove() bpftool_prog_list_wait(expected=1) -- cgit v1.2.3-59-g8ed1b From 10d30e301732636d93d7dcd2e0e6cd34d0454509 Mon Sep 17 00:00:00 2001 From: Kevin Laatz Date: Tue, 27 Aug 2019 02:25:27 +0000 Subject: libbpf: add flags to umem config This patch adds a 'flags' field to the umem_config and umem_reg structs. This will allow for more options to be added for configuring umems. The first use for the flags field is to add a flag for unaligned chunks mode. These flags can either be user-provided or filled with a default. Since we change the size of the xsk_umem_config struct, we need to version the ABI. This patch includes the ABI versioning for xsk_umem__create. The Makefile was also updated to handle multiple function versions in check-abi. Signed-off-by: Kevin Laatz Signed-off-by: Ciara Loftus Acked-by: Jonathan Lemon Signed-off-by: Daniel Borkmann --- tools/include/uapi/linux/if_xdp.h | 9 +++++++++ tools/lib/bpf/Makefile | 5 ++++- tools/lib/bpf/libbpf.map | 1 + tools/lib/bpf/xsk.c | 33 ++++++++++++++++++++++++++++++--- tools/lib/bpf/xsk.h | 27 +++++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/include/uapi/linux/if_xdp.h b/tools/include/uapi/linux/if_xdp.h index 62b80d57b72a..be328c59389d 100644 --- a/tools/include/uapi/linux/if_xdp.h +++ b/tools/include/uapi/linux/if_xdp.h @@ -26,6 +26,9 @@ */ #define XDP_USE_NEED_WAKEUP (1 << 3) +/* Flags for xsk_umem_config flags */ +#define XDP_UMEM_UNALIGNED_CHUNK_FLAG (1 << 0) + struct sockaddr_xdp { __u16 sxdp_family; __u16 sxdp_flags; @@ -66,6 +69,7 @@ struct xdp_umem_reg { __u64 len; /* Length of packet data area */ __u32 chunk_size; __u32 headroom; + __u32 flags; }; struct xdp_statistics { @@ -87,6 +91,11 @@ struct xdp_options { #define XDP_UMEM_PGOFF_FILL_RING 0x100000000ULL #define XDP_UMEM_PGOFF_COMPLETION_RING 0x180000000ULL +/* Masks for unaligned chunks mode */ +#define XSK_UNALIGNED_BUF_OFFSET_SHIFT 48 +#define XSK_UNALIGNED_BUF_ADDR_MASK \ + ((1ULL << XSK_UNALIGNED_BUF_OFFSET_SHIFT) - 1) + /* Rx/Tx descriptor */ struct xdp_desc { __u64 addr; diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index 613acb93b144..c6f94cffe06e 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile @@ -134,7 +134,9 @@ LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE)) PC_FILE := $(addprefix $(OUTPUT),$(PC_FILE)) GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN) | \ - awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {s++} END{print s}') + cut -d "@" -f1 | sed 's/_v[0-9]_[0-9]_[0-9].*//' | \ + awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$8}' | \ + sort -u | wc -l) VERSIONED_SYM_COUNT = $(shell readelf -s --wide $(OUTPUT)libbpf.so | \ grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | sort -u | wc -l) @@ -201,6 +203,7 @@ check_abi: $(OUTPUT)libbpf.so "Please make sure all LIBBPF_API symbols are" \ "versioned in $(VERSION_SCRIPT)." >&2; \ readelf -s --wide $(OUTPUT)libbpf-in.o | \ + cut -d "@" -f1 | sed 's/_v[0-9]_[0-9]_[0-9].*//' | \ awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$8}'| \ sort -u > $(OUTPUT)libbpf_global_syms.tmp; \ readelf -s --wide $(OUTPUT)libbpf.so | \ diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map index 664ce8e7a60e..d04c7cb623ed 100644 --- a/tools/lib/bpf/libbpf.map +++ b/tools/lib/bpf/libbpf.map @@ -183,6 +183,7 @@ LIBBPF_0.0.4 { perf_buffer__new; perf_buffer__new_raw; perf_buffer__poll; + xsk_umem__create; } LIBBPF_0.0.3; LIBBPF_0.0.5 { diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c index 12ad78510147..842c4fd55859 100644 --- a/tools/lib/bpf/xsk.c +++ b/tools/lib/bpf/xsk.c @@ -99,6 +99,7 @@ static void xsk_set_umem_config(struct xsk_umem_config *cfg, cfg->comp_size = XSK_RING_CONS__DEFAULT_NUM_DESCS; cfg->frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE; cfg->frame_headroom = XSK_UMEM__DEFAULT_FRAME_HEADROOM; + cfg->flags = XSK_UMEM__DEFAULT_FLAGS; return; } @@ -106,6 +107,7 @@ static void xsk_set_umem_config(struct xsk_umem_config *cfg, cfg->comp_size = usr_cfg->comp_size; cfg->frame_size = usr_cfg->frame_size; cfg->frame_headroom = usr_cfg->frame_headroom; + cfg->flags = usr_cfg->flags; } static int xsk_set_xdp_socket_config(struct xsk_socket_config *cfg, @@ -132,9 +134,10 @@ static int xsk_set_xdp_socket_config(struct xsk_socket_config *cfg, return 0; } -int xsk_umem__create(struct xsk_umem **umem_ptr, void *umem_area, __u64 size, - struct xsk_ring_prod *fill, struct xsk_ring_cons *comp, - const struct xsk_umem_config *usr_config) +int xsk_umem__create_v0_0_4(struct xsk_umem **umem_ptr, void *umem_area, + __u64 size, struct xsk_ring_prod *fill, + struct xsk_ring_cons *comp, + const struct xsk_umem_config *usr_config) { struct xdp_mmap_offsets off; struct xdp_umem_reg mr; @@ -165,6 +168,7 @@ int xsk_umem__create(struct xsk_umem **umem_ptr, void *umem_area, __u64 size, mr.len = size; mr.chunk_size = umem->config.frame_size; mr.headroom = umem->config.frame_headroom; + mr.flags = umem->config.flags; err = setsockopt(umem->fd, SOL_XDP, XDP_UMEM_REG, &mr, sizeof(mr)); if (err) { @@ -238,6 +242,29 @@ out_umem_alloc: return err; } +struct xsk_umem_config_v1 { + __u32 fill_size; + __u32 comp_size; + __u32 frame_size; + __u32 frame_headroom; +}; + +int xsk_umem__create_v0_0_2(struct xsk_umem **umem_ptr, void *umem_area, + __u64 size, struct xsk_ring_prod *fill, + struct xsk_ring_cons *comp, + const struct xsk_umem_config *usr_config) +{ + struct xsk_umem_config config; + + memcpy(&config, usr_config, sizeof(struct xsk_umem_config_v1)); + config.flags = 0; + + return xsk_umem__create_v0_0_4(umem_ptr, umem_area, size, fill, comp, + &config); +} +asm(".symver xsk_umem__create_v0_0_2, xsk_umem__create@LIBBPF_0.0.2"); +asm(".symver xsk_umem__create_v0_0_4, xsk_umem__create@@LIBBPF_0.0.4"); + static int xsk_load_xdp_prog(struct xsk_socket *xsk) { static const int log_buf_size = 16 * 1024; diff --git a/tools/lib/bpf/xsk.h b/tools/lib/bpf/xsk.h index aa1d6122b7db..584f6820a639 100644 --- a/tools/lib/bpf/xsk.h +++ b/tools/lib/bpf/xsk.h @@ -168,6 +168,21 @@ static inline void *xsk_umem__get_data(void *umem_area, __u64 addr) return &((char *)umem_area)[addr]; } +static inline __u64 xsk_umem__extract_addr(__u64 addr) +{ + return addr & XSK_UNALIGNED_BUF_ADDR_MASK; +} + +static inline __u64 xsk_umem__extract_offset(__u64 addr) +{ + return addr >> XSK_UNALIGNED_BUF_OFFSET_SHIFT; +} + +static inline __u64 xsk_umem__add_offset_to_addr(__u64 addr) +{ + return xsk_umem__extract_addr(addr) + xsk_umem__extract_offset(addr); +} + LIBBPF_API int xsk_umem__fd(const struct xsk_umem *umem); LIBBPF_API int xsk_socket__fd(const struct xsk_socket *xsk); @@ -176,12 +191,14 @@ LIBBPF_API int xsk_socket__fd(const struct xsk_socket *xsk); #define XSK_UMEM__DEFAULT_FRAME_SHIFT 12 /* 4096 bytes */ #define XSK_UMEM__DEFAULT_FRAME_SIZE (1 << XSK_UMEM__DEFAULT_FRAME_SHIFT) #define XSK_UMEM__DEFAULT_FRAME_HEADROOM 0 +#define XSK_UMEM__DEFAULT_FLAGS 0 struct xsk_umem_config { __u32 fill_size; __u32 comp_size; __u32 frame_size; __u32 frame_headroom; + __u32 flags; }; /* Flags for the libbpf_flags field. */ @@ -201,6 +218,16 @@ LIBBPF_API int xsk_umem__create(struct xsk_umem **umem, struct xsk_ring_prod *fill, struct xsk_ring_cons *comp, const struct xsk_umem_config *config); +LIBBPF_API int xsk_umem__create_v0_0_2(struct xsk_umem **umem, + void *umem_area, __u64 size, + struct xsk_ring_prod *fill, + struct xsk_ring_cons *comp, + const struct xsk_umem_config *config); +LIBBPF_API int xsk_umem__create_v0_0_4(struct xsk_umem **umem, + void *umem_area, __u64 size, + struct xsk_ring_prod *fill, + struct xsk_ring_cons *comp, + const struct xsk_umem_config *config); LIBBPF_API int xsk_socket__create(struct xsk_socket **xsk, const char *ifname, __u32 queue_id, struct xsk_umem *umem, -- cgit v1.2.3-59-g8ed1b From cf881485eb2af78c541c6f8ec71dfc7e0cb0e997 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 20 Jun 2019 00:08:46 +0900 Subject: selftests/ftrace: Add a testcase for kprobe multiprobe event Add a testcase for kprobe event with multi-probe. Link: http://lkml.kernel.org/r/156095692637.28024.17188971794698768977.stgit@devnote2 Signed-off-by: Masami Hiramatsu Signed-off-by: Steven Rostedt (VMware) --- .../ftrace/test.d/kprobe/kprobe_multiprobe.tc | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 tools/testing/selftests/ftrace/test.d/kprobe/kprobe_multiprobe.tc (limited to 'tools') diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_multiprobe.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_multiprobe.tc new file mode 100644 index 000000000000..44494bac86d1 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_multiprobe.tc @@ -0,0 +1,35 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Create/delete multiprobe on kprobe event + +[ -f kprobe_events ] || exit_unsupported + +grep -q "Create/append/" README || exit_unsupported + +# Choose 2 symbols for target +SYM1=_do_fork +SYM2=do_exit +EVENT_NAME=kprobes/testevent + +DEF1="p:$EVENT_NAME $SYM1" +DEF2="p:$EVENT_NAME $SYM2" + +:;: "Define an event which has 2 probes" ;: +echo $DEF1 >> kprobe_events +echo $DEF2 >> kprobe_events +cat kprobe_events | grep "$DEF1" +cat kprobe_events | grep "$DEF2" + +:;: "Remove the event by name (should remove both)" ;: +echo "-:$EVENT_NAME" >> kprobe_events +test `cat kprobe_events | wc -l` -eq 0 + +:;: "Remove just 1 event" ;: +echo $DEF1 >> kprobe_events +echo $DEF2 >> kprobe_events +echo "-:$EVENT_NAME $SYM1" >> kprobe_events +! cat kprobe_events | grep "$DEF1" +cat kprobe_events | grep "$DEF2" + +:;: "Appending different type must fail" ;: +! echo "$DEF1 \$stack" >> kprobe_events -- cgit v1.2.3-59-g8ed1b From 3e662c54a15c4c4409c45e6133107a3107796a96 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 20 Jun 2019 00:08:55 +0900 Subject: selftests/ftrace: Add syntax error test for immediates Add syntax error test cases for immediate value and immediate string. Link: http://lkml.kernel.org/r/156095693553.28024.7730929892585591691.stgit@devnote2 Signed-off-by: Masami Hiramatsu Signed-off-by: Steven Rostedt (VMware) --- tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc index 29faaec942c6..aa59944bcace 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc @@ -41,6 +41,11 @@ check_error 'p vfs_read ^%none_reg' # BAD_REG_NAME check_error 'p vfs_read ^@12345678abcde' # BAD_MEM_ADDR check_error 'p vfs_read ^@+10' # FILE_ON_KPROBE +grep -q "imm-value" README && \ +check_error 'p vfs_read arg1=\^x' # BAD_IMM +grep -q "imm-string" README && \ +check_error 'p vfs_read arg1=\"abcd^' # IMMSTR_NO_CLOSE + check_error 'p vfs_read ^+0@0)' # DEREF_NEED_BRACE check_error 'p vfs_read ^+0ab1(@0)' # BAD_DEREF_OFFS check_error 'p vfs_read +0(+0(@0^)' # DEREF_OPEN_BRACE -- cgit v1.2.3-59-g8ed1b From 7f5291da4b15ad0ebc0965af41a1a2e3f04c3f08 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 20 Jun 2019 00:09:05 +0900 Subject: selftests/ftrace: Add syntax error test for multiprobe Add syntax error test cases for multiprobe appending errors. Link: http://lkml.kernel.org/r/156095694541.28024.11918630805148623119.stgit@devnote2 Signed-off-by: Masami Hiramatsu Signed-off-by: Steven Rostedt (VMware) --- tools/testing/selftests/ftrace/test.d/functions | 2 +- .../selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/ftrace/test.d/functions b/tools/testing/selftests/ftrace/test.d/functions index 1d96c5f7e402..86986c4bba54 100644 --- a/tools/testing/selftests/ftrace/test.d/functions +++ b/tools/testing/selftests/ftrace/test.d/functions @@ -115,7 +115,7 @@ ftrace_errlog_check() { # err-prefix command-with-error-pos-by-^ command-file command=$(echo "$2" | tr -d ^) echo "Test command: $command" echo > error_log - (! echo "$command" > "$3" ) 2> /dev/null + (! echo "$command" >> "$3" ) 2> /dev/null grep "$1: error:" -A 3 error_log N=$(tail -n 1 error_log | wc -c) # " Command: " and "^\n" => 13 diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc index aa59944bcace..39ef7ac1f51c 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc @@ -87,4 +87,14 @@ case $(uname -m) in ;; esac +# multiprobe errors +if grep -q "Create/append/" README && grep -q "imm-value" README; then +echo 'p:kprobes/testevent _do_fork' > kprobe_events +check_error '^r:kprobes/testevent do_exit' # DIFF_PROBE_TYPE +echo 'p:kprobes/testevent _do_fork abcd=\1' > kprobe_events +check_error 'p:kprobes/testevent _do_fork ^bcd=\1' # DIFF_ARG_TYPE +check_error 'p:kprobes/testevent _do_fork ^abcd=\1:u8' # DIFF_ARG_TYPE +check_error 'p:kprobes/testevent _do_fork ^abcd=\"foo"' # DIFF_ARG_TYPE +fi + exit 0 -- cgit v1.2.3-59-g8ed1b From adb8049097a9ec4acd09fbd3aa8636199a78df8a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 16 Sep 2018 16:05:53 +0100 Subject: tools/power x86_energy_perf_policy: Fix "uninitialized variable" warnings at -O2 x86_energy_perf_policy first uses __get_cpuid() to check the maximum CPUID level and exits if it is too low. It then assumes that later calls will succeed (which I think is architecturally guaranteed). It also assumes that CPUID works at all (which is not guaranteed on x86_32). If optimisations are enabled, gcc warns about potentially uninitialized variables. Fix this by adding an exit-on-error after every call to __get_cpuid() instead of just checking the maximum level. Signed-off-by: Ben Hutchings Signed-off-by: Len Brown --- .../x86_energy_perf_policy.c | 26 +++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c index 34a796b303fe..7663abef51e9 100644 --- a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c +++ b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c @@ -1259,6 +1259,15 @@ void probe_dev_msr(void) if (system("/sbin/modprobe msr > /dev/null 2>&1")) err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" "); } + +static void get_cpuid_or_exit(unsigned int leaf, + unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *edx) +{ + if (!__get_cpuid(leaf, eax, ebx, ecx, edx)) + errx(1, "Processor not supported\n"); +} + /* * early_cpuid() * initialize turbo_is_enabled, has_hwp, has_epb @@ -1266,15 +1275,10 @@ void probe_dev_msr(void) */ void early_cpuid(void) { - unsigned int eax, ebx, ecx, edx, max_level; + unsigned int eax, ebx, ecx, edx; unsigned int fms, family, model; - __get_cpuid(0, &max_level, &ebx, &ecx, &edx); - - if (max_level < 6) - errx(1, "Processor not supported\n"); - - __get_cpuid(1, &fms, &ebx, &ecx, &edx); + get_cpuid_or_exit(1, &fms, &ebx, &ecx, &edx); family = (fms >> 8) & 0xf; model = (fms >> 4) & 0xf; if (family == 6 || family == 0xf) @@ -1288,7 +1292,7 @@ void early_cpuid(void) bdx_highest_ratio = msr & 0xFF; } - __get_cpuid(0x6, &eax, &ebx, &ecx, &edx); + get_cpuid_or_exit(0x6, &eax, &ebx, &ecx, &edx); turbo_is_enabled = (eax >> 1) & 1; has_hwp = (eax >> 7) & 1; has_epb = (ecx >> 3) & 1; @@ -1306,7 +1310,7 @@ void parse_cpuid(void) eax = ebx = ecx = edx = 0; - __get_cpuid(0, &max_level, &ebx, &ecx, &edx); + get_cpuid_or_exit(0, &max_level, &ebx, &ecx, &edx); if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e) genuine_intel = 1; @@ -1315,7 +1319,7 @@ void parse_cpuid(void) fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ", (char *)&ebx, (char *)&edx, (char *)&ecx); - __get_cpuid(1, &fms, &ebx, &ecx, &edx); + get_cpuid_or_exit(1, &fms, &ebx, &ecx, &edx); family = (fms >> 8) & 0xf; model = (fms >> 4) & 0xf; stepping = fms & 0xf; @@ -1340,7 +1344,7 @@ void parse_cpuid(void) errx(1, "CPUID: no MSR"); - __get_cpuid(0x6, &eax, &ebx, &ecx, &edx); + get_cpuid_or_exit(0x6, &eax, &ebx, &ecx, &edx); /* turbo_is_enabled already set */ /* has_hwp already set */ has_hwp_notify = eax & (1 << 8); -- cgit v1.2.3-59-g8ed1b From 6ac1730f7db86f0a92d4de0f2b4ca9cd124080fe Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 16 Sep 2018 16:06:10 +0100 Subject: tools/power/x86: Enable compiler optimisations and Fortify by default Compiling without optimisations is silly, especially since some warnings depend on the optimiser. Use -O2. Fortify adds warnings for unchecked I/O (among other things), which seems to be a good idea for user-space code. Enable that too. Signed-off-by: Ben Hutchings Signed-off-by: Len Brown --- tools/power/x86/turbostat/Makefile | 3 ++- tools/power/x86/x86_energy_perf_policy/Makefile | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/turbostat/Makefile b/tools/power/x86/turbostat/Makefile index 045f5f7d68ab..13f1e8b9ac52 100644 --- a/tools/power/x86/turbostat/Makefile +++ b/tools/power/x86/turbostat/Makefile @@ -9,9 +9,10 @@ ifeq ("$(origin O)", "command line") endif turbostat : turbostat.c -override CFLAGS += -Wall -I../../../include +override CFLAGS += -O2 -Wall -I../../../include override CFLAGS += -DMSRHEADER='"../../../../arch/x86/include/asm/msr-index.h"' override CFLAGS += -DINTEL_FAMILY_HEADER='"../../../../arch/x86/include/asm/intel-family.h"' +override CFLAGS += -D_FORTIFY_SOURCE=2 %: %.c @mkdir -p $(BUILD_OUTPUT) diff --git a/tools/power/x86/x86_energy_perf_policy/Makefile b/tools/power/x86/x86_energy_perf_policy/Makefile index 1fdeef864e7c..666b325a62a2 100644 --- a/tools/power/x86/x86_energy_perf_policy/Makefile +++ b/tools/power/x86/x86_energy_perf_policy/Makefile @@ -9,8 +9,9 @@ ifeq ("$(origin O)", "command line") endif x86_energy_perf_policy : x86_energy_perf_policy.c -override CFLAGS += -Wall -I../../../include +override CFLAGS += -O2 -Wall -I../../../include override CFLAGS += -DMSRHEADER='"../../../../arch/x86/include/asm/msr-index.h"' +override CFLAGS += -D_FORTIFY_SOURCE=2 %: %.c @mkdir -p $(BUILD_OUTPUT) -- cgit v1.2.3-59-g8ed1b From f3fe116a44fd02bc65dd312969697d06ca86b730 Mon Sep 17 00:00:00 2001 From: Matt Lupfer Date: Thu, 20 Sep 2018 10:31:44 -0400 Subject: tools/power: Fix typo in man page From context, we mean EPB (Enegry Performance Bias). Signed-off-by: Matt Lupfer Signed-off-by: Len Brown --- tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.8 b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.8 index 17db1c3af4d0..78c6361898b1 100644 --- a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.8 +++ b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.8 @@ -40,7 +40,7 @@ in the same processor package. Hardware P-States (HWP) are effectively an expansion of hardware P-state control from the opportunistic turbo-mode P-state range to include the entire range of available P-states. -On Broadwell Xeon, the initial HWP implementation, EBP influenced HWP. +On Broadwell Xeon, the initial HWP implementation, EPB influenced HWP. That influence was removed in subsequent generations, where it was moved to the Energy_Performance_Preference (EPP) field in -- cgit v1.2.3-59-g8ed1b From 03531482402a2bc4ab93cf6dde46833775e035e9 Mon Sep 17 00:00:00 2001 From: "Zephaniah E. Loss-Cutler-Hull" Date: Sat, 9 Feb 2019 05:25:48 -0800 Subject: tools/power x86_energy_perf_policy: Fix argument parsing The -w argument in x86_energy_perf_policy currently triggers an unconditional segfault. This is because the argument string reads: "+a:c:dD:E:e:f:m:M:rt:u:vw" and yet the argument handler expects an argument. When parse_optarg_string is called with a null argument, we then proceed to crash in strncmp, not horribly friendly. The man page describes -w as taking an argument, the long form (--hwp-window) is correctly marked as taking a required argument, and the code expects it. As such, this patch simply marks the short form (-w) as requiring an argument. Signed-off-by: Zephaniah E. Loss-Cutler-Hull Signed-off-by: Len Brown --- tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c index 7663abef51e9..3fe1eed900d4 100644 --- a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c +++ b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c @@ -545,7 +545,7 @@ void cmdline(int argc, char **argv) progname = argv[0]; - while ((opt = getopt_long_only(argc, argv, "+a:c:dD:E:e:f:m:M:rt:u:vw", + while ((opt = getopt_long_only(argc, argv, "+a:c:dD:E:e:f:m:M:rt:u:vw:", long_options, &option_index)) != -1) { switch (opt) { case 'a': -- cgit v1.2.3-59-g8ed1b From d743dae6d1936160366a32f3400f03db1da9421b Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 31 Aug 2019 12:30:24 -0400 Subject: tools/power turbostat: remove duplicate pc10 column Remove the duplicate pc10 column. Fixes: be0e54c4ebbf ("turbostat: Build-in "Low Power Idle" counters support") Reported-by: Naoya Horiguchi Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools') diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 75fc4fb9901c..90f7e8b4d4d4 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -849,7 +849,6 @@ int dump_counters(struct thread_data *t, struct core_data *c, outp += sprintf(outp, "pc8: %016llX\n", p->pc8); outp += sprintf(outp, "pc9: %016llX\n", p->pc9); outp += sprintf(outp, "pc10: %016llX\n", p->pc10); - outp += sprintf(outp, "pc10: %016llX\n", p->pc10); outp += sprintf(outp, "cpu_lpi: %016llX\n", p->cpu_lpi); outp += sprintf(outp, "sys_lpi: %016llX\n", p->sys_lpi); outp += sprintf(outp, "Joules PKG: %0X\n", p->energy_pkg); -- cgit v1.2.3-59-g8ed1b From d4794f25f122aa1a8a073be51112edaa723ffff4 Mon Sep 17 00:00:00 2001 From: Yazen Ghannam Date: Mon, 25 Mar 2019 17:32:42 +0000 Subject: tools/power turbostat: Make interval calculation per thread to reduce jitter Turbostat currently normalizes TSC and other values by dividing by an interval. This interval is the delta between the start of one global (all counters on all CPUs) sampling and the start of another. However, this introduces a lot of jitter into the data. In order to reduce jitter, the interval calculation should be based on timestamps taken per thread and close to the start of the thread's sampling. Define a per thread time value to hold the delta between samples taken on the thread. Use the timestamp taken at the beginning of sampling to calculate the delta. Move the thread's beginning timestamp to after the CPU migration to avoid jitter due to the migration. Use the global time delta for the average time delta. Signed-off-by: Yazen Ghannam Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 90f7e8b4d4d4..02813a2a8ffd 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -166,6 +166,7 @@ size_t cpu_present_setsize, cpu_affinity_setsize, cpu_subset_size; struct thread_data { struct timeval tv_begin; struct timeval tv_end; + struct timeval tv_delta; unsigned long long tsc; unsigned long long aperf; unsigned long long mperf; @@ -910,7 +911,7 @@ int format_counters(struct thread_data *t, struct core_data *c, if (DO_BIC(BIC_TOD)) outp += sprintf(outp, "%10ld.%06ld\t", t->tv_end.tv_sec, t->tv_end.tv_usec); - interval_float = tv_delta.tv_sec + tv_delta.tv_usec/1000000.0; + interval_float = t->tv_delta.tv_sec + t->tv_delta.tv_usec/1000000.0; tsc = t->tsc * tsc_tweak; @@ -1308,6 +1309,7 @@ delta_thread(struct thread_data *new, struct thread_data *old, * over-write old w/ new so we can print end of interval values */ + timersub(&new->tv_begin, &old->tv_begin, &old->tv_delta); old->tv_begin = new->tv_begin; old->tv_end = new->tv_end; @@ -1403,6 +1405,8 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data t->tv_begin.tv_usec = 0; t->tv_end.tv_sec = 0; t->tv_end.tv_usec = 0; + t->tv_delta.tv_sec = 0; + t->tv_delta.tv_usec = 0; t->tsc = 0; t->aperf = 0; @@ -1572,6 +1576,9 @@ void compute_average(struct thread_data *t, struct core_data *c, for_all_cpus(sum_counters, t, c, p); + /* Use the global time delta for the average. */ + average.threads.tv_delta = tv_delta; + average.threads.tsc /= topo.num_cpus; average.threads.aperf /= topo.num_cpus; average.threads.mperf /= topo.num_cpus; @@ -1761,13 +1768,13 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) struct msr_counter *mp; int i; - gettimeofday(&t->tv_begin, (struct timezone *)NULL); - if (cpu_migrate(cpu)) { fprintf(outf, "Could not migrate to CPU %d\n", cpu); return -1; } + gettimeofday(&t->tv_begin, (struct timezone *)NULL); + if (first_counter_read) get_apic_id(t); retry: -- cgit v1.2.3-59-g8ed1b From 15423b958f33132152e209e98df0dedc7a78f22c Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 8 Apr 2019 10:00:44 +0100 Subject: tools/power turbostat: fix leak of file descriptor on error return path Currently the error return path does not close the file fp and leaks a file descriptor. Fix this by closing the file. Fixes: 5ea7647b333f ("tools/power turbostat: Warn on bad ACPI LPIT data") Signed-off-by: Colin Ian King Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 02813a2a8ffd..41cf1206273c 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -2944,6 +2944,7 @@ int snapshot_sys_lpi_us(void) if (retval != 1) { fprintf(stderr, "Disabling Low Power Idle System output\n"); BIC_NOT_PRESENT(BIC_SYS_LPI); + fclose(fp); return -1; } fclose(fp); -- cgit v1.2.3-59-g8ed1b From 605736c6929d541c78a85dffae4d33a23b6b2149 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Mon, 8 Apr 2019 11:12:40 -0500 Subject: tools/power turbostat: fix file descriptor leaks Fix file descriptor leaks by closing fp before return. Addresses-Coverity-ID: 1444591 ("Resource leak") Addresses-Coverity-ID: 1444592 ("Resource leak") Fixes: 5ea7647b333f ("tools/power turbostat: Warn on bad ACPI LPIT data") Signed-off-by: Gustavo A. R. Silva Reviewed-by: Prarit Bhargava Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 41cf1206273c..2fb5c155289b 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -2918,6 +2918,7 @@ int snapshot_cpu_lpi_us(void) if (retval != 1) { fprintf(stderr, "Disabling Low Power Idle CPU output\n"); BIC_NOT_PRESENT(BIC_CPU_LPI); + fclose(fp); return -1; } -- cgit v1.2.3-59-g8ed1b From eeb71c950bc6eee460f2070643ce137e067b234c Mon Sep 17 00:00:00 2001 From: Naoya Horiguchi Date: Wed, 3 Apr 2019 16:02:14 +0900 Subject: tools/power turbostat: fix buffer overrun turbostat could be terminated by general protection fault on some latest hardwares which (for example) support 9 levels of C-states and show 18 "tADDED" lines. That bloats the total output and finally causes buffer overrun. So let's extend the buffer to avoid this. Signed-off-by: Naoya Horiguchi Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 2fb5c155289b..f8f4e1c130a6 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -5131,7 +5131,7 @@ int initialize_counters(int cpu_id) void allocate_output_buffer() { - output_buffer = calloc(1, (1 + topo.num_cpus) * 1024); + output_buffer = calloc(1, (1 + topo.num_cpus) * 2048); outp = output_buffer; if (outp == NULL) err(-1, "calloc output buffer"); -- cgit v1.2.3-59-g8ed1b From b62b3184576b8f87ca655dd9bfd1ae02fd4e50a5 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sun, 21 Apr 2019 16:30:22 +0800 Subject: tools/power turbostat: add Jacobsville support Jacobsville behaves like Denverton. Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index f8f4e1c130a6..35f4366a522e 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -4591,6 +4591,9 @@ unsigned int intel_model_duplicates(unsigned int model) case INTEL_FAM6_ICELAKE_MOBILE: return INTEL_FAM6_CANNONLAKE_MOBILE; + + case INTEL_FAM6_ATOM_TREMONT_X: + return INTEL_FAM6_ATOM_GOLDMONT_X; } return model; } -- cgit v1.2.3-59-g8ed1b From cd188af5282d9f9e65f63915b13239bafc746f8d Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 31 Aug 2019 14:09:29 -0400 Subject: tools/power turbostat: Fix Haswell Core systems turbostat: cpu0: msr offset 0x630 read failed: Input/output error because Haswell Core does not have C8-C10. Output C8-C10 only on Haswell ULT. Fixes: f5a4c76ad7de ("tools/power turbostat: consolidate duplicate model numbers") Reported-by: Prarit Bhargava Suggested-by: Kosuke Tatsukawa Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 35f4366a522e..78e7c94b94bf 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -3217,6 +3217,7 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) break; case INTEL_FAM6_HASWELL_CORE: /* HSW */ case INTEL_FAM6_HASWELL_X: /* HSX */ + case INTEL_FAM6_HASWELL_ULT: /* HSW */ case INTEL_FAM6_HASWELL_GT3E: /* HSW */ case INTEL_FAM6_BROADWELL_CORE: /* BDW */ case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ @@ -3413,6 +3414,7 @@ int has_config_tdp(unsigned int family, unsigned int model) case INTEL_FAM6_IVYBRIDGE: /* IVB */ case INTEL_FAM6_HASWELL_CORE: /* HSW */ case INTEL_FAM6_HASWELL_X: /* HSX */ + case INTEL_FAM6_HASWELL_ULT: /* HSW */ case INTEL_FAM6_HASWELL_GT3E: /* HSW */ case INTEL_FAM6_BROADWELL_CORE: /* BDW */ case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ @@ -3849,6 +3851,7 @@ void rapl_probe_intel(unsigned int family, unsigned int model) case INTEL_FAM6_SANDYBRIDGE: case INTEL_FAM6_IVYBRIDGE: case INTEL_FAM6_HASWELL_CORE: /* HSW */ + case INTEL_FAM6_HASWELL_ULT: /* HSW */ case INTEL_FAM6_HASWELL_GT3E: /* HSW */ case INTEL_FAM6_BROADWELL_CORE: /* BDW */ case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ @@ -4040,6 +4043,7 @@ void perf_limit_reasons_probe(unsigned int family, unsigned int model) switch (model) { case INTEL_FAM6_HASWELL_CORE: /* HSW */ + case INTEL_FAM6_HASWELL_ULT: /* HSW */ case INTEL_FAM6_HASWELL_GT3E: /* HSW */ do_gfx_perf_limit_reasons = 1; case INTEL_FAM6_HASWELL_X: /* HSX */ @@ -4259,6 +4263,7 @@ int has_snb_msrs(unsigned int family, unsigned int model) case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */ case INTEL_FAM6_HASWELL_CORE: /* HSW */ case INTEL_FAM6_HASWELL_X: /* HSW */ + case INTEL_FAM6_HASWELL_ULT: /* HSW */ case INTEL_FAM6_HASWELL_GT3E: /* HSW */ case INTEL_FAM6_BROADWELL_CORE: /* BDW */ case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ @@ -4292,7 +4297,7 @@ int has_hsw_msrs(unsigned int family, unsigned int model) return 0; switch (model) { - case INTEL_FAM6_HASWELL_CORE: + case INTEL_FAM6_HASWELL_ULT: /* HSW */ case INTEL_FAM6_BROADWELL_CORE: /* BDW */ case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ @@ -4576,9 +4581,6 @@ unsigned int intel_model_duplicates(unsigned int model) case INTEL_FAM6_XEON_PHI_KNM: return INTEL_FAM6_XEON_PHI_KNL; - case INTEL_FAM6_HASWELL_ULT: - return INTEL_FAM6_HASWELL_CORE; - case INTEL_FAM6_BROADWELL_X: case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ return INTEL_FAM6_BROADWELL_X; -- cgit v1.2.3-59-g8ed1b From 570992fc5733b5e1b00a4bdb9272df1e25d63972 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 31 Aug 2019 14:16:07 -0400 Subject: tools/power turbostat: rename has_hsw_msrs() Perhaps if this more descriptive name had been used, then we wouldn't have had the HSW ULT vs HSW CORE bug, fixed by the previous commit. Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 78e7c94b94bf..51c739043214 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -4280,7 +4280,7 @@ int has_snb_msrs(unsigned int family, unsigned int model) } /* - * HSW adds support for additional MSRs: + * HSW ULT added support for C8/C9/C10 MSRs: * * MSR_PKG_C8_RESIDENCY 0x00000630 * MSR_PKG_C9_RESIDENCY 0x00000631 @@ -4291,7 +4291,7 @@ int has_snb_msrs(unsigned int family, unsigned int model) * MSR_PKGC10_IRTL 0x00000635 * */ -int has_hsw_msrs(unsigned int family, unsigned int model) +int has_c8910_msrs(unsigned int family, unsigned int model) { if (!genuine_intel) return 0; @@ -4833,12 +4833,12 @@ void process_cpuid() BIC_NOT_PRESENT(BIC_CPU_c7); BIC_NOT_PRESENT(BIC_Pkgpc7); } - if (has_hsw_msrs(family, model)) { + if (has_c8910_msrs(family, model)) { BIC_PRESENT(BIC_Pkgpc8); BIC_PRESENT(BIC_Pkgpc9); BIC_PRESENT(BIC_Pkgpc10); } - do_irtl_hsw = has_hsw_msrs(family, model); + do_irtl_hsw = has_c8910_msrs(family, model); if (has_skl_msrs(family, model)) { BIC_PRESENT(BIC_Totl_c0); BIC_PRESENT(BIC_Any_c0); -- cgit v1.2.3-59-g8ed1b From d93ea567fc4eec2d3581015e23d2c555f8b393ba Mon Sep 17 00:00:00 2001 From: Rajneesh Bhardwaj Date: Fri, 14 Jun 2019 13:09:46 +0530 Subject: tools/power turbostat: Add Ice Lake NNPI support This enables turbostat utility on Ice Lake NNPI SoC. Link: https://lkml.org/lkml/2019/6/5/1034 Signed-off-by: Rajneesh Bhardwaj Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 51c739043214..393509655449 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -4592,6 +4592,7 @@ unsigned int intel_model_duplicates(unsigned int model) return INTEL_FAM6_SKYLAKE_MOBILE; case INTEL_FAM6_ICELAKE_MOBILE: + case INTEL_FAM6_ICELAKE_NNPI: return INTEL_FAM6_CANNONLAKE_MOBILE; case INTEL_FAM6_ATOM_TREMONT_X: -- cgit v1.2.3-59-g8ed1b From c026c23629b825100fd4b8223227d9a395f9a56b Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 14 Aug 2019 20:12:55 +0300 Subject: tools/power turbostat: read from pipes too Commit '47936f944e78 tools/power turbostat: fix printing on input' make a valid fix, but it completely disabled piped stdin support, which is a valuable use-case. Indeed, if stdin is a pipe, turbostat won't read anything from it, so it becomes impossible to get turbostat output at user-defined moments, instead of the regular intervals. There is no reason why this should works for terminals, but not for pipes. This patch improves the situation. Instead of ignoring pipes, we read data from them but gracefully handle the EOF case. Signed-off-by: Artem Bityutskiy Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 393509655449..095bd52cc086 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -100,6 +100,7 @@ unsigned int has_hwp_epp; /* IA32_HWP_REQUEST[bits 31:24] */ unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */ unsigned int has_misc_feature_control; unsigned int first_counter_read = 1; +int ignore_stdin; #define RAPL_PKG (1 << 0) /* 0x610 MSR_PKG_POWER_LIMIT */ @@ -3013,26 +3014,37 @@ void setup_signal_handler(void) void do_sleep(void) { - struct timeval select_timeout; + struct timeval tout; + struct timespec rest; fd_set readfds; int retval; FD_ZERO(&readfds); FD_SET(0, &readfds); - if (!isatty(fileno(stdin))) { + if (ignore_stdin) { nanosleep(&interval_ts, NULL); return; } - select_timeout = interval_tv; - retval = select(1, &readfds, NULL, NULL, &select_timeout); + tout = interval_tv; + retval = select(1, &readfds, NULL, NULL, &tout); if (retval == 1) { switch (getc(stdin)) { case 'q': exit_requested = 1; break; + case EOF: + /* + * 'stdin' is a pipe closed on the other end. There + * won't be any further input. + */ + ignore_stdin = 1; + /* Sleep the rest of the time */ + rest.tv_sec = (tout.tv_sec + tout.tv_usec / 1000000); + rest.tv_nsec = (tout.tv_usec % 1000000) * 1000; + nanosleep(&rest, NULL); } /* make sure this manually-invoked interval is at least 1ms long */ nanosleep(&one_msec, NULL); -- cgit v1.2.3-59-g8ed1b From 6ee9fc63d2e7999f93a466e202ae3b557e9c739c Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 14 Aug 2019 20:12:56 +0300 Subject: tools/power turbostat: do not enforce 1ms Turbostat works by taking a snapshot of counters, sleeping, taking another snapshot, calculating deltas, and printing out the table. The sleep time is controlled via -i option or by user sending a signal or a character to stdin. In the latter case, turbostat always adds 1 ms sleep before it reads the counters, in order to avoid larger imprecisions in the results in prints. While the 1 ms delay may be a good idea for a "dumb" user, it is a problem for an "aware" user. I do thousands and thousands of measurements over a short period of time (like 2ms), and turbostat unconditionally adds a 1ms to my interval, so I cannot get what I really need. This patch removes the unconditional 1ms sleep. This is an expert user tool, after all, and non-experts will unlikely ever use it in the non-fixed interval mode anyway, so I think it is OK to remove the 1ms delay. Signed-off-by: Artem Bityutskiy Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 095bd52cc086..7d72268e546d 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -39,7 +39,6 @@ FILE *outf; int *fd_percpu; struct timeval interval_tv = {5, 0}; struct timespec interval_ts = {5, 0}; -struct timespec one_msec = {0, 1000000}; unsigned int num_iterations; unsigned int debug; unsigned int quiet; @@ -2994,8 +2993,6 @@ static void signal_handler (int signal) fprintf(stderr, "SIGUSR1\n"); break; } - /* make sure this manually-invoked interval is at least 1ms long */ - nanosleep(&one_msec, NULL); } void setup_signal_handler(void) @@ -3046,8 +3043,6 @@ void do_sleep(void) rest.tv_nsec = (tout.tv_usec % 1000000) * 1000; nanosleep(&rest, NULL); } - /* make sure this manually-invoked interval is at least 1ms long */ - nanosleep(&one_msec, NULL); } } -- cgit v1.2.3-59-g8ed1b From 1e9042b9c8d46ada9ee7b3339a31f50d12e5d291 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Tue, 27 Aug 2019 10:57:14 -0700 Subject: tools/power turbostat: Fix CPU%C1 display value In some case C1% will be wrong value, when platform doesn't have MSR for C1 residency. For example: Core CPU CPU%c1 - - 100.00 0 0 100.00 0 2 100.00 1 1 100.00 1 3 100.00 But adding Busy% will fix this Core CPU Busy% CPU%c1 - - 99.77 0.23 0 0 99.77 0.23 0 2 99.77 0.23 1 1 99.77 0.23 1 3 99.77 0.23 This issue can be reproduced on most of the recent systems including Broadwell, Skylake and later. This is because if we don't select Busy% or Avg_MHz or Bzy_MHz then mperf value will not be read from MSR, so it will be 0. But this is required for C1% calculation when MSR for C1 residency is not present. Same is true for C3, C6 and C7 column selection. So add another define DO_BIC_READ(), which doesn't depend on user column selection and use for mperf, C3, C6 and C7 related counters. So when there is no platform support for C1 residency counters, we still read these counters, if the CPU has support and user selected display of CPU%c1. Signed-off-by: Srinivas Pandruvada Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 7d72268e546d..f57c4023231e 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -507,6 +507,7 @@ unsigned long long bic_enabled = (0xFFFFFFFFFFFFFFFFULL & ~BIC_DISABLED_BY_DEFAU unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs | BIC_APIC | BIC_X2APIC; #define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME) +#define DO_BIC_READ(COUNTER_NAME) (bic_present & COUNTER_NAME) #define ENABLE_BIC(COUNTER_NAME) (bic_enabled |= COUNTER_NAME) #define BIC_PRESENT(COUNTER_BIT) (bic_present |= COUNTER_BIT) #define BIC_NOT_PRESENT(COUNTER_BIT) (bic_present &= ~COUNTER_BIT) @@ -1287,6 +1288,14 @@ delta_core(struct core_data *new, struct core_data *old) } } +int soft_c1_residency_display(int bic) +{ + if (!DO_BIC(BIC_CPU_c1) || use_c1_residency_msr) + return 0; + + return DO_BIC_READ(bic); +} + /* * old = new - old */ @@ -1323,7 +1332,8 @@ delta_thread(struct thread_data *new, struct thread_data *old, old->c1 = new->c1 - old->c1; - if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz)) { + if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz) || + soft_c1_residency_display(BIC_Avg_MHz)) { if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) { old->aperf = new->aperf - old->aperf; old->mperf = new->mperf - old->mperf; @@ -1780,7 +1790,8 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) retry: t->tsc = rdtsc(); /* we are running on local CPU of interest */ - if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz)) { + if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz) || + soft_c1_residency_display(BIC_Avg_MHz)) { unsigned long long tsc_before, tsc_between, tsc_after, aperf_time, mperf_time; /* @@ -1857,20 +1868,20 @@ retry: if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) goto done; - if (DO_BIC(BIC_CPU_c3)) { + if (DO_BIC(BIC_CPU_c3) || soft_c1_residency_display(BIC_CPU_c3)) { if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3)) return -6; } - if (DO_BIC(BIC_CPU_c6) && !do_knl_cstates) { + if ((DO_BIC(BIC_CPU_c6) || soft_c1_residency_display(BIC_CPU_c6)) && !do_knl_cstates) { if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6)) return -7; - } else if (do_knl_cstates) { + } else if (do_knl_cstates || soft_c1_residency_display(BIC_CPU_c6)) { if (get_msr(cpu, MSR_KNL_CORE_C6_RESIDENCY, &c->c6)) return -7; } - if (DO_BIC(BIC_CPU_c7)) + if (DO_BIC(BIC_CPU_c7) || soft_c1_residency_display(BIC_CPU_c7)) if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7)) return -8; -- cgit v1.2.3-59-g8ed1b From 9cfa8e042f7cbb1994cc5923e46c78b36f6054f4 Mon Sep 17 00:00:00 2001 From: Pu Wen Date: Sat, 31 Aug 2019 10:19:58 +0800 Subject: tools/power turbostat: Fix caller parameter of get_tdp_amd() Commit 9392bd98bba760be96ee ("tools/power turbostat: Add support for AMD Fam 17h (Zen) RAPL") add a function get_tdp_amd(), the parameter is CPU family. But the rapl_probe_amd() function use wrong model parameter. Fix the wrong caller parameter of get_tdp_amd() to use family. Cc: # v5.1+ Signed-off-by: Pu Wen Reviewed-by: Calvin Walton Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index f57c4023231e..6cec6aa01241 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -4031,7 +4031,7 @@ void rapl_probe_amd(unsigned int family, unsigned int model) rapl_energy_units = ldexp(1.0, -(msr >> 8 & 0x1f)); rapl_power_units = ldexp(1.0, -(msr & 0xf)); - tdp = get_tdp_amd(model); + tdp = get_tdp_amd(family); rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; if (!quiet) -- cgit v1.2.3-59-g8ed1b From c1c10cc77883932abdb7b103687ecbb01e80bef9 Mon Sep 17 00:00:00 2001 From: Pu Wen Date: Sat, 31 Aug 2019 10:20:31 +0800 Subject: tools/power turbostat: Add support for Hygon Fam 18h (Dhyana) RAPL Commit 9392bd98bba760be96ee ("tools/power turbostat: Add support for AMD Fam 17h (Zen) RAPL") and the commit 3316f99a9f1b68c578c5 ("tools/power turbostat: Also read package power on AMD F17h (Zen)") add AMD Fam 17h RAPL support. Hygon Family 18h(Dhyana) support RAPL in bit 14 of CPUID 0x80000007 EDX, and has MSRs RAPL_PWR_UNIT/CORE_ENERGY_STAT/PKG_ENERGY_STAT. So add Hygon Dhyana Family 18h support for RAPL. Already tested on Hygon multi-node systems and it shows correct per-core energy usage and the total package power. Signed-off-by: Pu Wen Reviewed-by: Calvin Walton Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 6cec6aa01241..e8b6c608d6d1 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -59,6 +59,7 @@ unsigned int do_irtl_hsw; unsigned int units = 1000000; /* MHz etc */ unsigned int genuine_intel; unsigned int authentic_amd; +unsigned int hygon_genuine; unsigned int max_level, max_extended_level; unsigned int has_invariant_tsc; unsigned int do_nhm_platform_info; @@ -1730,7 +1731,7 @@ void get_apic_id(struct thread_data *t) if (!DO_BIC(BIC_X2APIC)) return; - if (authentic_amd) { + if (authentic_amd || hygon_genuine) { unsigned int topology_extensions; if (max_extended_level < 0x8000001e) @@ -3831,6 +3832,7 @@ double get_tdp_amd(unsigned int family) { switch (family) { case 0x17: + case 0x18: default: /* This is the max stock TDP of HEDT/Server Fam17h chips */ return 250.0; @@ -4011,6 +4013,7 @@ void rapl_probe_amd(unsigned int family, unsigned int model) switch (family) { case 0x17: /* Zen, Zen+ */ + case 0x18: /* Hygon Dhyana */ do_rapl = RAPL_AMD_F17H | RAPL_PER_CORE_ENERGY; if (rapl_joules) { BIC_PRESENT(BIC_Pkg_J); @@ -4047,7 +4050,7 @@ void rapl_probe(unsigned int family, unsigned int model) { if (genuine_intel) rapl_probe_intel(family, model); - if (authentic_amd) + if (authentic_amd || hygon_genuine) rapl_probe_amd(family, model); } @@ -4632,6 +4635,8 @@ void process_cpuid() genuine_intel = 1; else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65) authentic_amd = 1; + else if (ebx == 0x6f677948 && ecx == 0x656e6975 && edx == 0x6e65476e) + hygon_genuine = 1; if (!quiet) fprintf(outf, "CPUID(0): %.4s%.4s%.4s ", -- cgit v1.2.3-59-g8ed1b From 9eb4b5180d33c827f16829644ae0cd7382ecdb82 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 31 Aug 2019 14:40:39 -0400 Subject: tools/power turbostat: update version number Today is 19.08.31, at least in some parts of the world. Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index e8b6c608d6d1..b2a86438f074 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -5306,7 +5306,7 @@ int get_and_dump_counters(void) } void print_version() { - fprintf(outf, "turbostat version 19.03.20" + fprintf(outf, "turbostat version 19.08.31" " - Len Brown \n"); } -- cgit v1.2.3-59-g8ed1b From 8520a98dbab61e9e340cdfb72dd17ccc8a98961e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 29 Aug 2019 16:18:59 -0300 Subject: perf debug: Remove needless include directives from debug.h All we need there is a forward declaration for 'union perf_event', so remove it from there and add missing header directives in places using things from this indirect include. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-7ftk0ztstqub1tirjj8o8xbl@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 1 + tools/perf/arch/common.c | 2 ++ tools/perf/arch/x86/tests/bp-modify.c | 1 + tools/perf/arch/x86/tests/insn-x86.c | 1 + tools/perf/arch/x86/tests/rdpmc.c | 2 ++ tools/perf/arch/x86/util/perf_regs.c | 1 + tools/perf/builtin-c2c.c | 2 ++ tools/perf/builtin-config.c | 1 + tools/perf/builtin-data.c | 2 ++ tools/perf/builtin-diff.c | 1 + tools/perf/builtin-ftrace.c | 3 ++- tools/perf/builtin-help.c | 4 ++++ tools/perf/builtin-kmem.c | 1 + tools/perf/builtin-list.c | 1 + tools/perf/builtin-probe.c | 1 + tools/perf/builtin-record.c | 1 + tools/perf/builtin-report.c | 2 ++ tools/perf/builtin-top.c | 1 + tools/perf/builtin-trace.c | 1 + tools/perf/perf.c | 2 ++ tools/perf/tests/attr.c | 1 + tools/perf/tests/backward-ring-buffer.c | 1 + tools/perf/tests/bp_account.c | 1 + tools/perf/tests/bp_signal.c | 1 + tools/perf/tests/bp_signal_overflow.c | 1 + tools/perf/tests/bpf.c | 1 + tools/perf/tests/event-times.c | 1 + tools/perf/tests/expr.c | 1 + tools/perf/tests/kmod-path.c | 2 ++ tools/perf/tests/mmap-basic.c | 1 + tools/perf/tests/openat-syscall-all-cpus.c | 1 + tools/perf/tests/openat-syscall-tp-fields.c | 1 + tools/perf/tests/openat-syscall.c | 1 + tools/perf/tests/perf-record.c | 1 + tools/perf/tests/sample-parsing.c | 1 + tools/perf/tests/task-exit.c | 1 + tools/perf/tests/thread-map.c | 7 +++++++ tools/perf/tests/unit_number__scnprintf.c | 1 + tools/perf/tests/wp.c | 3 +++ tools/perf/ui/browsers/scripts.c | 1 + tools/perf/ui/gtk/helpline.c | 1 + tools/perf/ui/gtk/util.c | 1 + tools/perf/ui/tui/helpline.c | 1 + tools/perf/ui/util.c | 2 +- tools/perf/util/bpf-prologue.c | 1 + tools/perf/util/branch.c | 1 + tools/perf/util/callchain.c | 1 + tools/perf/util/cloexec.c | 2 ++ tools/perf/util/data.c | 1 + tools/perf/util/debug.c | 1 + tools/perf/util/debug.h | 6 ++---- tools/perf/util/dwarf-aux.c | 1 + tools/perf/util/dwarf-aux.h | 2 ++ tools/perf/util/env.c | 1 + tools/perf/util/evlist.c | 1 + tools/perf/util/expr.y | 2 ++ tools/perf/util/hist.c | 1 + tools/perf/util/intel-pt.c | 1 + tools/perf/util/llvm-utils.c | 1 + tools/perf/util/lzma.c | 1 + tools/perf/util/machine.c | 1 + tools/perf/util/map.c | 1 + tools/perf/util/ordered-events.c | 1 + tools/perf/util/parse-branch-options.c | 2 ++ tools/perf/util/perf-hooks.c | 1 + tools/perf/util/probe-finder.c | 1 + tools/perf/util/pstack.c | 1 + tools/perf/util/sort.c | 1 + tools/perf/util/strbuf.c | 4 ++++ tools/perf/util/symbol.c | 1 + tools/perf/util/target.c | 3 +++ tools/perf/util/thread-stack.c | 1 + tools/perf/util/util.c | 1 + tools/perf/util/values.c | 1 + tools/perf/util/zlib.c | 1 + 75 files changed, 104 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index b74fd408d496..197041fcba25 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c index a769382fb644..59dd875fd5e4 100644 --- a/tools/perf/arch/common.c +++ b/tools/perf/arch/common.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include #include +#include #include #include "common.h" #include "../util/env.h" diff --git a/tools/perf/arch/x86/tests/bp-modify.c b/tools/perf/arch/x86/tests/bp-modify.c index f53e4406709f..adcacf1b6609 100644 --- a/tools/perf/arch/x86/tests/bp-modify.c +++ b/tools/perf/arch/x86/tests/bp-modify.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/arch/x86/tests/insn-x86.c b/tools/perf/arch/x86/tests/insn-x86.c index c3e5f4ab0d3e..d67bc0ffb70a 100644 --- a/tools/perf/arch/x86/tests/insn-x86.c +++ b/tools/perf/arch/x86/tests/insn-x86.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include "debug.h" #include "tests/tests.h" diff --git a/tools/perf/arch/x86/tests/rdpmc.c b/tools/perf/arch/x86/tests/rdpmc.c index 345a6a0a328b..6e67cee792b1 100644 --- a/tools/perf/arch/x86/tests/rdpmc.c +++ b/tools/perf/arch/x86/tests/rdpmc.c @@ -6,11 +6,13 @@ #include #include #include +#include #include #include "perf-sys.h" #include "debug.h" #include "tests/tests.h" #include "cloexec.h" +#include "event.h" #include "util.h" #include "arch-tests.h" diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c index 74a606ea42d3..99ea60211e16 100644 --- a/tools/perf/arch/x86/util/perf_regs.c +++ b/tools/perf/arch/x86/util/perf_regs.c @@ -7,6 +7,7 @@ #include "../../perf-sys.h" #include "../../util/perf_regs.h" #include "../../util/debug.h" +#include "../../util/event.h" const struct sample_reg sample_reg_masks[] = { SMPL_REG(AX, PERF_REG_X86_AX), diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index 25a5f186dfde..d1ad694c67a2 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -20,6 +20,7 @@ #include #include "debug.h" #include "builtin.h" +#include #include #include "mem-events.h" #include "session.h" @@ -35,6 +36,7 @@ #include "thread.h" #include "mem2node.h" #include "symbol.h" +#include "ui/ui.h" #include "../perf.h" struct c2c_hists { diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index edfc8f76f1bd..42d8157e047a 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -13,6 +13,7 @@ #include "util/debug.h" #include "util/config.h" #include +#include #include static bool use_system_config, use_user_config; diff --git a/tools/perf/builtin-data.c b/tools/perf/builtin-data.c index dde25d4ca56d..ca2fb44874e4 100644 --- a/tools/perf/builtin-data.c +++ b/tools/perf/builtin-data.c @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include +#include #include "builtin.h" #include "perf.h" #include "debug.h" diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index ae4a8ebf90d2..827e4800d862 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -24,6 +24,7 @@ #include "util/annotate.h" #include "util/map.h" #include +#include #include #include diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 7374f86833fd..2f8ea44c00c4 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -13,8 +13,10 @@ #include #include #include +#include #include "debug.h" +#include #include #include #include "evlist.h" @@ -24,7 +26,6 @@ #include "util/cap.h" #include "util/config.h" - #define DEFAULT_TRACER "function_graph" struct perf_ftrace { diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c index 641d4a3f93c3..3976aebe3677 100644 --- a/tools/perf/builtin-help.c +++ b/tools/perf/builtin-help.c @@ -4,7 +4,9 @@ * * Builtin help command */ +#include "util/cache.h" #include "util/config.h" +#include "util/strbuf.h" #include "builtin.h" #include #include "common-cmds.h" @@ -13,10 +15,12 @@ #include #include "util/debug.h" #include +#include #include #include #include #include +#include #include #include #include diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 46f828936120..7eec0da64c46 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -14,6 +14,7 @@ #include "util/callchain.h" #include "util/time-utils.h" +#include #include #include "util/trace-event.h" #include "util/data.h" diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index dca0d33c1343..11afb760616b 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -16,6 +16,7 @@ #include "util/debug.h" #include "util/metricgroup.h" #include +#include static bool desc_flag = true; static bool details_flag; diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index f45fd7e9723e..8950c05ef8fd 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -26,6 +26,7 @@ #include "util/probe-finder.h" #include "util/probe-event.h" #include "util/probe-file.h" +#include #include #define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*" diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 56705d2a6bec..1447004eee8a 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 33c20e26b290..94e7e354cb16 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -45,6 +45,7 @@ #include "util/units.h" #include "util/branch.h" #include "util/util.h" +#include "ui/ui.h" #include #include @@ -53,6 +54,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index c3f95440e99c..5538b5886e35 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -45,6 +45,7 @@ #include "util/intlist.h" #include "util/parse-branch-options.h" #include "arch/common.h" +#include "ui/ui.h" #include "util/debug.h" #include "util/ordered-events.h" diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 105695033ebc..b1ec8ff52740 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -29,6 +29,7 @@ #include "util/event.h" #include "util/evlist.h" #include "util/evswitch.h" +#include #include #include "util/machine.h" #include "util/map.h" diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 237b9b3a1bf1..e0910637a82d 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -10,6 +10,7 @@ #include "builtin.h" #include "perf.h" +#include "util/cache.h" #include "util/env.h" #include #include "util/config.h" @@ -32,6 +33,7 @@ #include #include #include +#include #include const char perf_usage_string[] = diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c index 87dc3e1174af..a9599ab8c471 100644 --- a/tools/perf/tests/attr.c +++ b/tools/perf/tests/attr.c @@ -32,6 +32,7 @@ #include #include "../perf-sys.h" #include +#include "event.h" #include "tests.h" #define ENV "PERF_TEST_ATTR" diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index b6f27ef9fb02..512288e9f547 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -10,6 +10,7 @@ #include "tests.h" #include "debug.h" #include +#include #define NR_ITERS 111 diff --git a/tools/perf/tests/bp_account.c b/tools/perf/tests/bp_account.c index c4a30318d7e0..016bba2c142d 100644 --- a/tools/perf/tests/bp_account.c +++ b/tools/perf/tests/bp_account.c @@ -19,6 +19,7 @@ #include "tests.h" #include "debug.h" +#include "event.h" #include "../perf-sys.h" #include "cloexec.h" diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c index 2d292f8fb3dd..c1c2c13de254 100644 --- a/tools/perf/tests/bp_signal.c +++ b/tools/perf/tests/bp_signal.c @@ -25,6 +25,7 @@ #include "tests.h" #include "debug.h" +#include "event.h" #include "perf-sys.h" #include "cloexec.h" diff --git a/tools/perf/tests/bp_signal_overflow.c b/tools/perf/tests/bp_signal_overflow.c index 101315a3b34f..eb4dbbddf4ff 100644 --- a/tools/perf/tests/bp_signal_overflow.c +++ b/tools/perf/tests/bp_signal_overflow.c @@ -24,6 +24,7 @@ #include "tests.h" #include "debug.h" +#include "event.h" #include "../perf-sys.h" #include "cloexec.h" diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 98642961fc63..9fc163b2acbb 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include "tests.h" diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 714e3611352c..228d1618cf7d 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include #include diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index ee1d88650e69..87843af4c118 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -3,6 +3,7 @@ #include "util/expr.h" #include "tests.h" #include +#include #include static int test(struct parse_ctx *ctx, const char *e, double val2) diff --git a/tools/perf/tests/kmod-path.c b/tools/perf/tests/kmod-path.c index 0579a70bbbff..e483210b176b 100644 --- a/tools/perf/tests/kmod-path.c +++ b/tools/perf/tests/kmod-path.c @@ -1,9 +1,11 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include "tests.h" #include "dso.h" #include "debug.h" +#include "event.h" static int test(const char *path, bool alloc_name, bool kmod, int comp, const char *name) diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index fe91350fd5ab..bdf77bfe1b80 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -13,6 +13,7 @@ #include "tests.h" #include #include +#include #include /* diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index 4ae4dea07466..9171f77cd9cd 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "evsel.h" #include "tests.h" diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index 62492106fb5e..b71167b43dda 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include #include #include diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c index 58df4bda5e12..5ebffae18605 100644 --- a/tools/perf/tests/openat-syscall.c +++ b/tools/perf/tests/openat-syscall.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 3a205f6f9363..e1b42292cf7f 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include /* For the CLR_() macros */ #include diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c index a8ca29fe172b..0c09dc15a059 100644 --- a/tools/perf/tests/sample-parsing.c +++ b/tools/perf/tests/sample-parsing.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 0e0e0627184e..f610e8c0a083 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -9,6 +9,7 @@ #include #include +#include #include static int exited; diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c index c19ec8849e77..39168c57943b 100644 --- a/tools/perf/tests/thread-map.c +++ b/tools/perf/tests/thread-map.c @@ -1,12 +1,19 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include #include #include "tests.h" #include "thread_map.h" #include "debug.h" +#include "event.h" #include +#include + +struct perf_sample; +struct perf_tool; +struct machine; #define NAME (const char *) "perf" #define NAMEUL (unsigned long) NAME diff --git a/tools/perf/tests/unit_number__scnprintf.c b/tools/perf/tests/unit_number__scnprintf.c index 2bb8cb0039c1..3721757435da 100644 --- a/tools/perf/tests/unit_number__scnprintf.c +++ b/tools/perf/tests/unit_number__scnprintf.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "tests.h" #include "units.h" #include "debug.h" diff --git a/tools/perf/tests/wp.c b/tools/perf/tests/wp.c index 982ac55d69ea..d262d6639829 100644 --- a/tools/perf/tests/wp.c +++ b/tools/perf/tests/wp.c @@ -1,10 +1,13 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include #include +#include #include "tests.h" #include "debug.h" +#include "event.h" #include "cloexec.h" #include "../perf-sys.h" diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c index e63f3778d75c..77809c0fad02 100644 --- a/tools/perf/ui/browsers/scripts.c +++ b/tools/perf/ui/browsers/scripts.c @@ -9,6 +9,7 @@ #include "../browser.h" #include "../libslang.h" #include "config.h" +#include #include #define SCRIPT_NAMELEN 128 diff --git a/tools/perf/ui/gtk/helpline.c b/tools/perf/ui/gtk/helpline.c index fbf1ea9ce9a2..e166da9ec767 100644 --- a/tools/perf/ui/gtk/helpline.c +++ b/tools/perf/ui/gtk/helpline.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include "gtk.h" #include "../ui.h" diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c index c28bdb7517ac..c2c558958b9c 100644 --- a/tools/perf/ui/gtk/util.c +++ b/tools/perf/ui/gtk/util.c @@ -3,6 +3,7 @@ #include "../../util/debug.h" #include "gtk.h" +#include #include #include diff --git a/tools/perf/ui/tui/helpline.c b/tools/perf/ui/tui/helpline.c index 93d6b7240285..1793c98653a5 100644 --- a/tools/perf/ui/tui/helpline.c +++ b/tools/perf/ui/tui/helpline.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "../../util/debug.h" #include "../helpline.h" diff --git a/tools/perf/ui/util.c b/tools/perf/ui/util.c index 9ed76e88a3e4..689b27c34246 100644 --- a/tools/perf/ui/util.c +++ b/tools/perf/ui/util.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "util.h" #include "../util/debug.h" - +#include /* * Default error logging functions diff --git a/tools/perf/util/bpf-prologue.c b/tools/perf/util/bpf-prologue.c index 09e6c76e1c3b..b020a8678eb9 100644 --- a/tools/perf/util/bpf-prologue.c +++ b/tools/perf/util/bpf-prologue.c @@ -13,6 +13,7 @@ #include "bpf-prologue.h" #include "probe-finder.h" #include +#include #include #include diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c index 02d6d839ff24..30642e1f2b1b 100644 --- a/tools/perf/util/branch.c +++ b/tools/perf/util/branch.c @@ -1,6 +1,7 @@ #include "util/util.h" #include "util/debug.h" #include "util/branch.h" +#include static bool cross_area(u64 addr1, u64 addr2, int size) { diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index a47d0e8c2434..76bf05b26d3b 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "asm/bug.h" diff --git a/tools/perf/util/cloexec.c b/tools/perf/util/cloexec.c index 92d08198e64a..4e904fcb2783 100644 --- a/tools/perf/util/cloexec.c +++ b/tools/perf/util/cloexec.c @@ -4,10 +4,12 @@ #include "util.h" #include "../perf-sys.h" #include "cloexec.h" +#include "event.h" #include "asm/bug.h" #include "debug.h" #include #include +#include static unsigned long flag = PERF_FLAG_FD_CLOEXEC; diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c index 74aafe0df506..e75c3a279fe8 100644 --- a/tools/perf/util/data.c +++ b/tools/perf/util/data.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include #include #include diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index c822c5943340..522887ee4c02 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c @@ -19,6 +19,7 @@ #include "print_binary.h" #include "util.h" #include "target.h" +#include "ui/helpline.h" #include diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index 77445dfc5c7d..b2deee987ffa 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h @@ -4,11 +4,7 @@ #define __PERF_DEBUG_H #include -#include #include -#include "event.h" -#include "../ui/helpline.h" -#include "../ui/progress.h" #include "../ui/util.h" extern int verbose; @@ -42,6 +38,8 @@ extern int debug_data_convert; #define STRERR_BUFSIZE 128 /* For the buffer size of str_error_r */ +union perf_event; + int dump_printf(const char *fmt, ...) __printf(1, 2); void trace_event(union perf_event *event); diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index 03b2de1f5a35..df6cee5c071f 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -9,6 +9,7 @@ #include #include "debug.h" #include "dwarf-aux.h" +#include "strbuf.h" #include "string2.h" /** diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h index 0489b0cf8e2c..f204e5892403 100644 --- a/tools/perf/util/dwarf-aux.h +++ b/tools/perf/util/dwarf-aux.h @@ -10,6 +10,8 @@ #include #include +struct strbuf; + /* Find the realpath of the target file */ const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname); diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c index 571efb4f0351..3baca06786fb 100644 --- a/tools/perf/util/env.c +++ b/tools/perf/util/env.c @@ -9,6 +9,7 @@ #include #include #include +#include struct perf_env perf_env; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 71b231c7097f..b5d6d6ec9a9b 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y index 432b8560cf51..f9a20a39b64a 100644 --- a/tools/perf/util/expr.y +++ b/tools/perf/util/expr.y @@ -2,9 +2,11 @@ %{ #include "util.h" #include "util/debug.h" +#include // strtod() #define IN_EXPR_Y 1 #include "expr.h" #include "smt.h" +#include #include #define MAXIDLEN 256 diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index adae4134e972..02ea2ee62814 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 825e3690940d..9b56fb74bedf 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c index 9f0470ecbca9..55fb4b3b1157 100644 --- a/tools/perf/util/llvm-utils.c +++ b/tools/perf/util/llvm-utils.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "debug.h" #include "llvm-utils.h" diff --git a/tools/perf/util/lzma.c b/tools/perf/util/lzma.c index b1dd29a9d915..397447066033 100644 --- a/tools/perf/util/lzma.c +++ b/tools/perf/util/lzma.c @@ -9,6 +9,7 @@ #include "compress.h" #include "util.h" #include "debug.h" +#include #include #define BUFSIZE 8192 diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index a1542b4c047b..6e9afe4e55dd 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -30,6 +30,7 @@ #include #include #include +#include #include static void __machine__remove_thread(struct machine *machine, struct thread *th, bool lock); diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 27b7b102e4a2..c75b20b93820 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -20,6 +20,7 @@ #include "namespaces.h" #include "unwind.h" #include "srccode.h" +#include "ui/ui.h" static void __maps__insert(struct maps *maps, struct map *map); static void __maps__insert_name(struct maps *maps, struct map *map); diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c index bb5f34b7ab44..359db2b1fcef 100644 --- a/tools/perf/util/ordered-events.c +++ b/tools/perf/util/ordered-events.c @@ -8,6 +8,7 @@ #include "session.h" #include "asm/bug.h" #include "debug.h" +#include "ui/progress.h" #define pr_N(n, fmt, ...) \ eprintf(n, debug_ordered_events, fmt, ##__VA_ARGS__) diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c index 1430437b9d51..bb4aa88c50a8 100644 --- a/tools/perf/util/parse-branch-options.c +++ b/tools/perf/util/parse-branch-options.c @@ -1,8 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 #include "util/debug.h" +#include "util/event.h" #include #include "util/parse-branch-options.h" #include +#include #define BRANCH_OPT(n, m) \ { .name = n, .mode = (m) } diff --git a/tools/perf/util/perf-hooks.c b/tools/perf/util/perf-hooks.c index 4f3aa8d99ef4..e635c594f773 100644 --- a/tools/perf/util/perf-hooks.c +++ b/tools/perf/util/perf-hooks.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 025fc4491993..505905fc21c5 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -24,6 +24,7 @@ #include "dso.h" #include "debug.h" #include "intlist.h" +#include "strbuf.h" #include "strlist.h" #include "symbol.h" #include "probe-finder.h" diff --git a/tools/perf/util/pstack.c b/tools/perf/util/pstack.c index 28de8a4c2ce8..80ff41fc45be 100644 --- a/tools/perf/util/pstack.c +++ b/tools/perf/util/pstack.c @@ -10,6 +10,7 @@ #include #include #include +#include struct pstack { unsigned short top; diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 23d0ab7c801c..035355a9945e 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -22,6 +22,7 @@ #include "annotate.h" #include "time-utils.h" #include +#include regex_t parent_regex; const char default_parent_pattern[] = "^sys_|^do_page_fault"; diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c index 0afdbf38a2b2..a64a37628f12 100644 --- a/tools/perf/util/strbuf.c +++ b/tools/perf/util/strbuf.c @@ -1,8 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 +#include "cache.h" #include "debug.h" +#include "strbuf.h" #include +#include #include #include +#include #include #include diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 035f2e75728c..c37cca690864 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/util/target.c b/tools/perf/util/target.c index 3adc65480349..565f7aef7e6c 100644 --- a/tools/perf/util/target.c +++ b/tools/perf/util/target.c @@ -10,8 +10,11 @@ #include "debug.h" #include +#include #include #include +#include +#include enum target_errno target__validate(struct target *target) { diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c index 15134ac9b8f1..cd8a948d03ec 100644 --- a/tools/perf/util/thread-stack.c +++ b/tools/perf/util/thread-stack.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "thread.h" #include "event.h" #include "machine.h" diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 607daec22943..32322a20a68b 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "util.h" #include "debug.h" +#include "event.h" #include "namespaces.h" #include #include diff --git a/tools/perf/util/values.c b/tools/perf/util/values.c index c59154e2d124..b9823f414f10 100644 --- a/tools/perf/util/values.c +++ b/tools/perf/util/values.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include diff --git a/tools/perf/util/zlib.c b/tools/perf/util/zlib.c index 512ad7c09b13..59d456f716e9 100644 --- a/tools/perf/util/zlib.c +++ b/tools/perf/util/zlib.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include #include #include -- cgit v1.2.3-59-g8ed1b From b6b5574b80d6ce6ca87ae3ea1e97cff1bf730f2e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 29 Aug 2019 17:10:59 -0300 Subject: perf env: Remove env.h from other headers where just a fwd decl is needed And fixup the fallout of c files not building due to now missing headers. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-sw8k3kpla98pr3rqypbjk9hf@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/common.h | 4 +++- tools/perf/tests/mem2node.c | 2 ++ tools/perf/util/cputopo.h | 1 - tools/perf/util/mem2node.c | 2 ++ tools/perf/util/mem2node.h | 3 ++- 5 files changed, 9 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/common.h b/tools/perf/arch/common.h index c298a446d1f6..e965ed8bb328 100644 --- a/tools/perf/arch/common.h +++ b/tools/perf/arch/common.h @@ -2,7 +2,9 @@ #ifndef ARCH_PERF_COMMON_H #define ARCH_PERF_COMMON_H -#include "../util/env.h" +#include + +struct perf_env; int perf_env__lookup_objdump(struct perf_env *env, const char **path); bool perf_env__single_address_space(struct perf_env *env); diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c index 73b2855acaf4..7672ade70f20 100644 --- a/tools/perf/tests/mem2node.c +++ b/tools/perf/tests/mem2node.c @@ -1,10 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include #include #include "cpumap.h" #include "debug.h" +#include "env.h" #include "mem2node.h" #include "tests.h" diff --git a/tools/perf/util/cputopo.h b/tools/perf/util/cputopo.h index bae2f1d41856..7bf6b811f715 100644 --- a/tools/perf/util/cputopo.h +++ b/tools/perf/util/cputopo.h @@ -3,7 +3,6 @@ #define __PERF_CPUTOPO_H #include -#include "env.h" struct cpu_topology { u32 core_sib; diff --git a/tools/perf/util/mem2node.c b/tools/perf/util/mem2node.c index 14fb9e72aeeb..797d86a1ab09 100644 --- a/tools/perf/util/mem2node.c +++ b/tools/perf/util/mem2node.c @@ -1,8 +1,10 @@ #include #include #include +#include #include #include "debug.h" +#include "env.h" #include "mem2node.h" struct phys_entry { diff --git a/tools/perf/util/mem2node.h b/tools/perf/util/mem2node.h index 59c4752a2181..8dfa2b58d0cd 100644 --- a/tools/perf/util/mem2node.h +++ b/tools/perf/util/mem2node.h @@ -2,8 +2,9 @@ #define __MEM2NODE_H #include -#include "env.h" +#include +struct perf_env; struct phys_entry; struct mem2node { -- cgit v1.2.3-59-g8ed1b From 4cb3c6d546aa5493a960d05eb73bad8e69a58574 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 29 Aug 2019 17:19:02 -0300 Subject: perf event: Remove needless include directives from event.h bpf.h and build-id.h are not needed at all in event.h, remove them. And fixup the fallout of files that were getting needed stuff from this now pruned include. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-rdm3dgtlrndmmnlc4bafsg3b@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/powerpc/util/unwind-libdw.c | 1 + tools/perf/arch/x86/util/perf_regs.c | 1 + tools/perf/perf.c | 1 + tools/perf/util/bpf-event.h | 1 + tools/perf/util/callchain.h | 1 + tools/perf/util/config.c | 2 ++ tools/perf/util/debug.c | 1 + tools/perf/util/event.h | 18 ++++++++++++------ 8 files changed, 20 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/powerpc/util/unwind-libdw.c b/tools/perf/arch/powerpc/util/unwind-libdw.c index 7a1f05ef2fc0..abf2dbc7f829 100644 --- a/tools/perf/arch/powerpc/util/unwind-libdw.c +++ b/tools/perf/arch/powerpc/util/unwind-libdw.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include "../../util/unwind-libdw.h" #include "../../util/perf_regs.h" #include "../../util/event.h" diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c index 99ea60211e16..c218b83e063b 100644 --- a/tools/perf/arch/x86/util/perf_regs.c +++ b/tools/perf/arch/x86/util/perf_regs.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "../../perf-sys.h" diff --git a/tools/perf/perf.c b/tools/perf/perf.c index e0910637a82d..8763b2c0fbfd 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -10,6 +10,7 @@ #include "builtin.h" #include "perf.h" +#include "util/build-id.h" #include "util/cache.h" #include "util/env.h" #include diff --git a/tools/perf/util/bpf-event.h b/tools/perf/util/bpf-event.h index 417b78835ea0..a01c2fd68c03 100644 --- a/tools/perf/util/bpf-event.h +++ b/tools/perf/util/bpf-event.h @@ -13,6 +13,7 @@ struct machine; union perf_event; struct perf_env; struct perf_sample; +struct perf_session; struct record_opts; struct evlist; struct target; diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 45b9ed49e2b1..b042ceef4114 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -8,6 +8,7 @@ #include "map_symbol.h" #include "branch.h" +struct evsel; struct map; #define HELP_PAD "\t\t\t\t" diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index eb5308c41ed1..7ebf9e31ae22 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -17,6 +17,8 @@ #include "util/event.h" /* proc_map_timeout */ #include "util/hist.h" /* perf_hist_config */ #include "util/llvm-utils.h" /* perf_llvm_config */ +#include "build-id.h" +#include "debug.h" #include "config.h" #include "debug.h" #include diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index 522887ee4c02..143d379d4608 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #ifdef HAVE_BACKTRACE_SUPPORT #include diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index f56d268f06e3..006aa432be19 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -1,17 +1,23 @@ /* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_RECORD_H #define __PERF_RECORD_H - -#include +/* + * The linux/stddef.h isn't need here, but is needed for __always_inline used + * in files included from uapi/linux/perf_event.h such as + * /usr/include/linux/swab.h and /usr/include/linux/byteorder/little_endian.h, + * detected in at least musl libc, used in Alpine Linux. -acme + */ #include -#include -#include -#include +#include #include +#include -#include "build-id.h" #include "perf_regs.h" +struct dso; +struct machine; +struct perf_event_attr; + #ifdef __LP64__ /* * /usr/include/inttypes.h uses just 'lu' for PRIu64, but we end up defining -- cgit v1.2.3-59-g8ed1b From 38847db9740a984e8538ce2573cbc0fc7edf22b3 Mon Sep 17 00:00:00 2001 From: Tzvetomir Stoyanov Date: Mon, 5 Aug 2019 16:43:13 -0400 Subject: libtraceevent, perf tools: Changes in tep_print_event_* APIs Libtraceevent APIs for printing various trace events information are complicated, there are complex extra parameters. To control the way event information is printed, the user should call a set of functions in a specific sequence. These APIs are reimplemented to provide a more simple interface for printing event information. Removed APIs: tep_print_event_task() tep_print_event_time() tep_print_event_data() tep_event_info() tep_is_latency_format() tep_set_latency_format() tep_data_latency_format() tep_set_print_raw() A new API for printing event information is introduced: void tep_print_event(struct tep_handle *tep, struct trace_seq *s, struct tep_record *record, const char *fmt, ...); where "fmt" is a printf-like format string, followed by the event fields to be printed. Supported fields: TEP_PRINT_PID, "%d" - event PID TEP_PRINT_CPU, "%d" - event CPU TEP_PRINT_COMM, "%s" - event command string TEP_PRINT_NAME, "%s" - event name TEP_PRINT_LATENCY, "%s" - event latency TEP_PRINT_TIME, %d - event time stamp. A divisor and precision can be specified as part of this format string: "%precision.divisord". Example: "%3.1000d" - divide the time by 1000 and print the first 3 digits before the dot. Thus, the time stamp "123456000" will be printed as "123.456" TEP_PRINT_INFO, "%s" - event information. TEP_PRINT_INFO_RAW, "%s" - event information, in raw format. Example: tep_print_event(tep, s, record, "%16s-%-5d [%03d] %s %6.1000d %s %s", TEP_PRINT_COMM, TEP_PRINT_PID, TEP_PRINT_CPU, TEP_PRINT_LATENCY, TEP_PRINT_TIME, TEP_PRINT_NAME, TEP_PRINT_INFO); Output: ls-11314 [005] d.h. 185207.366383 function __wake_up Signed-off-by: Tzvetomir Stoyanov Cc: Andrew Morton Cc: Jiri Olsa Cc: Namhyung Kim Cc: linux-trace-devel@vger.kernel.org Cc: Patrick McLean Link: http://lore.kernel.org/linux-trace-devel/20190801074959.22023-2-tz.stoyanov@gmail.com Link: http://lore.kernel.org/lkml/20190805204355.041132030@goodmis.org Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse-api.c | 40 ---- tools/lib/traceevent/event-parse-local.h | 4 - tools/lib/traceevent/event-parse.c | 322 ++++++++++++++++++------------- tools/lib/traceevent/event-parse.h | 29 ++- tools/perf/builtin-kmem.c | 3 +- tools/perf/util/sort.c | 3 +- tools/perf/util/trace-event-parse.c | 2 +- 7 files changed, 203 insertions(+), 200 deletions(-) (limited to 'tools') diff --git a/tools/lib/traceevent/event-parse-api.c b/tools/lib/traceevent/event-parse-api.c index 988587840c80..4faf52a65791 100644 --- a/tools/lib/traceevent/event-parse-api.c +++ b/tools/lib/traceevent/event-parse-api.c @@ -302,33 +302,6 @@ void tep_set_local_bigendian(struct tep_handle *tep, enum tep_endian endian) tep->host_bigendian = endian; } -/** - * tep_is_latency_format - get if the latency output format is configured - * @tep: a handle to the tep_handle - * - * This returns true if the latency output format is configured - * If @tep is NULL, false is returned. - */ -bool tep_is_latency_format(struct tep_handle *tep) -{ - if (tep) - return (tep->latency_format); - return false; -} - -/** - * tep_set_latency_format - set the latency output format - * @tep: a handle to the tep_handle - * @lat: non zero for latency output format - * - * This sets the latency output format - */ -void tep_set_latency_format(struct tep_handle *tep, int lat) -{ - if (tep) - tep->latency_format = lat; -} - /** * tep_is_old_format - get if an old kernel is used * @tep: a handle to the tep_handle @@ -344,19 +317,6 @@ bool tep_is_old_format(struct tep_handle *tep) return false; } -/** - * tep_set_print_raw - set a flag to force print in raw format - * @tep: a handle to the tep_handle - * @print_raw: the new value of the print_raw flag - * - * This sets a flag to force print in raw format - */ -void tep_set_print_raw(struct tep_handle *tep, int print_raw) -{ - if (tep) - tep->print_raw = print_raw; -} - /** * tep_set_test_filters - set a flag to test a filter string * @tep: a handle to the tep_handle diff --git a/tools/lib/traceevent/event-parse-local.h b/tools/lib/traceevent/event-parse-local.h index 09aa142f7fdd..6e58ee1fe7c8 100644 --- a/tools/lib/traceevent/event-parse-local.h +++ b/tools/lib/traceevent/event-parse-local.h @@ -28,8 +28,6 @@ struct tep_handle { enum tep_endian file_bigendian; enum tep_endian host_bigendian; - int latency_format; - int old_format; int cpus; @@ -70,8 +68,6 @@ struct tep_handle { int ld_offset; int ld_size; - int print_raw; - int test_filters; int flags; diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 3e83636076b2..d1085aab9c43 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -5212,24 +5212,20 @@ out_failed: } } -/** - * tep_data_latency_format - parse the data for the latency format - * @tep: a handle to the trace event parser context - * @s: the trace_seq to write to - * @record: the record to read from - * +/* * This parses out the Latency format (interrupts disabled, * need rescheduling, in hard/soft interrupt, preempt count * and lock depth) and places it into the trace_seq. */ -void tep_data_latency_format(struct tep_handle *tep, - struct trace_seq *s, struct tep_record *record) +static void data_latency_format(struct tep_handle *tep, struct trace_seq *s, + char *format, struct tep_record *record) { static int check_lock_depth = 1; static int check_migrate_disable = 1; static int lock_depth_exists; static int migrate_disable_exists; unsigned int lat_flags; + struct trace_seq sq; unsigned int pc; int lock_depth = 0; int migrate_disable = 0; @@ -5237,6 +5233,7 @@ void tep_data_latency_format(struct tep_handle *tep, int softirq; void *data = record->data; + trace_seq_init(&sq); lat_flags = parse_common_flags(tep, data); pc = parse_common_pc(tep, data); /* lock_depth may not always exist */ @@ -5264,7 +5261,7 @@ void tep_data_latency_format(struct tep_handle *tep, hardirq = lat_flags & TRACE_FLAG_HARDIRQ; softirq = lat_flags & TRACE_FLAG_SOFTIRQ; - trace_seq_printf(s, "%c%c%c", + trace_seq_printf(&sq, "%c%c%c", (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' : (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ? 'X' : '.', @@ -5274,24 +5271,32 @@ void tep_data_latency_format(struct tep_handle *tep, hardirq ? 'h' : softirq ? 's' : '.'); if (pc) - trace_seq_printf(s, "%x", pc); + trace_seq_printf(&sq, "%x", pc); else - trace_seq_putc(s, '.'); + trace_seq_printf(&sq, "."); if (migrate_disable_exists) { if (migrate_disable < 0) - trace_seq_putc(s, '.'); + trace_seq_printf(&sq, "."); else - trace_seq_printf(s, "%d", migrate_disable); + trace_seq_printf(&sq, "%d", migrate_disable); } if (lock_depth_exists) { if (lock_depth < 0) - trace_seq_putc(s, '.'); + trace_seq_printf(&sq, "."); else - trace_seq_printf(s, "%d", lock_depth); + trace_seq_printf(&sq, "%d", lock_depth); } + if (sq.state == TRACE_SEQ__MEM_ALLOC_FAILED) { + s->state = TRACE_SEQ__MEM_ALLOC_FAILED; + return; + } + + trace_seq_terminate(&sq); + trace_seq_puts(s, sq.buffer); + trace_seq_destroy(&sq); trace_seq_terminate(s); } @@ -5452,21 +5457,16 @@ int tep_cmdline_pid(struct tep_handle *tep, struct tep_cmdline *cmdline) return cmdline->pid; } -/** - * tep_event_info - parse the data into the print format - * @s: the trace_seq to write to - * @event: the handle to the event - * @record: the record to read from - * +/* * This parses the raw @data using the given @event information and * writes the print format into the trace_seq. */ -void tep_event_info(struct trace_seq *s, struct tep_event *event, - struct tep_record *record) +static void print_event_info(struct trace_seq *s, char *format, bool raw, + struct tep_event *event, struct tep_record *record) { int print_pretty = 1; - if (event->tep->print_raw || (event->flags & TEP_EVENT_FL_PRINTRAW)) + if (raw || (event->flags & TEP_EVENT_FL_PRINTRAW)) tep_print_fields(s, record->data, record->size, event); else { @@ -5481,20 +5481,6 @@ void tep_event_info(struct trace_seq *s, struct tep_event *event, trace_seq_terminate(s); } -static bool is_timestamp_in_us(char *trace_clock, bool use_trace_clock) -{ - if (!trace_clock || !use_trace_clock) - return true; - - if (!strcmp(trace_clock, "local") || !strcmp(trace_clock, "global") - || !strcmp(trace_clock, "uptime") || !strcmp(trace_clock, "perf") - || !strncmp(trace_clock, "mono", 4)) - return true; - - /* trace_clock is setting in tsc or counter mode */ - return false; -} - /** * tep_find_event_by_record - return the event from a given record * @tep: a handle to the trace event parser context @@ -5518,129 +5504,195 @@ tep_find_event_by_record(struct tep_handle *tep, struct tep_record *record) return tep_find_event(tep, type); } -/** - * tep_print_event_task - Write the event task comm, pid and CPU - * @tep: a handle to the trace event parser context - * @s: the trace_seq to write to - * @event: the handle to the record's event - * @record: The record to get the event from - * - * Writes the tasks comm, pid and CPU to @s. +/* + * Writes the timestamp of the record into @s. Time divisor and precision can be + * specified as part of printf @format string. Example: + * "%3.1000d" - divide the time by 1000 and print the first 3 digits + * before the dot. Thus, the timestamp "123456000" will be printed as + * "123.456" */ -void tep_print_event_task(struct tep_handle *tep, struct trace_seq *s, - struct tep_event *event, - struct tep_record *record) +static void print_event_time(struct tep_handle *tep, struct trace_seq *s, + char *format, struct tep_event *event, + struct tep_record *record) +{ + unsigned long long time; + char *divstr; + int prec = 0, pr; + int div = 0; + int p10 = 1; + + if (isdigit(*(format + 1))) + prec = atoi(format + 1); + divstr = strchr(format, '.'); + if (divstr && isdigit(*(divstr + 1))) + div = atoi(divstr + 1); + time = record->ts; + if (div) + time /= div; + pr = prec; + while (pr--) + p10 *= 10; + + if (p10 > 1 && p10 < time) + trace_seq_printf(s, "%5llu.%0*llu", time / p10, prec, time % p10); + else + trace_seq_printf(s, "%12llu\n", time); +} + +struct print_event_type { + enum { + EVENT_TYPE_INT = 1, + EVENT_TYPE_STRING, + EVENT_TYPE_UNKNOWN, + } type; + char format[32]; +}; + +static void print_string(struct tep_handle *tep, struct trace_seq *s, + struct tep_record *record, struct tep_event *event, + const char *arg, struct print_event_type *type) { - void *data = record->data; const char *comm; int pid; - pid = parse_common_pid(tep, data); - comm = find_cmdline(tep, pid); + if (strncmp(arg, TEP_PRINT_LATENCY, strlen(TEP_PRINT_LATENCY)) == 0) { + data_latency_format(tep, s, type->format, record); + } else if (strncmp(arg, TEP_PRINT_COMM, strlen(TEP_PRINT_COMM)) == 0) { + pid = parse_common_pid(tep, record->data); + comm = find_cmdline(tep, pid); + trace_seq_printf(s, type->format, comm); + } else if (strncmp(arg, TEP_PRINT_INFO_RAW, strlen(TEP_PRINT_INFO_RAW)) == 0) { + print_event_info(s, type->format, true, event, record); + } else if (strncmp(arg, TEP_PRINT_INFO, strlen(TEP_PRINT_INFO)) == 0) { + print_event_info(s, type->format, false, event, record); + } else if (strncmp(arg, TEP_PRINT_NAME, strlen(TEP_PRINT_NAME)) == 0) { + trace_seq_printf(s, type->format, event->name); + } else { + trace_seq_printf(s, "[UNKNOWN TEP TYPE %s]", arg); + } - if (tep->latency_format) - trace_seq_printf(s, "%8.8s-%-5d %3d", comm, pid, record->cpu); - else - trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu); } -/** - * tep_print_event_time - Write the event timestamp - * @tep: a handle to the trace event parser context - * @s: the trace_seq to write to - * @event: the handle to the record's event - * @record: The record to get the event from - * @use_trace_clock: Set to parse according to the @tep->trace_clock - * - * Writes the timestamp of the record into @s. - */ -void tep_print_event_time(struct tep_handle *tep, struct trace_seq *s, - struct tep_event *event, - struct tep_record *record, - bool use_trace_clock) +static void print_int(struct tep_handle *tep, struct trace_seq *s, + struct tep_record *record, struct tep_event *event, + int arg, struct print_event_type *type) { - unsigned long secs; - unsigned long usecs; - unsigned long nsecs; - int p; - bool use_usec_format; + int param; - use_usec_format = is_timestamp_in_us(tep->trace_clock, use_trace_clock); - if (use_usec_format) { - secs = record->ts / NSEC_PER_SEC; - nsecs = record->ts - secs * NSEC_PER_SEC; + switch (arg) { + case TEP_PRINT_CPU: + param = record->cpu; + break; + case TEP_PRINT_PID: + param = parse_common_pid(tep, record->data); + break; + case TEP_PRINT_TIME: + return print_event_time(tep, s, type->format, event, record); + default: + return; } + trace_seq_printf(s, type->format, param); +} - if (tep->latency_format) { - tep_data_latency_format(tep, s, record); - } +static int tep_print_event_param_type(char *format, + struct print_event_type *type) +{ + char *str = format + 1; + int i = 1; - if (use_usec_format) { - if (tep->flags & TEP_NSEC_OUTPUT) { - usecs = nsecs; - p = 9; - } else { - usecs = (nsecs + 500) / NSEC_PER_USEC; - /* To avoid usecs larger than 1 sec */ - if (usecs >= USEC_PER_SEC) { - usecs -= USEC_PER_SEC; - secs++; - } - p = 6; + type->type = EVENT_TYPE_UNKNOWN; + while (*str) { + switch (*str) { + case 'd': + case 'u': + case 'i': + case 'x': + case 'X': + case 'o': + type->type = EVENT_TYPE_INT; + break; + case 's': + type->type = EVENT_TYPE_STRING; + break; } - - trace_seq_printf(s, " %5lu.%0*lu:", secs, p, usecs); - } else - trace_seq_printf(s, " %12llu:", record->ts); + str++; + i++; + if (type->type != EVENT_TYPE_UNKNOWN) + break; + } + memset(type->format, 0, 32); + memcpy(type->format, format, i < 32 ? i : 31); + return i; } /** - * tep_print_event_data - Write the event data section + * tep_print_event - Write various event information * @tep: a handle to the trace event parser context * @s: the trace_seq to write to - * @event: the handle to the record's event * @record: The record to get the event from - * - * Writes the parsing of the record's data to @s. + * @format: a printf format string. Supported event fileds: + * TEP_PRINT_PID, "%d" - event PID + * TEP_PRINT_CPU, "%d" - event CPU + * TEP_PRINT_COMM, "%s" - event command string + * TEP_PRINT_NAME, "%s" - event name + * TEP_PRINT_LATENCY, "%s" - event latency + * TEP_PRINT_TIME, %d - event time stamp. A divisor and precision + * can be specified as part of this format string: + * "%precision.divisord". Example: + * "%3.1000d" - divide the time by 1000 and print the first + * 3 digits before the dot. Thus, the time stamp + * "123456000" will be printed as "123.456" + * TEP_PRINT_INFO, "%s" - event information. If any width is specified in + * the format string, the event information will be printed + * in raw format. + * Writes the specified event information into @s. */ -void tep_print_event_data(struct tep_handle *tep, struct trace_seq *s, - struct tep_event *event, - struct tep_record *record) -{ - static const char *spaces = " "; /* 20 spaces */ - int len; - - trace_seq_printf(s, " %s: ", event->name); - - /* Space out the event names evenly. */ - len = strlen(event->name); - if (len < 20) - trace_seq_printf(s, "%.*s", 20 - len, spaces); - - tep_event_info(s, event, record); -} - void tep_print_event(struct tep_handle *tep, struct trace_seq *s, - struct tep_record *record, bool use_trace_clock) -{ + struct tep_record *record, const char *fmt, ...) +{ + struct print_event_type type; + char *format = strdup(fmt); + char *current = format; + char *str = format; + int offset; + va_list args; struct tep_event *event; - event = tep_find_event_by_record(tep, record); - if (!event) { - int i; - int type = trace_parse_common_type(tep, record->data); - - do_warning("ug! no event found for type %d", type); - trace_seq_printf(s, "[UNKNOWN TYPE %d]", type); - for (i = 0; i < record->size; i++) - trace_seq_printf(s, " %02x", - ((unsigned char *)record->data)[i]); + if (!format) return; - } - tep_print_event_task(tep, s, event, record); - tep_print_event_time(tep, s, event, record, use_trace_clock); - tep_print_event_data(tep, s, event, record); + event = tep_find_event_by_record(tep, record); + va_start(args, fmt); + while (*current) { + current = strchr(str, '%'); + if (!current) { + trace_seq_puts(s, str); + break; + } + memset(&type, 0, sizeof(type)); + offset = tep_print_event_param_type(current, &type); + *current = '\0'; + trace_seq_puts(s, str); + current += offset; + switch (type.type) { + case EVENT_TYPE_STRING: + print_string(tep, s, record, event, + va_arg(args, char*), &type); + break; + case EVENT_TYPE_INT: + print_int(tep, s, record, event, + va_arg(args, int), &type); + break; + case EVENT_TYPE_UNKNOWN: + default: + trace_seq_printf(s, "[UNKNOWN TYPE]"); + break; + } + str = current; + + } + va_end(args); + free(format); } static int events_id_cmp(const void *a, const void *b) diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index 642f68ab5fb2..cf7f302eb44a 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h @@ -442,18 +442,18 @@ int tep_register_print_string(struct tep_handle *tep, const char *fmt, unsigned long long addr); bool tep_is_pid_registered(struct tep_handle *tep, int pid); -void tep_print_event_task(struct tep_handle *tep, struct trace_seq *s, - struct tep_event *event, - struct tep_record *record); -void tep_print_event_time(struct tep_handle *tep, struct trace_seq *s, - struct tep_event *event, - struct tep_record *record, - bool use_trace_clock); -void tep_print_event_data(struct tep_handle *tep, struct trace_seq *s, - struct tep_event *event, - struct tep_record *record); +#define TEP_PRINT_INFO "INFO" +#define TEP_PRINT_INFO_RAW "INFO_RAW" +#define TEP_PRINT_COMM "COMM" +#define TEP_PRINT_LATENCY "LATENCY" +#define TEP_PRINT_NAME "NAME" +#define TEP_PRINT_PID 1U +#define TEP_PRINT_TIME 2U +#define TEP_PRINT_CPU 3U + void tep_print_event(struct tep_handle *tep, struct trace_seq *s, - struct tep_record *record, bool use_trace_clock); + struct tep_record *record, const char *fmt, ...) + __attribute__ ((format (printf, 4, 5))); int tep_parse_header_page(struct tep_handle *tep, char *buf, unsigned long size, int long_size); @@ -525,8 +525,6 @@ tep_find_event_by_name(struct tep_handle *tep, const char *sys, const char *name struct tep_event * tep_find_event_by_record(struct tep_handle *tep, struct tep_record *record); -void tep_data_latency_format(struct tep_handle *tep, - struct trace_seq *s, struct tep_record *record); int tep_data_type(struct tep_handle *tep, struct tep_record *rec); int tep_data_pid(struct tep_handle *tep, struct tep_record *rec); int tep_data_preempt_count(struct tep_handle *tep, struct tep_record *rec); @@ -541,8 +539,6 @@ void tep_print_field(struct trace_seq *s, void *data, struct tep_format_field *field); void tep_print_fields(struct trace_seq *s, void *data, int size __maybe_unused, struct tep_event *event); -void tep_event_info(struct trace_seq *s, struct tep_event *event, - struct tep_record *record); int tep_strerror(struct tep_handle *tep, enum tep_errno errnum, char *buf, size_t buflen); @@ -566,12 +562,9 @@ bool tep_is_file_bigendian(struct tep_handle *tep); void tep_set_file_bigendian(struct tep_handle *tep, enum tep_endian endian); bool tep_is_local_bigendian(struct tep_handle *tep); void tep_set_local_bigendian(struct tep_handle *tep, enum tep_endian endian); -bool tep_is_latency_format(struct tep_handle *tep); -void tep_set_latency_format(struct tep_handle *tep, int lat); int tep_get_header_page_size(struct tep_handle *tep); int tep_get_header_timestamp_size(struct tep_handle *tep); bool tep_is_old_format(struct tep_handle *tep); -void tep_set_print_raw(struct tep_handle *tep, int print_raw); void tep_set_test_filters(struct tep_handle *tep, int test_filters); struct tep_handle *tep_alloc(void); diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 7eec0da64c46..378b09c910a8 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -750,7 +750,8 @@ static int parse_gfp_flags(struct evsel *evsel, struct perf_sample *sample, } trace_seq_init(&seq); - tep_event_info(&seq, evsel->tp_format, &record); + tep_print_event(evsel->tp_format->tep, + &seq, &record, "%s", TEP_PRINT_INFO); str = strtok_r(seq.buffer, " ", &pos); while (str) { diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 035355a9945e..4650704540c9 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -709,7 +709,8 @@ static char *get_trace_output(struct hist_entry *he) tep_print_fields(&seq, he->raw_data, he->raw_size, evsel->tp_format); } else { - tep_event_info(&seq, evsel->tp_format, &rec); + tep_print_event(evsel->tp_format->tep, + &seq, &rec, "%s", TEP_PRINT_INFO); } /* * Trim the buffer, it starts at 4KB and we're not going to diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index 8e31a63045c3..5d6bfc70b210 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c @@ -109,7 +109,7 @@ void event_format__fprintf(struct tep_event *event, record.data = data; trace_seq_init(&s); - tep_event_info(&s, event, &record); + tep_print_event(event->tep, &s, &record, "%s", TEP_PRINT_INFO); trace_seq_do_fprintf(&s, fp); trace_seq_destroy(&s); } -- cgit v1.2.3-59-g8ed1b From 5d6552ab3b71fac48a9c7452c7014d37ca80b17f Mon Sep 17 00:00:00 2001 From: Tzvetomir Stoyanov Date: Mon, 5 Aug 2019 16:43:14 -0400 Subject: libtraceevent: Remove tep_register_trace_clock() The tep_register_trace_clock() API is used to instruct the traceevent library how to print the event time stamps. As event print interface if redesigned, this API is not needed any more. The new event print API is flexible and the user can specify how the time stamps are printed. Signed-off-by: Tzvetomir Stoyanov Cc: Andrew Morton Cc: Jiri Olsa Cc: Namhyung Kim Cc: Patrick McLean Cc: linux-trace-devel@vger.kernel.org Link: http://lore.kernel.org/linux-trace-devel/20190801074959.22023-3-tz.stoyanov@gmail.com Link: http://lore.kernel.org/lkml/20190805204355.195042846@goodmis.org Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse-local.h | 2 -- tools/lib/traceevent/event-parse.c | 11 ----------- tools/lib/traceevent/event-parse.h | 1 - 3 files changed, 14 deletions(-) (limited to 'tools') diff --git a/tools/lib/traceevent/event-parse-local.h b/tools/lib/traceevent/event-parse-local.h index 6e58ee1fe7c8..cee469803a34 100644 --- a/tools/lib/traceevent/event-parse-local.h +++ b/tools/lib/traceevent/event-parse-local.h @@ -81,8 +81,6 @@ struct tep_handle { /* cache */ struct tep_event *last_event; - - char *trace_clock; }; void tep_free_event(struct tep_event *event); diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index d1085aab9c43..bb22238debfe 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -393,16 +393,6 @@ int tep_override_comm(struct tep_handle *tep, const char *comm, int pid) return _tep_register_comm(tep, comm, pid, true); } -int tep_register_trace_clock(struct tep_handle *tep, const char *trace_clock) -{ - tep->trace_clock = strdup(trace_clock); - if (!tep->trace_clock) { - errno = ENOMEM; - return -1; - } - return 0; -} - struct func_map { unsigned long long addr; char *func; @@ -7057,7 +7047,6 @@ void tep_free(struct tep_handle *tep) free_handler(handle); } - free(tep->trace_clock); free(tep->events); free(tep->sort_events); free(tep->func_resolver); diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index cf7f302eb44a..d438ee44289f 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h @@ -435,7 +435,6 @@ int tep_set_function_resolver(struct tep_handle *tep, void tep_reset_function_resolver(struct tep_handle *tep); int tep_register_comm(struct tep_handle *tep, const char *comm, int pid); int tep_override_comm(struct tep_handle *tep, const char *comm, int pid); -int tep_register_trace_clock(struct tep_handle *tep, const char *trace_clock); int tep_register_function(struct tep_handle *tep, char *name, unsigned long long addr, char *mod); int tep_register_print_string(struct tep_handle *tep, const char *fmt, -- cgit v1.2.3-59-g8ed1b From e97fd1383cd77c467d2aed7fa4e596789df83977 Mon Sep 17 00:00:00 2001 From: Tzvetomir Stoyanov Date: Mon, 5 Aug 2019 16:43:15 -0400 Subject: libtraceevent: Change users plugin directory To be compliant with XDG user directory layout, the user's plugin directory is changed from ~/.traceevent/plugins to ~/.local/lib/traceevent/plugins/ Suggested-by: Patrick McLean Signed-off-by: Tzvetomir Stoyanov Cc: Andrew Morton Cc: Jiri Olsa Cc: Namhyung Kim Cc: Patrick McLean Cc: linux-trace-devel@vger.kernel.org Link: https://lore.kernel.org/linux-trace-devel/20190313144206.41e75cf8@patrickm/ Link: http://lore.kernel.org/linux-trace-devel/20190801074959.22023-4-tz.stoyanov@gmail.com Link: http://lore.kernel.org/lkml/20190805204355.344622683@goodmis.org Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/Makefile | 6 +++--- tools/lib/traceevent/event-plugin.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index 8352d53dcb5a..a39cdd0d890d 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile @@ -62,15 +62,15 @@ set_plugin_dir := 1 # Set plugin_dir to preffered global plugin location # If we install under $HOME directory we go under -# $(HOME)/.traceevent/plugins +# $(HOME)/.local/lib/traceevent/plugins # # We dont set PLUGIN_DIR in case we install under $HOME # directory, because by default the code looks under: -# $(HOME)/.traceevent/plugins by default. +# $(HOME)/.local/lib/traceevent/plugins by default. # ifeq ($(plugin_dir),) ifeq ($(prefix),$(HOME)) -override plugin_dir = $(HOME)/.traceevent/plugins +override plugin_dir = $(HOME)/.local/lib/traceevent/plugins set_plugin_dir := 0 else override plugin_dir = $(libdir)/traceevent/plugins diff --git a/tools/lib/traceevent/event-plugin.c b/tools/lib/traceevent/event-plugin.c index 8ca28de9337a..e1f7ddd5a6cf 100644 --- a/tools/lib/traceevent/event-plugin.c +++ b/tools/lib/traceevent/event-plugin.c @@ -18,7 +18,7 @@ #include "event-utils.h" #include "trace-seq.h" -#define LOCAL_PLUGIN_DIR ".traceevent/plugins" +#define LOCAL_PLUGIN_DIR ".local/lib/traceevent/plugins/" static struct registered_plugin_options { struct registered_plugin_options *next; -- cgit v1.2.3-59-g8ed1b From fac583fdb6741bf4850928b2a5bb8b0118b5879c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 30 Aug 2019 09:43:25 -0300 Subject: perf dso: Adopt DSO related macros from symbol.h Reducing the size of symbol.h by removing things that are better placed somewhere else. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-edenkmjt1oe5fks2s6umd30b@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 1 + tools/perf/util/build-id.c | 1 + tools/perf/util/dso.h | 3 +++ tools/perf/util/probe-file.c | 1 + tools/perf/util/symbol.c | 1 + tools/perf/util/symbol.h | 3 --- 6 files changed, 7 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 3bd1691f0be7..67a7513077d0 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -20,6 +20,7 @@ #include "color.h" #include "config.h" #include "cache.h" +#include "dso.h" #include "map.h" #include "symbol.h" #include "srcline.h" diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 4c96a33b09ff..e5fb77755d9e 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -13,6 +13,7 @@ #include #include #include +#include "dso.h" #include "build-id.h" #include "event.h" #include "namespaces.h" diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index 6e3f63781e51..ff0b81854628 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -16,6 +16,9 @@ struct machine; struct map; struct perf_env; +#define DSO__NAME_KALLSYMS "[kernel.kallsyms]" +#define DSO__NAME_KCORE "[kernel.kcore]" + enum dso_binary_type { DSO_BINARY_TYPE__KALLSYMS = 0, DSO_BINARY_TYPE__GUEST_KALLSYMS, diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index 5b4d49382932..10d2ab179c71 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -16,6 +16,7 @@ #include "strlist.h" #include "strfilter.h" #include "debug.h" +#include "dso.h" #include "cache.h" #include "color.h" #include "symbol.h" diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index c37cca690864..b11a69681662 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -18,6 +18,7 @@ #include "annotate.h" #include "build-id.h" #include "cap.h" +#include "dso.h" #include "util.h" #include "debug.h" #include "event.h" diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 183f630cb5f1..159c59652a5c 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -46,9 +46,6 @@ Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ #endif -#define DSO__NAME_KALLSYMS "[kernel.kallsyms]" -#define DSO__NAME_KCORE "[kernel.kcore]" - /** struct symbol - symtab entry * * @ignore - resolvable but tools ignore it (e.g. idle routines) -- cgit v1.2.3-59-g8ed1b From 9bea81b36a8d7d23c9bb7f4d63a9a842eec134a0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 30 Aug 2019 10:01:50 -0300 Subject: perf symbol: Move C++ demangle defines to the only file using it No need to have it generally available in such a critical header as symbol.h. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-es1ufxv7bihiumytn5dm3drn@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol-elf.c | 6 ++++++ tools/perf/util/symbol.h | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 7d504dc22108..6d22437e88ae 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -40,6 +40,12 @@ typedef Elf64_Nhdr GElf_Nhdr; +#ifndef DMGL_PARAMS +#define DMGL_NO_OPTS 0 /* For readability... */ +#define DMGL_PARAMS (1 << 0) /* Include function args */ +#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ +#endif + #ifdef HAVE_CPLUS_DEMANGLE_SUPPORT extern char *cplus_demangle(const char *, int); diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 159c59652a5c..bcc0d84a42b8 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -40,12 +40,6 @@ Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, GElf_Shdr *shp, const char *name, size_t *idx); #endif -#ifndef DMGL_PARAMS -#define DMGL_NO_OPTS 0 /* For readability... */ -#define DMGL_PARAMS (1 << 0) /* Include function args */ -#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ -#endif - /** struct symbol - symtab entry * * @ignore - resolvable but tools ignore it (e.g. idle routines) -- cgit v1.2.3-59-g8ed1b From c38fa94d188234f40fe3911b1a7650e056ef42ea Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 30 Aug 2019 10:19:19 -0300 Subject: perf symbols: Add missing linux/refcount.h to symbol.h We use refcount_t there, so we need that header or else it'll break when we remove dso.h, that is from where it is getting that definition now... Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-5albrk0uve6x9cf6x3ebwpae@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index bcc0d84a42b8..22660c7614a5 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -3,6 +3,7 @@ #define __PERF_SYMBOL 1 #include +#include #include #include #include -- cgit v1.2.3-59-g8ed1b From b1d1b094f7570a13dd7c9b995209baacc8aa6273 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 30 Aug 2019 10:26:37 -0300 Subject: perf symbols: Move symsrc prototypes to a separate header So that we can remove dso.h from symbol.h and reduce the header dependency tree. Fixup cases where struct dso guts are needed but were obtained via symbol.h, indirectly. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-ip683cegt306ncu3gsz7ii21@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/powerpc/util/sym-handling.c | 1 + tools/perf/builtin-probe.c | 1 + tools/perf/ui/browsers/map.c | 1 + tools/perf/ui/gtk/annotate.c | 1 + tools/perf/util/symbol-elf.c | 1 + tools/perf/util/symbol-minimal.c | 2 ++ tools/perf/util/symbol.c | 1 + tools/perf/util/symbol.h | 36 ++-------------------- tools/perf/util/symbol_fprintf.c | 1 + tools/perf/util/symsrc.h | 46 +++++++++++++++++++++++++++++ 10 files changed, 58 insertions(+), 33 deletions(-) create mode 100644 tools/perf/util/symsrc.h (limited to 'tools') diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c index b0a67eaf2ce8..8a4b717e0a53 100644 --- a/tools/perf/arch/powerpc/util/sym-handling.c +++ b/tools/perf/arch/powerpc/util/sym-handling.c @@ -5,6 +5,7 @@ */ #include "debug.h" +#include "dso.h" #include "symbol.h" #include "map.h" #include "probe-event.h" diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 8950c05ef8fd..6dce1724a378 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -18,6 +18,7 @@ #include "builtin.h" #include "namespaces.h" +#include "util/build-id.h" #include "util/strlist.h" #include "util/strfilter.h" #include "util/symbol.h" diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c index 4c545b92e20d..893b065971f6 100644 --- a/tools/perf/ui/browsers/map.c +++ b/tools/perf/ui/browsers/map.c @@ -8,6 +8,7 @@ #include "../../util/util.h" #include "../../util/debug.h" #include "../../util/map.h" +#include "../../util/dso.h" #include "../../util/symbol.h" #include "../browser.h" #include "../helpline.h" diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c index d7f984436dec..8e744af24f7c 100644 --- a/tools/perf/ui/gtk/annotate.c +++ b/tools/perf/ui/gtk/annotate.c @@ -5,6 +5,7 @@ #include "util/annotate.h" #include "util/evsel.h" #include "util/map.h" +#include "util/dso.h" #include "util/symbol.h" #include "ui/helpline.h" #include diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 6d22437e88ae..9428639872a6 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -10,6 +10,7 @@ #include "map.h" #include "map_groups.h" #include "symbol.h" +#include "symsrc.h" #include "demangle-java.h" #include "demangle-rust.h" #include "machine.h" diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c index 3bc8b7e3300e..7e2813ec9498 100644 --- a/tools/perf/util/symbol-minimal.c +++ b/tools/perf/util/symbol-minimal.c @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 +#include "dso.h" #include "symbol.h" +#include "symsrc.h" #include "util.h" #include diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index b11a69681662..e5ffe61ad66b 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -25,6 +25,7 @@ #include "machine.h" #include "map.h" #include "symbol.h" +#include "symsrc.h" #include "strlist.h" #include "intlist.h" #include "namespaces.h" diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 22660c7614a5..5a58407c2945 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -20,8 +20,7 @@ #endif #include -#include "dso.h" - +struct dso; struct map; struct map_groups; struct option; @@ -148,37 +147,6 @@ struct addr_location { s32 socket; }; -struct symsrc { - char *name; - int fd; - enum dso_binary_type type; - -#ifdef HAVE_LIBELF_SUPPORT - Elf *elf; - GElf_Ehdr ehdr; - - Elf_Scn *opdsec; - size_t opdidx; - GElf_Shdr opdshdr; - - Elf_Scn *symtab; - GElf_Shdr symshdr; - - Elf_Scn *dynsym; - size_t dynsym_idx; - GElf_Shdr dynshdr; - - bool adjust_symbols; - bool is_64_bit; -#endif -}; - -void symsrc__destroy(struct symsrc *ss); -int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name, - enum dso_binary_type type); -bool symsrc__has_symtab(struct symsrc *ss); -bool symsrc__possibly_runtime(struct symsrc *ss); - int dso__load(struct dso *dso, struct map *map); int dso__load_vmlinux(struct dso *dso, struct map *map, const char *vmlinux, bool vmlinux_allocated); @@ -232,6 +200,8 @@ bool symbol__restricted_filename(const char *filename, int symbol__config_symfs(const struct option *opt __maybe_unused, const char *dir, int unset __maybe_unused); +struct symsrc; + int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, struct symsrc *runtime_ss, int kmodule); int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss); diff --git a/tools/perf/util/symbol_fprintf.c b/tools/perf/util/symbol_fprintf.c index 02e89b02c2ce..35c936ce33ef 100644 --- a/tools/perf/util/symbol_fprintf.c +++ b/tools/perf/util/symbol_fprintf.c @@ -3,6 +3,7 @@ #include #include +#include "dso.h" #include "map.h" #include "symbol.h" diff --git a/tools/perf/util/symsrc.h b/tools/perf/util/symsrc.h new file mode 100644 index 000000000000..2665b4bde751 --- /dev/null +++ b/tools/perf/util/symsrc.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PERF_SYMSRC_ +#define __PERF_SYMSRC_ 1 + +#include +#include +#include "dso.h" + +#ifdef HAVE_LIBELF_SUPPORT +#include +#include +#endif +#include + +struct symsrc { + char *name; + int fd; + enum dso_binary_type type; + +#ifdef HAVE_LIBELF_SUPPORT + Elf *elf; + GElf_Ehdr ehdr; + + Elf_Scn *opdsec; + size_t opdidx; + GElf_Shdr opdshdr; + + Elf_Scn *symtab; + GElf_Shdr symshdr; + + Elf_Scn *dynsym; + size_t dynsym_idx; + GElf_Shdr dynshdr; + + bool adjust_symbols; + bool is_64_bit; +#endif +}; + +int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name, enum dso_binary_type type); +void symsrc__destroy(struct symsrc *ss); + +bool symsrc__has_symtab(struct symsrc *ss); +bool symsrc__possibly_runtime(struct symsrc *ss); + +#endif /* __PERF_SYMSRC_ */ -- cgit v1.2.3-59-g8ed1b From 4a3cec84949d14dc3ef7fb8a51b8949af93cac13 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 30 Aug 2019 11:11:01 -0300 Subject: perf dsos: Move the dsos struct and its methods to separate source files So that we can reduce the header dependency tree further, in the process noticed that lots of places were getting even things like build-id routines and 'struct perf_tool' definition indirectly, so fix all those too. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-ti0btma9ow5ndrytyoqdk62j@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 1 + tools/perf/builtin-buildid-cache.c | 1 + tools/perf/builtin-buildid-list.c | 1 + tools/perf/builtin-inject.c | 1 + tools/perf/builtin-kallsyms.c | 1 + tools/perf/builtin-kmem.c | 1 + tools/perf/builtin-kvm.c | 1 + tools/perf/builtin-mem.c | 1 + tools/perf/builtin-report.c | 1 + tools/perf/builtin-script.c | 1 + tools/perf/builtin-top.c | 1 + tools/perf/builtin-trace.c | 2 + tools/perf/tests/code-reading.c | 1 + tools/perf/tests/dso-data.c | 1 + tools/perf/tests/dwarf-unwind.c | 1 + tools/perf/tests/event_update.c | 1 + tools/perf/tests/hists_common.c | 1 + tools/perf/tests/hists_cumulate.c | 1 + tools/perf/tests/hists_output.c | 1 + tools/perf/tests/vmlinux-kallsyms.c | 1 + tools/perf/ui/browsers/annotate.c | 1 + tools/perf/ui/browsers/hists.c | 1 + tools/perf/util/Build | 1 + tools/perf/util/bpf-event.c | 1 + tools/perf/util/callchain.c | 1 + tools/perf/util/cs-etm.c | 2 + tools/perf/util/db-export.c | 1 + tools/perf/util/dso.c | 235 +-------------------- tools/perf/util/dso.h | 25 +-- tools/perf/util/dsos.c | 232 ++++++++++++++++++++ tools/perf/util/dsos.h | 44 ++++ tools/perf/util/event.c | 2 + tools/perf/util/header.c | 1 + tools/perf/util/hist.c | 1 + tools/perf/util/intel-bts.c | 1 + tools/perf/util/jitdump.c | 1 + tools/perf/util/machine.c | 1 + tools/perf/util/machine.h | 3 +- tools/perf/util/map.c | 1 + tools/perf/util/parse-events.c | 1 + tools/perf/util/probe-event.c | 2 + tools/perf/util/s390-cpumsf.c | 1 + .../perf/util/scripting-engines/trace-event-perl.c | 1 + .../util/scripting-engines/trace-event-python.c | 2 + tools/perf/util/sort.c | 1 + tools/perf/util/thread.c | 1 + tools/perf/util/unwind-libdw.c | 1 + tools/perf/util/unwind-libunwind.c | 1 + tools/perf/util/vdso.c | 1 + 49 files changed, 331 insertions(+), 257 deletions(-) create mode 100644 tools/perf/util/dsos.c create mode 100644 tools/perf/util/dsos.h (limited to 'tools') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 9bb637165bf9..738471a0a549 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -27,6 +27,7 @@ #include "util/thread.h" #include "util/sort.h" #include "util/hist.h" +#include "util/dso.h" #include "util/map.h" #include "util/session.h" #include "util/tool.h" diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index 9e756004ef28..b035911969b8 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -22,6 +22,7 @@ #include "util/strlist.h" #include "util/build-id.h" #include "util/session.h" +#include "util/dso.h" #include "util/symbol.h" #include "util/time-utils.h" #include "util/util.h" diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index 72bdc0eba990..38b2ec61c021 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -12,6 +12,7 @@ #include "util/build-id.h" #include "util/cache.h" #include "util/debug.h" +#include "util/dso.h" #include #include "util/session.h" #include "util/symbol.h" diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index ae46de46e826..c14f40b858bc 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -9,6 +9,7 @@ #include "builtin.h" #include "util/color.h" +#include "util/dso.h" #include "util/evlist.h" #include "util/evsel.h" #include "util/map.h" diff --git a/tools/perf/builtin-kallsyms.c b/tools/perf/builtin-kallsyms.c index c1a44671b0b5..c08ee81529e8 100644 --- a/tools/perf/builtin-kallsyms.c +++ b/tools/perf/builtin-kallsyms.c @@ -11,6 +11,7 @@ #include #include #include "debug.h" +#include "dso.h" #include "machine.h" #include "map.h" #include "symbol.h" diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 378b09c910a8..b5682beaad72 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -2,6 +2,7 @@ #include "builtin.h" #include "perf.h" +#include "util/dso.h" #include "util/evlist.h" #include "util/evsel.h" #include "util/config.h" diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 69d16ac852c3..474c4799d29d 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -2,6 +2,7 @@ #include "builtin.h" #include "perf.h" +#include "util/build-id.h" #include "util/evsel.h" #include "util/evlist.h" #include "util/term.h" diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 9e60eda9297d..c5f3b9e9509d 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -13,6 +13,7 @@ #include "util/data.h" #include "util/mem-events.h" #include "util/debug.h" +#include "util/dso.h" #include "util/map.h" #include "util/symbol.h" diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 94e7e354cb16..ba419ee40283 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -12,6 +12,7 @@ #include "util/annotate.h" #include "util/color.h" +#include "util/dso.h" #include #include #include diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index f3b31c6ed15f..1ff04b00a561 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -4,6 +4,7 @@ #include "util/cache.h" #include "util/counts.h" #include "util/debug.h" +#include "util/dso.h" #include #include "util/header.h" #include diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 5538b5886e35..0b7b12cfdd63 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -24,6 +24,7 @@ #include "util/bpf-event.h" #include "util/config.h" #include "util/color.h" +#include "util/dso.h" #include "util/evlist.h" #include "util/evsel.h" #include "util/event.h" diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index b1ec8ff52740..0f633f0d6be8 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -25,6 +25,7 @@ #include "util/color.h" #include "util/config.h" #include "util/debug.h" +#include "util/dso.h" #include "util/env.h" #include "util/event.h" #include "util/evlist.h" @@ -42,6 +43,7 @@ #include "util/intlist.h" #include "util/thread_map.h" #include "util/stat.h" +#include "util/tool.h" #include "util/util.h" #include "trace/beauty/beauty.h" #include "trace-event.h" diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index c4b73bb4b113..7b2b89f4b716 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -12,6 +12,7 @@ #include #include "debug.h" +#include "dso.h" #include "parse-events.h" #include "evlist.h" #include "evsel.h" diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index 946ab4b63acd..a4874d4ce7ef 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -9,6 +9,7 @@ #include #include #include +#include "dso.h" #include "util.h" #include "machine.h" #include "symbol.h" diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c index f33709a79335..4125255ff637 100644 --- a/tools/perf/tests/dwarf-unwind.c +++ b/tools/perf/tests/dwarf-unwind.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "tests.h" #include "debug.h" diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index 1411155597b8..4b68ec3a13fc 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -4,6 +4,7 @@ #include "evlist.h" #include "evsel.h" #include "machine.h" +#include "tool.h" #include "tests.h" #include "debug.h" diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c index 96ad95d3f338..cdde41c03056 100644 --- a/tools/perf/tests/hists_common.c +++ b/tools/perf/tests/hists_common.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include "util/debug.h" +#include "util/dso.h" #include "util/map.h" #include "util/symbol.h" #include "util/sort.h" diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index 93af420ad2e4..fa55b7bad3af 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "util/debug.h" +#include "util/dso.h" #include "util/event.h" #include "util/map.h" #include "util/symbol.h" diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index 07f4ca0704fb..3f6dfa212260 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "util/debug.h" +#include "util/dso.h" #include "util/event.h" #include "util/map.h" #include "util/symbol.h" diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index 5e8834fc7dec..01f434c067c6 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -4,6 +4,7 @@ #include #include #include +#include "dso.h" #include "map.h" #include "symbol.h" #include "util.h" diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 715601f5fce3..ac74ed2c23a0 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -5,6 +5,7 @@ #include "../util.h" #include "../../util/annotate.h" #include "../../util/debug.h" +#include "../../util/dso.h" #include "../../util/hist.h" #include "../../util/sort.h" #include "../../util/map.h" diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index a14dda74f43a..cf8857456056 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -12,6 +12,7 @@ #include #include "../../util/debug.h" +#include "../../util/dso.h" #include "../../util/callchain.h" #include "../../util/evsel.h" #include "../../util/evlist.h" diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 2e3856471e61..0b4d8e0d474c 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -36,6 +36,7 @@ perf-y += strfilter.o perf-y += top.o perf-y += usage.o perf-y += dso.o +perf-y += dsos.o perf-y += symbol.o perf-y += symbol_fprintf.o perf-y += color.o diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 2d6d500c9af7..7a3d4b125323 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -8,6 +8,7 @@ #include #include "bpf-event.h" #include "debug.h" +#include "dso.h" #include "symbol.h" #include "machine.h" #include "env.h" diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 76bf05b26d3b..c14646c1f2eb 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -22,6 +22,7 @@ #include "asm/bug.h" #include "debug.h" +#include "dso.h" #include "hist.h" #include "sort.h" #include "machine.h" diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index d6de3834865e..3ed1d3bb7089 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -21,12 +21,14 @@ #include "cs-etm.h" #include "cs-etm-decoder/cs-etm-decoder.h" #include "debug.h" +#include "dso.h" #include "evlist.h" #include "intlist.h" #include "machine.h" #include "map.h" #include "perf.h" #include "symbol.h" +#include "tool.h" #include "thread.h" #include "thread_map.h" #include "thread-stack.h" diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c index 701e9f814313..752227b265e7 100644 --- a/tools/perf/util/db-export.c +++ b/tools/perf/util/db-export.c @@ -7,6 +7,7 @@ #include #include +#include "dso.h" #include "evsel.h" #include "machine.h" #include "thread.h" diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index ebc9d46c15a7..ece97209792d 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include "bpf-event.h" #include "compress.h" @@ -20,6 +19,7 @@ #include "symbol.h" #include "srcline.h" #include "dso.h" +#include "dsos.h" #include "machine.h" #include "auxtrace.h" #include "util.h" /* O_CLOEXEC for older systems */ @@ -1094,66 +1094,6 @@ struct dso *machine__findnew_kernel(struct machine *machine, const char *name, return dso; } -/* - * Find a matching entry and/or link current entry to RB tree. - * Either one of the dso or name parameter must be non-NULL or the - * function will not work. - */ -static struct dso *__dso__findlink_by_longname(struct rb_root *root, - struct dso *dso, const char *name) -{ - struct rb_node **p = &root->rb_node; - struct rb_node *parent = NULL; - - if (!name) - name = dso->long_name; - /* - * Find node with the matching name - */ - while (*p) { - struct dso *this = rb_entry(*p, struct dso, rb_node); - int rc = strcmp(name, this->long_name); - - parent = *p; - if (rc == 0) { - /* - * In case the new DSO is a duplicate of an existing - * one, print a one-time warning & put the new entry - * at the end of the list of duplicates. - */ - if (!dso || (dso == this)) - return this; /* Find matching dso */ - /* - * The core kernel DSOs may have duplicated long name. - * In this case, the short name should be different. - * Comparing the short names to differentiate the DSOs. - */ - rc = strcmp(dso->short_name, this->short_name); - if (rc == 0) { - pr_err("Duplicated dso name: %s\n", name); - return NULL; - } - } - if (rc < 0) - p = &parent->rb_left; - else - p = &parent->rb_right; - } - if (dso) { - /* Add new node and rebalance tree */ - rb_link_node(&dso->rb_node, parent, p); - rb_insert_color(&dso->rb_node, root); - dso->root = root; - } - return NULL; -} - -static inline struct dso *__dso__find_by_longname(struct rb_root *root, - const char *name) -{ - return __dso__findlink_by_longname(root, NULL, name); -} - void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated) { struct rb_root *root = dso->root; @@ -1167,7 +1107,7 @@ void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated) if (root) { rb_erase(&dso->rb_node, root); /* - * __dso__findlink_by_longname() isn't guaranteed to add it + * __dsos__findnew_link_by_longname() isn't guaranteed to add it * back, so a clean removal is required here. */ RB_CLEAR_NODE(&dso->rb_node); @@ -1179,7 +1119,7 @@ void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated) dso->long_name_allocated = name_allocated; if (root) - __dso__findlink_by_longname(root, dso, NULL); + __dsos__findnew_link_by_longname(root, dso, NULL); } void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated) @@ -1195,38 +1135,6 @@ void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated) dso->short_name_allocated = name_allocated; } -static void dso__set_basename(struct dso *dso) -{ - char *base, *lname; - int tid; - - if (sscanf(dso->long_name, "/tmp/perf-%d.map", &tid) == 1) { - if (asprintf(&base, "[JIT] tid %d", tid) < 0) - return; - } else { - /* - * basename() may modify path buffer, so we must pass - * a copy. - */ - lname = strdup(dso->long_name); - if (!lname) - return; - - /* - * basename() may return a pointer to internal - * storage which is reused in subsequent calls - * so copy the result. - */ - base = strdup(basename(lname)); - - free(lname); - - if (!base) - return; - } - dso__set_short_name(dso, base, true); -} - int dso__name_len(const struct dso *dso) { if (!dso) @@ -1377,143 +1285,6 @@ int dso__kernel_module_get_build_id(struct dso *dso, return 0; } -bool __dsos__read_build_ids(struct list_head *head, bool with_hits) -{ - bool have_build_id = false; - struct dso *pos; - struct nscookie nsc; - - list_for_each_entry(pos, head, node) { - if (with_hits && !pos->hit && !dso__is_vdso(pos)) - continue; - if (pos->has_build_id) { - have_build_id = true; - continue; - } - nsinfo__mountns_enter(pos->nsinfo, &nsc); - if (filename__read_build_id(pos->long_name, pos->build_id, - sizeof(pos->build_id)) > 0) { - have_build_id = true; - pos->has_build_id = true; - } - nsinfo__mountns_exit(&nsc); - } - - return have_build_id; -} - -void __dsos__add(struct dsos *dsos, struct dso *dso) -{ - list_add_tail(&dso->node, &dsos->head); - __dso__findlink_by_longname(&dsos->root, dso, NULL); - /* - * It is now in the linked list, grab a reference, then garbage collect - * this when needing memory, by looking at LRU dso instances in the - * list with atomic_read(&dso->refcnt) == 1, i.e. no references - * anywhere besides the one for the list, do, under a lock for the - * list: remove it from the list, then a dso__put(), that probably will - * be the last and will then call dso__delete(), end of life. - * - * That, or at the end of the 'struct machine' lifetime, when all - * 'struct dso' instances will be removed from the list, in - * dsos__exit(), if they have no other reference from some other data - * structure. - * - * E.g.: after processing a 'perf.data' file and storing references - * to objects instantiated while processing events, we will have - * references to the 'thread', 'map', 'dso' structs all from 'struct - * hist_entry' instances, but we may not need anything not referenced, - * so we might as well call machines__exit()/machines__delete() and - * garbage collect it. - */ - dso__get(dso); -} - -void dsos__add(struct dsos *dsos, struct dso *dso) -{ - down_write(&dsos->lock); - __dsos__add(dsos, dso); - up_write(&dsos->lock); -} - -struct dso *__dsos__find(struct dsos *dsos, const char *name, bool cmp_short) -{ - struct dso *pos; - - if (cmp_short) { - list_for_each_entry(pos, &dsos->head, node) - if (strcmp(pos->short_name, name) == 0) - return pos; - return NULL; - } - return __dso__find_by_longname(&dsos->root, name); -} - -struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short) -{ - struct dso *dso; - down_read(&dsos->lock); - dso = __dsos__find(dsos, name, cmp_short); - up_read(&dsos->lock); - return dso; -} - -struct dso *__dsos__addnew(struct dsos *dsos, const char *name) -{ - struct dso *dso = dso__new(name); - - if (dso != NULL) { - __dsos__add(dsos, dso); - dso__set_basename(dso); - /* Put dso here because __dsos_add already got it */ - dso__put(dso); - } - return dso; -} - -struct dso *__dsos__findnew(struct dsos *dsos, const char *name) -{ - struct dso *dso = __dsos__find(dsos, name, false); - - return dso ? dso : __dsos__addnew(dsos, name); -} - -struct dso *dsos__findnew(struct dsos *dsos, const char *name) -{ - struct dso *dso; - down_write(&dsos->lock); - dso = dso__get(__dsos__findnew(dsos, name)); - up_write(&dsos->lock); - return dso; -} - -size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, - bool (skip)(struct dso *dso, int parm), int parm) -{ - struct dso *pos; - size_t ret = 0; - - list_for_each_entry(pos, head, node) { - if (skip && skip(pos, parm)) - continue; - ret += dso__fprintf_buildid(pos, fp); - ret += fprintf(fp, " %s\n", pos->long_name); - } - return ret; -} - -size_t __dsos__fprintf(struct list_head *head, FILE *fp) -{ - struct dso *pos; - size_t ret = 0; - - list_for_each_entry(pos, head, node) { - ret += dso__fprintf(pos, fp); - } - - return ret; -} - size_t dso__fprintf_buildid(struct dso *dso, FILE *fp) { char sbuild_id[SBUILD_ID_SIZE]; diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index ff0b81854628..e4dddb76770d 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -2,13 +2,13 @@ #ifndef __PERF_DSO #define __PERF_DSO +#include #include #include #include #include #include #include -#include "rwsem.h" #include #include "build-id.h" @@ -129,16 +129,6 @@ struct dso_cache { char data[0]; }; -/* - * DSOs are put into both a list for fast iteration and rbtree for fast - * long name lookup. - */ -struct dsos { - struct list_head head; - struct rb_root root; /* rbtree root sorted by long name */ - struct rw_semaphore lock; -}; - struct auxtrace_cache; struct dso { @@ -347,21 +337,8 @@ struct map *dso__new_map(const char *name); struct dso *machine__findnew_kernel(struct machine *machine, const char *name, const char *short_name, int dso_type); -void __dsos__add(struct dsos *dsos, struct dso *dso); -void dsos__add(struct dsos *dsos, struct dso *dso); -struct dso *__dsos__addnew(struct dsos *dsos, const char *name); -struct dso *__dsos__find(struct dsos *dsos, const char *name, bool cmp_short); -struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short); -struct dso *__dsos__findnew(struct dsos *dsos, const char *name); -struct dso *dsos__findnew(struct dsos *dsos, const char *name); -bool __dsos__read_build_ids(struct list_head *head, bool with_hits); - void dso__reset_find_symbol_cache(struct dso *dso); -size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, - bool (skip)(struct dso *dso, int parm), int parm); -size_t __dsos__fprintf(struct list_head *head, FILE *fp); - size_t dso__fprintf_buildid(struct dso *dso, FILE *fp); size_t dso__fprintf_symbols_by_name(struct dso *dso, FILE *fp); size_t dso__fprintf(struct dso *dso, FILE *fp); diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c new file mode 100644 index 000000000000..3ea80d203587 --- /dev/null +++ b/tools/perf/util/dsos.c @@ -0,0 +1,232 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "debug.h" +#include "dsos.h" +#include "dso.h" +#include "vdso.h" +#include "namespaces.h" +#include +#include +#include +#include // filename__read_build_id + +bool __dsos__read_build_ids(struct list_head *head, bool with_hits) +{ + bool have_build_id = false; + struct dso *pos; + struct nscookie nsc; + + list_for_each_entry(pos, head, node) { + if (with_hits && !pos->hit && !dso__is_vdso(pos)) + continue; + if (pos->has_build_id) { + have_build_id = true; + continue; + } + nsinfo__mountns_enter(pos->nsinfo, &nsc); + if (filename__read_build_id(pos->long_name, pos->build_id, + sizeof(pos->build_id)) > 0) { + have_build_id = true; + pos->has_build_id = true; + } + nsinfo__mountns_exit(&nsc); + } + + return have_build_id; +} + +/* + * Find a matching entry and/or link current entry to RB tree. + * Either one of the dso or name parameter must be non-NULL or the + * function will not work. + */ +struct dso *__dsos__findnew_link_by_longname(struct rb_root *root, struct dso *dso, const char *name) +{ + struct rb_node **p = &root->rb_node; + struct rb_node *parent = NULL; + + if (!name) + name = dso->long_name; + /* + * Find node with the matching name + */ + while (*p) { + struct dso *this = rb_entry(*p, struct dso, rb_node); + int rc = strcmp(name, this->long_name); + + parent = *p; + if (rc == 0) { + /* + * In case the new DSO is a duplicate of an existing + * one, print a one-time warning & put the new entry + * at the end of the list of duplicates. + */ + if (!dso || (dso == this)) + return this; /* Find matching dso */ + /* + * The core kernel DSOs may have duplicated long name. + * In this case, the short name should be different. + * Comparing the short names to differentiate the DSOs. + */ + rc = strcmp(dso->short_name, this->short_name); + if (rc == 0) { + pr_err("Duplicated dso name: %s\n", name); + return NULL; + } + } + if (rc < 0) + p = &parent->rb_left; + else + p = &parent->rb_right; + } + if (dso) { + /* Add new node and rebalance tree */ + rb_link_node(&dso->rb_node, parent, p); + rb_insert_color(&dso->rb_node, root); + dso->root = root; + } + return NULL; +} + +void __dsos__add(struct dsos *dsos, struct dso *dso) +{ + list_add_tail(&dso->node, &dsos->head); + __dsos__findnew_link_by_longname(&dsos->root, dso, NULL); + /* + * It is now in the linked list, grab a reference, then garbage collect + * this when needing memory, by looking at LRU dso instances in the + * list with atomic_read(&dso->refcnt) == 1, i.e. no references + * anywhere besides the one for the list, do, under a lock for the + * list: remove it from the list, then a dso__put(), that probably will + * be the last and will then call dso__delete(), end of life. + * + * That, or at the end of the 'struct machine' lifetime, when all + * 'struct dso' instances will be removed from the list, in + * dsos__exit(), if they have no other reference from some other data + * structure. + * + * E.g.: after processing a 'perf.data' file and storing references + * to objects instantiated while processing events, we will have + * references to the 'thread', 'map', 'dso' structs all from 'struct + * hist_entry' instances, but we may not need anything not referenced, + * so we might as well call machines__exit()/machines__delete() and + * garbage collect it. + */ + dso__get(dso); +} + +void dsos__add(struct dsos *dsos, struct dso *dso) +{ + down_write(&dsos->lock); + __dsos__add(dsos, dso); + up_write(&dsos->lock); +} + +struct dso *__dsos__find(struct dsos *dsos, const char *name, bool cmp_short) +{ + struct dso *pos; + + if (cmp_short) { + list_for_each_entry(pos, &dsos->head, node) + if (strcmp(pos->short_name, name) == 0) + return pos; + return NULL; + } + return __dsos__findnew_by_longname(&dsos->root, name); +} + +struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short) +{ + struct dso *dso; + down_read(&dsos->lock); + dso = __dsos__find(dsos, name, cmp_short); + up_read(&dsos->lock); + return dso; +} + +static void dso__set_basename(struct dso *dso) +{ + char *base, *lname; + int tid; + + if (sscanf(dso->long_name, "/tmp/perf-%d.map", &tid) == 1) { + if (asprintf(&base, "[JIT] tid %d", tid) < 0) + return; + } else { + /* + * basename() may modify path buffer, so we must pass + * a copy. + */ + lname = strdup(dso->long_name); + if (!lname) + return; + + /* + * basename() may return a pointer to internal + * storage which is reused in subsequent calls + * so copy the result. + */ + base = strdup(basename(lname)); + + free(lname); + + if (!base) + return; + } + dso__set_short_name(dso, base, true); +} + +struct dso *__dsos__addnew(struct dsos *dsos, const char *name) +{ + struct dso *dso = dso__new(name); + + if (dso != NULL) { + __dsos__add(dsos, dso); + dso__set_basename(dso); + /* Put dso here because __dsos_add already got it */ + dso__put(dso); + } + return dso; +} + +struct dso *__dsos__findnew(struct dsos *dsos, const char *name) +{ + struct dso *dso = __dsos__find(dsos, name, false); + + return dso ? dso : __dsos__addnew(dsos, name); +} + +struct dso *dsos__findnew(struct dsos *dsos, const char *name) +{ + struct dso *dso; + down_write(&dsos->lock); + dso = dso__get(__dsos__findnew(dsos, name)); + up_write(&dsos->lock); + return dso; +} + +size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, + bool (skip)(struct dso *dso, int parm), int parm) +{ + struct dso *pos; + size_t ret = 0; + + list_for_each_entry(pos, head, node) { + if (skip && skip(pos, parm)) + continue; + ret += dso__fprintf_buildid(pos, fp); + ret += fprintf(fp, " %s\n", pos->long_name); + } + return ret; +} + +size_t __dsos__fprintf(struct list_head *head, FILE *fp) +{ + struct dso *pos; + size_t ret = 0; + + list_for_each_entry(pos, head, node) { + ret += dso__fprintf(pos, fp); + } + + return ret; +} diff --git a/tools/perf/util/dsos.h b/tools/perf/util/dsos.h new file mode 100644 index 000000000000..32f1fbee0feb --- /dev/null +++ b/tools/perf/util/dsos.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PERF_DSOS +#define __PERF_DSOS + +#include +#include +#include +#include +#include "rwsem.h" + +struct dso; + +/* + * DSOs are put into both a list for fast iteration and rbtree for fast + * long name lookup. + */ +struct dsos { + struct list_head head; + struct rb_root root; /* rbtree root sorted by long name */ + struct rw_semaphore lock; +}; + +void __dsos__add(struct dsos *dsos, struct dso *dso); +void dsos__add(struct dsos *dsos, struct dso *dso); +struct dso *__dsos__addnew(struct dsos *dsos, const char *name); +struct dso *__dsos__find(struct dsos *dsos, const char *name, bool cmp_short); +struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short); +struct dso *__dsos__findnew(struct dsos *dsos, const char *name); +struct dso *dsos__findnew(struct dsos *dsos, const char *name); + +struct dso *__dsos__findnew_link_by_longname(struct rb_root *root, struct dso *dso, const char *name); + +static inline struct dso *__dsos__findnew_by_longname(struct rb_root *root, const char *name) +{ + return __dsos__findnew_link_by_longname(root, NULL, name); +} + +bool __dsos__read_build_ids(struct list_head *head, bool with_hits); + +size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, + bool (skip)(struct dso *dso, int parm), int parm); +size_t __dsos__fprintf(struct list_head *head, FILE *fp); + +#endif /* __PERF_DSOS */ diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 54169ad335c7..f4afbb858ebb 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -11,6 +11,7 @@ #include #include #include +#include "dso.h" #include "event.h" #include "debug.h" #include "hist.h" @@ -29,6 +30,7 @@ #include "stat.h" #include "session.h" #include "bpf-event.h" +#include "tool.h" #include "../perf.h" #define DEFAULT_PROC_MAP_PARSE_TIMEOUT 500 diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 20fb06162fd4..b0c34dda30a0 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -22,6 +22,7 @@ #include #include +#include "dso.h" #include "evlist.h" #include "evsel.h" #include "header.h" diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 02ea2ee62814..b526ef3ede98 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "callchain.h" #include "debug.h" +#include "dso.h" #include "build-id.h" #include "hist.h" #include "map.h" diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index 99dddb63dac1..a30427aa1de0 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c @@ -22,6 +22,7 @@ #include "map.h" #include "symbol.h" #include "session.h" +#include "tool.h" #include "thread.h" #include "thread-stack.h" #include "debug.h" diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c index bbeac4f66402..b80f29bfc7bb 100644 --- a/tools/perf/util/jitdump.c +++ b/tools/perf/util/jitdump.c @@ -14,6 +14,7 @@ #include #include +#include "build-id.h" #include "util.h" #include "event.h" #include "debug.h" diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 6e9afe4e55dd..003025465198 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -5,6 +5,7 @@ #include #include "callchain.h" #include "debug.h" +#include "dso.h" #include "event.h" #include "evsel.h" #include "hist.h" diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 7d69119d0b5d..ffd391a925a6 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -5,12 +5,13 @@ #include #include #include "map_groups.h" -#include "dso.h" +#include "dsos.h" #include "event.h" #include "rwsem.h" struct addr_location; struct branch_stack; +struct dso; struct evsel; struct perf_sample; struct symbol; diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index c75b20b93820..623a63cd1eec 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -8,6 +8,7 @@ #include #include #include /* To get things like MAP_HUGETLB even on older libc headers */ +#include "dso.h" #include "map.h" #include "thread.h" #include "vdso.h" diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 5f1ba6820cdd..523af1bd82e6 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -10,6 +10,7 @@ #include #include #include "term.h" +#include "build-id.h" #include "evlist.h" #include "evsel.h" #include diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 8394d48f8b32..5d12a78c8ac8 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -19,11 +19,13 @@ #include #include +#include "build-id.h" #include "event.h" #include "namespaces.h" #include "strlist.h" #include "strfilter.h" #include "debug.h" +#include "dso.h" #include "cache.h" #include "color.h" #include "map.h" diff --git a/tools/perf/util/s390-cpumsf.c b/tools/perf/util/s390-cpumsf.c index 4f6c1465998f..2ba4baa2c52f 100644 --- a/tools/perf/util/s390-cpumsf.c +++ b/tools/perf/util/s390-cpumsf.c @@ -157,6 +157,7 @@ #include "evlist.h" #include "machine.h" #include "session.h" +#include "tool.h" #include "thread.h" #include "debug.h" #include "auxtrace.h" diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index 800e82d35230..15961854ba67 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c @@ -35,6 +35,7 @@ #include #include "../callchain.h" +#include "../dso.h" #include "../machine.h" #include "../map.h" #include "../symbol.h" diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index abfde356be18..666a56e88d8e 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -31,8 +31,10 @@ #include #include +#include "../build-id.h" #include "../counts.h" #include "../debug.h" +#include "../dso.h" #include "../callchain.h" #include "../evsel.h" #include "../util.h" diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 4650704540c9..32ade5a1b553 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -5,6 +5,7 @@ #include #include #include "debug.h" +#include "dso.h" #include "sort.h" #include "hist.h" #include "cacheline.h" diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 5ba1601e8860..b64e9e049636 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -5,6 +5,7 @@ #include #include #include +#include "dso.h" #include "session.h" #include "thread.h" #include "thread-stack.h" diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index 28f71ca6ce1c..9ece188ae48a 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c @@ -5,6 +5,7 @@ #include #include #include "debug.h" +#include "dso.h" #include "unwind.h" #include "unwind-libdw.h" #include "machine.h" diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index 6499b22b158b..a24fb57c9b2c 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "unwind.h" +#include "dso.h" #include "map.h" #include "thread.h" #include "session.h" diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index 7f427bab6c12..e5e6599603f4 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c @@ -10,6 +10,7 @@ #include #include "vdso.h" +#include "dso.h" #include "util.h" #include "map.h" #include "symbol.h" -- cgit v1.2.3-59-g8ed1b From 171f7474b6bb6c7074431f76c28ea87d625c68fd Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 30 Aug 2019 11:28:14 -0300 Subject: perf hist: Remove needless ui/progress.h from hist.h We only need a forward declaration, add it and fixup all the files that need ui_progress definitions but were wrongly getting it from hist.h. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-84a90o9jdxybffxo9jmouokw@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-c2c.c | 1 + tools/perf/builtin-report.c | 1 + tools/perf/util/hist.h | 2 +- tools/perf/util/session.c | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index d1ad694c67a2..0d76b2cb8c0a 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -37,6 +37,7 @@ #include "mem2node.h" #include "symbol.h" #include "ui/ui.h" +#include "ui/progress.h" #include "../perf.h" struct c2c_hists { diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index ba419ee40283..d7a345667945 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -47,6 +47,7 @@ #include "util/branch.h" #include "util/util.h" #include "ui/ui.h" +#include "ui/progress.h" #include #include diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 7b9267ebebeb..1c0a635e5e32 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -8,7 +8,6 @@ #include "evsel.h" #include "header.h" #include "color.h" -#include "ui/progress.h" struct hist_entry; struct hist_entry_ops; @@ -18,6 +17,7 @@ struct mem_info; struct branch_info; struct block_info; struct symbol; +struct ui_progress; enum hist_filter { HIST_FILTER__DSO, diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index a72774e4463f..f166da76acf1 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -30,6 +30,7 @@ #include "sample-raw.h" #include "stat.h" #include "util.h" +#include "ui/progress.h" #include "../perf.h" #include "arch/common.h" -- cgit v1.2.3-59-g8ed1b From 4772925885dac93aa5f00d1c1da93277778099cd Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 30 Aug 2019 11:44:32 -0300 Subject: perf tools: Move 'struct events_stats' and prototypes to separate header This will allow us to untangle the header dependency a bit more, as some places will not need event.h anymore. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-enqncj29ovzaat3cd9203rwl@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/auxtrace.h | 5 +++++ tools/perf/util/event.h | 42 ---------------------------------- tools/perf/util/events_stats.h | 51 ++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/evlist.h | 2 +- tools/perf/util/hist.h | 4 +--- tools/perf/util/sort.h | 1 - 6 files changed, 58 insertions(+), 47 deletions(-) create mode 100644 tools/perf/util/events_stats.h (limited to 'tools') diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index b5ac24c770d4..c539e7b6ed56 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -30,6 +30,11 @@ struct record_opts; struct perf_record_auxtrace_info; struct events_stats; +enum auxtrace_error_type { + PERF_AUXTRACE_ERROR_ITRACE = 1, + PERF_AUXTRACE_ERROR_MAX +}; + /* Auxtrace records must have the same alignment as perf event records */ #define PERF_AUXTRACE_RECORD_ALIGNMENT 8 diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 006aa432be19..47ad81d47b1a 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -151,11 +151,6 @@ struct perf_sample { PERF_MEM_S(LOCK, NA) |\ PERF_MEM_S(TLB, NA)) -enum auxtrace_error_type { - PERF_AUXTRACE_ERROR_ITRACE = 1, - PERF_AUXTRACE_ERROR_MAX -}; - /* Attribute type for custom synthesized events */ #define PERF_TYPE_SYNTH (INT_MAX + 1U) @@ -277,43 +272,6 @@ static inline void *perf_synth__raw_data(void *p) #define perf_sample__bad_synth_size(s, d) ((s)->raw_size < sizeof(d) - 4) -/* - * The kernel collects the number of events it couldn't send in a stretch and - * when possible sends this number in a PERF_RECORD_LOST event. The number of - * such "chunks" of lost events is stored in .nr_events[PERF_EVENT_LOST] while - * total_lost tells exactly how many events the kernel in fact lost, i.e. it is - * the sum of all struct perf_record_lost.lost fields reported. - * - * The kernel discards mixed up samples and sends the number in a - * PERF_RECORD_LOST_SAMPLES event. The number of lost-samples events is stored - * in .nr_events[PERF_RECORD_LOST_SAMPLES] while total_lost_samples tells - * exactly how many samples the kernel in fact dropped, i.e. it is the sum of - * all struct perf_record_lost_samples.lost fields reported. - * - * The total_period is needed because by default auto-freq is used, so - * multipling nr_events[PERF_EVENT_SAMPLE] by a frequency isn't possible to get - * the total number of low level events, it is necessary to to sum all struct - * perf_record_sample.period and stash the result in total_period. - */ -struct events_stats { - u64 total_period; - u64 total_non_filtered_period; - u64 total_lost; - u64 total_lost_samples; - u64 total_aux_lost; - u64 total_aux_partial; - u64 total_invalid_chains; - u32 nr_events[PERF_RECORD_HEADER_MAX]; - u32 nr_non_filtered_samples; - u32 nr_lost_warned; - u32 nr_unknown_events; - u32 nr_invalid_chains; - u32 nr_unknown_id; - u32 nr_unprocessable_samples; - u32 nr_auxtrace_errors[PERF_AUXTRACE_ERROR_MAX]; - u32 nr_proc_map_timeout; -}; - enum { PERF_STAT_ROUND_TYPE__INTERVAL = 0, PERF_STAT_ROUND_TYPE__FINAL = 1, diff --git a/tools/perf/util/events_stats.h b/tools/perf/util/events_stats.h new file mode 100644 index 000000000000..859cb34fcff2 --- /dev/null +++ b/tools/perf/util/events_stats.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PERF_EVENTS_STATS_ +#define __PERF_EVENTS_STATS_ + +#include +#include +#include +#include "auxtrace.h" + +/* + * The kernel collects the number of events it couldn't send in a stretch and + * when possible sends this number in a PERF_RECORD_LOST event. The number of + * such "chunks" of lost events is stored in .nr_events[PERF_EVENT_LOST] while + * total_lost tells exactly how many events the kernel in fact lost, i.e. it is + * the sum of all struct perf_record_lost.lost fields reported. + * + * The kernel discards mixed up samples and sends the number in a + * PERF_RECORD_LOST_SAMPLES event. The number of lost-samples events is stored + * in .nr_events[PERF_RECORD_LOST_SAMPLES] while total_lost_samples tells + * exactly how many samples the kernel in fact dropped, i.e. it is the sum of + * all struct perf_record_lost_samples.lost fields reported. + * + * The total_period is needed because by default auto-freq is used, so + * multipling nr_events[PERF_EVENT_SAMPLE] by a frequency isn't possible to get + * the total number of low level events, it is necessary to to sum all struct + * perf_record_sample.period and stash the result in total_period. + */ +struct events_stats { + u64 total_period; + u64 total_non_filtered_period; + u64 total_lost; + u64 total_lost_samples; + u64 total_aux_lost; + u64 total_aux_partial; + u64 total_invalid_chains; + u32 nr_events[PERF_RECORD_HEADER_MAX]; + u32 nr_non_filtered_samples; + u32 nr_lost_warned; + u32 nr_unknown_events; + u32 nr_invalid_chains; + u32 nr_unknown_id; + u32 nr_unprocessable_samples; + u32 nr_auxtrace_errors[PERF_AUXTRACE_ERROR_MAX]; + u32 nr_proc_map_timeout; +}; + +void events_stats__inc(struct events_stats *stats, u32 type); + +size_t events_stats__fprintf(struct events_stats *stats, FILE *fp); + +#endif /* __PERF_EVENTS_STATS_ */ diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index ee288644e9e4..a55f0f2546e5 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -9,7 +9,7 @@ #include #include #include -#include "event.h" +#include "events_stats.h" #include "evsel.h" #include "mmap.h" #include diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 1c0a635e5e32..34803e33dc80 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -6,8 +6,8 @@ #include #include #include "evsel.h" -#include "header.h" #include "color.h" +#include "events_stats.h" struct hist_entry; struct hist_entry_ops; @@ -190,8 +190,6 @@ void hists__reset_stats(struct hists *hists); void hists__inc_stats(struct hists *hists, struct hist_entry *h); void hists__inc_nr_events(struct hists *hists, u32 type); void hists__inc_nr_samples(struct hists *hists, bool filtered); -void events_stats__inc(struct events_stats *stats, u32 type); -size_t events_stats__fprintf(struct events_stats *stats, FILE *fp); size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, int max_cols, float min_pcnt, FILE *fp, diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 3d7cef73924c..7b93f34ac1f4 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -9,7 +9,6 @@ #include "symbol_conf.h" #include "callchain.h" #include "values.h" - #include "hist.h" struct option; -- cgit v1.2.3-59-g8ed1b From 5c9dbe6da13398d09efc9ec479194afa6d9ec9e6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 30 Aug 2019 11:54:00 -0300 Subject: perf tools: Remove needless sort.h include directives Now that sort.h isn't included by any other header, we can check where it is really needed, i.e. we can remove it and be sure that it isn't being obtained indirectly. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-tom8k0lbsxd9joprr8zpu6w1@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 1 + tools/perf/ui/browsers/scripts.c | 1 - tools/perf/util/hist.c | 1 + tools/perf/util/mem-events.c | 1 - tools/perf/util/session.c | 1 - 5 files changed, 2 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 0b7b12cfdd63..0f0d96262d14 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -39,6 +39,7 @@ #include #include #include "util/parse-events.h" +#include "util/callchain.h" #include "util/cpumap.h" #include "util/sort.h" #include "util/string2.h" diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c index 77809c0fad02..bf1d9f9ec035 100644 --- a/tools/perf/ui/browsers/scripts.c +++ b/tools/perf/ui/browsers/scripts.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "../../builtin.h" #include "../../perf.h" -#include "../../util/sort.h" #include "../../util/util.h" #include "../../util/hist.h" #include "../../util/debug.h" diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index b526ef3ede98..0978dc4a33db 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/util/mem-events.c b/tools/perf/util/mem-events.c index 42c3e5a229d2..3a8d38ce3b54 100644 --- a/tools/perf/util/mem-events.c +++ b/tools/perf/util/mem-events.c @@ -11,7 +11,6 @@ #include "mem-events.h" #include "debug.h" #include "symbol.h" -#include "sort.h" unsigned int perf_mem_events__loads_ldlat = 30; diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index f166da76acf1..e5ac5f3c94d4 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -20,7 +20,6 @@ #include "symbol.h" #include "session.h" #include "tool.h" -#include "sort.h" #include "cpumap.h" #include "perf_regs.h" #include "asm/bug.h" -- cgit v1.2.3-59-g8ed1b From afce8c482c48e2c42c155eeae4cd048c2b5fbb99 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 30 Aug 2019 11:56:47 -0300 Subject: perf probe: No need for symbol.h, symbol_conf is enough Remove one more unneeded use of symbol.h Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-vrda1tuem1o8pk82t2kfjtun@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 6dce1724a378..26bc5923e6b5 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -21,7 +21,7 @@ #include "util/build-id.h" #include "util/strlist.h" #include "util/strfilter.h" -#include "util/symbol.h" +#include "util/symbol_conf.h" #include "util/debug.h" #include #include "util/probe-finder.h" -- cgit v1.2.3-59-g8ed1b From df1a0a110c2c0138665f6d8ec96812ea14c2d818 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 30 Aug 2019 12:07:23 -0300 Subject: perf tools: Remove needless map.h include directives Now that map.h isn't included by any other header, we can check where it is really needed, i.e. we can remove it and be sure that it isn't being obtained indirectly. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-iu8ylqky7g1i9i54v3y7qovw@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm64/util/sym-handling.c | 8 +++----- tools/perf/tests/thread-mg-share.c | 1 - tools/perf/util/intel-bts.c | 1 - 3 files changed, 3 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm64/util/sym-handling.c b/tools/perf/arch/arm64/util/sym-handling.c index 27fcf24d6850..5df788985130 100644 --- a/tools/perf/arch/arm64/util/sym-handling.c +++ b/tools/perf/arch/arm64/util/sym-handling.c @@ -4,11 +4,9 @@ * Copyright (C) 2015 Naveen N. Rao, IBM Corporation */ -#include "debug.h" -#include "symbol.h" -#include "map.h" -#include "probe-event.h" -#include "probe-file.h" +#include "symbol.h" // for the elf__needs_adjust_symbols() prototype +#include +#include #ifdef HAVE_LIBELF_SUPPORT bool elf__needs_adjust_symbols(GElf_Ehdr ehdr) diff --git a/tools/perf/tests/thread-mg-share.c b/tools/perf/tests/thread-mg-share.c index b1d1bbafe7ae..cbac71716dec 100644 --- a/tools/perf/tests/thread-mg-share.c +++ b/tools/perf/tests/thread-mg-share.c @@ -2,7 +2,6 @@ #include "tests.h" #include "machine.h" #include "thread.h" -#include "map.h" #include "debug.h" int test__thread_mg_share(struct test *test __maybe_unused, int subtest __maybe_unused) diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index a30427aa1de0..aacffa2b0362 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c @@ -19,7 +19,6 @@ #include "evsel.h" #include "evlist.h" #include "machine.h" -#include "map.h" #include "symbol.h" #include "session.h" #include "tool.h" -- cgit v1.2.3-59-g8ed1b From 4becb2395f9166b11d68817ed4af8fc06b840908 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 30 Aug 2019 12:13:45 -0300 Subject: perf tools: Remove needless thread.h include directives Now that thread.h isn't included by any other header, we can check where it is really needed, i.e. we can remove it and be sure that it isn't being obtained indirectly. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-kh333ivjbw05wsggckpziu86@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 1 - tools/perf/builtin-stat.c | 1 - tools/perf/builtin-top.c | 1 - tools/perf/tests/hists_filter.c | 1 - tools/perf/tests/hists_link.c | 1 - tools/perf/util/arm-spe.c | 1 - tools/perf/util/probe-event.c | 1 - tools/perf/util/probe-file.c | 1 - tools/perf/util/s390-cpumsf.c | 1 - 9 files changed, 9 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 738471a0a549..7135b77a18e7 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -24,7 +24,6 @@ #include "util/event.h" #include #include "util/parse-events.h" -#include "util/thread.h" #include "util/sort.h" #include "util/hist.h" #include "util/dso.h" diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index fa4212dac9bb..7e17bf9f700a 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -54,7 +54,6 @@ #include "util/stat.h" #include "util/header.h" #include "util/cpumap.h" -#include "util/thread.h" #include "util/thread_map.h" #include "util/counts.h" #include "util/group.h" diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 0f0d96262d14..eb941213fa0c 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -32,7 +32,6 @@ #include "util/map.h" #include "util/session.h" #include "util/symbol.h" -#include "util/thread.h" #include "util/thread_map.h" #include "util/top.h" #include "util/util.h" diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index 41dede2f40d8..618b51ffcc01 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -7,7 +7,6 @@ #include "util/event.h" #include "util/evlist.h" #include "util/machine.h" -#include "util/thread.h" #include "util/parse-events.h" #include "tests/tests.h" #include "tests/hists_common.h" diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index 012fe8ac0b24..8be4d0b61e3a 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -6,7 +6,6 @@ #include "evsel.h" #include "evlist.h" #include "machine.h" -#include "thread.h" #include "parse-events.h" #include "hists_common.h" #include diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c index d7c3fbb3694f..6bee59946c4f 100644 --- a/tools/perf/util/arm-spe.c +++ b/tools/perf/util/arm-spe.c @@ -20,7 +20,6 @@ #include "evlist.h" #include "machine.h" #include "session.h" -#include "thread.h" #include "debug.h" #include "auxtrace.h" #include "arm-spe.h" diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 5d12a78c8ac8..e90faa6bb5aa 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -31,7 +31,6 @@ #include "map.h" #include "map_groups.h" #include "symbol.h" -#include "thread.h" #include #include "trace-event.h" /* For __maybe_unused */ #include "probe-event.h" diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index 10d2ab179c71..adc949e8314f 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -20,7 +20,6 @@ #include "cache.h" #include "color.h" #include "symbol.h" -#include "thread.h" #include #include "probe-event.h" #include "probe-file.h" diff --git a/tools/perf/util/s390-cpumsf.c b/tools/perf/util/s390-cpumsf.c index 2ba4baa2c52f..24a99909d8b3 100644 --- a/tools/perf/util/s390-cpumsf.c +++ b/tools/perf/util/s390-cpumsf.c @@ -158,7 +158,6 @@ #include "machine.h" #include "session.h" #include "tool.h" -#include "thread.h" #include "debug.h" #include "auxtrace.h" #include "s390-cpumsf.h" -- cgit v1.2.3-59-g8ed1b From ef7d95661d046eddf2cf33847278781404679a2f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 30 Aug 2019 12:18:50 -0300 Subject: perf tools: Remove needless thread_map.h include directives Now that thread_map.h isn't included by any other header, we can check where it is really needed, i.e. we can remove it and be sure that it isn't being obtained indirectly. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-fyzvg64cz1ikvyxp8d6nrhz1@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 1 - tools/perf/builtin-top.c | 1 - tools/perf/util/cs-etm.c | 1 - 3 files changed, 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 197041fcba25..59e44f90dc46 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -24,7 +24,6 @@ #include "../../util/evlist.h" #include "../../util/evsel.h" #include "../../util/pmu.h" -#include "../../util/thread_map.h" #include "../../util/cs-etm.h" #include "../../util/util.h" diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index eb941213fa0c..726e3f2dd8c7 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -32,7 +32,6 @@ #include "util/map.h" #include "util/session.h" #include "util/symbol.h" -#include "util/thread_map.h" #include "util/top.h" #include "util/util.h" #include diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 3ed1d3bb7089..30c2048ce67d 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -30,7 +30,6 @@ #include "symbol.h" #include "tool.h" #include "thread.h" -#include "thread_map.h" #include "thread-stack.h" #include #include "util.h" -- cgit v1.2.3-59-g8ed1b From 7ae811b12e419fd70b7d7159f20ed8519bbe18cc Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 30 Aug 2019 12:29:03 -0300 Subject: perf tools: Remove needless evlist.h include directives Now that evlist.h isn't included by any other header, we can check where it is really needed, i.e. we can remove it and be sure that it isn't being obtained indirectly. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-6d7kape36m94a266md0d3xbh@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-lock.c | 2 +- tools/perf/builtin-timechart.c | 2 +- tools/perf/tests/hists_common.c | 1 - tools/perf/tests/sdt.c | 3 ++- tools/perf/ui/gtk/browser.c | 1 - tools/perf/util/arm-spe.c | 3 ++- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 38500bff4423..b0ff952be9db 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -4,7 +4,7 @@ #include "builtin.h" #include "perf.h" -#include "util/evlist.h" +#include "util/evlist.h" // for struct evsel_str_handler #include "util/evsel.h" #include "util/cache.h" #include "util/symbol.h" diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 1a74499f3311..65560a86f643 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -15,7 +15,7 @@ #include "util/color.h" #include #include "util/cache.h" -#include "util/evlist.h" +#include "util/evlist.h" // for struct evsel_str_handler #include "util/evsel.h" #include #include diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c index cdde41c03056..de110d8f169b 100644 --- a/tools/perf/tests/hists_common.c +++ b/tools/perf/tests/hists_common.c @@ -6,7 +6,6 @@ #include "util/symbol.h" #include "util/sort.h" #include "util/evsel.h" -#include "util/evlist.h" #include "util/machine.h" #include "util/thread.h" #include "tests/hists_common.h" diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c index dbc35a8912ed..cf1bd57d3023 100644 --- a/tools/perf/tests/sdt.c +++ b/tools/perf/tests/sdt.c @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include +#include #include -#include #include #include #include "tests.h" diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c index 4820e25ac68d..06a6a1ebaef0 100644 --- a/tools/perf/ui/gtk/browser.c +++ b/tools/perf/ui/gtk/browser.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#include "../evlist.h" #include "../cache.h" #include "../evsel.h" #include "../sort.h" diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c index 6bee59946c4f..8a7340f6a2a2 100644 --- a/tools/perf/util/arm-spe.c +++ b/tools/perf/util/arm-spe.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include #include @@ -17,7 +19,6 @@ #include "cpumap.h" #include "color.h" #include "evsel.h" -#include "evlist.h" #include "machine.h" #include "session.h" #include "debug.h" -- cgit v1.2.3-59-g8ed1b From fa0d98462fae5d4951f22f3ac1090d48c53396d1 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 30 Aug 2019 12:52:25 -0300 Subject: perf tools: Remove needless evlist.h include directives Remove the last unneeded use of cache.h in a header, we can check where it is really needed, i.e. we can remove it and be sure that it isn't being obtained indirectly. This is an old file, used by now incorrectly in many places, so it was providing includes needed indirectly, fixup this fallout. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-3x3l8gihoaeh7714os861ia7@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-buildid-cache.c | 3 ++- tools/perf/builtin-buildid-list.c | 2 +- tools/perf/builtin-kvm.c | 4 +++- tools/perf/builtin-list.c | 2 +- tools/perf/builtin-lock.c | 2 +- tools/perf/builtin-sched.c | 2 +- tools/perf/builtin-script.c | 2 +- tools/perf/builtin-timechart.c | 2 +- tools/perf/perf.c | 2 +- tools/perf/tests/llvm.c | 2 +- tools/perf/ui/browsers/header.c | 1 - tools/perf/ui/gtk/browser.c | 1 - tools/perf/ui/gtk/hists.c | 1 - tools/perf/ui/gtk/setup.c | 1 - tools/perf/ui/helpline.h | 2 -- tools/perf/ui/progress.c | 1 - tools/perf/ui/setup.c | 3 ++- tools/perf/ui/tui/helpline.c | 1 + tools/perf/ui/tui/progress.c | 1 - tools/perf/ui/tui/setup.c | 2 -- tools/perf/ui/tui/util.c | 1 - tools/perf/util/annotate.c | 1 - tools/perf/util/color.c | 3 ++- tools/perf/util/color_config.c | 3 ++- tools/perf/util/debug.c | 2 +- tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | 2 +- tools/perf/util/parse-events.c | 2 +- tools/perf/util/path.c | 3 ++- tools/perf/util/path.h | 3 +++ tools/perf/util/pmu.c | 3 ++- tools/perf/util/probe-event.c | 3 ++- tools/perf/util/probe-file.c | 2 +- 32 files changed, 33 insertions(+), 32 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index b035911969b8..1a69eb565dc0 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -15,9 +15,9 @@ #include #include "builtin.h" #include "namespaces.h" -#include "util/cache.h" #include "util/debug.h" #include "util/header.h" +#include #include #include "util/strlist.h" #include "util/build-id.h" @@ -27,6 +27,7 @@ #include "util/time-utils.h" #include "util/util.h" #include "util/probe-file.h" +#include static int build_id_cache__kcore_buildid(const char *proc_dir, char *sbuildid) { diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index 38b2ec61c021..5a0d8b378cb5 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -10,9 +10,9 @@ #include "builtin.h" #include "perf.h" #include "util/build-id.h" -#include "util/cache.h" #include "util/debug.h" #include "util/dso.h" +#include #include #include "util/session.h" #include "util/symbol.h" diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 474c4799d29d..0a4fcbe32bf6 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -6,12 +6,12 @@ #include "util/evsel.h" #include "util/evlist.h" #include "util/term.h" -#include "util/cache.h" #include "util/symbol.h" #include "util/thread.h" #include "util/header.h" #include "util/session.h" #include "util/intlist.h" +#include #include #include "util/trace-event.h" #include "util/debug.h" @@ -20,6 +20,7 @@ #include "util/top.h" #include "util/data.h" #include "util/ordered-events.h" +#include "ui/ui.h" #include #ifdef HAVE_TIMERFD_SUPPORT @@ -31,6 +32,7 @@ #include #include +#include #include #include #include diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 11afb760616b..e290f6b348d8 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -11,10 +11,10 @@ #include "builtin.h" #include "util/parse-events.h" -#include "util/cache.h" #include "util/pmu.h" #include "util/debug.h" #include "util/metricgroup.h" +#include #include #include diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index b0ff952be9db..4c2b7f437cdf 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -6,11 +6,11 @@ #include "util/evlist.h" // for struct evsel_str_handler #include "util/evsel.h" -#include "util/cache.h" #include "util/symbol.h" #include "util/thread.h" #include "util/header.h" +#include #include #include "util/trace-event.h" diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 91d0a9b10581..ec96d64aec69 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -4,7 +4,6 @@ #include "perf-sys.h" #include "util/evlist.h" -#include "util/cache.h" #include "util/evsel.h" #include "util/symbol.h" #include "util/thread.h" @@ -19,6 +18,7 @@ #include "util/callchain.h" #include "util/time-utils.h" +#include #include #include "util/trace-event.h" diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 1ff04b00a561..e079b34201f2 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "builtin.h" -#include "util/cache.h" #include "util/counts.h" #include "util/debug.h" #include "util/dso.h" @@ -30,6 +29,7 @@ #include "util/thread-stack.h" #include "util/time-utils.h" #include "util/path.h" +#include "ui/ui.h" #include "print_binary.h" #include "archinsn.h" #include diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 65560a86f643..e0e822695a29 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -14,7 +14,6 @@ #include "builtin.h" #include "util/color.h" #include -#include "util/cache.h" #include "util/evlist.h" // for struct evsel_str_handler #include "util/evsel.h" #include @@ -27,6 +26,7 @@ #include "perf.h" #include "util/header.h" +#include #include #include "util/parse-events.h" #include "util/event.h" diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 8763b2c0fbfd..1193b923e801 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -1,4 +1,3 @@ -// SPDX-License-Identifier: GPL-2.0 /* * perf.c * @@ -22,6 +21,7 @@ #include "util/debug.h" #include "util/event.h" #include "util/util.h" +#include "ui/ui.h" #include "perf-sys.h" #include #include diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c index ca5a5f94ce79..022e4c9cf092 100644 --- a/tools/perf/tests/llvm.c +++ b/tools/perf/tests/llvm.c @@ -1,9 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include #include -#include #include "llvm.h" #include "tests.h" #include "debug.h" diff --git a/tools/perf/ui/browsers/header.c b/tools/perf/ui/browsers/header.c index 5aeb663dd184..0f59a7001479 100644 --- a/tools/perf/ui/browsers/header.c +++ b/tools/perf/ui/browsers/header.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#include "util/cache.h" #include "util/debug.h" #include "ui/browser.h" #include "ui/keysyms.h" diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c index 06a6a1ebaef0..8f3e43d148a8 100644 --- a/tools/perf/ui/gtk/browser.c +++ b/tools/perf/ui/gtk/browser.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#include "../cache.h" #include "../evsel.h" #include "../sort.h" #include "../hist.h" diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index 0efdb226d1a7..6c2efc10bf5c 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 #include "../evlist.h" -#include "../cache.h" #include "../callchain.h" #include "../evsel.h" #include "../sort.h" diff --git a/tools/perf/ui/gtk/setup.c b/tools/perf/ui/gtk/setup.c index 506e73b3834c..1a2616b97b5c 100644 --- a/tools/perf/ui/gtk/setup.c +++ b/tools/perf/ui/gtk/setup.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 #include "gtk.h" -#include "../../util/cache.h" #include "../../util/debug.h" extern struct perf_error_ops perf_gtk_eops; diff --git a/tools/perf/ui/helpline.h b/tools/perf/ui/helpline.h index 8f775a053ca3..2165a098dee8 100644 --- a/tools/perf/ui/helpline.h +++ b/tools/perf/ui/helpline.h @@ -5,8 +5,6 @@ #include #include -#include "../util/cache.h" - struct ui_helpline { void (*pop)(void); void (*push)(const char *msg); diff --git a/tools/perf/ui/progress.c b/tools/perf/ui/progress.c index 8cd3b64c6893..99d60223c74b 100644 --- a/tools/perf/ui/progress.c +++ b/tools/perf/ui/progress.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 #include -#include "../util/cache.h" #include "progress.h" static void null_progress__update(struct ui_progress *p __maybe_unused) diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c index 3bc7c9a6fae9..c7a86b4be9f5 100644 --- a/tools/perf/ui/setup.c +++ b/tools/perf/ui/setup.c @@ -2,10 +2,11 @@ #include #include -#include "../util/cache.h" +#include #include "../util/debug.h" #include "../util/hist.h" #include "../util/util.h" +#include "ui.h" pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; void *perf_gtk_handle; diff --git a/tools/perf/ui/tui/helpline.c b/tools/perf/ui/tui/helpline.c index 1793c98653a5..5f188f678c55 100644 --- a/tools/perf/ui/tui/helpline.c +++ b/tools/perf/ui/tui/helpline.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "../../util/debug.h" #include "../helpline.h" diff --git a/tools/perf/ui/tui/progress.c b/tools/perf/ui/tui/progress.c index 5a24dd3ce4db..3d74af5a7ece 100644 --- a/tools/perf/ui/tui/progress.c +++ b/tools/perf/ui/tui/progress.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 #include -#include "../../util/cache.h" #include "../progress.h" #include "../libslang.h" #include "../ui.h" diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c index 2881982b483c..56651a4f5aa0 100644 --- a/tools/perf/ui/tui/setup.c +++ b/tools/perf/ui/tui/setup.c @@ -1,4 +1,3 @@ -// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -8,7 +7,6 @@ #include #endif -#include "../../util/cache.h" #include "../../util/debug.h" #include "../../util/util.h" #include "../../perf.h" diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c index 1163df8b6f06..087d9ab054c8 100644 --- a/tools/perf/ui/tui/util.c +++ b/tools/perf/ui/tui/util.c @@ -5,7 +5,6 @@ #include #include -#include "../../util/cache.h" #include "../../util/debug.h" #include "../browser.h" #include "../keysyms.h" diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 67a7513077d0..eb3c50de831d 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -19,7 +19,6 @@ #include "build-id.h" #include "color.h" #include "config.h" -#include "cache.h" #include "dso.h" #include "map.h" #include "symbol.h" diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c index 39b8c4ec4e2e..bffbdd216a6a 100644 --- a/tools/perf/util/color.c +++ b/tools/perf/util/color.c @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 #include -#include "cache.h" +#include #include #include +#include #include "color.h" #include #include diff --git a/tools/perf/util/color_config.c b/tools/perf/util/color_config.c index 817dc56e7e95..dc09ba7cb31e 100644 --- a/tools/perf/util/color_config.c +++ b/tools/perf/util/color_config.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include -#include "cache.h" +#include +#include #include "config.h" #include #include diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index 143d379d4608..a1b59bd35519 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c @@ -13,7 +13,6 @@ #ifdef HAVE_BACKTRACE_SUPPORT #include #endif -#include "cache.h" #include "color.h" #include "event.h" #include "debug.h" @@ -21,6 +20,7 @@ #include "util.h" #include "target.h" #include "ui/helpline.h" +#include "ui/ui.h" #include diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c index 3bfdf2b7a96a..f8ccfd6be0ee 100644 --- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c @@ -14,9 +14,9 @@ #include #include #include +#include #include -#include "../cache.h" #include "../auxtrace.h" #include "intel-pt-insn-decoder.h" diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 523af1bd82e6..5ec21d21113c 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -13,13 +13,13 @@ #include "build-id.h" #include "evlist.h" #include "evsel.h" +#include #include #include "parse-events.h" #include #include "string2.h" #include "strlist.h" #include "symbol.h" -#include "cache.h" #include "header.h" #include "bpf-loader.h" #include "debug.h" diff --git a/tools/perf/util/path.c b/tools/perf/util/path.c index ca56ba2dd3da..caed0336429f 100644 --- a/tools/perf/util/path.c +++ b/tools/perf/util/path.c @@ -11,11 +11,12 @@ * * which is what it's designed for. */ -#include "cache.h" #include "path.h" +#include "cache.h" #include #include #include +#include #include #include #include diff --git a/tools/perf/util/path.h b/tools/perf/util/path.h index f014f905df50..083429b7efa3 100644 --- a/tools/perf/util/path.h +++ b/tools/perf/util/path.h @@ -2,6 +2,9 @@ #ifndef _PERF_PATH_H #define _PERF_PATH_H +#include +#include + struct dirent; int path__join(char *bf, size_t size, const char *path1, const char *path2); diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 9807be6f09bb..6b3448f6eb94 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -22,8 +23,8 @@ #include "cpumap.h" #include "header.h" #include "pmu-events/pmu-events.h" -#include "cache.h" #include "string2.h" +#include "strbuf.h" struct perf_pmu_format { char *name; diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index e90faa6bb5aa..b8e0967c5c21 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -26,7 +26,6 @@ #include "strfilter.h" #include "debug.h" #include "dso.h" -#include "cache.h" #include "color.h" #include "map.h" #include "map_groups.h" @@ -38,7 +37,9 @@ #include "probe-file.h" #include "session.h" #include "string2.h" +#include "strbuf.h" +#include #include #include diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index adc949e8314f..d13db55a2feb 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -17,9 +17,9 @@ #include "strfilter.h" #include "debug.h" #include "dso.h" -#include "cache.h" #include "color.h" #include "symbol.h" +#include "strbuf.h" #include #include "probe-event.h" #include "probe-file.h" -- cgit v1.2.3-59-g8ed1b From f2a39fe84901df2b3d1bec3459b65cee3e8db57c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 30 Aug 2019 14:45:20 -0300 Subject: perf auxtrace: Uninline functions that touch perf_session So that we don't carry the session.h include directive in auxtrace.h, which in turn opens a can of worms of files that were getting all sorts of things via that include, fix them all. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-d2d83aovpgri2z75wlitquni@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/annotate/instructions.c | 1 + tools/perf/arch/arm/util/cs-etm.c | 1 + tools/perf/arch/arm64/annotate/instructions.c | 1 + tools/perf/arch/x86/tests/perf-time-to-tsc.c | 1 + tools/perf/builtin-ftrace.c | 1 + tools/perf/tests/backward-ring-buffer.c | 1 + tools/perf/tests/bpf.c | 1 + tools/perf/tests/builtin-test.c | 1 + tools/perf/tests/code-reading.c | 6 ++++ tools/perf/tests/event-times.c | 1 + tools/perf/tests/event_update.c | 2 ++ tools/perf/tests/keep-tracking.c | 1 + tools/perf/tests/mmap-basic.c | 1 + tools/perf/tests/parse-events.c | 1 + tools/perf/tests/switch-tracking.c | 1 + tools/perf/ui/browsers/hists.c | 1 + tools/perf/ui/browsers/res_sample.c | 2 ++ tools/perf/ui/browsers/scripts.c | 1 + tools/perf/ui/hist.c | 2 ++ tools/perf/ui/stdio/hist.c | 1 + tools/perf/util/annotate.c | 3 ++ tools/perf/util/auxtrace.c | 33 ++++++++++++++++++++ tools/perf/util/auxtrace.h | 43 +++++---------------------- tools/perf/util/bpf-loader.c | 1 + tools/perf/util/cgroup.c | 2 ++ tools/perf/util/config.c | 1 + tools/perf/util/cs-etm.c | 1 + tools/perf/util/cs-etm.h | 3 +- tools/perf/util/dso.c | 2 ++ tools/perf/util/evlist.c | 1 + tools/perf/util/evsel.c | 1 + tools/perf/util/machine.c | 2 ++ tools/perf/util/mmap.c | 3 ++ tools/perf/util/mmap.h | 1 + tools/perf/util/python.c | 2 ++ tools/perf/util/record.c | 2 ++ tools/perf/util/s390-sample-raw.c | 1 - tools/perf/util/sort.c | 1 + tools/perf/util/stat-display.c | 1 + tools/perf/util/stat.c | 3 ++ tools/perf/util/top.h | 1 + 41 files changed, 98 insertions(+), 38 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/annotate/instructions.c b/tools/perf/arch/arm/annotate/instructions.c index c7d1a69b894f..e1d4b484cc4b 100644 --- a/tools/perf/arch/arm/annotate/instructions.c +++ b/tools/perf/arch/arm/annotate/instructions.c @@ -3,6 +3,7 @@ #include #include #include +#include struct arm_annotate { regex_t call_insn, diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 59e44f90dc46..c32db09baf0d 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -26,6 +26,7 @@ #include "../../util/pmu.h" #include "../../util/cs-etm.h" #include "../../util/util.h" +#include "../../util/session.h" #include #include diff --git a/tools/perf/arch/arm64/annotate/instructions.c b/tools/perf/arch/arm64/annotate/instructions.c index 8f70a1b282df..43aa93ed8414 100644 --- a/tools/perf/arch/arm64/annotate/instructions.c +++ b/tools/perf/arch/arm64/annotate/instructions.c @@ -2,6 +2,7 @@ #include #include #include +#include struct arm64_annotate { regex_t call_insn, diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index 2d1f4713b728..eb3635941c2b 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include #include #include diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 2f8ea44c00c4..d5adc417a4ca 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 512288e9f547..a637a4a90760 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -9,6 +9,7 @@ #include "record.h" #include "tests.h" #include "debug.h" +#include "parse-events.h" #include #include diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 9fc163b2acbb..fc102e4f403e 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -18,6 +18,7 @@ #include "tests.h" #include "llvm.h" #include "debug.h" +#include "parse-events.h" #define NR_ITERS 111 #define PERF_TEST_BPF_PATH "/sys/fs/bpf/perf_test" diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index c3bec9d2c201..55774baffc2a 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 7b2b89f4b716..c1c29e08e7fb 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -13,7 +13,9 @@ #include "debug.h" #include "dso.h" +#include "env.h" #include "parse-events.h" +#include "trace-event.h" #include "evlist.h" #include "evsel.h" #include "thread_map.h" @@ -496,6 +498,10 @@ static void fs_something(void) } } +#ifdef __s390x__ +#include "header.h" // for get_cpuid() +#endif + static const char *do_determine_event(bool excl_kernel) { const char *event = excl_kernel ? "cycles:u" : "cycles"; diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 228d1618cf7d..d824a726906c 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -11,6 +11,7 @@ #include "evsel.h" #include "util.h" #include "debug.h" +#include "parse-events.h" #include "thread_map.h" #include "target.h" diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index 4b68ec3a13fc..cac4290e233a 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -1,8 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include "evlist.h" #include "evsel.h" +#include "header.h" #include "machine.h" #include "tool.h" #include "tests.h" diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index c758798d3774..9f0762d987fa 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include #include diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index bdf77bfe1b80..85e1d7337dc0 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -3,6 +3,7 @@ #include /* For the CLR_() macros */ #include +#include #include #include "debug.h" diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 49f52e4de41b..02ba696fb87f 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -5,6 +5,7 @@ #include #include "tests.h" #include "debug.h" +#include "pmu.h" #include "util.h" #include #include diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 4bed15aee1a8..1a60fa1219f5 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index cf8857456056..f7e54c16e594 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -16,6 +16,7 @@ #include "../../util/callchain.h" #include "../../util/evsel.h" #include "../../util/evlist.h" +#include "../../util/header.h" #include "../../util/hist.h" #include "../../util/map.h" #include "../../util/symbol.h" diff --git a/tools/perf/ui/browsers/res_sample.c b/tools/perf/ui/browsers/res_sample.c index db3954fea74c..f16a38fea45e 100644 --- a/tools/perf/ui/browsers/res_sample.c +++ b/tools/perf/ui/browsers/res_sample.c @@ -9,6 +9,8 @@ #include "../util.h" #include "../../util/util.h" #include "../../perf.h" +#include +#include #include #include diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c index bf1d9f9ec035..586a21acc13d 100644 --- a/tools/perf/ui/browsers/scripts.c +++ b/tools/perf/ui/browsers/scripts.c @@ -10,6 +10,7 @@ #include "config.h" #include #include +#include #define SCRIPT_NAMELEN 128 #define SCRIPT_MAX_NO 64 diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index bf90ce5b2cdf..3e533de7d852 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include +#include #include #include "../util/callchain.h" diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index 51ed67548b83..832ca6cfbe30 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include "../../util/callchain.h" diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index eb3c50de831d..1748f528b6e9 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -20,7 +21,9 @@ #include "color.h" #include "config.h" #include "dso.h" +#include "env.h" #include "map.h" +#include "map_groups.h" #include "symbol.h" #include "srcline.h" #include "units.h" diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 10c707724035..6f25224a3def 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -2196,3 +2196,36 @@ int auxtrace_parse_filters(struct evlist *evlist) return 0; } + +int auxtrace__process_event(struct perf_session *session, union perf_event *event, + struct perf_sample *sample, struct perf_tool *tool) +{ + if (!session->auxtrace) + return 0; + + return session->auxtrace->process_event(session, event, sample, tool); +} + +int auxtrace__flush_events(struct perf_session *session, struct perf_tool *tool) +{ + if (!session->auxtrace) + return 0; + + return session->auxtrace->flush_events(session, tool); +} + +void auxtrace__free_events(struct perf_session *session) +{ + if (!session->auxtrace) + return; + + return session->auxtrace->free_events(session); +} + +void auxtrace__free(struct perf_session *session) +{ + if (!session->auxtrace) + return; + + return session->auxtrace->free(session); +} diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index c539e7b6ed56..37e70dc01436 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -18,7 +18,6 @@ #include #include "event.h" -#include "session.h" union perf_event; struct perf_session; @@ -380,6 +379,8 @@ struct addr_filters { int cnt; }; +struct auxtrace_cache; + #ifdef HAVE_AUXTRACE_SUPPORT /* @@ -549,41 +550,11 @@ int addr_filters__parse_bare_filter(struct addr_filters *filts, const char *filter); int auxtrace_parse_filters(struct evlist *evlist); -static inline int auxtrace__process_event(struct perf_session *session, - union perf_event *event, - struct perf_sample *sample, - struct perf_tool *tool) -{ - if (!session->auxtrace) - return 0; - - return session->auxtrace->process_event(session, event, sample, tool); -} - -static inline int auxtrace__flush_events(struct perf_session *session, - struct perf_tool *tool) -{ - if (!session->auxtrace) - return 0; - - return session->auxtrace->flush_events(session, tool); -} - -static inline void auxtrace__free_events(struct perf_session *session) -{ - if (!session->auxtrace) - return; - - return session->auxtrace->free_events(session); -} - -static inline void auxtrace__free(struct perf_session *session) -{ - if (!session->auxtrace) - return; - - return session->auxtrace->free(session); -} +int auxtrace__process_event(struct perf_session *session, union perf_event *event, + struct perf_sample *sample, struct perf_tool *tool); +int auxtrace__flush_events(struct perf_session *session, struct perf_tool *tool); +void auxtrace__free_events(struct perf_session *session); +void auxtrace__free(struct perf_session *session); #define ITRACE_HELP \ " i: synthesize instructions events\n" \ diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index c1a57323e25d..37283e865352 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "debug.h" #include "evlist.h" #include "bpf-loader.h" diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 96a931c6f728..4881d4af3381 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include int nr_cgroups; diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 7ebf9e31ae22..0bc9c4d7fdc5 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -23,6 +23,7 @@ #include "debug.h" #include #include +#include #include #include #include diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 30c2048ce67d..0174ecf757d7 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -27,6 +27,7 @@ #include "machine.h" #include "map.h" #include "perf.h" +#include "session.h" #include "symbol.h" #include "tool.h" #include "thread.h" diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h index bc848fd095f4..650ecc2a6349 100644 --- a/tools/perf/util/cs-etm.h +++ b/tools/perf/util/cs-etm.h @@ -8,9 +8,10 @@ #define INCLUDE__UTIL_PERF_CS_ETM_H__ #include "util/event.h" -#include "util/session.h" #include +struct perf_session; + /* Versionning header in case things need tro change in the future. That way * decoding of old snapshot is still possible. */ diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index ece97209792d..e11ddf86f2b3 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -10,9 +10,11 @@ #include #include #include +#include #include #include "bpf-event.h" #include "compress.h" +#include "env.h" #include "namespaces.h" #include "path.h" #include "map.h" diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index b5d6d6ec9a9b..095924aa186b 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "parse-events.h" #include diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index b6b406a1678f..85825384f9e8 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "asm/bug.h" #include "callchain.h" diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 003025465198..6a77aefbe319 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -3,9 +3,11 @@ #include #include #include +#include #include "callchain.h" #include "debug.h" #include "dso.h" +#include "env.h" #include "event.h" #include "evsel.h" #include "hist.h" diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 28477ff5114e..33c5b5495482 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -10,9 +10,12 @@ #include #include #include +#include +#include #ifdef HAVE_LIBNUMA_SUPPORT #include #endif +#include "cpumap.h" #include "debug.h" #include "event.h" #include "mmap.h" diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index 274ce389cd84..3857a49e8f96 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -6,6 +6,7 @@ #include #include #include +#include // for cpu_set_t #ifdef HAVE_AIO_SUPPORT #include #endif diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 9b350482c403..07ca4535e6f7 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "debug.h" #include "evlist.h" #include "callchain.h" @@ -13,6 +14,7 @@ #include "cpumap.h" #include "print_binary.h" #include "thread_map.h" +#include "trace-event.h" #include "mmap.h" #include "util.h" #include "../perf-sys.h" diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index ccad796bce5f..286fe816c0f3 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -5,6 +5,8 @@ #include "cpumap.h" #include "parse-events.h" #include +#include +#include #include #include #include diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sample-raw.c index d311c81464e5..0ddfa7b3e4f2 100644 --- a/tools/perf/util/s390-sample-raw.c +++ b/tools/perf/util/s390-sample-raw.c @@ -23,7 +23,6 @@ #include "debug.h" #include "util.h" -#include "auxtrace.h" #include "session.h" #include "evlist.h" #include "config.h" diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 32ade5a1b553..b974a2c3a3c5 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include "debug.h" diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 1461dac2322d..ed3b0ac2f785 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -1,3 +1,4 @@ +#include #include #include #include diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index f4a1edcec7b2..8f1ea27f976f 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -2,9 +2,12 @@ #include #include #include +#include #include "counts.h" #include "debug.h" +#include "header.h" #include "stat.h" +#include "session.h" #include "target.h" #include "evlist.h" #include "evsel.h" diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h index 7367433e767a..f117d4f4821e 100644 --- a/tools/perf/util/top.h +++ b/tools/perf/util/top.h @@ -5,6 +5,7 @@ #include "tool.h" #include "evswitch.h" #include "annotate.h" +#include "ordered-events.h" #include "record.h" #include #include -- cgit v1.2.3-59-g8ed1b From d3300a3c4e76ccecf4daa889327e340a870c550b Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 30 Aug 2019 15:09:54 -0300 Subject: perf symbols: Move mem_info and branch_info out of symbol.h The mem_info struct goes to mem-events.h and branch_info goes to branch.h, where they belong, this way we can remove several headers from symbols.h and trim the include dependency tree more. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-aupw71xnravcsu2xoabfmhpc@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/powerpc/util/mem-events.c | 1 + tools/perf/builtin-annotate.c | 2 ++ tools/perf/builtin-c2c.c | 1 + tools/perf/builtin-mem.c | 1 + tools/perf/builtin-report.c | 3 +++ tools/perf/builtin-version.c | 2 +- tools/perf/tests/mem.c | 1 + tools/perf/tests/sample-parsing.c | 1 + tools/perf/ui/browsers/hists.c | 2 ++ tools/perf/util/branch.c | 1 + tools/perf/util/branch.h | 8 ++++++++ tools/perf/util/cs-etm.c | 2 ++ tools/perf/util/hist.c | 3 +++ tools/perf/util/machine.c | 3 +++ tools/perf/util/map.c | 1 + tools/perf/util/mem-events.c | 1 + tools/perf/util/mem-events.h | 9 +++++++++ tools/perf/util/s390-sample-raw.c | 1 - tools/perf/util/session.c | 2 ++ tools/perf/util/sort.c | 2 ++ tools/perf/util/symbol.c | 2 ++ tools/perf/util/symbol.h | 17 ----------------- 22 files changed, 47 insertions(+), 19 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/powerpc/util/mem-events.c b/tools/perf/arch/powerpc/util/mem-events.c index d08311f04e95..07fb5e049488 100644 --- a/tools/perf/arch/powerpc/util/mem-events.c +++ b/tools/perf/arch/powerpc/util/mem-events.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include "map_symbol.h" #include "mem-events.h" /* PowerPC does not support 'ldlat' parameter. */ diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 7135b77a18e7..4e4d2e76232e 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -33,6 +33,8 @@ #include "util/data.h" #include "arch/common.h" #include "util/block-range.h" +#include "util/map_symbol.h" +#include "util/branch.h" #include #include diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index 0d76b2cb8c0a..b09b12e0976b 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -22,6 +22,7 @@ #include "builtin.h" #include #include +#include "map_symbol.h" #include "mem-events.h" #include "session.h" #include "hist.h" diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index c5f3b9e9509d..27d2bde943a8 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -11,6 +11,7 @@ #include "util/tool.h" #include "util/session.h" #include "util/data.h" +#include "util/map_symbol.h" #include "util/mem-events.h" #include "util/debug.h" #include "util/dso.h" diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index d7a345667945..b18fab94d38d 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -19,6 +19,9 @@ #include #include "util/map.h" #include "util/symbol.h" +#include "util/map_symbol.h" +#include "util/mem-events.h" +#include "util/branch.h" #include "util/callchain.h" #include "util/values.h" diff --git a/tools/perf/builtin-version.c b/tools/perf/builtin-version.c index bf114ca9ca87..05cf2af9e2c2 100644 --- a/tools/perf/builtin-version.c +++ b/tools/perf/builtin-version.c @@ -2,8 +2,8 @@ #include "builtin.h" #include "perf.h" #include "color.h" -#include #include +#include #include #include #include diff --git a/tools/perf/tests/mem.c b/tools/perf/tests/mem.c index efe3397824d2..673a11a6cd1b 100644 --- a/tools/perf/tests/mem.c +++ b/tools/perf/tests/mem.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include "util/map_symbol.h" #include "util/mem-events.h" #include "util/symbol.h" #include "linux/perf_event.h" diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c index 0c09dc15a059..5fcc06817076 100644 --- a/tools/perf/tests/sample-parsing.c +++ b/tools/perf/tests/sample-parsing.c @@ -7,6 +7,7 @@ #include #include +#include "map_symbol.h" #include "branch.h" #include "util.h" #include "event.h" diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index f7e54c16e594..589168ca9f62 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -20,6 +20,8 @@ #include "../../util/hist.h" #include "../../util/map.h" #include "../../util/symbol.h" +#include "../../util/map_symbol.h" +#include "../../util/branch.h" #include "../../util/pstack.h" #include "../../util/sort.h" #include "../../util/top.h" diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c index 30642e1f2b1b..9d1e090084a2 100644 --- a/tools/perf/util/branch.c +++ b/tools/perf/util/branch.c @@ -1,5 +1,6 @@ #include "util/util.h" #include "util/debug.h" +#include "util/map_symbol.h" #include "util/branch.h" #include diff --git a/tools/perf/util/branch.h b/tools/perf/util/branch.h index 64f96b79f1d7..06f66dad0b79 100644 --- a/tools/perf/util/branch.h +++ b/tools/perf/util/branch.h @@ -16,6 +16,14 @@ struct branch_flags { u64 reserved:40; }; +struct branch_info { + struct addr_map_symbol from; + struct addr_map_symbol to; + struct branch_flags flags; + char *srcline_from; + char *srcline_to; +}; + struct branch_entry { u64 from; u64 to; diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 0174ecf757d7..707afdbd9529 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -28,6 +28,8 @@ #include "map.h" #include "perf.h" #include "session.h" +#include "map_symbol.h" +#include "branch.h" #include "symbol.h" #include "tool.h" #include "thread.h" diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 0978dc4a33db..679a1d75090c 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -5,6 +5,9 @@ #include "build-id.h" #include "hist.h" #include "map.h" +#include "map_symbol.h" +#include "branch.h" +#include "mem-events.h" #include "session.h" #include "namespaces.h" #include "sort.h" diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 6a77aefbe319..b4749d3eed08 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -13,6 +13,9 @@ #include "hist.h" #include "machine.h" #include "map.h" +#include "map_symbol.h" +#include "branch.h" +#include "mem-events.h" #include "srcline.h" #include "symbol.h" #include "sort.h" diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 623a63cd1eec..5b83ed1ebbd6 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -10,6 +10,7 @@ #include /* To get things like MAP_HUGETLB even on older libc headers */ #include "dso.h" #include "map.h" +#include "map_symbol.h" #include "thread.h" #include "vdso.h" #include "build-id.h" diff --git a/tools/perf/util/mem-events.c b/tools/perf/util/mem-events.c index 3a8d38ce3b54..3d391583f2ae 100644 --- a/tools/perf/util/mem-events.c +++ b/tools/perf/util/mem-events.c @@ -8,6 +8,7 @@ #include #include #include +#include "map_symbol.h" #include "mem-events.h" #include "debug.h" #include "symbol.h" diff --git a/tools/perf/util/mem-events.h b/tools/perf/util/mem-events.h index a889ec2fa9f5..f1389bdae7bf 100644 --- a/tools/perf/util/mem-events.h +++ b/tools/perf/util/mem-events.h @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include "stat.h" struct perf_mem_event { @@ -16,6 +18,13 @@ struct perf_mem_event { const char *sysfs_name; }; +struct mem_info { + struct addr_map_symbol iaddr; + struct addr_map_symbol daddr; + union perf_mem_data_src data_src; + refcount_t refcnt; +}; + enum { PERF_MEM_EVENTS__LOAD, PERF_MEM_EVENTS__STORE, diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sample-raw.c index 0ddfa7b3e4f2..4d9593e331ea 100644 --- a/tools/perf/util/s390-sample-raw.c +++ b/tools/perf/util/s390-sample-raw.c @@ -25,7 +25,6 @@ #include "util.h" #include "session.h" #include "evlist.h" -#include "config.h" #include "color.h" #include "sample-raw.h" #include "s390-cpumcf-kernel.h" diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index e5ac5f3c94d4..e9e4a04f15db 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -12,6 +12,8 @@ #include #include +#include "map_symbol.h" +#include "branch.h" #include "debug.h" #include "evlist.h" #include "evsel.h" diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index b974a2c3a3c5..a2308eb77681 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -13,6 +13,8 @@ #include "comm.h" #include "map.h" #include "symbol.h" +#include "map_symbol.h" +#include "branch.h" #include "thread.h" #include "evsel.h" #include "evlist.h" diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index e5ffe61ad66b..765c75df2904 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -25,6 +25,8 @@ #include "machine.h" #include "map.h" #include "symbol.h" +#include "map_symbol.h" +#include "mem-events.h" #include "symsrc.h" #include "strlist.h" #include "intlist.h" diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 5a58407c2945..0b0c6b5b1899 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -9,8 +9,6 @@ #include #include #include -#include "map_symbol.h" -#include "branch.h" #include "path.h" #include "symbol_conf.h" @@ -107,21 +105,6 @@ struct ref_reloc_sym { u64 unrelocated_addr; }; -struct branch_info { - struct addr_map_symbol from; - struct addr_map_symbol to; - struct branch_flags flags; - char *srcline_from; - char *srcline_to; -}; - -struct mem_info { - struct addr_map_symbol iaddr; - struct addr_map_symbol daddr; - union perf_mem_data_src data_src; - refcount_t refcnt; -}; - struct block_info { struct symbol *sym; u64 start; -- cgit v1.2.3-59-g8ed1b From a55ab7c4ca6986a542d313b02043a39ebf712a39 Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Wed, 28 Aug 2019 13:59:29 +0800 Subject: perf pmu: Change convert_scale from static to global The function convert_scale() can be used to convert string to unit and scale. For example, s = "6000000000ns"; convert_scale(s, &unit, &scale); unit = "ns", scale = 6000000000. Currently this function is static. This patch renames the function to perf_pmu__convert_scale and changes the function to global. No functional change. Signed-off-by: Jin Yao Cc: Alexander Shishkin Cc: Andi Kleen Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190828055932.8269-2-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/pmu.c | 6 +++--- tools/perf/util/pmu.h | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 6b3448f6eb94..fb597fa94234 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -102,7 +102,7 @@ static int pmu_format(const char *name, struct list_head *format) return 0; } -static int convert_scale(const char *scale, char **end, double *sval) +int perf_pmu__convert_scale(const char *scale, char **end, double *sval) { char *lc; int ret = 0; @@ -165,7 +165,7 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char * else scale[sret] = '\0'; - ret = convert_scale(scale, NULL, &alias->scale); + ret = perf_pmu__convert_scale(scale, NULL, &alias->scale); error: close(fd); return ret; @@ -373,7 +373,7 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, desc ? strdup(desc) : NULL; alias->topic = topic ? strdup(topic) : NULL; if (unit) { - if (convert_scale(unit, &unit, &alias->scale) < 0) + if (perf_pmu__convert_scale(unit, &unit, &alias->scale) < 0) return -1; snprintf(alias->unit, sizeof(alias->unit), "%s", unit); } diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 3f8b79b1dd85..f36ade6df76d 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -96,4 +96,6 @@ struct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu); struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu); +int perf_pmu__convert_scale(const char *scale, char **end, double *sval); + #endif /* __PMU_H */ -- cgit v1.2.3-59-g8ed1b From 287f2649f791819dd2d8f32f0213c8c521d6dfa0 Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Wed, 28 Aug 2019 13:59:31 +0800 Subject: perf metricgroup: Scale the metric result Some metrics define the scale unit, such as { "BriefDescription": "Intel Optane DC persistent memory read latency (ns). Derived from unc_m_pmm_rpq_occupancy.all", "Counter": "0,1,2,3", "EventCode": "0xE0", "EventName": "UNC_M_PMM_READ_LATENCY", "MetricExpr": "UNC_M_PMM_RPQ_OCCUPANCY.ALL / UNC_M_PMM_RPQ_INSERTS / UNC_M_CLOCKTICKS", "MetricName": "UNC_M_PMM_READ_LATENCY", "PerPkg": "1", "ScaleUnit": "6000000000ns", "UMask": "0x1", "Unit": "iMC" }, For above example, the ratio should be, ratio = (UNC_M_PMM_RPQ_OCCUPANCY.ALL / UNC_M_PMM_RPQ_INSERTS / UNC_M_CLOCKTICKS) * 6000000000 But in current code, the ratio is not scaled ( * 6000000000) With this patch, the ratio is scaled and the unit (ns) is printed. For example, # 219.4 ns UNC_M_PMM_READ_LATENCY Signed-off-by: Jin Yao Cc: Alexander Shishkin Cc: Andi Kleen Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190828055932.8269-4-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/metricgroup.c | 3 +++ tools/perf/util/metricgroup.h | 1 + tools/perf/util/stat-shadow.c | 38 +++++++++++++++++++++++++++----------- 3 files changed, 31 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 33f5e2101874..f474a29f1b69 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -87,6 +87,7 @@ struct egroup { const char **ids; const char *metric_name; const char *metric_expr; + const char *metric_unit; }; static bool record_evsel(int *ind, struct evsel **start, @@ -182,6 +183,7 @@ static int metricgroup__setup_events(struct list_head *groups, } expr->metric_expr = eg->metric_expr; expr->metric_name = eg->metric_name; + expr->metric_unit = eg->metric_unit; expr->metric_events = metric_events; list_add(&expr->nd, &me->head); } @@ -453,6 +455,7 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events, eg->idnum = idnum; eg->metric_name = pe->metric_name; eg->metric_expr = pe->metric_expr; + eg->metric_unit = pe->unit; list_add_tail(&eg->nd, group_list); ret = 0; } diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index e5092f6404ae..475c7f912864 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -20,6 +20,7 @@ struct metric_expr { struct list_head nd; const char *metric_expr; const char *metric_name; + const char *metric_unit; struct evsel **metric_events; }; diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index 2ed5e0066c70..696d263f6eb6 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -715,6 +715,7 @@ static void generic_metric(struct perf_stat_config *config, struct evsel **metric_events, char *name, const char *metric_name, + const char *metric_unit, double avg, int cpu, struct perf_stat_output_ctx *out, @@ -722,7 +723,7 @@ static void generic_metric(struct perf_stat_config *config, { print_metric_t print_metric = out->print_metric; struct parse_ctx pctx; - double ratio; + double ratio, scale; int i; void *ctxp = out->ctx; char *n, *pn; @@ -732,7 +733,6 @@ static void generic_metric(struct perf_stat_config *config, for (i = 0; metric_events[i]; i++) { struct saved_value *v; struct stats *stats; - double scale; if (!strcmp(metric_events[i]->name, "duration_time")) { stats = &walltime_nsecs_stats; @@ -762,16 +762,32 @@ static void generic_metric(struct perf_stat_config *config, if (!metric_events[i]) { const char *p = metric_expr; - if (expr__parse(&ratio, &pctx, &p) == 0) - print_metric(config, ctxp, NULL, "%8.1f", - metric_name ? - metric_name : - out->force_header ? name : "", - ratio); - else + if (expr__parse(&ratio, &pctx, &p) == 0) { + char *unit; + char metric_bf[64]; + + if (metric_unit && metric_name) { + if (perf_pmu__convert_scale(metric_unit, + &unit, &scale) >= 0) { + ratio *= scale; + } + + scnprintf(metric_bf, sizeof(metric_bf), + "%s %s", unit, metric_name); + print_metric(config, ctxp, NULL, "%8.1f", + metric_bf, ratio); + } else { + print_metric(config, ctxp, NULL, "%8.1f", + metric_name ? + metric_name : + out->force_header ? name : "", + ratio); + } + } else { print_metric(config, ctxp, NULL, NULL, out->force_header ? (metric_name ? metric_name : name) : "", 0); + } } else print_metric(config, ctxp, NULL, NULL, "", 0); @@ -992,7 +1008,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config, print_metric(config, ctxp, NULL, NULL, name, 0); } else if (evsel->metric_expr) { generic_metric(config, evsel->metric_expr, evsel->metric_events, evsel->name, - evsel->metric_name, avg, cpu, out, st); + evsel->metric_name, NULL, avg, cpu, out, st); } else if (runtime_stat_n(st, STAT_NSECS, 0, cpu) != 0) { char unit = 'M'; char unit_buf[10]; @@ -1021,7 +1037,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config, out->new_line(config, ctxp); generic_metric(config, mexp->metric_expr, mexp->metric_events, evsel->name, mexp->metric_name, - avg, cpu, out, st); + mexp->metric_unit, avg, cpu, out, st); } } if (num == 0) -- cgit v1.2.3-59-g8ed1b From f01642e4912bb80a01d693f4cc6fb0897207a090 Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Wed, 28 Aug 2019 13:59:32 +0800 Subject: perf metricgroup: Support multiple events for metricgroup Some uncore metrics don't work as expected. For example, on cascadelakex: root@lkp-csl-2sp2:~# perf stat -M UNC_M_PMM_BANDWIDTH.TOTAL -a -- sleep 1 Performance counter stats for 'system wide': 1841092 unc_m_pmm_rpq_inserts 3680816 unc_m_pmm_wpq_inserts 1.001775055 seconds time elapsed root@lkp-csl-2sp2:~# perf stat -M UNC_M_PMM_READ_LATENCY -a -- sleep 1 Performance counter stats for 'system wide': 860649746 unc_m_pmm_rpq_occupancy.all 1840557 unc_m_pmm_rpq_inserts 12790627455 unc_m_clockticks 1.001773348 seconds time elapsed No metrics 'UNC_M_PMM_BANDWIDTH.TOTAL' or 'UNC_M_PMM_READ_LATENCY' are reported. The issue is, the case of an alias expanding to mulitple events is not supported, typically the uncore events. (see comments in find_evsel_group()). For UNC_M_PMM_BANDWIDTH.TOTAL in above example, the expanded event group is '{unc_m_pmm_rpq_inserts,unc_m_pmm_wpq_inserts}:W', but the actual events passed to find_evsel_group are: unc_m_pmm_rpq_inserts unc_m_pmm_rpq_inserts unc_m_pmm_rpq_inserts unc_m_pmm_rpq_inserts unc_m_pmm_rpq_inserts unc_m_pmm_rpq_inserts unc_m_pmm_wpq_inserts unc_m_pmm_wpq_inserts unc_m_pmm_wpq_inserts unc_m_pmm_wpq_inserts unc_m_pmm_wpq_inserts unc_m_pmm_wpq_inserts For this multiple events case, it's not supported well. This patch introduces a new field 'metric_leader' in struct evsel. The first event is considered as a metric leader. For the rest of same events, they point to the first event via it's metric_leader field in struct evsel. This design is for adding the counting results of all same events to the first event in group (the metric_leader). With this patch, root@lkp-csl-2sp2:~# perf stat -M UNC_M_PMM_BANDWIDTH.TOTAL -a -- sleep 1 Performance counter stats for 'system wide': 1842108 unc_m_pmm_rpq_inserts # 337.2 MB/sec UNC_M_PMM_BANDWIDTH.TOTAL 3682209 unc_m_pmm_wpq_inserts 1.001819706 seconds time elapsed root@lkp-csl-2sp2:~# perf stat -M UNC_M_PMM_READ_LATENCY -a -- sleep 1 Performance counter stats for 'system wide': 861970685 unc_m_pmm_rpq_occupancy.all # 219.4 ns UNC_M_PMM_READ_LATENCY 1842772 unc_m_pmm_rpq_inserts 12790196356 unc_m_clockticks 1.001749103 seconds time elapsed Now we can see the correct metrics 'UNC_M_PMM_BANDWIDTH.TOTAL' and 'UNC_M_PMM_READ_LATENCY'. Signed-off-by: Jin Yao Cc: Alexander Shishkin Cc: Andi Kleen Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190828055932.8269-5-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.h | 1 + tools/perf/util/metricgroup.c | 84 ++++++++++++++++++++++--------------------- tools/perf/util/stat-shadow.c | 27 +++++++++++--- 3 files changed, 68 insertions(+), 44 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index fd60caced4fc..68321d10eb2d 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -168,6 +168,7 @@ struct evsel { const char * metric_expr; const char * metric_name; struct evsel **metric_events; + struct evsel *metric_leader; bool collect_stat; bool weak_group; bool percore; diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index f474a29f1b69..a7c0424dbda3 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -90,57 +90,61 @@ struct egroup { const char *metric_unit; }; -static bool record_evsel(int *ind, struct evsel **start, - int idnum, - struct evsel **metric_events, - struct evsel *ev) -{ - metric_events[*ind] = ev; - if (*ind == 0) - *start = ev; - if (++*ind == idnum) { - metric_events[*ind] = NULL; - return true; - } - return false; -} - static struct evsel *find_evsel_group(struct evlist *perf_evlist, const char **ids, int idnum, struct evsel **metric_events) { - struct evsel *ev, *start = NULL; - int ind = 0; + struct evsel *ev; + int i = 0; + bool leader_found; evlist__for_each_entry (perf_evlist, ev) { - if (ev->collect_stat) - continue; - if (!strcmp(ev->name, ids[ind])) { - if (record_evsel(&ind, &start, idnum, - metric_events, ev)) - return start; + if (!strcmp(ev->name, ids[i])) { + if (!metric_events[i]) + metric_events[i] = ev; } else { - /* - * We saw some other event that is not - * in our list of events. Discard - * the whole match and start again. - */ - ind = 0; - start = NULL; - if (!strcmp(ev->name, ids[ind])) { - if (record_evsel(&ind, &start, idnum, - metric_events, ev)) - return start; + if (++i == idnum) { + /* Discard the whole match and start again */ + i = 0; + memset(metric_events, 0, + sizeof(struct evsel *) * idnum); + continue; + } + + if (!strcmp(ev->name, ids[i])) + metric_events[i] = ev; + else { + /* Discard the whole match and start again */ + i = 0; + memset(metric_events, 0, + sizeof(struct evsel *) * idnum); + continue; } } } - /* - * This can happen when an alias expands to multiple - * events, like for uncore events. - * We don't support this case for now. - */ - return NULL; + + if (i != idnum - 1) { + /* Not whole match */ + return NULL; + } + + metric_events[idnum] = NULL; + + for (i = 0; i < idnum; i++) { + leader_found = false; + evlist__for_each_entry(perf_evlist, ev) { + if (!leader_found && (ev == metric_events[i])) + leader_found = true; + + if (leader_found && + !strcmp(ev->name, metric_events[i]->name)) { + ev->metric_leader = metric_events[i]; + } + } + } + + return metric_events[0]; } static int metricgroup__setup_events(struct list_head *groups, diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index 696d263f6eb6..70c87fdb2a43 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -31,6 +31,8 @@ struct saved_value { int cpu; struct runtime_stat *stat; struct stats stats; + u64 metric_total; + int metric_other; }; static int saved_value_cmp(struct rb_node *rb_node, const void *entry) @@ -212,6 +214,7 @@ void perf_stat__update_shadow_stats(struct evsel *counter, u64 count, { int ctx = evsel_context(counter); u64 count_ns = count; + struct saved_value *v; count *= counter->scale; @@ -266,9 +269,15 @@ void perf_stat__update_shadow_stats(struct evsel *counter, u64 count, update_runtime_stat(st, STAT_APERF, ctx, cpu, count); if (counter->collect_stat) { - struct saved_value *v = saved_value_lookup(counter, cpu, true, - STAT_NONE, 0, st); + v = saved_value_lookup(counter, cpu, true, STAT_NONE, 0, st); update_stats(&v->stats, count); + if (counter->metric_leader) + v->metric_total += count; + } else if (counter->metric_leader) { + v = saved_value_lookup(counter->metric_leader, + cpu, true, STAT_NONE, 0, st); + v->metric_total += count; + v->metric_other++; } } @@ -729,10 +738,10 @@ static void generic_metric(struct perf_stat_config *config, char *n, *pn; expr__ctx_init(&pctx); - expr__add_id(&pctx, name, avg); for (i = 0; metric_events[i]; i++) { struct saved_value *v; struct stats *stats; + u64 metric_total = 0; if (!strcmp(metric_events[i]->name, "duration_time")) { stats = &walltime_nsecs_stats; @@ -744,6 +753,9 @@ static void generic_metric(struct perf_stat_config *config, break; stats = &v->stats; scale = 1.0; + + if (v->metric_other) + metric_total = v->metric_total; } n = strdup(metric_events[i]->name); @@ -757,8 +769,15 @@ static void generic_metric(struct perf_stat_config *config, pn = strchr(n, ' '); if (pn) *pn = 0; - expr__add_id(&pctx, n, avg_stats(stats)*scale); + + if (metric_total) + expr__add_id(&pctx, n, metric_total); + else + expr__add_id(&pctx, n, avg_stats(stats)*scale); } + + expr__add_id(&pctx, name, avg); + if (!metric_events[i]) { const char *p = metric_expr; -- cgit v1.2.3-59-g8ed1b From d046b725487a97a3a3b35a00e84ca093963b8b4e Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 29 Aug 2019 17:41:18 -0500 Subject: objtool: Move x86 insn decoder to a common location The kernel tree has three identical copies of the x86 instruction decoder. Two of them are in the tools subdir. The tools subdir is supposed to be completely standalone and separate from the kernel. So having at least one copy of the kernel decoder in the tools subdir is unavoidable. However, we don't need *two* of them. Move objtool's copy of the decoder to a shared location, so that perf will also be able to use it. Signed-off-by: Josh Poimboeuf Reviewed-by: Masami Hiramatsu Acked-by: Peter Zijlstra (Intel) Cc: Adrian Hunter Cc: Jiri Olsa Cc: x86@kernel.org Link: http://lore.kernel.org/lkml/55b486b88f6bcd0c9a2a04b34f964860c8390ca8.1567118001.git.jpoimboe@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/x86/include/asm/inat.h | 230 +++++ tools/arch/x86/include/asm/inat_types.h | 15 + tools/arch/x86/include/asm/insn.h | 216 ++++ tools/arch/x86/include/asm/orc_types.h | 97 ++ tools/arch/x86/lib/inat.c | 83 ++ tools/arch/x86/lib/insn.c | 593 +++++++++++ tools/arch/x86/lib/x86-opcode-map.txt | 1072 ++++++++++++++++++++ tools/arch/x86/tools/gen-insn-attr-x86.awk | 393 +++++++ tools/objtool/Makefile | 4 +- tools/objtool/arch/x86/Build | 4 +- tools/objtool/arch/x86/decode.c | 4 +- tools/objtool/arch/x86/include/asm/inat.h | 230 ----- tools/objtool/arch/x86/include/asm/inat_types.h | 15 - tools/objtool/arch/x86/include/asm/insn.h | 216 ---- tools/objtool/arch/x86/include/asm/orc_types.h | 97 -- tools/objtool/arch/x86/lib/inat.c | 83 -- tools/objtool/arch/x86/lib/insn.c | 593 ----------- tools/objtool/arch/x86/lib/x86-opcode-map.txt | 1072 -------------------- tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk | 393 ------- tools/objtool/sync-check.sh | 12 +- 20 files changed, 2711 insertions(+), 2711 deletions(-) create mode 100644 tools/arch/x86/include/asm/inat.h create mode 100644 tools/arch/x86/include/asm/inat_types.h create mode 100644 tools/arch/x86/include/asm/insn.h create mode 100644 tools/arch/x86/include/asm/orc_types.h create mode 100644 tools/arch/x86/lib/inat.c create mode 100644 tools/arch/x86/lib/insn.c create mode 100644 tools/arch/x86/lib/x86-opcode-map.txt create mode 100644 tools/arch/x86/tools/gen-insn-attr-x86.awk delete mode 100644 tools/objtool/arch/x86/include/asm/inat.h delete mode 100644 tools/objtool/arch/x86/include/asm/inat_types.h delete mode 100644 tools/objtool/arch/x86/include/asm/insn.h delete mode 100644 tools/objtool/arch/x86/include/asm/orc_types.h delete mode 100644 tools/objtool/arch/x86/lib/inat.c delete mode 100644 tools/objtool/arch/x86/lib/insn.c delete mode 100644 tools/objtool/arch/x86/lib/x86-opcode-map.txt delete mode 100644 tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk (limited to 'tools') diff --git a/tools/arch/x86/include/asm/inat.h b/tools/arch/x86/include/asm/inat.h new file mode 100644 index 000000000000..4cf2ad521f65 --- /dev/null +++ b/tools/arch/x86/include/asm/inat.h @@ -0,0 +1,230 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _ASM_X86_INAT_H +#define _ASM_X86_INAT_H +/* + * x86 instruction attributes + * + * Written by Masami Hiramatsu + */ +#include + +/* + * Internal bits. Don't use bitmasks directly, because these bits are + * unstable. You should use checking functions. + */ + +#define INAT_OPCODE_TABLE_SIZE 256 +#define INAT_GROUP_TABLE_SIZE 8 + +/* Legacy last prefixes */ +#define INAT_PFX_OPNDSZ 1 /* 0x66 */ /* LPFX1 */ +#define INAT_PFX_REPE 2 /* 0xF3 */ /* LPFX2 */ +#define INAT_PFX_REPNE 3 /* 0xF2 */ /* LPFX3 */ +/* Other Legacy prefixes */ +#define INAT_PFX_LOCK 4 /* 0xF0 */ +#define INAT_PFX_CS 5 /* 0x2E */ +#define INAT_PFX_DS 6 /* 0x3E */ +#define INAT_PFX_ES 7 /* 0x26 */ +#define INAT_PFX_FS 8 /* 0x64 */ +#define INAT_PFX_GS 9 /* 0x65 */ +#define INAT_PFX_SS 10 /* 0x36 */ +#define INAT_PFX_ADDRSZ 11 /* 0x67 */ +/* x86-64 REX prefix */ +#define INAT_PFX_REX 12 /* 0x4X */ +/* AVX VEX prefixes */ +#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */ +#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */ +#define INAT_PFX_EVEX 15 /* EVEX prefix */ + +#define INAT_LSTPFX_MAX 3 +#define INAT_LGCPFX_MAX 11 + +/* Immediate size */ +#define INAT_IMM_BYTE 1 +#define INAT_IMM_WORD 2 +#define INAT_IMM_DWORD 3 +#define INAT_IMM_QWORD 4 +#define INAT_IMM_PTR 5 +#define INAT_IMM_VWORD32 6 +#define INAT_IMM_VWORD 7 + +/* Legacy prefix */ +#define INAT_PFX_OFFS 0 +#define INAT_PFX_BITS 4 +#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1) +#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS) +/* Escape opcodes */ +#define INAT_ESC_OFFS (INAT_PFX_OFFS + INAT_PFX_BITS) +#define INAT_ESC_BITS 2 +#define INAT_ESC_MAX ((1 << INAT_ESC_BITS) - 1) +#define INAT_ESC_MASK (INAT_ESC_MAX << INAT_ESC_OFFS) +/* Group opcodes (1-16) */ +#define INAT_GRP_OFFS (INAT_ESC_OFFS + INAT_ESC_BITS) +#define INAT_GRP_BITS 5 +#define INAT_GRP_MAX ((1 << INAT_GRP_BITS) - 1) +#define INAT_GRP_MASK (INAT_GRP_MAX << INAT_GRP_OFFS) +/* Immediates */ +#define INAT_IMM_OFFS (INAT_GRP_OFFS + INAT_GRP_BITS) +#define INAT_IMM_BITS 3 +#define INAT_IMM_MASK (((1 << INAT_IMM_BITS) - 1) << INAT_IMM_OFFS) +/* Flags */ +#define INAT_FLAG_OFFS (INAT_IMM_OFFS + INAT_IMM_BITS) +#define INAT_MODRM (1 << (INAT_FLAG_OFFS)) +#define INAT_FORCE64 (1 << (INAT_FLAG_OFFS + 1)) +#define INAT_SCNDIMM (1 << (INAT_FLAG_OFFS + 2)) +#define INAT_MOFFSET (1 << (INAT_FLAG_OFFS + 3)) +#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4)) +#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5)) +#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6)) +#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7)) +/* Attribute making macros for attribute tables */ +#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS) +#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS) +#define INAT_MAKE_GROUP(grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM) +#define INAT_MAKE_IMM(imm) (imm << INAT_IMM_OFFS) + +/* Identifiers for segment registers */ +#define INAT_SEG_REG_IGNORE 0 +#define INAT_SEG_REG_DEFAULT 1 +#define INAT_SEG_REG_CS 2 +#define INAT_SEG_REG_SS 3 +#define INAT_SEG_REG_DS 4 +#define INAT_SEG_REG_ES 5 +#define INAT_SEG_REG_FS 6 +#define INAT_SEG_REG_GS 7 + +/* Attribute search APIs */ +extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode); +extern int inat_get_last_prefix_id(insn_byte_t last_pfx); +extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, + int lpfx_id, + insn_attr_t esc_attr); +extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm, + int lpfx_id, + insn_attr_t esc_attr); +extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, + insn_byte_t vex_m, + insn_byte_t vex_pp); + +/* Attribute checking functions */ +static inline int inat_is_legacy_prefix(insn_attr_t attr) +{ + attr &= INAT_PFX_MASK; + return attr && attr <= INAT_LGCPFX_MAX; +} + +static inline int inat_is_address_size_prefix(insn_attr_t attr) +{ + return (attr & INAT_PFX_MASK) == INAT_PFX_ADDRSZ; +} + +static inline int inat_is_operand_size_prefix(insn_attr_t attr) +{ + return (attr & INAT_PFX_MASK) == INAT_PFX_OPNDSZ; +} + +static inline int inat_is_rex_prefix(insn_attr_t attr) +{ + return (attr & INAT_PFX_MASK) == INAT_PFX_REX; +} + +static inline int inat_last_prefix_id(insn_attr_t attr) +{ + if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX) + return 0; + else + return attr & INAT_PFX_MASK; +} + +static inline int inat_is_vex_prefix(insn_attr_t attr) +{ + attr &= INAT_PFX_MASK; + return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 || + attr == INAT_PFX_EVEX; +} + +static inline int inat_is_evex_prefix(insn_attr_t attr) +{ + return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX; +} + +static inline int inat_is_vex3_prefix(insn_attr_t attr) +{ + return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3; +} + +static inline int inat_is_escape(insn_attr_t attr) +{ + return attr & INAT_ESC_MASK; +} + +static inline int inat_escape_id(insn_attr_t attr) +{ + return (attr & INAT_ESC_MASK) >> INAT_ESC_OFFS; +} + +static inline int inat_is_group(insn_attr_t attr) +{ + return attr & INAT_GRP_MASK; +} + +static inline int inat_group_id(insn_attr_t attr) +{ + return (attr & INAT_GRP_MASK) >> INAT_GRP_OFFS; +} + +static inline int inat_group_common_attribute(insn_attr_t attr) +{ + return attr & ~INAT_GRP_MASK; +} + +static inline int inat_has_immediate(insn_attr_t attr) +{ + return attr & INAT_IMM_MASK; +} + +static inline int inat_immediate_size(insn_attr_t attr) +{ + return (attr & INAT_IMM_MASK) >> INAT_IMM_OFFS; +} + +static inline int inat_has_modrm(insn_attr_t attr) +{ + return attr & INAT_MODRM; +} + +static inline int inat_is_force64(insn_attr_t attr) +{ + return attr & INAT_FORCE64; +} + +static inline int inat_has_second_immediate(insn_attr_t attr) +{ + return attr & INAT_SCNDIMM; +} + +static inline int inat_has_moffset(insn_attr_t attr) +{ + return attr & INAT_MOFFSET; +} + +static inline int inat_has_variant(insn_attr_t attr) +{ + return attr & INAT_VARIANT; +} + +static inline int inat_accept_vex(insn_attr_t attr) +{ + return attr & INAT_VEXOK; +} + +static inline int inat_must_vex(insn_attr_t attr) +{ + return attr & (INAT_VEXONLY | INAT_EVEXONLY); +} + +static inline int inat_must_evex(insn_attr_t attr) +{ + return attr & INAT_EVEXONLY; +} +#endif diff --git a/tools/arch/x86/include/asm/inat_types.h b/tools/arch/x86/include/asm/inat_types.h new file mode 100644 index 000000000000..b047efa9ddc2 --- /dev/null +++ b/tools/arch/x86/include/asm/inat_types.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _ASM_X86_INAT_TYPES_H +#define _ASM_X86_INAT_TYPES_H +/* + * x86 instruction attributes + * + * Written by Masami Hiramatsu + */ + +/* Instruction attributes */ +typedef unsigned int insn_attr_t; +typedef unsigned char insn_byte_t; +typedef signed int insn_value_t; + +#endif diff --git a/tools/arch/x86/include/asm/insn.h b/tools/arch/x86/include/asm/insn.h new file mode 100644 index 000000000000..154f27be8bfc --- /dev/null +++ b/tools/arch/x86/include/asm/insn.h @@ -0,0 +1,216 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _ASM_X86_INSN_H +#define _ASM_X86_INSN_H +/* + * x86 instruction analysis + * + * Copyright (C) IBM Corporation, 2009 + */ + +/* insn_attr_t is defined in inat.h */ +#include + +struct insn_field { + union { + insn_value_t value; + insn_byte_t bytes[4]; + }; + /* !0 if we've run insn_get_xxx() for this field */ + unsigned char got; + unsigned char nbytes; +}; + +struct insn { + struct insn_field prefixes; /* + * Prefixes + * prefixes.bytes[3]: last prefix + */ + struct insn_field rex_prefix; /* REX prefix */ + struct insn_field vex_prefix; /* VEX prefix */ + struct insn_field opcode; /* + * opcode.bytes[0]: opcode1 + * opcode.bytes[1]: opcode2 + * opcode.bytes[2]: opcode3 + */ + struct insn_field modrm; + struct insn_field sib; + struct insn_field displacement; + union { + struct insn_field immediate; + struct insn_field moffset1; /* for 64bit MOV */ + struct insn_field immediate1; /* for 64bit imm or off16/32 */ + }; + union { + struct insn_field moffset2; /* for 64bit MOV */ + struct insn_field immediate2; /* for 64bit imm or seg16 */ + }; + + insn_attr_t attr; + unsigned char opnd_bytes; + unsigned char addr_bytes; + unsigned char length; + unsigned char x86_64; + + const insn_byte_t *kaddr; /* kernel address of insn to analyze */ + const insn_byte_t *end_kaddr; /* kernel address of last insn in buffer */ + const insn_byte_t *next_byte; +}; + +#define MAX_INSN_SIZE 15 + +#define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6) +#define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3) +#define X86_MODRM_RM(modrm) ((modrm) & 0x07) + +#define X86_SIB_SCALE(sib) (((sib) & 0xc0) >> 6) +#define X86_SIB_INDEX(sib) (((sib) & 0x38) >> 3) +#define X86_SIB_BASE(sib) ((sib) & 0x07) + +#define X86_REX_W(rex) ((rex) & 8) +#define X86_REX_R(rex) ((rex) & 4) +#define X86_REX_X(rex) ((rex) & 2) +#define X86_REX_B(rex) ((rex) & 1) + +/* VEX bit flags */ +#define X86_VEX_W(vex) ((vex) & 0x80) /* VEX3 Byte2 */ +#define X86_VEX_R(vex) ((vex) & 0x80) /* VEX2/3 Byte1 */ +#define X86_VEX_X(vex) ((vex) & 0x40) /* VEX3 Byte1 */ +#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */ +#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */ +/* VEX bit fields */ +#define X86_EVEX_M(vex) ((vex) & 0x03) /* EVEX Byte1 */ +#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */ +#define X86_VEX2_M 1 /* VEX2.M always 1 */ +#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */ +#define X86_VEX_P(vex) ((vex) & 0x03) /* VEX3 Byte2, VEX2 Byte1 */ +#define X86_VEX_M_MAX 0x1f /* VEX3.M Maximum value */ + +extern void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64); +extern void insn_get_prefixes(struct insn *insn); +extern void insn_get_opcode(struct insn *insn); +extern void insn_get_modrm(struct insn *insn); +extern void insn_get_sib(struct insn *insn); +extern void insn_get_displacement(struct insn *insn); +extern void insn_get_immediate(struct insn *insn); +extern void insn_get_length(struct insn *insn); + +/* Attribute will be determined after getting ModRM (for opcode groups) */ +static inline void insn_get_attribute(struct insn *insn) +{ + insn_get_modrm(insn); +} + +/* Instruction uses RIP-relative addressing */ +extern int insn_rip_relative(struct insn *insn); + +/* Init insn for kernel text */ +static inline void kernel_insn_init(struct insn *insn, + const void *kaddr, int buf_len) +{ +#ifdef CONFIG_X86_64 + insn_init(insn, kaddr, buf_len, 1); +#else /* CONFIG_X86_32 */ + insn_init(insn, kaddr, buf_len, 0); +#endif +} + +static inline int insn_is_avx(struct insn *insn) +{ + if (!insn->prefixes.got) + insn_get_prefixes(insn); + return (insn->vex_prefix.value != 0); +} + +static inline int insn_is_evex(struct insn *insn) +{ + if (!insn->prefixes.got) + insn_get_prefixes(insn); + return (insn->vex_prefix.nbytes == 4); +} + +/* Ensure this instruction is decoded completely */ +static inline int insn_complete(struct insn *insn) +{ + return insn->opcode.got && insn->modrm.got && insn->sib.got && + insn->displacement.got && insn->immediate.got; +} + +static inline insn_byte_t insn_vex_m_bits(struct insn *insn) +{ + if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */ + return X86_VEX2_M; + else if (insn->vex_prefix.nbytes == 3) /* 3 bytes VEX */ + return X86_VEX3_M(insn->vex_prefix.bytes[1]); + else /* EVEX */ + return X86_EVEX_M(insn->vex_prefix.bytes[1]); +} + +static inline insn_byte_t insn_vex_p_bits(struct insn *insn) +{ + if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */ + return X86_VEX_P(insn->vex_prefix.bytes[1]); + else + return X86_VEX_P(insn->vex_prefix.bytes[2]); +} + +/* Get the last prefix id from last prefix or VEX prefix */ +static inline int insn_last_prefix_id(struct insn *insn) +{ + if (insn_is_avx(insn)) + return insn_vex_p_bits(insn); /* VEX_p is a SIMD prefix id */ + + if (insn->prefixes.bytes[3]) + return inat_get_last_prefix_id(insn->prefixes.bytes[3]); + + return 0; +} + +/* Offset of each field from kaddr */ +static inline int insn_offset_rex_prefix(struct insn *insn) +{ + return insn->prefixes.nbytes; +} +static inline int insn_offset_vex_prefix(struct insn *insn) +{ + return insn_offset_rex_prefix(insn) + insn->rex_prefix.nbytes; +} +static inline int insn_offset_opcode(struct insn *insn) +{ + return insn_offset_vex_prefix(insn) + insn->vex_prefix.nbytes; +} +static inline int insn_offset_modrm(struct insn *insn) +{ + return insn_offset_opcode(insn) + insn->opcode.nbytes; +} +static inline int insn_offset_sib(struct insn *insn) +{ + return insn_offset_modrm(insn) + insn->modrm.nbytes; +} +static inline int insn_offset_displacement(struct insn *insn) +{ + return insn_offset_sib(insn) + insn->sib.nbytes; +} +static inline int insn_offset_immediate(struct insn *insn) +{ + return insn_offset_displacement(insn) + insn->displacement.nbytes; +} + +#define POP_SS_OPCODE 0x1f +#define MOV_SREG_OPCODE 0x8e + +/* + * Intel SDM Vol.3A 6.8.3 states; + * "Any single-step trap that would be delivered following the MOV to SS + * instruction or POP to SS instruction (because EFLAGS.TF is 1) is + * suppressed." + * This function returns true if @insn is MOV SS or POP SS. On these + * instructions, single stepping is suppressed. + */ +static inline int insn_masking_exception(struct insn *insn) +{ + return insn->opcode.bytes[0] == POP_SS_OPCODE || + (insn->opcode.bytes[0] == MOV_SREG_OPCODE && + X86_MODRM_REG(insn->modrm.bytes[0]) == 2); +} + +#endif /* _ASM_X86_INSN_H */ diff --git a/tools/arch/x86/include/asm/orc_types.h b/tools/arch/x86/include/asm/orc_types.h new file mode 100644 index 000000000000..6e060907c163 --- /dev/null +++ b/tools/arch/x86/include/asm/orc_types.h @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2017 Josh Poimboeuf + */ + +#ifndef _ORC_TYPES_H +#define _ORC_TYPES_H + +#include +#include + +/* + * The ORC_REG_* registers are base registers which are used to find other + * registers on the stack. + * + * ORC_REG_PREV_SP, also known as DWARF Call Frame Address (CFA), is the + * address of the previous frame: the caller's SP before it called the current + * function. + * + * ORC_REG_UNDEFINED means the corresponding register's value didn't change in + * the current frame. + * + * The most commonly used base registers are SP and BP -- which the previous SP + * is usually based on -- and PREV_SP and UNDEFINED -- which the previous BP is + * usually based on. + * + * The rest of the base registers are needed for special cases like entry code + * and GCC realigned stacks. + */ +#define ORC_REG_UNDEFINED 0 +#define ORC_REG_PREV_SP 1 +#define ORC_REG_DX 2 +#define ORC_REG_DI 3 +#define ORC_REG_BP 4 +#define ORC_REG_SP 5 +#define ORC_REG_R10 6 +#define ORC_REG_R13 7 +#define ORC_REG_BP_INDIRECT 8 +#define ORC_REG_SP_INDIRECT 9 +#define ORC_REG_MAX 15 + +/* + * ORC_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP (the + * caller's SP right before it made the call). Used for all callable + * functions, i.e. all C code and all callable asm functions. + * + * ORC_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset points + * to a fully populated pt_regs from a syscall, interrupt, or exception. + * + * ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset + * points to the iret return frame. + * + * The UNWIND_HINT macros are used only for the unwind_hint struct. They + * aren't used in struct orc_entry due to size and complexity constraints. + * Objtool converts them to real types when it converts the hints to orc + * entries. + */ +#define ORC_TYPE_CALL 0 +#define ORC_TYPE_REGS 1 +#define ORC_TYPE_REGS_IRET 2 +#define UNWIND_HINT_TYPE_SAVE 3 +#define UNWIND_HINT_TYPE_RESTORE 4 + +#ifndef __ASSEMBLY__ +/* + * This struct is more or less a vastly simplified version of the DWARF Call + * Frame Information standard. It contains only the necessary parts of DWARF + * CFI, simplified for ease of access by the in-kernel unwinder. It tells the + * unwinder how to find the previous SP and BP (and sometimes entry regs) on + * the stack for a given code address. Each instance of the struct corresponds + * to one or more code locations. + */ +struct orc_entry { + s16 sp_offset; + s16 bp_offset; + unsigned sp_reg:4; + unsigned bp_reg:4; + unsigned type:2; + unsigned end:1; +} __packed; + +/* + * This struct is used by asm and inline asm code to manually annotate the + * location of registers on the stack for the ORC unwinder. + * + * Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*. + */ +struct unwind_hint { + u32 ip; + s16 sp_offset; + u8 sp_reg; + u8 type; + u8 end; +}; +#endif /* __ASSEMBLY__ */ + +#endif /* _ORC_TYPES_H */ diff --git a/tools/arch/x86/lib/inat.c b/tools/arch/x86/lib/inat.c new file mode 100644 index 000000000000..12539fca75c4 --- /dev/null +++ b/tools/arch/x86/lib/inat.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * x86 instruction attribute tables + * + * Written by Masami Hiramatsu + */ +#include + +/* Attribute tables are generated from opcode map */ +#include "inat-tables.c" + +/* Attribute search APIs */ +insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode) +{ + return inat_primary_table[opcode]; +} + +int inat_get_last_prefix_id(insn_byte_t last_pfx) +{ + insn_attr_t lpfx_attr; + + lpfx_attr = inat_get_opcode_attribute(last_pfx); + return inat_last_prefix_id(lpfx_attr); +} + +insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, int lpfx_id, + insn_attr_t esc_attr) +{ + const insn_attr_t *table; + int n; + + n = inat_escape_id(esc_attr); + + table = inat_escape_tables[n][0]; + if (!table) + return 0; + if (inat_has_variant(table[opcode]) && lpfx_id) { + table = inat_escape_tables[n][lpfx_id]; + if (!table) + return 0; + } + return table[opcode]; +} + +insn_attr_t inat_get_group_attribute(insn_byte_t modrm, int lpfx_id, + insn_attr_t grp_attr) +{ + const insn_attr_t *table; + int n; + + n = inat_group_id(grp_attr); + + table = inat_group_tables[n][0]; + if (!table) + return inat_group_common_attribute(grp_attr); + if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && lpfx_id) { + table = inat_group_tables[n][lpfx_id]; + if (!table) + return inat_group_common_attribute(grp_attr); + } + return table[X86_MODRM_REG(modrm)] | + inat_group_common_attribute(grp_attr); +} + +insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m, + insn_byte_t vex_p) +{ + const insn_attr_t *table; + if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX) + return 0; + /* At first, this checks the master table */ + table = inat_avx_tables[vex_m][0]; + if (!table) + return 0; + if (!inat_is_group(table[opcode]) && vex_p) { + /* If this is not a group, get attribute directly */ + table = inat_avx_tables[vex_m][vex_p]; + if (!table) + return 0; + } + return table[opcode]; +} + diff --git a/tools/arch/x86/lib/insn.c b/tools/arch/x86/lib/insn.c new file mode 100644 index 000000000000..0b5862ba6a75 --- /dev/null +++ b/tools/arch/x86/lib/insn.c @@ -0,0 +1,593 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * x86 instruction analysis + * + * Copyright (C) IBM Corporation, 2002, 2004, 2009 + */ + +#ifdef __KERNEL__ +#include +#else +#include +#endif +#include +#include + +/* Verify next sizeof(t) bytes can be on the same instruction */ +#define validate_next(t, insn, n) \ + ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr) + +#define __get_next(t, insn) \ + ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; }) + +#define __peek_nbyte_next(t, insn, n) \ + ({ t r = *(t*)((insn)->next_byte + n); r; }) + +#define get_next(t, insn) \ + ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); }) + +#define peek_nbyte_next(t, insn, n) \ + ({ if (unlikely(!validate_next(t, insn, n))) goto err_out; __peek_nbyte_next(t, insn, n); }) + +#define peek_next(t, insn) peek_nbyte_next(t, insn, 0) + +/** + * insn_init() - initialize struct insn + * @insn: &struct insn to be initialized + * @kaddr: address (in kernel memory) of instruction (or copy thereof) + * @x86_64: !0 for 64-bit kernel or 64-bit app + */ +void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64) +{ + /* + * Instructions longer than MAX_INSN_SIZE (15 bytes) are invalid + * even if the input buffer is long enough to hold them. + */ + if (buf_len > MAX_INSN_SIZE) + buf_len = MAX_INSN_SIZE; + + memset(insn, 0, sizeof(*insn)); + insn->kaddr = kaddr; + insn->end_kaddr = kaddr + buf_len; + insn->next_byte = kaddr; + insn->x86_64 = x86_64 ? 1 : 0; + insn->opnd_bytes = 4; + if (x86_64) + insn->addr_bytes = 8; + else + insn->addr_bytes = 4; +} + +/** + * insn_get_prefixes - scan x86 instruction prefix bytes + * @insn: &struct insn containing instruction + * + * Populates the @insn->prefixes bitmap, and updates @insn->next_byte + * to point to the (first) opcode. No effect if @insn->prefixes.got + * is already set. + */ +void insn_get_prefixes(struct insn *insn) +{ + struct insn_field *prefixes = &insn->prefixes; + insn_attr_t attr; + insn_byte_t b, lb; + int i, nb; + + if (prefixes->got) + return; + + nb = 0; + lb = 0; + b = peek_next(insn_byte_t, insn); + attr = inat_get_opcode_attribute(b); + while (inat_is_legacy_prefix(attr)) { + /* Skip if same prefix */ + for (i = 0; i < nb; i++) + if (prefixes->bytes[i] == b) + goto found; + if (nb == 4) + /* Invalid instruction */ + break; + prefixes->bytes[nb++] = b; + if (inat_is_address_size_prefix(attr)) { + /* address size switches 2/4 or 4/8 */ + if (insn->x86_64) + insn->addr_bytes ^= 12; + else + insn->addr_bytes ^= 6; + } else if (inat_is_operand_size_prefix(attr)) { + /* oprand size switches 2/4 */ + insn->opnd_bytes ^= 6; + } +found: + prefixes->nbytes++; + insn->next_byte++; + lb = b; + b = peek_next(insn_byte_t, insn); + attr = inat_get_opcode_attribute(b); + } + /* Set the last prefix */ + if (lb && lb != insn->prefixes.bytes[3]) { + if (unlikely(insn->prefixes.bytes[3])) { + /* Swap the last prefix */ + b = insn->prefixes.bytes[3]; + for (i = 0; i < nb; i++) + if (prefixes->bytes[i] == lb) + prefixes->bytes[i] = b; + } + insn->prefixes.bytes[3] = lb; + } + + /* Decode REX prefix */ + if (insn->x86_64) { + b = peek_next(insn_byte_t, insn); + attr = inat_get_opcode_attribute(b); + if (inat_is_rex_prefix(attr)) { + insn->rex_prefix.value = b; + insn->rex_prefix.nbytes = 1; + insn->next_byte++; + if (X86_REX_W(b)) + /* REX.W overrides opnd_size */ + insn->opnd_bytes = 8; + } + } + insn->rex_prefix.got = 1; + + /* Decode VEX prefix */ + b = peek_next(insn_byte_t, insn); + attr = inat_get_opcode_attribute(b); + if (inat_is_vex_prefix(attr)) { + insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1); + if (!insn->x86_64) { + /* + * In 32-bits mode, if the [7:6] bits (mod bits of + * ModRM) on the second byte are not 11b, it is + * LDS or LES or BOUND. + */ + if (X86_MODRM_MOD(b2) != 3) + goto vex_end; + } + insn->vex_prefix.bytes[0] = b; + insn->vex_prefix.bytes[1] = b2; + if (inat_is_evex_prefix(attr)) { + b2 = peek_nbyte_next(insn_byte_t, insn, 2); + insn->vex_prefix.bytes[2] = b2; + b2 = peek_nbyte_next(insn_byte_t, insn, 3); + insn->vex_prefix.bytes[3] = b2; + insn->vex_prefix.nbytes = 4; + insn->next_byte += 4; + if (insn->x86_64 && X86_VEX_W(b2)) + /* VEX.W overrides opnd_size */ + insn->opnd_bytes = 8; + } else if (inat_is_vex3_prefix(attr)) { + b2 = peek_nbyte_next(insn_byte_t, insn, 2); + insn->vex_prefix.bytes[2] = b2; + insn->vex_prefix.nbytes = 3; + insn->next_byte += 3; + if (insn->x86_64 && X86_VEX_W(b2)) + /* VEX.W overrides opnd_size */ + insn->opnd_bytes = 8; + } else { + /* + * For VEX2, fake VEX3-like byte#2. + * Makes it easier to decode vex.W, vex.vvvv, + * vex.L and vex.pp. Masking with 0x7f sets vex.W == 0. + */ + insn->vex_prefix.bytes[2] = b2 & 0x7f; + insn->vex_prefix.nbytes = 2; + insn->next_byte += 2; + } + } +vex_end: + insn->vex_prefix.got = 1; + + prefixes->got = 1; + +err_out: + return; +} + +/** + * insn_get_opcode - collect opcode(s) + * @insn: &struct insn containing instruction + * + * Populates @insn->opcode, updates @insn->next_byte to point past the + * opcode byte(s), and set @insn->attr (except for groups). + * If necessary, first collects any preceding (prefix) bytes. + * Sets @insn->opcode.value = opcode1. No effect if @insn->opcode.got + * is already 1. + */ +void insn_get_opcode(struct insn *insn) +{ + struct insn_field *opcode = &insn->opcode; + insn_byte_t op; + int pfx_id; + if (opcode->got) + return; + if (!insn->prefixes.got) + insn_get_prefixes(insn); + + /* Get first opcode */ + op = get_next(insn_byte_t, insn); + opcode->bytes[0] = op; + opcode->nbytes = 1; + + /* Check if there is VEX prefix or not */ + if (insn_is_avx(insn)) { + insn_byte_t m, p; + m = insn_vex_m_bits(insn); + p = insn_vex_p_bits(insn); + insn->attr = inat_get_avx_attribute(op, m, p); + if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) || + (!inat_accept_vex(insn->attr) && + !inat_is_group(insn->attr))) + insn->attr = 0; /* This instruction is bad */ + goto end; /* VEX has only 1 byte for opcode */ + } + + insn->attr = inat_get_opcode_attribute(op); + while (inat_is_escape(insn->attr)) { + /* Get escaped opcode */ + op = get_next(insn_byte_t, insn); + opcode->bytes[opcode->nbytes++] = op; + pfx_id = insn_last_prefix_id(insn); + insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr); + } + if (inat_must_vex(insn->attr)) + insn->attr = 0; /* This instruction is bad */ +end: + opcode->got = 1; + +err_out: + return; +} + +/** + * insn_get_modrm - collect ModRM byte, if any + * @insn: &struct insn containing instruction + * + * Populates @insn->modrm and updates @insn->next_byte to point past the + * ModRM byte, if any. If necessary, first collects the preceding bytes + * (prefixes and opcode(s)). No effect if @insn->modrm.got is already 1. + */ +void insn_get_modrm(struct insn *insn) +{ + struct insn_field *modrm = &insn->modrm; + insn_byte_t pfx_id, mod; + if (modrm->got) + return; + if (!insn->opcode.got) + insn_get_opcode(insn); + + if (inat_has_modrm(insn->attr)) { + mod = get_next(insn_byte_t, insn); + modrm->value = mod; + modrm->nbytes = 1; + if (inat_is_group(insn->attr)) { + pfx_id = insn_last_prefix_id(insn); + insn->attr = inat_get_group_attribute(mod, pfx_id, + insn->attr); + if (insn_is_avx(insn) && !inat_accept_vex(insn->attr)) + insn->attr = 0; /* This is bad */ + } + } + + if (insn->x86_64 && inat_is_force64(insn->attr)) + insn->opnd_bytes = 8; + modrm->got = 1; + +err_out: + return; +} + + +/** + * insn_rip_relative() - Does instruction use RIP-relative addressing mode? + * @insn: &struct insn containing instruction + * + * If necessary, first collects the instruction up to and including the + * ModRM byte. No effect if @insn->x86_64 is 0. + */ +int insn_rip_relative(struct insn *insn) +{ + struct insn_field *modrm = &insn->modrm; + + if (!insn->x86_64) + return 0; + if (!modrm->got) + insn_get_modrm(insn); + /* + * For rip-relative instructions, the mod field (top 2 bits) + * is zero and the r/m field (bottom 3 bits) is 0x5. + */ + return (modrm->nbytes && (modrm->value & 0xc7) == 0x5); +} + +/** + * insn_get_sib() - Get the SIB byte of instruction + * @insn: &struct insn containing instruction + * + * If necessary, first collects the instruction up to and including the + * ModRM byte. + */ +void insn_get_sib(struct insn *insn) +{ + insn_byte_t modrm; + + if (insn->sib.got) + return; + if (!insn->modrm.got) + insn_get_modrm(insn); + if (insn->modrm.nbytes) { + modrm = (insn_byte_t)insn->modrm.value; + if (insn->addr_bytes != 2 && + X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) { + insn->sib.value = get_next(insn_byte_t, insn); + insn->sib.nbytes = 1; + } + } + insn->sib.got = 1; + +err_out: + return; +} + + +/** + * insn_get_displacement() - Get the displacement of instruction + * @insn: &struct insn containing instruction + * + * If necessary, first collects the instruction up to and including the + * SIB byte. + * Displacement value is sign-expanded. + */ +void insn_get_displacement(struct insn *insn) +{ + insn_byte_t mod, rm, base; + + if (insn->displacement.got) + return; + if (!insn->sib.got) + insn_get_sib(insn); + if (insn->modrm.nbytes) { + /* + * Interpreting the modrm byte: + * mod = 00 - no displacement fields (exceptions below) + * mod = 01 - 1-byte displacement field + * mod = 10 - displacement field is 4 bytes, or 2 bytes if + * address size = 2 (0x67 prefix in 32-bit mode) + * mod = 11 - no memory operand + * + * If address size = 2... + * mod = 00, r/m = 110 - displacement field is 2 bytes + * + * If address size != 2... + * mod != 11, r/m = 100 - SIB byte exists + * mod = 00, SIB base = 101 - displacement field is 4 bytes + * mod = 00, r/m = 101 - rip-relative addressing, displacement + * field is 4 bytes + */ + mod = X86_MODRM_MOD(insn->modrm.value); + rm = X86_MODRM_RM(insn->modrm.value); + base = X86_SIB_BASE(insn->sib.value); + if (mod == 3) + goto out; + if (mod == 1) { + insn->displacement.value = get_next(signed char, insn); + insn->displacement.nbytes = 1; + } else if (insn->addr_bytes == 2) { + if ((mod == 0 && rm == 6) || mod == 2) { + insn->displacement.value = + get_next(short, insn); + insn->displacement.nbytes = 2; + } + } else { + if ((mod == 0 && rm == 5) || mod == 2 || + (mod == 0 && base == 5)) { + insn->displacement.value = get_next(int, insn); + insn->displacement.nbytes = 4; + } + } + } +out: + insn->displacement.got = 1; + +err_out: + return; +} + +/* Decode moffset16/32/64. Return 0 if failed */ +static int __get_moffset(struct insn *insn) +{ + switch (insn->addr_bytes) { + case 2: + insn->moffset1.value = get_next(short, insn); + insn->moffset1.nbytes = 2; + break; + case 4: + insn->moffset1.value = get_next(int, insn); + insn->moffset1.nbytes = 4; + break; + case 8: + insn->moffset1.value = get_next(int, insn); + insn->moffset1.nbytes = 4; + insn->moffset2.value = get_next(int, insn); + insn->moffset2.nbytes = 4; + break; + default: /* opnd_bytes must be modified manually */ + goto err_out; + } + insn->moffset1.got = insn->moffset2.got = 1; + + return 1; + +err_out: + return 0; +} + +/* Decode imm v32(Iz). Return 0 if failed */ +static int __get_immv32(struct insn *insn) +{ + switch (insn->opnd_bytes) { + case 2: + insn->immediate.value = get_next(short, insn); + insn->immediate.nbytes = 2; + break; + case 4: + case 8: + insn->immediate.value = get_next(int, insn); + insn->immediate.nbytes = 4; + break; + default: /* opnd_bytes must be modified manually */ + goto err_out; + } + + return 1; + +err_out: + return 0; +} + +/* Decode imm v64(Iv/Ov), Return 0 if failed */ +static int __get_immv(struct insn *insn) +{ + switch (insn->opnd_bytes) { + case 2: + insn->immediate1.value = get_next(short, insn); + insn->immediate1.nbytes = 2; + break; + case 4: + insn->immediate1.value = get_next(int, insn); + insn->immediate1.nbytes = 4; + break; + case 8: + insn->immediate1.value = get_next(int, insn); + insn->immediate1.nbytes = 4; + insn->immediate2.value = get_next(int, insn); + insn->immediate2.nbytes = 4; + break; + default: /* opnd_bytes must be modified manually */ + goto err_out; + } + insn->immediate1.got = insn->immediate2.got = 1; + + return 1; +err_out: + return 0; +} + +/* Decode ptr16:16/32(Ap) */ +static int __get_immptr(struct insn *insn) +{ + switch (insn->opnd_bytes) { + case 2: + insn->immediate1.value = get_next(short, insn); + insn->immediate1.nbytes = 2; + break; + case 4: + insn->immediate1.value = get_next(int, insn); + insn->immediate1.nbytes = 4; + break; + case 8: + /* ptr16:64 is not exist (no segment) */ + return 0; + default: /* opnd_bytes must be modified manually */ + goto err_out; + } + insn->immediate2.value = get_next(unsigned short, insn); + insn->immediate2.nbytes = 2; + insn->immediate1.got = insn->immediate2.got = 1; + + return 1; +err_out: + return 0; +} + +/** + * insn_get_immediate() - Get the immediates of instruction + * @insn: &struct insn containing instruction + * + * If necessary, first collects the instruction up to and including the + * displacement bytes. + * Basically, most of immediates are sign-expanded. Unsigned-value can be + * get by bit masking with ((1 << (nbytes * 8)) - 1) + */ +void insn_get_immediate(struct insn *insn) +{ + if (insn->immediate.got) + return; + if (!insn->displacement.got) + insn_get_displacement(insn); + + if (inat_has_moffset(insn->attr)) { + if (!__get_moffset(insn)) + goto err_out; + goto done; + } + + if (!inat_has_immediate(insn->attr)) + /* no immediates */ + goto done; + + switch (inat_immediate_size(insn->attr)) { + case INAT_IMM_BYTE: + insn->immediate.value = get_next(signed char, insn); + insn->immediate.nbytes = 1; + break; + case INAT_IMM_WORD: + insn->immediate.value = get_next(short, insn); + insn->immediate.nbytes = 2; + break; + case INAT_IMM_DWORD: + insn->immediate.value = get_next(int, insn); + insn->immediate.nbytes = 4; + break; + case INAT_IMM_QWORD: + insn->immediate1.value = get_next(int, insn); + insn->immediate1.nbytes = 4; + insn->immediate2.value = get_next(int, insn); + insn->immediate2.nbytes = 4; + break; + case INAT_IMM_PTR: + if (!__get_immptr(insn)) + goto err_out; + break; + case INAT_IMM_VWORD32: + if (!__get_immv32(insn)) + goto err_out; + break; + case INAT_IMM_VWORD: + if (!__get_immv(insn)) + goto err_out; + break; + default: + /* Here, insn must have an immediate, but failed */ + goto err_out; + } + if (inat_has_second_immediate(insn->attr)) { + insn->immediate2.value = get_next(signed char, insn); + insn->immediate2.nbytes = 1; + } +done: + insn->immediate.got = 1; + +err_out: + return; +} + +/** + * insn_get_length() - Get the length of instruction + * @insn: &struct insn containing instruction + * + * If necessary, first collects the instruction up to and including the + * immediates bytes. + */ +void insn_get_length(struct insn *insn) +{ + if (insn->length) + return; + if (!insn->immediate.got) + insn_get_immediate(insn); + insn->length = (unsigned char)((unsigned long)insn->next_byte + - (unsigned long)insn->kaddr); +} diff --git a/tools/arch/x86/lib/x86-opcode-map.txt b/tools/arch/x86/lib/x86-opcode-map.txt new file mode 100644 index 000000000000..e0b85930dd77 --- /dev/null +++ b/tools/arch/x86/lib/x86-opcode-map.txt @@ -0,0 +1,1072 @@ +# x86 Opcode Maps +# +# This is (mostly) based on following documentations. +# - Intel(R) 64 and IA-32 Architectures Software Developer's Manual Vol.2C +# (#326018-047US, June 2013) +# +# +# Table: table-name +# Referrer: escaped-name +# AVXcode: avx-code +# opcode: mnemonic|GrpXXX [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...] +# (or) +# opcode: escape # escaped-name +# EndTable +# +# mnemonics that begin with lowercase 'v' accept a VEX or EVEX prefix +# mnemonics that begin with lowercase 'k' accept a VEX prefix +# +# +# GrpTable: GrpXXX +# reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...] +# EndTable +# +# AVX Superscripts +# (ev): this opcode requires EVEX prefix. +# (evo): this opcode is changed by EVEX prefix (EVEX opcode) +# (v): this opcode requires VEX prefix. +# (v1): this opcode only supports 128bit VEX. +# +# Last Prefix Superscripts +# - (66): the last prefix is 0x66 +# - (F3): the last prefix is 0xF3 +# - (F2): the last prefix is 0xF2 +# - (!F3) : the last prefix is not 0xF3 (including non-last prefix case) +# - (66&F2): Both 0x66 and 0xF2 prefixes are specified. + +Table: one byte opcode +Referrer: +AVXcode: +# 0x00 - 0x0f +00: ADD Eb,Gb +01: ADD Ev,Gv +02: ADD Gb,Eb +03: ADD Gv,Ev +04: ADD AL,Ib +05: ADD rAX,Iz +06: PUSH ES (i64) +07: POP ES (i64) +08: OR Eb,Gb +09: OR Ev,Gv +0a: OR Gb,Eb +0b: OR Gv,Ev +0c: OR AL,Ib +0d: OR rAX,Iz +0e: PUSH CS (i64) +0f: escape # 2-byte escape +# 0x10 - 0x1f +10: ADC Eb,Gb +11: ADC Ev,Gv +12: ADC Gb,Eb +13: ADC Gv,Ev +14: ADC AL,Ib +15: ADC rAX,Iz +16: PUSH SS (i64) +17: POP SS (i64) +18: SBB Eb,Gb +19: SBB Ev,Gv +1a: SBB Gb,Eb +1b: SBB Gv,Ev +1c: SBB AL,Ib +1d: SBB rAX,Iz +1e: PUSH DS (i64) +1f: POP DS (i64) +# 0x20 - 0x2f +20: AND Eb,Gb +21: AND Ev,Gv +22: AND Gb,Eb +23: AND Gv,Ev +24: AND AL,Ib +25: AND rAx,Iz +26: SEG=ES (Prefix) +27: DAA (i64) +28: SUB Eb,Gb +29: SUB Ev,Gv +2a: SUB Gb,Eb +2b: SUB Gv,Ev +2c: SUB AL,Ib +2d: SUB rAX,Iz +2e: SEG=CS (Prefix) +2f: DAS (i64) +# 0x30 - 0x3f +30: XOR Eb,Gb +31: XOR Ev,Gv +32: XOR Gb,Eb +33: XOR Gv,Ev +34: XOR AL,Ib +35: XOR rAX,Iz +36: SEG=SS (Prefix) +37: AAA (i64) +38: CMP Eb,Gb +39: CMP Ev,Gv +3a: CMP Gb,Eb +3b: CMP Gv,Ev +3c: CMP AL,Ib +3d: CMP rAX,Iz +3e: SEG=DS (Prefix) +3f: AAS (i64) +# 0x40 - 0x4f +40: INC eAX (i64) | REX (o64) +41: INC eCX (i64) | REX.B (o64) +42: INC eDX (i64) | REX.X (o64) +43: INC eBX (i64) | REX.XB (o64) +44: INC eSP (i64) | REX.R (o64) +45: INC eBP (i64) | REX.RB (o64) +46: INC eSI (i64) | REX.RX (o64) +47: INC eDI (i64) | REX.RXB (o64) +48: DEC eAX (i64) | REX.W (o64) +49: DEC eCX (i64) | REX.WB (o64) +4a: DEC eDX (i64) | REX.WX (o64) +4b: DEC eBX (i64) | REX.WXB (o64) +4c: DEC eSP (i64) | REX.WR (o64) +4d: DEC eBP (i64) | REX.WRB (o64) +4e: DEC eSI (i64) | REX.WRX (o64) +4f: DEC eDI (i64) | REX.WRXB (o64) +# 0x50 - 0x5f +50: PUSH rAX/r8 (d64) +51: PUSH rCX/r9 (d64) +52: PUSH rDX/r10 (d64) +53: PUSH rBX/r11 (d64) +54: PUSH rSP/r12 (d64) +55: PUSH rBP/r13 (d64) +56: PUSH rSI/r14 (d64) +57: PUSH rDI/r15 (d64) +58: POP rAX/r8 (d64) +59: POP rCX/r9 (d64) +5a: POP rDX/r10 (d64) +5b: POP rBX/r11 (d64) +5c: POP rSP/r12 (d64) +5d: POP rBP/r13 (d64) +5e: POP rSI/r14 (d64) +5f: POP rDI/r15 (d64) +# 0x60 - 0x6f +60: PUSHA/PUSHAD (i64) +61: POPA/POPAD (i64) +62: BOUND Gv,Ma (i64) | EVEX (Prefix) +63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64) +64: SEG=FS (Prefix) +65: SEG=GS (Prefix) +66: Operand-Size (Prefix) +67: Address-Size (Prefix) +68: PUSH Iz (d64) +69: IMUL Gv,Ev,Iz +6a: PUSH Ib (d64) +6b: IMUL Gv,Ev,Ib +6c: INS/INSB Yb,DX +6d: INS/INSW/INSD Yz,DX +6e: OUTS/OUTSB DX,Xb +6f: OUTS/OUTSW/OUTSD DX,Xz +# 0x70 - 0x7f +70: JO Jb +71: JNO Jb +72: JB/JNAE/JC Jb +73: JNB/JAE/JNC Jb +74: JZ/JE Jb +75: JNZ/JNE Jb +76: JBE/JNA Jb +77: JNBE/JA Jb +78: JS Jb +79: JNS Jb +7a: JP/JPE Jb +7b: JNP/JPO Jb +7c: JL/JNGE Jb +7d: JNL/JGE Jb +7e: JLE/JNG Jb +7f: JNLE/JG Jb +# 0x80 - 0x8f +80: Grp1 Eb,Ib (1A) +81: Grp1 Ev,Iz (1A) +82: Grp1 Eb,Ib (1A),(i64) +83: Grp1 Ev,Ib (1A) +84: TEST Eb,Gb +85: TEST Ev,Gv +86: XCHG Eb,Gb +87: XCHG Ev,Gv +88: MOV Eb,Gb +89: MOV Ev,Gv +8a: MOV Gb,Eb +8b: MOV Gv,Ev +8c: MOV Ev,Sw +8d: LEA Gv,M +8e: MOV Sw,Ew +8f: Grp1A (1A) | POP Ev (d64) +# 0x90 - 0x9f +90: NOP | PAUSE (F3) | XCHG r8,rAX +91: XCHG rCX/r9,rAX +92: XCHG rDX/r10,rAX +93: XCHG rBX/r11,rAX +94: XCHG rSP/r12,rAX +95: XCHG rBP/r13,rAX +96: XCHG rSI/r14,rAX +97: XCHG rDI/r15,rAX +98: CBW/CWDE/CDQE +99: CWD/CDQ/CQO +9a: CALLF Ap (i64) +9b: FWAIT/WAIT +9c: PUSHF/D/Q Fv (d64) +9d: POPF/D/Q Fv (d64) +9e: SAHF +9f: LAHF +# 0xa0 - 0xaf +a0: MOV AL,Ob +a1: MOV rAX,Ov +a2: MOV Ob,AL +a3: MOV Ov,rAX +a4: MOVS/B Yb,Xb +a5: MOVS/W/D/Q Yv,Xv +a6: CMPS/B Xb,Yb +a7: CMPS/W/D Xv,Yv +a8: TEST AL,Ib +a9: TEST rAX,Iz +aa: STOS/B Yb,AL +ab: STOS/W/D/Q Yv,rAX +ac: LODS/B AL,Xb +ad: LODS/W/D/Q rAX,Xv +ae: SCAS/B AL,Yb +# Note: The May 2011 Intel manual shows Xv for the second parameter of the +# next instruction but Yv is correct +af: SCAS/W/D/Q rAX,Yv +# 0xb0 - 0xbf +b0: MOV AL/R8L,Ib +b1: MOV CL/R9L,Ib +b2: MOV DL/R10L,Ib +b3: MOV BL/R11L,Ib +b4: MOV AH/R12L,Ib +b5: MOV CH/R13L,Ib +b6: MOV DH/R14L,Ib +b7: MOV BH/R15L,Ib +b8: MOV rAX/r8,Iv +b9: MOV rCX/r9,Iv +ba: MOV rDX/r10,Iv +bb: MOV rBX/r11,Iv +bc: MOV rSP/r12,Iv +bd: MOV rBP/r13,Iv +be: MOV rSI/r14,Iv +bf: MOV rDI/r15,Iv +# 0xc0 - 0xcf +c0: Grp2 Eb,Ib (1A) +c1: Grp2 Ev,Ib (1A) +c2: RETN Iw (f64) +c3: RETN +c4: LES Gz,Mp (i64) | VEX+2byte (Prefix) +c5: LDS Gz,Mp (i64) | VEX+1byte (Prefix) +c6: Grp11A Eb,Ib (1A) +c7: Grp11B Ev,Iz (1A) +c8: ENTER Iw,Ib +c9: LEAVE (d64) +ca: RETF Iw +cb: RETF +cc: INT3 +cd: INT Ib +ce: INTO (i64) +cf: IRET/D/Q +# 0xd0 - 0xdf +d0: Grp2 Eb,1 (1A) +d1: Grp2 Ev,1 (1A) +d2: Grp2 Eb,CL (1A) +d3: Grp2 Ev,CL (1A) +d4: AAM Ib (i64) +d5: AAD Ib (i64) +d6: +d7: XLAT/XLATB +d8: ESC +d9: ESC +da: ESC +db: ESC +dc: ESC +dd: ESC +de: ESC +df: ESC +# 0xe0 - 0xef +# Note: "forced64" is Intel CPU behavior: they ignore 0x66 prefix +# in 64-bit mode. AMD CPUs accept 0x66 prefix, it causes RIP truncation +# to 16 bits. In 32-bit mode, 0x66 is accepted by both Intel and AMD. +e0: LOOPNE/LOOPNZ Jb (f64) +e1: LOOPE/LOOPZ Jb (f64) +e2: LOOP Jb (f64) +e3: JrCXZ Jb (f64) +e4: IN AL,Ib +e5: IN eAX,Ib +e6: OUT Ib,AL +e7: OUT Ib,eAX +# With 0x66 prefix in 64-bit mode, for AMD CPUs immediate offset +# in "near" jumps and calls is 16-bit. For CALL, +# push of return address is 16-bit wide, RSP is decremented by 2 +# but is not truncated to 16 bits, unlike RIP. +e8: CALL Jz (f64) +e9: JMP-near Jz (f64) +ea: JMP-far Ap (i64) +eb: JMP-short Jb (f64) +ec: IN AL,DX +ed: IN eAX,DX +ee: OUT DX,AL +ef: OUT DX,eAX +# 0xf0 - 0xff +f0: LOCK (Prefix) +f1: +f2: REPNE (Prefix) | XACQUIRE (Prefix) +f3: REP/REPE (Prefix) | XRELEASE (Prefix) +f4: HLT +f5: CMC +f6: Grp3_1 Eb (1A) +f7: Grp3_2 Ev (1A) +f8: CLC +f9: STC +fa: CLI +fb: STI +fc: CLD +fd: STD +fe: Grp4 (1A) +ff: Grp5 (1A) +EndTable + +Table: 2-byte opcode (0x0f) +Referrer: 2-byte escape +AVXcode: 1 +# 0x0f 0x00-0x0f +00: Grp6 (1A) +01: Grp7 (1A) +02: LAR Gv,Ew +03: LSL Gv,Ew +04: +05: SYSCALL (o64) +06: CLTS +07: SYSRET (o64) +08: INVD +09: WBINVD +0a: +0b: UD2 (1B) +0c: +# AMD's prefetch group. Intel supports prefetchw(/1) only. +0d: GrpP +0e: FEMMS +# 3DNow! uses the last imm byte as opcode extension. +0f: 3DNow! Pq,Qq,Ib +# 0x0f 0x10-0x1f +# NOTE: According to Intel SDM opcode map, vmovups and vmovupd has no operands +# but it actually has operands. And also, vmovss and vmovsd only accept 128bit. +# MOVSS/MOVSD has too many forms(3) on SDM. This map just shows a typical form. +# Many AVX instructions lack v1 superscript, according to Intel AVX-Prgramming +# Reference A.1 +10: vmovups Vps,Wps | vmovupd Vpd,Wpd (66) | vmovss Vx,Hx,Wss (F3),(v1) | vmovsd Vx,Hx,Wsd (F2),(v1) +11: vmovups Wps,Vps | vmovupd Wpd,Vpd (66) | vmovss Wss,Hx,Vss (F3),(v1) | vmovsd Wsd,Hx,Vsd (F2),(v1) +12: vmovlps Vq,Hq,Mq (v1) | vmovhlps Vq,Hq,Uq (v1) | vmovlpd Vq,Hq,Mq (66),(v1) | vmovsldup Vx,Wx (F3) | vmovddup Vx,Wx (F2) +13: vmovlps Mq,Vq (v1) | vmovlpd Mq,Vq (66),(v1) +14: vunpcklps Vx,Hx,Wx | vunpcklpd Vx,Hx,Wx (66) +15: vunpckhps Vx,Hx,Wx | vunpckhpd Vx,Hx,Wx (66) +16: vmovhps Vdq,Hq,Mq (v1) | vmovlhps Vdq,Hq,Uq (v1) | vmovhpd Vdq,Hq,Mq (66),(v1) | vmovshdup Vx,Wx (F3) +17: vmovhps Mq,Vq (v1) | vmovhpd Mq,Vq (66),(v1) +18: Grp16 (1A) +19: +# Intel SDM opcode map does not list MPX instructions. For now using Gv for +# bnd registers and Ev for everything else is OK because the instruction +# decoder does not use the information except as an indication that there is +# a ModR/M byte. +1a: BNDCL Gv,Ev (F3) | BNDCU Gv,Ev (F2) | BNDMOV Gv,Ev (66) | BNDLDX Gv,Ev +1b: BNDCN Gv,Ev (F2) | BNDMOV Ev,Gv (66) | BNDMK Gv,Ev (F3) | BNDSTX Ev,Gv +1c: +1d: +1e: +1f: NOP Ev +# 0x0f 0x20-0x2f +20: MOV Rd,Cd +21: MOV Rd,Dd +22: MOV Cd,Rd +23: MOV Dd,Rd +24: +25: +26: +27: +28: vmovaps Vps,Wps | vmovapd Vpd,Wpd (66) +29: vmovaps Wps,Vps | vmovapd Wpd,Vpd (66) +2a: cvtpi2ps Vps,Qpi | cvtpi2pd Vpd,Qpi (66) | vcvtsi2ss Vss,Hss,Ey (F3),(v1) | vcvtsi2sd Vsd,Hsd,Ey (F2),(v1) +2b: vmovntps Mps,Vps | vmovntpd Mpd,Vpd (66) +2c: cvttps2pi Ppi,Wps | cvttpd2pi Ppi,Wpd (66) | vcvttss2si Gy,Wss (F3),(v1) | vcvttsd2si Gy,Wsd (F2),(v1) +2d: cvtps2pi Ppi,Wps | cvtpd2pi Qpi,Wpd (66) | vcvtss2si Gy,Wss (F3),(v1) | vcvtsd2si Gy,Wsd (F2),(v1) +2e: vucomiss Vss,Wss (v1) | vucomisd Vsd,Wsd (66),(v1) +2f: vcomiss Vss,Wss (v1) | vcomisd Vsd,Wsd (66),(v1) +# 0x0f 0x30-0x3f +30: WRMSR +31: RDTSC +32: RDMSR +33: RDPMC +34: SYSENTER +35: SYSEXIT +36: +37: GETSEC +38: escape # 3-byte escape 1 +39: +3a: escape # 3-byte escape 2 +3b: +3c: +3d: +3e: +3f: +# 0x0f 0x40-0x4f +40: CMOVO Gv,Ev +41: CMOVNO Gv,Ev | kandw/q Vk,Hk,Uk | kandb/d Vk,Hk,Uk (66) +42: CMOVB/C/NAE Gv,Ev | kandnw/q Vk,Hk,Uk | kandnb/d Vk,Hk,Uk (66) +43: CMOVAE/NB/NC Gv,Ev +44: CMOVE/Z Gv,Ev | knotw/q Vk,Uk | knotb/d Vk,Uk (66) +45: CMOVNE/NZ Gv,Ev | korw/q Vk,Hk,Uk | korb/d Vk,Hk,Uk (66) +46: CMOVBE/NA Gv,Ev | kxnorw/q Vk,Hk,Uk | kxnorb/d Vk,Hk,Uk (66) +47: CMOVA/NBE Gv,Ev | kxorw/q Vk,Hk,Uk | kxorb/d Vk,Hk,Uk (66) +48: CMOVS Gv,Ev +49: CMOVNS Gv,Ev +4a: CMOVP/PE Gv,Ev | kaddw/q Vk,Hk,Uk | kaddb/d Vk,Hk,Uk (66) +4b: CMOVNP/PO Gv,Ev | kunpckbw Vk,Hk,Uk (66) | kunpckwd/dq Vk,Hk,Uk +4c: CMOVL/NGE Gv,Ev +4d: CMOVNL/GE Gv,Ev +4e: CMOVLE/NG Gv,Ev +4f: CMOVNLE/G Gv,Ev +# 0x0f 0x50-0x5f +50: vmovmskps Gy,Ups | vmovmskpd Gy,Upd (66) +51: vsqrtps Vps,Wps | vsqrtpd Vpd,Wpd (66) | vsqrtss Vss,Hss,Wss (F3),(v1) | vsqrtsd Vsd,Hsd,Wsd (F2),(v1) +52: vrsqrtps Vps,Wps | vrsqrtss Vss,Hss,Wss (F3),(v1) +53: vrcpps Vps,Wps | vrcpss Vss,Hss,Wss (F3),(v1) +54: vandps Vps,Hps,Wps | vandpd Vpd,Hpd,Wpd (66) +55: vandnps Vps,Hps,Wps | vandnpd Vpd,Hpd,Wpd (66) +56: vorps Vps,Hps,Wps | vorpd Vpd,Hpd,Wpd (66) +57: vxorps Vps,Hps,Wps | vxorpd Vpd,Hpd,Wpd (66) +58: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1) +59: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1) +5a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1) +5b: vcvtdq2ps Vps,Wdq | vcvtqq2ps Vps,Wqq (evo) | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3) +5c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1) +5d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1) +5e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1) +5f: vmaxps Vps,Hps,Wps | vmaxpd Vpd,Hpd,Wpd (66) | vmaxss Vss,Hss,Wss (F3),(v1) | vmaxsd Vsd,Hsd,Wsd (F2),(v1) +# 0x0f 0x60-0x6f +60: punpcklbw Pq,Qd | vpunpcklbw Vx,Hx,Wx (66),(v1) +61: punpcklwd Pq,Qd | vpunpcklwd Vx,Hx,Wx (66),(v1) +62: punpckldq Pq,Qd | vpunpckldq Vx,Hx,Wx (66),(v1) +63: packsswb Pq,Qq | vpacksswb Vx,Hx,Wx (66),(v1) +64: pcmpgtb Pq,Qq | vpcmpgtb Vx,Hx,Wx (66),(v1) +65: pcmpgtw Pq,Qq | vpcmpgtw Vx,Hx,Wx (66),(v1) +66: pcmpgtd Pq,Qq | vpcmpgtd Vx,Hx,Wx (66),(v1) +67: packuswb Pq,Qq | vpackuswb Vx,Hx,Wx (66),(v1) +68: punpckhbw Pq,Qd | vpunpckhbw Vx,Hx,Wx (66),(v1) +69: punpckhwd Pq,Qd | vpunpckhwd Vx,Hx,Wx (66),(v1) +6a: punpckhdq Pq,Qd | vpunpckhdq Vx,Hx,Wx (66),(v1) +6b: packssdw Pq,Qd | vpackssdw Vx,Hx,Wx (66),(v1) +6c: vpunpcklqdq Vx,Hx,Wx (66),(v1) +6d: vpunpckhqdq Vx,Hx,Wx (66),(v1) +6e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1) +6f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqa32/64 Vx,Wx (66),(evo) | vmovdqu Vx,Wx (F3) | vmovdqu32/64 Vx,Wx (F3),(evo) | vmovdqu8/16 Vx,Wx (F2),(ev) +# 0x0f 0x70-0x7f +70: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1) +71: Grp12 (1A) +72: Grp13 (1A) +73: Grp14 (1A) +74: pcmpeqb Pq,Qq | vpcmpeqb Vx,Hx,Wx (66),(v1) +75: pcmpeqw Pq,Qq | vpcmpeqw Vx,Hx,Wx (66),(v1) +76: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1) +# Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX. +77: emms | vzeroupper | vzeroall +78: VMREAD Ey,Gy | vcvttps2udq/pd2udq Vx,Wpd (evo) | vcvttsd2usi Gv,Wx (F2),(ev) | vcvttss2usi Gv,Wx (F3),(ev) | vcvttps2uqq/pd2uqq Vx,Wx (66),(ev) +79: VMWRITE Gy,Ey | vcvtps2udq/pd2udq Vx,Wpd (evo) | vcvtsd2usi Gv,Wx (F2),(ev) | vcvtss2usi Gv,Wx (F3),(ev) | vcvtps2uqq/pd2uqq Vx,Wx (66),(ev) +7a: vcvtudq2pd/uqq2pd Vpd,Wx (F3),(ev) | vcvtudq2ps/uqq2ps Vpd,Wx (F2),(ev) | vcvttps2qq/pd2qq Vx,Wx (66),(ev) +7b: vcvtusi2sd Vpd,Hpd,Ev (F2),(ev) | vcvtusi2ss Vps,Hps,Ev (F3),(ev) | vcvtps2qq/pd2qq Vx,Wx (66),(ev) +7c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2) +7d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2) +7e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1) +7f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqa32/64 Wx,Vx (66),(evo) | vmovdqu Wx,Vx (F3) | vmovdqu32/64 Wx,Vx (F3),(evo) | vmovdqu8/16 Wx,Vx (F2),(ev) +# 0x0f 0x80-0x8f +# Note: "forced64" is Intel CPU behavior (see comment about CALL insn). +80: JO Jz (f64) +81: JNO Jz (f64) +82: JB/JC/JNAE Jz (f64) +83: JAE/JNB/JNC Jz (f64) +84: JE/JZ Jz (f64) +85: JNE/JNZ Jz (f64) +86: JBE/JNA Jz (f64) +87: JA/JNBE Jz (f64) +88: JS Jz (f64) +89: JNS Jz (f64) +8a: JP/JPE Jz (f64) +8b: JNP/JPO Jz (f64) +8c: JL/JNGE Jz (f64) +8d: JNL/JGE Jz (f64) +8e: JLE/JNG Jz (f64) +8f: JNLE/JG Jz (f64) +# 0x0f 0x90-0x9f +90: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66) +91: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66) +92: SETB/C/NAE Eb | kmovw Vk,Rv | kmovb Vk,Rv (66) | kmovq/d Vk,Rv (F2) +93: SETAE/NB/NC Eb | kmovw Gv,Uk | kmovb Gv,Uk (66) | kmovq/d Gv,Uk (F2) +94: SETE/Z Eb +95: SETNE/NZ Eb +96: SETBE/NA Eb +97: SETA/NBE Eb +98: SETS Eb | kortestw/q Vk,Uk | kortestb/d Vk,Uk (66) +99: SETNS Eb | ktestw/q Vk,Uk | ktestb/d Vk,Uk (66) +9a: SETP/PE Eb +9b: SETNP/PO Eb +9c: SETL/NGE Eb +9d: SETNL/GE Eb +9e: SETLE/NG Eb +9f: SETNLE/G Eb +# 0x0f 0xa0-0xaf +a0: PUSH FS (d64) +a1: POP FS (d64) +a2: CPUID +a3: BT Ev,Gv +a4: SHLD Ev,Gv,Ib +a5: SHLD Ev,Gv,CL +a6: GrpPDLK +a7: GrpRNG +a8: PUSH GS (d64) +a9: POP GS (d64) +aa: RSM +ab: BTS Ev,Gv +ac: SHRD Ev,Gv,Ib +ad: SHRD Ev,Gv,CL +ae: Grp15 (1A),(1C) +af: IMUL Gv,Ev +# 0x0f 0xb0-0xbf +b0: CMPXCHG Eb,Gb +b1: CMPXCHG Ev,Gv +b2: LSS Gv,Mp +b3: BTR Ev,Gv +b4: LFS Gv,Mp +b5: LGS Gv,Mp +b6: MOVZX Gv,Eb +b7: MOVZX Gv,Ew +b8: JMPE (!F3) | POPCNT Gv,Ev (F3) +b9: Grp10 (1A) +ba: Grp8 Ev,Ib (1A) +bb: BTC Ev,Gv +bc: BSF Gv,Ev (!F3) | TZCNT Gv,Ev (F3) +bd: BSR Gv,Ev (!F3) | LZCNT Gv,Ev (F3) +be: MOVSX Gv,Eb +bf: MOVSX Gv,Ew +# 0x0f 0xc0-0xcf +c0: XADD Eb,Gb +c1: XADD Ev,Gv +c2: vcmpps Vps,Hps,Wps,Ib | vcmppd Vpd,Hpd,Wpd,Ib (66) | vcmpss Vss,Hss,Wss,Ib (F3),(v1) | vcmpsd Vsd,Hsd,Wsd,Ib (F2),(v1) +c3: movnti My,Gy +c4: pinsrw Pq,Ry/Mw,Ib | vpinsrw Vdq,Hdq,Ry/Mw,Ib (66),(v1) +c5: pextrw Gd,Nq,Ib | vpextrw Gd,Udq,Ib (66),(v1) +c6: vshufps Vps,Hps,Wps,Ib | vshufpd Vpd,Hpd,Wpd,Ib (66) +c7: Grp9 (1A) +c8: BSWAP RAX/EAX/R8/R8D +c9: BSWAP RCX/ECX/R9/R9D +ca: BSWAP RDX/EDX/R10/R10D +cb: BSWAP RBX/EBX/R11/R11D +cc: BSWAP RSP/ESP/R12/R12D +cd: BSWAP RBP/EBP/R13/R13D +ce: BSWAP RSI/ESI/R14/R14D +cf: BSWAP RDI/EDI/R15/R15D +# 0x0f 0xd0-0xdf +d0: vaddsubpd Vpd,Hpd,Wpd (66) | vaddsubps Vps,Hps,Wps (F2) +d1: psrlw Pq,Qq | vpsrlw Vx,Hx,Wx (66),(v1) +d2: psrld Pq,Qq | vpsrld Vx,Hx,Wx (66),(v1) +d3: psrlq Pq,Qq | vpsrlq Vx,Hx,Wx (66),(v1) +d4: paddq Pq,Qq | vpaddq Vx,Hx,Wx (66),(v1) +d5: pmullw Pq,Qq | vpmullw Vx,Hx,Wx (66),(v1) +d6: vmovq Wq,Vq (66),(v1) | movq2dq Vdq,Nq (F3) | movdq2q Pq,Uq (F2) +d7: pmovmskb Gd,Nq | vpmovmskb Gd,Ux (66),(v1) +d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1) +d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1) +da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1) +db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) | vpandd/q Vx,Hx,Wx (66),(evo) +dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1) +dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1) +de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1) +df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) | vpandnd/q Vx,Hx,Wx (66),(evo) +# 0x0f 0xe0-0xef +e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1) +e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1) +e2: psrad Pq,Qq | vpsrad Vx,Hx,Wx (66),(v1) +e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1) +e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1) +e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1) +e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtdq2pd/qq2pd Vx,Wdq (F3),(evo) | vcvtpd2dq Vx,Wpd (F2) +e7: movntq Mq,Pq | vmovntdq Mx,Vx (66) +e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1) +e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1) +ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1) +eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) | vpord/q Vx,Hx,Wx (66),(evo) +ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1) +ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1) +ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1) +ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) | vpxord/q Vx,Hx,Wx (66),(evo) +# 0x0f 0xf0-0xff +f0: vlddqu Vx,Mx (F2) +f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1) +f2: pslld Pq,Qq | vpslld Vx,Hx,Wx (66),(v1) +f3: psllq Pq,Qq | vpsllq Vx,Hx,Wx (66),(v1) +f4: pmuludq Pq,Qq | vpmuludq Vx,Hx,Wx (66),(v1) +f5: pmaddwd Pq,Qq | vpmaddwd Vx,Hx,Wx (66),(v1) +f6: psadbw Pq,Qq | vpsadbw Vx,Hx,Wx (66),(v1) +f7: maskmovq Pq,Nq | vmaskmovdqu Vx,Ux (66),(v1) +f8: psubb Pq,Qq | vpsubb Vx,Hx,Wx (66),(v1) +f9: psubw Pq,Qq | vpsubw Vx,Hx,Wx (66),(v1) +fa: psubd Pq,Qq | vpsubd Vx,Hx,Wx (66),(v1) +fb: psubq Pq,Qq | vpsubq Vx,Hx,Wx (66),(v1) +fc: paddb Pq,Qq | vpaddb Vx,Hx,Wx (66),(v1) +fd: paddw Pq,Qq | vpaddw Vx,Hx,Wx (66),(v1) +fe: paddd Pq,Qq | vpaddd Vx,Hx,Wx (66),(v1) +ff: UD0 +EndTable + +Table: 3-byte opcode 1 (0x0f 0x38) +Referrer: 3-byte escape 1 +AVXcode: 2 +# 0x0f 0x38 0x00-0x0f +00: pshufb Pq,Qq | vpshufb Vx,Hx,Wx (66),(v1) +01: phaddw Pq,Qq | vphaddw Vx,Hx,Wx (66),(v1) +02: phaddd Pq,Qq | vphaddd Vx,Hx,Wx (66),(v1) +03: phaddsw Pq,Qq | vphaddsw Vx,Hx,Wx (66),(v1) +04: pmaddubsw Pq,Qq | vpmaddubsw Vx,Hx,Wx (66),(v1) +05: phsubw Pq,Qq | vphsubw Vx,Hx,Wx (66),(v1) +06: phsubd Pq,Qq | vphsubd Vx,Hx,Wx (66),(v1) +07: phsubsw Pq,Qq | vphsubsw Vx,Hx,Wx (66),(v1) +08: psignb Pq,Qq | vpsignb Vx,Hx,Wx (66),(v1) +09: psignw Pq,Qq | vpsignw Vx,Hx,Wx (66),(v1) +0a: psignd Pq,Qq | vpsignd Vx,Hx,Wx (66),(v1) +0b: pmulhrsw Pq,Qq | vpmulhrsw Vx,Hx,Wx (66),(v1) +0c: vpermilps Vx,Hx,Wx (66),(v) +0d: vpermilpd Vx,Hx,Wx (66),(v) +0e: vtestps Vx,Wx (66),(v) +0f: vtestpd Vx,Wx (66),(v) +# 0x0f 0x38 0x10-0x1f +10: pblendvb Vdq,Wdq (66) | vpsrlvw Vx,Hx,Wx (66),(evo) | vpmovuswb Wx,Vx (F3),(ev) +11: vpmovusdb Wx,Vd (F3),(ev) | vpsravw Vx,Hx,Wx (66),(ev) +12: vpmovusqb Wx,Vq (F3),(ev) | vpsllvw Vx,Hx,Wx (66),(ev) +13: vcvtph2ps Vx,Wx (66),(v) | vpmovusdw Wx,Vd (F3),(ev) +14: blendvps Vdq,Wdq (66) | vpmovusqw Wx,Vq (F3),(ev) | vprorvd/q Vx,Hx,Wx (66),(evo) +15: blendvpd Vdq,Wdq (66) | vpmovusqd Wx,Vq (F3),(ev) | vprolvd/q Vx,Hx,Wx (66),(evo) +16: vpermps Vqq,Hqq,Wqq (66),(v) | vpermps/d Vqq,Hqq,Wqq (66),(evo) +17: vptest Vx,Wx (66) +18: vbroadcastss Vx,Wd (66),(v) +19: vbroadcastsd Vqq,Wq (66),(v) | vbroadcastf32x2 Vqq,Wq (66),(evo) +1a: vbroadcastf128 Vqq,Mdq (66),(v) | vbroadcastf32x4/64x2 Vqq,Wq (66),(evo) +1b: vbroadcastf32x8/64x4 Vqq,Mdq (66),(ev) +1c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1) +1d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1) +1e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1) +1f: vpabsq Vx,Wx (66),(ev) +# 0x0f 0x38 0x20-0x2f +20: vpmovsxbw Vx,Ux/Mq (66),(v1) | vpmovswb Wx,Vx (F3),(ev) +21: vpmovsxbd Vx,Ux/Md (66),(v1) | vpmovsdb Wx,Vd (F3),(ev) +22: vpmovsxbq Vx,Ux/Mw (66),(v1) | vpmovsqb Wx,Vq (F3),(ev) +23: vpmovsxwd Vx,Ux/Mq (66),(v1) | vpmovsdw Wx,Vd (F3),(ev) +24: vpmovsxwq Vx,Ux/Md (66),(v1) | vpmovsqw Wx,Vq (F3),(ev) +25: vpmovsxdq Vx,Ux/Mq (66),(v1) | vpmovsqd Wx,Vq (F3),(ev) +26: vptestmb/w Vk,Hx,Wx (66),(ev) | vptestnmb/w Vk,Hx,Wx (F3),(ev) +27: vptestmd/q Vk,Hx,Wx (66),(ev) | vptestnmd/q Vk,Hx,Wx (F3),(ev) +28: vpmuldq Vx,Hx,Wx (66),(v1) | vpmovm2b/w Vx,Uk (F3),(ev) +29: vpcmpeqq Vx,Hx,Wx (66),(v1) | vpmovb2m/w2m Vk,Ux (F3),(ev) +2a: vmovntdqa Vx,Mx (66),(v1) | vpbroadcastmb2q Vx,Uk (F3),(ev) +2b: vpackusdw Vx,Hx,Wx (66),(v1) +2c: vmaskmovps Vx,Hx,Mx (66),(v) | vscalefps/d Vx,Hx,Wx (66),(evo) +2d: vmaskmovpd Vx,Hx,Mx (66),(v) | vscalefss/d Vx,Hx,Wx (66),(evo) +2e: vmaskmovps Mx,Hx,Vx (66),(v) +2f: vmaskmovpd Mx,Hx,Vx (66),(v) +# 0x0f 0x38 0x30-0x3f +30: vpmovzxbw Vx,Ux/Mq (66),(v1) | vpmovwb Wx,Vx (F3),(ev) +31: vpmovzxbd Vx,Ux/Md (66),(v1) | vpmovdb Wx,Vd (F3),(ev) +32: vpmovzxbq Vx,Ux/Mw (66),(v1) | vpmovqb Wx,Vq (F3),(ev) +33: vpmovzxwd Vx,Ux/Mq (66),(v1) | vpmovdw Wx,Vd (F3),(ev) +34: vpmovzxwq Vx,Ux/Md (66),(v1) | vpmovqw Wx,Vq (F3),(ev) +35: vpmovzxdq Vx,Ux/Mq (66),(v1) | vpmovqd Wx,Vq (F3),(ev) +36: vpermd Vqq,Hqq,Wqq (66),(v) | vpermd/q Vqq,Hqq,Wqq (66),(evo) +37: vpcmpgtq Vx,Hx,Wx (66),(v1) +38: vpminsb Vx,Hx,Wx (66),(v1) | vpmovm2d/q Vx,Uk (F3),(ev) +39: vpminsd Vx,Hx,Wx (66),(v1) | vpminsd/q Vx,Hx,Wx (66),(evo) | vpmovd2m/q2m Vk,Ux (F3),(ev) +3a: vpminuw Vx,Hx,Wx (66),(v1) | vpbroadcastmw2d Vx,Uk (F3),(ev) +3b: vpminud Vx,Hx,Wx (66),(v1) | vpminud/q Vx,Hx,Wx (66),(evo) +3c: vpmaxsb Vx,Hx,Wx (66),(v1) +3d: vpmaxsd Vx,Hx,Wx (66),(v1) | vpmaxsd/q Vx,Hx,Wx (66),(evo) +3e: vpmaxuw Vx,Hx,Wx (66),(v1) +3f: vpmaxud Vx,Hx,Wx (66),(v1) | vpmaxud/q Vx,Hx,Wx (66),(evo) +# 0x0f 0x38 0x40-0x8f +40: vpmulld Vx,Hx,Wx (66),(v1) | vpmulld/q Vx,Hx,Wx (66),(evo) +41: vphminposuw Vdq,Wdq (66),(v1) +42: vgetexpps/d Vx,Wx (66),(ev) +43: vgetexpss/d Vx,Hx,Wx (66),(ev) +44: vplzcntd/q Vx,Wx (66),(ev) +45: vpsrlvd/q Vx,Hx,Wx (66),(v) +46: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo) +47: vpsllvd/q Vx,Hx,Wx (66),(v) +# Skip 0x48-0x4b +4c: vrcp14ps/d Vpd,Wpd (66),(ev) +4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev) +4e: vrsqrt14ps/d Vpd,Wpd (66),(ev) +4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev) +# Skip 0x50-0x57 +58: vpbroadcastd Vx,Wx (66),(v) +59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo) +5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo) +5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev) +# Skip 0x5c-0x63 +64: vpblendmd/q Vx,Hx,Wx (66),(ev) +65: vblendmps/d Vx,Hx,Wx (66),(ev) +66: vpblendmb/w Vx,Hx,Wx (66),(ev) +# Skip 0x67-0x74 +75: vpermi2b/w Vx,Hx,Wx (66),(ev) +76: vpermi2d/q Vx,Hx,Wx (66),(ev) +77: vpermi2ps/d Vx,Hx,Wx (66),(ev) +78: vpbroadcastb Vx,Wx (66),(v) +79: vpbroadcastw Vx,Wx (66),(v) +7a: vpbroadcastb Vx,Rv (66),(ev) +7b: vpbroadcastw Vx,Rv (66),(ev) +7c: vpbroadcastd/q Vx,Rv (66),(ev) +7d: vpermt2b/w Vx,Hx,Wx (66),(ev) +7e: vpermt2d/q Vx,Hx,Wx (66),(ev) +7f: vpermt2ps/d Vx,Hx,Wx (66),(ev) +80: INVEPT Gy,Mdq (66) +81: INVVPID Gy,Mdq (66) +82: INVPCID Gy,Mdq (66) +83: vpmultishiftqb Vx,Hx,Wx (66),(ev) +88: vexpandps/d Vpd,Wpd (66),(ev) +89: vpexpandd/q Vx,Wx (66),(ev) +8a: vcompressps/d Wx,Vx (66),(ev) +8b: vpcompressd/q Wx,Vx (66),(ev) +8c: vpmaskmovd/q Vx,Hx,Mx (66),(v) +8d: vpermb/w Vx,Hx,Wx (66),(ev) +8e: vpmaskmovd/q Mx,Vx,Hx (66),(v) +# 0x0f 0x38 0x90-0xbf (FMA) +90: vgatherdd/q Vx,Hx,Wx (66),(v) | vpgatherdd/q Vx,Wx (66),(evo) +91: vgatherqd/q Vx,Hx,Wx (66),(v) | vpgatherqd/q Vx,Wx (66),(evo) +92: vgatherdps/d Vx,Hx,Wx (66),(v) +93: vgatherqps/d Vx,Hx,Wx (66),(v) +94: +95: +96: vfmaddsub132ps/d Vx,Hx,Wx (66),(v) +97: vfmsubadd132ps/d Vx,Hx,Wx (66),(v) +98: vfmadd132ps/d Vx,Hx,Wx (66),(v) +99: vfmadd132ss/d Vx,Hx,Wx (66),(v),(v1) +9a: vfmsub132ps/d Vx,Hx,Wx (66),(v) +9b: vfmsub132ss/d Vx,Hx,Wx (66),(v),(v1) +9c: vfnmadd132ps/d Vx,Hx,Wx (66),(v) +9d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1) +9e: vfnmsub132ps/d Vx,Hx,Wx (66),(v) +9f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1) +a0: vpscatterdd/q Wx,Vx (66),(ev) +a1: vpscatterqd/q Wx,Vx (66),(ev) +a2: vscatterdps/d Wx,Vx (66),(ev) +a3: vscatterqps/d Wx,Vx (66),(ev) +a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v) +a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v) +a8: vfmadd213ps/d Vx,Hx,Wx (66),(v) +a9: vfmadd213ss/d Vx,Hx,Wx (66),(v),(v1) +aa: vfmsub213ps/d Vx,Hx,Wx (66),(v) +ab: vfmsub213ss/d Vx,Hx,Wx (66),(v),(v1) +ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v) +ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1) +ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v) +af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1) +b4: vpmadd52luq Vx,Hx,Wx (66),(ev) +b5: vpmadd52huq Vx,Hx,Wx (66),(ev) +b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v) +b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v) +b8: vfmadd231ps/d Vx,Hx,Wx (66),(v) +b9: vfmadd231ss/d Vx,Hx,Wx (66),(v),(v1) +ba: vfmsub231ps/d Vx,Hx,Wx (66),(v) +bb: vfmsub231ss/d Vx,Hx,Wx (66),(v),(v1) +bc: vfnmadd231ps/d Vx,Hx,Wx (66),(v) +bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1) +be: vfnmsub231ps/d Vx,Hx,Wx (66),(v) +bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1) +# 0x0f 0x38 0xc0-0xff +c4: vpconflictd/q Vx,Wx (66),(ev) +c6: Grp18 (1A) +c7: Grp19 (1A) +c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev) +c9: sha1msg1 Vdq,Wdq +ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev) +cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev) +cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev) +cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev) +db: VAESIMC Vdq,Wdq (66),(v1) +dc: VAESENC Vdq,Hdq,Wdq (66),(v1) +dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1) +de: VAESDEC Vdq,Hdq,Wdq (66),(v1) +df: VAESDECLAST Vdq,Hdq,Wdq (66),(v1) +f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2) +f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2) +f2: ANDN Gy,By,Ey (v) +f3: Grp17 (1A) +f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v) +f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v) +f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v) +EndTable + +Table: 3-byte opcode 2 (0x0f 0x3a) +Referrer: 3-byte escape 2 +AVXcode: 3 +# 0x0f 0x3a 0x00-0xff +00: vpermq Vqq,Wqq,Ib (66),(v) +01: vpermpd Vqq,Wqq,Ib (66),(v) +02: vpblendd Vx,Hx,Wx,Ib (66),(v) +03: valignd/q Vx,Hx,Wx,Ib (66),(ev) +04: vpermilps Vx,Wx,Ib (66),(v) +05: vpermilpd Vx,Wx,Ib (66),(v) +06: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v) +07: +08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo) +09: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo) +0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo) +0b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo) +0c: vblendps Vx,Hx,Wx,Ib (66) +0d: vblendpd Vx,Hx,Wx,Ib (66) +0e: vpblendw Vx,Hx,Wx,Ib (66),(v1) +0f: palignr Pq,Qq,Ib | vpalignr Vx,Hx,Wx,Ib (66),(v1) +14: vpextrb Rd/Mb,Vdq,Ib (66),(v1) +15: vpextrw Rd/Mw,Vdq,Ib (66),(v1) +16: vpextrd/q Ey,Vdq,Ib (66),(v1) +17: vextractps Ed,Vdq,Ib (66),(v1) +18: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) | vinsertf32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo) +19: vextractf128 Wdq,Vqq,Ib (66),(v) | vextractf32x4/64x2 Wdq,Vqq,Ib (66),(evo) +1a: vinsertf32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev) +1b: vextractf32x8/64x4 Wdq,Vqq,Ib (66),(ev) +1d: vcvtps2ph Wx,Vx,Ib (66),(v) +1e: vpcmpud/q Vk,Hd,Wd,Ib (66),(ev) +1f: vpcmpd/q Vk,Hd,Wd,Ib (66),(ev) +20: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1) +21: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1) +22: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1) +23: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev) +25: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev) +26: vgetmantps/d Vx,Wx,Ib (66),(ev) +27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev) +30: kshiftrb/w Vk,Uk,Ib (66),(v) +31: kshiftrd/q Vk,Uk,Ib (66),(v) +32: kshiftlb/w Vk,Uk,Ib (66),(v) +33: kshiftld/q Vk,Uk,Ib (66),(v) +38: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) | vinserti32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo) +39: vextracti128 Wdq,Vqq,Ib (66),(v) | vextracti32x4/64x2 Wdq,Vqq,Ib (66),(evo) +3a: vinserti32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev) +3b: vextracti32x8/64x4 Wdq,Vqq,Ib (66),(ev) +3e: vpcmpub/w Vk,Hk,Wx,Ib (66),(ev) +3f: vpcmpb/w Vk,Hk,Wx,Ib (66),(ev) +40: vdpps Vx,Hx,Wx,Ib (66) +41: vdppd Vdq,Hdq,Wdq,Ib (66),(v1) +42: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) | vdbpsadbw Vx,Hx,Wx,Ib (66),(evo) +43: vshufi32x4/64x2 Vx,Hx,Wx,Ib (66),(ev) +44: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1) +46: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v) +4a: vblendvps Vx,Hx,Wx,Lx (66),(v) +4b: vblendvpd Vx,Hx,Wx,Lx (66),(v) +4c: vpblendvb Vx,Hx,Wx,Lx (66),(v1) +50: vrangeps/d Vx,Hx,Wx,Ib (66),(ev) +51: vrangess/d Vx,Hx,Wx,Ib (66),(ev) +54: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev) +55: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev) +56: vreduceps/d Vx,Wx,Ib (66),(ev) +57: vreducess/d Vx,Hx,Wx,Ib (66),(ev) +60: vpcmpestrm Vdq,Wdq,Ib (66),(v1) +61: vpcmpestri Vdq,Wdq,Ib (66),(v1) +62: vpcmpistrm Vdq,Wdq,Ib (66),(v1) +63: vpcmpistri Vdq,Wdq,Ib (66),(v1) +66: vfpclassps/d Vk,Wx,Ib (66),(ev) +67: vfpclassss/d Vk,Wx,Ib (66),(ev) +cc: sha1rnds4 Vdq,Wdq,Ib +df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1) +f0: RORX Gy,Ey,Ib (F2),(v) +EndTable + +GrpTable: Grp1 +0: ADD +1: OR +2: ADC +3: SBB +4: AND +5: SUB +6: XOR +7: CMP +EndTable + +GrpTable: Grp1A +0: POP +EndTable + +GrpTable: Grp2 +0: ROL +1: ROR +2: RCL +3: RCR +4: SHL/SAL +5: SHR +6: +7: SAR +EndTable + +GrpTable: Grp3_1 +0: TEST Eb,Ib +1: TEST Eb,Ib +2: NOT Eb +3: NEG Eb +4: MUL AL,Eb +5: IMUL AL,Eb +6: DIV AL,Eb +7: IDIV AL,Eb +EndTable + +GrpTable: Grp3_2 +0: TEST Ev,Iz +1: +2: NOT Ev +3: NEG Ev +4: MUL rAX,Ev +5: IMUL rAX,Ev +6: DIV rAX,Ev +7: IDIV rAX,Ev +EndTable + +GrpTable: Grp4 +0: INC Eb +1: DEC Eb +EndTable + +GrpTable: Grp5 +0: INC Ev +1: DEC Ev +# Note: "forced64" is Intel CPU behavior (see comment about CALL insn). +2: CALLN Ev (f64) +3: CALLF Ep +4: JMPN Ev (f64) +5: JMPF Mp +6: PUSH Ev (d64) +7: +EndTable + +GrpTable: Grp6 +0: SLDT Rv/Mw +1: STR Rv/Mw +2: LLDT Ew +3: LTR Ew +4: VERR Ew +5: VERW Ew +EndTable + +GrpTable: Grp7 +0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) +1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B) +2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B) +3: LIDT Ms +4: SMSW Mw/Rv +5: rdpkru (110),(11B) | wrpkru (111),(11B) +6: LMSW Ew +7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B) +EndTable + +GrpTable: Grp8 +4: BT +5: BTS +6: BTR +7: BTC +EndTable + +GrpTable: Grp9 +1: CMPXCHG8B/16B Mq/Mdq +3: xrstors +4: xsavec +5: xsaves +6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B) +7: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B) +EndTable + +GrpTable: Grp10 +# all are UD1 +0: UD1 +1: UD1 +2: UD1 +3: UD1 +4: UD1 +5: UD1 +6: UD1 +7: UD1 +EndTable + +# Grp11A and Grp11B are expressed as Grp11 in Intel SDM +GrpTable: Grp11A +0: MOV Eb,Ib +7: XABORT Ib (000),(11B) +EndTable + +GrpTable: Grp11B +0: MOV Eb,Iz +7: XBEGIN Jz (000),(11B) +EndTable + +GrpTable: Grp12 +2: psrlw Nq,Ib (11B) | vpsrlw Hx,Ux,Ib (66),(11B),(v1) +4: psraw Nq,Ib (11B) | vpsraw Hx,Ux,Ib (66),(11B),(v1) +6: psllw Nq,Ib (11B) | vpsllw Hx,Ux,Ib (66),(11B),(v1) +EndTable + +GrpTable: Grp13 +0: vprord/q Hx,Wx,Ib (66),(ev) +1: vprold/q Hx,Wx,Ib (66),(ev) +2: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1) +4: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) | vpsrad/q Hx,Ux,Ib (66),(evo) +6: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1) +EndTable + +GrpTable: Grp14 +2: psrlq Nq,Ib (11B) | vpsrlq Hx,Ux,Ib (66),(11B),(v1) +3: vpsrldq Hx,Ux,Ib (66),(11B),(v1) +6: psllq Nq,Ib (11B) | vpsllq Hx,Ux,Ib (66),(11B),(v1) +7: vpslldq Hx,Ux,Ib (66),(11B),(v1) +EndTable + +GrpTable: Grp15 +0: fxsave | RDFSBASE Ry (F3),(11B) +1: fxstor | RDGSBASE Ry (F3),(11B) +2: vldmxcsr Md (v1) | WRFSBASE Ry (F3),(11B) +3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B) +4: XSAVE | ptwrite Ey (F3),(11B) +5: XRSTOR | lfence (11B) +6: XSAVEOPT | clwb (66) | mfence (11B) +7: clflush | clflushopt (66) | sfence (11B) +EndTable + +GrpTable: Grp16 +0: prefetch NTA +1: prefetch T0 +2: prefetch T1 +3: prefetch T2 +EndTable + +GrpTable: Grp17 +1: BLSR By,Ey (v) +2: BLSMSK By,Ey (v) +3: BLSI By,Ey (v) +EndTable + +GrpTable: Grp18 +1: vgatherpf0dps/d Wx (66),(ev) +2: vgatherpf1dps/d Wx (66),(ev) +5: vscatterpf0dps/d Wx (66),(ev) +6: vscatterpf1dps/d Wx (66),(ev) +EndTable + +GrpTable: Grp19 +1: vgatherpf0qps/d Wx (66),(ev) +2: vgatherpf1qps/d Wx (66),(ev) +5: vscatterpf0qps/d Wx (66),(ev) +6: vscatterpf1qps/d Wx (66),(ev) +EndTable + +# AMD's Prefetch Group +GrpTable: GrpP +0: PREFETCH +1: PREFETCHW +EndTable + +GrpTable: GrpPDLK +0: MONTMUL +1: XSHA1 +2: XSHA2 +EndTable + +GrpTable: GrpRNG +0: xstore-rng +1: xcrypt-ecb +2: xcrypt-cbc +4: xcrypt-cfb +5: xcrypt-ofb +EndTable diff --git a/tools/arch/x86/tools/gen-insn-attr-x86.awk b/tools/arch/x86/tools/gen-insn-attr-x86.awk new file mode 100644 index 000000000000..b02a36b2c14f --- /dev/null +++ b/tools/arch/x86/tools/gen-insn-attr-x86.awk @@ -0,0 +1,393 @@ +#!/bin/awk -f +# SPDX-License-Identifier: GPL-2.0 +# gen-insn-attr-x86.awk: Instruction attribute table generator +# Written by Masami Hiramatsu +# +# Usage: awk -f gen-insn-attr-x86.awk x86-opcode-map.txt > inat-tables.c + +# Awk implementation sanity check +function check_awk_implement() { + if (sprintf("%x", 0) != "0") + return "Your awk has a printf-format problem." + return "" +} + +# Clear working vars +function clear_vars() { + delete table + delete lptable2 + delete lptable1 + delete lptable3 + eid = -1 # escape id + gid = -1 # group id + aid = -1 # AVX id + tname = "" +} + +BEGIN { + # Implementation error checking + awkchecked = check_awk_implement() + if (awkchecked != "") { + print "Error: " awkchecked > "/dev/stderr" + print "Please try to use gawk." > "/dev/stderr" + exit 1 + } + + # Setup generating tables + print "/* x86 opcode map generated from x86-opcode-map.txt */" + print "/* Do not change this code. */\n" + ggid = 1 + geid = 1 + gaid = 0 + delete etable + delete gtable + delete atable + + opnd_expr = "^[A-Za-z/]" + ext_expr = "^\\(" + sep_expr = "^\\|$" + group_expr = "^Grp[0-9A-Za-z]+" + + imm_expr = "^[IJAOL][a-z]" + imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" + imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" + imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)" + imm_flag["Id"] = "INAT_MAKE_IMM(INAT_IMM_DWORD)" + imm_flag["Iq"] = "INAT_MAKE_IMM(INAT_IMM_QWORD)" + imm_flag["Ap"] = "INAT_MAKE_IMM(INAT_IMM_PTR)" + imm_flag["Iz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)" + imm_flag["Jz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)" + imm_flag["Iv"] = "INAT_MAKE_IMM(INAT_IMM_VWORD)" + imm_flag["Ob"] = "INAT_MOFFSET" + imm_flag["Ov"] = "INAT_MOFFSET" + imm_flag["Lx"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" + + modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])" + force64_expr = "\\([df]64\\)" + rex_expr = "^REX(\\.[XRWB]+)*" + fpu_expr = "^ESC" # TODO + + lprefix1_expr = "\\((66|!F3)\\)" + lprefix2_expr = "\\(F3\\)" + lprefix3_expr = "\\((F2|!F3|66\\&F2)\\)" + lprefix_expr = "\\((66|F2|F3)\\)" + max_lprefix = 4 + + # All opcodes starting with lower-case 'v', 'k' or with (v1) superscript + # accepts VEX prefix + vexok_opcode_expr = "^[vk].*" + vexok_expr = "\\(v1\\)" + # All opcodes with (v) superscript supports *only* VEX prefix + vexonly_expr = "\\(v\\)" + # All opcodes with (ev) superscript supports *only* EVEX prefix + evexonly_expr = "\\(ev\\)" + + prefix_expr = "\\(Prefix\\)" + prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ" + prefix_num["REPNE"] = "INAT_PFX_REPNE" + prefix_num["REP/REPE"] = "INAT_PFX_REPE" + prefix_num["XACQUIRE"] = "INAT_PFX_REPNE" + prefix_num["XRELEASE"] = "INAT_PFX_REPE" + prefix_num["LOCK"] = "INAT_PFX_LOCK" + prefix_num["SEG=CS"] = "INAT_PFX_CS" + prefix_num["SEG=DS"] = "INAT_PFX_DS" + prefix_num["SEG=ES"] = "INAT_PFX_ES" + prefix_num["SEG=FS"] = "INAT_PFX_FS" + prefix_num["SEG=GS"] = "INAT_PFX_GS" + prefix_num["SEG=SS"] = "INAT_PFX_SS" + prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ" + prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" + prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" + prefix_num["EVEX"] = "INAT_PFX_EVEX" + + clear_vars() +} + +function semantic_error(msg) { + print "Semantic error at " NR ": " msg > "/dev/stderr" + exit 1 +} + +function debug(msg) { + print "DEBUG: " msg +} + +function array_size(arr, i,c) { + c = 0 + for (i in arr) + c++ + return c +} + +/^Table:/ { + print "/* " $0 " */" + if (tname != "") + semantic_error("Hit Table: before EndTable:."); +} + +/^Referrer:/ { + if (NF != 1) { + # escape opcode table + ref = "" + for (i = 2; i <= NF; i++) + ref = ref $i + eid = escape[ref] + tname = sprintf("inat_escape_table_%d", eid) + } +} + +/^AVXcode:/ { + if (NF != 1) { + # AVX/escape opcode table + aid = $2 + if (gaid <= aid) + gaid = aid + 1 + if (tname == "") # AVX only opcode table + tname = sprintf("inat_avx_table_%d", $2) + } + if (aid == -1 && eid == -1) # primary opcode table + tname = "inat_primary_table" +} + +/^GrpTable:/ { + print "/* " $0 " */" + if (!($2 in group)) + semantic_error("No group: " $2 ) + gid = group[$2] + tname = "inat_group_table_" gid +} + +function print_table(tbl,name,fmt,n) +{ + print "const insn_attr_t " name " = {" + for (i = 0; i < n; i++) { + id = sprintf(fmt, i) + if (tbl[id]) + print " [" id "] = " tbl[id] "," + } + print "};" +} + +/^EndTable/ { + if (gid != -1) { + # print group tables + if (array_size(table) != 0) { + print_table(table, tname "[INAT_GROUP_TABLE_SIZE]", + "0x%x", 8) + gtable[gid,0] = tname + } + if (array_size(lptable1) != 0) { + print_table(lptable1, tname "_1[INAT_GROUP_TABLE_SIZE]", + "0x%x", 8) + gtable[gid,1] = tname "_1" + } + if (array_size(lptable2) != 0) { + print_table(lptable2, tname "_2[INAT_GROUP_TABLE_SIZE]", + "0x%x", 8) + gtable[gid,2] = tname "_2" + } + if (array_size(lptable3) != 0) { + print_table(lptable3, tname "_3[INAT_GROUP_TABLE_SIZE]", + "0x%x", 8) + gtable[gid,3] = tname "_3" + } + } else { + # print primary/escaped tables + if (array_size(table) != 0) { + print_table(table, tname "[INAT_OPCODE_TABLE_SIZE]", + "0x%02x", 256) + etable[eid,0] = tname + if (aid >= 0) + atable[aid,0] = tname + } + if (array_size(lptable1) != 0) { + print_table(lptable1,tname "_1[INAT_OPCODE_TABLE_SIZE]", + "0x%02x", 256) + etable[eid,1] = tname "_1" + if (aid >= 0) + atable[aid,1] = tname "_1" + } + if (array_size(lptable2) != 0) { + print_table(lptable2,tname "_2[INAT_OPCODE_TABLE_SIZE]", + "0x%02x", 256) + etable[eid,2] = tname "_2" + if (aid >= 0) + atable[aid,2] = tname "_2" + } + if (array_size(lptable3) != 0) { + print_table(lptable3,tname "_3[INAT_OPCODE_TABLE_SIZE]", + "0x%02x", 256) + etable[eid,3] = tname "_3" + if (aid >= 0) + atable[aid,3] = tname "_3" + } + } + print "" + clear_vars() +} + +function add_flags(old,new) { + if (old && new) + return old " | " new + else if (old) + return old + else + return new +} + +# convert operands to flags. +function convert_operands(count,opnd, i,j,imm,mod) +{ + imm = null + mod = null + for (j = 1; j <= count; j++) { + i = opnd[j] + if (match(i, imm_expr) == 1) { + if (!imm_flag[i]) + semantic_error("Unknown imm opnd: " i) + if (imm) { + if (i != "Ib") + semantic_error("Second IMM error") + imm = add_flags(imm, "INAT_SCNDIMM") + } else + imm = imm_flag[i] + } else if (match(i, modrm_expr)) + mod = "INAT_MODRM" + } + return add_flags(imm, mod) +} + +/^[0-9a-f]+\:/ { + if (NR == 1) + next + # get index + idx = "0x" substr($1, 1, index($1,":") - 1) + if (idx in table) + semantic_error("Redefine " idx " in " tname) + + # check if escaped opcode + if ("escape" == $2) { + if ($3 != "#") + semantic_error("No escaped name") + ref = "" + for (i = 4; i <= NF; i++) + ref = ref $i + if (ref in escape) + semantic_error("Redefine escape (" ref ")") + escape[ref] = geid + geid++ + table[idx] = "INAT_MAKE_ESCAPE(" escape[ref] ")" + next + } + + variant = null + # converts + i = 2 + while (i <= NF) { + opcode = $(i++) + delete opnds + ext = null + flags = null + opnd = null + # parse one opcode + if (match($i, opnd_expr)) { + opnd = $i + count = split($(i++), opnds, ",") + flags = convert_operands(count, opnds) + } + if (match($i, ext_expr)) + ext = $(i++) + if (match($i, sep_expr)) + i++ + else if (i < NF) + semantic_error($i " is not a separator") + + # check if group opcode + if (match(opcode, group_expr)) { + if (!(opcode in group)) { + group[opcode] = ggid + ggid++ + } + flags = add_flags(flags, "INAT_MAKE_GROUP(" group[opcode] ")") + } + # check force(or default) 64bit + if (match(ext, force64_expr)) + flags = add_flags(flags, "INAT_FORCE64") + + # check REX prefix + if (match(opcode, rex_expr)) + flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)") + + # check coprocessor escape : TODO + if (match(opcode, fpu_expr)) + flags = add_flags(flags, "INAT_MODRM") + + # check VEX codes + if (match(ext, evexonly_expr)) + flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY") + else if (match(ext, vexonly_expr)) + flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY") + else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr)) + flags = add_flags(flags, "INAT_VEXOK") + + # check prefixes + if (match(ext, prefix_expr)) { + if (!prefix_num[opcode]) + semantic_error("Unknown prefix: " opcode) + flags = add_flags(flags, "INAT_MAKE_PREFIX(" prefix_num[opcode] ")") + } + if (length(flags) == 0) + continue + # check if last prefix + if (match(ext, lprefix1_expr)) { + lptable1[idx] = add_flags(lptable1[idx],flags) + variant = "INAT_VARIANT" + } + if (match(ext, lprefix2_expr)) { + lptable2[idx] = add_flags(lptable2[idx],flags) + variant = "INAT_VARIANT" + } + if (match(ext, lprefix3_expr)) { + lptable3[idx] = add_flags(lptable3[idx],flags) + variant = "INAT_VARIANT" + } + if (!match(ext, lprefix_expr)){ + table[idx] = add_flags(table[idx],flags) + } + } + if (variant) + table[idx] = add_flags(table[idx],variant) +} + +END { + if (awkchecked != "") + exit 1 + # print escape opcode map's array + print "/* Escape opcode map array */" + print "const insn_attr_t * const inat_escape_tables[INAT_ESC_MAX + 1]" \ + "[INAT_LSTPFX_MAX + 1] = {" + for (i = 0; i < geid; i++) + for (j = 0; j < max_lprefix; j++) + if (etable[i,j]) + print " ["i"]["j"] = "etable[i,j]"," + print "};\n" + # print group opcode map's array + print "/* Group opcode map array */" + print "const insn_attr_t * const inat_group_tables[INAT_GRP_MAX + 1]"\ + "[INAT_LSTPFX_MAX + 1] = {" + for (i = 0; i < ggid; i++) + for (j = 0; j < max_lprefix; j++) + if (gtable[i,j]) + print " ["i"]["j"] = "gtable[i,j]"," + print "};\n" + # print AVX opcode map's array + print "/* AVX opcode map array */" + print "const insn_attr_t * const inat_avx_tables[X86_VEX_M_MAX + 1]"\ + "[INAT_LSTPFX_MAX + 1] = {" + for (i = 0; i < gaid; i++) + for (j = 0; j < max_lprefix; j++) + if (atable[i,j]) + print " ["i"]["j"] = "atable[i,j]"," + print "};" +} + diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index 88158239622b..8c9b9adc67ef 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -33,7 +33,7 @@ all: $(OBJTOOL) INCLUDES := -I$(srctree)/tools/include \ -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \ - -I$(srctree)/tools/objtool/arch/$(ARCH)/include + -I$(srctree)/tools/arch/$(ARCH)/include WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed CFLAGS += -Werror $(WARNINGS) $(KBUILD_HOSTCFLAGS) -g $(INCLUDES) $(LIBELF_FLAGS) LDFLAGS += $(LIBELF_LIBS) $(LIBSUBCMD) $(KBUILD_HOSTLDFLAGS) @@ -60,7 +60,7 @@ $(LIBSUBCMD): fixdep FORCE clean: $(call QUIET_CLEAN, objtool) $(RM) $(OBJTOOL) $(Q)find $(OUTPUT) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete - $(Q)$(RM) $(OUTPUT)arch/x86/lib/inat-tables.c $(OUTPUT)fixdep + $(Q)$(RM) $(OUTPUT)arch/x86/inat-tables.c $(OUTPUT)fixdep FORCE: diff --git a/tools/objtool/arch/x86/Build b/tools/objtool/arch/x86/Build index b998412c017d..7c5004008e97 100644 --- a/tools/objtool/arch/x86/Build +++ b/tools/objtool/arch/x86/Build @@ -1,7 +1,7 @@ objtool-y += decode.o -inat_tables_script = arch/x86/tools/gen-insn-attr-x86.awk -inat_tables_maps = arch/x86/lib/x86-opcode-map.txt +inat_tables_script = ../arch/x86/tools/gen-insn-attr-x86.awk +inat_tables_maps = ../arch/x86/lib/x86-opcode-map.txt $(OUTPUT)arch/x86/lib/inat-tables.c: $(inat_tables_script) $(inat_tables_maps) $(call rule_mkdir) diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c index 0567c47a91b1..a62e032863a8 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -8,8 +8,8 @@ #define unlikely(cond) (cond) #include -#include "lib/inat.c" -#include "lib/insn.c" +#include "../../../arch/x86/lib/inat.c" +#include "../../../arch/x86/lib/insn.c" #include "../../elf.h" #include "../../arch.h" diff --git a/tools/objtool/arch/x86/include/asm/inat.h b/tools/objtool/arch/x86/include/asm/inat.h deleted file mode 100644 index 4cf2ad521f65..000000000000 --- a/tools/objtool/arch/x86/include/asm/inat.h +++ /dev/null @@ -1,230 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -#ifndef _ASM_X86_INAT_H -#define _ASM_X86_INAT_H -/* - * x86 instruction attributes - * - * Written by Masami Hiramatsu - */ -#include - -/* - * Internal bits. Don't use bitmasks directly, because these bits are - * unstable. You should use checking functions. - */ - -#define INAT_OPCODE_TABLE_SIZE 256 -#define INAT_GROUP_TABLE_SIZE 8 - -/* Legacy last prefixes */ -#define INAT_PFX_OPNDSZ 1 /* 0x66 */ /* LPFX1 */ -#define INAT_PFX_REPE 2 /* 0xF3 */ /* LPFX2 */ -#define INAT_PFX_REPNE 3 /* 0xF2 */ /* LPFX3 */ -/* Other Legacy prefixes */ -#define INAT_PFX_LOCK 4 /* 0xF0 */ -#define INAT_PFX_CS 5 /* 0x2E */ -#define INAT_PFX_DS 6 /* 0x3E */ -#define INAT_PFX_ES 7 /* 0x26 */ -#define INAT_PFX_FS 8 /* 0x64 */ -#define INAT_PFX_GS 9 /* 0x65 */ -#define INAT_PFX_SS 10 /* 0x36 */ -#define INAT_PFX_ADDRSZ 11 /* 0x67 */ -/* x86-64 REX prefix */ -#define INAT_PFX_REX 12 /* 0x4X */ -/* AVX VEX prefixes */ -#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */ -#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */ -#define INAT_PFX_EVEX 15 /* EVEX prefix */ - -#define INAT_LSTPFX_MAX 3 -#define INAT_LGCPFX_MAX 11 - -/* Immediate size */ -#define INAT_IMM_BYTE 1 -#define INAT_IMM_WORD 2 -#define INAT_IMM_DWORD 3 -#define INAT_IMM_QWORD 4 -#define INAT_IMM_PTR 5 -#define INAT_IMM_VWORD32 6 -#define INAT_IMM_VWORD 7 - -/* Legacy prefix */ -#define INAT_PFX_OFFS 0 -#define INAT_PFX_BITS 4 -#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1) -#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS) -/* Escape opcodes */ -#define INAT_ESC_OFFS (INAT_PFX_OFFS + INAT_PFX_BITS) -#define INAT_ESC_BITS 2 -#define INAT_ESC_MAX ((1 << INAT_ESC_BITS) - 1) -#define INAT_ESC_MASK (INAT_ESC_MAX << INAT_ESC_OFFS) -/* Group opcodes (1-16) */ -#define INAT_GRP_OFFS (INAT_ESC_OFFS + INAT_ESC_BITS) -#define INAT_GRP_BITS 5 -#define INAT_GRP_MAX ((1 << INAT_GRP_BITS) - 1) -#define INAT_GRP_MASK (INAT_GRP_MAX << INAT_GRP_OFFS) -/* Immediates */ -#define INAT_IMM_OFFS (INAT_GRP_OFFS + INAT_GRP_BITS) -#define INAT_IMM_BITS 3 -#define INAT_IMM_MASK (((1 << INAT_IMM_BITS) - 1) << INAT_IMM_OFFS) -/* Flags */ -#define INAT_FLAG_OFFS (INAT_IMM_OFFS + INAT_IMM_BITS) -#define INAT_MODRM (1 << (INAT_FLAG_OFFS)) -#define INAT_FORCE64 (1 << (INAT_FLAG_OFFS + 1)) -#define INAT_SCNDIMM (1 << (INAT_FLAG_OFFS + 2)) -#define INAT_MOFFSET (1 << (INAT_FLAG_OFFS + 3)) -#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4)) -#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5)) -#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6)) -#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7)) -/* Attribute making macros for attribute tables */ -#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS) -#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS) -#define INAT_MAKE_GROUP(grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM) -#define INAT_MAKE_IMM(imm) (imm << INAT_IMM_OFFS) - -/* Identifiers for segment registers */ -#define INAT_SEG_REG_IGNORE 0 -#define INAT_SEG_REG_DEFAULT 1 -#define INAT_SEG_REG_CS 2 -#define INAT_SEG_REG_SS 3 -#define INAT_SEG_REG_DS 4 -#define INAT_SEG_REG_ES 5 -#define INAT_SEG_REG_FS 6 -#define INAT_SEG_REG_GS 7 - -/* Attribute search APIs */ -extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode); -extern int inat_get_last_prefix_id(insn_byte_t last_pfx); -extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, - int lpfx_id, - insn_attr_t esc_attr); -extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm, - int lpfx_id, - insn_attr_t esc_attr); -extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, - insn_byte_t vex_m, - insn_byte_t vex_pp); - -/* Attribute checking functions */ -static inline int inat_is_legacy_prefix(insn_attr_t attr) -{ - attr &= INAT_PFX_MASK; - return attr && attr <= INAT_LGCPFX_MAX; -} - -static inline int inat_is_address_size_prefix(insn_attr_t attr) -{ - return (attr & INAT_PFX_MASK) == INAT_PFX_ADDRSZ; -} - -static inline int inat_is_operand_size_prefix(insn_attr_t attr) -{ - return (attr & INAT_PFX_MASK) == INAT_PFX_OPNDSZ; -} - -static inline int inat_is_rex_prefix(insn_attr_t attr) -{ - return (attr & INAT_PFX_MASK) == INAT_PFX_REX; -} - -static inline int inat_last_prefix_id(insn_attr_t attr) -{ - if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX) - return 0; - else - return attr & INAT_PFX_MASK; -} - -static inline int inat_is_vex_prefix(insn_attr_t attr) -{ - attr &= INAT_PFX_MASK; - return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 || - attr == INAT_PFX_EVEX; -} - -static inline int inat_is_evex_prefix(insn_attr_t attr) -{ - return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX; -} - -static inline int inat_is_vex3_prefix(insn_attr_t attr) -{ - return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3; -} - -static inline int inat_is_escape(insn_attr_t attr) -{ - return attr & INAT_ESC_MASK; -} - -static inline int inat_escape_id(insn_attr_t attr) -{ - return (attr & INAT_ESC_MASK) >> INAT_ESC_OFFS; -} - -static inline int inat_is_group(insn_attr_t attr) -{ - return attr & INAT_GRP_MASK; -} - -static inline int inat_group_id(insn_attr_t attr) -{ - return (attr & INAT_GRP_MASK) >> INAT_GRP_OFFS; -} - -static inline int inat_group_common_attribute(insn_attr_t attr) -{ - return attr & ~INAT_GRP_MASK; -} - -static inline int inat_has_immediate(insn_attr_t attr) -{ - return attr & INAT_IMM_MASK; -} - -static inline int inat_immediate_size(insn_attr_t attr) -{ - return (attr & INAT_IMM_MASK) >> INAT_IMM_OFFS; -} - -static inline int inat_has_modrm(insn_attr_t attr) -{ - return attr & INAT_MODRM; -} - -static inline int inat_is_force64(insn_attr_t attr) -{ - return attr & INAT_FORCE64; -} - -static inline int inat_has_second_immediate(insn_attr_t attr) -{ - return attr & INAT_SCNDIMM; -} - -static inline int inat_has_moffset(insn_attr_t attr) -{ - return attr & INAT_MOFFSET; -} - -static inline int inat_has_variant(insn_attr_t attr) -{ - return attr & INAT_VARIANT; -} - -static inline int inat_accept_vex(insn_attr_t attr) -{ - return attr & INAT_VEXOK; -} - -static inline int inat_must_vex(insn_attr_t attr) -{ - return attr & (INAT_VEXONLY | INAT_EVEXONLY); -} - -static inline int inat_must_evex(insn_attr_t attr) -{ - return attr & INAT_EVEXONLY; -} -#endif diff --git a/tools/objtool/arch/x86/include/asm/inat_types.h b/tools/objtool/arch/x86/include/asm/inat_types.h deleted file mode 100644 index b047efa9ddc2..000000000000 --- a/tools/objtool/arch/x86/include/asm/inat_types.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -#ifndef _ASM_X86_INAT_TYPES_H -#define _ASM_X86_INAT_TYPES_H -/* - * x86 instruction attributes - * - * Written by Masami Hiramatsu - */ - -/* Instruction attributes */ -typedef unsigned int insn_attr_t; -typedef unsigned char insn_byte_t; -typedef signed int insn_value_t; - -#endif diff --git a/tools/objtool/arch/x86/include/asm/insn.h b/tools/objtool/arch/x86/include/asm/insn.h deleted file mode 100644 index 154f27be8bfc..000000000000 --- a/tools/objtool/arch/x86/include/asm/insn.h +++ /dev/null @@ -1,216 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -#ifndef _ASM_X86_INSN_H -#define _ASM_X86_INSN_H -/* - * x86 instruction analysis - * - * Copyright (C) IBM Corporation, 2009 - */ - -/* insn_attr_t is defined in inat.h */ -#include - -struct insn_field { - union { - insn_value_t value; - insn_byte_t bytes[4]; - }; - /* !0 if we've run insn_get_xxx() for this field */ - unsigned char got; - unsigned char nbytes; -}; - -struct insn { - struct insn_field prefixes; /* - * Prefixes - * prefixes.bytes[3]: last prefix - */ - struct insn_field rex_prefix; /* REX prefix */ - struct insn_field vex_prefix; /* VEX prefix */ - struct insn_field opcode; /* - * opcode.bytes[0]: opcode1 - * opcode.bytes[1]: opcode2 - * opcode.bytes[2]: opcode3 - */ - struct insn_field modrm; - struct insn_field sib; - struct insn_field displacement; - union { - struct insn_field immediate; - struct insn_field moffset1; /* for 64bit MOV */ - struct insn_field immediate1; /* for 64bit imm or off16/32 */ - }; - union { - struct insn_field moffset2; /* for 64bit MOV */ - struct insn_field immediate2; /* for 64bit imm or seg16 */ - }; - - insn_attr_t attr; - unsigned char opnd_bytes; - unsigned char addr_bytes; - unsigned char length; - unsigned char x86_64; - - const insn_byte_t *kaddr; /* kernel address of insn to analyze */ - const insn_byte_t *end_kaddr; /* kernel address of last insn in buffer */ - const insn_byte_t *next_byte; -}; - -#define MAX_INSN_SIZE 15 - -#define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6) -#define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3) -#define X86_MODRM_RM(modrm) ((modrm) & 0x07) - -#define X86_SIB_SCALE(sib) (((sib) & 0xc0) >> 6) -#define X86_SIB_INDEX(sib) (((sib) & 0x38) >> 3) -#define X86_SIB_BASE(sib) ((sib) & 0x07) - -#define X86_REX_W(rex) ((rex) & 8) -#define X86_REX_R(rex) ((rex) & 4) -#define X86_REX_X(rex) ((rex) & 2) -#define X86_REX_B(rex) ((rex) & 1) - -/* VEX bit flags */ -#define X86_VEX_W(vex) ((vex) & 0x80) /* VEX3 Byte2 */ -#define X86_VEX_R(vex) ((vex) & 0x80) /* VEX2/3 Byte1 */ -#define X86_VEX_X(vex) ((vex) & 0x40) /* VEX3 Byte1 */ -#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */ -#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */ -/* VEX bit fields */ -#define X86_EVEX_M(vex) ((vex) & 0x03) /* EVEX Byte1 */ -#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */ -#define X86_VEX2_M 1 /* VEX2.M always 1 */ -#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */ -#define X86_VEX_P(vex) ((vex) & 0x03) /* VEX3 Byte2, VEX2 Byte1 */ -#define X86_VEX_M_MAX 0x1f /* VEX3.M Maximum value */ - -extern void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64); -extern void insn_get_prefixes(struct insn *insn); -extern void insn_get_opcode(struct insn *insn); -extern void insn_get_modrm(struct insn *insn); -extern void insn_get_sib(struct insn *insn); -extern void insn_get_displacement(struct insn *insn); -extern void insn_get_immediate(struct insn *insn); -extern void insn_get_length(struct insn *insn); - -/* Attribute will be determined after getting ModRM (for opcode groups) */ -static inline void insn_get_attribute(struct insn *insn) -{ - insn_get_modrm(insn); -} - -/* Instruction uses RIP-relative addressing */ -extern int insn_rip_relative(struct insn *insn); - -/* Init insn for kernel text */ -static inline void kernel_insn_init(struct insn *insn, - const void *kaddr, int buf_len) -{ -#ifdef CONFIG_X86_64 - insn_init(insn, kaddr, buf_len, 1); -#else /* CONFIG_X86_32 */ - insn_init(insn, kaddr, buf_len, 0); -#endif -} - -static inline int insn_is_avx(struct insn *insn) -{ - if (!insn->prefixes.got) - insn_get_prefixes(insn); - return (insn->vex_prefix.value != 0); -} - -static inline int insn_is_evex(struct insn *insn) -{ - if (!insn->prefixes.got) - insn_get_prefixes(insn); - return (insn->vex_prefix.nbytes == 4); -} - -/* Ensure this instruction is decoded completely */ -static inline int insn_complete(struct insn *insn) -{ - return insn->opcode.got && insn->modrm.got && insn->sib.got && - insn->displacement.got && insn->immediate.got; -} - -static inline insn_byte_t insn_vex_m_bits(struct insn *insn) -{ - if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */ - return X86_VEX2_M; - else if (insn->vex_prefix.nbytes == 3) /* 3 bytes VEX */ - return X86_VEX3_M(insn->vex_prefix.bytes[1]); - else /* EVEX */ - return X86_EVEX_M(insn->vex_prefix.bytes[1]); -} - -static inline insn_byte_t insn_vex_p_bits(struct insn *insn) -{ - if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */ - return X86_VEX_P(insn->vex_prefix.bytes[1]); - else - return X86_VEX_P(insn->vex_prefix.bytes[2]); -} - -/* Get the last prefix id from last prefix or VEX prefix */ -static inline int insn_last_prefix_id(struct insn *insn) -{ - if (insn_is_avx(insn)) - return insn_vex_p_bits(insn); /* VEX_p is a SIMD prefix id */ - - if (insn->prefixes.bytes[3]) - return inat_get_last_prefix_id(insn->prefixes.bytes[3]); - - return 0; -} - -/* Offset of each field from kaddr */ -static inline int insn_offset_rex_prefix(struct insn *insn) -{ - return insn->prefixes.nbytes; -} -static inline int insn_offset_vex_prefix(struct insn *insn) -{ - return insn_offset_rex_prefix(insn) + insn->rex_prefix.nbytes; -} -static inline int insn_offset_opcode(struct insn *insn) -{ - return insn_offset_vex_prefix(insn) + insn->vex_prefix.nbytes; -} -static inline int insn_offset_modrm(struct insn *insn) -{ - return insn_offset_opcode(insn) + insn->opcode.nbytes; -} -static inline int insn_offset_sib(struct insn *insn) -{ - return insn_offset_modrm(insn) + insn->modrm.nbytes; -} -static inline int insn_offset_displacement(struct insn *insn) -{ - return insn_offset_sib(insn) + insn->sib.nbytes; -} -static inline int insn_offset_immediate(struct insn *insn) -{ - return insn_offset_displacement(insn) + insn->displacement.nbytes; -} - -#define POP_SS_OPCODE 0x1f -#define MOV_SREG_OPCODE 0x8e - -/* - * Intel SDM Vol.3A 6.8.3 states; - * "Any single-step trap that would be delivered following the MOV to SS - * instruction or POP to SS instruction (because EFLAGS.TF is 1) is - * suppressed." - * This function returns true if @insn is MOV SS or POP SS. On these - * instructions, single stepping is suppressed. - */ -static inline int insn_masking_exception(struct insn *insn) -{ - return insn->opcode.bytes[0] == POP_SS_OPCODE || - (insn->opcode.bytes[0] == MOV_SREG_OPCODE && - X86_MODRM_REG(insn->modrm.bytes[0]) == 2); -} - -#endif /* _ASM_X86_INSN_H */ diff --git a/tools/objtool/arch/x86/include/asm/orc_types.h b/tools/objtool/arch/x86/include/asm/orc_types.h deleted file mode 100644 index 6e060907c163..000000000000 --- a/tools/objtool/arch/x86/include/asm/orc_types.h +++ /dev/null @@ -1,97 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2017 Josh Poimboeuf - */ - -#ifndef _ORC_TYPES_H -#define _ORC_TYPES_H - -#include -#include - -/* - * The ORC_REG_* registers are base registers which are used to find other - * registers on the stack. - * - * ORC_REG_PREV_SP, also known as DWARF Call Frame Address (CFA), is the - * address of the previous frame: the caller's SP before it called the current - * function. - * - * ORC_REG_UNDEFINED means the corresponding register's value didn't change in - * the current frame. - * - * The most commonly used base registers are SP and BP -- which the previous SP - * is usually based on -- and PREV_SP and UNDEFINED -- which the previous BP is - * usually based on. - * - * The rest of the base registers are needed for special cases like entry code - * and GCC realigned stacks. - */ -#define ORC_REG_UNDEFINED 0 -#define ORC_REG_PREV_SP 1 -#define ORC_REG_DX 2 -#define ORC_REG_DI 3 -#define ORC_REG_BP 4 -#define ORC_REG_SP 5 -#define ORC_REG_R10 6 -#define ORC_REG_R13 7 -#define ORC_REG_BP_INDIRECT 8 -#define ORC_REG_SP_INDIRECT 9 -#define ORC_REG_MAX 15 - -/* - * ORC_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP (the - * caller's SP right before it made the call). Used for all callable - * functions, i.e. all C code and all callable asm functions. - * - * ORC_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset points - * to a fully populated pt_regs from a syscall, interrupt, or exception. - * - * ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset - * points to the iret return frame. - * - * The UNWIND_HINT macros are used only for the unwind_hint struct. They - * aren't used in struct orc_entry due to size and complexity constraints. - * Objtool converts them to real types when it converts the hints to orc - * entries. - */ -#define ORC_TYPE_CALL 0 -#define ORC_TYPE_REGS 1 -#define ORC_TYPE_REGS_IRET 2 -#define UNWIND_HINT_TYPE_SAVE 3 -#define UNWIND_HINT_TYPE_RESTORE 4 - -#ifndef __ASSEMBLY__ -/* - * This struct is more or less a vastly simplified version of the DWARF Call - * Frame Information standard. It contains only the necessary parts of DWARF - * CFI, simplified for ease of access by the in-kernel unwinder. It tells the - * unwinder how to find the previous SP and BP (and sometimes entry regs) on - * the stack for a given code address. Each instance of the struct corresponds - * to one or more code locations. - */ -struct orc_entry { - s16 sp_offset; - s16 bp_offset; - unsigned sp_reg:4; - unsigned bp_reg:4; - unsigned type:2; - unsigned end:1; -} __packed; - -/* - * This struct is used by asm and inline asm code to manually annotate the - * location of registers on the stack for the ORC unwinder. - * - * Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*. - */ -struct unwind_hint { - u32 ip; - s16 sp_offset; - u8 sp_reg; - u8 type; - u8 end; -}; -#endif /* __ASSEMBLY__ */ - -#endif /* _ORC_TYPES_H */ diff --git a/tools/objtool/arch/x86/lib/inat.c b/tools/objtool/arch/x86/lib/inat.c deleted file mode 100644 index 12539fca75c4..000000000000 --- a/tools/objtool/arch/x86/lib/inat.c +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * x86 instruction attribute tables - * - * Written by Masami Hiramatsu - */ -#include - -/* Attribute tables are generated from opcode map */ -#include "inat-tables.c" - -/* Attribute search APIs */ -insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode) -{ - return inat_primary_table[opcode]; -} - -int inat_get_last_prefix_id(insn_byte_t last_pfx) -{ - insn_attr_t lpfx_attr; - - lpfx_attr = inat_get_opcode_attribute(last_pfx); - return inat_last_prefix_id(lpfx_attr); -} - -insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, int lpfx_id, - insn_attr_t esc_attr) -{ - const insn_attr_t *table; - int n; - - n = inat_escape_id(esc_attr); - - table = inat_escape_tables[n][0]; - if (!table) - return 0; - if (inat_has_variant(table[opcode]) && lpfx_id) { - table = inat_escape_tables[n][lpfx_id]; - if (!table) - return 0; - } - return table[opcode]; -} - -insn_attr_t inat_get_group_attribute(insn_byte_t modrm, int lpfx_id, - insn_attr_t grp_attr) -{ - const insn_attr_t *table; - int n; - - n = inat_group_id(grp_attr); - - table = inat_group_tables[n][0]; - if (!table) - return inat_group_common_attribute(grp_attr); - if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && lpfx_id) { - table = inat_group_tables[n][lpfx_id]; - if (!table) - return inat_group_common_attribute(grp_attr); - } - return table[X86_MODRM_REG(modrm)] | - inat_group_common_attribute(grp_attr); -} - -insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m, - insn_byte_t vex_p) -{ - const insn_attr_t *table; - if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX) - return 0; - /* At first, this checks the master table */ - table = inat_avx_tables[vex_m][0]; - if (!table) - return 0; - if (!inat_is_group(table[opcode]) && vex_p) { - /* If this is not a group, get attribute directly */ - table = inat_avx_tables[vex_m][vex_p]; - if (!table) - return 0; - } - return table[opcode]; -} - diff --git a/tools/objtool/arch/x86/lib/insn.c b/tools/objtool/arch/x86/lib/insn.c deleted file mode 100644 index 0b5862ba6a75..000000000000 --- a/tools/objtool/arch/x86/lib/insn.c +++ /dev/null @@ -1,593 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * x86 instruction analysis - * - * Copyright (C) IBM Corporation, 2002, 2004, 2009 - */ - -#ifdef __KERNEL__ -#include -#else -#include -#endif -#include -#include - -/* Verify next sizeof(t) bytes can be on the same instruction */ -#define validate_next(t, insn, n) \ - ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr) - -#define __get_next(t, insn) \ - ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; }) - -#define __peek_nbyte_next(t, insn, n) \ - ({ t r = *(t*)((insn)->next_byte + n); r; }) - -#define get_next(t, insn) \ - ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); }) - -#define peek_nbyte_next(t, insn, n) \ - ({ if (unlikely(!validate_next(t, insn, n))) goto err_out; __peek_nbyte_next(t, insn, n); }) - -#define peek_next(t, insn) peek_nbyte_next(t, insn, 0) - -/** - * insn_init() - initialize struct insn - * @insn: &struct insn to be initialized - * @kaddr: address (in kernel memory) of instruction (or copy thereof) - * @x86_64: !0 for 64-bit kernel or 64-bit app - */ -void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64) -{ - /* - * Instructions longer than MAX_INSN_SIZE (15 bytes) are invalid - * even if the input buffer is long enough to hold them. - */ - if (buf_len > MAX_INSN_SIZE) - buf_len = MAX_INSN_SIZE; - - memset(insn, 0, sizeof(*insn)); - insn->kaddr = kaddr; - insn->end_kaddr = kaddr + buf_len; - insn->next_byte = kaddr; - insn->x86_64 = x86_64 ? 1 : 0; - insn->opnd_bytes = 4; - if (x86_64) - insn->addr_bytes = 8; - else - insn->addr_bytes = 4; -} - -/** - * insn_get_prefixes - scan x86 instruction prefix bytes - * @insn: &struct insn containing instruction - * - * Populates the @insn->prefixes bitmap, and updates @insn->next_byte - * to point to the (first) opcode. No effect if @insn->prefixes.got - * is already set. - */ -void insn_get_prefixes(struct insn *insn) -{ - struct insn_field *prefixes = &insn->prefixes; - insn_attr_t attr; - insn_byte_t b, lb; - int i, nb; - - if (prefixes->got) - return; - - nb = 0; - lb = 0; - b = peek_next(insn_byte_t, insn); - attr = inat_get_opcode_attribute(b); - while (inat_is_legacy_prefix(attr)) { - /* Skip if same prefix */ - for (i = 0; i < nb; i++) - if (prefixes->bytes[i] == b) - goto found; - if (nb == 4) - /* Invalid instruction */ - break; - prefixes->bytes[nb++] = b; - if (inat_is_address_size_prefix(attr)) { - /* address size switches 2/4 or 4/8 */ - if (insn->x86_64) - insn->addr_bytes ^= 12; - else - insn->addr_bytes ^= 6; - } else if (inat_is_operand_size_prefix(attr)) { - /* oprand size switches 2/4 */ - insn->opnd_bytes ^= 6; - } -found: - prefixes->nbytes++; - insn->next_byte++; - lb = b; - b = peek_next(insn_byte_t, insn); - attr = inat_get_opcode_attribute(b); - } - /* Set the last prefix */ - if (lb && lb != insn->prefixes.bytes[3]) { - if (unlikely(insn->prefixes.bytes[3])) { - /* Swap the last prefix */ - b = insn->prefixes.bytes[3]; - for (i = 0; i < nb; i++) - if (prefixes->bytes[i] == lb) - prefixes->bytes[i] = b; - } - insn->prefixes.bytes[3] = lb; - } - - /* Decode REX prefix */ - if (insn->x86_64) { - b = peek_next(insn_byte_t, insn); - attr = inat_get_opcode_attribute(b); - if (inat_is_rex_prefix(attr)) { - insn->rex_prefix.value = b; - insn->rex_prefix.nbytes = 1; - insn->next_byte++; - if (X86_REX_W(b)) - /* REX.W overrides opnd_size */ - insn->opnd_bytes = 8; - } - } - insn->rex_prefix.got = 1; - - /* Decode VEX prefix */ - b = peek_next(insn_byte_t, insn); - attr = inat_get_opcode_attribute(b); - if (inat_is_vex_prefix(attr)) { - insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1); - if (!insn->x86_64) { - /* - * In 32-bits mode, if the [7:6] bits (mod bits of - * ModRM) on the second byte are not 11b, it is - * LDS or LES or BOUND. - */ - if (X86_MODRM_MOD(b2) != 3) - goto vex_end; - } - insn->vex_prefix.bytes[0] = b; - insn->vex_prefix.bytes[1] = b2; - if (inat_is_evex_prefix(attr)) { - b2 = peek_nbyte_next(insn_byte_t, insn, 2); - insn->vex_prefix.bytes[2] = b2; - b2 = peek_nbyte_next(insn_byte_t, insn, 3); - insn->vex_prefix.bytes[3] = b2; - insn->vex_prefix.nbytes = 4; - insn->next_byte += 4; - if (insn->x86_64 && X86_VEX_W(b2)) - /* VEX.W overrides opnd_size */ - insn->opnd_bytes = 8; - } else if (inat_is_vex3_prefix(attr)) { - b2 = peek_nbyte_next(insn_byte_t, insn, 2); - insn->vex_prefix.bytes[2] = b2; - insn->vex_prefix.nbytes = 3; - insn->next_byte += 3; - if (insn->x86_64 && X86_VEX_W(b2)) - /* VEX.W overrides opnd_size */ - insn->opnd_bytes = 8; - } else { - /* - * For VEX2, fake VEX3-like byte#2. - * Makes it easier to decode vex.W, vex.vvvv, - * vex.L and vex.pp. Masking with 0x7f sets vex.W == 0. - */ - insn->vex_prefix.bytes[2] = b2 & 0x7f; - insn->vex_prefix.nbytes = 2; - insn->next_byte += 2; - } - } -vex_end: - insn->vex_prefix.got = 1; - - prefixes->got = 1; - -err_out: - return; -} - -/** - * insn_get_opcode - collect opcode(s) - * @insn: &struct insn containing instruction - * - * Populates @insn->opcode, updates @insn->next_byte to point past the - * opcode byte(s), and set @insn->attr (except for groups). - * If necessary, first collects any preceding (prefix) bytes. - * Sets @insn->opcode.value = opcode1. No effect if @insn->opcode.got - * is already 1. - */ -void insn_get_opcode(struct insn *insn) -{ - struct insn_field *opcode = &insn->opcode; - insn_byte_t op; - int pfx_id; - if (opcode->got) - return; - if (!insn->prefixes.got) - insn_get_prefixes(insn); - - /* Get first opcode */ - op = get_next(insn_byte_t, insn); - opcode->bytes[0] = op; - opcode->nbytes = 1; - - /* Check if there is VEX prefix or not */ - if (insn_is_avx(insn)) { - insn_byte_t m, p; - m = insn_vex_m_bits(insn); - p = insn_vex_p_bits(insn); - insn->attr = inat_get_avx_attribute(op, m, p); - if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) || - (!inat_accept_vex(insn->attr) && - !inat_is_group(insn->attr))) - insn->attr = 0; /* This instruction is bad */ - goto end; /* VEX has only 1 byte for opcode */ - } - - insn->attr = inat_get_opcode_attribute(op); - while (inat_is_escape(insn->attr)) { - /* Get escaped opcode */ - op = get_next(insn_byte_t, insn); - opcode->bytes[opcode->nbytes++] = op; - pfx_id = insn_last_prefix_id(insn); - insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr); - } - if (inat_must_vex(insn->attr)) - insn->attr = 0; /* This instruction is bad */ -end: - opcode->got = 1; - -err_out: - return; -} - -/** - * insn_get_modrm - collect ModRM byte, if any - * @insn: &struct insn containing instruction - * - * Populates @insn->modrm and updates @insn->next_byte to point past the - * ModRM byte, if any. If necessary, first collects the preceding bytes - * (prefixes and opcode(s)). No effect if @insn->modrm.got is already 1. - */ -void insn_get_modrm(struct insn *insn) -{ - struct insn_field *modrm = &insn->modrm; - insn_byte_t pfx_id, mod; - if (modrm->got) - return; - if (!insn->opcode.got) - insn_get_opcode(insn); - - if (inat_has_modrm(insn->attr)) { - mod = get_next(insn_byte_t, insn); - modrm->value = mod; - modrm->nbytes = 1; - if (inat_is_group(insn->attr)) { - pfx_id = insn_last_prefix_id(insn); - insn->attr = inat_get_group_attribute(mod, pfx_id, - insn->attr); - if (insn_is_avx(insn) && !inat_accept_vex(insn->attr)) - insn->attr = 0; /* This is bad */ - } - } - - if (insn->x86_64 && inat_is_force64(insn->attr)) - insn->opnd_bytes = 8; - modrm->got = 1; - -err_out: - return; -} - - -/** - * insn_rip_relative() - Does instruction use RIP-relative addressing mode? - * @insn: &struct insn containing instruction - * - * If necessary, first collects the instruction up to and including the - * ModRM byte. No effect if @insn->x86_64 is 0. - */ -int insn_rip_relative(struct insn *insn) -{ - struct insn_field *modrm = &insn->modrm; - - if (!insn->x86_64) - return 0; - if (!modrm->got) - insn_get_modrm(insn); - /* - * For rip-relative instructions, the mod field (top 2 bits) - * is zero and the r/m field (bottom 3 bits) is 0x5. - */ - return (modrm->nbytes && (modrm->value & 0xc7) == 0x5); -} - -/** - * insn_get_sib() - Get the SIB byte of instruction - * @insn: &struct insn containing instruction - * - * If necessary, first collects the instruction up to and including the - * ModRM byte. - */ -void insn_get_sib(struct insn *insn) -{ - insn_byte_t modrm; - - if (insn->sib.got) - return; - if (!insn->modrm.got) - insn_get_modrm(insn); - if (insn->modrm.nbytes) { - modrm = (insn_byte_t)insn->modrm.value; - if (insn->addr_bytes != 2 && - X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) { - insn->sib.value = get_next(insn_byte_t, insn); - insn->sib.nbytes = 1; - } - } - insn->sib.got = 1; - -err_out: - return; -} - - -/** - * insn_get_displacement() - Get the displacement of instruction - * @insn: &struct insn containing instruction - * - * If necessary, first collects the instruction up to and including the - * SIB byte. - * Displacement value is sign-expanded. - */ -void insn_get_displacement(struct insn *insn) -{ - insn_byte_t mod, rm, base; - - if (insn->displacement.got) - return; - if (!insn->sib.got) - insn_get_sib(insn); - if (insn->modrm.nbytes) { - /* - * Interpreting the modrm byte: - * mod = 00 - no displacement fields (exceptions below) - * mod = 01 - 1-byte displacement field - * mod = 10 - displacement field is 4 bytes, or 2 bytes if - * address size = 2 (0x67 prefix in 32-bit mode) - * mod = 11 - no memory operand - * - * If address size = 2... - * mod = 00, r/m = 110 - displacement field is 2 bytes - * - * If address size != 2... - * mod != 11, r/m = 100 - SIB byte exists - * mod = 00, SIB base = 101 - displacement field is 4 bytes - * mod = 00, r/m = 101 - rip-relative addressing, displacement - * field is 4 bytes - */ - mod = X86_MODRM_MOD(insn->modrm.value); - rm = X86_MODRM_RM(insn->modrm.value); - base = X86_SIB_BASE(insn->sib.value); - if (mod == 3) - goto out; - if (mod == 1) { - insn->displacement.value = get_next(signed char, insn); - insn->displacement.nbytes = 1; - } else if (insn->addr_bytes == 2) { - if ((mod == 0 && rm == 6) || mod == 2) { - insn->displacement.value = - get_next(short, insn); - insn->displacement.nbytes = 2; - } - } else { - if ((mod == 0 && rm == 5) || mod == 2 || - (mod == 0 && base == 5)) { - insn->displacement.value = get_next(int, insn); - insn->displacement.nbytes = 4; - } - } - } -out: - insn->displacement.got = 1; - -err_out: - return; -} - -/* Decode moffset16/32/64. Return 0 if failed */ -static int __get_moffset(struct insn *insn) -{ - switch (insn->addr_bytes) { - case 2: - insn->moffset1.value = get_next(short, insn); - insn->moffset1.nbytes = 2; - break; - case 4: - insn->moffset1.value = get_next(int, insn); - insn->moffset1.nbytes = 4; - break; - case 8: - insn->moffset1.value = get_next(int, insn); - insn->moffset1.nbytes = 4; - insn->moffset2.value = get_next(int, insn); - insn->moffset2.nbytes = 4; - break; - default: /* opnd_bytes must be modified manually */ - goto err_out; - } - insn->moffset1.got = insn->moffset2.got = 1; - - return 1; - -err_out: - return 0; -} - -/* Decode imm v32(Iz). Return 0 if failed */ -static int __get_immv32(struct insn *insn) -{ - switch (insn->opnd_bytes) { - case 2: - insn->immediate.value = get_next(short, insn); - insn->immediate.nbytes = 2; - break; - case 4: - case 8: - insn->immediate.value = get_next(int, insn); - insn->immediate.nbytes = 4; - break; - default: /* opnd_bytes must be modified manually */ - goto err_out; - } - - return 1; - -err_out: - return 0; -} - -/* Decode imm v64(Iv/Ov), Return 0 if failed */ -static int __get_immv(struct insn *insn) -{ - switch (insn->opnd_bytes) { - case 2: - insn->immediate1.value = get_next(short, insn); - insn->immediate1.nbytes = 2; - break; - case 4: - insn->immediate1.value = get_next(int, insn); - insn->immediate1.nbytes = 4; - break; - case 8: - insn->immediate1.value = get_next(int, insn); - insn->immediate1.nbytes = 4; - insn->immediate2.value = get_next(int, insn); - insn->immediate2.nbytes = 4; - break; - default: /* opnd_bytes must be modified manually */ - goto err_out; - } - insn->immediate1.got = insn->immediate2.got = 1; - - return 1; -err_out: - return 0; -} - -/* Decode ptr16:16/32(Ap) */ -static int __get_immptr(struct insn *insn) -{ - switch (insn->opnd_bytes) { - case 2: - insn->immediate1.value = get_next(short, insn); - insn->immediate1.nbytes = 2; - break; - case 4: - insn->immediate1.value = get_next(int, insn); - insn->immediate1.nbytes = 4; - break; - case 8: - /* ptr16:64 is not exist (no segment) */ - return 0; - default: /* opnd_bytes must be modified manually */ - goto err_out; - } - insn->immediate2.value = get_next(unsigned short, insn); - insn->immediate2.nbytes = 2; - insn->immediate1.got = insn->immediate2.got = 1; - - return 1; -err_out: - return 0; -} - -/** - * insn_get_immediate() - Get the immediates of instruction - * @insn: &struct insn containing instruction - * - * If necessary, first collects the instruction up to and including the - * displacement bytes. - * Basically, most of immediates are sign-expanded. Unsigned-value can be - * get by bit masking with ((1 << (nbytes * 8)) - 1) - */ -void insn_get_immediate(struct insn *insn) -{ - if (insn->immediate.got) - return; - if (!insn->displacement.got) - insn_get_displacement(insn); - - if (inat_has_moffset(insn->attr)) { - if (!__get_moffset(insn)) - goto err_out; - goto done; - } - - if (!inat_has_immediate(insn->attr)) - /* no immediates */ - goto done; - - switch (inat_immediate_size(insn->attr)) { - case INAT_IMM_BYTE: - insn->immediate.value = get_next(signed char, insn); - insn->immediate.nbytes = 1; - break; - case INAT_IMM_WORD: - insn->immediate.value = get_next(short, insn); - insn->immediate.nbytes = 2; - break; - case INAT_IMM_DWORD: - insn->immediate.value = get_next(int, insn); - insn->immediate.nbytes = 4; - break; - case INAT_IMM_QWORD: - insn->immediate1.value = get_next(int, insn); - insn->immediate1.nbytes = 4; - insn->immediate2.value = get_next(int, insn); - insn->immediate2.nbytes = 4; - break; - case INAT_IMM_PTR: - if (!__get_immptr(insn)) - goto err_out; - break; - case INAT_IMM_VWORD32: - if (!__get_immv32(insn)) - goto err_out; - break; - case INAT_IMM_VWORD: - if (!__get_immv(insn)) - goto err_out; - break; - default: - /* Here, insn must have an immediate, but failed */ - goto err_out; - } - if (inat_has_second_immediate(insn->attr)) { - insn->immediate2.value = get_next(signed char, insn); - insn->immediate2.nbytes = 1; - } -done: - insn->immediate.got = 1; - -err_out: - return; -} - -/** - * insn_get_length() - Get the length of instruction - * @insn: &struct insn containing instruction - * - * If necessary, first collects the instruction up to and including the - * immediates bytes. - */ -void insn_get_length(struct insn *insn) -{ - if (insn->length) - return; - if (!insn->immediate.got) - insn_get_immediate(insn); - insn->length = (unsigned char)((unsigned long)insn->next_byte - - (unsigned long)insn->kaddr); -} diff --git a/tools/objtool/arch/x86/lib/x86-opcode-map.txt b/tools/objtool/arch/x86/lib/x86-opcode-map.txt deleted file mode 100644 index e0b85930dd77..000000000000 --- a/tools/objtool/arch/x86/lib/x86-opcode-map.txt +++ /dev/null @@ -1,1072 +0,0 @@ -# x86 Opcode Maps -# -# This is (mostly) based on following documentations. -# - Intel(R) 64 and IA-32 Architectures Software Developer's Manual Vol.2C -# (#326018-047US, June 2013) -# -# -# Table: table-name -# Referrer: escaped-name -# AVXcode: avx-code -# opcode: mnemonic|GrpXXX [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...] -# (or) -# opcode: escape # escaped-name -# EndTable -# -# mnemonics that begin with lowercase 'v' accept a VEX or EVEX prefix -# mnemonics that begin with lowercase 'k' accept a VEX prefix -# -# -# GrpTable: GrpXXX -# reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...] -# EndTable -# -# AVX Superscripts -# (ev): this opcode requires EVEX prefix. -# (evo): this opcode is changed by EVEX prefix (EVEX opcode) -# (v): this opcode requires VEX prefix. -# (v1): this opcode only supports 128bit VEX. -# -# Last Prefix Superscripts -# - (66): the last prefix is 0x66 -# - (F3): the last prefix is 0xF3 -# - (F2): the last prefix is 0xF2 -# - (!F3) : the last prefix is not 0xF3 (including non-last prefix case) -# - (66&F2): Both 0x66 and 0xF2 prefixes are specified. - -Table: one byte opcode -Referrer: -AVXcode: -# 0x00 - 0x0f -00: ADD Eb,Gb -01: ADD Ev,Gv -02: ADD Gb,Eb -03: ADD Gv,Ev -04: ADD AL,Ib -05: ADD rAX,Iz -06: PUSH ES (i64) -07: POP ES (i64) -08: OR Eb,Gb -09: OR Ev,Gv -0a: OR Gb,Eb -0b: OR Gv,Ev -0c: OR AL,Ib -0d: OR rAX,Iz -0e: PUSH CS (i64) -0f: escape # 2-byte escape -# 0x10 - 0x1f -10: ADC Eb,Gb -11: ADC Ev,Gv -12: ADC Gb,Eb -13: ADC Gv,Ev -14: ADC AL,Ib -15: ADC rAX,Iz -16: PUSH SS (i64) -17: POP SS (i64) -18: SBB Eb,Gb -19: SBB Ev,Gv -1a: SBB Gb,Eb -1b: SBB Gv,Ev -1c: SBB AL,Ib -1d: SBB rAX,Iz -1e: PUSH DS (i64) -1f: POP DS (i64) -# 0x20 - 0x2f -20: AND Eb,Gb -21: AND Ev,Gv -22: AND Gb,Eb -23: AND Gv,Ev -24: AND AL,Ib -25: AND rAx,Iz -26: SEG=ES (Prefix) -27: DAA (i64) -28: SUB Eb,Gb -29: SUB Ev,Gv -2a: SUB Gb,Eb -2b: SUB Gv,Ev -2c: SUB AL,Ib -2d: SUB rAX,Iz -2e: SEG=CS (Prefix) -2f: DAS (i64) -# 0x30 - 0x3f -30: XOR Eb,Gb -31: XOR Ev,Gv -32: XOR Gb,Eb -33: XOR Gv,Ev -34: XOR AL,Ib -35: XOR rAX,Iz -36: SEG=SS (Prefix) -37: AAA (i64) -38: CMP Eb,Gb -39: CMP Ev,Gv -3a: CMP Gb,Eb -3b: CMP Gv,Ev -3c: CMP AL,Ib -3d: CMP rAX,Iz -3e: SEG=DS (Prefix) -3f: AAS (i64) -# 0x40 - 0x4f -40: INC eAX (i64) | REX (o64) -41: INC eCX (i64) | REX.B (o64) -42: INC eDX (i64) | REX.X (o64) -43: INC eBX (i64) | REX.XB (o64) -44: INC eSP (i64) | REX.R (o64) -45: INC eBP (i64) | REX.RB (o64) -46: INC eSI (i64) | REX.RX (o64) -47: INC eDI (i64) | REX.RXB (o64) -48: DEC eAX (i64) | REX.W (o64) -49: DEC eCX (i64) | REX.WB (o64) -4a: DEC eDX (i64) | REX.WX (o64) -4b: DEC eBX (i64) | REX.WXB (o64) -4c: DEC eSP (i64) | REX.WR (o64) -4d: DEC eBP (i64) | REX.WRB (o64) -4e: DEC eSI (i64) | REX.WRX (o64) -4f: DEC eDI (i64) | REX.WRXB (o64) -# 0x50 - 0x5f -50: PUSH rAX/r8 (d64) -51: PUSH rCX/r9 (d64) -52: PUSH rDX/r10 (d64) -53: PUSH rBX/r11 (d64) -54: PUSH rSP/r12 (d64) -55: PUSH rBP/r13 (d64) -56: PUSH rSI/r14 (d64) -57: PUSH rDI/r15 (d64) -58: POP rAX/r8 (d64) -59: POP rCX/r9 (d64) -5a: POP rDX/r10 (d64) -5b: POP rBX/r11 (d64) -5c: POP rSP/r12 (d64) -5d: POP rBP/r13 (d64) -5e: POP rSI/r14 (d64) -5f: POP rDI/r15 (d64) -# 0x60 - 0x6f -60: PUSHA/PUSHAD (i64) -61: POPA/POPAD (i64) -62: BOUND Gv,Ma (i64) | EVEX (Prefix) -63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64) -64: SEG=FS (Prefix) -65: SEG=GS (Prefix) -66: Operand-Size (Prefix) -67: Address-Size (Prefix) -68: PUSH Iz (d64) -69: IMUL Gv,Ev,Iz -6a: PUSH Ib (d64) -6b: IMUL Gv,Ev,Ib -6c: INS/INSB Yb,DX -6d: INS/INSW/INSD Yz,DX -6e: OUTS/OUTSB DX,Xb -6f: OUTS/OUTSW/OUTSD DX,Xz -# 0x70 - 0x7f -70: JO Jb -71: JNO Jb -72: JB/JNAE/JC Jb -73: JNB/JAE/JNC Jb -74: JZ/JE Jb -75: JNZ/JNE Jb -76: JBE/JNA Jb -77: JNBE/JA Jb -78: JS Jb -79: JNS Jb -7a: JP/JPE Jb -7b: JNP/JPO Jb -7c: JL/JNGE Jb -7d: JNL/JGE Jb -7e: JLE/JNG Jb -7f: JNLE/JG Jb -# 0x80 - 0x8f -80: Grp1 Eb,Ib (1A) -81: Grp1 Ev,Iz (1A) -82: Grp1 Eb,Ib (1A),(i64) -83: Grp1 Ev,Ib (1A) -84: TEST Eb,Gb -85: TEST Ev,Gv -86: XCHG Eb,Gb -87: XCHG Ev,Gv -88: MOV Eb,Gb -89: MOV Ev,Gv -8a: MOV Gb,Eb -8b: MOV Gv,Ev -8c: MOV Ev,Sw -8d: LEA Gv,M -8e: MOV Sw,Ew -8f: Grp1A (1A) | POP Ev (d64) -# 0x90 - 0x9f -90: NOP | PAUSE (F3) | XCHG r8,rAX -91: XCHG rCX/r9,rAX -92: XCHG rDX/r10,rAX -93: XCHG rBX/r11,rAX -94: XCHG rSP/r12,rAX -95: XCHG rBP/r13,rAX -96: XCHG rSI/r14,rAX -97: XCHG rDI/r15,rAX -98: CBW/CWDE/CDQE -99: CWD/CDQ/CQO -9a: CALLF Ap (i64) -9b: FWAIT/WAIT -9c: PUSHF/D/Q Fv (d64) -9d: POPF/D/Q Fv (d64) -9e: SAHF -9f: LAHF -# 0xa0 - 0xaf -a0: MOV AL,Ob -a1: MOV rAX,Ov -a2: MOV Ob,AL -a3: MOV Ov,rAX -a4: MOVS/B Yb,Xb -a5: MOVS/W/D/Q Yv,Xv -a6: CMPS/B Xb,Yb -a7: CMPS/W/D Xv,Yv -a8: TEST AL,Ib -a9: TEST rAX,Iz -aa: STOS/B Yb,AL -ab: STOS/W/D/Q Yv,rAX -ac: LODS/B AL,Xb -ad: LODS/W/D/Q rAX,Xv -ae: SCAS/B AL,Yb -# Note: The May 2011 Intel manual shows Xv for the second parameter of the -# next instruction but Yv is correct -af: SCAS/W/D/Q rAX,Yv -# 0xb0 - 0xbf -b0: MOV AL/R8L,Ib -b1: MOV CL/R9L,Ib -b2: MOV DL/R10L,Ib -b3: MOV BL/R11L,Ib -b4: MOV AH/R12L,Ib -b5: MOV CH/R13L,Ib -b6: MOV DH/R14L,Ib -b7: MOV BH/R15L,Ib -b8: MOV rAX/r8,Iv -b9: MOV rCX/r9,Iv -ba: MOV rDX/r10,Iv -bb: MOV rBX/r11,Iv -bc: MOV rSP/r12,Iv -bd: MOV rBP/r13,Iv -be: MOV rSI/r14,Iv -bf: MOV rDI/r15,Iv -# 0xc0 - 0xcf -c0: Grp2 Eb,Ib (1A) -c1: Grp2 Ev,Ib (1A) -c2: RETN Iw (f64) -c3: RETN -c4: LES Gz,Mp (i64) | VEX+2byte (Prefix) -c5: LDS Gz,Mp (i64) | VEX+1byte (Prefix) -c6: Grp11A Eb,Ib (1A) -c7: Grp11B Ev,Iz (1A) -c8: ENTER Iw,Ib -c9: LEAVE (d64) -ca: RETF Iw -cb: RETF -cc: INT3 -cd: INT Ib -ce: INTO (i64) -cf: IRET/D/Q -# 0xd0 - 0xdf -d0: Grp2 Eb,1 (1A) -d1: Grp2 Ev,1 (1A) -d2: Grp2 Eb,CL (1A) -d3: Grp2 Ev,CL (1A) -d4: AAM Ib (i64) -d5: AAD Ib (i64) -d6: -d7: XLAT/XLATB -d8: ESC -d9: ESC -da: ESC -db: ESC -dc: ESC -dd: ESC -de: ESC -df: ESC -# 0xe0 - 0xef -# Note: "forced64" is Intel CPU behavior: they ignore 0x66 prefix -# in 64-bit mode. AMD CPUs accept 0x66 prefix, it causes RIP truncation -# to 16 bits. In 32-bit mode, 0x66 is accepted by both Intel and AMD. -e0: LOOPNE/LOOPNZ Jb (f64) -e1: LOOPE/LOOPZ Jb (f64) -e2: LOOP Jb (f64) -e3: JrCXZ Jb (f64) -e4: IN AL,Ib -e5: IN eAX,Ib -e6: OUT Ib,AL -e7: OUT Ib,eAX -# With 0x66 prefix in 64-bit mode, for AMD CPUs immediate offset -# in "near" jumps and calls is 16-bit. For CALL, -# push of return address is 16-bit wide, RSP is decremented by 2 -# but is not truncated to 16 bits, unlike RIP. -e8: CALL Jz (f64) -e9: JMP-near Jz (f64) -ea: JMP-far Ap (i64) -eb: JMP-short Jb (f64) -ec: IN AL,DX -ed: IN eAX,DX -ee: OUT DX,AL -ef: OUT DX,eAX -# 0xf0 - 0xff -f0: LOCK (Prefix) -f1: -f2: REPNE (Prefix) | XACQUIRE (Prefix) -f3: REP/REPE (Prefix) | XRELEASE (Prefix) -f4: HLT -f5: CMC -f6: Grp3_1 Eb (1A) -f7: Grp3_2 Ev (1A) -f8: CLC -f9: STC -fa: CLI -fb: STI -fc: CLD -fd: STD -fe: Grp4 (1A) -ff: Grp5 (1A) -EndTable - -Table: 2-byte opcode (0x0f) -Referrer: 2-byte escape -AVXcode: 1 -# 0x0f 0x00-0x0f -00: Grp6 (1A) -01: Grp7 (1A) -02: LAR Gv,Ew -03: LSL Gv,Ew -04: -05: SYSCALL (o64) -06: CLTS -07: SYSRET (o64) -08: INVD -09: WBINVD -0a: -0b: UD2 (1B) -0c: -# AMD's prefetch group. Intel supports prefetchw(/1) only. -0d: GrpP -0e: FEMMS -# 3DNow! uses the last imm byte as opcode extension. -0f: 3DNow! Pq,Qq,Ib -# 0x0f 0x10-0x1f -# NOTE: According to Intel SDM opcode map, vmovups and vmovupd has no operands -# but it actually has operands. And also, vmovss and vmovsd only accept 128bit. -# MOVSS/MOVSD has too many forms(3) on SDM. This map just shows a typical form. -# Many AVX instructions lack v1 superscript, according to Intel AVX-Prgramming -# Reference A.1 -10: vmovups Vps,Wps | vmovupd Vpd,Wpd (66) | vmovss Vx,Hx,Wss (F3),(v1) | vmovsd Vx,Hx,Wsd (F2),(v1) -11: vmovups Wps,Vps | vmovupd Wpd,Vpd (66) | vmovss Wss,Hx,Vss (F3),(v1) | vmovsd Wsd,Hx,Vsd (F2),(v1) -12: vmovlps Vq,Hq,Mq (v1) | vmovhlps Vq,Hq,Uq (v1) | vmovlpd Vq,Hq,Mq (66),(v1) | vmovsldup Vx,Wx (F3) | vmovddup Vx,Wx (F2) -13: vmovlps Mq,Vq (v1) | vmovlpd Mq,Vq (66),(v1) -14: vunpcklps Vx,Hx,Wx | vunpcklpd Vx,Hx,Wx (66) -15: vunpckhps Vx,Hx,Wx | vunpckhpd Vx,Hx,Wx (66) -16: vmovhps Vdq,Hq,Mq (v1) | vmovlhps Vdq,Hq,Uq (v1) | vmovhpd Vdq,Hq,Mq (66),(v1) | vmovshdup Vx,Wx (F3) -17: vmovhps Mq,Vq (v1) | vmovhpd Mq,Vq (66),(v1) -18: Grp16 (1A) -19: -# Intel SDM opcode map does not list MPX instructions. For now using Gv for -# bnd registers and Ev for everything else is OK because the instruction -# decoder does not use the information except as an indication that there is -# a ModR/M byte. -1a: BNDCL Gv,Ev (F3) | BNDCU Gv,Ev (F2) | BNDMOV Gv,Ev (66) | BNDLDX Gv,Ev -1b: BNDCN Gv,Ev (F2) | BNDMOV Ev,Gv (66) | BNDMK Gv,Ev (F3) | BNDSTX Ev,Gv -1c: -1d: -1e: -1f: NOP Ev -# 0x0f 0x20-0x2f -20: MOV Rd,Cd -21: MOV Rd,Dd -22: MOV Cd,Rd -23: MOV Dd,Rd -24: -25: -26: -27: -28: vmovaps Vps,Wps | vmovapd Vpd,Wpd (66) -29: vmovaps Wps,Vps | vmovapd Wpd,Vpd (66) -2a: cvtpi2ps Vps,Qpi | cvtpi2pd Vpd,Qpi (66) | vcvtsi2ss Vss,Hss,Ey (F3),(v1) | vcvtsi2sd Vsd,Hsd,Ey (F2),(v1) -2b: vmovntps Mps,Vps | vmovntpd Mpd,Vpd (66) -2c: cvttps2pi Ppi,Wps | cvttpd2pi Ppi,Wpd (66) | vcvttss2si Gy,Wss (F3),(v1) | vcvttsd2si Gy,Wsd (F2),(v1) -2d: cvtps2pi Ppi,Wps | cvtpd2pi Qpi,Wpd (66) | vcvtss2si Gy,Wss (F3),(v1) | vcvtsd2si Gy,Wsd (F2),(v1) -2e: vucomiss Vss,Wss (v1) | vucomisd Vsd,Wsd (66),(v1) -2f: vcomiss Vss,Wss (v1) | vcomisd Vsd,Wsd (66),(v1) -# 0x0f 0x30-0x3f -30: WRMSR -31: RDTSC -32: RDMSR -33: RDPMC -34: SYSENTER -35: SYSEXIT -36: -37: GETSEC -38: escape # 3-byte escape 1 -39: -3a: escape # 3-byte escape 2 -3b: -3c: -3d: -3e: -3f: -# 0x0f 0x40-0x4f -40: CMOVO Gv,Ev -41: CMOVNO Gv,Ev | kandw/q Vk,Hk,Uk | kandb/d Vk,Hk,Uk (66) -42: CMOVB/C/NAE Gv,Ev | kandnw/q Vk,Hk,Uk | kandnb/d Vk,Hk,Uk (66) -43: CMOVAE/NB/NC Gv,Ev -44: CMOVE/Z Gv,Ev | knotw/q Vk,Uk | knotb/d Vk,Uk (66) -45: CMOVNE/NZ Gv,Ev | korw/q Vk,Hk,Uk | korb/d Vk,Hk,Uk (66) -46: CMOVBE/NA Gv,Ev | kxnorw/q Vk,Hk,Uk | kxnorb/d Vk,Hk,Uk (66) -47: CMOVA/NBE Gv,Ev | kxorw/q Vk,Hk,Uk | kxorb/d Vk,Hk,Uk (66) -48: CMOVS Gv,Ev -49: CMOVNS Gv,Ev -4a: CMOVP/PE Gv,Ev | kaddw/q Vk,Hk,Uk | kaddb/d Vk,Hk,Uk (66) -4b: CMOVNP/PO Gv,Ev | kunpckbw Vk,Hk,Uk (66) | kunpckwd/dq Vk,Hk,Uk -4c: CMOVL/NGE Gv,Ev -4d: CMOVNL/GE Gv,Ev -4e: CMOVLE/NG Gv,Ev -4f: CMOVNLE/G Gv,Ev -# 0x0f 0x50-0x5f -50: vmovmskps Gy,Ups | vmovmskpd Gy,Upd (66) -51: vsqrtps Vps,Wps | vsqrtpd Vpd,Wpd (66) | vsqrtss Vss,Hss,Wss (F3),(v1) | vsqrtsd Vsd,Hsd,Wsd (F2),(v1) -52: vrsqrtps Vps,Wps | vrsqrtss Vss,Hss,Wss (F3),(v1) -53: vrcpps Vps,Wps | vrcpss Vss,Hss,Wss (F3),(v1) -54: vandps Vps,Hps,Wps | vandpd Vpd,Hpd,Wpd (66) -55: vandnps Vps,Hps,Wps | vandnpd Vpd,Hpd,Wpd (66) -56: vorps Vps,Hps,Wps | vorpd Vpd,Hpd,Wpd (66) -57: vxorps Vps,Hps,Wps | vxorpd Vpd,Hpd,Wpd (66) -58: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1) -59: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1) -5a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1) -5b: vcvtdq2ps Vps,Wdq | vcvtqq2ps Vps,Wqq (evo) | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3) -5c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1) -5d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1) -5e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1) -5f: vmaxps Vps,Hps,Wps | vmaxpd Vpd,Hpd,Wpd (66) | vmaxss Vss,Hss,Wss (F3),(v1) | vmaxsd Vsd,Hsd,Wsd (F2),(v1) -# 0x0f 0x60-0x6f -60: punpcklbw Pq,Qd | vpunpcklbw Vx,Hx,Wx (66),(v1) -61: punpcklwd Pq,Qd | vpunpcklwd Vx,Hx,Wx (66),(v1) -62: punpckldq Pq,Qd | vpunpckldq Vx,Hx,Wx (66),(v1) -63: packsswb Pq,Qq | vpacksswb Vx,Hx,Wx (66),(v1) -64: pcmpgtb Pq,Qq | vpcmpgtb Vx,Hx,Wx (66),(v1) -65: pcmpgtw Pq,Qq | vpcmpgtw Vx,Hx,Wx (66),(v1) -66: pcmpgtd Pq,Qq | vpcmpgtd Vx,Hx,Wx (66),(v1) -67: packuswb Pq,Qq | vpackuswb Vx,Hx,Wx (66),(v1) -68: punpckhbw Pq,Qd | vpunpckhbw Vx,Hx,Wx (66),(v1) -69: punpckhwd Pq,Qd | vpunpckhwd Vx,Hx,Wx (66),(v1) -6a: punpckhdq Pq,Qd | vpunpckhdq Vx,Hx,Wx (66),(v1) -6b: packssdw Pq,Qd | vpackssdw Vx,Hx,Wx (66),(v1) -6c: vpunpcklqdq Vx,Hx,Wx (66),(v1) -6d: vpunpckhqdq Vx,Hx,Wx (66),(v1) -6e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1) -6f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqa32/64 Vx,Wx (66),(evo) | vmovdqu Vx,Wx (F3) | vmovdqu32/64 Vx,Wx (F3),(evo) | vmovdqu8/16 Vx,Wx (F2),(ev) -# 0x0f 0x70-0x7f -70: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1) -71: Grp12 (1A) -72: Grp13 (1A) -73: Grp14 (1A) -74: pcmpeqb Pq,Qq | vpcmpeqb Vx,Hx,Wx (66),(v1) -75: pcmpeqw Pq,Qq | vpcmpeqw Vx,Hx,Wx (66),(v1) -76: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1) -# Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX. -77: emms | vzeroupper | vzeroall -78: VMREAD Ey,Gy | vcvttps2udq/pd2udq Vx,Wpd (evo) | vcvttsd2usi Gv,Wx (F2),(ev) | vcvttss2usi Gv,Wx (F3),(ev) | vcvttps2uqq/pd2uqq Vx,Wx (66),(ev) -79: VMWRITE Gy,Ey | vcvtps2udq/pd2udq Vx,Wpd (evo) | vcvtsd2usi Gv,Wx (F2),(ev) | vcvtss2usi Gv,Wx (F3),(ev) | vcvtps2uqq/pd2uqq Vx,Wx (66),(ev) -7a: vcvtudq2pd/uqq2pd Vpd,Wx (F3),(ev) | vcvtudq2ps/uqq2ps Vpd,Wx (F2),(ev) | vcvttps2qq/pd2qq Vx,Wx (66),(ev) -7b: vcvtusi2sd Vpd,Hpd,Ev (F2),(ev) | vcvtusi2ss Vps,Hps,Ev (F3),(ev) | vcvtps2qq/pd2qq Vx,Wx (66),(ev) -7c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2) -7d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2) -7e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1) -7f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqa32/64 Wx,Vx (66),(evo) | vmovdqu Wx,Vx (F3) | vmovdqu32/64 Wx,Vx (F3),(evo) | vmovdqu8/16 Wx,Vx (F2),(ev) -# 0x0f 0x80-0x8f -# Note: "forced64" is Intel CPU behavior (see comment about CALL insn). -80: JO Jz (f64) -81: JNO Jz (f64) -82: JB/JC/JNAE Jz (f64) -83: JAE/JNB/JNC Jz (f64) -84: JE/JZ Jz (f64) -85: JNE/JNZ Jz (f64) -86: JBE/JNA Jz (f64) -87: JA/JNBE Jz (f64) -88: JS Jz (f64) -89: JNS Jz (f64) -8a: JP/JPE Jz (f64) -8b: JNP/JPO Jz (f64) -8c: JL/JNGE Jz (f64) -8d: JNL/JGE Jz (f64) -8e: JLE/JNG Jz (f64) -8f: JNLE/JG Jz (f64) -# 0x0f 0x90-0x9f -90: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66) -91: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66) -92: SETB/C/NAE Eb | kmovw Vk,Rv | kmovb Vk,Rv (66) | kmovq/d Vk,Rv (F2) -93: SETAE/NB/NC Eb | kmovw Gv,Uk | kmovb Gv,Uk (66) | kmovq/d Gv,Uk (F2) -94: SETE/Z Eb -95: SETNE/NZ Eb -96: SETBE/NA Eb -97: SETA/NBE Eb -98: SETS Eb | kortestw/q Vk,Uk | kortestb/d Vk,Uk (66) -99: SETNS Eb | ktestw/q Vk,Uk | ktestb/d Vk,Uk (66) -9a: SETP/PE Eb -9b: SETNP/PO Eb -9c: SETL/NGE Eb -9d: SETNL/GE Eb -9e: SETLE/NG Eb -9f: SETNLE/G Eb -# 0x0f 0xa0-0xaf -a0: PUSH FS (d64) -a1: POP FS (d64) -a2: CPUID -a3: BT Ev,Gv -a4: SHLD Ev,Gv,Ib -a5: SHLD Ev,Gv,CL -a6: GrpPDLK -a7: GrpRNG -a8: PUSH GS (d64) -a9: POP GS (d64) -aa: RSM -ab: BTS Ev,Gv -ac: SHRD Ev,Gv,Ib -ad: SHRD Ev,Gv,CL -ae: Grp15 (1A),(1C) -af: IMUL Gv,Ev -# 0x0f 0xb0-0xbf -b0: CMPXCHG Eb,Gb -b1: CMPXCHG Ev,Gv -b2: LSS Gv,Mp -b3: BTR Ev,Gv -b4: LFS Gv,Mp -b5: LGS Gv,Mp -b6: MOVZX Gv,Eb -b7: MOVZX Gv,Ew -b8: JMPE (!F3) | POPCNT Gv,Ev (F3) -b9: Grp10 (1A) -ba: Grp8 Ev,Ib (1A) -bb: BTC Ev,Gv -bc: BSF Gv,Ev (!F3) | TZCNT Gv,Ev (F3) -bd: BSR Gv,Ev (!F3) | LZCNT Gv,Ev (F3) -be: MOVSX Gv,Eb -bf: MOVSX Gv,Ew -# 0x0f 0xc0-0xcf -c0: XADD Eb,Gb -c1: XADD Ev,Gv -c2: vcmpps Vps,Hps,Wps,Ib | vcmppd Vpd,Hpd,Wpd,Ib (66) | vcmpss Vss,Hss,Wss,Ib (F3),(v1) | vcmpsd Vsd,Hsd,Wsd,Ib (F2),(v1) -c3: movnti My,Gy -c4: pinsrw Pq,Ry/Mw,Ib | vpinsrw Vdq,Hdq,Ry/Mw,Ib (66),(v1) -c5: pextrw Gd,Nq,Ib | vpextrw Gd,Udq,Ib (66),(v1) -c6: vshufps Vps,Hps,Wps,Ib | vshufpd Vpd,Hpd,Wpd,Ib (66) -c7: Grp9 (1A) -c8: BSWAP RAX/EAX/R8/R8D -c9: BSWAP RCX/ECX/R9/R9D -ca: BSWAP RDX/EDX/R10/R10D -cb: BSWAP RBX/EBX/R11/R11D -cc: BSWAP RSP/ESP/R12/R12D -cd: BSWAP RBP/EBP/R13/R13D -ce: BSWAP RSI/ESI/R14/R14D -cf: BSWAP RDI/EDI/R15/R15D -# 0x0f 0xd0-0xdf -d0: vaddsubpd Vpd,Hpd,Wpd (66) | vaddsubps Vps,Hps,Wps (F2) -d1: psrlw Pq,Qq | vpsrlw Vx,Hx,Wx (66),(v1) -d2: psrld Pq,Qq | vpsrld Vx,Hx,Wx (66),(v1) -d3: psrlq Pq,Qq | vpsrlq Vx,Hx,Wx (66),(v1) -d4: paddq Pq,Qq | vpaddq Vx,Hx,Wx (66),(v1) -d5: pmullw Pq,Qq | vpmullw Vx,Hx,Wx (66),(v1) -d6: vmovq Wq,Vq (66),(v1) | movq2dq Vdq,Nq (F3) | movdq2q Pq,Uq (F2) -d7: pmovmskb Gd,Nq | vpmovmskb Gd,Ux (66),(v1) -d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1) -d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1) -da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1) -db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) | vpandd/q Vx,Hx,Wx (66),(evo) -dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1) -dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1) -de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1) -df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) | vpandnd/q Vx,Hx,Wx (66),(evo) -# 0x0f 0xe0-0xef -e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1) -e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1) -e2: psrad Pq,Qq | vpsrad Vx,Hx,Wx (66),(v1) -e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1) -e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1) -e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1) -e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtdq2pd/qq2pd Vx,Wdq (F3),(evo) | vcvtpd2dq Vx,Wpd (F2) -e7: movntq Mq,Pq | vmovntdq Mx,Vx (66) -e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1) -e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1) -ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1) -eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) | vpord/q Vx,Hx,Wx (66),(evo) -ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1) -ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1) -ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1) -ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) | vpxord/q Vx,Hx,Wx (66),(evo) -# 0x0f 0xf0-0xff -f0: vlddqu Vx,Mx (F2) -f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1) -f2: pslld Pq,Qq | vpslld Vx,Hx,Wx (66),(v1) -f3: psllq Pq,Qq | vpsllq Vx,Hx,Wx (66),(v1) -f4: pmuludq Pq,Qq | vpmuludq Vx,Hx,Wx (66),(v1) -f5: pmaddwd Pq,Qq | vpmaddwd Vx,Hx,Wx (66),(v1) -f6: psadbw Pq,Qq | vpsadbw Vx,Hx,Wx (66),(v1) -f7: maskmovq Pq,Nq | vmaskmovdqu Vx,Ux (66),(v1) -f8: psubb Pq,Qq | vpsubb Vx,Hx,Wx (66),(v1) -f9: psubw Pq,Qq | vpsubw Vx,Hx,Wx (66),(v1) -fa: psubd Pq,Qq | vpsubd Vx,Hx,Wx (66),(v1) -fb: psubq Pq,Qq | vpsubq Vx,Hx,Wx (66),(v1) -fc: paddb Pq,Qq | vpaddb Vx,Hx,Wx (66),(v1) -fd: paddw Pq,Qq | vpaddw Vx,Hx,Wx (66),(v1) -fe: paddd Pq,Qq | vpaddd Vx,Hx,Wx (66),(v1) -ff: UD0 -EndTable - -Table: 3-byte opcode 1 (0x0f 0x38) -Referrer: 3-byte escape 1 -AVXcode: 2 -# 0x0f 0x38 0x00-0x0f -00: pshufb Pq,Qq | vpshufb Vx,Hx,Wx (66),(v1) -01: phaddw Pq,Qq | vphaddw Vx,Hx,Wx (66),(v1) -02: phaddd Pq,Qq | vphaddd Vx,Hx,Wx (66),(v1) -03: phaddsw Pq,Qq | vphaddsw Vx,Hx,Wx (66),(v1) -04: pmaddubsw Pq,Qq | vpmaddubsw Vx,Hx,Wx (66),(v1) -05: phsubw Pq,Qq | vphsubw Vx,Hx,Wx (66),(v1) -06: phsubd Pq,Qq | vphsubd Vx,Hx,Wx (66),(v1) -07: phsubsw Pq,Qq | vphsubsw Vx,Hx,Wx (66),(v1) -08: psignb Pq,Qq | vpsignb Vx,Hx,Wx (66),(v1) -09: psignw Pq,Qq | vpsignw Vx,Hx,Wx (66),(v1) -0a: psignd Pq,Qq | vpsignd Vx,Hx,Wx (66),(v1) -0b: pmulhrsw Pq,Qq | vpmulhrsw Vx,Hx,Wx (66),(v1) -0c: vpermilps Vx,Hx,Wx (66),(v) -0d: vpermilpd Vx,Hx,Wx (66),(v) -0e: vtestps Vx,Wx (66),(v) -0f: vtestpd Vx,Wx (66),(v) -# 0x0f 0x38 0x10-0x1f -10: pblendvb Vdq,Wdq (66) | vpsrlvw Vx,Hx,Wx (66),(evo) | vpmovuswb Wx,Vx (F3),(ev) -11: vpmovusdb Wx,Vd (F3),(ev) | vpsravw Vx,Hx,Wx (66),(ev) -12: vpmovusqb Wx,Vq (F3),(ev) | vpsllvw Vx,Hx,Wx (66),(ev) -13: vcvtph2ps Vx,Wx (66),(v) | vpmovusdw Wx,Vd (F3),(ev) -14: blendvps Vdq,Wdq (66) | vpmovusqw Wx,Vq (F3),(ev) | vprorvd/q Vx,Hx,Wx (66),(evo) -15: blendvpd Vdq,Wdq (66) | vpmovusqd Wx,Vq (F3),(ev) | vprolvd/q Vx,Hx,Wx (66),(evo) -16: vpermps Vqq,Hqq,Wqq (66),(v) | vpermps/d Vqq,Hqq,Wqq (66),(evo) -17: vptest Vx,Wx (66) -18: vbroadcastss Vx,Wd (66),(v) -19: vbroadcastsd Vqq,Wq (66),(v) | vbroadcastf32x2 Vqq,Wq (66),(evo) -1a: vbroadcastf128 Vqq,Mdq (66),(v) | vbroadcastf32x4/64x2 Vqq,Wq (66),(evo) -1b: vbroadcastf32x8/64x4 Vqq,Mdq (66),(ev) -1c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1) -1d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1) -1e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1) -1f: vpabsq Vx,Wx (66),(ev) -# 0x0f 0x38 0x20-0x2f -20: vpmovsxbw Vx,Ux/Mq (66),(v1) | vpmovswb Wx,Vx (F3),(ev) -21: vpmovsxbd Vx,Ux/Md (66),(v1) | vpmovsdb Wx,Vd (F3),(ev) -22: vpmovsxbq Vx,Ux/Mw (66),(v1) | vpmovsqb Wx,Vq (F3),(ev) -23: vpmovsxwd Vx,Ux/Mq (66),(v1) | vpmovsdw Wx,Vd (F3),(ev) -24: vpmovsxwq Vx,Ux/Md (66),(v1) | vpmovsqw Wx,Vq (F3),(ev) -25: vpmovsxdq Vx,Ux/Mq (66),(v1) | vpmovsqd Wx,Vq (F3),(ev) -26: vptestmb/w Vk,Hx,Wx (66),(ev) | vptestnmb/w Vk,Hx,Wx (F3),(ev) -27: vptestmd/q Vk,Hx,Wx (66),(ev) | vptestnmd/q Vk,Hx,Wx (F3),(ev) -28: vpmuldq Vx,Hx,Wx (66),(v1) | vpmovm2b/w Vx,Uk (F3),(ev) -29: vpcmpeqq Vx,Hx,Wx (66),(v1) | vpmovb2m/w2m Vk,Ux (F3),(ev) -2a: vmovntdqa Vx,Mx (66),(v1) | vpbroadcastmb2q Vx,Uk (F3),(ev) -2b: vpackusdw Vx,Hx,Wx (66),(v1) -2c: vmaskmovps Vx,Hx,Mx (66),(v) | vscalefps/d Vx,Hx,Wx (66),(evo) -2d: vmaskmovpd Vx,Hx,Mx (66),(v) | vscalefss/d Vx,Hx,Wx (66),(evo) -2e: vmaskmovps Mx,Hx,Vx (66),(v) -2f: vmaskmovpd Mx,Hx,Vx (66),(v) -# 0x0f 0x38 0x30-0x3f -30: vpmovzxbw Vx,Ux/Mq (66),(v1) | vpmovwb Wx,Vx (F3),(ev) -31: vpmovzxbd Vx,Ux/Md (66),(v1) | vpmovdb Wx,Vd (F3),(ev) -32: vpmovzxbq Vx,Ux/Mw (66),(v1) | vpmovqb Wx,Vq (F3),(ev) -33: vpmovzxwd Vx,Ux/Mq (66),(v1) | vpmovdw Wx,Vd (F3),(ev) -34: vpmovzxwq Vx,Ux/Md (66),(v1) | vpmovqw Wx,Vq (F3),(ev) -35: vpmovzxdq Vx,Ux/Mq (66),(v1) | vpmovqd Wx,Vq (F3),(ev) -36: vpermd Vqq,Hqq,Wqq (66),(v) | vpermd/q Vqq,Hqq,Wqq (66),(evo) -37: vpcmpgtq Vx,Hx,Wx (66),(v1) -38: vpminsb Vx,Hx,Wx (66),(v1) | vpmovm2d/q Vx,Uk (F3),(ev) -39: vpminsd Vx,Hx,Wx (66),(v1) | vpminsd/q Vx,Hx,Wx (66),(evo) | vpmovd2m/q2m Vk,Ux (F3),(ev) -3a: vpminuw Vx,Hx,Wx (66),(v1) | vpbroadcastmw2d Vx,Uk (F3),(ev) -3b: vpminud Vx,Hx,Wx (66),(v1) | vpminud/q Vx,Hx,Wx (66),(evo) -3c: vpmaxsb Vx,Hx,Wx (66),(v1) -3d: vpmaxsd Vx,Hx,Wx (66),(v1) | vpmaxsd/q Vx,Hx,Wx (66),(evo) -3e: vpmaxuw Vx,Hx,Wx (66),(v1) -3f: vpmaxud Vx,Hx,Wx (66),(v1) | vpmaxud/q Vx,Hx,Wx (66),(evo) -# 0x0f 0x38 0x40-0x8f -40: vpmulld Vx,Hx,Wx (66),(v1) | vpmulld/q Vx,Hx,Wx (66),(evo) -41: vphminposuw Vdq,Wdq (66),(v1) -42: vgetexpps/d Vx,Wx (66),(ev) -43: vgetexpss/d Vx,Hx,Wx (66),(ev) -44: vplzcntd/q Vx,Wx (66),(ev) -45: vpsrlvd/q Vx,Hx,Wx (66),(v) -46: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo) -47: vpsllvd/q Vx,Hx,Wx (66),(v) -# Skip 0x48-0x4b -4c: vrcp14ps/d Vpd,Wpd (66),(ev) -4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev) -4e: vrsqrt14ps/d Vpd,Wpd (66),(ev) -4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev) -# Skip 0x50-0x57 -58: vpbroadcastd Vx,Wx (66),(v) -59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo) -5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo) -5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev) -# Skip 0x5c-0x63 -64: vpblendmd/q Vx,Hx,Wx (66),(ev) -65: vblendmps/d Vx,Hx,Wx (66),(ev) -66: vpblendmb/w Vx,Hx,Wx (66),(ev) -# Skip 0x67-0x74 -75: vpermi2b/w Vx,Hx,Wx (66),(ev) -76: vpermi2d/q Vx,Hx,Wx (66),(ev) -77: vpermi2ps/d Vx,Hx,Wx (66),(ev) -78: vpbroadcastb Vx,Wx (66),(v) -79: vpbroadcastw Vx,Wx (66),(v) -7a: vpbroadcastb Vx,Rv (66),(ev) -7b: vpbroadcastw Vx,Rv (66),(ev) -7c: vpbroadcastd/q Vx,Rv (66),(ev) -7d: vpermt2b/w Vx,Hx,Wx (66),(ev) -7e: vpermt2d/q Vx,Hx,Wx (66),(ev) -7f: vpermt2ps/d Vx,Hx,Wx (66),(ev) -80: INVEPT Gy,Mdq (66) -81: INVVPID Gy,Mdq (66) -82: INVPCID Gy,Mdq (66) -83: vpmultishiftqb Vx,Hx,Wx (66),(ev) -88: vexpandps/d Vpd,Wpd (66),(ev) -89: vpexpandd/q Vx,Wx (66),(ev) -8a: vcompressps/d Wx,Vx (66),(ev) -8b: vpcompressd/q Wx,Vx (66),(ev) -8c: vpmaskmovd/q Vx,Hx,Mx (66),(v) -8d: vpermb/w Vx,Hx,Wx (66),(ev) -8e: vpmaskmovd/q Mx,Vx,Hx (66),(v) -# 0x0f 0x38 0x90-0xbf (FMA) -90: vgatherdd/q Vx,Hx,Wx (66),(v) | vpgatherdd/q Vx,Wx (66),(evo) -91: vgatherqd/q Vx,Hx,Wx (66),(v) | vpgatherqd/q Vx,Wx (66),(evo) -92: vgatherdps/d Vx,Hx,Wx (66),(v) -93: vgatherqps/d Vx,Hx,Wx (66),(v) -94: -95: -96: vfmaddsub132ps/d Vx,Hx,Wx (66),(v) -97: vfmsubadd132ps/d Vx,Hx,Wx (66),(v) -98: vfmadd132ps/d Vx,Hx,Wx (66),(v) -99: vfmadd132ss/d Vx,Hx,Wx (66),(v),(v1) -9a: vfmsub132ps/d Vx,Hx,Wx (66),(v) -9b: vfmsub132ss/d Vx,Hx,Wx (66),(v),(v1) -9c: vfnmadd132ps/d Vx,Hx,Wx (66),(v) -9d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1) -9e: vfnmsub132ps/d Vx,Hx,Wx (66),(v) -9f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1) -a0: vpscatterdd/q Wx,Vx (66),(ev) -a1: vpscatterqd/q Wx,Vx (66),(ev) -a2: vscatterdps/d Wx,Vx (66),(ev) -a3: vscatterqps/d Wx,Vx (66),(ev) -a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v) -a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v) -a8: vfmadd213ps/d Vx,Hx,Wx (66),(v) -a9: vfmadd213ss/d Vx,Hx,Wx (66),(v),(v1) -aa: vfmsub213ps/d Vx,Hx,Wx (66),(v) -ab: vfmsub213ss/d Vx,Hx,Wx (66),(v),(v1) -ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v) -ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1) -ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v) -af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1) -b4: vpmadd52luq Vx,Hx,Wx (66),(ev) -b5: vpmadd52huq Vx,Hx,Wx (66),(ev) -b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v) -b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v) -b8: vfmadd231ps/d Vx,Hx,Wx (66),(v) -b9: vfmadd231ss/d Vx,Hx,Wx (66),(v),(v1) -ba: vfmsub231ps/d Vx,Hx,Wx (66),(v) -bb: vfmsub231ss/d Vx,Hx,Wx (66),(v),(v1) -bc: vfnmadd231ps/d Vx,Hx,Wx (66),(v) -bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1) -be: vfnmsub231ps/d Vx,Hx,Wx (66),(v) -bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1) -# 0x0f 0x38 0xc0-0xff -c4: vpconflictd/q Vx,Wx (66),(ev) -c6: Grp18 (1A) -c7: Grp19 (1A) -c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev) -c9: sha1msg1 Vdq,Wdq -ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev) -cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev) -cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev) -cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev) -db: VAESIMC Vdq,Wdq (66),(v1) -dc: VAESENC Vdq,Hdq,Wdq (66),(v1) -dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1) -de: VAESDEC Vdq,Hdq,Wdq (66),(v1) -df: VAESDECLAST Vdq,Hdq,Wdq (66),(v1) -f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2) -f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2) -f2: ANDN Gy,By,Ey (v) -f3: Grp17 (1A) -f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v) -f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v) -f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v) -EndTable - -Table: 3-byte opcode 2 (0x0f 0x3a) -Referrer: 3-byte escape 2 -AVXcode: 3 -# 0x0f 0x3a 0x00-0xff -00: vpermq Vqq,Wqq,Ib (66),(v) -01: vpermpd Vqq,Wqq,Ib (66),(v) -02: vpblendd Vx,Hx,Wx,Ib (66),(v) -03: valignd/q Vx,Hx,Wx,Ib (66),(ev) -04: vpermilps Vx,Wx,Ib (66),(v) -05: vpermilpd Vx,Wx,Ib (66),(v) -06: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v) -07: -08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo) -09: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo) -0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo) -0b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo) -0c: vblendps Vx,Hx,Wx,Ib (66) -0d: vblendpd Vx,Hx,Wx,Ib (66) -0e: vpblendw Vx,Hx,Wx,Ib (66),(v1) -0f: palignr Pq,Qq,Ib | vpalignr Vx,Hx,Wx,Ib (66),(v1) -14: vpextrb Rd/Mb,Vdq,Ib (66),(v1) -15: vpextrw Rd/Mw,Vdq,Ib (66),(v1) -16: vpextrd/q Ey,Vdq,Ib (66),(v1) -17: vextractps Ed,Vdq,Ib (66),(v1) -18: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) | vinsertf32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo) -19: vextractf128 Wdq,Vqq,Ib (66),(v) | vextractf32x4/64x2 Wdq,Vqq,Ib (66),(evo) -1a: vinsertf32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev) -1b: vextractf32x8/64x4 Wdq,Vqq,Ib (66),(ev) -1d: vcvtps2ph Wx,Vx,Ib (66),(v) -1e: vpcmpud/q Vk,Hd,Wd,Ib (66),(ev) -1f: vpcmpd/q Vk,Hd,Wd,Ib (66),(ev) -20: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1) -21: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1) -22: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1) -23: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev) -25: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev) -26: vgetmantps/d Vx,Wx,Ib (66),(ev) -27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev) -30: kshiftrb/w Vk,Uk,Ib (66),(v) -31: kshiftrd/q Vk,Uk,Ib (66),(v) -32: kshiftlb/w Vk,Uk,Ib (66),(v) -33: kshiftld/q Vk,Uk,Ib (66),(v) -38: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) | vinserti32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo) -39: vextracti128 Wdq,Vqq,Ib (66),(v) | vextracti32x4/64x2 Wdq,Vqq,Ib (66),(evo) -3a: vinserti32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev) -3b: vextracti32x8/64x4 Wdq,Vqq,Ib (66),(ev) -3e: vpcmpub/w Vk,Hk,Wx,Ib (66),(ev) -3f: vpcmpb/w Vk,Hk,Wx,Ib (66),(ev) -40: vdpps Vx,Hx,Wx,Ib (66) -41: vdppd Vdq,Hdq,Wdq,Ib (66),(v1) -42: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) | vdbpsadbw Vx,Hx,Wx,Ib (66),(evo) -43: vshufi32x4/64x2 Vx,Hx,Wx,Ib (66),(ev) -44: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1) -46: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v) -4a: vblendvps Vx,Hx,Wx,Lx (66),(v) -4b: vblendvpd Vx,Hx,Wx,Lx (66),(v) -4c: vpblendvb Vx,Hx,Wx,Lx (66),(v1) -50: vrangeps/d Vx,Hx,Wx,Ib (66),(ev) -51: vrangess/d Vx,Hx,Wx,Ib (66),(ev) -54: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev) -55: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev) -56: vreduceps/d Vx,Wx,Ib (66),(ev) -57: vreducess/d Vx,Hx,Wx,Ib (66),(ev) -60: vpcmpestrm Vdq,Wdq,Ib (66),(v1) -61: vpcmpestri Vdq,Wdq,Ib (66),(v1) -62: vpcmpistrm Vdq,Wdq,Ib (66),(v1) -63: vpcmpistri Vdq,Wdq,Ib (66),(v1) -66: vfpclassps/d Vk,Wx,Ib (66),(ev) -67: vfpclassss/d Vk,Wx,Ib (66),(ev) -cc: sha1rnds4 Vdq,Wdq,Ib -df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1) -f0: RORX Gy,Ey,Ib (F2),(v) -EndTable - -GrpTable: Grp1 -0: ADD -1: OR -2: ADC -3: SBB -4: AND -5: SUB -6: XOR -7: CMP -EndTable - -GrpTable: Grp1A -0: POP -EndTable - -GrpTable: Grp2 -0: ROL -1: ROR -2: RCL -3: RCR -4: SHL/SAL -5: SHR -6: -7: SAR -EndTable - -GrpTable: Grp3_1 -0: TEST Eb,Ib -1: TEST Eb,Ib -2: NOT Eb -3: NEG Eb -4: MUL AL,Eb -5: IMUL AL,Eb -6: DIV AL,Eb -7: IDIV AL,Eb -EndTable - -GrpTable: Grp3_2 -0: TEST Ev,Iz -1: -2: NOT Ev -3: NEG Ev -4: MUL rAX,Ev -5: IMUL rAX,Ev -6: DIV rAX,Ev -7: IDIV rAX,Ev -EndTable - -GrpTable: Grp4 -0: INC Eb -1: DEC Eb -EndTable - -GrpTable: Grp5 -0: INC Ev -1: DEC Ev -# Note: "forced64" is Intel CPU behavior (see comment about CALL insn). -2: CALLN Ev (f64) -3: CALLF Ep -4: JMPN Ev (f64) -5: JMPF Mp -6: PUSH Ev (d64) -7: -EndTable - -GrpTable: Grp6 -0: SLDT Rv/Mw -1: STR Rv/Mw -2: LLDT Ew -3: LTR Ew -4: VERR Ew -5: VERW Ew -EndTable - -GrpTable: Grp7 -0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) -1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B) -2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B) -3: LIDT Ms -4: SMSW Mw/Rv -5: rdpkru (110),(11B) | wrpkru (111),(11B) -6: LMSW Ew -7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B) -EndTable - -GrpTable: Grp8 -4: BT -5: BTS -6: BTR -7: BTC -EndTable - -GrpTable: Grp9 -1: CMPXCHG8B/16B Mq/Mdq -3: xrstors -4: xsavec -5: xsaves -6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B) -7: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B) -EndTable - -GrpTable: Grp10 -# all are UD1 -0: UD1 -1: UD1 -2: UD1 -3: UD1 -4: UD1 -5: UD1 -6: UD1 -7: UD1 -EndTable - -# Grp11A and Grp11B are expressed as Grp11 in Intel SDM -GrpTable: Grp11A -0: MOV Eb,Ib -7: XABORT Ib (000),(11B) -EndTable - -GrpTable: Grp11B -0: MOV Eb,Iz -7: XBEGIN Jz (000),(11B) -EndTable - -GrpTable: Grp12 -2: psrlw Nq,Ib (11B) | vpsrlw Hx,Ux,Ib (66),(11B),(v1) -4: psraw Nq,Ib (11B) | vpsraw Hx,Ux,Ib (66),(11B),(v1) -6: psllw Nq,Ib (11B) | vpsllw Hx,Ux,Ib (66),(11B),(v1) -EndTable - -GrpTable: Grp13 -0: vprord/q Hx,Wx,Ib (66),(ev) -1: vprold/q Hx,Wx,Ib (66),(ev) -2: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1) -4: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) | vpsrad/q Hx,Ux,Ib (66),(evo) -6: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1) -EndTable - -GrpTable: Grp14 -2: psrlq Nq,Ib (11B) | vpsrlq Hx,Ux,Ib (66),(11B),(v1) -3: vpsrldq Hx,Ux,Ib (66),(11B),(v1) -6: psllq Nq,Ib (11B) | vpsllq Hx,Ux,Ib (66),(11B),(v1) -7: vpslldq Hx,Ux,Ib (66),(11B),(v1) -EndTable - -GrpTable: Grp15 -0: fxsave | RDFSBASE Ry (F3),(11B) -1: fxstor | RDGSBASE Ry (F3),(11B) -2: vldmxcsr Md (v1) | WRFSBASE Ry (F3),(11B) -3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B) -4: XSAVE | ptwrite Ey (F3),(11B) -5: XRSTOR | lfence (11B) -6: XSAVEOPT | clwb (66) | mfence (11B) -7: clflush | clflushopt (66) | sfence (11B) -EndTable - -GrpTable: Grp16 -0: prefetch NTA -1: prefetch T0 -2: prefetch T1 -3: prefetch T2 -EndTable - -GrpTable: Grp17 -1: BLSR By,Ey (v) -2: BLSMSK By,Ey (v) -3: BLSI By,Ey (v) -EndTable - -GrpTable: Grp18 -1: vgatherpf0dps/d Wx (66),(ev) -2: vgatherpf1dps/d Wx (66),(ev) -5: vscatterpf0dps/d Wx (66),(ev) -6: vscatterpf1dps/d Wx (66),(ev) -EndTable - -GrpTable: Grp19 -1: vgatherpf0qps/d Wx (66),(ev) -2: vgatherpf1qps/d Wx (66),(ev) -5: vscatterpf0qps/d Wx (66),(ev) -6: vscatterpf1qps/d Wx (66),(ev) -EndTable - -# AMD's Prefetch Group -GrpTable: GrpP -0: PREFETCH -1: PREFETCHW -EndTable - -GrpTable: GrpPDLK -0: MONTMUL -1: XSHA1 -2: XSHA2 -EndTable - -GrpTable: GrpRNG -0: xstore-rng -1: xcrypt-ecb -2: xcrypt-cbc -4: xcrypt-cfb -5: xcrypt-ofb -EndTable diff --git a/tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk b/tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk deleted file mode 100644 index b02a36b2c14f..000000000000 --- a/tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk +++ /dev/null @@ -1,393 +0,0 @@ -#!/bin/awk -f -# SPDX-License-Identifier: GPL-2.0 -# gen-insn-attr-x86.awk: Instruction attribute table generator -# Written by Masami Hiramatsu -# -# Usage: awk -f gen-insn-attr-x86.awk x86-opcode-map.txt > inat-tables.c - -# Awk implementation sanity check -function check_awk_implement() { - if (sprintf("%x", 0) != "0") - return "Your awk has a printf-format problem." - return "" -} - -# Clear working vars -function clear_vars() { - delete table - delete lptable2 - delete lptable1 - delete lptable3 - eid = -1 # escape id - gid = -1 # group id - aid = -1 # AVX id - tname = "" -} - -BEGIN { - # Implementation error checking - awkchecked = check_awk_implement() - if (awkchecked != "") { - print "Error: " awkchecked > "/dev/stderr" - print "Please try to use gawk." > "/dev/stderr" - exit 1 - } - - # Setup generating tables - print "/* x86 opcode map generated from x86-opcode-map.txt */" - print "/* Do not change this code. */\n" - ggid = 1 - geid = 1 - gaid = 0 - delete etable - delete gtable - delete atable - - opnd_expr = "^[A-Za-z/]" - ext_expr = "^\\(" - sep_expr = "^\\|$" - group_expr = "^Grp[0-9A-Za-z]+" - - imm_expr = "^[IJAOL][a-z]" - imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" - imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" - imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)" - imm_flag["Id"] = "INAT_MAKE_IMM(INAT_IMM_DWORD)" - imm_flag["Iq"] = "INAT_MAKE_IMM(INAT_IMM_QWORD)" - imm_flag["Ap"] = "INAT_MAKE_IMM(INAT_IMM_PTR)" - imm_flag["Iz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)" - imm_flag["Jz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)" - imm_flag["Iv"] = "INAT_MAKE_IMM(INAT_IMM_VWORD)" - imm_flag["Ob"] = "INAT_MOFFSET" - imm_flag["Ov"] = "INAT_MOFFSET" - imm_flag["Lx"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" - - modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])" - force64_expr = "\\([df]64\\)" - rex_expr = "^REX(\\.[XRWB]+)*" - fpu_expr = "^ESC" # TODO - - lprefix1_expr = "\\((66|!F3)\\)" - lprefix2_expr = "\\(F3\\)" - lprefix3_expr = "\\((F2|!F3|66\\&F2)\\)" - lprefix_expr = "\\((66|F2|F3)\\)" - max_lprefix = 4 - - # All opcodes starting with lower-case 'v', 'k' or with (v1) superscript - # accepts VEX prefix - vexok_opcode_expr = "^[vk].*" - vexok_expr = "\\(v1\\)" - # All opcodes with (v) superscript supports *only* VEX prefix - vexonly_expr = "\\(v\\)" - # All opcodes with (ev) superscript supports *only* EVEX prefix - evexonly_expr = "\\(ev\\)" - - prefix_expr = "\\(Prefix\\)" - prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ" - prefix_num["REPNE"] = "INAT_PFX_REPNE" - prefix_num["REP/REPE"] = "INAT_PFX_REPE" - prefix_num["XACQUIRE"] = "INAT_PFX_REPNE" - prefix_num["XRELEASE"] = "INAT_PFX_REPE" - prefix_num["LOCK"] = "INAT_PFX_LOCK" - prefix_num["SEG=CS"] = "INAT_PFX_CS" - prefix_num["SEG=DS"] = "INAT_PFX_DS" - prefix_num["SEG=ES"] = "INAT_PFX_ES" - prefix_num["SEG=FS"] = "INAT_PFX_FS" - prefix_num["SEG=GS"] = "INAT_PFX_GS" - prefix_num["SEG=SS"] = "INAT_PFX_SS" - prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ" - prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" - prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" - prefix_num["EVEX"] = "INAT_PFX_EVEX" - - clear_vars() -} - -function semantic_error(msg) { - print "Semantic error at " NR ": " msg > "/dev/stderr" - exit 1 -} - -function debug(msg) { - print "DEBUG: " msg -} - -function array_size(arr, i,c) { - c = 0 - for (i in arr) - c++ - return c -} - -/^Table:/ { - print "/* " $0 " */" - if (tname != "") - semantic_error("Hit Table: before EndTable:."); -} - -/^Referrer:/ { - if (NF != 1) { - # escape opcode table - ref = "" - for (i = 2; i <= NF; i++) - ref = ref $i - eid = escape[ref] - tname = sprintf("inat_escape_table_%d", eid) - } -} - -/^AVXcode:/ { - if (NF != 1) { - # AVX/escape opcode table - aid = $2 - if (gaid <= aid) - gaid = aid + 1 - if (tname == "") # AVX only opcode table - tname = sprintf("inat_avx_table_%d", $2) - } - if (aid == -1 && eid == -1) # primary opcode table - tname = "inat_primary_table" -} - -/^GrpTable:/ { - print "/* " $0 " */" - if (!($2 in group)) - semantic_error("No group: " $2 ) - gid = group[$2] - tname = "inat_group_table_" gid -} - -function print_table(tbl,name,fmt,n) -{ - print "const insn_attr_t " name " = {" - for (i = 0; i < n; i++) { - id = sprintf(fmt, i) - if (tbl[id]) - print " [" id "] = " tbl[id] "," - } - print "};" -} - -/^EndTable/ { - if (gid != -1) { - # print group tables - if (array_size(table) != 0) { - print_table(table, tname "[INAT_GROUP_TABLE_SIZE]", - "0x%x", 8) - gtable[gid,0] = tname - } - if (array_size(lptable1) != 0) { - print_table(lptable1, tname "_1[INAT_GROUP_TABLE_SIZE]", - "0x%x", 8) - gtable[gid,1] = tname "_1" - } - if (array_size(lptable2) != 0) { - print_table(lptable2, tname "_2[INAT_GROUP_TABLE_SIZE]", - "0x%x", 8) - gtable[gid,2] = tname "_2" - } - if (array_size(lptable3) != 0) { - print_table(lptable3, tname "_3[INAT_GROUP_TABLE_SIZE]", - "0x%x", 8) - gtable[gid,3] = tname "_3" - } - } else { - # print primary/escaped tables - if (array_size(table) != 0) { - print_table(table, tname "[INAT_OPCODE_TABLE_SIZE]", - "0x%02x", 256) - etable[eid,0] = tname - if (aid >= 0) - atable[aid,0] = tname - } - if (array_size(lptable1) != 0) { - print_table(lptable1,tname "_1[INAT_OPCODE_TABLE_SIZE]", - "0x%02x", 256) - etable[eid,1] = tname "_1" - if (aid >= 0) - atable[aid,1] = tname "_1" - } - if (array_size(lptable2) != 0) { - print_table(lptable2,tname "_2[INAT_OPCODE_TABLE_SIZE]", - "0x%02x", 256) - etable[eid,2] = tname "_2" - if (aid >= 0) - atable[aid,2] = tname "_2" - } - if (array_size(lptable3) != 0) { - print_table(lptable3,tname "_3[INAT_OPCODE_TABLE_SIZE]", - "0x%02x", 256) - etable[eid,3] = tname "_3" - if (aid >= 0) - atable[aid,3] = tname "_3" - } - } - print "" - clear_vars() -} - -function add_flags(old,new) { - if (old && new) - return old " | " new - else if (old) - return old - else - return new -} - -# convert operands to flags. -function convert_operands(count,opnd, i,j,imm,mod) -{ - imm = null - mod = null - for (j = 1; j <= count; j++) { - i = opnd[j] - if (match(i, imm_expr) == 1) { - if (!imm_flag[i]) - semantic_error("Unknown imm opnd: " i) - if (imm) { - if (i != "Ib") - semantic_error("Second IMM error") - imm = add_flags(imm, "INAT_SCNDIMM") - } else - imm = imm_flag[i] - } else if (match(i, modrm_expr)) - mod = "INAT_MODRM" - } - return add_flags(imm, mod) -} - -/^[0-9a-f]+\:/ { - if (NR == 1) - next - # get index - idx = "0x" substr($1, 1, index($1,":") - 1) - if (idx in table) - semantic_error("Redefine " idx " in " tname) - - # check if escaped opcode - if ("escape" == $2) { - if ($3 != "#") - semantic_error("No escaped name") - ref = "" - for (i = 4; i <= NF; i++) - ref = ref $i - if (ref in escape) - semantic_error("Redefine escape (" ref ")") - escape[ref] = geid - geid++ - table[idx] = "INAT_MAKE_ESCAPE(" escape[ref] ")" - next - } - - variant = null - # converts - i = 2 - while (i <= NF) { - opcode = $(i++) - delete opnds - ext = null - flags = null - opnd = null - # parse one opcode - if (match($i, opnd_expr)) { - opnd = $i - count = split($(i++), opnds, ",") - flags = convert_operands(count, opnds) - } - if (match($i, ext_expr)) - ext = $(i++) - if (match($i, sep_expr)) - i++ - else if (i < NF) - semantic_error($i " is not a separator") - - # check if group opcode - if (match(opcode, group_expr)) { - if (!(opcode in group)) { - group[opcode] = ggid - ggid++ - } - flags = add_flags(flags, "INAT_MAKE_GROUP(" group[opcode] ")") - } - # check force(or default) 64bit - if (match(ext, force64_expr)) - flags = add_flags(flags, "INAT_FORCE64") - - # check REX prefix - if (match(opcode, rex_expr)) - flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)") - - # check coprocessor escape : TODO - if (match(opcode, fpu_expr)) - flags = add_flags(flags, "INAT_MODRM") - - # check VEX codes - if (match(ext, evexonly_expr)) - flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY") - else if (match(ext, vexonly_expr)) - flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY") - else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr)) - flags = add_flags(flags, "INAT_VEXOK") - - # check prefixes - if (match(ext, prefix_expr)) { - if (!prefix_num[opcode]) - semantic_error("Unknown prefix: " opcode) - flags = add_flags(flags, "INAT_MAKE_PREFIX(" prefix_num[opcode] ")") - } - if (length(flags) == 0) - continue - # check if last prefix - if (match(ext, lprefix1_expr)) { - lptable1[idx] = add_flags(lptable1[idx],flags) - variant = "INAT_VARIANT" - } - if (match(ext, lprefix2_expr)) { - lptable2[idx] = add_flags(lptable2[idx],flags) - variant = "INAT_VARIANT" - } - if (match(ext, lprefix3_expr)) { - lptable3[idx] = add_flags(lptable3[idx],flags) - variant = "INAT_VARIANT" - } - if (!match(ext, lprefix_expr)){ - table[idx] = add_flags(table[idx],flags) - } - } - if (variant) - table[idx] = add_flags(table[idx],variant) -} - -END { - if (awkchecked != "") - exit 1 - # print escape opcode map's array - print "/* Escape opcode map array */" - print "const insn_attr_t * const inat_escape_tables[INAT_ESC_MAX + 1]" \ - "[INAT_LSTPFX_MAX + 1] = {" - for (i = 0; i < geid; i++) - for (j = 0; j < max_lprefix; j++) - if (etable[i,j]) - print " ["i"]["j"] = "etable[i,j]"," - print "};\n" - # print group opcode map's array - print "/* Group opcode map array */" - print "const insn_attr_t * const inat_group_tables[INAT_GRP_MAX + 1]"\ - "[INAT_LSTPFX_MAX + 1] = {" - for (i = 0; i < ggid; i++) - for (j = 0; j < max_lprefix; j++) - if (gtable[i,j]) - print " ["i"]["j"] = "gtable[i,j]"," - print "};\n" - # print AVX opcode map's array - print "/* AVX opcode map array */" - print "const insn_attr_t * const inat_avx_tables[X86_VEX_M_MAX + 1]"\ - "[INAT_LSTPFX_MAX + 1] = {" - for (i = 0; i < gaid; i++) - for (j = 0; j < max_lprefix; j++) - if (atable[i,j]) - print " ["i"]["j"] = "atable[i,j]"," - print "};" -} - diff --git a/tools/objtool/sync-check.sh b/tools/objtool/sync-check.sh index 1470e74e9d66..66f1575b80f3 100755 --- a/tools/objtool/sync-check.sh +++ b/tools/objtool/sync-check.sh @@ -2,21 +2,21 @@ # SPDX-License-Identifier: GPL-2.0 FILES=' -arch/x86/lib/insn.c -arch/x86/lib/inat.c -arch/x86/lib/x86-opcode-map.txt -arch/x86/tools/gen-insn-attr-x86.awk -arch/x86/include/asm/insn.h arch/x86/include/asm/inat.h arch/x86/include/asm/inat_types.h +arch/x86/include/asm/insn.h arch/x86/include/asm/orc_types.h +arch/x86/lib/inat.c +arch/x86/lib/insn.c +arch/x86/lib/x86-opcode-map.txt +arch/x86/tools/gen-insn-attr-x86.awk ' check() { local file=$1 - diff $file ../../$file > /dev/null || + diff ../$file ../../$file > /dev/null || echo "Warning: synced file at 'tools/objtool/$file' differs from latest kernel version at '$file'" } -- cgit v1.2.3-59-g8ed1b From 58993fb2c5115e93c52058e25f9b2ff289374870 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 29 Aug 2019 17:41:19 -0500 Subject: perf: Update .gitignore file After a "make tools/perf", git reports the following untracked files: tools/perf/feature/ tools/perf/fixdep tools/perf/libtraceevent-dynamic-list Add these generated files to perf's .gitignore file. Signed-off-by: Josh Poimboeuf Reviewed-by: Masami Hiramatsu Acked-by: Peter Zijlstra Cc: Adrian Hunter Cc: Jiri Olsa Cc: x86@kernel.org Link: http://lore.kernel.org/lkml/03acbc6c2fbc72054861f6c301875db75db33030.1567118001.git.jpoimboe@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/.gitignore | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore index 3e5135dded16..bf1252dc2cb0 100644 --- a/tools/perf/.gitignore +++ b/tools/perf/.gitignore @@ -34,3 +34,6 @@ arch/*/include/generated/ trace/beauty/generated/ pmu-events/pmu-events.c pmu-events/jevents +feature/ +fixdep +libtraceevent-dynamic-list -- cgit v1.2.3-59-g8ed1b From f1da0a6c136542b9571b30af27bc1e84254f7a47 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 29 Aug 2019 17:41:20 -0500 Subject: perf intel-pt: Remove inat.c from build dependency list intel-pt-insn-decoder.c includes inat.c directly, so it already has an implicit dependency on inat.c. The Build file dependency is redundant. Signed-off-by: Josh Poimboeuf Reviewed-by: Masami Hiramatsu Acked-by: Peter Zijlstra Cc: Adrian Hunter Cc: Jiri Olsa Cc: x86@kernel.org Link: http://lore.kernel.org/lkml/53776d6d29bc9eceb571d52df8fa32250c58a0f3.1567118001.git.jpoimboe@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/intel-pt-decoder/Build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/intel-pt-decoder/Build b/tools/perf/util/intel-pt-decoder/Build index 23bf788f84b9..acb18a3463c3 100644 --- a/tools/perf/util/intel-pt-decoder/Build +++ b/tools/perf/util/intel-pt-decoder/Build @@ -9,7 +9,7 @@ $(OUTPUT)util/intel-pt-decoder/inat-tables.c: $(inat_tables_script) $(inat_table # Busybox's diff doesn't have -I, avoid warning in the case -$(OUTPUT)util/intel-pt-decoder/intel-pt-insn-decoder.o: util/intel-pt-decoder/intel-pt-insn-decoder.c util/intel-pt-decoder/inat.c $(OUTPUT)util/intel-pt-decoder/inat-tables.c +$(OUTPUT)util/intel-pt-decoder/intel-pt-insn-decoder.o: util/intel-pt-decoder/intel-pt-insn-decoder.c $(OUTPUT)util/intel-pt-decoder/inat-tables.c @(diff -I 2>&1 | grep -q 'option requires an argument' && \ test -d ../../kernel -a -d ../../tools -a -d ../perf && ( \ ((diff -B -I'^#include' util/intel-pt-decoder/insn.c ../../arch/x86/lib/insn.c >/dev/null) || \ -- cgit v1.2.3-59-g8ed1b From 00a263902ac3da886cf275663a938f503a853f68 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 29 Aug 2019 17:41:21 -0500 Subject: perf intel-pt: Use shared x86 insn decoder Now that there's a common version of the decoder for all tools, use it instead of the local copy. Also use perf's check-headers.sh script to diff the decoder files to make sure they remain in sync with the kernel version. Objtool has a similar check. Committer notes: Had to keep this all pointing explicitely to x86 headers/files, i.e. instead of asm/isnn.h we had to use ../include/asm/insn.h when the files were in differemt dirs, or just replace "" with "foo.h". This way we continue to be able to process perf.data files with Intel PT traces in distros other than x86. Also fixed up the awk script paths to use $(srcdir)/tools/arch instead or relative directories so that we keep detached tarballs (make help | grep perf) working. For now the include lines in these headers are being ignored so as not to flag false reports of kernel/tools out of sync. Signed-off-by: Josh Poimboeuf Reviewed-by: Masami Hiramatsu Acked-by: Peter Zijlstra (Intel) Cc: Adrian Hunter Cc: Jiri Olsa Cc: x86@kernel.org Link: http://lore.kernel.org/lkml/8a37e615d2880f039505d693d1e068a009358a2b.1567118001.git.jpoimboe@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/x86/include/asm/inat.h | 2 +- tools/arch/x86/include/asm/insn.h | 2 +- tools/arch/x86/lib/inat.c | 2 +- tools/arch/x86/lib/insn.c | 4 +- tools/perf/arch/x86/tests/insn-x86.c | 2 +- tools/perf/arch/x86/util/archinsn.c | 2 +- tools/perf/check-headers.sh | 11 +- tools/perf/util/intel-pt-decoder/Build | 20 +- .../util/intel-pt-decoder/gen-insn-attr-x86.awk | 392 ------- tools/perf/util/intel-pt-decoder/inat.c | 82 -- tools/perf/util/intel-pt-decoder/inat.h | 230 ----- tools/perf/util/intel-pt-decoder/inat_types.h | 15 - tools/perf/util/intel-pt-decoder/insn.c | 593 ----------- tools/perf/util/intel-pt-decoder/insn.h | 216 ---- .../util/intel-pt-decoder/intel-pt-insn-decoder.c | 10 +- .../perf/util/intel-pt-decoder/x86-opcode-map.txt | 1072 -------------------- 16 files changed, 23 insertions(+), 2632 deletions(-) delete mode 100644 tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk delete mode 100644 tools/perf/util/intel-pt-decoder/inat.c delete mode 100644 tools/perf/util/intel-pt-decoder/inat.h delete mode 100644 tools/perf/util/intel-pt-decoder/inat_types.h delete mode 100644 tools/perf/util/intel-pt-decoder/insn.c delete mode 100644 tools/perf/util/intel-pt-decoder/insn.h delete mode 100644 tools/perf/util/intel-pt-decoder/x86-opcode-map.txt (limited to 'tools') diff --git a/tools/arch/x86/include/asm/inat.h b/tools/arch/x86/include/asm/inat.h index 4cf2ad521f65..877827b7c2c3 100644 --- a/tools/arch/x86/include/asm/inat.h +++ b/tools/arch/x86/include/asm/inat.h @@ -6,7 +6,7 @@ * * Written by Masami Hiramatsu */ -#include +#include "inat_types.h" /* * Internal bits. Don't use bitmasks directly, because these bits are diff --git a/tools/arch/x86/include/asm/insn.h b/tools/arch/x86/include/asm/insn.h index 154f27be8bfc..37a4c390750b 100644 --- a/tools/arch/x86/include/asm/insn.h +++ b/tools/arch/x86/include/asm/insn.h @@ -8,7 +8,7 @@ */ /* insn_attr_t is defined in inat.h */ -#include +#include "inat.h" struct insn_field { union { diff --git a/tools/arch/x86/lib/inat.c b/tools/arch/x86/lib/inat.c index 12539fca75c4..4f5ed49e1b4e 100644 --- a/tools/arch/x86/lib/inat.c +++ b/tools/arch/x86/lib/inat.c @@ -4,7 +4,7 @@ * * Written by Masami Hiramatsu */ -#include +#include "../include/asm/insn.h" /* Attribute tables are generated from opcode map */ #include "inat-tables.c" diff --git a/tools/arch/x86/lib/insn.c b/tools/arch/x86/lib/insn.c index 0b5862ba6a75..79e048f1d902 100644 --- a/tools/arch/x86/lib/insn.c +++ b/tools/arch/x86/lib/insn.c @@ -10,8 +10,8 @@ #else #include #endif -#include -#include +#include "../include/asm/inat.h" +#include "../include/asm/insn.h" /* Verify next sizeof(t) bytes can be on the same instruction */ #define validate_next(t, insn, n) \ diff --git a/tools/perf/arch/x86/tests/insn-x86.c b/tools/perf/arch/x86/tests/insn-x86.c index d67bc0ffb70a..745f29adb14b 100644 --- a/tools/perf/arch/x86/tests/insn-x86.c +++ b/tools/perf/arch/x86/tests/insn-x86.c @@ -1,12 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include "../../../../arch/x86/include/asm/insn.h" #include #include "debug.h" #include "tests/tests.h" #include "arch-tests.h" -#include "intel-pt-decoder/insn.h" #include "intel-pt-decoder/intel-pt-insn-decoder.h" struct test_data { diff --git a/tools/perf/arch/x86/util/archinsn.c b/tools/perf/arch/x86/util/archinsn.c index 62e8e1820132..9876c7a7ed7c 100644 --- a/tools/perf/arch/x86/util/archinsn.c +++ b/tools/perf/arch/x86/util/archinsn.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 +#include "../../../../arch/x86/include/asm/insn.h" #include "archinsn.h" -#include "util/intel-pt-decoder/insn.h" #include "machine.h" #include "thread.h" #include "symbol.h" diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh index 5308b3836278..cbcc3590098c 100755 --- a/tools/perf/check-headers.sh +++ b/tools/perf/check-headers.sh @@ -1,7 +1,7 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 -HEADERS=' +FILES=' include/uapi/linux/const.h include/uapi/drm/drm.h include/uapi/drm/i915_drm.h @@ -26,7 +26,14 @@ include/uapi/linux/hw_breakpoint.h arch/x86/include/asm/disabled-features.h arch/x86/include/asm/required-features.h arch/x86/include/asm/cpufeatures.h +arch/x86/include/asm/inat.h +arch/x86/include/asm/inat_types.h +arch/x86/include/asm/insn.h arch/x86/include/uapi/asm/prctl.h +arch/x86/lib/inat.c +arch/x86/lib/insn.c +arch/x86/lib/x86-opcode-map.txt +arch/x86/tools/gen-insn-attr-x86.awk arch/arm/include/uapi/asm/perf_regs.h arch/arm64/include/uapi/asm/perf_regs.h arch/powerpc/include/uapi/asm/perf_regs.h @@ -98,7 +105,7 @@ test -d ../../include || exit 0 cd ../.. # simple diff check -for i in $HEADERS; do +for i in $FILES; do check $i -B done diff --git a/tools/perf/util/intel-pt-decoder/Build b/tools/perf/util/intel-pt-decoder/Build index acb18a3463c3..bc629359826f 100644 --- a/tools/perf/util/intel-pt-decoder/Build +++ b/tools/perf/util/intel-pt-decoder/Build @@ -1,7 +1,7 @@ perf-$(CONFIG_AUXTRACE) += intel-pt-pkt-decoder.o intel-pt-insn-decoder.o intel-pt-log.o intel-pt-decoder.o -inat_tables_script = util/intel-pt-decoder/gen-insn-attr-x86.awk -inat_tables_maps = util/intel-pt-decoder/x86-opcode-map.txt +inat_tables_script = $(srctree)/tools/arch/x86/tools/gen-insn-attr-x86.awk +inat_tables_maps = $(srctree)/tools/arch/x86/lib/x86-opcode-map.txt $(OUTPUT)util/intel-pt-decoder/inat-tables.c: $(inat_tables_script) $(inat_tables_maps) $(call rule_mkdir) @@ -10,22 +10,6 @@ $(OUTPUT)util/intel-pt-decoder/inat-tables.c: $(inat_tables_script) $(inat_table # Busybox's diff doesn't have -I, avoid warning in the case $(OUTPUT)util/intel-pt-decoder/intel-pt-insn-decoder.o: util/intel-pt-decoder/intel-pt-insn-decoder.c $(OUTPUT)util/intel-pt-decoder/inat-tables.c - @(diff -I 2>&1 | grep -q 'option requires an argument' && \ - test -d ../../kernel -a -d ../../tools -a -d ../perf && ( \ - ((diff -B -I'^#include' util/intel-pt-decoder/insn.c ../../arch/x86/lib/insn.c >/dev/null) || \ - (echo "Warning: Intel PT: x86 instruction decoder C file at 'tools/perf/util/intel-pt-decoder/insn.c' differs from latest version at 'arch/x86/lib/insn.c'" >&2)) && \ - ((diff -B -I'^#include' util/intel-pt-decoder/inat.c ../../arch/x86/lib/inat.c >/dev/null) || \ - (echo "Warning: Intel PT: x86 instruction decoder C file at 'tools/perf/util/intel-pt-decoder/inat.c' differs from latest version at 'arch/x86/lib/inat.c'" >&2)) && \ - ((diff -B util/intel-pt-decoder/x86-opcode-map.txt ../../arch/x86/lib/x86-opcode-map.txt >/dev/null) || \ - (echo "Warning: Intel PT: x86 instruction decoder map file at 'tools/perf/util/intel-pt-decoder/x86-opcode-map.txt' differs from latest version at 'arch/x86/lib/x86-opcode-map.txt'" >&2)) && \ - ((diff -B util/intel-pt-decoder/gen-insn-attr-x86.awk ../../arch/x86/tools/gen-insn-attr-x86.awk >/dev/null) || \ - (echo "Warning: Intel PT: x86 instruction decoder script at 'tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk' differs from latest version at 'arch/x86/tools/gen-insn-attr-x86.awk'" >&2)) && \ - ((diff -B -I'^#include' util/intel-pt-decoder/insn.h ../../arch/x86/include/asm/insn.h >/dev/null) || \ - (echo "Warning: Intel PT: x86 instruction decoder header at 'tools/perf/util/intel-pt-decoder/insn.h' differs from latest version at 'arch/x86/include/asm/insn.h'" >&2)) && \ - ((diff -B -I'^#include' util/intel-pt-decoder/inat.h ../../arch/x86/include/asm/inat.h >/dev/null) || \ - (echo "Warning: Intel PT: x86 instruction decoder header at 'tools/perf/util/intel-pt-decoder/inat.h' differs from latest version at 'arch/x86/include/asm/inat.h'" >&2)) && \ - ((diff -B -I'^#include' util/intel-pt-decoder/inat_types.h ../../arch/x86/include/asm/inat_types.h >/dev/null) || \ - (echo "Warning: Intel PT: x86 instruction decoder header at 'tools/perf/util/intel-pt-decoder/inat_types.h' differs from latest version at 'arch/x86/include/asm/inat_types.h'" >&2)))) || true $(call rule_mkdir) $(call if_changed_dep,cc_o_c) diff --git a/tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk b/tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk deleted file mode 100644 index ddd5c4c21129..000000000000 --- a/tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk +++ /dev/null @@ -1,392 +0,0 @@ -#!/bin/awk -f -# SPDX-License-Identifier: GPL-2.0 -# gen-insn-attr-x86.awk: Instruction attribute table generator -# Written by Masami Hiramatsu -# -# Usage: awk -f gen-insn-attr-x86.awk x86-opcode-map.txt > inat-tables.c - -# Awk implementation sanity check -function check_awk_implement() { - if (sprintf("%x", 0) != "0") - return "Your awk has a printf-format problem." - return "" -} - -# Clear working vars -function clear_vars() { - delete table - delete lptable2 - delete lptable1 - delete lptable3 - eid = -1 # escape id - gid = -1 # group id - aid = -1 # AVX id - tname = "" -} - -BEGIN { - # Implementation error checking - awkchecked = check_awk_implement() - if (awkchecked != "") { - print "Error: " awkchecked > "/dev/stderr" - print "Please try to use gawk." > "/dev/stderr" - exit 1 - } - - # Setup generating tables - print "/* x86 opcode map generated from x86-opcode-map.txt */" - print "/* Do not change this code. */\n" - ggid = 1 - geid = 1 - gaid = 0 - delete etable - delete gtable - delete atable - - opnd_expr = "^[A-Za-z/]" - ext_expr = "^\\(" - sep_expr = "^\\|$" - group_expr = "^Grp[0-9A-Za-z]+" - - imm_expr = "^[IJAOL][a-z]" - imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" - imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" - imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)" - imm_flag["Id"] = "INAT_MAKE_IMM(INAT_IMM_DWORD)" - imm_flag["Iq"] = "INAT_MAKE_IMM(INAT_IMM_QWORD)" - imm_flag["Ap"] = "INAT_MAKE_IMM(INAT_IMM_PTR)" - imm_flag["Iz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)" - imm_flag["Jz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)" - imm_flag["Iv"] = "INAT_MAKE_IMM(INAT_IMM_VWORD)" - imm_flag["Ob"] = "INAT_MOFFSET" - imm_flag["Ov"] = "INAT_MOFFSET" - imm_flag["Lx"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" - - modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])" - force64_expr = "\\([df]64\\)" - rex_expr = "^REX(\\.[XRWB]+)*" - fpu_expr = "^ESC" # TODO - - lprefix1_expr = "\\((66|!F3)\\)" - lprefix2_expr = "\\(F3\\)" - lprefix3_expr = "\\((F2|!F3|66\\&F2)\\)" - lprefix_expr = "\\((66|F2|F3)\\)" - max_lprefix = 4 - - # All opcodes starting with lower-case 'v', 'k' or with (v1) superscript - # accepts VEX prefix - vexok_opcode_expr = "^[vk].*" - vexok_expr = "\\(v1\\)" - # All opcodes with (v) superscript supports *only* VEX prefix - vexonly_expr = "\\(v\\)" - # All opcodes with (ev) superscript supports *only* EVEX prefix - evexonly_expr = "\\(ev\\)" - - prefix_expr = "\\(Prefix\\)" - prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ" - prefix_num["REPNE"] = "INAT_PFX_REPNE" - prefix_num["REP/REPE"] = "INAT_PFX_REPE" - prefix_num["XACQUIRE"] = "INAT_PFX_REPNE" - prefix_num["XRELEASE"] = "INAT_PFX_REPE" - prefix_num["LOCK"] = "INAT_PFX_LOCK" - prefix_num["SEG=CS"] = "INAT_PFX_CS" - prefix_num["SEG=DS"] = "INAT_PFX_DS" - prefix_num["SEG=ES"] = "INAT_PFX_ES" - prefix_num["SEG=FS"] = "INAT_PFX_FS" - prefix_num["SEG=GS"] = "INAT_PFX_GS" - prefix_num["SEG=SS"] = "INAT_PFX_SS" - prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ" - prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" - prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" - prefix_num["EVEX"] = "INAT_PFX_EVEX" - - clear_vars() -} - -function semantic_error(msg) { - print "Semantic error at " NR ": " msg > "/dev/stderr" - exit 1 -} - -function debug(msg) { - print "DEBUG: " msg -} - -function array_size(arr, i,c) { - c = 0 - for (i in arr) - c++ - return c -} - -/^Table:/ { - print "/* " $0 " */" - if (tname != "") - semantic_error("Hit Table: before EndTable:."); -} - -/^Referrer:/ { - if (NF != 1) { - # escape opcode table - ref = "" - for (i = 2; i <= NF; i++) - ref = ref $i - eid = escape[ref] - tname = sprintf("inat_escape_table_%d", eid) - } -} - -/^AVXcode:/ { - if (NF != 1) { - # AVX/escape opcode table - aid = $2 - if (gaid <= aid) - gaid = aid + 1 - if (tname == "") # AVX only opcode table - tname = sprintf("inat_avx_table_%d", $2) - } - if (aid == -1 && eid == -1) # primary opcode table - tname = "inat_primary_table" -} - -/^GrpTable:/ { - print "/* " $0 " */" - if (!($2 in group)) - semantic_error("No group: " $2 ) - gid = group[$2] - tname = "inat_group_table_" gid -} - -function print_table(tbl,name,fmt,n) -{ - print "const insn_attr_t " name " = {" - for (i = 0; i < n; i++) { - id = sprintf(fmt, i) - if (tbl[id]) - print " [" id "] = " tbl[id] "," - } - print "};" -} - -/^EndTable/ { - if (gid != -1) { - # print group tables - if (array_size(table) != 0) { - print_table(table, tname "[INAT_GROUP_TABLE_SIZE]", - "0x%x", 8) - gtable[gid,0] = tname - } - if (array_size(lptable1) != 0) { - print_table(lptable1, tname "_1[INAT_GROUP_TABLE_SIZE]", - "0x%x", 8) - gtable[gid,1] = tname "_1" - } - if (array_size(lptable2) != 0) { - print_table(lptable2, tname "_2[INAT_GROUP_TABLE_SIZE]", - "0x%x", 8) - gtable[gid,2] = tname "_2" - } - if (array_size(lptable3) != 0) { - print_table(lptable3, tname "_3[INAT_GROUP_TABLE_SIZE]", - "0x%x", 8) - gtable[gid,3] = tname "_3" - } - } else { - # print primary/escaped tables - if (array_size(table) != 0) { - print_table(table, tname "[INAT_OPCODE_TABLE_SIZE]", - "0x%02x", 256) - etable[eid,0] = tname - if (aid >= 0) - atable[aid,0] = tname - } - if (array_size(lptable1) != 0) { - print_table(lptable1,tname "_1[INAT_OPCODE_TABLE_SIZE]", - "0x%02x", 256) - etable[eid,1] = tname "_1" - if (aid >= 0) - atable[aid,1] = tname "_1" - } - if (array_size(lptable2) != 0) { - print_table(lptable2,tname "_2[INAT_OPCODE_TABLE_SIZE]", - "0x%02x", 256) - etable[eid,2] = tname "_2" - if (aid >= 0) - atable[aid,2] = tname "_2" - } - if (array_size(lptable3) != 0) { - print_table(lptable3,tname "_3[INAT_OPCODE_TABLE_SIZE]", - "0x%02x", 256) - etable[eid,3] = tname "_3" - if (aid >= 0) - atable[aid,3] = tname "_3" - } - } - print "" - clear_vars() -} - -function add_flags(old,new) { - if (old && new) - return old " | " new - else if (old) - return old - else - return new -} - -# convert operands to flags. -function convert_operands(count,opnd, i,j,imm,mod) -{ - imm = null - mod = null - for (j = 1; j <= count; j++) { - i = opnd[j] - if (match(i, imm_expr) == 1) { - if (!imm_flag[i]) - semantic_error("Unknown imm opnd: " i) - if (imm) { - if (i != "Ib") - semantic_error("Second IMM error") - imm = add_flags(imm, "INAT_SCNDIMM") - } else - imm = imm_flag[i] - } else if (match(i, modrm_expr)) - mod = "INAT_MODRM" - } - return add_flags(imm, mod) -} - -/^[0-9a-f]+\:/ { - if (NR == 1) - next - # get index - idx = "0x" substr($1, 1, index($1,":") - 1) - if (idx in table) - semantic_error("Redefine " idx " in " tname) - - # check if escaped opcode - if ("escape" == $2) { - if ($3 != "#") - semantic_error("No escaped name") - ref = "" - for (i = 4; i <= NF; i++) - ref = ref $i - if (ref in escape) - semantic_error("Redefine escape (" ref ")") - escape[ref] = geid - geid++ - table[idx] = "INAT_MAKE_ESCAPE(" escape[ref] ")" - next - } - - variant = null - # converts - i = 2 - while (i <= NF) { - opcode = $(i++) - delete opnds - ext = null - flags = null - opnd = null - # parse one opcode - if (match($i, opnd_expr)) { - opnd = $i - count = split($(i++), opnds, ",") - flags = convert_operands(count, opnds) - } - if (match($i, ext_expr)) - ext = $(i++) - if (match($i, sep_expr)) - i++ - else if (i < NF) - semantic_error($i " is not a separator") - - # check if group opcode - if (match(opcode, group_expr)) { - if (!(opcode in group)) { - group[opcode] = ggid - ggid++ - } - flags = add_flags(flags, "INAT_MAKE_GROUP(" group[opcode] ")") - } - # check force(or default) 64bit - if (match(ext, force64_expr)) - flags = add_flags(flags, "INAT_FORCE64") - - # check REX prefix - if (match(opcode, rex_expr)) - flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)") - - # check coprocessor escape : TODO - if (match(opcode, fpu_expr)) - flags = add_flags(flags, "INAT_MODRM") - - # check VEX codes - if (match(ext, evexonly_expr)) - flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY") - else if (match(ext, vexonly_expr)) - flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY") - else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr)) - flags = add_flags(flags, "INAT_VEXOK") - - # check prefixes - if (match(ext, prefix_expr)) { - if (!prefix_num[opcode]) - semantic_error("Unknown prefix: " opcode) - flags = add_flags(flags, "INAT_MAKE_PREFIX(" prefix_num[opcode] ")") - } - if (length(flags) == 0) - continue - # check if last prefix - if (match(ext, lprefix1_expr)) { - lptable1[idx] = add_flags(lptable1[idx],flags) - variant = "INAT_VARIANT" - } - if (match(ext, lprefix2_expr)) { - lptable2[idx] = add_flags(lptable2[idx],flags) - variant = "INAT_VARIANT" - } - if (match(ext, lprefix3_expr)) { - lptable3[idx] = add_flags(lptable3[idx],flags) - variant = "INAT_VARIANT" - } - if (!match(ext, lprefix_expr)){ - table[idx] = add_flags(table[idx],flags) - } - } - if (variant) - table[idx] = add_flags(table[idx],variant) -} - -END { - if (awkchecked != "") - exit 1 - # print escape opcode map's array - print "/* Escape opcode map array */" - print "const insn_attr_t * const inat_escape_tables[INAT_ESC_MAX + 1]" \ - "[INAT_LSTPFX_MAX + 1] = {" - for (i = 0; i < geid; i++) - for (j = 0; j < max_lprefix; j++) - if (etable[i,j]) - print " ["i"]["j"] = "etable[i,j]"," - print "};\n" - # print group opcode map's array - print "/* Group opcode map array */" - print "const insn_attr_t * const inat_group_tables[INAT_GRP_MAX + 1]"\ - "[INAT_LSTPFX_MAX + 1] = {" - for (i = 0; i < ggid; i++) - for (j = 0; j < max_lprefix; j++) - if (gtable[i,j]) - print " ["i"]["j"] = "gtable[i,j]"," - print "};\n" - # print AVX opcode map's array - print "/* AVX opcode map array */" - print "const insn_attr_t * const inat_avx_tables[X86_VEX_M_MAX + 1]"\ - "[INAT_LSTPFX_MAX + 1] = {" - for (i = 0; i < gaid; i++) - for (j = 0; j < max_lprefix; j++) - if (atable[i,j]) - print " ["i"]["j"] = "atable[i,j]"," - print "};" -} diff --git a/tools/perf/util/intel-pt-decoder/inat.c b/tools/perf/util/intel-pt-decoder/inat.c deleted file mode 100644 index 446c0413a27c..000000000000 --- a/tools/perf/util/intel-pt-decoder/inat.c +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * x86 instruction attribute tables - * - * Written by Masami Hiramatsu - */ -#include "insn.h" - -/* Attribute tables are generated from opcode map */ -#include "inat-tables.c" - -/* Attribute search APIs */ -insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode) -{ - return inat_primary_table[opcode]; -} - -int inat_get_last_prefix_id(insn_byte_t last_pfx) -{ - insn_attr_t lpfx_attr; - - lpfx_attr = inat_get_opcode_attribute(last_pfx); - return inat_last_prefix_id(lpfx_attr); -} - -insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, int lpfx_id, - insn_attr_t esc_attr) -{ - const insn_attr_t *table; - int n; - - n = inat_escape_id(esc_attr); - - table = inat_escape_tables[n][0]; - if (!table) - return 0; - if (inat_has_variant(table[opcode]) && lpfx_id) { - table = inat_escape_tables[n][lpfx_id]; - if (!table) - return 0; - } - return table[opcode]; -} - -insn_attr_t inat_get_group_attribute(insn_byte_t modrm, int lpfx_id, - insn_attr_t grp_attr) -{ - const insn_attr_t *table; - int n; - - n = inat_group_id(grp_attr); - - table = inat_group_tables[n][0]; - if (!table) - return inat_group_common_attribute(grp_attr); - if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && lpfx_id) { - table = inat_group_tables[n][lpfx_id]; - if (!table) - return inat_group_common_attribute(grp_attr); - } - return table[X86_MODRM_REG(modrm)] | - inat_group_common_attribute(grp_attr); -} - -insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m, - insn_byte_t vex_p) -{ - const insn_attr_t *table; - if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX) - return 0; - /* At first, this checks the master table */ - table = inat_avx_tables[vex_m][0]; - if (!table) - return 0; - if (!inat_is_group(table[opcode]) && vex_p) { - /* If this is not a group, get attribute directly */ - table = inat_avx_tables[vex_m][vex_p]; - if (!table) - return 0; - } - return table[opcode]; -} diff --git a/tools/perf/util/intel-pt-decoder/inat.h b/tools/perf/util/intel-pt-decoder/inat.h deleted file mode 100644 index 877827b7c2c3..000000000000 --- a/tools/perf/util/intel-pt-decoder/inat.h +++ /dev/null @@ -1,230 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -#ifndef _ASM_X86_INAT_H -#define _ASM_X86_INAT_H -/* - * x86 instruction attributes - * - * Written by Masami Hiramatsu - */ -#include "inat_types.h" - -/* - * Internal bits. Don't use bitmasks directly, because these bits are - * unstable. You should use checking functions. - */ - -#define INAT_OPCODE_TABLE_SIZE 256 -#define INAT_GROUP_TABLE_SIZE 8 - -/* Legacy last prefixes */ -#define INAT_PFX_OPNDSZ 1 /* 0x66 */ /* LPFX1 */ -#define INAT_PFX_REPE 2 /* 0xF3 */ /* LPFX2 */ -#define INAT_PFX_REPNE 3 /* 0xF2 */ /* LPFX3 */ -/* Other Legacy prefixes */ -#define INAT_PFX_LOCK 4 /* 0xF0 */ -#define INAT_PFX_CS 5 /* 0x2E */ -#define INAT_PFX_DS 6 /* 0x3E */ -#define INAT_PFX_ES 7 /* 0x26 */ -#define INAT_PFX_FS 8 /* 0x64 */ -#define INAT_PFX_GS 9 /* 0x65 */ -#define INAT_PFX_SS 10 /* 0x36 */ -#define INAT_PFX_ADDRSZ 11 /* 0x67 */ -/* x86-64 REX prefix */ -#define INAT_PFX_REX 12 /* 0x4X */ -/* AVX VEX prefixes */ -#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */ -#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */ -#define INAT_PFX_EVEX 15 /* EVEX prefix */ - -#define INAT_LSTPFX_MAX 3 -#define INAT_LGCPFX_MAX 11 - -/* Immediate size */ -#define INAT_IMM_BYTE 1 -#define INAT_IMM_WORD 2 -#define INAT_IMM_DWORD 3 -#define INAT_IMM_QWORD 4 -#define INAT_IMM_PTR 5 -#define INAT_IMM_VWORD32 6 -#define INAT_IMM_VWORD 7 - -/* Legacy prefix */ -#define INAT_PFX_OFFS 0 -#define INAT_PFX_BITS 4 -#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1) -#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS) -/* Escape opcodes */ -#define INAT_ESC_OFFS (INAT_PFX_OFFS + INAT_PFX_BITS) -#define INAT_ESC_BITS 2 -#define INAT_ESC_MAX ((1 << INAT_ESC_BITS) - 1) -#define INAT_ESC_MASK (INAT_ESC_MAX << INAT_ESC_OFFS) -/* Group opcodes (1-16) */ -#define INAT_GRP_OFFS (INAT_ESC_OFFS + INAT_ESC_BITS) -#define INAT_GRP_BITS 5 -#define INAT_GRP_MAX ((1 << INAT_GRP_BITS) - 1) -#define INAT_GRP_MASK (INAT_GRP_MAX << INAT_GRP_OFFS) -/* Immediates */ -#define INAT_IMM_OFFS (INAT_GRP_OFFS + INAT_GRP_BITS) -#define INAT_IMM_BITS 3 -#define INAT_IMM_MASK (((1 << INAT_IMM_BITS) - 1) << INAT_IMM_OFFS) -/* Flags */ -#define INAT_FLAG_OFFS (INAT_IMM_OFFS + INAT_IMM_BITS) -#define INAT_MODRM (1 << (INAT_FLAG_OFFS)) -#define INAT_FORCE64 (1 << (INAT_FLAG_OFFS + 1)) -#define INAT_SCNDIMM (1 << (INAT_FLAG_OFFS + 2)) -#define INAT_MOFFSET (1 << (INAT_FLAG_OFFS + 3)) -#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4)) -#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5)) -#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6)) -#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7)) -/* Attribute making macros for attribute tables */ -#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS) -#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS) -#define INAT_MAKE_GROUP(grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM) -#define INAT_MAKE_IMM(imm) (imm << INAT_IMM_OFFS) - -/* Identifiers for segment registers */ -#define INAT_SEG_REG_IGNORE 0 -#define INAT_SEG_REG_DEFAULT 1 -#define INAT_SEG_REG_CS 2 -#define INAT_SEG_REG_SS 3 -#define INAT_SEG_REG_DS 4 -#define INAT_SEG_REG_ES 5 -#define INAT_SEG_REG_FS 6 -#define INAT_SEG_REG_GS 7 - -/* Attribute search APIs */ -extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode); -extern int inat_get_last_prefix_id(insn_byte_t last_pfx); -extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, - int lpfx_id, - insn_attr_t esc_attr); -extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm, - int lpfx_id, - insn_attr_t esc_attr); -extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, - insn_byte_t vex_m, - insn_byte_t vex_pp); - -/* Attribute checking functions */ -static inline int inat_is_legacy_prefix(insn_attr_t attr) -{ - attr &= INAT_PFX_MASK; - return attr && attr <= INAT_LGCPFX_MAX; -} - -static inline int inat_is_address_size_prefix(insn_attr_t attr) -{ - return (attr & INAT_PFX_MASK) == INAT_PFX_ADDRSZ; -} - -static inline int inat_is_operand_size_prefix(insn_attr_t attr) -{ - return (attr & INAT_PFX_MASK) == INAT_PFX_OPNDSZ; -} - -static inline int inat_is_rex_prefix(insn_attr_t attr) -{ - return (attr & INAT_PFX_MASK) == INAT_PFX_REX; -} - -static inline int inat_last_prefix_id(insn_attr_t attr) -{ - if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX) - return 0; - else - return attr & INAT_PFX_MASK; -} - -static inline int inat_is_vex_prefix(insn_attr_t attr) -{ - attr &= INAT_PFX_MASK; - return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 || - attr == INAT_PFX_EVEX; -} - -static inline int inat_is_evex_prefix(insn_attr_t attr) -{ - return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX; -} - -static inline int inat_is_vex3_prefix(insn_attr_t attr) -{ - return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3; -} - -static inline int inat_is_escape(insn_attr_t attr) -{ - return attr & INAT_ESC_MASK; -} - -static inline int inat_escape_id(insn_attr_t attr) -{ - return (attr & INAT_ESC_MASK) >> INAT_ESC_OFFS; -} - -static inline int inat_is_group(insn_attr_t attr) -{ - return attr & INAT_GRP_MASK; -} - -static inline int inat_group_id(insn_attr_t attr) -{ - return (attr & INAT_GRP_MASK) >> INAT_GRP_OFFS; -} - -static inline int inat_group_common_attribute(insn_attr_t attr) -{ - return attr & ~INAT_GRP_MASK; -} - -static inline int inat_has_immediate(insn_attr_t attr) -{ - return attr & INAT_IMM_MASK; -} - -static inline int inat_immediate_size(insn_attr_t attr) -{ - return (attr & INAT_IMM_MASK) >> INAT_IMM_OFFS; -} - -static inline int inat_has_modrm(insn_attr_t attr) -{ - return attr & INAT_MODRM; -} - -static inline int inat_is_force64(insn_attr_t attr) -{ - return attr & INAT_FORCE64; -} - -static inline int inat_has_second_immediate(insn_attr_t attr) -{ - return attr & INAT_SCNDIMM; -} - -static inline int inat_has_moffset(insn_attr_t attr) -{ - return attr & INAT_MOFFSET; -} - -static inline int inat_has_variant(insn_attr_t attr) -{ - return attr & INAT_VARIANT; -} - -static inline int inat_accept_vex(insn_attr_t attr) -{ - return attr & INAT_VEXOK; -} - -static inline int inat_must_vex(insn_attr_t attr) -{ - return attr & (INAT_VEXONLY | INAT_EVEXONLY); -} - -static inline int inat_must_evex(insn_attr_t attr) -{ - return attr & INAT_EVEXONLY; -} -#endif diff --git a/tools/perf/util/intel-pt-decoder/inat_types.h b/tools/perf/util/intel-pt-decoder/inat_types.h deleted file mode 100644 index b047efa9ddc2..000000000000 --- a/tools/perf/util/intel-pt-decoder/inat_types.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -#ifndef _ASM_X86_INAT_TYPES_H -#define _ASM_X86_INAT_TYPES_H -/* - * x86 instruction attributes - * - * Written by Masami Hiramatsu - */ - -/* Instruction attributes */ -typedef unsigned int insn_attr_t; -typedef unsigned char insn_byte_t; -typedef signed int insn_value_t; - -#endif diff --git a/tools/perf/util/intel-pt-decoder/insn.c b/tools/perf/util/intel-pt-decoder/insn.c deleted file mode 100644 index 82783bf43b74..000000000000 --- a/tools/perf/util/intel-pt-decoder/insn.c +++ /dev/null @@ -1,593 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * x86 instruction analysis - * - * Copyright (C) IBM Corporation, 2002, 2004, 2009 - */ - -#ifdef __KERNEL__ -#include -#else -#include -#endif -#include "inat.h" -#include "insn.h" - -/* Verify next sizeof(t) bytes can be on the same instruction */ -#define validate_next(t, insn, n) \ - ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr) - -#define __get_next(t, insn) \ - ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; }) - -#define __peek_nbyte_next(t, insn, n) \ - ({ t r = *(t*)((insn)->next_byte + n); r; }) - -#define get_next(t, insn) \ - ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); }) - -#define peek_nbyte_next(t, insn, n) \ - ({ if (unlikely(!validate_next(t, insn, n))) goto err_out; __peek_nbyte_next(t, insn, n); }) - -#define peek_next(t, insn) peek_nbyte_next(t, insn, 0) - -/** - * insn_init() - initialize struct insn - * @insn: &struct insn to be initialized - * @kaddr: address (in kernel memory) of instruction (or copy thereof) - * @x86_64: !0 for 64-bit kernel or 64-bit app - */ -void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64) -{ - /* - * Instructions longer than MAX_INSN_SIZE (15 bytes) are invalid - * even if the input buffer is long enough to hold them. - */ - if (buf_len > MAX_INSN_SIZE) - buf_len = MAX_INSN_SIZE; - - memset(insn, 0, sizeof(*insn)); - insn->kaddr = kaddr; - insn->end_kaddr = kaddr + buf_len; - insn->next_byte = kaddr; - insn->x86_64 = x86_64 ? 1 : 0; - insn->opnd_bytes = 4; - if (x86_64) - insn->addr_bytes = 8; - else - insn->addr_bytes = 4; -} - -/** - * insn_get_prefixes - scan x86 instruction prefix bytes - * @insn: &struct insn containing instruction - * - * Populates the @insn->prefixes bitmap, and updates @insn->next_byte - * to point to the (first) opcode. No effect if @insn->prefixes.got - * is already set. - */ -void insn_get_prefixes(struct insn *insn) -{ - struct insn_field *prefixes = &insn->prefixes; - insn_attr_t attr; - insn_byte_t b, lb; - int i, nb; - - if (prefixes->got) - return; - - nb = 0; - lb = 0; - b = peek_next(insn_byte_t, insn); - attr = inat_get_opcode_attribute(b); - while (inat_is_legacy_prefix(attr)) { - /* Skip if same prefix */ - for (i = 0; i < nb; i++) - if (prefixes->bytes[i] == b) - goto found; - if (nb == 4) - /* Invalid instruction */ - break; - prefixes->bytes[nb++] = b; - if (inat_is_address_size_prefix(attr)) { - /* address size switches 2/4 or 4/8 */ - if (insn->x86_64) - insn->addr_bytes ^= 12; - else - insn->addr_bytes ^= 6; - } else if (inat_is_operand_size_prefix(attr)) { - /* oprand size switches 2/4 */ - insn->opnd_bytes ^= 6; - } -found: - prefixes->nbytes++; - insn->next_byte++; - lb = b; - b = peek_next(insn_byte_t, insn); - attr = inat_get_opcode_attribute(b); - } - /* Set the last prefix */ - if (lb && lb != insn->prefixes.bytes[3]) { - if (unlikely(insn->prefixes.bytes[3])) { - /* Swap the last prefix */ - b = insn->prefixes.bytes[3]; - for (i = 0; i < nb; i++) - if (prefixes->bytes[i] == lb) - prefixes->bytes[i] = b; - } - insn->prefixes.bytes[3] = lb; - } - - /* Decode REX prefix */ - if (insn->x86_64) { - b = peek_next(insn_byte_t, insn); - attr = inat_get_opcode_attribute(b); - if (inat_is_rex_prefix(attr)) { - insn->rex_prefix.value = b; - insn->rex_prefix.nbytes = 1; - insn->next_byte++; - if (X86_REX_W(b)) - /* REX.W overrides opnd_size */ - insn->opnd_bytes = 8; - } - } - insn->rex_prefix.got = 1; - - /* Decode VEX prefix */ - b = peek_next(insn_byte_t, insn); - attr = inat_get_opcode_attribute(b); - if (inat_is_vex_prefix(attr)) { - insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1); - if (!insn->x86_64) { - /* - * In 32-bits mode, if the [7:6] bits (mod bits of - * ModRM) on the second byte are not 11b, it is - * LDS or LES or BOUND. - */ - if (X86_MODRM_MOD(b2) != 3) - goto vex_end; - } - insn->vex_prefix.bytes[0] = b; - insn->vex_prefix.bytes[1] = b2; - if (inat_is_evex_prefix(attr)) { - b2 = peek_nbyte_next(insn_byte_t, insn, 2); - insn->vex_prefix.bytes[2] = b2; - b2 = peek_nbyte_next(insn_byte_t, insn, 3); - insn->vex_prefix.bytes[3] = b2; - insn->vex_prefix.nbytes = 4; - insn->next_byte += 4; - if (insn->x86_64 && X86_VEX_W(b2)) - /* VEX.W overrides opnd_size */ - insn->opnd_bytes = 8; - } else if (inat_is_vex3_prefix(attr)) { - b2 = peek_nbyte_next(insn_byte_t, insn, 2); - insn->vex_prefix.bytes[2] = b2; - insn->vex_prefix.nbytes = 3; - insn->next_byte += 3; - if (insn->x86_64 && X86_VEX_W(b2)) - /* VEX.W overrides opnd_size */ - insn->opnd_bytes = 8; - } else { - /* - * For VEX2, fake VEX3-like byte#2. - * Makes it easier to decode vex.W, vex.vvvv, - * vex.L and vex.pp. Masking with 0x7f sets vex.W == 0. - */ - insn->vex_prefix.bytes[2] = b2 & 0x7f; - insn->vex_prefix.nbytes = 2; - insn->next_byte += 2; - } - } -vex_end: - insn->vex_prefix.got = 1; - - prefixes->got = 1; - -err_out: - return; -} - -/** - * insn_get_opcode - collect opcode(s) - * @insn: &struct insn containing instruction - * - * Populates @insn->opcode, updates @insn->next_byte to point past the - * opcode byte(s), and set @insn->attr (except for groups). - * If necessary, first collects any preceding (prefix) bytes. - * Sets @insn->opcode.value = opcode1. No effect if @insn->opcode.got - * is already 1. - */ -void insn_get_opcode(struct insn *insn) -{ - struct insn_field *opcode = &insn->opcode; - insn_byte_t op; - int pfx_id; - if (opcode->got) - return; - if (!insn->prefixes.got) - insn_get_prefixes(insn); - - /* Get first opcode */ - op = get_next(insn_byte_t, insn); - opcode->bytes[0] = op; - opcode->nbytes = 1; - - /* Check if there is VEX prefix or not */ - if (insn_is_avx(insn)) { - insn_byte_t m, p; - m = insn_vex_m_bits(insn); - p = insn_vex_p_bits(insn); - insn->attr = inat_get_avx_attribute(op, m, p); - if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) || - (!inat_accept_vex(insn->attr) && - !inat_is_group(insn->attr))) - insn->attr = 0; /* This instruction is bad */ - goto end; /* VEX has only 1 byte for opcode */ - } - - insn->attr = inat_get_opcode_attribute(op); - while (inat_is_escape(insn->attr)) { - /* Get escaped opcode */ - op = get_next(insn_byte_t, insn); - opcode->bytes[opcode->nbytes++] = op; - pfx_id = insn_last_prefix_id(insn); - insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr); - } - if (inat_must_vex(insn->attr)) - insn->attr = 0; /* This instruction is bad */ -end: - opcode->got = 1; - -err_out: - return; -} - -/** - * insn_get_modrm - collect ModRM byte, if any - * @insn: &struct insn containing instruction - * - * Populates @insn->modrm and updates @insn->next_byte to point past the - * ModRM byte, if any. If necessary, first collects the preceding bytes - * (prefixes and opcode(s)). No effect if @insn->modrm.got is already 1. - */ -void insn_get_modrm(struct insn *insn) -{ - struct insn_field *modrm = &insn->modrm; - insn_byte_t pfx_id, mod; - if (modrm->got) - return; - if (!insn->opcode.got) - insn_get_opcode(insn); - - if (inat_has_modrm(insn->attr)) { - mod = get_next(insn_byte_t, insn); - modrm->value = mod; - modrm->nbytes = 1; - if (inat_is_group(insn->attr)) { - pfx_id = insn_last_prefix_id(insn); - insn->attr = inat_get_group_attribute(mod, pfx_id, - insn->attr); - if (insn_is_avx(insn) && !inat_accept_vex(insn->attr)) - insn->attr = 0; /* This is bad */ - } - } - - if (insn->x86_64 && inat_is_force64(insn->attr)) - insn->opnd_bytes = 8; - modrm->got = 1; - -err_out: - return; -} - - -/** - * insn_rip_relative() - Does instruction use RIP-relative addressing mode? - * @insn: &struct insn containing instruction - * - * If necessary, first collects the instruction up to and including the - * ModRM byte. No effect if @insn->x86_64 is 0. - */ -int insn_rip_relative(struct insn *insn) -{ - struct insn_field *modrm = &insn->modrm; - - if (!insn->x86_64) - return 0; - if (!modrm->got) - insn_get_modrm(insn); - /* - * For rip-relative instructions, the mod field (top 2 bits) - * is zero and the r/m field (bottom 3 bits) is 0x5. - */ - return (modrm->nbytes && (modrm->value & 0xc7) == 0x5); -} - -/** - * insn_get_sib() - Get the SIB byte of instruction - * @insn: &struct insn containing instruction - * - * If necessary, first collects the instruction up to and including the - * ModRM byte. - */ -void insn_get_sib(struct insn *insn) -{ - insn_byte_t modrm; - - if (insn->sib.got) - return; - if (!insn->modrm.got) - insn_get_modrm(insn); - if (insn->modrm.nbytes) { - modrm = (insn_byte_t)insn->modrm.value; - if (insn->addr_bytes != 2 && - X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) { - insn->sib.value = get_next(insn_byte_t, insn); - insn->sib.nbytes = 1; - } - } - insn->sib.got = 1; - -err_out: - return; -} - - -/** - * insn_get_displacement() - Get the displacement of instruction - * @insn: &struct insn containing instruction - * - * If necessary, first collects the instruction up to and including the - * SIB byte. - * Displacement value is sign-expanded. - */ -void insn_get_displacement(struct insn *insn) -{ - insn_byte_t mod, rm, base; - - if (insn->displacement.got) - return; - if (!insn->sib.got) - insn_get_sib(insn); - if (insn->modrm.nbytes) { - /* - * Interpreting the modrm byte: - * mod = 00 - no displacement fields (exceptions below) - * mod = 01 - 1-byte displacement field - * mod = 10 - displacement field is 4 bytes, or 2 bytes if - * address size = 2 (0x67 prefix in 32-bit mode) - * mod = 11 - no memory operand - * - * If address size = 2... - * mod = 00, r/m = 110 - displacement field is 2 bytes - * - * If address size != 2... - * mod != 11, r/m = 100 - SIB byte exists - * mod = 00, SIB base = 101 - displacement field is 4 bytes - * mod = 00, r/m = 101 - rip-relative addressing, displacement - * field is 4 bytes - */ - mod = X86_MODRM_MOD(insn->modrm.value); - rm = X86_MODRM_RM(insn->modrm.value); - base = X86_SIB_BASE(insn->sib.value); - if (mod == 3) - goto out; - if (mod == 1) { - insn->displacement.value = get_next(signed char, insn); - insn->displacement.nbytes = 1; - } else if (insn->addr_bytes == 2) { - if ((mod == 0 && rm == 6) || mod == 2) { - insn->displacement.value = - get_next(short, insn); - insn->displacement.nbytes = 2; - } - } else { - if ((mod == 0 && rm == 5) || mod == 2 || - (mod == 0 && base == 5)) { - insn->displacement.value = get_next(int, insn); - insn->displacement.nbytes = 4; - } - } - } -out: - insn->displacement.got = 1; - -err_out: - return; -} - -/* Decode moffset16/32/64. Return 0 if failed */ -static int __get_moffset(struct insn *insn) -{ - switch (insn->addr_bytes) { - case 2: - insn->moffset1.value = get_next(short, insn); - insn->moffset1.nbytes = 2; - break; - case 4: - insn->moffset1.value = get_next(int, insn); - insn->moffset1.nbytes = 4; - break; - case 8: - insn->moffset1.value = get_next(int, insn); - insn->moffset1.nbytes = 4; - insn->moffset2.value = get_next(int, insn); - insn->moffset2.nbytes = 4; - break; - default: /* opnd_bytes must be modified manually */ - goto err_out; - } - insn->moffset1.got = insn->moffset2.got = 1; - - return 1; - -err_out: - return 0; -} - -/* Decode imm v32(Iz). Return 0 if failed */ -static int __get_immv32(struct insn *insn) -{ - switch (insn->opnd_bytes) { - case 2: - insn->immediate.value = get_next(short, insn); - insn->immediate.nbytes = 2; - break; - case 4: - case 8: - insn->immediate.value = get_next(int, insn); - insn->immediate.nbytes = 4; - break; - default: /* opnd_bytes must be modified manually */ - goto err_out; - } - - return 1; - -err_out: - return 0; -} - -/* Decode imm v64(Iv/Ov), Return 0 if failed */ -static int __get_immv(struct insn *insn) -{ - switch (insn->opnd_bytes) { - case 2: - insn->immediate1.value = get_next(short, insn); - insn->immediate1.nbytes = 2; - break; - case 4: - insn->immediate1.value = get_next(int, insn); - insn->immediate1.nbytes = 4; - break; - case 8: - insn->immediate1.value = get_next(int, insn); - insn->immediate1.nbytes = 4; - insn->immediate2.value = get_next(int, insn); - insn->immediate2.nbytes = 4; - break; - default: /* opnd_bytes must be modified manually */ - goto err_out; - } - insn->immediate1.got = insn->immediate2.got = 1; - - return 1; -err_out: - return 0; -} - -/* Decode ptr16:16/32(Ap) */ -static int __get_immptr(struct insn *insn) -{ - switch (insn->opnd_bytes) { - case 2: - insn->immediate1.value = get_next(short, insn); - insn->immediate1.nbytes = 2; - break; - case 4: - insn->immediate1.value = get_next(int, insn); - insn->immediate1.nbytes = 4; - break; - case 8: - /* ptr16:64 is not exist (no segment) */ - return 0; - default: /* opnd_bytes must be modified manually */ - goto err_out; - } - insn->immediate2.value = get_next(unsigned short, insn); - insn->immediate2.nbytes = 2; - insn->immediate1.got = insn->immediate2.got = 1; - - return 1; -err_out: - return 0; -} - -/** - * insn_get_immediate() - Get the immediates of instruction - * @insn: &struct insn containing instruction - * - * If necessary, first collects the instruction up to and including the - * displacement bytes. - * Basically, most of immediates are sign-expanded. Unsigned-value can be - * get by bit masking with ((1 << (nbytes * 8)) - 1) - */ -void insn_get_immediate(struct insn *insn) -{ - if (insn->immediate.got) - return; - if (!insn->displacement.got) - insn_get_displacement(insn); - - if (inat_has_moffset(insn->attr)) { - if (!__get_moffset(insn)) - goto err_out; - goto done; - } - - if (!inat_has_immediate(insn->attr)) - /* no immediates */ - goto done; - - switch (inat_immediate_size(insn->attr)) { - case INAT_IMM_BYTE: - insn->immediate.value = get_next(signed char, insn); - insn->immediate.nbytes = 1; - break; - case INAT_IMM_WORD: - insn->immediate.value = get_next(short, insn); - insn->immediate.nbytes = 2; - break; - case INAT_IMM_DWORD: - insn->immediate.value = get_next(int, insn); - insn->immediate.nbytes = 4; - break; - case INAT_IMM_QWORD: - insn->immediate1.value = get_next(int, insn); - insn->immediate1.nbytes = 4; - insn->immediate2.value = get_next(int, insn); - insn->immediate2.nbytes = 4; - break; - case INAT_IMM_PTR: - if (!__get_immptr(insn)) - goto err_out; - break; - case INAT_IMM_VWORD32: - if (!__get_immv32(insn)) - goto err_out; - break; - case INAT_IMM_VWORD: - if (!__get_immv(insn)) - goto err_out; - break; - default: - /* Here, insn must have an immediate, but failed */ - goto err_out; - } - if (inat_has_second_immediate(insn->attr)) { - insn->immediate2.value = get_next(signed char, insn); - insn->immediate2.nbytes = 1; - } -done: - insn->immediate.got = 1; - -err_out: - return; -} - -/** - * insn_get_length() - Get the length of instruction - * @insn: &struct insn containing instruction - * - * If necessary, first collects the instruction up to and including the - * immediates bytes. - */ -void insn_get_length(struct insn *insn) -{ - if (insn->length) - return; - if (!insn->immediate.got) - insn_get_immediate(insn); - insn->length = (unsigned char)((unsigned long)insn->next_byte - - (unsigned long)insn->kaddr); -} diff --git a/tools/perf/util/intel-pt-decoder/insn.h b/tools/perf/util/intel-pt-decoder/insn.h deleted file mode 100644 index 37a4c390750b..000000000000 --- a/tools/perf/util/intel-pt-decoder/insn.h +++ /dev/null @@ -1,216 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -#ifndef _ASM_X86_INSN_H -#define _ASM_X86_INSN_H -/* - * x86 instruction analysis - * - * Copyright (C) IBM Corporation, 2009 - */ - -/* insn_attr_t is defined in inat.h */ -#include "inat.h" - -struct insn_field { - union { - insn_value_t value; - insn_byte_t bytes[4]; - }; - /* !0 if we've run insn_get_xxx() for this field */ - unsigned char got; - unsigned char nbytes; -}; - -struct insn { - struct insn_field prefixes; /* - * Prefixes - * prefixes.bytes[3]: last prefix - */ - struct insn_field rex_prefix; /* REX prefix */ - struct insn_field vex_prefix; /* VEX prefix */ - struct insn_field opcode; /* - * opcode.bytes[0]: opcode1 - * opcode.bytes[1]: opcode2 - * opcode.bytes[2]: opcode3 - */ - struct insn_field modrm; - struct insn_field sib; - struct insn_field displacement; - union { - struct insn_field immediate; - struct insn_field moffset1; /* for 64bit MOV */ - struct insn_field immediate1; /* for 64bit imm or off16/32 */ - }; - union { - struct insn_field moffset2; /* for 64bit MOV */ - struct insn_field immediate2; /* for 64bit imm or seg16 */ - }; - - insn_attr_t attr; - unsigned char opnd_bytes; - unsigned char addr_bytes; - unsigned char length; - unsigned char x86_64; - - const insn_byte_t *kaddr; /* kernel address of insn to analyze */ - const insn_byte_t *end_kaddr; /* kernel address of last insn in buffer */ - const insn_byte_t *next_byte; -}; - -#define MAX_INSN_SIZE 15 - -#define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6) -#define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3) -#define X86_MODRM_RM(modrm) ((modrm) & 0x07) - -#define X86_SIB_SCALE(sib) (((sib) & 0xc0) >> 6) -#define X86_SIB_INDEX(sib) (((sib) & 0x38) >> 3) -#define X86_SIB_BASE(sib) ((sib) & 0x07) - -#define X86_REX_W(rex) ((rex) & 8) -#define X86_REX_R(rex) ((rex) & 4) -#define X86_REX_X(rex) ((rex) & 2) -#define X86_REX_B(rex) ((rex) & 1) - -/* VEX bit flags */ -#define X86_VEX_W(vex) ((vex) & 0x80) /* VEX3 Byte2 */ -#define X86_VEX_R(vex) ((vex) & 0x80) /* VEX2/3 Byte1 */ -#define X86_VEX_X(vex) ((vex) & 0x40) /* VEX3 Byte1 */ -#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */ -#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */ -/* VEX bit fields */ -#define X86_EVEX_M(vex) ((vex) & 0x03) /* EVEX Byte1 */ -#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */ -#define X86_VEX2_M 1 /* VEX2.M always 1 */ -#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */ -#define X86_VEX_P(vex) ((vex) & 0x03) /* VEX3 Byte2, VEX2 Byte1 */ -#define X86_VEX_M_MAX 0x1f /* VEX3.M Maximum value */ - -extern void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64); -extern void insn_get_prefixes(struct insn *insn); -extern void insn_get_opcode(struct insn *insn); -extern void insn_get_modrm(struct insn *insn); -extern void insn_get_sib(struct insn *insn); -extern void insn_get_displacement(struct insn *insn); -extern void insn_get_immediate(struct insn *insn); -extern void insn_get_length(struct insn *insn); - -/* Attribute will be determined after getting ModRM (for opcode groups) */ -static inline void insn_get_attribute(struct insn *insn) -{ - insn_get_modrm(insn); -} - -/* Instruction uses RIP-relative addressing */ -extern int insn_rip_relative(struct insn *insn); - -/* Init insn for kernel text */ -static inline void kernel_insn_init(struct insn *insn, - const void *kaddr, int buf_len) -{ -#ifdef CONFIG_X86_64 - insn_init(insn, kaddr, buf_len, 1); -#else /* CONFIG_X86_32 */ - insn_init(insn, kaddr, buf_len, 0); -#endif -} - -static inline int insn_is_avx(struct insn *insn) -{ - if (!insn->prefixes.got) - insn_get_prefixes(insn); - return (insn->vex_prefix.value != 0); -} - -static inline int insn_is_evex(struct insn *insn) -{ - if (!insn->prefixes.got) - insn_get_prefixes(insn); - return (insn->vex_prefix.nbytes == 4); -} - -/* Ensure this instruction is decoded completely */ -static inline int insn_complete(struct insn *insn) -{ - return insn->opcode.got && insn->modrm.got && insn->sib.got && - insn->displacement.got && insn->immediate.got; -} - -static inline insn_byte_t insn_vex_m_bits(struct insn *insn) -{ - if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */ - return X86_VEX2_M; - else if (insn->vex_prefix.nbytes == 3) /* 3 bytes VEX */ - return X86_VEX3_M(insn->vex_prefix.bytes[1]); - else /* EVEX */ - return X86_EVEX_M(insn->vex_prefix.bytes[1]); -} - -static inline insn_byte_t insn_vex_p_bits(struct insn *insn) -{ - if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */ - return X86_VEX_P(insn->vex_prefix.bytes[1]); - else - return X86_VEX_P(insn->vex_prefix.bytes[2]); -} - -/* Get the last prefix id from last prefix or VEX prefix */ -static inline int insn_last_prefix_id(struct insn *insn) -{ - if (insn_is_avx(insn)) - return insn_vex_p_bits(insn); /* VEX_p is a SIMD prefix id */ - - if (insn->prefixes.bytes[3]) - return inat_get_last_prefix_id(insn->prefixes.bytes[3]); - - return 0; -} - -/* Offset of each field from kaddr */ -static inline int insn_offset_rex_prefix(struct insn *insn) -{ - return insn->prefixes.nbytes; -} -static inline int insn_offset_vex_prefix(struct insn *insn) -{ - return insn_offset_rex_prefix(insn) + insn->rex_prefix.nbytes; -} -static inline int insn_offset_opcode(struct insn *insn) -{ - return insn_offset_vex_prefix(insn) + insn->vex_prefix.nbytes; -} -static inline int insn_offset_modrm(struct insn *insn) -{ - return insn_offset_opcode(insn) + insn->opcode.nbytes; -} -static inline int insn_offset_sib(struct insn *insn) -{ - return insn_offset_modrm(insn) + insn->modrm.nbytes; -} -static inline int insn_offset_displacement(struct insn *insn) -{ - return insn_offset_sib(insn) + insn->sib.nbytes; -} -static inline int insn_offset_immediate(struct insn *insn) -{ - return insn_offset_displacement(insn) + insn->displacement.nbytes; -} - -#define POP_SS_OPCODE 0x1f -#define MOV_SREG_OPCODE 0x8e - -/* - * Intel SDM Vol.3A 6.8.3 states; - * "Any single-step trap that would be delivered following the MOV to SS - * instruction or POP to SS instruction (because EFLAGS.TF is 1) is - * suppressed." - * This function returns true if @insn is MOV SS or POP SS. On these - * instructions, single stepping is suppressed. - */ -static inline int insn_masking_exception(struct insn *insn) -{ - return insn->opcode.bytes[0] == POP_SS_OPCODE || - (insn->opcode.bytes[0] == MOV_SREG_OPCODE && - X86_MODRM_REG(insn->modrm.bytes[0]) == 2); -} - -#endif /* _ASM_X86_INSN_H */ diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c index 598f56be9f17..fb8a3558d3d5 100644 --- a/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c +++ b/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c @@ -4,17 +4,17 @@ * Copyright (c) 2013-2014, Intel Corporation. */ +#include #include #include #include #include +#include "../../../arch/x86/include/asm/insn.h" -#include "event.h" - -#include "insn.h" +#include "../../../arch/x86/lib/inat.c" +#include "../../../arch/x86/lib/insn.c" -#include "inat.c" -#include "insn.c" +#include "event.h" #include "intel-pt-insn-decoder.h" #include "dump-insn.h" diff --git a/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt b/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt deleted file mode 100644 index e0b85930dd77..000000000000 --- a/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt +++ /dev/null @@ -1,1072 +0,0 @@ -# x86 Opcode Maps -# -# This is (mostly) based on following documentations. -# - Intel(R) 64 and IA-32 Architectures Software Developer's Manual Vol.2C -# (#326018-047US, June 2013) -# -# -# Table: table-name -# Referrer: escaped-name -# AVXcode: avx-code -# opcode: mnemonic|GrpXXX [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...] -# (or) -# opcode: escape # escaped-name -# EndTable -# -# mnemonics that begin with lowercase 'v' accept a VEX or EVEX prefix -# mnemonics that begin with lowercase 'k' accept a VEX prefix -# -# -# GrpTable: GrpXXX -# reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...] -# EndTable -# -# AVX Superscripts -# (ev): this opcode requires EVEX prefix. -# (evo): this opcode is changed by EVEX prefix (EVEX opcode) -# (v): this opcode requires VEX prefix. -# (v1): this opcode only supports 128bit VEX. -# -# Last Prefix Superscripts -# - (66): the last prefix is 0x66 -# - (F3): the last prefix is 0xF3 -# - (F2): the last prefix is 0xF2 -# - (!F3) : the last prefix is not 0xF3 (including non-last prefix case) -# - (66&F2): Both 0x66 and 0xF2 prefixes are specified. - -Table: one byte opcode -Referrer: -AVXcode: -# 0x00 - 0x0f -00: ADD Eb,Gb -01: ADD Ev,Gv -02: ADD Gb,Eb -03: ADD Gv,Ev -04: ADD AL,Ib -05: ADD rAX,Iz -06: PUSH ES (i64) -07: POP ES (i64) -08: OR Eb,Gb -09: OR Ev,Gv -0a: OR Gb,Eb -0b: OR Gv,Ev -0c: OR AL,Ib -0d: OR rAX,Iz -0e: PUSH CS (i64) -0f: escape # 2-byte escape -# 0x10 - 0x1f -10: ADC Eb,Gb -11: ADC Ev,Gv -12: ADC Gb,Eb -13: ADC Gv,Ev -14: ADC AL,Ib -15: ADC rAX,Iz -16: PUSH SS (i64) -17: POP SS (i64) -18: SBB Eb,Gb -19: SBB Ev,Gv -1a: SBB Gb,Eb -1b: SBB Gv,Ev -1c: SBB AL,Ib -1d: SBB rAX,Iz -1e: PUSH DS (i64) -1f: POP DS (i64) -# 0x20 - 0x2f -20: AND Eb,Gb -21: AND Ev,Gv -22: AND Gb,Eb -23: AND Gv,Ev -24: AND AL,Ib -25: AND rAx,Iz -26: SEG=ES (Prefix) -27: DAA (i64) -28: SUB Eb,Gb -29: SUB Ev,Gv -2a: SUB Gb,Eb -2b: SUB Gv,Ev -2c: SUB AL,Ib -2d: SUB rAX,Iz -2e: SEG=CS (Prefix) -2f: DAS (i64) -# 0x30 - 0x3f -30: XOR Eb,Gb -31: XOR Ev,Gv -32: XOR Gb,Eb -33: XOR Gv,Ev -34: XOR AL,Ib -35: XOR rAX,Iz -36: SEG=SS (Prefix) -37: AAA (i64) -38: CMP Eb,Gb -39: CMP Ev,Gv -3a: CMP Gb,Eb -3b: CMP Gv,Ev -3c: CMP AL,Ib -3d: CMP rAX,Iz -3e: SEG=DS (Prefix) -3f: AAS (i64) -# 0x40 - 0x4f -40: INC eAX (i64) | REX (o64) -41: INC eCX (i64) | REX.B (o64) -42: INC eDX (i64) | REX.X (o64) -43: INC eBX (i64) | REX.XB (o64) -44: INC eSP (i64) | REX.R (o64) -45: INC eBP (i64) | REX.RB (o64) -46: INC eSI (i64) | REX.RX (o64) -47: INC eDI (i64) | REX.RXB (o64) -48: DEC eAX (i64) | REX.W (o64) -49: DEC eCX (i64) | REX.WB (o64) -4a: DEC eDX (i64) | REX.WX (o64) -4b: DEC eBX (i64) | REX.WXB (o64) -4c: DEC eSP (i64) | REX.WR (o64) -4d: DEC eBP (i64) | REX.WRB (o64) -4e: DEC eSI (i64) | REX.WRX (o64) -4f: DEC eDI (i64) | REX.WRXB (o64) -# 0x50 - 0x5f -50: PUSH rAX/r8 (d64) -51: PUSH rCX/r9 (d64) -52: PUSH rDX/r10 (d64) -53: PUSH rBX/r11 (d64) -54: PUSH rSP/r12 (d64) -55: PUSH rBP/r13 (d64) -56: PUSH rSI/r14 (d64) -57: PUSH rDI/r15 (d64) -58: POP rAX/r8 (d64) -59: POP rCX/r9 (d64) -5a: POP rDX/r10 (d64) -5b: POP rBX/r11 (d64) -5c: POP rSP/r12 (d64) -5d: POP rBP/r13 (d64) -5e: POP rSI/r14 (d64) -5f: POP rDI/r15 (d64) -# 0x60 - 0x6f -60: PUSHA/PUSHAD (i64) -61: POPA/POPAD (i64) -62: BOUND Gv,Ma (i64) | EVEX (Prefix) -63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64) -64: SEG=FS (Prefix) -65: SEG=GS (Prefix) -66: Operand-Size (Prefix) -67: Address-Size (Prefix) -68: PUSH Iz (d64) -69: IMUL Gv,Ev,Iz -6a: PUSH Ib (d64) -6b: IMUL Gv,Ev,Ib -6c: INS/INSB Yb,DX -6d: INS/INSW/INSD Yz,DX -6e: OUTS/OUTSB DX,Xb -6f: OUTS/OUTSW/OUTSD DX,Xz -# 0x70 - 0x7f -70: JO Jb -71: JNO Jb -72: JB/JNAE/JC Jb -73: JNB/JAE/JNC Jb -74: JZ/JE Jb -75: JNZ/JNE Jb -76: JBE/JNA Jb -77: JNBE/JA Jb -78: JS Jb -79: JNS Jb -7a: JP/JPE Jb -7b: JNP/JPO Jb -7c: JL/JNGE Jb -7d: JNL/JGE Jb -7e: JLE/JNG Jb -7f: JNLE/JG Jb -# 0x80 - 0x8f -80: Grp1 Eb,Ib (1A) -81: Grp1 Ev,Iz (1A) -82: Grp1 Eb,Ib (1A),(i64) -83: Grp1 Ev,Ib (1A) -84: TEST Eb,Gb -85: TEST Ev,Gv -86: XCHG Eb,Gb -87: XCHG Ev,Gv -88: MOV Eb,Gb -89: MOV Ev,Gv -8a: MOV Gb,Eb -8b: MOV Gv,Ev -8c: MOV Ev,Sw -8d: LEA Gv,M -8e: MOV Sw,Ew -8f: Grp1A (1A) | POP Ev (d64) -# 0x90 - 0x9f -90: NOP | PAUSE (F3) | XCHG r8,rAX -91: XCHG rCX/r9,rAX -92: XCHG rDX/r10,rAX -93: XCHG rBX/r11,rAX -94: XCHG rSP/r12,rAX -95: XCHG rBP/r13,rAX -96: XCHG rSI/r14,rAX -97: XCHG rDI/r15,rAX -98: CBW/CWDE/CDQE -99: CWD/CDQ/CQO -9a: CALLF Ap (i64) -9b: FWAIT/WAIT -9c: PUSHF/D/Q Fv (d64) -9d: POPF/D/Q Fv (d64) -9e: SAHF -9f: LAHF -# 0xa0 - 0xaf -a0: MOV AL,Ob -a1: MOV rAX,Ov -a2: MOV Ob,AL -a3: MOV Ov,rAX -a4: MOVS/B Yb,Xb -a5: MOVS/W/D/Q Yv,Xv -a6: CMPS/B Xb,Yb -a7: CMPS/W/D Xv,Yv -a8: TEST AL,Ib -a9: TEST rAX,Iz -aa: STOS/B Yb,AL -ab: STOS/W/D/Q Yv,rAX -ac: LODS/B AL,Xb -ad: LODS/W/D/Q rAX,Xv -ae: SCAS/B AL,Yb -# Note: The May 2011 Intel manual shows Xv for the second parameter of the -# next instruction but Yv is correct -af: SCAS/W/D/Q rAX,Yv -# 0xb0 - 0xbf -b0: MOV AL/R8L,Ib -b1: MOV CL/R9L,Ib -b2: MOV DL/R10L,Ib -b3: MOV BL/R11L,Ib -b4: MOV AH/R12L,Ib -b5: MOV CH/R13L,Ib -b6: MOV DH/R14L,Ib -b7: MOV BH/R15L,Ib -b8: MOV rAX/r8,Iv -b9: MOV rCX/r9,Iv -ba: MOV rDX/r10,Iv -bb: MOV rBX/r11,Iv -bc: MOV rSP/r12,Iv -bd: MOV rBP/r13,Iv -be: MOV rSI/r14,Iv -bf: MOV rDI/r15,Iv -# 0xc0 - 0xcf -c0: Grp2 Eb,Ib (1A) -c1: Grp2 Ev,Ib (1A) -c2: RETN Iw (f64) -c3: RETN -c4: LES Gz,Mp (i64) | VEX+2byte (Prefix) -c5: LDS Gz,Mp (i64) | VEX+1byte (Prefix) -c6: Grp11A Eb,Ib (1A) -c7: Grp11B Ev,Iz (1A) -c8: ENTER Iw,Ib -c9: LEAVE (d64) -ca: RETF Iw -cb: RETF -cc: INT3 -cd: INT Ib -ce: INTO (i64) -cf: IRET/D/Q -# 0xd0 - 0xdf -d0: Grp2 Eb,1 (1A) -d1: Grp2 Ev,1 (1A) -d2: Grp2 Eb,CL (1A) -d3: Grp2 Ev,CL (1A) -d4: AAM Ib (i64) -d5: AAD Ib (i64) -d6: -d7: XLAT/XLATB -d8: ESC -d9: ESC -da: ESC -db: ESC -dc: ESC -dd: ESC -de: ESC -df: ESC -# 0xe0 - 0xef -# Note: "forced64" is Intel CPU behavior: they ignore 0x66 prefix -# in 64-bit mode. AMD CPUs accept 0x66 prefix, it causes RIP truncation -# to 16 bits. In 32-bit mode, 0x66 is accepted by both Intel and AMD. -e0: LOOPNE/LOOPNZ Jb (f64) -e1: LOOPE/LOOPZ Jb (f64) -e2: LOOP Jb (f64) -e3: JrCXZ Jb (f64) -e4: IN AL,Ib -e5: IN eAX,Ib -e6: OUT Ib,AL -e7: OUT Ib,eAX -# With 0x66 prefix in 64-bit mode, for AMD CPUs immediate offset -# in "near" jumps and calls is 16-bit. For CALL, -# push of return address is 16-bit wide, RSP is decremented by 2 -# but is not truncated to 16 bits, unlike RIP. -e8: CALL Jz (f64) -e9: JMP-near Jz (f64) -ea: JMP-far Ap (i64) -eb: JMP-short Jb (f64) -ec: IN AL,DX -ed: IN eAX,DX -ee: OUT DX,AL -ef: OUT DX,eAX -# 0xf0 - 0xff -f0: LOCK (Prefix) -f1: -f2: REPNE (Prefix) | XACQUIRE (Prefix) -f3: REP/REPE (Prefix) | XRELEASE (Prefix) -f4: HLT -f5: CMC -f6: Grp3_1 Eb (1A) -f7: Grp3_2 Ev (1A) -f8: CLC -f9: STC -fa: CLI -fb: STI -fc: CLD -fd: STD -fe: Grp4 (1A) -ff: Grp5 (1A) -EndTable - -Table: 2-byte opcode (0x0f) -Referrer: 2-byte escape -AVXcode: 1 -# 0x0f 0x00-0x0f -00: Grp6 (1A) -01: Grp7 (1A) -02: LAR Gv,Ew -03: LSL Gv,Ew -04: -05: SYSCALL (o64) -06: CLTS -07: SYSRET (o64) -08: INVD -09: WBINVD -0a: -0b: UD2 (1B) -0c: -# AMD's prefetch group. Intel supports prefetchw(/1) only. -0d: GrpP -0e: FEMMS -# 3DNow! uses the last imm byte as opcode extension. -0f: 3DNow! Pq,Qq,Ib -# 0x0f 0x10-0x1f -# NOTE: According to Intel SDM opcode map, vmovups and vmovupd has no operands -# but it actually has operands. And also, vmovss and vmovsd only accept 128bit. -# MOVSS/MOVSD has too many forms(3) on SDM. This map just shows a typical form. -# Many AVX instructions lack v1 superscript, according to Intel AVX-Prgramming -# Reference A.1 -10: vmovups Vps,Wps | vmovupd Vpd,Wpd (66) | vmovss Vx,Hx,Wss (F3),(v1) | vmovsd Vx,Hx,Wsd (F2),(v1) -11: vmovups Wps,Vps | vmovupd Wpd,Vpd (66) | vmovss Wss,Hx,Vss (F3),(v1) | vmovsd Wsd,Hx,Vsd (F2),(v1) -12: vmovlps Vq,Hq,Mq (v1) | vmovhlps Vq,Hq,Uq (v1) | vmovlpd Vq,Hq,Mq (66),(v1) | vmovsldup Vx,Wx (F3) | vmovddup Vx,Wx (F2) -13: vmovlps Mq,Vq (v1) | vmovlpd Mq,Vq (66),(v1) -14: vunpcklps Vx,Hx,Wx | vunpcklpd Vx,Hx,Wx (66) -15: vunpckhps Vx,Hx,Wx | vunpckhpd Vx,Hx,Wx (66) -16: vmovhps Vdq,Hq,Mq (v1) | vmovlhps Vdq,Hq,Uq (v1) | vmovhpd Vdq,Hq,Mq (66),(v1) | vmovshdup Vx,Wx (F3) -17: vmovhps Mq,Vq (v1) | vmovhpd Mq,Vq (66),(v1) -18: Grp16 (1A) -19: -# Intel SDM opcode map does not list MPX instructions. For now using Gv for -# bnd registers and Ev for everything else is OK because the instruction -# decoder does not use the information except as an indication that there is -# a ModR/M byte. -1a: BNDCL Gv,Ev (F3) | BNDCU Gv,Ev (F2) | BNDMOV Gv,Ev (66) | BNDLDX Gv,Ev -1b: BNDCN Gv,Ev (F2) | BNDMOV Ev,Gv (66) | BNDMK Gv,Ev (F3) | BNDSTX Ev,Gv -1c: -1d: -1e: -1f: NOP Ev -# 0x0f 0x20-0x2f -20: MOV Rd,Cd -21: MOV Rd,Dd -22: MOV Cd,Rd -23: MOV Dd,Rd -24: -25: -26: -27: -28: vmovaps Vps,Wps | vmovapd Vpd,Wpd (66) -29: vmovaps Wps,Vps | vmovapd Wpd,Vpd (66) -2a: cvtpi2ps Vps,Qpi | cvtpi2pd Vpd,Qpi (66) | vcvtsi2ss Vss,Hss,Ey (F3),(v1) | vcvtsi2sd Vsd,Hsd,Ey (F2),(v1) -2b: vmovntps Mps,Vps | vmovntpd Mpd,Vpd (66) -2c: cvttps2pi Ppi,Wps | cvttpd2pi Ppi,Wpd (66) | vcvttss2si Gy,Wss (F3),(v1) | vcvttsd2si Gy,Wsd (F2),(v1) -2d: cvtps2pi Ppi,Wps | cvtpd2pi Qpi,Wpd (66) | vcvtss2si Gy,Wss (F3),(v1) | vcvtsd2si Gy,Wsd (F2),(v1) -2e: vucomiss Vss,Wss (v1) | vucomisd Vsd,Wsd (66),(v1) -2f: vcomiss Vss,Wss (v1) | vcomisd Vsd,Wsd (66),(v1) -# 0x0f 0x30-0x3f -30: WRMSR -31: RDTSC -32: RDMSR -33: RDPMC -34: SYSENTER -35: SYSEXIT -36: -37: GETSEC -38: escape # 3-byte escape 1 -39: -3a: escape # 3-byte escape 2 -3b: -3c: -3d: -3e: -3f: -# 0x0f 0x40-0x4f -40: CMOVO Gv,Ev -41: CMOVNO Gv,Ev | kandw/q Vk,Hk,Uk | kandb/d Vk,Hk,Uk (66) -42: CMOVB/C/NAE Gv,Ev | kandnw/q Vk,Hk,Uk | kandnb/d Vk,Hk,Uk (66) -43: CMOVAE/NB/NC Gv,Ev -44: CMOVE/Z Gv,Ev | knotw/q Vk,Uk | knotb/d Vk,Uk (66) -45: CMOVNE/NZ Gv,Ev | korw/q Vk,Hk,Uk | korb/d Vk,Hk,Uk (66) -46: CMOVBE/NA Gv,Ev | kxnorw/q Vk,Hk,Uk | kxnorb/d Vk,Hk,Uk (66) -47: CMOVA/NBE Gv,Ev | kxorw/q Vk,Hk,Uk | kxorb/d Vk,Hk,Uk (66) -48: CMOVS Gv,Ev -49: CMOVNS Gv,Ev -4a: CMOVP/PE Gv,Ev | kaddw/q Vk,Hk,Uk | kaddb/d Vk,Hk,Uk (66) -4b: CMOVNP/PO Gv,Ev | kunpckbw Vk,Hk,Uk (66) | kunpckwd/dq Vk,Hk,Uk -4c: CMOVL/NGE Gv,Ev -4d: CMOVNL/GE Gv,Ev -4e: CMOVLE/NG Gv,Ev -4f: CMOVNLE/G Gv,Ev -# 0x0f 0x50-0x5f -50: vmovmskps Gy,Ups | vmovmskpd Gy,Upd (66) -51: vsqrtps Vps,Wps | vsqrtpd Vpd,Wpd (66) | vsqrtss Vss,Hss,Wss (F3),(v1) | vsqrtsd Vsd,Hsd,Wsd (F2),(v1) -52: vrsqrtps Vps,Wps | vrsqrtss Vss,Hss,Wss (F3),(v1) -53: vrcpps Vps,Wps | vrcpss Vss,Hss,Wss (F3),(v1) -54: vandps Vps,Hps,Wps | vandpd Vpd,Hpd,Wpd (66) -55: vandnps Vps,Hps,Wps | vandnpd Vpd,Hpd,Wpd (66) -56: vorps Vps,Hps,Wps | vorpd Vpd,Hpd,Wpd (66) -57: vxorps Vps,Hps,Wps | vxorpd Vpd,Hpd,Wpd (66) -58: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1) -59: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1) -5a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1) -5b: vcvtdq2ps Vps,Wdq | vcvtqq2ps Vps,Wqq (evo) | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3) -5c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1) -5d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1) -5e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1) -5f: vmaxps Vps,Hps,Wps | vmaxpd Vpd,Hpd,Wpd (66) | vmaxss Vss,Hss,Wss (F3),(v1) | vmaxsd Vsd,Hsd,Wsd (F2),(v1) -# 0x0f 0x60-0x6f -60: punpcklbw Pq,Qd | vpunpcklbw Vx,Hx,Wx (66),(v1) -61: punpcklwd Pq,Qd | vpunpcklwd Vx,Hx,Wx (66),(v1) -62: punpckldq Pq,Qd | vpunpckldq Vx,Hx,Wx (66),(v1) -63: packsswb Pq,Qq | vpacksswb Vx,Hx,Wx (66),(v1) -64: pcmpgtb Pq,Qq | vpcmpgtb Vx,Hx,Wx (66),(v1) -65: pcmpgtw Pq,Qq | vpcmpgtw Vx,Hx,Wx (66),(v1) -66: pcmpgtd Pq,Qq | vpcmpgtd Vx,Hx,Wx (66),(v1) -67: packuswb Pq,Qq | vpackuswb Vx,Hx,Wx (66),(v1) -68: punpckhbw Pq,Qd | vpunpckhbw Vx,Hx,Wx (66),(v1) -69: punpckhwd Pq,Qd | vpunpckhwd Vx,Hx,Wx (66),(v1) -6a: punpckhdq Pq,Qd | vpunpckhdq Vx,Hx,Wx (66),(v1) -6b: packssdw Pq,Qd | vpackssdw Vx,Hx,Wx (66),(v1) -6c: vpunpcklqdq Vx,Hx,Wx (66),(v1) -6d: vpunpckhqdq Vx,Hx,Wx (66),(v1) -6e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1) -6f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqa32/64 Vx,Wx (66),(evo) | vmovdqu Vx,Wx (F3) | vmovdqu32/64 Vx,Wx (F3),(evo) | vmovdqu8/16 Vx,Wx (F2),(ev) -# 0x0f 0x70-0x7f -70: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1) -71: Grp12 (1A) -72: Grp13 (1A) -73: Grp14 (1A) -74: pcmpeqb Pq,Qq | vpcmpeqb Vx,Hx,Wx (66),(v1) -75: pcmpeqw Pq,Qq | vpcmpeqw Vx,Hx,Wx (66),(v1) -76: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1) -# Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX. -77: emms | vzeroupper | vzeroall -78: VMREAD Ey,Gy | vcvttps2udq/pd2udq Vx,Wpd (evo) | vcvttsd2usi Gv,Wx (F2),(ev) | vcvttss2usi Gv,Wx (F3),(ev) | vcvttps2uqq/pd2uqq Vx,Wx (66),(ev) -79: VMWRITE Gy,Ey | vcvtps2udq/pd2udq Vx,Wpd (evo) | vcvtsd2usi Gv,Wx (F2),(ev) | vcvtss2usi Gv,Wx (F3),(ev) | vcvtps2uqq/pd2uqq Vx,Wx (66),(ev) -7a: vcvtudq2pd/uqq2pd Vpd,Wx (F3),(ev) | vcvtudq2ps/uqq2ps Vpd,Wx (F2),(ev) | vcvttps2qq/pd2qq Vx,Wx (66),(ev) -7b: vcvtusi2sd Vpd,Hpd,Ev (F2),(ev) | vcvtusi2ss Vps,Hps,Ev (F3),(ev) | vcvtps2qq/pd2qq Vx,Wx (66),(ev) -7c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2) -7d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2) -7e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1) -7f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqa32/64 Wx,Vx (66),(evo) | vmovdqu Wx,Vx (F3) | vmovdqu32/64 Wx,Vx (F3),(evo) | vmovdqu8/16 Wx,Vx (F2),(ev) -# 0x0f 0x80-0x8f -# Note: "forced64" is Intel CPU behavior (see comment about CALL insn). -80: JO Jz (f64) -81: JNO Jz (f64) -82: JB/JC/JNAE Jz (f64) -83: JAE/JNB/JNC Jz (f64) -84: JE/JZ Jz (f64) -85: JNE/JNZ Jz (f64) -86: JBE/JNA Jz (f64) -87: JA/JNBE Jz (f64) -88: JS Jz (f64) -89: JNS Jz (f64) -8a: JP/JPE Jz (f64) -8b: JNP/JPO Jz (f64) -8c: JL/JNGE Jz (f64) -8d: JNL/JGE Jz (f64) -8e: JLE/JNG Jz (f64) -8f: JNLE/JG Jz (f64) -# 0x0f 0x90-0x9f -90: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66) -91: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66) -92: SETB/C/NAE Eb | kmovw Vk,Rv | kmovb Vk,Rv (66) | kmovq/d Vk,Rv (F2) -93: SETAE/NB/NC Eb | kmovw Gv,Uk | kmovb Gv,Uk (66) | kmovq/d Gv,Uk (F2) -94: SETE/Z Eb -95: SETNE/NZ Eb -96: SETBE/NA Eb -97: SETA/NBE Eb -98: SETS Eb | kortestw/q Vk,Uk | kortestb/d Vk,Uk (66) -99: SETNS Eb | ktestw/q Vk,Uk | ktestb/d Vk,Uk (66) -9a: SETP/PE Eb -9b: SETNP/PO Eb -9c: SETL/NGE Eb -9d: SETNL/GE Eb -9e: SETLE/NG Eb -9f: SETNLE/G Eb -# 0x0f 0xa0-0xaf -a0: PUSH FS (d64) -a1: POP FS (d64) -a2: CPUID -a3: BT Ev,Gv -a4: SHLD Ev,Gv,Ib -a5: SHLD Ev,Gv,CL -a6: GrpPDLK -a7: GrpRNG -a8: PUSH GS (d64) -a9: POP GS (d64) -aa: RSM -ab: BTS Ev,Gv -ac: SHRD Ev,Gv,Ib -ad: SHRD Ev,Gv,CL -ae: Grp15 (1A),(1C) -af: IMUL Gv,Ev -# 0x0f 0xb0-0xbf -b0: CMPXCHG Eb,Gb -b1: CMPXCHG Ev,Gv -b2: LSS Gv,Mp -b3: BTR Ev,Gv -b4: LFS Gv,Mp -b5: LGS Gv,Mp -b6: MOVZX Gv,Eb -b7: MOVZX Gv,Ew -b8: JMPE (!F3) | POPCNT Gv,Ev (F3) -b9: Grp10 (1A) -ba: Grp8 Ev,Ib (1A) -bb: BTC Ev,Gv -bc: BSF Gv,Ev (!F3) | TZCNT Gv,Ev (F3) -bd: BSR Gv,Ev (!F3) | LZCNT Gv,Ev (F3) -be: MOVSX Gv,Eb -bf: MOVSX Gv,Ew -# 0x0f 0xc0-0xcf -c0: XADD Eb,Gb -c1: XADD Ev,Gv -c2: vcmpps Vps,Hps,Wps,Ib | vcmppd Vpd,Hpd,Wpd,Ib (66) | vcmpss Vss,Hss,Wss,Ib (F3),(v1) | vcmpsd Vsd,Hsd,Wsd,Ib (F2),(v1) -c3: movnti My,Gy -c4: pinsrw Pq,Ry/Mw,Ib | vpinsrw Vdq,Hdq,Ry/Mw,Ib (66),(v1) -c5: pextrw Gd,Nq,Ib | vpextrw Gd,Udq,Ib (66),(v1) -c6: vshufps Vps,Hps,Wps,Ib | vshufpd Vpd,Hpd,Wpd,Ib (66) -c7: Grp9 (1A) -c8: BSWAP RAX/EAX/R8/R8D -c9: BSWAP RCX/ECX/R9/R9D -ca: BSWAP RDX/EDX/R10/R10D -cb: BSWAP RBX/EBX/R11/R11D -cc: BSWAP RSP/ESP/R12/R12D -cd: BSWAP RBP/EBP/R13/R13D -ce: BSWAP RSI/ESI/R14/R14D -cf: BSWAP RDI/EDI/R15/R15D -# 0x0f 0xd0-0xdf -d0: vaddsubpd Vpd,Hpd,Wpd (66) | vaddsubps Vps,Hps,Wps (F2) -d1: psrlw Pq,Qq | vpsrlw Vx,Hx,Wx (66),(v1) -d2: psrld Pq,Qq | vpsrld Vx,Hx,Wx (66),(v1) -d3: psrlq Pq,Qq | vpsrlq Vx,Hx,Wx (66),(v1) -d4: paddq Pq,Qq | vpaddq Vx,Hx,Wx (66),(v1) -d5: pmullw Pq,Qq | vpmullw Vx,Hx,Wx (66),(v1) -d6: vmovq Wq,Vq (66),(v1) | movq2dq Vdq,Nq (F3) | movdq2q Pq,Uq (F2) -d7: pmovmskb Gd,Nq | vpmovmskb Gd,Ux (66),(v1) -d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1) -d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1) -da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1) -db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) | vpandd/q Vx,Hx,Wx (66),(evo) -dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1) -dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1) -de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1) -df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) | vpandnd/q Vx,Hx,Wx (66),(evo) -# 0x0f 0xe0-0xef -e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1) -e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1) -e2: psrad Pq,Qq | vpsrad Vx,Hx,Wx (66),(v1) -e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1) -e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1) -e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1) -e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtdq2pd/qq2pd Vx,Wdq (F3),(evo) | vcvtpd2dq Vx,Wpd (F2) -e7: movntq Mq,Pq | vmovntdq Mx,Vx (66) -e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1) -e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1) -ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1) -eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) | vpord/q Vx,Hx,Wx (66),(evo) -ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1) -ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1) -ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1) -ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) | vpxord/q Vx,Hx,Wx (66),(evo) -# 0x0f 0xf0-0xff -f0: vlddqu Vx,Mx (F2) -f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1) -f2: pslld Pq,Qq | vpslld Vx,Hx,Wx (66),(v1) -f3: psllq Pq,Qq | vpsllq Vx,Hx,Wx (66),(v1) -f4: pmuludq Pq,Qq | vpmuludq Vx,Hx,Wx (66),(v1) -f5: pmaddwd Pq,Qq | vpmaddwd Vx,Hx,Wx (66),(v1) -f6: psadbw Pq,Qq | vpsadbw Vx,Hx,Wx (66),(v1) -f7: maskmovq Pq,Nq | vmaskmovdqu Vx,Ux (66),(v1) -f8: psubb Pq,Qq | vpsubb Vx,Hx,Wx (66),(v1) -f9: psubw Pq,Qq | vpsubw Vx,Hx,Wx (66),(v1) -fa: psubd Pq,Qq | vpsubd Vx,Hx,Wx (66),(v1) -fb: psubq Pq,Qq | vpsubq Vx,Hx,Wx (66),(v1) -fc: paddb Pq,Qq | vpaddb Vx,Hx,Wx (66),(v1) -fd: paddw Pq,Qq | vpaddw Vx,Hx,Wx (66),(v1) -fe: paddd Pq,Qq | vpaddd Vx,Hx,Wx (66),(v1) -ff: UD0 -EndTable - -Table: 3-byte opcode 1 (0x0f 0x38) -Referrer: 3-byte escape 1 -AVXcode: 2 -# 0x0f 0x38 0x00-0x0f -00: pshufb Pq,Qq | vpshufb Vx,Hx,Wx (66),(v1) -01: phaddw Pq,Qq | vphaddw Vx,Hx,Wx (66),(v1) -02: phaddd Pq,Qq | vphaddd Vx,Hx,Wx (66),(v1) -03: phaddsw Pq,Qq | vphaddsw Vx,Hx,Wx (66),(v1) -04: pmaddubsw Pq,Qq | vpmaddubsw Vx,Hx,Wx (66),(v1) -05: phsubw Pq,Qq | vphsubw Vx,Hx,Wx (66),(v1) -06: phsubd Pq,Qq | vphsubd Vx,Hx,Wx (66),(v1) -07: phsubsw Pq,Qq | vphsubsw Vx,Hx,Wx (66),(v1) -08: psignb Pq,Qq | vpsignb Vx,Hx,Wx (66),(v1) -09: psignw Pq,Qq | vpsignw Vx,Hx,Wx (66),(v1) -0a: psignd Pq,Qq | vpsignd Vx,Hx,Wx (66),(v1) -0b: pmulhrsw Pq,Qq | vpmulhrsw Vx,Hx,Wx (66),(v1) -0c: vpermilps Vx,Hx,Wx (66),(v) -0d: vpermilpd Vx,Hx,Wx (66),(v) -0e: vtestps Vx,Wx (66),(v) -0f: vtestpd Vx,Wx (66),(v) -# 0x0f 0x38 0x10-0x1f -10: pblendvb Vdq,Wdq (66) | vpsrlvw Vx,Hx,Wx (66),(evo) | vpmovuswb Wx,Vx (F3),(ev) -11: vpmovusdb Wx,Vd (F3),(ev) | vpsravw Vx,Hx,Wx (66),(ev) -12: vpmovusqb Wx,Vq (F3),(ev) | vpsllvw Vx,Hx,Wx (66),(ev) -13: vcvtph2ps Vx,Wx (66),(v) | vpmovusdw Wx,Vd (F3),(ev) -14: blendvps Vdq,Wdq (66) | vpmovusqw Wx,Vq (F3),(ev) | vprorvd/q Vx,Hx,Wx (66),(evo) -15: blendvpd Vdq,Wdq (66) | vpmovusqd Wx,Vq (F3),(ev) | vprolvd/q Vx,Hx,Wx (66),(evo) -16: vpermps Vqq,Hqq,Wqq (66),(v) | vpermps/d Vqq,Hqq,Wqq (66),(evo) -17: vptest Vx,Wx (66) -18: vbroadcastss Vx,Wd (66),(v) -19: vbroadcastsd Vqq,Wq (66),(v) | vbroadcastf32x2 Vqq,Wq (66),(evo) -1a: vbroadcastf128 Vqq,Mdq (66),(v) | vbroadcastf32x4/64x2 Vqq,Wq (66),(evo) -1b: vbroadcastf32x8/64x4 Vqq,Mdq (66),(ev) -1c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1) -1d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1) -1e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1) -1f: vpabsq Vx,Wx (66),(ev) -# 0x0f 0x38 0x20-0x2f -20: vpmovsxbw Vx,Ux/Mq (66),(v1) | vpmovswb Wx,Vx (F3),(ev) -21: vpmovsxbd Vx,Ux/Md (66),(v1) | vpmovsdb Wx,Vd (F3),(ev) -22: vpmovsxbq Vx,Ux/Mw (66),(v1) | vpmovsqb Wx,Vq (F3),(ev) -23: vpmovsxwd Vx,Ux/Mq (66),(v1) | vpmovsdw Wx,Vd (F3),(ev) -24: vpmovsxwq Vx,Ux/Md (66),(v1) | vpmovsqw Wx,Vq (F3),(ev) -25: vpmovsxdq Vx,Ux/Mq (66),(v1) | vpmovsqd Wx,Vq (F3),(ev) -26: vptestmb/w Vk,Hx,Wx (66),(ev) | vptestnmb/w Vk,Hx,Wx (F3),(ev) -27: vptestmd/q Vk,Hx,Wx (66),(ev) | vptestnmd/q Vk,Hx,Wx (F3),(ev) -28: vpmuldq Vx,Hx,Wx (66),(v1) | vpmovm2b/w Vx,Uk (F3),(ev) -29: vpcmpeqq Vx,Hx,Wx (66),(v1) | vpmovb2m/w2m Vk,Ux (F3),(ev) -2a: vmovntdqa Vx,Mx (66),(v1) | vpbroadcastmb2q Vx,Uk (F3),(ev) -2b: vpackusdw Vx,Hx,Wx (66),(v1) -2c: vmaskmovps Vx,Hx,Mx (66),(v) | vscalefps/d Vx,Hx,Wx (66),(evo) -2d: vmaskmovpd Vx,Hx,Mx (66),(v) | vscalefss/d Vx,Hx,Wx (66),(evo) -2e: vmaskmovps Mx,Hx,Vx (66),(v) -2f: vmaskmovpd Mx,Hx,Vx (66),(v) -# 0x0f 0x38 0x30-0x3f -30: vpmovzxbw Vx,Ux/Mq (66),(v1) | vpmovwb Wx,Vx (F3),(ev) -31: vpmovzxbd Vx,Ux/Md (66),(v1) | vpmovdb Wx,Vd (F3),(ev) -32: vpmovzxbq Vx,Ux/Mw (66),(v1) | vpmovqb Wx,Vq (F3),(ev) -33: vpmovzxwd Vx,Ux/Mq (66),(v1) | vpmovdw Wx,Vd (F3),(ev) -34: vpmovzxwq Vx,Ux/Md (66),(v1) | vpmovqw Wx,Vq (F3),(ev) -35: vpmovzxdq Vx,Ux/Mq (66),(v1) | vpmovqd Wx,Vq (F3),(ev) -36: vpermd Vqq,Hqq,Wqq (66),(v) | vpermd/q Vqq,Hqq,Wqq (66),(evo) -37: vpcmpgtq Vx,Hx,Wx (66),(v1) -38: vpminsb Vx,Hx,Wx (66),(v1) | vpmovm2d/q Vx,Uk (F3),(ev) -39: vpminsd Vx,Hx,Wx (66),(v1) | vpminsd/q Vx,Hx,Wx (66),(evo) | vpmovd2m/q2m Vk,Ux (F3),(ev) -3a: vpminuw Vx,Hx,Wx (66),(v1) | vpbroadcastmw2d Vx,Uk (F3),(ev) -3b: vpminud Vx,Hx,Wx (66),(v1) | vpminud/q Vx,Hx,Wx (66),(evo) -3c: vpmaxsb Vx,Hx,Wx (66),(v1) -3d: vpmaxsd Vx,Hx,Wx (66),(v1) | vpmaxsd/q Vx,Hx,Wx (66),(evo) -3e: vpmaxuw Vx,Hx,Wx (66),(v1) -3f: vpmaxud Vx,Hx,Wx (66),(v1) | vpmaxud/q Vx,Hx,Wx (66),(evo) -# 0x0f 0x38 0x40-0x8f -40: vpmulld Vx,Hx,Wx (66),(v1) | vpmulld/q Vx,Hx,Wx (66),(evo) -41: vphminposuw Vdq,Wdq (66),(v1) -42: vgetexpps/d Vx,Wx (66),(ev) -43: vgetexpss/d Vx,Hx,Wx (66),(ev) -44: vplzcntd/q Vx,Wx (66),(ev) -45: vpsrlvd/q Vx,Hx,Wx (66),(v) -46: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo) -47: vpsllvd/q Vx,Hx,Wx (66),(v) -# Skip 0x48-0x4b -4c: vrcp14ps/d Vpd,Wpd (66),(ev) -4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev) -4e: vrsqrt14ps/d Vpd,Wpd (66),(ev) -4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev) -# Skip 0x50-0x57 -58: vpbroadcastd Vx,Wx (66),(v) -59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo) -5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo) -5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev) -# Skip 0x5c-0x63 -64: vpblendmd/q Vx,Hx,Wx (66),(ev) -65: vblendmps/d Vx,Hx,Wx (66),(ev) -66: vpblendmb/w Vx,Hx,Wx (66),(ev) -# Skip 0x67-0x74 -75: vpermi2b/w Vx,Hx,Wx (66),(ev) -76: vpermi2d/q Vx,Hx,Wx (66),(ev) -77: vpermi2ps/d Vx,Hx,Wx (66),(ev) -78: vpbroadcastb Vx,Wx (66),(v) -79: vpbroadcastw Vx,Wx (66),(v) -7a: vpbroadcastb Vx,Rv (66),(ev) -7b: vpbroadcastw Vx,Rv (66),(ev) -7c: vpbroadcastd/q Vx,Rv (66),(ev) -7d: vpermt2b/w Vx,Hx,Wx (66),(ev) -7e: vpermt2d/q Vx,Hx,Wx (66),(ev) -7f: vpermt2ps/d Vx,Hx,Wx (66),(ev) -80: INVEPT Gy,Mdq (66) -81: INVVPID Gy,Mdq (66) -82: INVPCID Gy,Mdq (66) -83: vpmultishiftqb Vx,Hx,Wx (66),(ev) -88: vexpandps/d Vpd,Wpd (66),(ev) -89: vpexpandd/q Vx,Wx (66),(ev) -8a: vcompressps/d Wx,Vx (66),(ev) -8b: vpcompressd/q Wx,Vx (66),(ev) -8c: vpmaskmovd/q Vx,Hx,Mx (66),(v) -8d: vpermb/w Vx,Hx,Wx (66),(ev) -8e: vpmaskmovd/q Mx,Vx,Hx (66),(v) -# 0x0f 0x38 0x90-0xbf (FMA) -90: vgatherdd/q Vx,Hx,Wx (66),(v) | vpgatherdd/q Vx,Wx (66),(evo) -91: vgatherqd/q Vx,Hx,Wx (66),(v) | vpgatherqd/q Vx,Wx (66),(evo) -92: vgatherdps/d Vx,Hx,Wx (66),(v) -93: vgatherqps/d Vx,Hx,Wx (66),(v) -94: -95: -96: vfmaddsub132ps/d Vx,Hx,Wx (66),(v) -97: vfmsubadd132ps/d Vx,Hx,Wx (66),(v) -98: vfmadd132ps/d Vx,Hx,Wx (66),(v) -99: vfmadd132ss/d Vx,Hx,Wx (66),(v),(v1) -9a: vfmsub132ps/d Vx,Hx,Wx (66),(v) -9b: vfmsub132ss/d Vx,Hx,Wx (66),(v),(v1) -9c: vfnmadd132ps/d Vx,Hx,Wx (66),(v) -9d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1) -9e: vfnmsub132ps/d Vx,Hx,Wx (66),(v) -9f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1) -a0: vpscatterdd/q Wx,Vx (66),(ev) -a1: vpscatterqd/q Wx,Vx (66),(ev) -a2: vscatterdps/d Wx,Vx (66),(ev) -a3: vscatterqps/d Wx,Vx (66),(ev) -a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v) -a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v) -a8: vfmadd213ps/d Vx,Hx,Wx (66),(v) -a9: vfmadd213ss/d Vx,Hx,Wx (66),(v),(v1) -aa: vfmsub213ps/d Vx,Hx,Wx (66),(v) -ab: vfmsub213ss/d Vx,Hx,Wx (66),(v),(v1) -ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v) -ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1) -ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v) -af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1) -b4: vpmadd52luq Vx,Hx,Wx (66),(ev) -b5: vpmadd52huq Vx,Hx,Wx (66),(ev) -b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v) -b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v) -b8: vfmadd231ps/d Vx,Hx,Wx (66),(v) -b9: vfmadd231ss/d Vx,Hx,Wx (66),(v),(v1) -ba: vfmsub231ps/d Vx,Hx,Wx (66),(v) -bb: vfmsub231ss/d Vx,Hx,Wx (66),(v),(v1) -bc: vfnmadd231ps/d Vx,Hx,Wx (66),(v) -bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1) -be: vfnmsub231ps/d Vx,Hx,Wx (66),(v) -bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1) -# 0x0f 0x38 0xc0-0xff -c4: vpconflictd/q Vx,Wx (66),(ev) -c6: Grp18 (1A) -c7: Grp19 (1A) -c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev) -c9: sha1msg1 Vdq,Wdq -ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev) -cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev) -cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev) -cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev) -db: VAESIMC Vdq,Wdq (66),(v1) -dc: VAESENC Vdq,Hdq,Wdq (66),(v1) -dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1) -de: VAESDEC Vdq,Hdq,Wdq (66),(v1) -df: VAESDECLAST Vdq,Hdq,Wdq (66),(v1) -f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2) -f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2) -f2: ANDN Gy,By,Ey (v) -f3: Grp17 (1A) -f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v) -f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v) -f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v) -EndTable - -Table: 3-byte opcode 2 (0x0f 0x3a) -Referrer: 3-byte escape 2 -AVXcode: 3 -# 0x0f 0x3a 0x00-0xff -00: vpermq Vqq,Wqq,Ib (66),(v) -01: vpermpd Vqq,Wqq,Ib (66),(v) -02: vpblendd Vx,Hx,Wx,Ib (66),(v) -03: valignd/q Vx,Hx,Wx,Ib (66),(ev) -04: vpermilps Vx,Wx,Ib (66),(v) -05: vpermilpd Vx,Wx,Ib (66),(v) -06: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v) -07: -08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo) -09: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo) -0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo) -0b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo) -0c: vblendps Vx,Hx,Wx,Ib (66) -0d: vblendpd Vx,Hx,Wx,Ib (66) -0e: vpblendw Vx,Hx,Wx,Ib (66),(v1) -0f: palignr Pq,Qq,Ib | vpalignr Vx,Hx,Wx,Ib (66),(v1) -14: vpextrb Rd/Mb,Vdq,Ib (66),(v1) -15: vpextrw Rd/Mw,Vdq,Ib (66),(v1) -16: vpextrd/q Ey,Vdq,Ib (66),(v1) -17: vextractps Ed,Vdq,Ib (66),(v1) -18: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) | vinsertf32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo) -19: vextractf128 Wdq,Vqq,Ib (66),(v) | vextractf32x4/64x2 Wdq,Vqq,Ib (66),(evo) -1a: vinsertf32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev) -1b: vextractf32x8/64x4 Wdq,Vqq,Ib (66),(ev) -1d: vcvtps2ph Wx,Vx,Ib (66),(v) -1e: vpcmpud/q Vk,Hd,Wd,Ib (66),(ev) -1f: vpcmpd/q Vk,Hd,Wd,Ib (66),(ev) -20: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1) -21: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1) -22: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1) -23: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev) -25: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev) -26: vgetmantps/d Vx,Wx,Ib (66),(ev) -27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev) -30: kshiftrb/w Vk,Uk,Ib (66),(v) -31: kshiftrd/q Vk,Uk,Ib (66),(v) -32: kshiftlb/w Vk,Uk,Ib (66),(v) -33: kshiftld/q Vk,Uk,Ib (66),(v) -38: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) | vinserti32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo) -39: vextracti128 Wdq,Vqq,Ib (66),(v) | vextracti32x4/64x2 Wdq,Vqq,Ib (66),(evo) -3a: vinserti32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev) -3b: vextracti32x8/64x4 Wdq,Vqq,Ib (66),(ev) -3e: vpcmpub/w Vk,Hk,Wx,Ib (66),(ev) -3f: vpcmpb/w Vk,Hk,Wx,Ib (66),(ev) -40: vdpps Vx,Hx,Wx,Ib (66) -41: vdppd Vdq,Hdq,Wdq,Ib (66),(v1) -42: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) | vdbpsadbw Vx,Hx,Wx,Ib (66),(evo) -43: vshufi32x4/64x2 Vx,Hx,Wx,Ib (66),(ev) -44: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1) -46: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v) -4a: vblendvps Vx,Hx,Wx,Lx (66),(v) -4b: vblendvpd Vx,Hx,Wx,Lx (66),(v) -4c: vpblendvb Vx,Hx,Wx,Lx (66),(v1) -50: vrangeps/d Vx,Hx,Wx,Ib (66),(ev) -51: vrangess/d Vx,Hx,Wx,Ib (66),(ev) -54: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev) -55: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev) -56: vreduceps/d Vx,Wx,Ib (66),(ev) -57: vreducess/d Vx,Hx,Wx,Ib (66),(ev) -60: vpcmpestrm Vdq,Wdq,Ib (66),(v1) -61: vpcmpestri Vdq,Wdq,Ib (66),(v1) -62: vpcmpistrm Vdq,Wdq,Ib (66),(v1) -63: vpcmpistri Vdq,Wdq,Ib (66),(v1) -66: vfpclassps/d Vk,Wx,Ib (66),(ev) -67: vfpclassss/d Vk,Wx,Ib (66),(ev) -cc: sha1rnds4 Vdq,Wdq,Ib -df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1) -f0: RORX Gy,Ey,Ib (F2),(v) -EndTable - -GrpTable: Grp1 -0: ADD -1: OR -2: ADC -3: SBB -4: AND -5: SUB -6: XOR -7: CMP -EndTable - -GrpTable: Grp1A -0: POP -EndTable - -GrpTable: Grp2 -0: ROL -1: ROR -2: RCL -3: RCR -4: SHL/SAL -5: SHR -6: -7: SAR -EndTable - -GrpTable: Grp3_1 -0: TEST Eb,Ib -1: TEST Eb,Ib -2: NOT Eb -3: NEG Eb -4: MUL AL,Eb -5: IMUL AL,Eb -6: DIV AL,Eb -7: IDIV AL,Eb -EndTable - -GrpTable: Grp3_2 -0: TEST Ev,Iz -1: -2: NOT Ev -3: NEG Ev -4: MUL rAX,Ev -5: IMUL rAX,Ev -6: DIV rAX,Ev -7: IDIV rAX,Ev -EndTable - -GrpTable: Grp4 -0: INC Eb -1: DEC Eb -EndTable - -GrpTable: Grp5 -0: INC Ev -1: DEC Ev -# Note: "forced64" is Intel CPU behavior (see comment about CALL insn). -2: CALLN Ev (f64) -3: CALLF Ep -4: JMPN Ev (f64) -5: JMPF Mp -6: PUSH Ev (d64) -7: -EndTable - -GrpTable: Grp6 -0: SLDT Rv/Mw -1: STR Rv/Mw -2: LLDT Ew -3: LTR Ew -4: VERR Ew -5: VERW Ew -EndTable - -GrpTable: Grp7 -0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) -1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B) -2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B) -3: LIDT Ms -4: SMSW Mw/Rv -5: rdpkru (110),(11B) | wrpkru (111),(11B) -6: LMSW Ew -7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B) -EndTable - -GrpTable: Grp8 -4: BT -5: BTS -6: BTR -7: BTC -EndTable - -GrpTable: Grp9 -1: CMPXCHG8B/16B Mq/Mdq -3: xrstors -4: xsavec -5: xsaves -6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B) -7: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B) -EndTable - -GrpTable: Grp10 -# all are UD1 -0: UD1 -1: UD1 -2: UD1 -3: UD1 -4: UD1 -5: UD1 -6: UD1 -7: UD1 -EndTable - -# Grp11A and Grp11B are expressed as Grp11 in Intel SDM -GrpTable: Grp11A -0: MOV Eb,Ib -7: XABORT Ib (000),(11B) -EndTable - -GrpTable: Grp11B -0: MOV Eb,Iz -7: XBEGIN Jz (000),(11B) -EndTable - -GrpTable: Grp12 -2: psrlw Nq,Ib (11B) | vpsrlw Hx,Ux,Ib (66),(11B),(v1) -4: psraw Nq,Ib (11B) | vpsraw Hx,Ux,Ib (66),(11B),(v1) -6: psllw Nq,Ib (11B) | vpsllw Hx,Ux,Ib (66),(11B),(v1) -EndTable - -GrpTable: Grp13 -0: vprord/q Hx,Wx,Ib (66),(ev) -1: vprold/q Hx,Wx,Ib (66),(ev) -2: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1) -4: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) | vpsrad/q Hx,Ux,Ib (66),(evo) -6: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1) -EndTable - -GrpTable: Grp14 -2: psrlq Nq,Ib (11B) | vpsrlq Hx,Ux,Ib (66),(11B),(v1) -3: vpsrldq Hx,Ux,Ib (66),(11B),(v1) -6: psllq Nq,Ib (11B) | vpsllq Hx,Ux,Ib (66),(11B),(v1) -7: vpslldq Hx,Ux,Ib (66),(11B),(v1) -EndTable - -GrpTable: Grp15 -0: fxsave | RDFSBASE Ry (F3),(11B) -1: fxstor | RDGSBASE Ry (F3),(11B) -2: vldmxcsr Md (v1) | WRFSBASE Ry (F3),(11B) -3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B) -4: XSAVE | ptwrite Ey (F3),(11B) -5: XRSTOR | lfence (11B) -6: XSAVEOPT | clwb (66) | mfence (11B) -7: clflush | clflushopt (66) | sfence (11B) -EndTable - -GrpTable: Grp16 -0: prefetch NTA -1: prefetch T0 -2: prefetch T1 -3: prefetch T2 -EndTable - -GrpTable: Grp17 -1: BLSR By,Ey (v) -2: BLSMSK By,Ey (v) -3: BLSI By,Ey (v) -EndTable - -GrpTable: Grp18 -1: vgatherpf0dps/d Wx (66),(ev) -2: vgatherpf1dps/d Wx (66),(ev) -5: vscatterpf0dps/d Wx (66),(ev) -6: vscatterpf1dps/d Wx (66),(ev) -EndTable - -GrpTable: Grp19 -1: vgatherpf0qps/d Wx (66),(ev) -2: vgatherpf1qps/d Wx (66),(ev) -5: vscatterpf0qps/d Wx (66),(ev) -6: vscatterpf1qps/d Wx (66),(ev) -EndTable - -# AMD's Prefetch Group -GrpTable: GrpP -0: PREFETCH -1: PREFETCHW -EndTable - -GrpTable: GrpPDLK -0: MONTMUL -1: XSHA1 -2: XSHA2 -EndTable - -GrpTable: GrpRNG -0: xstore-rng -1: xcrypt-ecb -2: xcrypt-cbc -4: xcrypt-cfb -5: xcrypt-ofb -EndTable -- cgit v1.2.3-59-g8ed1b From 87a682a7c4e719d238d1839098375470b55e2097 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 31 Aug 2019 17:14:19 -0300 Subject: perf build: Ignore intentional differences for the x86 insn decoder Since we need to build this in !x86, we need to explicitely use the x86 files, not things like asm/insn.h, so we intentionally differ from the master copy in the kernel sources, add -I diff directives to ignore just these differences when checking for drift. Acked-by: Josh Poimboeuf Acked-by: Masami Hiramatsu Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/n/tip-9qziqjjt120mmz6kyepka9p7@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/check-headers.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh index cbcc3590098c..e2e0f06c97d0 100755 --- a/tools/perf/check-headers.sh +++ b/tools/perf/check-headers.sh @@ -26,12 +26,8 @@ include/uapi/linux/hw_breakpoint.h arch/x86/include/asm/disabled-features.h arch/x86/include/asm/required-features.h arch/x86/include/asm/cpufeatures.h -arch/x86/include/asm/inat.h arch/x86/include/asm/inat_types.h -arch/x86/include/asm/insn.h arch/x86/include/uapi/asm/prctl.h -arch/x86/lib/inat.c -arch/x86/lib/insn.c arch/x86/lib/x86-opcode-map.txt arch/x86/tools/gen-insn-attr-x86.awk arch/arm/include/uapi/asm/perf_regs.h @@ -116,6 +112,10 @@ check include/uapi/asm-generic/mman.h '-I "^#include <\(uapi/\)*asm-generic/mman check include/uapi/linux/mman.h '-I "^#include <\(uapi/\)*asm/mman.h>"' check include/linux/ctype.h '-I "isdigit("' check lib/ctype.c '-I "^EXPORT_SYMBOL" -I "^#include " -B' +check arch/x86/include/asm/inat.h '-I "^#include [\"<]\(asm/\)*inat_types.h[\">]"' +check arch/x86/include/asm/insn.h '-I "^#include [\"<]\(asm/\)*inat.h[\">]"' +check arch/x86/lib/inat.c '-I "^#include [\"<]\(../include/\)*asm/insn.h[\">]"' +check arch/x86/lib/insn.c '-I "^#include [\"<]\(../include/\)*asm/in\(at\|sn\).h[\">]"' # diff non-symmetric files check_2 tools/perf/arch/x86/entry/syscalls/syscall_64.tbl arch/x86/entry/syscalls/syscall_64.tbl -- cgit v1.2.3-59-g8ed1b From 2ffd84ae973b5ad16be96840574bb1142fda268a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 31 Aug 2019 17:29:47 -0300 Subject: objtool: Update sync-check.sh from perf's check-headers.sh To allow using the -I trick that will be needed for checking the x86 insn decoder files. Without the specific -I lines we still get the same warnings as before: $ make -C tools/objtool/ clean ; make -C tools/objtool/ make: Entering directory '/home/acme/git/perf/tools/objtool' CLEAN objtool find -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete rm -f arch/x86/inat-tables.c fixdep LD objtool-in.o make[1]: Leaving directory '/home/acme/git/perf/tools/objtool' Warning: Kernel ABI header at 'tools/arch/x86/include/asm/inat.h' differs from latest version at 'arch/x86/include/asm/inat.h' diff -u tools/arch/x86/include/asm/inat.h arch/x86/include/asm/inat.h Warning: Kernel ABI header at 'tools/arch/x86/include/asm/insn.h' differs from latest version at 'arch/x86/include/asm/insn.h' diff -u tools/arch/x86/include/asm/insn.h arch/x86/include/asm/insn.h Warning: Kernel ABI header at 'tools/arch/x86/lib/inat.c' differs from latest version at 'arch/x86/lib/inat.c' diff -u tools/arch/x86/lib/inat.c arch/x86/lib/inat.c Warning: Kernel ABI header at 'tools/arch/x86/lib/insn.c' differs from latest version at 'arch/x86/lib/insn.c' diff -u tools/arch/x86/lib/insn.c arch/x86/lib/insn.c /home/acme/git/perf/tools/objtool LINK objtool make: Leaving directory '/home/acme/git/perf/tools/objtool' $ The next patch will add the -I lines for those files. Acked-by: Josh Poimboeuf Link: http://lore.kernel.org/lkml/20190830193109.p7jagidsrahoa4pn@treble Acked-by: Masami Hiramatsu Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/n/tip-vu3p38mnxlwd80rlsnjkqcf2@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/objtool/sync-check.sh | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/objtool/sync-check.sh b/tools/objtool/sync-check.sh index 66f1575b80f3..6fa87de1c765 100755 --- a/tools/objtool/sync-check.sh +++ b/tools/objtool/sync-check.sh @@ -12,18 +12,39 @@ arch/x86/lib/x86-opcode-map.txt arch/x86/tools/gen-insn-attr-x86.awk ' -check() -{ - local file=$1 +check_2 () { + file1=$1 + file2=$2 - diff ../$file ../../$file > /dev/null || - echo "Warning: synced file at 'tools/objtool/$file' differs from latest kernel version at '$file'" + shift + shift + + cmd="diff $* $file1 $file2 > /dev/null" + + test -f $file2 && { + eval $cmd || { + echo "Warning: Kernel ABI header at '$file1' differs from latest version at '$file2'" >&2 + echo diff -u $file1 $file2 + } + } +} + +check () { + file=$1 + + shift + + check_2 tools/$file $file $* } if [ ! -d ../../kernel ] || [ ! -d ../../tools ] || [ ! -d ../objtool ]; then exit 0 fi +cd ../.. + for i in $FILES; do check $i done + +cd - -- cgit v1.2.3-59-g8ed1b From ae31a514a134d9e4ca1d7b0f0a19b5934747d79f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 31 Aug 2019 17:35:53 -0300 Subject: objtool: Ignore intentional differences for the x86 insn decoder Since we need to build this in !x86, we need to explicitely use the x86 files, not things like asm/insn.h, so we intentionally differ from the master copy in the kernel sources, add -I diff directives to ignore just these differences when checking for drift. Acked-by: Josh Poimboeuf Link: http://lore.kernel.org/lkml/20190830193109.p7jagidsrahoa4pn@treble Acked-by: Masami Hiramatsu Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/n/tip-j965m9b7xtdc83em3twfkh9o@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/objtool/sync-check.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/objtool/sync-check.sh b/tools/objtool/sync-check.sh index 6fa87de1c765..0a832e265a50 100755 --- a/tools/objtool/sync-check.sh +++ b/tools/objtool/sync-check.sh @@ -2,12 +2,8 @@ # SPDX-License-Identifier: GPL-2.0 FILES=' -arch/x86/include/asm/inat.h arch/x86/include/asm/inat_types.h -arch/x86/include/asm/insn.h arch/x86/include/asm/orc_types.h -arch/x86/lib/inat.c -arch/x86/lib/insn.c arch/x86/lib/x86-opcode-map.txt arch/x86/tools/gen-insn-attr-x86.awk ' @@ -47,4 +43,9 @@ for i in $FILES; do check $i done +check arch/x86/include/asm/inat.h '-I "^#include [\"<]\(asm/\)*inat_types.h[\">]"' +check arch/x86/include/asm/insn.h '-I "^#include [\"<]\(asm/\)*inat.h[\">]"' +check arch/x86/lib/inat.c '-I "^#include [\"<]\(../include/\)*asm/insn.h[\">]"' +check arch/x86/lib/insn.c '-I "^#include [\"<]\(../include/\)*asm/in\(at\|sn\).h[\">]"' + cd - -- cgit v1.2.3-59-g8ed1b From 02a3f0d5a70a865d55c4b7cb2e327cb30491f7fd Mon Sep 17 00:00:00 2001 From: Davide Caratti Date: Fri, 30 Aug 2019 18:51:47 +0200 Subject: tc-testing: don't hardcode 'ip' in nsPlugin.py the following tdc test fails on Fedora: # ./tdc.py -e 2638 -- ns/SubPlugin.__init__ Test 2638: Add matchall and try to get it -----> prepare stage *** Could not execute: "$TC qdisc add dev $DEV1 clsact" -----> prepare stage *** Error message: "/bin/sh: ip: command not found" returncode 127; expected [0] -----> prepare stage *** Aborting test run. Let nsPlugin.py use the 'IP' variable introduced with commit 92c1a19e2fb9 ("tc-tests: added path to ip command in tdc"), so that the path to 'ip' is correctly resolved to the value we have in tdc_config.py. # ./tdc.py -e 2638 -- ns/SubPlugin.__init__ Test 2638: Add matchall and try to get it All test results: 1..1 ok 1 2638 - Add matchall and try to get it Fixes: 489ce2f42514 ("tc-testing: Restore original behaviour for namespaces in tdc") Reported-by: Hangbin Liu Signed-off-by: Davide Caratti Acked-by: Nicolas Dichtel Signed-off-by: David S. Miller --- .../selftests/tc-testing/plugin-lib/nsPlugin.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py b/tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py index affa7f2d9670..9539cffa9e5e 100644 --- a/tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py +++ b/tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py @@ -64,7 +64,7 @@ class SubPlugin(TdcPlugin): cmdlist.insert(0, self.args.NAMES['NS']) cmdlist.insert(0, 'exec') cmdlist.insert(0, 'netns') - cmdlist.insert(0, 'ip') + cmdlist.insert(0, self.args.NAMES['IP']) else: pass @@ -78,16 +78,16 @@ class SubPlugin(TdcPlugin): return command def _ports_create(self): - cmd = 'ip link add $DEV0 type veth peer name $DEV1' + cmd = '$IP link add $DEV0 type veth peer name $DEV1' self._exec_cmd('pre', cmd) - cmd = 'ip link set $DEV0 up' + cmd = '$IP link set $DEV0 up' self._exec_cmd('pre', cmd) if not self.args.namespace: - cmd = 'ip link set $DEV1 up' + cmd = '$IP link set $DEV1 up' self._exec_cmd('pre', cmd) def _ports_destroy(self): - cmd = 'ip link del $DEV0' + cmd = '$IP link del $DEV0' self._exec_cmd('post', cmd) def _ns_create(self): @@ -97,16 +97,16 @@ class SubPlugin(TdcPlugin): ''' self._ports_create() if self.args.namespace: - cmd = 'ip netns add {}'.format(self.args.NAMES['NS']) + cmd = '$IP netns add {}'.format(self.args.NAMES['NS']) self._exec_cmd('pre', cmd) - cmd = 'ip link set $DEV1 netns {}'.format(self.args.NAMES['NS']) + cmd = '$IP link set $DEV1 netns {}'.format(self.args.NAMES['NS']) self._exec_cmd('pre', cmd) - cmd = 'ip -n {} link set $DEV1 up'.format(self.args.NAMES['NS']) + cmd = '$IP -n {} link set $DEV1 up'.format(self.args.NAMES['NS']) self._exec_cmd('pre', cmd) if self.args.device: - cmd = 'ip link set $DEV2 netns {}'.format(self.args.NAMES['NS']) + cmd = '$IP link set $DEV2 netns {}'.format(self.args.NAMES['NS']) self._exec_cmd('pre', cmd) - cmd = 'ip -n {} link set $DEV2 up'.format(self.args.NAMES['NS']) + cmd = '$IP -n {} link set $DEV2 up'.format(self.args.NAMES['NS']) self._exec_cmd('pre', cmd) def _ns_destroy(self): @@ -115,7 +115,7 @@ class SubPlugin(TdcPlugin): devices as well) ''' if self.args.namespace: - cmd = 'ip netns delete {}'.format(self.args.NAMES['NS']) + cmd = '$IP netns delete {}'.format(self.args.NAMES['NS']) self._exec_cmd('post', cmd) def _exec_cmd(self, stage, command): -- cgit v1.2.3-59-g8ed1b From d80507d15d45e285fc596d23665c9b88cf0dfec3 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Fri, 30 Aug 2019 19:34:26 -0700 Subject: selftests/bpf: test_progs: fix verbose mode garbage fseeko(.., 0, SEEK_SET) on a memstream just puts the buffer pointer to the beginning so when we call fflush on it we get some garbage log data from the previous test. Let's manually set terminating byte to zero at the reported buffer size. To show the issue consider the following snippet: stream = open_memstream (&buf, &len); fprintf(stream, "aaa"); fflush(stream); printf("buf=%s, len=%zu\n", buf, len); fseeko(stream, 0, SEEK_SET); fprintf(stream, "b"); fflush(stream); printf("buf=%s, len=%zu\n", buf, len); Output: buf=aaa, len=3 buf=baa, len=1 Fixes: 946152b3c5d6 ("selftests/bpf: test_progs: switch to open_memstream") Signed-off-by: Stanislav Fomichev Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/test_progs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index e5892cb60eca..e8616e778cb5 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -45,6 +45,7 @@ static void dump_test_log(const struct prog_test_def *test, bool failed) if (env.verbose || test->force_log || failed) { if (env.log_cnt) { + env.log_buf[env.log_cnt] = '\0'; fprintf(env.stdout, "%s", env.log_buf); if (env.log_buf[env.log_cnt - 1] != '\n') fprintf(env.stdout, "\n"); -- cgit v1.2.3-59-g8ed1b From ac915762ea3977af49383bd914d506da0905c72e Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Fri, 30 Aug 2019 19:34:27 -0700 Subject: selftests/bpf: test_progs: add missing \n to CHECK_FAIL Copy-paste error from CHECK. Fixes: d38835b75f67 ("selftests/bpf: test_progs: remove global fail/success counts") Signed-off-by: Stanislav Fomichev Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/test_progs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h index 33da849cb765..c8edb9464ba6 100644 --- a/tools/testing/selftests/bpf/test_progs.h +++ b/tools/testing/selftests/bpf/test_progs.h @@ -107,7 +107,7 @@ extern struct ipv6_packet pkt_v6; int __ret = !!(condition); \ if (__ret) { \ test__fail(); \ - printf("%s:FAIL:%d ", __func__, __LINE__); \ + printf("%s:FAIL:%d\n", __func__, __LINE__); \ } \ __ret; \ }) -- cgit v1.2.3-59-g8ed1b From b9632679944307f3caab183fa69a4d79ffeb40ce Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Fri, 30 Aug 2019 13:07:29 +0200 Subject: selftests/bpf: introduce bpf_cpu_to_be64 and bpf_be64_to_cpu test_lwt_seg6local and test_seg6_loop use custom 64-bit endianness conversion macros. Centralize their definitions in bpf_endian.h in order to reduce code duplication. This will also be useful when bpf_endian.h is promoted to an offical libbpf header. Signed-off-by: Ilya Leoshkevich Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/bpf_endian.h | 14 ++++++++++++++ tools/testing/selftests/bpf/progs/test_lwt_seg6local.c | 16 ++++++---------- tools/testing/selftests/bpf/progs/test_seg6_loop.c | 8 ++------ 3 files changed, 22 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/bpf_endian.h b/tools/testing/selftests/bpf/bpf_endian.h index ff3593b0ae03..fbe28008450f 100644 --- a/tools/testing/selftests/bpf/bpf_endian.h +++ b/tools/testing/selftests/bpf/bpf_endian.h @@ -29,6 +29,10 @@ # define __bpf_htonl(x) __builtin_bswap32(x) # define __bpf_constant_ntohl(x) ___constant_swab32(x) # define __bpf_constant_htonl(x) ___constant_swab32(x) +# define __bpf_be64_to_cpu(x) __builtin_bswap64(x) +# define __bpf_cpu_to_be64(x) __builtin_bswap64(x) +# define __bpf_constant_be64_to_cpu(x) ___constant_swab64(x) +# define __bpf_constant_cpu_to_be64(x) ___constant_swab64(x) #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ # define __bpf_ntohs(x) (x) # define __bpf_htons(x) (x) @@ -38,6 +42,10 @@ # define __bpf_htonl(x) (x) # define __bpf_constant_ntohl(x) (x) # define __bpf_constant_htonl(x) (x) +# define __bpf_be64_to_cpu(x) (x) +# define __bpf_cpu_to_be64(x) (x) +# define __bpf_constant_be64_to_cpu(x) (x) +# define __bpf_constant_cpu_to_be64(x) (x) #else # error "Fix your compiler's __BYTE_ORDER__?!" #endif @@ -54,5 +62,11 @@ #define bpf_ntohl(x) \ (__builtin_constant_p(x) ? \ __bpf_constant_ntohl(x) : __bpf_ntohl(x)) +#define bpf_cpu_to_be64(x) \ + (__builtin_constant_p(x) ? \ + __bpf_constant_cpu_to_be64(x) : __bpf_cpu_to_be64(x)) +#define bpf_be64_to_cpu(x) \ + (__builtin_constant_p(x) ? \ + __bpf_constant_be64_to_cpu(x) : __bpf_be64_to_cpu(x)) #endif /* __BPF_ENDIAN__ */ diff --git a/tools/testing/selftests/bpf/progs/test_lwt_seg6local.c b/tools/testing/selftests/bpf/progs/test_lwt_seg6local.c index a334a0e882e4..41a3ebcd593d 100644 --- a/tools/testing/selftests/bpf/progs/test_lwt_seg6local.c +++ b/tools/testing/selftests/bpf/progs/test_lwt_seg6local.c @@ -12,10 +12,6 @@ #define SR6_FLAG_ALERT (1 << 4) -#define htonll(x) ((bpf_htonl(1)) == 1 ? (x) : ((uint64_t)bpf_htonl((x) & \ - 0xFFFFFFFF) << 32) | bpf_htonl((x) >> 32)) -#define ntohll(x) ((bpf_ntohl(1)) == 1 ? (x) : ((uint64_t)bpf_ntohl((x) & \ - 0xFFFFFFFF) << 32) | bpf_ntohl((x) >> 32)) #define BPF_PACKET_HEADER __attribute__((packed)) struct ip6_t { @@ -276,8 +272,8 @@ int has_egr_tlv(struct __sk_buff *skb, struct ip6_srh_t *srh) return 0; // check if egress TLV value is correct - if (ntohll(egr_addr.hi) == 0xfd00000000000000 && - ntohll(egr_addr.lo) == 0x4) + if (bpf_be64_to_cpu(egr_addr.hi) == 0xfd00000000000000 && + bpf_be64_to_cpu(egr_addr.lo) == 0x4) return 1; } @@ -308,8 +304,8 @@ int __encap_srh(struct __sk_buff *skb) #pragma clang loop unroll(full) for (unsigned long long lo = 0; lo < 4; lo++) { - seg->lo = htonll(4 - lo); - seg->hi = htonll(hi); + seg->lo = bpf_cpu_to_be64(4 - lo); + seg->hi = bpf_cpu_to_be64(hi); seg = (struct ip6_addr_t *)((char *)seg + sizeof(*seg)); } @@ -349,8 +345,8 @@ int __add_egr_x(struct __sk_buff *skb) if (err) return BPF_DROP; - addr.lo = htonll(lo); - addr.hi = htonll(hi); + addr.lo = bpf_cpu_to_be64(lo); + addr.hi = bpf_cpu_to_be64(hi); err = bpf_lwt_seg6_action(skb, SEG6_LOCAL_ACTION_END_X, (void *)&addr, sizeof(addr)); if (err) diff --git a/tools/testing/selftests/bpf/progs/test_seg6_loop.c b/tools/testing/selftests/bpf/progs/test_seg6_loop.c index 1dbe1d4d467e..c4d104428643 100644 --- a/tools/testing/selftests/bpf/progs/test_seg6_loop.c +++ b/tools/testing/selftests/bpf/progs/test_seg6_loop.c @@ -12,10 +12,6 @@ #define SR6_FLAG_ALERT (1 << 4) -#define htonll(x) ((bpf_htonl(1)) == 1 ? (x) : ((uint64_t)bpf_htonl((x) & \ - 0xFFFFFFFF) << 32) | bpf_htonl((x) >> 32)) -#define ntohll(x) ((bpf_ntohl(1)) == 1 ? (x) : ((uint64_t)bpf_ntohl((x) & \ - 0xFFFFFFFF) << 32) | bpf_ntohl((x) >> 32)) #define BPF_PACKET_HEADER __attribute__((packed)) struct ip6_t { @@ -251,8 +247,8 @@ int __add_egr_x(struct __sk_buff *skb) if (err) return BPF_DROP; - addr.lo = htonll(lo); - addr.hi = htonll(hi); + addr.lo = bpf_cpu_to_be64(lo); + addr.hi = bpf_cpu_to_be64(hi); err = bpf_lwt_seg6_action(skb, SEG6_LOCAL_ACTION_END_X, (void *)&addr, sizeof(addr)); if (err) -- cgit v1.2.3-59-g8ed1b From 3404ddf234ba4677bf224cb15ddcdea0ceab956e Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Fri, 30 Aug 2019 13:07:30 +0200 Subject: selftests/bpf: fix "ctx:write sysctl:write read ok" on s390 "ctx:write sysctl:write read ok" fails on s390 because it reads the first byte of an int assuming it's the least-significant one, which is not the case on big-endian arches. Since we are not testing narrow accesses here (there is e.g. "ctx:file_pos sysctl:read read ok narrow" for that), simply read the whole int. Fixes: 1f5fa9ab6e2e ("selftests/bpf: Test BPF_CGROUP_SYSCTL") Signed-off-by: Ilya Leoshkevich Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/test_sysctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_sysctl.c b/tools/testing/selftests/bpf/test_sysctl.c index a3bebd7c68dd..908f327839d5 100644 --- a/tools/testing/selftests/bpf/test_sysctl.c +++ b/tools/testing/selftests/bpf/test_sysctl.c @@ -100,7 +100,7 @@ static struct sysctl_test tests[] = { .descr = "ctx:write sysctl:write read ok", .insns = { /* If (write) */ - BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_1, + BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, offsetof(struct bpf_sysctl, write)), BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 1, 2), -- cgit v1.2.3-59-g8ed1b From 416c572821841bef2cbb6346fb559901efff4ff3 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Fri, 30 Aug 2019 13:07:31 +0200 Subject: selftests/bpf: improve unexpected success reporting in test_syctl When tests fail because sysctl() unexpectedly succeeds, they print an inappropriate "Unexpected failure" message and a random errno. Zero out errno before calling sysctl() and replace the message with "Unexpected success". Fixes: 1f5fa9ab6e2e ("selftests/bpf: Test BPF_CGROUP_SYSCTL") Signed-off-by: Ilya Leoshkevich Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/test_sysctl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_sysctl.c b/tools/testing/selftests/bpf/test_sysctl.c index 908f327839d5..106644f7e73e 100644 --- a/tools/testing/selftests/bpf/test_sysctl.c +++ b/tools/testing/selftests/bpf/test_sysctl.c @@ -1499,6 +1499,7 @@ static int run_test_case(int cgfd, struct sysctl_test *test) goto err; } + errno = 0; if (access_sysctl(sysctl_path, test) == -1) { if (test->result == OP_EPERM && errno == EPERM) goto out; @@ -1507,7 +1508,7 @@ static int run_test_case(int cgfd, struct sysctl_test *test) } if (test->result != SUCCESS) { - log_err("Unexpected failure"); + log_err("Unexpected success"); goto err; } -- cgit v1.2.3-59-g8ed1b From 3ec2a0ed3fec4ec8b27d9b71fdcbc1c30d1542d3 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Fri, 30 Aug 2019 13:07:32 +0200 Subject: selftests/bpf: fix endianness issues in test_sysctl A lot of test_sysctl sub-tests fail due to handling strings as a bunch of immediate values in a little-endian-specific manner. Fix by wrapping all immediates in bpf_ntohl and the new bpf_be64_to_cpu. fixup_sysctl_value() dynamically writes an immediate, and thus should be endianness-aware. Implement this by simply memcpy()ing the raw user-provided value, since testcase endianness and bpf program endianness match. Fixes: 1f5fa9ab6e2e ("selftests/bpf: Test BPF_CGROUP_SYSCTL") Fixes: 9a1027e52535 ("selftests/bpf: Test file_pos field in bpf_sysctl ctx") Fixes: 6041c67f28d8 ("selftests/bpf: Test bpf_sysctl_get_name helper") Fixes: 11ff34f74e32 ("selftests/bpf: Test sysctl_get_current_value helper") Fixes: 786047dd08de ("selftests/bpf: Test bpf_sysctl_{get,set}_new_value helpers") Fixes: 8549ddc832d6 ("selftests/bpf: Test bpf_strtol and bpf_strtoul helpers") Signed-off-by: Ilya Leoshkevich Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/test_sysctl.c | 125 ++++++++++++++++++++---------- 1 file changed, 82 insertions(+), 43 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_sysctl.c b/tools/testing/selftests/bpf/test_sysctl.c index 106644f7e73e..fc33ae36b760 100644 --- a/tools/testing/selftests/bpf/test_sysctl.c +++ b/tools/testing/selftests/bpf/test_sysctl.c @@ -13,6 +13,7 @@ #include #include +#include "bpf_endian.h" #include "bpf_rlimit.h" #include "bpf_util.h" #include "cgroup_helpers.h" @@ -214,7 +215,8 @@ static struct sysctl_test tests[] = { /* if (ret == expected && */ BPF_JMP_IMM(BPF_JNE, BPF_REG_0, sizeof("tcp_mem") - 1, 6), /* buf == "tcp_mem\0") */ - BPF_LD_IMM64(BPF_REG_8, 0x006d656d5f706374ULL), + BPF_LD_IMM64(BPF_REG_8, + bpf_be64_to_cpu(0x7463705f6d656d00ULL)), BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0), BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2), @@ -255,7 +257,8 @@ static struct sysctl_test tests[] = { BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6), /* buf[0:7] == "tcp_me\0") */ - BPF_LD_IMM64(BPF_REG_8, 0x00656d5f706374ULL), + BPF_LD_IMM64(BPF_REG_8, + bpf_be64_to_cpu(0x7463705f6d650000ULL)), BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0), BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2), @@ -298,12 +301,14 @@ static struct sysctl_test tests[] = { BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 16, 14), /* buf[0:8] == "net/ipv4" && */ - BPF_LD_IMM64(BPF_REG_8, 0x347670692f74656eULL), + BPF_LD_IMM64(BPF_REG_8, + bpf_be64_to_cpu(0x6e65742f69707634ULL)), BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0), BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 10), /* buf[8:16] == "/tcp_mem" && */ - BPF_LD_IMM64(BPF_REG_8, 0x6d656d5f7063742fULL), + BPF_LD_IMM64(BPF_REG_8, + bpf_be64_to_cpu(0x2f7463705f6d656dULL)), BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8), BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6), @@ -350,12 +355,14 @@ static struct sysctl_test tests[] = { BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 10), /* buf[0:8] == "net/ipv4" && */ - BPF_LD_IMM64(BPF_REG_8, 0x347670692f74656eULL), + BPF_LD_IMM64(BPF_REG_8, + bpf_be64_to_cpu(0x6e65742f69707634ULL)), BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0), BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6), /* buf[8:16] == "/tcp_me\0") */ - BPF_LD_IMM64(BPF_REG_8, 0x00656d5f7063742fULL), + BPF_LD_IMM64(BPF_REG_8, + bpf_be64_to_cpu(0x2f7463705f6d6500ULL)), BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8), BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2), @@ -396,7 +403,8 @@ static struct sysctl_test tests[] = { BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6), /* buf[0:8] == "net/ip\0") */ - BPF_LD_IMM64(BPF_REG_8, 0x000070692f74656eULL), + BPF_LD_IMM64(BPF_REG_8, + bpf_be64_to_cpu(0x6e65742f69700000ULL)), BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0), BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2), @@ -431,7 +439,8 @@ static struct sysctl_test tests[] = { BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 6, 6), /* buf[0:6] == "Linux\n\0") */ - BPF_LD_IMM64(BPF_REG_8, 0x000a78756e694cULL), + BPF_LD_IMM64(BPF_REG_8, + bpf_be64_to_cpu(0x4c696e75780a0000ULL)), BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0), BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2), @@ -469,7 +478,8 @@ static struct sysctl_test tests[] = { BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 6, 6), /* buf[0:6] == "Linux\n\0") */ - BPF_LD_IMM64(BPF_REG_8, 0x000a78756e694cULL), + BPF_LD_IMM64(BPF_REG_8, + bpf_be64_to_cpu(0x4c696e75780a0000ULL)), BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0), BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2), @@ -507,7 +517,8 @@ static struct sysctl_test tests[] = { BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6), /* buf[0:6] == "Linux\0") */ - BPF_LD_IMM64(BPF_REG_8, 0x000078756e694cULL), + BPF_LD_IMM64(BPF_REG_8, + bpf_be64_to_cpu(0x4c696e7578000000ULL)), BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0), BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2), @@ -650,7 +661,8 @@ static struct sysctl_test tests[] = { /* buf[0:4] == "606\0") */ BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_7, 0), - BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 0x00363036, 2), + BPF_JMP_IMM(BPF_JNE, BPF_REG_9, + bpf_ntohl(0x36303600), 2), /* return DENY; */ BPF_MOV64_IMM(BPF_REG_0, 0), @@ -685,17 +697,20 @@ static struct sysctl_test tests[] = { BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 23, 14), /* buf[0:8] == "3000000 " && */ - BPF_LD_IMM64(BPF_REG_8, 0x2030303030303033ULL), + BPF_LD_IMM64(BPF_REG_8, + bpf_be64_to_cpu(0x3330303030303020ULL)), BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0), BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 10), /* buf[8:16] == "4000000 " && */ - BPF_LD_IMM64(BPF_REG_8, 0x2030303030303034ULL), + BPF_LD_IMM64(BPF_REG_8, + bpf_be64_to_cpu(0x3430303030303020ULL)), BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8), BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6), /* buf[16:24] == "6000000\0") */ - BPF_LD_IMM64(BPF_REG_8, 0x0030303030303036ULL), + BPF_LD_IMM64(BPF_REG_8, + bpf_be64_to_cpu(0x3630303030303000ULL)), BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 16), BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2), @@ -735,7 +750,8 @@ static struct sysctl_test tests[] = { /* buf[0:3] == "60\0") */ BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_7, 0), - BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 0x003036, 2), + BPF_JMP_IMM(BPF_JNE, BPF_REG_9, + bpf_ntohl(0x36300000), 2), /* return DENY; */ BPF_MOV64_IMM(BPF_REG_0, 0), @@ -757,7 +773,8 @@ static struct sysctl_test tests[] = { /* sysctl_set_new_value arg2 (buf) */ BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), - BPF_MOV64_IMM(BPF_REG_0, 0x00303036), + BPF_MOV64_IMM(BPF_REG_0, + bpf_ntohl(0x36303000)), BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), BPF_MOV64_REG(BPF_REG_2, BPF_REG_7), @@ -791,7 +808,7 @@ static struct sysctl_test tests[] = { /* sysctl_set_new_value arg2 (buf) */ BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), - BPF_MOV64_IMM(BPF_REG_0, FIXUP_SYSCTL_VALUE), + BPF_LD_IMM64(BPF_REG_0, FIXUP_SYSCTL_VALUE), BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), BPF_MOV64_REG(BPF_REG_2, BPF_REG_7), @@ -825,8 +842,9 @@ static struct sysctl_test tests[] = { /* arg1 (buf) */ BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), - BPF_MOV64_IMM(BPF_REG_0, 0x00303036), - BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), + BPF_MOV64_IMM(BPF_REG_0, + bpf_ntohl(0x36303000)), + BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0), BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), @@ -869,7 +887,8 @@ static struct sysctl_test tests[] = { BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), /* "600 602\0" */ - BPF_LD_IMM64(BPF_REG_0, 0x0032303620303036ULL), + BPF_LD_IMM64(BPF_REG_0, + bpf_be64_to_cpu(0x3630302036303200ULL)), BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), @@ -937,7 +956,8 @@ static struct sysctl_test tests[] = { /* arg1 (buf) */ BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), - BPF_MOV64_IMM(BPF_REG_0, 0x00303036), + BPF_MOV64_IMM(BPF_REG_0, + bpf_ntohl(0x36303000)), BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), @@ -969,8 +989,9 @@ static struct sysctl_test tests[] = { /* arg1 (buf) */ BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), - BPF_MOV64_IMM(BPF_REG_0, 0x00373730), - BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), + BPF_MOV64_IMM(BPF_REG_0, + bpf_ntohl(0x30373700)), + BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0), BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), @@ -1012,7 +1033,8 @@ static struct sysctl_test tests[] = { /* arg1 (buf) */ BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), - BPF_MOV64_IMM(BPF_REG_0, 0x00303036), + BPF_MOV64_IMM(BPF_REG_0, + bpf_ntohl(0x36303000)), BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), @@ -1052,7 +1074,8 @@ static struct sysctl_test tests[] = { /* arg1 (buf) */ BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), - BPF_MOV64_IMM(BPF_REG_0, 0x090a0c0d), + BPF_MOV64_IMM(BPF_REG_0, + bpf_ntohl(0x0d0c0a09)), BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), @@ -1092,7 +1115,9 @@ static struct sysctl_test tests[] = { /* arg1 (buf) */ BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), - BPF_MOV64_IMM(BPF_REG_0, 0x00362d0a), /* " -6\0" */ + /* " -6\0" */ + BPF_MOV64_IMM(BPF_REG_0, + bpf_ntohl(0x0a2d3600)), BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), @@ -1132,8 +1157,10 @@ static struct sysctl_test tests[] = { /* arg1 (buf) */ BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), - BPF_MOV64_IMM(BPF_REG_0, 0x00362d0a), /* " -6\0" */ - BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), + /* " -6\0" */ + BPF_MOV64_IMM(BPF_REG_0, + bpf_ntohl(0x0a2d3600)), + BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0), BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), @@ -1175,8 +1202,10 @@ static struct sysctl_test tests[] = { /* arg1 (buf) */ BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), - BPF_MOV64_IMM(BPF_REG_0, 0x65667830), /* "0xfe" */ - BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), + /* "0xfe" */ + BPF_MOV64_IMM(BPF_REG_0, + bpf_ntohl(0x30786665)), + BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0), BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), @@ -1218,11 +1247,14 @@ static struct sysctl_test tests[] = { /* arg1 (buf) 9223372036854775807 */ BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24), - BPF_LD_IMM64(BPF_REG_0, 0x3032373333323239ULL), + BPF_LD_IMM64(BPF_REG_0, + bpf_be64_to_cpu(0x3932323333373230ULL)), BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), - BPF_LD_IMM64(BPF_REG_0, 0x3537373435383633ULL), + BPF_LD_IMM64(BPF_REG_0, + bpf_be64_to_cpu(0x3336383534373735ULL)), BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8), - BPF_LD_IMM64(BPF_REG_0, 0x0000000000373038ULL), + BPF_LD_IMM64(BPF_REG_0, + bpf_be64_to_cpu(0x3830370000000000ULL)), BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 16), BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), @@ -1266,11 +1298,14 @@ static struct sysctl_test tests[] = { /* arg1 (buf) 9223372036854775808 */ BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24), - BPF_LD_IMM64(BPF_REG_0, 0x3032373333323239ULL), + BPF_LD_IMM64(BPF_REG_0, + bpf_be64_to_cpu(0x3932323333373230ULL)), BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), - BPF_LD_IMM64(BPF_REG_0, 0x3537373435383633ULL), + BPF_LD_IMM64(BPF_REG_0, + bpf_be64_to_cpu(0x3336383534373735ULL)), BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8), - BPF_LD_IMM64(BPF_REG_0, 0x0000000000383038ULL), + BPF_LD_IMM64(BPF_REG_0, + bpf_be64_to_cpu(0x3830380000000000ULL)), BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 16), BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), @@ -1344,20 +1379,24 @@ static size_t probe_prog_length(const struct bpf_insn *fp) static int fixup_sysctl_value(const char *buf, size_t buf_len, struct bpf_insn *prog, size_t insn_num) { - uint32_t value_num = 0; + union { + uint8_t raw[sizeof(uint64_t)]; + uint64_t num; + } value = {}; uint8_t c, i; - if (buf_len > sizeof(value_num)) { + if (buf_len > sizeof(value)) { log_err("Value is too big (%zd) to use in fixup", buf_len); return -1; } - - for (i = 0; i < buf_len; ++i) { - c = buf[i]; - value_num |= (c << i * 8); + if (prog[insn_num].code != (BPF_LD | BPF_DW | BPF_IMM)) { + log_err("Can fixup only BPF_LD_IMM64 insns"); + return -1; } - prog[insn_num].imm = value_num; + memcpy(value.raw, buf, buf_len); + prog[insn_num].imm = (uint32_t)value.num; + prog[insn_num + 1].imm = (uint32_t)(value.num >> 32); return 0; } -- cgit v1.2.3-59-g8ed1b From 1798045900b7fb24a2b9c37d8517bbcfc5d3eaa9 Mon Sep 17 00:00:00 2001 From: Scott Branden Date: Thu, 22 Aug 2019 11:40:05 -0700 Subject: selftests: firmware: Add request_firmware_into_buf tests Add tests cases for checking request_firmware_into_buf api. API was introduced into kernel with no testing present previously. Signed-off-by: Scott Branden Acked-by: Luis Chamberlain Acked-by: Shuah Khan Link: https://lore.kernel.org/r/20190822184005.901-3-scott.branden@broadcom.com Signed-off-by: Greg Kroah-Hartman --- tools/testing/selftests/firmware/fw_filesystem.sh | 57 ++++++++++++++++++++++- tools/testing/selftests/firmware/fw_lib.sh | 11 +++++ 2 files changed, 66 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/firmware/fw_filesystem.sh b/tools/testing/selftests/firmware/fw_filesystem.sh index f901076aa2ea..56894477c8bd 100755 --- a/tools/testing/selftests/firmware/fw_filesystem.sh +++ b/tools/testing/selftests/firmware/fw_filesystem.sh @@ -116,6 +116,16 @@ config_set_name() echo -n $1 > $DIR/config_name } +config_set_into_buf() +{ + echo 1 > $DIR/config_into_buf +} + +config_unset_into_buf() +{ + echo 0 > $DIR/config_into_buf +} + config_set_sync_direct() { echo 1 > $DIR/config_sync_direct @@ -153,11 +163,14 @@ config_set_read_fw_idx() read_firmwares() { - if [ "$1" = "xzonly" ]; then - fwfile="${FW}-orig" + if [ "$(cat $DIR/config_into_buf)" == "1" ]; then + fwfile="$FW_INTO_BUF" else fwfile="$FW" fi + if [ "$1" = "xzonly" ]; then + fwfile="${fwfile}-orig" + fi for i in $(seq 0 3); do config_set_read_fw_idx $i # Verify the contents are what we expect. @@ -194,6 +207,18 @@ test_batched_request_firmware_nofile() echo "OK" } +test_batched_request_firmware_into_buf_nofile() +{ + echo -n "Batched request_firmware_into_buf() nofile try #$1: " + config_reset + config_set_name nope-test-firmware.bin + config_set_into_buf + config_trigger_sync + read_firmwares_expect_nofile + release_all_firmware + echo "OK" +} + test_batched_request_firmware_direct_nofile() { echo -n "Batched request_firmware_direct() nofile try #$1: " @@ -259,6 +284,18 @@ test_batched_request_firmware() echo "OK" } +test_batched_request_firmware_into_buf() +{ + echo -n "Batched request_firmware_into_buf() $2 try #$1: " + config_reset + config_set_name $TEST_FIRMWARE_INTO_BUF_FILENAME + config_set_into_buf + config_trigger_sync + read_firmwares $2 + release_all_firmware + echo "OK" +} + test_batched_request_firmware_direct() { echo -n "Batched request_firmware_direct() $2 try #$1: " @@ -307,6 +344,10 @@ for i in $(seq 1 5); do test_batched_request_firmware $i normal done +for i in $(seq 1 5); do + test_batched_request_firmware_into_buf $i normal +done + for i in $(seq 1 5); do test_batched_request_firmware_direct $i normal done @@ -327,6 +368,10 @@ for i in $(seq 1 5); do test_batched_request_firmware_nofile $i done +for i in $(seq 1 5); do + test_batched_request_firmware_into_buf_nofile $i +done + for i in $(seq 1 5); do test_batched_request_firmware_direct_nofile $i done @@ -350,6 +395,10 @@ for i in $(seq 1 5); do test_batched_request_firmware $i both done +for i in $(seq 1 5); do + test_batched_request_firmware_into_buf $i both +done + for i in $(seq 1 5); do test_batched_request_firmware_direct $i both done @@ -370,6 +419,10 @@ for i in $(seq 1 5); do test_batched_request_firmware $i xzonly done +for i in $(seq 1 5); do + test_batched_request_firmware_into_buf $i xzonly +done + for i in $(seq 1 5); do test_batched_request_firmware_direct $i xzonly done diff --git a/tools/testing/selftests/firmware/fw_lib.sh b/tools/testing/selftests/firmware/fw_lib.sh index f236cc295450..b879305a766d 100755 --- a/tools/testing/selftests/firmware/fw_lib.sh +++ b/tools/testing/selftests/firmware/fw_lib.sh @@ -9,6 +9,12 @@ DIR=/sys/devices/virtual/misc/test_firmware PROC_CONFIG="/proc/config.gz" TEST_DIR=$(dirname $0) +# We need to load a different file to test request_firmware_into_buf +# I believe the issue is firmware loaded cached vs. non-cached +# with same filename is bungled. +# To reproduce rename this to test-firmware.bin +TEST_FIRMWARE_INTO_BUF_FILENAME=test-firmware-into-buf.bin + # Kselftest framework requirement - SKIP code is 4. ksft_skip=4 @@ -108,6 +114,8 @@ setup_tmp_file() FWPATH=$(mktemp -d) FW="$FWPATH/test-firmware.bin" echo "ABCD0123" >"$FW" + FW_INTO_BUF="$FWPATH/$TEST_FIRMWARE_INTO_BUF_FILENAME" + echo "EFGH4567" >"$FW_INTO_BUF" NAME=$(basename "$FW") if [ "$TEST_REQS_FW_SET_CUSTOM_PATH" = "yes" ]; then echo -n "$FWPATH" >/sys/module/firmware_class/parameters/path @@ -175,6 +183,9 @@ test_finish() if [ -f $FW ]; then rm -f "$FW" fi + if [ -f $FW_INTO_BUF ]; then + rm -f "$FW_INTO_BUF" + fi if [ -d $FWPATH ]; then rm -rf "$FWPATH" fi -- cgit v1.2.3-59-g8ed1b From 81cb736c0c928444e2f4707513c167d5d39844a4 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 4 Sep 2019 10:52:00 +0200 Subject: KVM: selftests: Test invalid bits in kvm_valid_regs and kvm_dirty_regs on s390x Now that we disallow invalid bits in kvm_valid_regs and kvm_dirty_regs on s390x, too, we should also check this condition in the selftests. The code has been taken from the x86-version of the sync_regs_test. Reviewed-by: Janosch Frank Reviewed-by: Christian Borntraeger Reviewed-by: Cornelia Huck Signed-off-by: Thomas Huth Link: https://lore.kernel.org/lkml/20190904085200.29021-3-thuth@redhat.com/ Signed-off-by: Janosch Frank --- tools/testing/selftests/kvm/s390x/sync_regs_test.c | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/s390x/sync_regs_test.c b/tools/testing/selftests/kvm/s390x/sync_regs_test.c index bbc93094519b..d5290b4ad636 100644 --- a/tools/testing/selftests/kvm/s390x/sync_regs_test.c +++ b/tools/testing/selftests/kvm/s390x/sync_regs_test.c @@ -85,6 +85,36 @@ int main(int argc, char *argv[]) run = vcpu_state(vm, VCPU_ID); + /* Request reading invalid register set from VCPU. */ + run->kvm_valid_regs = INVALID_SYNC_FIELD; + rv = _vcpu_run(vm, VCPU_ID); + TEST_ASSERT(rv < 0 && errno == EINVAL, + "Invalid kvm_valid_regs did not cause expected KVM_RUN error: %d\n", + rv); + vcpu_state(vm, VCPU_ID)->kvm_valid_regs = 0; + + run->kvm_valid_regs = INVALID_SYNC_FIELD | TEST_SYNC_FIELDS; + rv = _vcpu_run(vm, VCPU_ID); + TEST_ASSERT(rv < 0 && errno == EINVAL, + "Invalid kvm_valid_regs did not cause expected KVM_RUN error: %d\n", + rv); + vcpu_state(vm, VCPU_ID)->kvm_valid_regs = 0; + + /* Request setting invalid register set into VCPU. */ + run->kvm_dirty_regs = INVALID_SYNC_FIELD; + rv = _vcpu_run(vm, VCPU_ID); + TEST_ASSERT(rv < 0 && errno == EINVAL, + "Invalid kvm_dirty_regs did not cause expected KVM_RUN error: %d\n", + rv); + vcpu_state(vm, VCPU_ID)->kvm_dirty_regs = 0; + + run->kvm_dirty_regs = INVALID_SYNC_FIELD | TEST_SYNC_FIELDS; + rv = _vcpu_run(vm, VCPU_ID); + TEST_ASSERT(rv < 0 && errno == EINVAL, + "Invalid kvm_dirty_regs did not cause expected KVM_RUN error: %d\n", + rv); + vcpu_state(vm, VCPU_ID)->kvm_dirty_regs = 0; + /* Request and verify all valid register sets. */ run->kvm_valid_regs = TEST_SYNC_FIELDS; rv = _vcpu_run(vm, VCPU_ID); -- cgit v1.2.3-59-g8ed1b From 4216148337211be7ad2bfe38a0dffc3ce479c283 Mon Sep 17 00:00:00 2001 From: Todd Brandt Date: Wed, 4 Sep 2019 14:04:52 -0700 Subject: pm-graph: make setVal unbuffered again for python2 and python3 sleepgraph: - kprobe_events won't set correctly if the data is buffered - force sysvals.setVal to be unbuffered and use binary mode - tested in both python2 and python3 Link: https://bugzilla.kernel.org/show_bug.cgi?id=204773 Signed-off-by: Todd Brandt [ rjw: Subject ] Signed-off-by: Rafael J. Wysocki --- tools/power/pm-graph/sleepgraph.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/power/pm-graph/sleepgraph.py b/tools/power/pm-graph/sleepgraph.py index 1794c79a7d1b..f7d1c1f62f86 100755 --- a/tools/power/pm-graph/sleepgraph.py +++ b/tools/power/pm-graph/sleepgraph.py @@ -667,19 +667,19 @@ class SystemValues: if linesack < linesout: return False return True - def setVal(self, val, file, mode='w'): + def setVal(self, val, file): if not os.path.exists(file): return False try: - fp = open(file, mode) - fp.write(val) + fp = open(file, 'wb', 0) + fp.write(val.encode()) fp.flush() fp.close() except: return False return True - def fsetVal(self, val, path, mode='w'): - return self.setVal(val, self.tpath+path, mode) + def fsetVal(self, val, path): + return self.setVal(val, self.tpath+path) def getVal(self, file): res = '' if not os.path.exists(file): -- cgit v1.2.3-59-g8ed1b From 85d86c8aa52eb5b3539eebe3adcc2f077118b412 Mon Sep 17 00:00:00 2001 From: Oliver O'Halloran Date: Tue, 3 Sep 2019 20:16:05 +1000 Subject: selftests/powerpc: Add basic EEH selftest Use the new eeh_dev_check and eeh_dev_break interfaces to test EEH recovery. Historically this has been done manually using platform specific EEH error injection facilities (e.g. via RTAS). However, documentation on how to use these facilities is haphazard at best and non-existent at worst so it's hard to develop a cross-platform test. The new debugfs interfaces allow the kernel to handle the platform specific details so we can write a more generic set of sets. This patch adds the most basic of recovery tests where: a) Errors are injected and recovered from sequentially, b) Errors are not injected into PCI-PCI bridges, such as PCIe switches. c) Errors are only injected into device function zero. d) No errors are injected into Virtual Functions. a), b) and c) are largely due to limitations of Linux's EEH support. EEH recovery is serialised in the EEH recovery thread which forces a). Similarly, multi-function PCI devices are almost always grouped into the same PE so injecting an error on one function exercises the same code paths. c) is because we currently more or less ignore PCI bridges during recovery and assume that the recovered topology will be the same as the original. d) is due to the limits of the eeh_dev_break interface. With the current implementation we can't inject an error into a specific VF without potentially causing additional errors on other VFs. Due to the serialised recovery process we might end up timing out waiting for another function to recover before the function of interest is recovered. The platform specific error injection facilities are finer-grained and allow this capability, but doing that requires working out how to use those facilities first. Basicly, it's better than nothing and it's a base to build on. Signed-off-by: Oliver O'Halloran Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20190903101605.2890-15-oohall@gmail.com --- tools/testing/selftests/powerpc/Makefile | 1 + tools/testing/selftests/powerpc/eeh/Makefile | 9 +++ tools/testing/selftests/powerpc/eeh/eeh-basic.sh | 82 ++++++++++++++++++++++ .../testing/selftests/powerpc/eeh/eeh-functions.sh | 76 ++++++++++++++++++++ 4 files changed, 168 insertions(+) create mode 100644 tools/testing/selftests/powerpc/eeh/Makefile create mode 100755 tools/testing/selftests/powerpc/eeh/eeh-basic.sh create mode 100755 tools/testing/selftests/powerpc/eeh/eeh-functions.sh (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile index b3ad909aefbc..644770c3b754 100644 --- a/tools/testing/selftests/powerpc/Makefile +++ b/tools/testing/selftests/powerpc/Makefile @@ -26,6 +26,7 @@ SUB_DIRS = alignment \ switch_endian \ syscalls \ tm \ + eeh \ vphn \ math \ ptrace \ diff --git a/tools/testing/selftests/powerpc/eeh/Makefile b/tools/testing/selftests/powerpc/eeh/Makefile new file mode 100644 index 000000000000..b397babd569b --- /dev/null +++ b/tools/testing/selftests/powerpc/eeh/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 +noarg: + $(MAKE) -C ../ + +TEST_PROGS := eeh-basic.sh +TEST_FILES := eeh-functions.sh + +top_srcdir = ../../../../.. +include ../../lib.mk diff --git a/tools/testing/selftests/powerpc/eeh/eeh-basic.sh b/tools/testing/selftests/powerpc/eeh/eeh-basic.sh new file mode 100755 index 000000000000..f988d2f42e8f --- /dev/null +++ b/tools/testing/selftests/powerpc/eeh/eeh-basic.sh @@ -0,0 +1,82 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only + +. ./eeh-functions.sh + +if ! eeh_supported ; then + echo "EEH not supported on this system, skipping" + exit 0; +fi + +if [ ! -e "/sys/kernel/debug/powerpc/eeh_dev_check" ] && \ + [ ! -e "/sys/kernel/debug/powerpc/eeh_dev_break" ] ; then + echo "debugfs EEH testing files are missing. Is debugfs mounted?" + exit 1; +fi + +pre_lspci=`mktemp` +lspci > $pre_lspci + +# Bump the max freeze count to something absurd so we don't +# trip over it while breaking things. +echo 5000 > /sys/kernel/debug/powerpc/eeh_max_freezes + +# record the devices that we break in here. Assuming everything +# goes to plan we should get them back once the recover process +# is finished. +devices="" + +# Build up a list of candidate devices. +for dev in `ls -1 /sys/bus/pci/devices/ | grep '\.0$'` ; do + # skip bridges since we can't recover them (yet...) + if [ -e "/sys/bus/pci/devices/$dev/pci_bus" ] ; then + echo "$dev, Skipped: bridge" + continue; + fi + + # Skip VFs for now since we don't have a reliable way + # to break them. + if [ -e "/sys/bus/pci/devices/$dev/physfn" ] ; then + echo "$dev, Skipped: virtfn" + continue; + fi + + # Don't inject errosr into an already-frozen PE. This happens with + # PEs that contain multiple PCI devices (e.g. multi-function cards) + # and injecting new errors during the recovery process will probably + # result in the recovery failing and the device being marked as + # failed. + if ! pe_ok $dev ; then + echo "$dev, Skipped: Bad initial PE state" + continue; + fi + + echo "$dev, Added" + + # Add to this list of device to check + devices="$devices $dev" +done + +dev_count="$(echo $devices | wc -w)" +echo "Found ${dev_count} breakable devices..." + +failed=0 +for dev in $devices ; do + echo "Breaking $dev..." + + if ! pe_ok $dev ; then + echo "Skipping $dev, Initial PE state is not ok" + failed="$((failed + 1))" + continue; + fi + + if ! eeh_one_dev $dev ; then + failed="$((failed + 1))" + fi +done + +echo "$failed devices failed to recover ($dev_count tested)" +lspci | diff -u $pre_lspci - +rm -f $pre_lspci + +exit $failed diff --git a/tools/testing/selftests/powerpc/eeh/eeh-functions.sh b/tools/testing/selftests/powerpc/eeh/eeh-functions.sh new file mode 100755 index 000000000000..26112ab5cdf4 --- /dev/null +++ b/tools/testing/selftests/powerpc/eeh/eeh-functions.sh @@ -0,0 +1,76 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only + +pe_ok() { + local dev="$1" + local path="/sys/bus/pci/devices/$dev/eeh_pe_state" + + if ! [ -e "$path" ] ; then + return 1; + fi + + local fw_state="$(cut -d' ' -f1 < $path)" + local sw_state="$(cut -d' ' -f2 < $path)" + + # If EEH_PE_ISOLATED or EEH_PE_RECOVERING are set then the PE is in an + # error state or being recovered. Either way, not ok. + if [ "$((sw_state & 0x3))" -ne 0 ] ; then + return 1 + fi + + # A functioning PE should have the EEH_STATE_MMIO_ACTIVE and + # EEH_STATE_DMA_ACTIVE flags set. For some goddamn stupid reason + # the platform backends set these when the PE is in reset. The + # RECOVERING check above should stop any false positives though. + if [ "$((fw_state & 0x18))" -ne "$((0x18))" ] ; then + return 1 + fi + + return 0; +} + +eeh_supported() { + test -e /proc/powerpc/eeh && \ + grep -q 'EEH Subsystem is enabled' /proc/powerpc/eeh +} + +eeh_one_dev() { + local dev="$1" + + # Using this function from the command line is sometimes useful for + # testing so check that the argument is a well-formed sysfs device + # name. + if ! test -e /sys/bus/pci/devices/$dev/ ; then + echo "Error: '$dev' must be a sysfs device name (DDDD:BB:DD.F)" + return 1; + fi + + # Break it + echo $dev >/sys/kernel/debug/powerpc/eeh_dev_break + + # Force an EEH device check. If the kernel has already + # noticed the EEH (due to a driver poll or whatever), this + # is a no-op. + echo $dev >/sys/kernel/debug/powerpc/eeh_dev_check + + # Enforce a 30s timeout for recovery. Even the IPR, which is infamously + # slow to reset, should recover within 30s. + max_wait=30 + + for i in `seq 0 ${max_wait}` ; do + if pe_ok $dev ; then + break; + fi + echo "$dev, waited $i/${max_wait}" + sleep 1 + done + + if ! pe_ok $dev ; then + echo "$dev, Failed to recover!" + return 1; + fi + + echo "$dev, Recovered after $i seconds" + return 0; +} + -- cgit v1.2.3-59-g8ed1b From 51bc620ba972e1600b791a32c69fa28c80e16fdb Mon Sep 17 00:00:00 2001 From: Mao Han Date: Thu, 5 Sep 2019 11:46:36 +0800 Subject: riscv: Add support for libdw This patch adds support for DWARF register mappings and libdw registers initialization, which is used by perf callchain analyzing when --call-graph=dwarf is given. Signed-off-by: Mao Han Cc: Paul Walmsley Cc: Greentime Hu Cc: Palmer Dabbelt Cc: linux-riscv Cc: Christoph Hellwig Cc: Guo Ren Tested-by: Greentime Hu Signed-off-by: Paul Walmsley --- tools/arch/riscv/include/uapi/asm/perf_regs.h | 42 ++++++++++++ tools/perf/Makefile.config | 6 +- tools/perf/arch/riscv/Build | 1 + tools/perf/arch/riscv/Makefile | 4 ++ tools/perf/arch/riscv/include/perf_regs.h | 96 +++++++++++++++++++++++++++ tools/perf/arch/riscv/util/Build | 2 + tools/perf/arch/riscv/util/dwarf-regs.c | 72 ++++++++++++++++++++ tools/perf/arch/riscv/util/unwind-libdw.c | 57 ++++++++++++++++ 8 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 tools/arch/riscv/include/uapi/asm/perf_regs.h create mode 100644 tools/perf/arch/riscv/Build create mode 100644 tools/perf/arch/riscv/Makefile create mode 100644 tools/perf/arch/riscv/include/perf_regs.h create mode 100644 tools/perf/arch/riscv/util/Build create mode 100644 tools/perf/arch/riscv/util/dwarf-regs.c create mode 100644 tools/perf/arch/riscv/util/unwind-libdw.c (limited to 'tools') diff --git a/tools/arch/riscv/include/uapi/asm/perf_regs.h b/tools/arch/riscv/include/uapi/asm/perf_regs.h new file mode 100644 index 000000000000..196f964bfcb4 --- /dev/null +++ b/tools/arch/riscv/include/uapi/asm/perf_regs.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */ + +#ifndef _ASM_RISCV_PERF_REGS_H +#define _ASM_RISCV_PERF_REGS_H + +enum perf_event_riscv_regs { + PERF_REG_RISCV_PC, + PERF_REG_RISCV_RA, + PERF_REG_RISCV_SP, + PERF_REG_RISCV_GP, + PERF_REG_RISCV_TP, + PERF_REG_RISCV_T0, + PERF_REG_RISCV_T1, + PERF_REG_RISCV_T2, + PERF_REG_RISCV_S0, + PERF_REG_RISCV_S1, + PERF_REG_RISCV_A0, + PERF_REG_RISCV_A1, + PERF_REG_RISCV_A2, + PERF_REG_RISCV_A3, + PERF_REG_RISCV_A4, + PERF_REG_RISCV_A5, + PERF_REG_RISCV_A6, + PERF_REG_RISCV_A7, + PERF_REG_RISCV_S2, + PERF_REG_RISCV_S3, + PERF_REG_RISCV_S4, + PERF_REG_RISCV_S5, + PERF_REG_RISCV_S6, + PERF_REG_RISCV_S7, + PERF_REG_RISCV_S8, + PERF_REG_RISCV_S9, + PERF_REG_RISCV_S10, + PERF_REG_RISCV_S11, + PERF_REG_RISCV_T3, + PERF_REG_RISCV_T4, + PERF_REG_RISCV_T5, + PERF_REG_RISCV_T6, + PERF_REG_RISCV_MAX, +}; +#endif /* _ASM_RISCV_PERF_REGS_H */ diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 89ac5a1f1550..eaf25ee104e4 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -60,6 +60,10 @@ ifeq ($(SRCARCH),arm64) LIBUNWIND_LIBS = -lunwind -lunwind-aarch64 endif +ifeq ($(SRCARCH),riscv) + NO_PERF_REGS := 0 +endif + ifeq ($(SRCARCH),csky) NO_PERF_REGS := 0 endif @@ -82,7 +86,7 @@ endif # Disable it on all other architectures in case libdw unwind # support is detected in system. Add supported architectures # to the check. -ifneq ($(SRCARCH),$(filter $(SRCARCH),x86 arm arm64 powerpc s390 csky)) +ifneq ($(SRCARCH),$(filter $(SRCARCH),x86 arm arm64 powerpc s390 csky riscv)) NO_LIBDW_DWARF_UNWIND := 1 endif diff --git a/tools/perf/arch/riscv/Build b/tools/perf/arch/riscv/Build new file mode 100644 index 000000000000..e4e5f33c84d8 --- /dev/null +++ b/tools/perf/arch/riscv/Build @@ -0,0 +1 @@ +perf-y += util/ diff --git a/tools/perf/arch/riscv/Makefile b/tools/perf/arch/riscv/Makefile new file mode 100644 index 000000000000..1aa9dd772489 --- /dev/null +++ b/tools/perf/arch/riscv/Makefile @@ -0,0 +1,4 @@ +ifndef NO_DWARF +PERF_HAVE_DWARF_REGS := 1 +endif +PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1 diff --git a/tools/perf/arch/riscv/include/perf_regs.h b/tools/perf/arch/riscv/include/perf_regs.h new file mode 100644 index 000000000000..7a8bcde7a2b1 --- /dev/null +++ b/tools/perf/arch/riscv/include/perf_regs.h @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */ + +#ifndef ARCH_PERF_REGS_H +#define ARCH_PERF_REGS_H + +#include +#include +#include + +#define PERF_REGS_MASK ((1ULL << PERF_REG_RISCV_MAX) - 1) +#define PERF_REGS_MAX PERF_REG_RISCV_MAX +#if __riscv_xlen == 64 +#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64 +#else +#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32 +#endif + +#define PERF_REG_IP PERF_REG_RISCV_PC +#define PERF_REG_SP PERF_REG_RISCV_SP + +static inline const char *perf_reg_name(int id) +{ + switch (id) { + case PERF_REG_RISCV_PC: + return "pc"; + case PERF_REG_RISCV_RA: + return "ra"; + case PERF_REG_RISCV_SP: + return "sp"; + case PERF_REG_RISCV_GP: + return "gp"; + case PERF_REG_RISCV_TP: + return "tp"; + case PERF_REG_RISCV_T0: + return "t0"; + case PERF_REG_RISCV_T1: + return "t1"; + case PERF_REG_RISCV_T2: + return "t2"; + case PERF_REG_RISCV_S0: + return "s0"; + case PERF_REG_RISCV_S1: + return "s1"; + case PERF_REG_RISCV_A0: + return "a0"; + case PERF_REG_RISCV_A1: + return "a1"; + case PERF_REG_RISCV_A2: + return "a2"; + case PERF_REG_RISCV_A3: + return "a3"; + case PERF_REG_RISCV_A4: + return "a4"; + case PERF_REG_RISCV_A5: + return "a5"; + case PERF_REG_RISCV_A6: + return "a6"; + case PERF_REG_RISCV_A7: + return "a7"; + case PERF_REG_RISCV_S2: + return "s2"; + case PERF_REG_RISCV_S3: + return "s3"; + case PERF_REG_RISCV_S4: + return "s4"; + case PERF_REG_RISCV_S5: + return "s5"; + case PERF_REG_RISCV_S6: + return "s6"; + case PERF_REG_RISCV_S7: + return "s7"; + case PERF_REG_RISCV_S8: + return "s8"; + case PERF_REG_RISCV_S9: + return "s9"; + case PERF_REG_RISCV_S10: + return "s10"; + case PERF_REG_RISCV_S11: + return "s11"; + case PERF_REG_RISCV_T3: + return "t3"; + case PERF_REG_RISCV_T4: + return "t4"; + case PERF_REG_RISCV_T5: + return "t5"; + case PERF_REG_RISCV_T6: + return "t6"; + default: + return NULL; + } + + return NULL; +} + +#endif /* ARCH_PERF_REGS_H */ diff --git a/tools/perf/arch/riscv/util/Build b/tools/perf/arch/riscv/util/Build new file mode 100644 index 000000000000..1160bb2332ba --- /dev/null +++ b/tools/perf/arch/riscv/util/Build @@ -0,0 +1,2 @@ +perf-$(CONFIG_DWARF) += dwarf-regs.o +perf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o diff --git a/tools/perf/arch/riscv/util/dwarf-regs.c b/tools/perf/arch/riscv/util/dwarf-regs.c new file mode 100644 index 000000000000..cd0504c02e2e --- /dev/null +++ b/tools/perf/arch/riscv/util/dwarf-regs.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. + * Mapping of DWARF debug register numbers into register names. + */ + +#include +#include /* for EINVAL */ +#include /* for strcmp */ +#include + +struct pt_regs_dwarfnum { + const char *name; + unsigned int dwarfnum; +}; + +#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num} +#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0} + +struct pt_regs_dwarfnum riscv_dwarf_regs_table[] = { + REG_DWARFNUM_NAME("%zero", 0), + REG_DWARFNUM_NAME("%ra", 1), + REG_DWARFNUM_NAME("%sp", 2), + REG_DWARFNUM_NAME("%gp", 3), + REG_DWARFNUM_NAME("%tp", 4), + REG_DWARFNUM_NAME("%t0", 5), + REG_DWARFNUM_NAME("%t1", 6), + REG_DWARFNUM_NAME("%t2", 7), + REG_DWARFNUM_NAME("%s0", 8), + REG_DWARFNUM_NAME("%s1", 9), + REG_DWARFNUM_NAME("%a0", 10), + REG_DWARFNUM_NAME("%a1", 11), + REG_DWARFNUM_NAME("%a2", 12), + REG_DWARFNUM_NAME("%a3", 13), + REG_DWARFNUM_NAME("%a4", 14), + REG_DWARFNUM_NAME("%a5", 15), + REG_DWARFNUM_NAME("%a6", 16), + REG_DWARFNUM_NAME("%a7", 17), + REG_DWARFNUM_NAME("%s2", 18), + REG_DWARFNUM_NAME("%s3", 19), + REG_DWARFNUM_NAME("%s4", 20), + REG_DWARFNUM_NAME("%s5", 21), + REG_DWARFNUM_NAME("%s6", 22), + REG_DWARFNUM_NAME("%s7", 23), + REG_DWARFNUM_NAME("%s8", 24), + REG_DWARFNUM_NAME("%s9", 25), + REG_DWARFNUM_NAME("%s10", 26), + REG_DWARFNUM_NAME("%s11", 27), + REG_DWARFNUM_NAME("%t3", 28), + REG_DWARFNUM_NAME("%t4", 29), + REG_DWARFNUM_NAME("%t5", 30), + REG_DWARFNUM_NAME("%t6", 31), + REG_DWARFNUM_END, +}; + +#define RISCV_MAX_REGS ((sizeof(riscv_dwarf_regs_table) / \ + sizeof(riscv_dwarf_regs_table[0])) - 1) + +const char *get_arch_regstr(unsigned int n) +{ + return (n < RISCV_MAX_REGS) ? riscv_dwarf_regs_table[n].name : NULL; +} + +int regs_query_register_offset(const char *name) +{ + const struct pt_regs_dwarfnum *roff; + + for (roff = riscv_dwarf_regs_table; roff->name; roff++) + if (!strcmp(roff->name, name)) + return roff->dwarfnum; + return -EINVAL; +} diff --git a/tools/perf/arch/riscv/util/unwind-libdw.c b/tools/perf/arch/riscv/util/unwind-libdw.c new file mode 100644 index 000000000000..19536e172850 --- /dev/null +++ b/tools/perf/arch/riscv/util/unwind-libdw.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */ + +#include +#include "../../util/unwind-libdw.h" +#include "../../util/perf_regs.h" +#include "../../util/event.h" + +bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) +{ + struct unwind_info *ui = arg; + struct regs_dump *user_regs = &ui->sample->user_regs; + Dwarf_Word dwarf_regs[32]; + +#define REG(r) ({ \ + Dwarf_Word val = 0; \ + perf_reg_value(&val, user_regs, PERF_REG_RISCV_##r); \ + val; \ +}) + + dwarf_regs[0] = 0; + dwarf_regs[1] = REG(RA); + dwarf_regs[2] = REG(SP); + dwarf_regs[3] = REG(GP); + dwarf_regs[4] = REG(TP); + dwarf_regs[5] = REG(T0); + dwarf_regs[6] = REG(T1); + dwarf_regs[7] = REG(T2); + dwarf_regs[8] = REG(S0); + dwarf_regs[9] = REG(S1); + dwarf_regs[10] = REG(A0); + dwarf_regs[11] = REG(A1); + dwarf_regs[12] = REG(A2); + dwarf_regs[13] = REG(A3); + dwarf_regs[14] = REG(A4); + dwarf_regs[15] = REG(A5); + dwarf_regs[16] = REG(A6); + dwarf_regs[17] = REG(A7); + dwarf_regs[18] = REG(S2); + dwarf_regs[19] = REG(S3); + dwarf_regs[20] = REG(S4); + dwarf_regs[21] = REG(S5); + dwarf_regs[22] = REG(S6); + dwarf_regs[23] = REG(S7); + dwarf_regs[24] = REG(S8); + dwarf_regs[25] = REG(S9); + dwarf_regs[26] = REG(S10); + dwarf_regs[27] = REG(S11); + dwarf_regs[28] = REG(T3); + dwarf_regs[29] = REG(T4); + dwarf_regs[30] = REG(T5); + dwarf_regs[31] = REG(T6); + dwfl_thread_state_register_pc(thread, REG(PC)); + + return dwfl_thread_state_registers(thread, 0, PERF_REG_RISCV_MAX, + dwarf_regs); +} -- cgit v1.2.3-59-g8ed1b From 91bfb564853f4aaa0487a2b5e9c6ecd400768abd Mon Sep 17 00:00:00 2001 From: David Ahern Date: Tue, 3 Sep 2019 15:22:13 -0700 Subject: selftest: A few cleanups for fib_nexthops.sh Cleanups of the tests in fib_nexthops.sh 1. Several tests noted unexpected route output, but the discrepancy was not showing in the summary output and overlooked in the verbose output. Add a WARNING message to the summary output to make it clear a test is not showing expected output. 2. Several check_* calls are missing extra data like scope and metric causing mismatches when the nexthops or routes are correct - some of them are a side effect of the evolving iproute2 command. Update the data to the expected output. 3. Several check_routes are checking for the wrong nexthop data, most likely a copy-paste-update error. 4. A couple of tests were re-using a nexthop id that already existed. Fix those to use a new id. Fixes: 6345266a9989 ("selftests: Add test cases for nexthop objects") Signed-off-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/fib_nexthops.sh | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh index c5c93d5fb3ad..f9ebeac1e6f2 100755 --- a/tools/testing/selftests/net/fib_nexthops.sh +++ b/tools/testing/selftests/net/fib_nexthops.sh @@ -212,6 +212,8 @@ check_output() printf " ${out}\n" printf " Expected:\n" printf " ${expected}\n\n" + else + echo " WARNING: Unexpected route entry" fi fi @@ -274,7 +276,7 @@ ipv6_fcnal() run_cmd "$IP nexthop get id 52" log_test $? 0 "Get nexthop by id" - check_nexthop "id 52" "id 52 via 2001:db8:91::2 dev veth1" + check_nexthop "id 52" "id 52 via 2001:db8:91::2 dev veth1 scope link" run_cmd "$IP nexthop del id 52" log_test $? 0 "Delete nexthop by id" @@ -479,12 +481,12 @@ ipv6_fcnal_runtime() run_cmd "$IP -6 nexthop add id 85 dev veth1" run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 85" log_test $? 0 "IPv6 route with device only nexthop" - check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 85 dev veth1" + check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 85 dev veth1 metric 1024 pref medium" run_cmd "$IP nexthop add id 123 group 81/85" run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 123" log_test $? 0 "IPv6 multipath route with nexthop mix - dev only + gw" - check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 85 nexthop via 2001:db8:91::2 dev veth1 nexthop dev veth1" + check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 123 metric 1024 nexthop via 2001:db8:91::2 dev veth1 weight 1 nexthop dev veth1 weight 1 pref medium" # # IPv6 route with v4 nexthop - not allowed @@ -538,7 +540,7 @@ ipv4_fcnal() run_cmd "$IP nexthop get id 12" log_test $? 0 "Get nexthop by id" - check_nexthop "id 12" "id 12 via 172.16.1.2 src 172.16.1.1 dev veth1 scope link" + check_nexthop "id 12" "id 12 via 172.16.1.2 dev veth1 scope link" run_cmd "$IP nexthop del id 12" log_test $? 0 "Delete nexthop by id" @@ -685,7 +687,7 @@ ipv4_withv6_fcnal() set +e run_cmd "$IP ro add 172.16.101.1/32 nhid 11" log_test $? 0 "IPv6 nexthop with IPv4 route" - check_route "172.16.101.1" "172.16.101.1 nhid 11 via ${lladdr} dev veth1" + check_route "172.16.101.1" "172.16.101.1 nhid 11 via inet6 ${lladdr} dev veth1" set -e run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1" @@ -694,11 +696,11 @@ ipv4_withv6_fcnal() run_cmd "$IP ro replace 172.16.101.1/32 nhid 101" log_test $? 0 "IPv6 nexthop with IPv4 route" - check_route "172.16.101.1" "172.16.101.1 nhid 101 nexthop via ${lladdr} dev veth1 weight 1 nexthop via 172.16.1.2 dev veth1 weight 1" + check_route "172.16.101.1" "172.16.101.1 nhid 101 nexthop via inet6 ${lladdr} dev veth1 weight 1 nexthop via 172.16.1.2 dev veth1 weight 1" run_cmd "$IP ro replace 172.16.101.1/32 via inet6 ${lladdr} dev veth1" log_test $? 0 "IPv4 route with IPv6 gateway" - check_route "172.16.101.1" "172.16.101.1 via ${lladdr} dev veth1" + check_route "172.16.101.1" "172.16.101.1 via inet6 ${lladdr} dev veth1" run_cmd "$IP ro replace 172.16.101.1/32 via inet6 2001:db8:50::1 dev veth1" log_test $? 2 "IPv4 route with invalid IPv6 gateway" @@ -785,10 +787,10 @@ ipv4_fcnal_runtime() log_test $? 0 "IPv4 route with device only nexthop" check_route "172.16.101.1" "172.16.101.1 nhid 85 dev veth1" - run_cmd "$IP nexthop add id 122 group 21/85" - run_cmd "$IP ro replace 172.16.101.1/32 nhid 122" + run_cmd "$IP nexthop add id 123 group 21/85" + run_cmd "$IP ro replace 172.16.101.1/32 nhid 123" log_test $? 0 "IPv4 multipath route with nexthop mix - dev only + gw" - check_route "172.16.101.1" "172.16.101.1 nhid 85 nexthop via 172.16.1.2 dev veth1 nexthop dev veth1" + check_route "172.16.101.1" "172.16.101.1 nhid 123 nexthop via 172.16.1.2 dev veth1 weight 1 nexthop dev veth1 weight 1" # # IPv4 with IPv6 @@ -820,7 +822,7 @@ ipv4_fcnal_runtime() run_cmd "$IP ro replace 172.16.101.1/32 nhid 101" log_test $? 0 "IPv4 route with mixed v4-v6 multipath route" - check_route "172.16.101.1" "172.16.101.1 nhid 101 nexthop via ${lladdr} dev veth1 weight 1 nexthop via 172.16.1.2 dev veth1 weight 1" + check_route "172.16.101.1" "172.16.101.1 nhid 101 nexthop via inet6 ${lladdr} dev veth1 weight 1 nexthop via 172.16.1.2 dev veth1 weight 1" run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" log_test $? 0 "IPv6 nexthop with IPv4 route" -- cgit v1.2.3-59-g8ed1b From 310f4204eeb6053e35c277a23d9c179e8e32322e Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Tue, 3 Sep 2019 15:51:33 -0700 Subject: selftests/bpf: precision tracking tests Add two tests to check that stack slot marking during backtracking doesn't trigger 'spi > allocated_stack' warning. One test is using BPF_ST insn. Another is using BPF_STX. Signed-off-by: Alexei Starovoitov Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/verifier/precise.c | 52 ++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/verifier/precise.c b/tools/testing/selftests/bpf/verifier/precise.c index a455a4a71f11..02151f8c940f 100644 --- a/tools/testing/selftests/bpf/verifier/precise.c +++ b/tools/testing/selftests/bpf/verifier/precise.c @@ -140,3 +140,55 @@ .errstr = "!read_ok", .result = REJECT, }, +{ + "precise: ST insn causing spi > allocated_stack", + .insns = { + BPF_MOV64_REG(BPF_REG_3, BPF_REG_10), + BPF_JMP_IMM(BPF_JNE, BPF_REG_3, 123, 0), + BPF_ST_MEM(BPF_DW, BPF_REG_3, -8, 0), + BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), + BPF_MOV64_IMM(BPF_REG_0, -1), + BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_XDP, + .flags = BPF_F_TEST_STATE_FREQ, + .errstr = "5: (2d) if r4 > r0 goto pc+0\ + last_idx 5 first_idx 5\ + parent didn't have regs=10 stack=0 marks\ + last_idx 4 first_idx 2\ + regs=10 stack=0 before 4\ + regs=10 stack=0 before 3\ + regs=0 stack=1 before 2\ + last_idx 5 first_idx 5\ + parent didn't have regs=1 stack=0 marks", + .result = VERBOSE_ACCEPT, + .retval = -1, +}, +{ + "precise: STX insn causing spi > allocated_stack", + .insns = { + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), + BPF_MOV64_REG(BPF_REG_3, BPF_REG_10), + BPF_JMP_IMM(BPF_JNE, BPF_REG_3, 123, 0), + BPF_STX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, -8), + BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), + BPF_MOV64_IMM(BPF_REG_0, -1), + BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_XDP, + .flags = BPF_F_TEST_STATE_FREQ, + .errstr = "last_idx 6 first_idx 6\ + parent didn't have regs=10 stack=0 marks\ + last_idx 5 first_idx 3\ + regs=10 stack=0 before 5\ + regs=10 stack=0 before 4\ + regs=0 stack=1 before 3\ + last_idx 6 first_idx 6\ + parent didn't have regs=1 stack=0 marks\ + last_idx 5 first_idx 3\ + regs=1 stack=0 before 5", + .result = VERBOSE_ACCEPT, + .retval = -1, +}, -- cgit v1.2.3-59-g8ed1b From 88dadc632763bdccddf99d8454aa3a7932605f00 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Wed, 4 Sep 2019 09:25:04 -0700 Subject: selftests/bpf: test_progs: add test__join_cgroup helper test__join_cgroup() combines the following operations that usually go hand in hand and returns cgroup fd: * setup cgroup environment (make sure cgroupfs is mounted) * mkdir cgroup * join cgroup It also marks a test as a "cgroup cleanup needed" and removes cgroup state after the test is done. Signed-off-by: Stanislav Fomichev Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/Makefile | 4 ++-- tools/testing/selftests/bpf/test_progs.c | 38 ++++++++++++++++++++++++++++++++ tools/testing/selftests/bpf/test_progs.h | 1 + 3 files changed, 41 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 9eef5edf17be..ce9650bad453 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -106,7 +106,7 @@ $(OUTPUT)/test_socket_cookie: cgroup_helpers.c $(OUTPUT)/test_sockmap: cgroup_helpers.c $(OUTPUT)/test_tcpbpf_user: cgroup_helpers.c $(OUTPUT)/test_tcpnotify_user: cgroup_helpers.c trace_helpers.c -$(OUTPUT)/test_progs: trace_helpers.c +$(OUTPUT)/test_progs: cgroup_helpers.c trace_helpers.c $(OUTPUT)/get_cgroup_id_user: cgroup_helpers.c $(OUTPUT)/test_cgroup_storage: cgroup_helpers.c $(OUTPUT)/test_netcnt: cgroup_helpers.c @@ -200,7 +200,7 @@ $(ALU32_BUILD_DIR)/test_progs_32: test_progs.c $(OUTPUT)/libbpf.a\ | $(ALU32_BUILD_DIR) $(CC) $(TEST_PROGS_CFLAGS) $(CFLAGS) \ -o $(ALU32_BUILD_DIR)/test_progs_32 \ - test_progs.c test_stub.c trace_helpers.c prog_tests/*.c \ + test_progs.c test_stub.c cgroup_helpers.c trace_helpers.c prog_tests/*.c \ $(OUTPUT)/libbpf.a $(LDLIBS) $(ALU32_BUILD_DIR)/test_progs_32: $(PROG_TESTS_H) diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index e8616e778cb5..af75a1c7a458 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -2,6 +2,7 @@ /* Copyright (c) 2017 Facebook */ #include "test_progs.h" +#include "cgroup_helpers.h" #include "bpf_rlimit.h" #include #include @@ -17,6 +18,7 @@ struct prog_test_def { int error_cnt; int skip_cnt; bool tested; + bool need_cgroup_cleanup; const char *subtest_name; int subtest_num; @@ -122,6 +124,39 @@ void test__fail(void) env.test->error_cnt++; } +int test__join_cgroup(const char *path) +{ + int fd; + + if (!env.test->need_cgroup_cleanup) { + if (setup_cgroup_environment()) { + fprintf(stderr, + "#%d %s: Failed to setup cgroup environment\n", + env.test->test_num, env.test->test_name); + return -1; + } + + env.test->need_cgroup_cleanup = true; + } + + fd = create_and_get_cgroup(path); + if (fd < 0) { + fprintf(stderr, + "#%d %s: Failed to create cgroup '%s' (errno=%d)\n", + env.test->test_num, env.test->test_name, path, errno); + return fd; + } + + if (join_cgroup(path)) { + fprintf(stderr, + "#%d %s: Failed to join cgroup '%s' (errno=%d)\n", + env.test->test_num, env.test->test_name, path, errno); + return -1; + } + + return fd; +} + struct ipv4_packet pkt_v4 = { .eth.h_proto = __bpf_constant_htons(ETH_P_IP), .iph.ihl = 5, @@ -530,6 +565,9 @@ int main(int argc, char **argv) fprintf(env.stdout, "#%d %s:%s\n", test->test_num, test->test_name, test->error_cnt ? "FAIL" : "OK"); + + if (test->need_cgroup_cleanup) + cleanup_cgroup_environment(); } stdio_restore(); printf("Summary: %d/%d PASSED, %d SKIPPED, %d FAILED\n", diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h index c8edb9464ba6..e518bd5da3e2 100644 --- a/tools/testing/selftests/bpf/test_progs.h +++ b/tools/testing/selftests/bpf/test_progs.h @@ -71,6 +71,7 @@ extern void test__force_log(); extern bool test__start_subtest(const char *name); extern void test__skip(void); extern void test__fail(void); +extern int test__join_cgroup(const char *path); #define MAGIC_BYTES 123 -- cgit v1.2.3-59-g8ed1b From 4a64742168ce9e9972dab3f684629845c6e6dc67 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Wed, 4 Sep 2019 09:25:05 -0700 Subject: selftests/bpf: test_progs: convert test_sockopt Move the files, adjust includes, remove entry from Makefile & .gitignore Signed-off-by: Stanislav Fomichev Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/.gitignore | 1 - tools/testing/selftests/bpf/Makefile | 3 +- tools/testing/selftests/bpf/prog_tests/sockopt.c | 985 +++++++++++++++++++++ tools/testing/selftests/bpf/test_sockopt.c | 1021 ---------------------- 4 files changed, 986 insertions(+), 1024 deletions(-) create mode 100644 tools/testing/selftests/bpf/prog_tests/sockopt.c delete mode 100644 tools/testing/selftests/bpf/test_sockopt.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore index 60c9338cd9b4..0315120eac8f 100644 --- a/tools/testing/selftests/bpf/.gitignore +++ b/tools/testing/selftests/bpf/.gitignore @@ -39,7 +39,6 @@ libbpf.so.* test_hashmap test_btf_dump xdping -test_sockopt test_sockopt_sk test_sockopt_multi test_sockopt_inherit diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index ce9650bad453..7151cbc4676e 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -28,7 +28,7 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test test_sock test_btf test_sockmap get_cgroup_id_user test_socket_cookie \ test_cgroup_storage test_select_reuseport test_section_names \ test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap \ - test_btf_dump test_cgroup_attach xdping test_sockopt test_sockopt_sk \ + test_btf_dump test_cgroup_attach xdping test_sockopt_sk \ test_sockopt_multi test_sockopt_inherit test_tcp_rtt BPF_OBJ_FILES = $(patsubst %.c,%.o, $(notdir $(wildcard progs/*.c))) @@ -113,7 +113,6 @@ $(OUTPUT)/test_netcnt: cgroup_helpers.c $(OUTPUT)/test_sock_fields: cgroup_helpers.c $(OUTPUT)/test_sysctl: cgroup_helpers.c $(OUTPUT)/test_cgroup_attach: cgroup_helpers.c -$(OUTPUT)/test_sockopt: cgroup_helpers.c $(OUTPUT)/test_sockopt_sk: cgroup_helpers.c $(OUTPUT)/test_sockopt_multi: cgroup_helpers.c $(OUTPUT)/test_sockopt_inherit: cgroup_helpers.c diff --git a/tools/testing/selftests/bpf/prog_tests/sockopt.c b/tools/testing/selftests/bpf/prog_tests/sockopt.c new file mode 100644 index 000000000000..3e8517a8395a --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/sockopt.c @@ -0,0 +1,985 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include "cgroup_helpers.h" + +static char bpf_log_buf[4096]; +static bool verbose; + +enum sockopt_test_error { + OK = 0, + DENY_LOAD, + DENY_ATTACH, + EPERM_GETSOCKOPT, + EFAULT_GETSOCKOPT, + EPERM_SETSOCKOPT, + EFAULT_SETSOCKOPT, +}; + +static struct sockopt_test { + const char *descr; + const struct bpf_insn insns[64]; + enum bpf_attach_type attach_type; + enum bpf_attach_type expected_attach_type; + + int set_optname; + int set_level; + const char set_optval[64]; + socklen_t set_optlen; + + int get_optname; + int get_level; + const char get_optval[64]; + socklen_t get_optlen; + socklen_t get_optlen_ret; + + enum sockopt_test_error error; +} tests[] = { + + /* ==================== getsockopt ==================== */ + + { + .descr = "getsockopt: no expected_attach_type", + .insns = { + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = 0, + .error = DENY_LOAD, + }, + { + .descr = "getsockopt: wrong expected_attach_type", + .insns = { + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + .error = DENY_ATTACH, + }, + { + .descr = "getsockopt: bypass bpf hook", + .insns = { + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + + .get_level = SOL_IP, + .set_level = SOL_IP, + + .get_optname = IP_TOS, + .set_optname = IP_TOS, + + .set_optval = { 1 << 3 }, + .set_optlen = 1, + + .get_optval = { 1 << 3 }, + .get_optlen = 1, + }, + { + .descr = "getsockopt: return EPERM from bpf hook", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + + .get_level = SOL_IP, + .get_optname = IP_TOS, + + .get_optlen = 1, + .error = EPERM_GETSOCKOPT, + }, + { + .descr = "getsockopt: no optval bounds check, deny loading", + .insns = { + /* r6 = ctx->optval */ + BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, optval)), + + /* ctx->optval[0] = 0x80 */ + BPF_MOV64_IMM(BPF_REG_0, 0x80), + BPF_STX_MEM(BPF_W, BPF_REG_6, BPF_REG_0, 0), + + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + .error = DENY_LOAD, + }, + { + .descr = "getsockopt: read ctx->level", + .insns = { + /* r6 = ctx->level */ + BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, level)), + + /* if (ctx->level == 123) { */ + BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 123, 4), + /* ctx->retval = 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, retval)), + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_JMP_A(1), + /* } else { */ + /* return 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), + /* } */ + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + + .get_level = 123, + + .get_optlen = 1, + }, + { + .descr = "getsockopt: deny writing to ctx->level", + .insns = { + /* ctx->level = 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, level)), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + + .error = DENY_LOAD, + }, + { + .descr = "getsockopt: read ctx->optname", + .insns = { + /* r6 = ctx->optname */ + BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, optname)), + + /* if (ctx->optname == 123) { */ + BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 123, 4), + /* ctx->retval = 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, retval)), + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_JMP_A(1), + /* } else { */ + /* return 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), + /* } */ + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + + .get_optname = 123, + + .get_optlen = 1, + }, + { + .descr = "getsockopt: read ctx->retval", + .insns = { + /* r6 = ctx->retval */ + BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, retval)), + + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + + .get_level = SOL_IP, + .get_optname = IP_TOS, + .get_optlen = 1, + }, + { + .descr = "getsockopt: deny writing to ctx->optname", + .insns = { + /* ctx->optname = 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, optname)), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + + .error = DENY_LOAD, + }, + { + .descr = "getsockopt: read ctx->optlen", + .insns = { + /* r6 = ctx->optlen */ + BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, optlen)), + + /* if (ctx->optlen == 64) { */ + BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 64, 4), + /* ctx->retval = 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, retval)), + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_JMP_A(1), + /* } else { */ + /* return 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), + /* } */ + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + + .get_optlen = 64, + }, + { + .descr = "getsockopt: deny bigger ctx->optlen", + .insns = { + /* ctx->optlen = 65 */ + BPF_MOV64_IMM(BPF_REG_0, 65), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, optlen)), + + /* ctx->retval = 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, retval)), + + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + + .get_optlen = 64, + + .error = EFAULT_GETSOCKOPT, + }, + { + .descr = "getsockopt: deny arbitrary ctx->retval", + .insns = { + /* ctx->retval = 123 */ + BPF_MOV64_IMM(BPF_REG_0, 123), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, retval)), + + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + + .get_optlen = 64, + + .error = EFAULT_GETSOCKOPT, + }, + { + .descr = "getsockopt: support smaller ctx->optlen", + .insns = { + /* ctx->optlen = 32 */ + BPF_MOV64_IMM(BPF_REG_0, 32), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, optlen)), + /* ctx->retval = 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, retval)), + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + + .get_optlen = 64, + .get_optlen_ret = 32, + }, + { + .descr = "getsockopt: deny writing to ctx->optval", + .insns = { + /* ctx->optval = 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, optval)), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + + .error = DENY_LOAD, + }, + { + .descr = "getsockopt: deny writing to ctx->optval_end", + .insns = { + /* ctx->optval_end = 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, optval_end)), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + + .error = DENY_LOAD, + }, + { + .descr = "getsockopt: rewrite value", + .insns = { + /* r6 = ctx->optval */ + BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, optval)), + /* r2 = ctx->optval */ + BPF_MOV64_REG(BPF_REG_2, BPF_REG_6), + /* r6 = ctx->optval + 1 */ + BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1), + + /* r7 = ctx->optval_end */ + BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_1, + offsetof(struct bpf_sockopt, optval_end)), + + /* if (ctx->optval + 1 <= ctx->optval_end) { */ + BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 1), + /* ctx->optval[0] = 0xF0 */ + BPF_ST_MEM(BPF_B, BPF_REG_2, 0, 0xF0), + /* } */ + + /* ctx->retval = 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, retval)), + + /* return 1*/ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + + .get_level = SOL_IP, + .get_optname = IP_TOS, + + .get_optval = { 0xF0 }, + .get_optlen = 1, + }, + + /* ==================== setsockopt ==================== */ + + { + .descr = "setsockopt: no expected_attach_type", + .insns = { + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = 0, + .error = DENY_LOAD, + }, + { + .descr = "setsockopt: wrong expected_attach_type", + .insns = { + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + .error = DENY_ATTACH, + }, + { + .descr = "setsockopt: bypass bpf hook", + .insns = { + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .get_level = SOL_IP, + .set_level = SOL_IP, + + .get_optname = IP_TOS, + .set_optname = IP_TOS, + + .set_optval = { 1 << 3 }, + .set_optlen = 1, + + .get_optval = { 1 << 3 }, + .get_optlen = 1, + }, + { + .descr = "setsockopt: return EPERM from bpf hook", + .insns = { + /* return 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .set_level = SOL_IP, + .set_optname = IP_TOS, + + .set_optlen = 1, + .error = EPERM_SETSOCKOPT, + }, + { + .descr = "setsockopt: no optval bounds check, deny loading", + .insns = { + /* r6 = ctx->optval */ + BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, optval)), + + /* r0 = ctx->optval[0] */ + BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, 0), + + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + .error = DENY_LOAD, + }, + { + .descr = "setsockopt: read ctx->level", + .insns = { + /* r6 = ctx->level */ + BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, level)), + + /* if (ctx->level == 123) { */ + BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 123, 4), + /* ctx->optlen = -1 */ + BPF_MOV64_IMM(BPF_REG_0, -1), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, optlen)), + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_JMP_A(1), + /* } else { */ + /* return 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), + /* } */ + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .set_level = 123, + + .set_optlen = 1, + }, + { + .descr = "setsockopt: allow changing ctx->level", + .insns = { + /* ctx->level = SOL_IP */ + BPF_MOV64_IMM(BPF_REG_0, SOL_IP), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, level)), + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .get_level = SOL_IP, + .set_level = 234, /* should be rewritten to SOL_IP */ + + .get_optname = IP_TOS, + .set_optname = IP_TOS, + + .set_optval = { 1 << 3 }, + .set_optlen = 1, + .get_optval = { 1 << 3 }, + .get_optlen = 1, + }, + { + .descr = "setsockopt: read ctx->optname", + .insns = { + /* r6 = ctx->optname */ + BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, optname)), + + /* if (ctx->optname == 123) { */ + BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 123, 4), + /* ctx->optlen = -1 */ + BPF_MOV64_IMM(BPF_REG_0, -1), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, optlen)), + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_JMP_A(1), + /* } else { */ + /* return 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), + /* } */ + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .set_optname = 123, + + .set_optlen = 1, + }, + { + .descr = "setsockopt: allow changing ctx->optname", + .insns = { + /* ctx->optname = IP_TOS */ + BPF_MOV64_IMM(BPF_REG_0, IP_TOS), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, optname)), + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .get_level = SOL_IP, + .set_level = SOL_IP, + + .get_optname = IP_TOS, + .set_optname = 456, /* should be rewritten to IP_TOS */ + + .set_optval = { 1 << 3 }, + .set_optlen = 1, + .get_optval = { 1 << 3 }, + .get_optlen = 1, + }, + { + .descr = "setsockopt: read ctx->optlen", + .insns = { + /* r6 = ctx->optlen */ + BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, optlen)), + + /* if (ctx->optlen == 64) { */ + BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 64, 4), + /* ctx->optlen = -1 */ + BPF_MOV64_IMM(BPF_REG_0, -1), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, optlen)), + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_JMP_A(1), + /* } else { */ + /* return 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), + /* } */ + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .set_optlen = 64, + }, + { + .descr = "setsockopt: ctx->optlen == -1 is ok", + .insns = { + /* ctx->optlen = -1 */ + BPF_MOV64_IMM(BPF_REG_0, -1), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, optlen)), + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .set_optlen = 64, + }, + { + .descr = "setsockopt: deny ctx->optlen < 0 (except -1)", + .insns = { + /* ctx->optlen = -2 */ + BPF_MOV64_IMM(BPF_REG_0, -2), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, optlen)), + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .set_optlen = 4, + + .error = EFAULT_SETSOCKOPT, + }, + { + .descr = "setsockopt: deny ctx->optlen > input optlen", + .insns = { + /* ctx->optlen = 65 */ + BPF_MOV64_IMM(BPF_REG_0, 65), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, optlen)), + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .set_optlen = 64, + + .error = EFAULT_SETSOCKOPT, + }, + { + .descr = "setsockopt: allow changing ctx->optlen within bounds", + .insns = { + /* r6 = ctx->optval */ + BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, optval)), + /* r2 = ctx->optval */ + BPF_MOV64_REG(BPF_REG_2, BPF_REG_6), + /* r6 = ctx->optval + 1 */ + BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1), + + /* r7 = ctx->optval_end */ + BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_1, + offsetof(struct bpf_sockopt, optval_end)), + + /* if (ctx->optval + 1 <= ctx->optval_end) { */ + BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 1), + /* ctx->optval[0] = 1 << 3 */ + BPF_ST_MEM(BPF_B, BPF_REG_2, 0, 1 << 3), + /* } */ + + /* ctx->optlen = 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, optlen)), + + /* return 1*/ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .get_level = SOL_IP, + .set_level = SOL_IP, + + .get_optname = IP_TOS, + .set_optname = IP_TOS, + + .set_optval = { 1, 1, 1, 1 }, + .set_optlen = 4, + .get_optval = { 1 << 3 }, + .get_optlen = 1, + }, + { + .descr = "setsockopt: deny write ctx->retval", + .insns = { + /* ctx->retval = 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, retval)), + + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .error = DENY_LOAD, + }, + { + .descr = "setsockopt: deny read ctx->retval", + .insns = { + /* r6 = ctx->retval */ + BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, retval)), + + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .error = DENY_LOAD, + }, + { + .descr = "setsockopt: deny writing to ctx->optval", + .insns = { + /* ctx->optval = 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, optval)), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .error = DENY_LOAD, + }, + { + .descr = "setsockopt: deny writing to ctx->optval_end", + .insns = { + /* ctx->optval_end = 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, optval_end)), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .error = DENY_LOAD, + }, + { + .descr = "setsockopt: allow IP_TOS <= 128", + .insns = { + /* r6 = ctx->optval */ + BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, optval)), + /* r7 = ctx->optval + 1 */ + BPF_MOV64_REG(BPF_REG_7, BPF_REG_6), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 1), + + /* r8 = ctx->optval_end */ + BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_1, + offsetof(struct bpf_sockopt, optval_end)), + + /* if (ctx->optval + 1 <= ctx->optval_end) { */ + BPF_JMP_REG(BPF_JGT, BPF_REG_7, BPF_REG_8, 4), + + /* r9 = ctx->optval[0] */ + BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_6, 0), + + /* if (ctx->optval[0] < 128) */ + BPF_JMP_IMM(BPF_JGT, BPF_REG_9, 128, 2), + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_JMP_A(1), + /* } */ + + /* } else { */ + BPF_MOV64_IMM(BPF_REG_0, 0), + /* } */ + + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .get_level = SOL_IP, + .set_level = SOL_IP, + + .get_optname = IP_TOS, + .set_optname = IP_TOS, + + .set_optval = { 0x80 }, + .set_optlen = 1, + .get_optval = { 0x80 }, + .get_optlen = 1, + }, + { + .descr = "setsockopt: deny IP_TOS > 128", + .insns = { + /* r6 = ctx->optval */ + BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, optval)), + /* r7 = ctx->optval + 1 */ + BPF_MOV64_REG(BPF_REG_7, BPF_REG_6), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 1), + + /* r8 = ctx->optval_end */ + BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_1, + offsetof(struct bpf_sockopt, optval_end)), + + /* if (ctx->optval + 1 <= ctx->optval_end) { */ + BPF_JMP_REG(BPF_JGT, BPF_REG_7, BPF_REG_8, 4), + + /* r9 = ctx->optval[0] */ + BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_6, 0), + + /* if (ctx->optval[0] < 128) */ + BPF_JMP_IMM(BPF_JGT, BPF_REG_9, 128, 2), + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_JMP_A(1), + /* } */ + + /* } else { */ + BPF_MOV64_IMM(BPF_REG_0, 0), + /* } */ + + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .get_level = SOL_IP, + .set_level = SOL_IP, + + .get_optname = IP_TOS, + .set_optname = IP_TOS, + + .set_optval = { 0x81 }, + .set_optlen = 1, + .get_optval = { 0x00 }, + .get_optlen = 1, + + .error = EPERM_SETSOCKOPT, + }, +}; + +static int load_prog(const struct bpf_insn *insns, + enum bpf_attach_type expected_attach_type) +{ + struct bpf_load_program_attr attr = { + .prog_type = BPF_PROG_TYPE_CGROUP_SOCKOPT, + .expected_attach_type = expected_attach_type, + .insns = insns, + .license = "GPL", + .log_level = 2, + }; + int fd; + + for (; + insns[attr.insns_cnt].code != (BPF_JMP | BPF_EXIT); + attr.insns_cnt++) { + } + attr.insns_cnt++; + + fd = bpf_load_program_xattr(&attr, bpf_log_buf, sizeof(bpf_log_buf)); + if (verbose && fd < 0) + fprintf(stderr, "%s\n", bpf_log_buf); + + return fd; +} + +static int run_test(int cgroup_fd, struct sockopt_test *test) +{ + int sock_fd, err, prog_fd; + void *optval = NULL; + int ret = 0; + + prog_fd = load_prog(test->insns, test->expected_attach_type); + if (prog_fd < 0) { + if (test->error == DENY_LOAD) + return 0; + + log_err("Failed to load BPF program"); + return -1; + } + + err = bpf_prog_attach(prog_fd, cgroup_fd, test->attach_type, 0); + if (err < 0) { + if (test->error == DENY_ATTACH) + goto close_prog_fd; + + log_err("Failed to attach BPF program"); + ret = -1; + goto close_prog_fd; + } + + sock_fd = socket(AF_INET, SOCK_STREAM, 0); + if (sock_fd < 0) { + log_err("Failed to create AF_INET socket"); + ret = -1; + goto detach_prog; + } + + if (test->set_optlen) { + err = setsockopt(sock_fd, test->set_level, test->set_optname, + test->set_optval, test->set_optlen); + if (err) { + if (errno == EPERM && test->error == EPERM_SETSOCKOPT) + goto close_sock_fd; + if (errno == EFAULT && test->error == EFAULT_SETSOCKOPT) + goto free_optval; + + log_err("Failed to call setsockopt"); + ret = -1; + goto close_sock_fd; + } + } + + if (test->get_optlen) { + optval = malloc(test->get_optlen); + socklen_t optlen = test->get_optlen; + socklen_t expected_get_optlen = test->get_optlen_ret ?: + test->get_optlen; + + err = getsockopt(sock_fd, test->get_level, test->get_optname, + optval, &optlen); + if (err) { + if (errno == EPERM && test->error == EPERM_GETSOCKOPT) + goto free_optval; + if (errno == EFAULT && test->error == EFAULT_GETSOCKOPT) + goto free_optval; + + log_err("Failed to call getsockopt"); + ret = -1; + goto free_optval; + } + + if (optlen != expected_get_optlen) { + errno = 0; + log_err("getsockopt returned unexpected optlen"); + ret = -1; + goto free_optval; + } + + if (memcmp(optval, test->get_optval, optlen) != 0) { + errno = 0; + log_err("getsockopt returned unexpected optval"); + ret = -1; + goto free_optval; + } + } + + ret = test->error != OK; + +free_optval: + free(optval); +close_sock_fd: + close(sock_fd); +detach_prog: + bpf_prog_detach2(prog_fd, cgroup_fd, test->attach_type); +close_prog_fd: + close(prog_fd); + return ret; +} + +void test_sockopt(void) +{ + int cgroup_fd, i; + + cgroup_fd = test__join_cgroup("/sockopt"); + if (CHECK_FAIL(cgroup_fd < 0)) + return; + + for (i = 0; i < ARRAY_SIZE(tests); i++) { + test__start_subtest(tests[i].descr); + CHECK_FAIL(run_test(cgroup_fd, &tests[i])); + } + + close(cgroup_fd); +} diff --git a/tools/testing/selftests/bpf/test_sockopt.c b/tools/testing/selftests/bpf/test_sockopt.c deleted file mode 100644 index 23bd0819382d..000000000000 --- a/tools/testing/selftests/bpf/test_sockopt.c +++ /dev/null @@ -1,1021 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "bpf_rlimit.h" -#include "bpf_util.h" -#include "cgroup_helpers.h" - -#define CG_PATH "/sockopt" - -static char bpf_log_buf[4096]; -static bool verbose; - -enum sockopt_test_error { - OK = 0, - DENY_LOAD, - DENY_ATTACH, - EPERM_GETSOCKOPT, - EFAULT_GETSOCKOPT, - EPERM_SETSOCKOPT, - EFAULT_SETSOCKOPT, -}; - -static struct sockopt_test { - const char *descr; - const struct bpf_insn insns[64]; - enum bpf_attach_type attach_type; - enum bpf_attach_type expected_attach_type; - - int set_optname; - int set_level; - const char set_optval[64]; - socklen_t set_optlen; - - int get_optname; - int get_level; - const char get_optval[64]; - socklen_t get_optlen; - socklen_t get_optlen_ret; - - enum sockopt_test_error error; -} tests[] = { - - /* ==================== getsockopt ==================== */ - - { - .descr = "getsockopt: no expected_attach_type", - .insns = { - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - - }, - .attach_type = BPF_CGROUP_GETSOCKOPT, - .expected_attach_type = 0, - .error = DENY_LOAD, - }, - { - .descr = "getsockopt: wrong expected_attach_type", - .insns = { - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - - }, - .attach_type = BPF_CGROUP_GETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - .error = DENY_ATTACH, - }, - { - .descr = "getsockopt: bypass bpf hook", - .insns = { - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_GETSOCKOPT, - .expected_attach_type = BPF_CGROUP_GETSOCKOPT, - - .get_level = SOL_IP, - .set_level = SOL_IP, - - .get_optname = IP_TOS, - .set_optname = IP_TOS, - - .set_optval = { 1 << 3 }, - .set_optlen = 1, - - .get_optval = { 1 << 3 }, - .get_optlen = 1, - }, - { - .descr = "getsockopt: return EPERM from bpf hook", - .insns = { - BPF_MOV64_IMM(BPF_REG_0, 0), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_GETSOCKOPT, - .expected_attach_type = BPF_CGROUP_GETSOCKOPT, - - .get_level = SOL_IP, - .get_optname = IP_TOS, - - .get_optlen = 1, - .error = EPERM_GETSOCKOPT, - }, - { - .descr = "getsockopt: no optval bounds check, deny loading", - .insns = { - /* r6 = ctx->optval */ - BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, - offsetof(struct bpf_sockopt, optval)), - - /* ctx->optval[0] = 0x80 */ - BPF_MOV64_IMM(BPF_REG_0, 0x80), - BPF_STX_MEM(BPF_W, BPF_REG_6, BPF_REG_0, 0), - - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_GETSOCKOPT, - .expected_attach_type = BPF_CGROUP_GETSOCKOPT, - .error = DENY_LOAD, - }, - { - .descr = "getsockopt: read ctx->level", - .insns = { - /* r6 = ctx->level */ - BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, - offsetof(struct bpf_sockopt, level)), - - /* if (ctx->level == 123) { */ - BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 123, 4), - /* ctx->retval = 0 */ - BPF_MOV64_IMM(BPF_REG_0, 0), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, retval)), - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_JMP_A(1), - /* } else { */ - /* return 0 */ - BPF_MOV64_IMM(BPF_REG_0, 0), - /* } */ - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_GETSOCKOPT, - .expected_attach_type = BPF_CGROUP_GETSOCKOPT, - - .get_level = 123, - - .get_optlen = 1, - }, - { - .descr = "getsockopt: deny writing to ctx->level", - .insns = { - /* ctx->level = 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, level)), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_GETSOCKOPT, - .expected_attach_type = BPF_CGROUP_GETSOCKOPT, - - .error = DENY_LOAD, - }, - { - .descr = "getsockopt: read ctx->optname", - .insns = { - /* r6 = ctx->optname */ - BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, - offsetof(struct bpf_sockopt, optname)), - - /* if (ctx->optname == 123) { */ - BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 123, 4), - /* ctx->retval = 0 */ - BPF_MOV64_IMM(BPF_REG_0, 0), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, retval)), - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_JMP_A(1), - /* } else { */ - /* return 0 */ - BPF_MOV64_IMM(BPF_REG_0, 0), - /* } */ - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_GETSOCKOPT, - .expected_attach_type = BPF_CGROUP_GETSOCKOPT, - - .get_optname = 123, - - .get_optlen = 1, - }, - { - .descr = "getsockopt: read ctx->retval", - .insns = { - /* r6 = ctx->retval */ - BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, - offsetof(struct bpf_sockopt, retval)), - - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_GETSOCKOPT, - .expected_attach_type = BPF_CGROUP_GETSOCKOPT, - - .get_level = SOL_IP, - .get_optname = IP_TOS, - .get_optlen = 1, - }, - { - .descr = "getsockopt: deny writing to ctx->optname", - .insns = { - /* ctx->optname = 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, optname)), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_GETSOCKOPT, - .expected_attach_type = BPF_CGROUP_GETSOCKOPT, - - .error = DENY_LOAD, - }, - { - .descr = "getsockopt: read ctx->optlen", - .insns = { - /* r6 = ctx->optlen */ - BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, - offsetof(struct bpf_sockopt, optlen)), - - /* if (ctx->optlen == 64) { */ - BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 64, 4), - /* ctx->retval = 0 */ - BPF_MOV64_IMM(BPF_REG_0, 0), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, retval)), - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_JMP_A(1), - /* } else { */ - /* return 0 */ - BPF_MOV64_IMM(BPF_REG_0, 0), - /* } */ - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_GETSOCKOPT, - .expected_attach_type = BPF_CGROUP_GETSOCKOPT, - - .get_optlen = 64, - }, - { - .descr = "getsockopt: deny bigger ctx->optlen", - .insns = { - /* ctx->optlen = 65 */ - BPF_MOV64_IMM(BPF_REG_0, 65), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, optlen)), - - /* ctx->retval = 0 */ - BPF_MOV64_IMM(BPF_REG_0, 0), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, retval)), - - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_GETSOCKOPT, - .expected_attach_type = BPF_CGROUP_GETSOCKOPT, - - .get_optlen = 64, - - .error = EFAULT_GETSOCKOPT, - }, - { - .descr = "getsockopt: deny arbitrary ctx->retval", - .insns = { - /* ctx->retval = 123 */ - BPF_MOV64_IMM(BPF_REG_0, 123), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, retval)), - - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_GETSOCKOPT, - .expected_attach_type = BPF_CGROUP_GETSOCKOPT, - - .get_optlen = 64, - - .error = EFAULT_GETSOCKOPT, - }, - { - .descr = "getsockopt: support smaller ctx->optlen", - .insns = { - /* ctx->optlen = 32 */ - BPF_MOV64_IMM(BPF_REG_0, 32), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, optlen)), - /* ctx->retval = 0 */ - BPF_MOV64_IMM(BPF_REG_0, 0), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, retval)), - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_GETSOCKOPT, - .expected_attach_type = BPF_CGROUP_GETSOCKOPT, - - .get_optlen = 64, - .get_optlen_ret = 32, - }, - { - .descr = "getsockopt: deny writing to ctx->optval", - .insns = { - /* ctx->optval = 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, optval)), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_GETSOCKOPT, - .expected_attach_type = BPF_CGROUP_GETSOCKOPT, - - .error = DENY_LOAD, - }, - { - .descr = "getsockopt: deny writing to ctx->optval_end", - .insns = { - /* ctx->optval_end = 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, optval_end)), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_GETSOCKOPT, - .expected_attach_type = BPF_CGROUP_GETSOCKOPT, - - .error = DENY_LOAD, - }, - { - .descr = "getsockopt: rewrite value", - .insns = { - /* r6 = ctx->optval */ - BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, - offsetof(struct bpf_sockopt, optval)), - /* r2 = ctx->optval */ - BPF_MOV64_REG(BPF_REG_2, BPF_REG_6), - /* r6 = ctx->optval + 1 */ - BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1), - - /* r7 = ctx->optval_end */ - BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_1, - offsetof(struct bpf_sockopt, optval_end)), - - /* if (ctx->optval + 1 <= ctx->optval_end) { */ - BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 1), - /* ctx->optval[0] = 0xF0 */ - BPF_ST_MEM(BPF_B, BPF_REG_2, 0, 0xF0), - /* } */ - - /* ctx->retval = 0 */ - BPF_MOV64_IMM(BPF_REG_0, 0), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, retval)), - - /* return 1*/ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_GETSOCKOPT, - .expected_attach_type = BPF_CGROUP_GETSOCKOPT, - - .get_level = SOL_IP, - .get_optname = IP_TOS, - - .get_optval = { 0xF0 }, - .get_optlen = 1, - }, - - /* ==================== setsockopt ==================== */ - - { - .descr = "setsockopt: no expected_attach_type", - .insns = { - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = 0, - .error = DENY_LOAD, - }, - { - .descr = "setsockopt: wrong expected_attach_type", - .insns = { - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_GETSOCKOPT, - .error = DENY_ATTACH, - }, - { - .descr = "setsockopt: bypass bpf hook", - .insns = { - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - - .get_level = SOL_IP, - .set_level = SOL_IP, - - .get_optname = IP_TOS, - .set_optname = IP_TOS, - - .set_optval = { 1 << 3 }, - .set_optlen = 1, - - .get_optval = { 1 << 3 }, - .get_optlen = 1, - }, - { - .descr = "setsockopt: return EPERM from bpf hook", - .insns = { - /* return 0 */ - BPF_MOV64_IMM(BPF_REG_0, 0), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - - .set_level = SOL_IP, - .set_optname = IP_TOS, - - .set_optlen = 1, - .error = EPERM_SETSOCKOPT, - }, - { - .descr = "setsockopt: no optval bounds check, deny loading", - .insns = { - /* r6 = ctx->optval */ - BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, - offsetof(struct bpf_sockopt, optval)), - - /* r0 = ctx->optval[0] */ - BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, 0), - - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - .error = DENY_LOAD, - }, - { - .descr = "setsockopt: read ctx->level", - .insns = { - /* r6 = ctx->level */ - BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, - offsetof(struct bpf_sockopt, level)), - - /* if (ctx->level == 123) { */ - BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 123, 4), - /* ctx->optlen = -1 */ - BPF_MOV64_IMM(BPF_REG_0, -1), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, optlen)), - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_JMP_A(1), - /* } else { */ - /* return 0 */ - BPF_MOV64_IMM(BPF_REG_0, 0), - /* } */ - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - - .set_level = 123, - - .set_optlen = 1, - }, - { - .descr = "setsockopt: allow changing ctx->level", - .insns = { - /* ctx->level = SOL_IP */ - BPF_MOV64_IMM(BPF_REG_0, SOL_IP), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, level)), - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - - .get_level = SOL_IP, - .set_level = 234, /* should be rewritten to SOL_IP */ - - .get_optname = IP_TOS, - .set_optname = IP_TOS, - - .set_optval = { 1 << 3 }, - .set_optlen = 1, - .get_optval = { 1 << 3 }, - .get_optlen = 1, - }, - { - .descr = "setsockopt: read ctx->optname", - .insns = { - /* r6 = ctx->optname */ - BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, - offsetof(struct bpf_sockopt, optname)), - - /* if (ctx->optname == 123) { */ - BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 123, 4), - /* ctx->optlen = -1 */ - BPF_MOV64_IMM(BPF_REG_0, -1), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, optlen)), - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_JMP_A(1), - /* } else { */ - /* return 0 */ - BPF_MOV64_IMM(BPF_REG_0, 0), - /* } */ - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - - .set_optname = 123, - - .set_optlen = 1, - }, - { - .descr = "setsockopt: allow changing ctx->optname", - .insns = { - /* ctx->optname = IP_TOS */ - BPF_MOV64_IMM(BPF_REG_0, IP_TOS), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, optname)), - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - - .get_level = SOL_IP, - .set_level = SOL_IP, - - .get_optname = IP_TOS, - .set_optname = 456, /* should be rewritten to IP_TOS */ - - .set_optval = { 1 << 3 }, - .set_optlen = 1, - .get_optval = { 1 << 3 }, - .get_optlen = 1, - }, - { - .descr = "setsockopt: read ctx->optlen", - .insns = { - /* r6 = ctx->optlen */ - BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, - offsetof(struct bpf_sockopt, optlen)), - - /* if (ctx->optlen == 64) { */ - BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 64, 4), - /* ctx->optlen = -1 */ - BPF_MOV64_IMM(BPF_REG_0, -1), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, optlen)), - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_JMP_A(1), - /* } else { */ - /* return 0 */ - BPF_MOV64_IMM(BPF_REG_0, 0), - /* } */ - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - - .set_optlen = 64, - }, - { - .descr = "setsockopt: ctx->optlen == -1 is ok", - .insns = { - /* ctx->optlen = -1 */ - BPF_MOV64_IMM(BPF_REG_0, -1), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, optlen)), - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - - .set_optlen = 64, - }, - { - .descr = "setsockopt: deny ctx->optlen < 0 (except -1)", - .insns = { - /* ctx->optlen = -2 */ - BPF_MOV64_IMM(BPF_REG_0, -2), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, optlen)), - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - - .set_optlen = 4, - - .error = EFAULT_SETSOCKOPT, - }, - { - .descr = "setsockopt: deny ctx->optlen > input optlen", - .insns = { - /* ctx->optlen = 65 */ - BPF_MOV64_IMM(BPF_REG_0, 65), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, optlen)), - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - - .set_optlen = 64, - - .error = EFAULT_SETSOCKOPT, - }, - { - .descr = "setsockopt: allow changing ctx->optlen within bounds", - .insns = { - /* r6 = ctx->optval */ - BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, - offsetof(struct bpf_sockopt, optval)), - /* r2 = ctx->optval */ - BPF_MOV64_REG(BPF_REG_2, BPF_REG_6), - /* r6 = ctx->optval + 1 */ - BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 1), - - /* r7 = ctx->optval_end */ - BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_1, - offsetof(struct bpf_sockopt, optval_end)), - - /* if (ctx->optval + 1 <= ctx->optval_end) { */ - BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 1), - /* ctx->optval[0] = 1 << 3 */ - BPF_ST_MEM(BPF_B, BPF_REG_2, 0, 1 << 3), - /* } */ - - /* ctx->optlen = 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, optlen)), - - /* return 1*/ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - - .get_level = SOL_IP, - .set_level = SOL_IP, - - .get_optname = IP_TOS, - .set_optname = IP_TOS, - - .set_optval = { 1, 1, 1, 1 }, - .set_optlen = 4, - .get_optval = { 1 << 3 }, - .get_optlen = 1, - }, - { - .descr = "setsockopt: deny write ctx->retval", - .insns = { - /* ctx->retval = 0 */ - BPF_MOV64_IMM(BPF_REG_0, 0), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, retval)), - - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - - .error = DENY_LOAD, - }, - { - .descr = "setsockopt: deny read ctx->retval", - .insns = { - /* r6 = ctx->retval */ - BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, - offsetof(struct bpf_sockopt, retval)), - - /* return 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - - .error = DENY_LOAD, - }, - { - .descr = "setsockopt: deny writing to ctx->optval", - .insns = { - /* ctx->optval = 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, optval)), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - - .error = DENY_LOAD, - }, - { - .descr = "setsockopt: deny writing to ctx->optval_end", - .insns = { - /* ctx->optval_end = 1 */ - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, - offsetof(struct bpf_sockopt, optval_end)), - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - - .error = DENY_LOAD, - }, - { - .descr = "setsockopt: allow IP_TOS <= 128", - .insns = { - /* r6 = ctx->optval */ - BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, - offsetof(struct bpf_sockopt, optval)), - /* r7 = ctx->optval + 1 */ - BPF_MOV64_REG(BPF_REG_7, BPF_REG_6), - BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 1), - - /* r8 = ctx->optval_end */ - BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_1, - offsetof(struct bpf_sockopt, optval_end)), - - /* if (ctx->optval + 1 <= ctx->optval_end) { */ - BPF_JMP_REG(BPF_JGT, BPF_REG_7, BPF_REG_8, 4), - - /* r9 = ctx->optval[0] */ - BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_6, 0), - - /* if (ctx->optval[0] < 128) */ - BPF_JMP_IMM(BPF_JGT, BPF_REG_9, 128, 2), - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_JMP_A(1), - /* } */ - - /* } else { */ - BPF_MOV64_IMM(BPF_REG_0, 0), - /* } */ - - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - - .get_level = SOL_IP, - .set_level = SOL_IP, - - .get_optname = IP_TOS, - .set_optname = IP_TOS, - - .set_optval = { 0x80 }, - .set_optlen = 1, - .get_optval = { 0x80 }, - .get_optlen = 1, - }, - { - .descr = "setsockopt: deny IP_TOS > 128", - .insns = { - /* r6 = ctx->optval */ - BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, - offsetof(struct bpf_sockopt, optval)), - /* r7 = ctx->optval + 1 */ - BPF_MOV64_REG(BPF_REG_7, BPF_REG_6), - BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 1), - - /* r8 = ctx->optval_end */ - BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_1, - offsetof(struct bpf_sockopt, optval_end)), - - /* if (ctx->optval + 1 <= ctx->optval_end) { */ - BPF_JMP_REG(BPF_JGT, BPF_REG_7, BPF_REG_8, 4), - - /* r9 = ctx->optval[0] */ - BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_6, 0), - - /* if (ctx->optval[0] < 128) */ - BPF_JMP_IMM(BPF_JGT, BPF_REG_9, 128, 2), - BPF_MOV64_IMM(BPF_REG_0, 1), - BPF_JMP_A(1), - /* } */ - - /* } else { */ - BPF_MOV64_IMM(BPF_REG_0, 0), - /* } */ - - BPF_EXIT_INSN(), - }, - .attach_type = BPF_CGROUP_SETSOCKOPT, - .expected_attach_type = BPF_CGROUP_SETSOCKOPT, - - .get_level = SOL_IP, - .set_level = SOL_IP, - - .get_optname = IP_TOS, - .set_optname = IP_TOS, - - .set_optval = { 0x81 }, - .set_optlen = 1, - .get_optval = { 0x00 }, - .get_optlen = 1, - - .error = EPERM_SETSOCKOPT, - }, -}; - -static int load_prog(const struct bpf_insn *insns, - enum bpf_attach_type expected_attach_type) -{ - struct bpf_load_program_attr attr = { - .prog_type = BPF_PROG_TYPE_CGROUP_SOCKOPT, - .expected_attach_type = expected_attach_type, - .insns = insns, - .license = "GPL", - .log_level = 2, - }; - int fd; - - for (; - insns[attr.insns_cnt].code != (BPF_JMP | BPF_EXIT); - attr.insns_cnt++) { - } - attr.insns_cnt++; - - fd = bpf_load_program_xattr(&attr, bpf_log_buf, sizeof(bpf_log_buf)); - if (verbose && fd < 0) - fprintf(stderr, "%s\n", bpf_log_buf); - - return fd; -} - -static int run_test(int cgroup_fd, struct sockopt_test *test) -{ - int sock_fd, err, prog_fd; - void *optval = NULL; - int ret = 0; - - prog_fd = load_prog(test->insns, test->expected_attach_type); - if (prog_fd < 0) { - if (test->error == DENY_LOAD) - return 0; - - log_err("Failed to load BPF program"); - return -1; - } - - err = bpf_prog_attach(prog_fd, cgroup_fd, test->attach_type, 0); - if (err < 0) { - if (test->error == DENY_ATTACH) - goto close_prog_fd; - - log_err("Failed to attach BPF program"); - ret = -1; - goto close_prog_fd; - } - - sock_fd = socket(AF_INET, SOCK_STREAM, 0); - if (sock_fd < 0) { - log_err("Failed to create AF_INET socket"); - ret = -1; - goto detach_prog; - } - - if (test->set_optlen) { - err = setsockopt(sock_fd, test->set_level, test->set_optname, - test->set_optval, test->set_optlen); - if (err) { - if (errno == EPERM && test->error == EPERM_SETSOCKOPT) - goto close_sock_fd; - if (errno == EFAULT && test->error == EFAULT_SETSOCKOPT) - goto free_optval; - - log_err("Failed to call setsockopt"); - ret = -1; - goto close_sock_fd; - } - } - - if (test->get_optlen) { - optval = malloc(test->get_optlen); - socklen_t optlen = test->get_optlen; - socklen_t expected_get_optlen = test->get_optlen_ret ?: - test->get_optlen; - - err = getsockopt(sock_fd, test->get_level, test->get_optname, - optval, &optlen); - if (err) { - if (errno == EPERM && test->error == EPERM_GETSOCKOPT) - goto free_optval; - if (errno == EFAULT && test->error == EFAULT_GETSOCKOPT) - goto free_optval; - - log_err("Failed to call getsockopt"); - ret = -1; - goto free_optval; - } - - if (optlen != expected_get_optlen) { - errno = 0; - log_err("getsockopt returned unexpected optlen"); - ret = -1; - goto free_optval; - } - - if (memcmp(optval, test->get_optval, optlen) != 0) { - errno = 0; - log_err("getsockopt returned unexpected optval"); - ret = -1; - goto free_optval; - } - } - - ret = test->error != OK; - -free_optval: - free(optval); -close_sock_fd: - close(sock_fd); -detach_prog: - bpf_prog_detach2(prog_fd, cgroup_fd, test->attach_type); -close_prog_fd: - close(prog_fd); - return ret; -} - -int main(int args, char **argv) -{ - int err = EXIT_FAILURE, error_cnt = 0; - int cgroup_fd, i; - - if (setup_cgroup_environment()) - goto cleanup_obj; - - cgroup_fd = create_and_get_cgroup(CG_PATH); - if (cgroup_fd < 0) - goto cleanup_cgroup_env; - - if (join_cgroup(CG_PATH)) - goto cleanup_cgroup; - - for (i = 0; i < ARRAY_SIZE(tests); i++) { - int err = run_test(cgroup_fd, &tests[i]); - - if (err) - error_cnt++; - - printf("#%d %s: %s\n", i, err ? "FAIL" : "PASS", - tests[i].descr); - } - - printf("Summary: %ld PASSED, %d FAILED\n", - ARRAY_SIZE(tests) - error_cnt, error_cnt); - err = error_cnt ? EXIT_FAILURE : EXIT_SUCCESS; - -cleanup_cgroup: - close(cgroup_fd); -cleanup_cgroup_env: - cleanup_cgroup_environment(); -cleanup_obj: - return err; -} -- cgit v1.2.3-59-g8ed1b From 9a365e67d8bbcfff47063a4eeaa98fd3668e223a Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Wed, 4 Sep 2019 09:25:06 -0700 Subject: selftests/bpf: test_progs: convert test_sockopt_sk Move the files, adjust includes, remove entry from Makefile & .gitignore Signed-off-by: Stanislav Fomichev Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/.gitignore | 1 - tools/testing/selftests/bpf/Makefile | 3 +- .../testing/selftests/bpf/prog_tests/sockopt_sk.c | 200 +++++++++++++++++ tools/testing/selftests/bpf/test_progs.h | 3 +- tools/testing/selftests/bpf/test_sockopt_sk.c | 236 --------------------- 5 files changed, 203 insertions(+), 240 deletions(-) create mode 100644 tools/testing/selftests/bpf/prog_tests/sockopt_sk.c delete mode 100644 tools/testing/selftests/bpf/test_sockopt_sk.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore index 0315120eac8f..bc83c1a7ea1b 100644 --- a/tools/testing/selftests/bpf/.gitignore +++ b/tools/testing/selftests/bpf/.gitignore @@ -39,7 +39,6 @@ libbpf.so.* test_hashmap test_btf_dump xdping -test_sockopt_sk test_sockopt_multi test_sockopt_inherit test_tcp_rtt diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 7151cbc4676e..32a54b71d30d 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -28,7 +28,7 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test test_sock test_btf test_sockmap get_cgroup_id_user test_socket_cookie \ test_cgroup_storage test_select_reuseport test_section_names \ test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap \ - test_btf_dump test_cgroup_attach xdping test_sockopt_sk \ + test_btf_dump test_cgroup_attach xdping \ test_sockopt_multi test_sockopt_inherit test_tcp_rtt BPF_OBJ_FILES = $(patsubst %.c,%.o, $(notdir $(wildcard progs/*.c))) @@ -113,7 +113,6 @@ $(OUTPUT)/test_netcnt: cgroup_helpers.c $(OUTPUT)/test_sock_fields: cgroup_helpers.c $(OUTPUT)/test_sysctl: cgroup_helpers.c $(OUTPUT)/test_cgroup_attach: cgroup_helpers.c -$(OUTPUT)/test_sockopt_sk: cgroup_helpers.c $(OUTPUT)/test_sockopt_multi: cgroup_helpers.c $(OUTPUT)/test_sockopt_inherit: cgroup_helpers.c $(OUTPUT)/test_tcp_rtt: cgroup_helpers.c diff --git a/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c new file mode 100644 index 000000000000..2061a6beac0f --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c @@ -0,0 +1,200 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include "cgroup_helpers.h" + +#define SOL_CUSTOM 0xdeadbeef + +static int getsetsockopt(void) +{ + int fd, err; + union { + char u8[4]; + __u32 u32; + char cc[16]; /* TCP_CA_NAME_MAX */ + } buf = {}; + socklen_t optlen; + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) { + log_err("Failed to create socket"); + return -1; + } + + /* IP_TOS - BPF bypass */ + + buf.u8[0] = 0x08; + err = setsockopt(fd, SOL_IP, IP_TOS, &buf, 1); + if (err) { + log_err("Failed to call setsockopt(IP_TOS)"); + goto err; + } + + buf.u8[0] = 0x00; + optlen = 1; + err = getsockopt(fd, SOL_IP, IP_TOS, &buf, &optlen); + if (err) { + log_err("Failed to call getsockopt(IP_TOS)"); + goto err; + } + + if (buf.u8[0] != 0x08) { + log_err("Unexpected getsockopt(IP_TOS) buf[0] 0x%02x != 0x08", + buf.u8[0]); + goto err; + } + + /* IP_TTL - EPERM */ + + buf.u8[0] = 1; + err = setsockopt(fd, SOL_IP, IP_TTL, &buf, 1); + if (!err || errno != EPERM) { + log_err("Unexpected success from setsockopt(IP_TTL)"); + goto err; + } + + /* SOL_CUSTOM - handled by BPF */ + + buf.u8[0] = 0x01; + err = setsockopt(fd, SOL_CUSTOM, 0, &buf, 1); + if (err) { + log_err("Failed to call setsockopt"); + goto err; + } + + buf.u32 = 0x00; + optlen = 4; + err = getsockopt(fd, SOL_CUSTOM, 0, &buf, &optlen); + if (err) { + log_err("Failed to call getsockopt"); + goto err; + } + + if (optlen != 1) { + log_err("Unexpected optlen %d != 1", optlen); + goto err; + } + if (buf.u8[0] != 0x01) { + log_err("Unexpected buf[0] 0x%02x != 0x01", buf.u8[0]); + goto err; + } + + /* SO_SNDBUF is overwritten */ + + buf.u32 = 0x01010101; + err = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buf, 4); + if (err) { + log_err("Failed to call setsockopt(SO_SNDBUF)"); + goto err; + } + + buf.u32 = 0x00; + optlen = 4; + err = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buf, &optlen); + if (err) { + log_err("Failed to call getsockopt(SO_SNDBUF)"); + goto err; + } + + if (buf.u32 != 0x55AA*2) { + log_err("Unexpected getsockopt(SO_SNDBUF) 0x%x != 0x55AA*2", + buf.u32); + goto err; + } + + /* TCP_CONGESTION can extend the string */ + + strcpy(buf.cc, "nv"); + err = setsockopt(fd, SOL_TCP, TCP_CONGESTION, &buf, strlen("nv")); + if (err) { + log_err("Failed to call setsockopt(TCP_CONGESTION)"); + goto err; + } + + + optlen = sizeof(buf.cc); + err = getsockopt(fd, SOL_TCP, TCP_CONGESTION, &buf, &optlen); + if (err) { + log_err("Failed to call getsockopt(TCP_CONGESTION)"); + goto err; + } + + if (strcmp(buf.cc, "cubic") != 0) { + log_err("Unexpected getsockopt(TCP_CONGESTION) %s != %s", + buf.cc, "cubic"); + goto err; + } + + close(fd); + return 0; +err: + close(fd); + return -1; +} + +static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title) +{ + enum bpf_attach_type attach_type; + enum bpf_prog_type prog_type; + struct bpf_program *prog; + int err; + + err = libbpf_prog_type_by_name(title, &prog_type, &attach_type); + if (err) { + log_err("Failed to deduct types for %s BPF program", title); + return -1; + } + + prog = bpf_object__find_program_by_title(obj, title); + if (!prog) { + log_err("Failed to find %s BPF program", title); + return -1; + } + + err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, + attach_type, 0); + if (err) { + log_err("Failed to attach %s BPF program", title); + return -1; + } + + return 0; +} + +static void run_test(int cgroup_fd) +{ + struct bpf_prog_load_attr attr = { + .file = "./sockopt_sk.o", + }; + struct bpf_object *obj; + int ignored; + int err; + + err = bpf_prog_load_xattr(&attr, &obj, &ignored); + if (CHECK_FAIL(err)) + return; + + err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt"); + if (CHECK_FAIL(err)) + goto close_bpf_object; + + err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt"); + if (CHECK_FAIL(err)) + goto close_bpf_object; + + CHECK_FAIL(getsetsockopt()); + +close_bpf_object: + bpf_object__close(obj); +} + +void test_sockopt_sk(void) +{ + int cgroup_fd; + + cgroup_fd = test__join_cgroup("/sockopt_sk"); + if (CHECK_FAIL(cgroup_fd < 0)) + return; + + run_test(cgroup_fd); + close(cgroup_fd); +} diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h index e518bd5da3e2..0c48f64f732b 100644 --- a/tools/testing/selftests/bpf/test_progs.h +++ b/tools/testing/selftests/bpf/test_progs.h @@ -16,9 +16,10 @@ typedef __u16 __sum16; #include #include #include -#include +#include #include #include +#include #include #include diff --git a/tools/testing/selftests/bpf/test_sockopt_sk.c b/tools/testing/selftests/bpf/test_sockopt_sk.c deleted file mode 100644 index e4f6055d92e9..000000000000 --- a/tools/testing/selftests/bpf/test_sockopt_sk.c +++ /dev/null @@ -1,236 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "bpf_rlimit.h" -#include "bpf_util.h" -#include "cgroup_helpers.h" - -#define CG_PATH "/sockopt" - -#define SOL_CUSTOM 0xdeadbeef - -static int getsetsockopt(void) -{ - int fd, err; - union { - char u8[4]; - __u32 u32; - char cc[16]; /* TCP_CA_NAME_MAX */ - } buf = {}; - socklen_t optlen; - - fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) { - log_err("Failed to create socket"); - return -1; - } - - /* IP_TOS - BPF bypass */ - - buf.u8[0] = 0x08; - err = setsockopt(fd, SOL_IP, IP_TOS, &buf, 1); - if (err) { - log_err("Failed to call setsockopt(IP_TOS)"); - goto err; - } - - buf.u8[0] = 0x00; - optlen = 1; - err = getsockopt(fd, SOL_IP, IP_TOS, &buf, &optlen); - if (err) { - log_err("Failed to call getsockopt(IP_TOS)"); - goto err; - } - - if (buf.u8[0] != 0x08) { - log_err("Unexpected getsockopt(IP_TOS) buf[0] 0x%02x != 0x08", - buf.u8[0]); - goto err; - } - - /* IP_TTL - EPERM */ - - buf.u8[0] = 1; - err = setsockopt(fd, SOL_IP, IP_TTL, &buf, 1); - if (!err || errno != EPERM) { - log_err("Unexpected success from setsockopt(IP_TTL)"); - goto err; - } - - /* SOL_CUSTOM - handled by BPF */ - - buf.u8[0] = 0x01; - err = setsockopt(fd, SOL_CUSTOM, 0, &buf, 1); - if (err) { - log_err("Failed to call setsockopt"); - goto err; - } - - buf.u32 = 0x00; - optlen = 4; - err = getsockopt(fd, SOL_CUSTOM, 0, &buf, &optlen); - if (err) { - log_err("Failed to call getsockopt"); - goto err; - } - - if (optlen != 1) { - log_err("Unexpected optlen %d != 1", optlen); - goto err; - } - if (buf.u8[0] != 0x01) { - log_err("Unexpected buf[0] 0x%02x != 0x01", buf.u8[0]); - goto err; - } - - /* SO_SNDBUF is overwritten */ - - buf.u32 = 0x01010101; - err = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buf, 4); - if (err) { - log_err("Failed to call setsockopt(SO_SNDBUF)"); - goto err; - } - - buf.u32 = 0x00; - optlen = 4; - err = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buf, &optlen); - if (err) { - log_err("Failed to call getsockopt(SO_SNDBUF)"); - goto err; - } - - if (buf.u32 != 0x55AA*2) { - log_err("Unexpected getsockopt(SO_SNDBUF) 0x%x != 0x55AA*2", - buf.u32); - goto err; - } - - /* TCP_CONGESTION can extend the string */ - - strcpy(buf.cc, "nv"); - err = setsockopt(fd, SOL_TCP, TCP_CONGESTION, &buf, strlen("nv")); - if (err) { - log_err("Failed to call setsockopt(TCP_CONGESTION)"); - goto err; - } - - - optlen = sizeof(buf.cc); - err = getsockopt(fd, SOL_TCP, TCP_CONGESTION, &buf, &optlen); - if (err) { - log_err("Failed to call getsockopt(TCP_CONGESTION)"); - goto err; - } - - if (strcmp(buf.cc, "cubic") != 0) { - log_err("Unexpected getsockopt(TCP_CONGESTION) %s != %s", - buf.cc, "cubic"); - goto err; - } - - close(fd); - return 0; -err: - close(fd); - return -1; -} - -static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title) -{ - enum bpf_attach_type attach_type; - enum bpf_prog_type prog_type; - struct bpf_program *prog; - int err; - - err = libbpf_prog_type_by_name(title, &prog_type, &attach_type); - if (err) { - log_err("Failed to deduct types for %s BPF program", title); - return -1; - } - - prog = bpf_object__find_program_by_title(obj, title); - if (!prog) { - log_err("Failed to find %s BPF program", title); - return -1; - } - - err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, - attach_type, 0); - if (err) { - log_err("Failed to attach %s BPF program", title); - return -1; - } - - return 0; -} - -static int run_test(int cgroup_fd) -{ - struct bpf_prog_load_attr attr = { - .file = "./sockopt_sk.o", - }; - struct bpf_object *obj; - int ignored; - int err; - - err = bpf_prog_load_xattr(&attr, &obj, &ignored); - if (err) { - log_err("Failed to load BPF object"); - return -1; - } - - err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt"); - if (err) - goto close_bpf_object; - - err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt"); - if (err) - goto close_bpf_object; - - err = getsetsockopt(); - -close_bpf_object: - bpf_object__close(obj); - return err; -} - -int main(int args, char **argv) -{ - int cgroup_fd; - int err = EXIT_SUCCESS; - - if (setup_cgroup_environment()) - goto cleanup_obj; - - cgroup_fd = create_and_get_cgroup(CG_PATH); - if (cgroup_fd < 0) - goto cleanup_cgroup_env; - - if (join_cgroup(CG_PATH)) - goto cleanup_cgroup; - - if (run_test(cgroup_fd)) - err = EXIT_FAILURE; - - printf("test_sockopt_sk: %s\n", - err == EXIT_SUCCESS ? "PASSED" : "FAILED"); - -cleanup_cgroup: - close(cgroup_fd); -cleanup_cgroup_env: - cleanup_cgroup_environment(); -cleanup_obj: - return err; -} -- cgit v1.2.3-59-g8ed1b From 3886bd7c9b01317a5721161f8314f6c25f4f6229 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Wed, 4 Sep 2019 09:25:07 -0700 Subject: selftests/bpf: test_progs: convert test_sockopt_multi Move the files, adjust includes, remove entry from Makefile & .gitignore Signed-off-by: Stanislav Fomichev Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/.gitignore | 1 - tools/testing/selftests/bpf/Makefile | 3 +- .../selftests/bpf/prog_tests/sockopt_multi.c | 332 ++++++++++++++++++ tools/testing/selftests/bpf/test_sockopt_multi.c | 374 --------------------- 4 files changed, 333 insertions(+), 377 deletions(-) create mode 100644 tools/testing/selftests/bpf/prog_tests/sockopt_multi.c delete mode 100644 tools/testing/selftests/bpf/test_sockopt_multi.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore index bc83c1a7ea1b..4143add5a11e 100644 --- a/tools/testing/selftests/bpf/.gitignore +++ b/tools/testing/selftests/bpf/.gitignore @@ -39,6 +39,5 @@ libbpf.so.* test_hashmap test_btf_dump xdping -test_sockopt_multi test_sockopt_inherit test_tcp_rtt diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 32a54b71d30d..0ab9642c4f5e 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -29,7 +29,7 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test test_cgroup_storage test_select_reuseport test_section_names \ test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap \ test_btf_dump test_cgroup_attach xdping \ - test_sockopt_multi test_sockopt_inherit test_tcp_rtt + test_sockopt_inherit test_tcp_rtt BPF_OBJ_FILES = $(patsubst %.c,%.o, $(notdir $(wildcard progs/*.c))) TEST_GEN_FILES = $(BPF_OBJ_FILES) @@ -113,7 +113,6 @@ $(OUTPUT)/test_netcnt: cgroup_helpers.c $(OUTPUT)/test_sock_fields: cgroup_helpers.c $(OUTPUT)/test_sysctl: cgroup_helpers.c $(OUTPUT)/test_cgroup_attach: cgroup_helpers.c -$(OUTPUT)/test_sockopt_multi: cgroup_helpers.c $(OUTPUT)/test_sockopt_inherit: cgroup_helpers.c $(OUTPUT)/test_tcp_rtt: cgroup_helpers.c diff --git a/tools/testing/selftests/bpf/prog_tests/sockopt_multi.c b/tools/testing/selftests/bpf/prog_tests/sockopt_multi.c new file mode 100644 index 000000000000..29188d6f5c8d --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/sockopt_multi.c @@ -0,0 +1,332 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include "cgroup_helpers.h" + +static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title) +{ + enum bpf_attach_type attach_type; + enum bpf_prog_type prog_type; + struct bpf_program *prog; + int err; + + err = libbpf_prog_type_by_name(title, &prog_type, &attach_type); + if (err) { + log_err("Failed to deduct types for %s BPF program", title); + return -1; + } + + prog = bpf_object__find_program_by_title(obj, title); + if (!prog) { + log_err("Failed to find %s BPF program", title); + return -1; + } + + err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, + attach_type, BPF_F_ALLOW_MULTI); + if (err) { + log_err("Failed to attach %s BPF program", title); + return -1; + } + + return 0; +} + +static int prog_detach(struct bpf_object *obj, int cgroup_fd, const char *title) +{ + enum bpf_attach_type attach_type; + enum bpf_prog_type prog_type; + struct bpf_program *prog; + int err; + + err = libbpf_prog_type_by_name(title, &prog_type, &attach_type); + if (err) + return -1; + + prog = bpf_object__find_program_by_title(obj, title); + if (!prog) + return -1; + + err = bpf_prog_detach2(bpf_program__fd(prog), cgroup_fd, + attach_type); + if (err) + return -1; + + return 0; +} + +static int run_getsockopt_test(struct bpf_object *obj, int cg_parent, + int cg_child, int sock_fd) +{ + socklen_t optlen; + __u8 buf; + int err; + + /* Set IP_TOS to the expected value (0x80). */ + + buf = 0x80; + err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1); + if (err < 0) { + log_err("Failed to call setsockopt(IP_TOS)"); + goto detach; + } + + buf = 0x00; + optlen = 1; + err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); + if (err) { + log_err("Failed to call getsockopt(IP_TOS)"); + goto detach; + } + + if (buf != 0x80) { + log_err("Unexpected getsockopt 0x%x != 0x80 without BPF", buf); + err = -1; + goto detach; + } + + /* Attach child program and make sure it returns new value: + * - kernel: -> 0x80 + * - child: 0x80 -> 0x90 + */ + + err = prog_attach(obj, cg_child, "cgroup/getsockopt/child"); + if (err) + goto detach; + + buf = 0x00; + optlen = 1; + err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); + if (err) { + log_err("Failed to call getsockopt(IP_TOS)"); + goto detach; + } + + if (buf != 0x90) { + log_err("Unexpected getsockopt 0x%x != 0x90", buf); + err = -1; + goto detach; + } + + /* Attach parent program and make sure it returns new value: + * - kernel: -> 0x80 + * - child: 0x80 -> 0x90 + * - parent: 0x90 -> 0xA0 + */ + + err = prog_attach(obj, cg_parent, "cgroup/getsockopt/parent"); + if (err) + goto detach; + + buf = 0x00; + optlen = 1; + err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); + if (err) { + log_err("Failed to call getsockopt(IP_TOS)"); + goto detach; + } + + if (buf != 0xA0) { + log_err("Unexpected getsockopt 0x%x != 0xA0", buf); + err = -1; + goto detach; + } + + /* Setting unexpected initial sockopt should return EPERM: + * - kernel: -> 0x40 + * - child: unexpected 0x40, EPERM + * - parent: unexpected 0x40, EPERM + */ + + buf = 0x40; + if (setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1) < 0) { + log_err("Failed to call setsockopt(IP_TOS)"); + goto detach; + } + + buf = 0x00; + optlen = 1; + err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); + if (!err) { + log_err("Unexpected success from getsockopt(IP_TOS)"); + goto detach; + } + + /* Detach child program and make sure we still get EPERM: + * - kernel: -> 0x40 + * - parent: unexpected 0x40, EPERM + */ + + err = prog_detach(obj, cg_child, "cgroup/getsockopt/child"); + if (err) { + log_err("Failed to detach child program"); + goto detach; + } + + buf = 0x00; + optlen = 1; + err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); + if (!err) { + log_err("Unexpected success from getsockopt(IP_TOS)"); + goto detach; + } + + /* Set initial value to the one the parent program expects: + * - kernel: -> 0x90 + * - parent: 0x90 -> 0xA0 + */ + + buf = 0x90; + err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1); + if (err < 0) { + log_err("Failed to call setsockopt(IP_TOS)"); + goto detach; + } + + buf = 0x00; + optlen = 1; + err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); + if (err) { + log_err("Failed to call getsockopt(IP_TOS)"); + goto detach; + } + + if (buf != 0xA0) { + log_err("Unexpected getsockopt 0x%x != 0xA0", buf); + err = -1; + goto detach; + } + +detach: + prog_detach(obj, cg_child, "cgroup/getsockopt/child"); + prog_detach(obj, cg_parent, "cgroup/getsockopt/parent"); + + return err; +} + +static int run_setsockopt_test(struct bpf_object *obj, int cg_parent, + int cg_child, int sock_fd) +{ + socklen_t optlen; + __u8 buf; + int err; + + /* Set IP_TOS to the expected value (0x80). */ + + buf = 0x80; + err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1); + if (err < 0) { + log_err("Failed to call setsockopt(IP_TOS)"); + goto detach; + } + + buf = 0x00; + optlen = 1; + err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); + if (err) { + log_err("Failed to call getsockopt(IP_TOS)"); + goto detach; + } + + if (buf != 0x80) { + log_err("Unexpected getsockopt 0x%x != 0x80 without BPF", buf); + err = -1; + goto detach; + } + + /* Attach child program and make sure it adds 0x10. */ + + err = prog_attach(obj, cg_child, "cgroup/setsockopt"); + if (err) + goto detach; + + buf = 0x80; + err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1); + if (err < 0) { + log_err("Failed to call setsockopt(IP_TOS)"); + goto detach; + } + + buf = 0x00; + optlen = 1; + err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); + if (err) { + log_err("Failed to call getsockopt(IP_TOS)"); + goto detach; + } + + if (buf != 0x80 + 0x10) { + log_err("Unexpected getsockopt 0x%x != 0x80 + 0x10", buf); + err = -1; + goto detach; + } + + /* Attach parent program and make sure it adds another 0x10. */ + + err = prog_attach(obj, cg_parent, "cgroup/setsockopt"); + if (err) + goto detach; + + buf = 0x80; + err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1); + if (err < 0) { + log_err("Failed to call setsockopt(IP_TOS)"); + goto detach; + } + + buf = 0x00; + optlen = 1; + err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); + if (err) { + log_err("Failed to call getsockopt(IP_TOS)"); + goto detach; + } + + if (buf != 0x80 + 2 * 0x10) { + log_err("Unexpected getsockopt 0x%x != 0x80 + 2 * 0x10", buf); + err = -1; + goto detach; + } + +detach: + prog_detach(obj, cg_child, "cgroup/setsockopt"); + prog_detach(obj, cg_parent, "cgroup/setsockopt"); + + return err; +} + +void test_sockopt_multi(void) +{ + struct bpf_prog_load_attr attr = { + .file = "./sockopt_multi.o", + }; + int cg_parent = -1, cg_child = -1; + struct bpf_object *obj = NULL; + int sock_fd = -1; + int err = -1; + int ignored; + + cg_parent = test__join_cgroup("/parent"); + if (CHECK_FAIL(cg_parent < 0)) + goto out; + + cg_child = test__join_cgroup("/parent/child"); + if (CHECK_FAIL(cg_child < 0)) + goto out; + + err = bpf_prog_load_xattr(&attr, &obj, &ignored); + if (CHECK_FAIL(err)) + goto out; + + sock_fd = socket(AF_INET, SOCK_STREAM, 0); + if (CHECK_FAIL(sock_fd < 0)) + goto out; + + CHECK_FAIL(run_getsockopt_test(obj, cg_parent, cg_child, sock_fd)); + CHECK_FAIL(run_setsockopt_test(obj, cg_parent, cg_child, sock_fd)); + +out: + close(sock_fd); + bpf_object__close(obj); + close(cg_child); + close(cg_parent); +} diff --git a/tools/testing/selftests/bpf/test_sockopt_multi.c b/tools/testing/selftests/bpf/test_sockopt_multi.c deleted file mode 100644 index 4be3441db867..000000000000 --- a/tools/testing/selftests/bpf/test_sockopt_multi.c +++ /dev/null @@ -1,374 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "bpf_rlimit.h" -#include "bpf_util.h" -#include "cgroup_helpers.h" - -static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title) -{ - enum bpf_attach_type attach_type; - enum bpf_prog_type prog_type; - struct bpf_program *prog; - int err; - - err = libbpf_prog_type_by_name(title, &prog_type, &attach_type); - if (err) { - log_err("Failed to deduct types for %s BPF program", title); - return -1; - } - - prog = bpf_object__find_program_by_title(obj, title); - if (!prog) { - log_err("Failed to find %s BPF program", title); - return -1; - } - - err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, - attach_type, BPF_F_ALLOW_MULTI); - if (err) { - log_err("Failed to attach %s BPF program", title); - return -1; - } - - return 0; -} - -static int prog_detach(struct bpf_object *obj, int cgroup_fd, const char *title) -{ - enum bpf_attach_type attach_type; - enum bpf_prog_type prog_type; - struct bpf_program *prog; - int err; - - err = libbpf_prog_type_by_name(title, &prog_type, &attach_type); - if (err) - return -1; - - prog = bpf_object__find_program_by_title(obj, title); - if (!prog) - return -1; - - err = bpf_prog_detach2(bpf_program__fd(prog), cgroup_fd, - attach_type); - if (err) - return -1; - - return 0; -} - -static int run_getsockopt_test(struct bpf_object *obj, int cg_parent, - int cg_child, int sock_fd) -{ - socklen_t optlen; - __u8 buf; - int err; - - /* Set IP_TOS to the expected value (0x80). */ - - buf = 0x80; - err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1); - if (err < 0) { - log_err("Failed to call setsockopt(IP_TOS)"); - goto detach; - } - - buf = 0x00; - optlen = 1; - err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); - if (err) { - log_err("Failed to call getsockopt(IP_TOS)"); - goto detach; - } - - if (buf != 0x80) { - log_err("Unexpected getsockopt 0x%x != 0x80 without BPF", buf); - err = -1; - goto detach; - } - - /* Attach child program and make sure it returns new value: - * - kernel: -> 0x80 - * - child: 0x80 -> 0x90 - */ - - err = prog_attach(obj, cg_child, "cgroup/getsockopt/child"); - if (err) - goto detach; - - buf = 0x00; - optlen = 1; - err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); - if (err) { - log_err("Failed to call getsockopt(IP_TOS)"); - goto detach; - } - - if (buf != 0x90) { - log_err("Unexpected getsockopt 0x%x != 0x90", buf); - err = -1; - goto detach; - } - - /* Attach parent program and make sure it returns new value: - * - kernel: -> 0x80 - * - child: 0x80 -> 0x90 - * - parent: 0x90 -> 0xA0 - */ - - err = prog_attach(obj, cg_parent, "cgroup/getsockopt/parent"); - if (err) - goto detach; - - buf = 0x00; - optlen = 1; - err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); - if (err) { - log_err("Failed to call getsockopt(IP_TOS)"); - goto detach; - } - - if (buf != 0xA0) { - log_err("Unexpected getsockopt 0x%x != 0xA0", buf); - err = -1; - goto detach; - } - - /* Setting unexpected initial sockopt should return EPERM: - * - kernel: -> 0x40 - * - child: unexpected 0x40, EPERM - * - parent: unexpected 0x40, EPERM - */ - - buf = 0x40; - if (setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1) < 0) { - log_err("Failed to call setsockopt(IP_TOS)"); - goto detach; - } - - buf = 0x00; - optlen = 1; - err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); - if (!err) { - log_err("Unexpected success from getsockopt(IP_TOS)"); - goto detach; - } - - /* Detach child program and make sure we still get EPERM: - * - kernel: -> 0x40 - * - parent: unexpected 0x40, EPERM - */ - - err = prog_detach(obj, cg_child, "cgroup/getsockopt/child"); - if (err) { - log_err("Failed to detach child program"); - goto detach; - } - - buf = 0x00; - optlen = 1; - err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); - if (!err) { - log_err("Unexpected success from getsockopt(IP_TOS)"); - goto detach; - } - - /* Set initial value to the one the parent program expects: - * - kernel: -> 0x90 - * - parent: 0x90 -> 0xA0 - */ - - buf = 0x90; - err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1); - if (err < 0) { - log_err("Failed to call setsockopt(IP_TOS)"); - goto detach; - } - - buf = 0x00; - optlen = 1; - err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); - if (err) { - log_err("Failed to call getsockopt(IP_TOS)"); - goto detach; - } - - if (buf != 0xA0) { - log_err("Unexpected getsockopt 0x%x != 0xA0", buf); - err = -1; - goto detach; - } - -detach: - prog_detach(obj, cg_child, "cgroup/getsockopt/child"); - prog_detach(obj, cg_parent, "cgroup/getsockopt/parent"); - - return err; -} - -static int run_setsockopt_test(struct bpf_object *obj, int cg_parent, - int cg_child, int sock_fd) -{ - socklen_t optlen; - __u8 buf; - int err; - - /* Set IP_TOS to the expected value (0x80). */ - - buf = 0x80; - err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1); - if (err < 0) { - log_err("Failed to call setsockopt(IP_TOS)"); - goto detach; - } - - buf = 0x00; - optlen = 1; - err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); - if (err) { - log_err("Failed to call getsockopt(IP_TOS)"); - goto detach; - } - - if (buf != 0x80) { - log_err("Unexpected getsockopt 0x%x != 0x80 without BPF", buf); - err = -1; - goto detach; - } - - /* Attach child program and make sure it adds 0x10. */ - - err = prog_attach(obj, cg_child, "cgroup/setsockopt"); - if (err) - goto detach; - - buf = 0x80; - err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1); - if (err < 0) { - log_err("Failed to call setsockopt(IP_TOS)"); - goto detach; - } - - buf = 0x00; - optlen = 1; - err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); - if (err) { - log_err("Failed to call getsockopt(IP_TOS)"); - goto detach; - } - - if (buf != 0x80 + 0x10) { - log_err("Unexpected getsockopt 0x%x != 0x80 + 0x10", buf); - err = -1; - goto detach; - } - - /* Attach parent program and make sure it adds another 0x10. */ - - err = prog_attach(obj, cg_parent, "cgroup/setsockopt"); - if (err) - goto detach; - - buf = 0x80; - err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1); - if (err < 0) { - log_err("Failed to call setsockopt(IP_TOS)"); - goto detach; - } - - buf = 0x00; - optlen = 1; - err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen); - if (err) { - log_err("Failed to call getsockopt(IP_TOS)"); - goto detach; - } - - if (buf != 0x80 + 2 * 0x10) { - log_err("Unexpected getsockopt 0x%x != 0x80 + 2 * 0x10", buf); - err = -1; - goto detach; - } - -detach: - prog_detach(obj, cg_child, "cgroup/setsockopt"); - prog_detach(obj, cg_parent, "cgroup/setsockopt"); - - return err; -} - -int main(int argc, char **argv) -{ - struct bpf_prog_load_attr attr = { - .file = "./sockopt_multi.o", - }; - int cg_parent = -1, cg_child = -1; - struct bpf_object *obj = NULL; - int sock_fd = -1; - int err = -1; - int ignored; - - if (setup_cgroup_environment()) { - log_err("Failed to setup cgroup environment\n"); - goto out; - } - - cg_parent = create_and_get_cgroup("/parent"); - if (cg_parent < 0) { - log_err("Failed to create cgroup /parent\n"); - goto out; - } - - cg_child = create_and_get_cgroup("/parent/child"); - if (cg_child < 0) { - log_err("Failed to create cgroup /parent/child\n"); - goto out; - } - - if (join_cgroup("/parent/child")) { - log_err("Failed to join cgroup /parent/child\n"); - goto out; - } - - err = bpf_prog_load_xattr(&attr, &obj, &ignored); - if (err) { - log_err("Failed to load BPF object"); - goto out; - } - - sock_fd = socket(AF_INET, SOCK_STREAM, 0); - if (sock_fd < 0) { - log_err("Failed to create socket"); - goto out; - } - - if (run_getsockopt_test(obj, cg_parent, cg_child, sock_fd)) - err = -1; - printf("test_sockopt_multi: getsockopt %s\n", - err ? "FAILED" : "PASSED"); - - if (run_setsockopt_test(obj, cg_parent, cg_child, sock_fd)) - err = -1; - printf("test_sockopt_multi: setsockopt %s\n", - err ? "FAILED" : "PASSED"); - -out: - close(sock_fd); - bpf_object__close(obj); - close(cg_child); - close(cg_parent); - - printf("test_sockopt_multi: %s\n", err ? "FAILED" : "PASSED"); - return err ? EXIT_FAILURE : EXIT_SUCCESS; -} -- cgit v1.2.3-59-g8ed1b From e3e02e1d9c24b0c3a36f9c854ae80e61fd62b2a9 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Wed, 4 Sep 2019 09:25:08 -0700 Subject: selftests/bpf: test_progs: convert test_sockopt_inherit Move the files, adjust includes, remove entry from Makefile & .gitignore I also added pthread_cond_wait for the server thread startup. We don't want to connect to the server that's not yet up (for some reason this existing race is now more prominent with test_progs). Signed-off-by: Stanislav Fomichev Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/.gitignore | 1 - tools/testing/selftests/bpf/Makefile | 4 +- .../selftests/bpf/prog_tests/sockopt_inherit.c | 235 +++++++++++++++++++ tools/testing/selftests/bpf/test_sockopt_inherit.c | 253 --------------------- 4 files changed, 236 insertions(+), 257 deletions(-) create mode 100644 tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c delete mode 100644 tools/testing/selftests/bpf/test_sockopt_inherit.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore index 4143add5a11e..5b06bb45b500 100644 --- a/tools/testing/selftests/bpf/.gitignore +++ b/tools/testing/selftests/bpf/.gitignore @@ -39,5 +39,4 @@ libbpf.so.* test_hashmap test_btf_dump xdping -test_sockopt_inherit test_tcp_rtt diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 0ab9642c4f5e..4d9a0304a011 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -28,8 +28,7 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test test_sock test_btf test_sockmap get_cgroup_id_user test_socket_cookie \ test_cgroup_storage test_select_reuseport test_section_names \ test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap \ - test_btf_dump test_cgroup_attach xdping \ - test_sockopt_inherit test_tcp_rtt + test_btf_dump test_cgroup_attach xdping test_tcp_rtt BPF_OBJ_FILES = $(patsubst %.c,%.o, $(notdir $(wildcard progs/*.c))) TEST_GEN_FILES = $(BPF_OBJ_FILES) @@ -113,7 +112,6 @@ $(OUTPUT)/test_netcnt: cgroup_helpers.c $(OUTPUT)/test_sock_fields: cgroup_helpers.c $(OUTPUT)/test_sysctl: cgroup_helpers.c $(OUTPUT)/test_cgroup_attach: cgroup_helpers.c -$(OUTPUT)/test_sockopt_inherit: cgroup_helpers.c $(OUTPUT)/test_tcp_rtt: cgroup_helpers.c .PHONY: force diff --git a/tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c b/tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c new file mode 100644 index 000000000000..6cbeea7b4bf1 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c @@ -0,0 +1,235 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include "cgroup_helpers.h" + +#define SOL_CUSTOM 0xdeadbeef +#define CUSTOM_INHERIT1 0 +#define CUSTOM_INHERIT2 1 +#define CUSTOM_LISTENER 2 + +static int connect_to_server(int server_fd) +{ + struct sockaddr_storage addr; + socklen_t len = sizeof(addr); + int fd; + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) { + log_err("Failed to create client socket"); + return -1; + } + + if (getsockname(server_fd, (struct sockaddr *)&addr, &len)) { + log_err("Failed to get server addr"); + goto out; + } + + if (connect(fd, (const struct sockaddr *)&addr, len) < 0) { + log_err("Fail to connect to server"); + goto out; + } + + return fd; + +out: + close(fd); + return -1; +} + +static int verify_sockopt(int fd, int optname, const char *msg, char expected) +{ + socklen_t optlen = 1; + char buf = 0; + int err; + + err = getsockopt(fd, SOL_CUSTOM, optname, &buf, &optlen); + if (err) { + log_err("%s: failed to call getsockopt", msg); + return 1; + } + + printf("%s %d: got=0x%x ? expected=0x%x\n", msg, optname, buf, expected); + + if (buf != expected) { + log_err("%s: unexpected getsockopt value %d != %d", msg, + buf, expected); + return 1; + } + + return 0; +} + +static pthread_mutex_t server_started_mtx = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t server_started = PTHREAD_COND_INITIALIZER; + +static void *server_thread(void *arg) +{ + struct sockaddr_storage addr; + socklen_t len = sizeof(addr); + int fd = *(int *)arg; + int client_fd; + int err = 0; + + err = listen(fd, 1); + + pthread_mutex_lock(&server_started_mtx); + pthread_cond_signal(&server_started); + pthread_mutex_unlock(&server_started_mtx); + + if (CHECK_FAIL(err < 0)) { + perror("Failed to listed on socket"); + return NULL; + } + + err += verify_sockopt(fd, CUSTOM_INHERIT1, "listen", 1); + err += verify_sockopt(fd, CUSTOM_INHERIT2, "listen", 1); + err += verify_sockopt(fd, CUSTOM_LISTENER, "listen", 1); + + client_fd = accept(fd, (struct sockaddr *)&addr, &len); + if (CHECK_FAIL(client_fd < 0)) { + perror("Failed to accept client"); + return NULL; + } + + err += verify_sockopt(client_fd, CUSTOM_INHERIT1, "accept", 1); + err += verify_sockopt(client_fd, CUSTOM_INHERIT2, "accept", 1); + err += verify_sockopt(client_fd, CUSTOM_LISTENER, "accept", 0); + + close(client_fd); + + return (void *)(long)err; +} + +static int start_server(void) +{ + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_addr.s_addr = htonl(INADDR_LOOPBACK), + }; + char buf; + int err; + int fd; + int i; + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) { + log_err("Failed to create server socket"); + return -1; + } + + for (i = CUSTOM_INHERIT1; i <= CUSTOM_LISTENER; i++) { + buf = 0x01; + err = setsockopt(fd, SOL_CUSTOM, i, &buf, 1); + if (err) { + log_err("Failed to call setsockopt(%d)", i); + close(fd); + return -1; + } + } + + if (bind(fd, (const struct sockaddr *)&addr, sizeof(addr)) < 0) { + log_err("Failed to bind socket"); + close(fd); + return -1; + } + + return fd; +} + +static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title) +{ + enum bpf_attach_type attach_type; + enum bpf_prog_type prog_type; + struct bpf_program *prog; + int err; + + err = libbpf_prog_type_by_name(title, &prog_type, &attach_type); + if (err) { + log_err("Failed to deduct types for %s BPF program", title); + return -1; + } + + prog = bpf_object__find_program_by_title(obj, title); + if (!prog) { + log_err("Failed to find %s BPF program", title); + return -1; + } + + err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, + attach_type, 0); + if (err) { + log_err("Failed to attach %s BPF program", title); + return -1; + } + + return 0; +} + +static void run_test(int cgroup_fd) +{ + struct bpf_prog_load_attr attr = { + .file = "./sockopt_inherit.o", + }; + int server_fd = -1, client_fd; + struct bpf_object *obj; + void *server_err; + pthread_t tid; + int ignored; + int err; + + err = bpf_prog_load_xattr(&attr, &obj, &ignored); + if (CHECK_FAIL(err)) + return; + + err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt"); + if (CHECK_FAIL(err)) + goto close_bpf_object; + + err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt"); + if (CHECK_FAIL(err)) + goto close_bpf_object; + + server_fd = start_server(); + if (CHECK_FAIL(server_fd < 0)) + goto close_bpf_object; + + if (CHECK_FAIL(pthread_create(&tid, NULL, server_thread, + (void *)&server_fd))) + goto close_bpf_object; + + pthread_mutex_lock(&server_started_mtx); + pthread_cond_wait(&server_started, &server_started_mtx); + pthread_mutex_unlock(&server_started_mtx); + + client_fd = connect_to_server(server_fd); + if (CHECK_FAIL(client_fd < 0)) + goto close_server_fd; + + CHECK_FAIL(verify_sockopt(client_fd, CUSTOM_INHERIT1, "connect", 0)); + CHECK_FAIL(verify_sockopt(client_fd, CUSTOM_INHERIT2, "connect", 0)); + CHECK_FAIL(verify_sockopt(client_fd, CUSTOM_LISTENER, "connect", 0)); + + pthread_join(tid, &server_err); + + err = (int)(long)server_err; + CHECK_FAIL(err); + + close(client_fd); + +close_server_fd: + close(server_fd); +close_bpf_object: + bpf_object__close(obj); +} + +void test_sockopt_inherit(void) +{ + int cgroup_fd; + + cgroup_fd = test__join_cgroup("/sockopt_inherit"); + if (CHECK_FAIL(cgroup_fd < 0)) + return; + + run_test(cgroup_fd); + close(cgroup_fd); +} diff --git a/tools/testing/selftests/bpf/test_sockopt_inherit.c b/tools/testing/selftests/bpf/test_sockopt_inherit.c deleted file mode 100644 index 1bf699815b9b..000000000000 --- a/tools/testing/selftests/bpf/test_sockopt_inherit.c +++ /dev/null @@ -1,253 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "bpf_rlimit.h" -#include "bpf_util.h" -#include "cgroup_helpers.h" - -#define CG_PATH "/sockopt_inherit" -#define SOL_CUSTOM 0xdeadbeef -#define CUSTOM_INHERIT1 0 -#define CUSTOM_INHERIT2 1 -#define CUSTOM_LISTENER 2 - -static int connect_to_server(int server_fd) -{ - struct sockaddr_storage addr; - socklen_t len = sizeof(addr); - int fd; - - fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) { - log_err("Failed to create client socket"); - return -1; - } - - if (getsockname(server_fd, (struct sockaddr *)&addr, &len)) { - log_err("Failed to get server addr"); - goto out; - } - - if (connect(fd, (const struct sockaddr *)&addr, len) < 0) { - log_err("Fail to connect to server"); - goto out; - } - - return fd; - -out: - close(fd); - return -1; -} - -static int verify_sockopt(int fd, int optname, const char *msg, char expected) -{ - socklen_t optlen = 1; - char buf = 0; - int err; - - err = getsockopt(fd, SOL_CUSTOM, optname, &buf, &optlen); - if (err) { - log_err("%s: failed to call getsockopt", msg); - return 1; - } - - printf("%s %d: got=0x%x ? expected=0x%x\n", msg, optname, buf, expected); - - if (buf != expected) { - log_err("%s: unexpected getsockopt value %d != %d", msg, - buf, expected); - return 1; - } - - return 0; -} - -static void *server_thread(void *arg) -{ - struct sockaddr_storage addr; - socklen_t len = sizeof(addr); - int fd = *(int *)arg; - int client_fd; - int err = 0; - - if (listen(fd, 1) < 0) - error(1, errno, "Failed to listed on socket"); - - err += verify_sockopt(fd, CUSTOM_INHERIT1, "listen", 1); - err += verify_sockopt(fd, CUSTOM_INHERIT2, "listen", 1); - err += verify_sockopt(fd, CUSTOM_LISTENER, "listen", 1); - - client_fd = accept(fd, (struct sockaddr *)&addr, &len); - if (client_fd < 0) - error(1, errno, "Failed to accept client"); - - err += verify_sockopt(client_fd, CUSTOM_INHERIT1, "accept", 1); - err += verify_sockopt(client_fd, CUSTOM_INHERIT2, "accept", 1); - err += verify_sockopt(client_fd, CUSTOM_LISTENER, "accept", 0); - - close(client_fd); - - return (void *)(long)err; -} - -static int start_server(void) -{ - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_addr.s_addr = htonl(INADDR_LOOPBACK), - }; - char buf; - int err; - int fd; - int i; - - fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) { - log_err("Failed to create server socket"); - return -1; - } - - for (i = CUSTOM_INHERIT1; i <= CUSTOM_LISTENER; i++) { - buf = 0x01; - err = setsockopt(fd, SOL_CUSTOM, i, &buf, 1); - if (err) { - log_err("Failed to call setsockopt(%d)", i); - close(fd); - return -1; - } - } - - if (bind(fd, (const struct sockaddr *)&addr, sizeof(addr)) < 0) { - log_err("Failed to bind socket"); - close(fd); - return -1; - } - - return fd; -} - -static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title) -{ - enum bpf_attach_type attach_type; - enum bpf_prog_type prog_type; - struct bpf_program *prog; - int err; - - err = libbpf_prog_type_by_name(title, &prog_type, &attach_type); - if (err) { - log_err("Failed to deduct types for %s BPF program", title); - return -1; - } - - prog = bpf_object__find_program_by_title(obj, title); - if (!prog) { - log_err("Failed to find %s BPF program", title); - return -1; - } - - err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, - attach_type, 0); - if (err) { - log_err("Failed to attach %s BPF program", title); - return -1; - } - - return 0; -} - -static int run_test(int cgroup_fd) -{ - struct bpf_prog_load_attr attr = { - .file = "./sockopt_inherit.o", - }; - int server_fd = -1, client_fd; - struct bpf_object *obj; - void *server_err; - pthread_t tid; - int ignored; - int err; - - err = bpf_prog_load_xattr(&attr, &obj, &ignored); - if (err) { - log_err("Failed to load BPF object"); - return -1; - } - - err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt"); - if (err) - goto close_bpf_object; - - err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt"); - if (err) - goto close_bpf_object; - - server_fd = start_server(); - if (server_fd < 0) { - err = -1; - goto close_bpf_object; - } - - pthread_create(&tid, NULL, server_thread, (void *)&server_fd); - - client_fd = connect_to_server(server_fd); - if (client_fd < 0) { - err = -1; - goto close_server_fd; - } - - err += verify_sockopt(client_fd, CUSTOM_INHERIT1, "connect", 0); - err += verify_sockopt(client_fd, CUSTOM_INHERIT2, "connect", 0); - err += verify_sockopt(client_fd, CUSTOM_LISTENER, "connect", 0); - - pthread_join(tid, &server_err); - - err += (int)(long)server_err; - - close(client_fd); - -close_server_fd: - close(server_fd); -close_bpf_object: - bpf_object__close(obj); - return err; -} - -int main(int args, char **argv) -{ - int cgroup_fd; - int err = EXIT_SUCCESS; - - if (setup_cgroup_environment()) - return err; - - cgroup_fd = create_and_get_cgroup(CG_PATH); - if (cgroup_fd < 0) - goto cleanup_cgroup_env; - - if (join_cgroup(CG_PATH)) - goto cleanup_cgroup; - - if (run_test(cgroup_fd)) - err = EXIT_FAILURE; - - printf("test_sockopt_inherit: %s\n", - err == EXIT_SUCCESS ? "PASSED" : "FAILED"); - -cleanup_cgroup: - close(cgroup_fd); -cleanup_cgroup_env: - cleanup_cgroup_environment(); - return err; -} -- cgit v1.2.3-59-g8ed1b From 1f4f80fed217e8186a7e1067ae71260e133012ce Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Wed, 4 Sep 2019 09:25:09 -0700 Subject: selftests/bpf: test_progs: convert test_tcp_rtt Move the files, adjust includes, remove entry from Makefile & .gitignore Signed-off-by: Stanislav Fomichev Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/.gitignore | 1 - tools/testing/selftests/bpf/Makefile | 3 +- tools/testing/selftests/bpf/prog_tests/tcp_rtt.c | 256 ++++++++++++++++++++ tools/testing/selftests/bpf/test_tcp_rtt.c | 285 ----------------------- 4 files changed, 257 insertions(+), 288 deletions(-) create mode 100644 tools/testing/selftests/bpf/prog_tests/tcp_rtt.c delete mode 100644 tools/testing/selftests/bpf/test_tcp_rtt.c (limited to 'tools') diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore index 5b06bb45b500..7470327edcfe 100644 --- a/tools/testing/selftests/bpf/.gitignore +++ b/tools/testing/selftests/bpf/.gitignore @@ -39,4 +39,3 @@ libbpf.so.* test_hashmap test_btf_dump xdping -test_tcp_rtt diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 4d9a0304a011..7f3196af1ae4 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -28,7 +28,7 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test test_sock test_btf test_sockmap get_cgroup_id_user test_socket_cookie \ test_cgroup_storage test_select_reuseport test_section_names \ test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap \ - test_btf_dump test_cgroup_attach xdping test_tcp_rtt + test_btf_dump test_cgroup_attach xdping BPF_OBJ_FILES = $(patsubst %.c,%.o, $(notdir $(wildcard progs/*.c))) TEST_GEN_FILES = $(BPF_OBJ_FILES) @@ -112,7 +112,6 @@ $(OUTPUT)/test_netcnt: cgroup_helpers.c $(OUTPUT)/test_sock_fields: cgroup_helpers.c $(OUTPUT)/test_sysctl: cgroup_helpers.c $(OUTPUT)/test_cgroup_attach: cgroup_helpers.c -$(OUTPUT)/test_tcp_rtt: cgroup_helpers.c .PHONY: force diff --git a/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c b/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c new file mode 100644 index 000000000000..fdc0b3614a9e --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c @@ -0,0 +1,256 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include "cgroup_helpers.h" + +struct tcp_rtt_storage { + __u32 invoked; + __u32 dsack_dups; + __u32 delivered; + __u32 delivered_ce; + __u32 icsk_retransmits; +}; + +static void send_byte(int fd) +{ + char b = 0x55; + + if (CHECK_FAIL(write(fd, &b, sizeof(b)) != 1)) + perror("Failed to send single byte"); +} + +static int wait_for_ack(int fd, int retries) +{ + struct tcp_info info; + socklen_t optlen; + int i, err; + + for (i = 0; i < retries; i++) { + optlen = sizeof(info); + err = getsockopt(fd, SOL_TCP, TCP_INFO, &info, &optlen); + if (err < 0) { + log_err("Failed to lookup TCP stats"); + return err; + } + + if (info.tcpi_unacked == 0) + return 0; + + usleep(10); + } + + log_err("Did not receive ACK"); + return -1; +} + +static int verify_sk(int map_fd, int client_fd, const char *msg, __u32 invoked, + __u32 dsack_dups, __u32 delivered, __u32 delivered_ce, + __u32 icsk_retransmits) +{ + int err = 0; + struct tcp_rtt_storage val; + + if (CHECK_FAIL(bpf_map_lookup_elem(map_fd, &client_fd, &val) < 0)) { + perror("Failed to read socket storage"); + return -1; + } + + if (val.invoked != invoked) { + log_err("%s: unexpected bpf_tcp_sock.invoked %d != %d", + msg, val.invoked, invoked); + err++; + } + + if (val.dsack_dups != dsack_dups) { + log_err("%s: unexpected bpf_tcp_sock.dsack_dups %d != %d", + msg, val.dsack_dups, dsack_dups); + err++; + } + + if (val.delivered != delivered) { + log_err("%s: unexpected bpf_tcp_sock.delivered %d != %d", + msg, val.delivered, delivered); + err++; + } + + if (val.delivered_ce != delivered_ce) { + log_err("%s: unexpected bpf_tcp_sock.delivered_ce %d != %d", + msg, val.delivered_ce, delivered_ce); + err++; + } + + if (val.icsk_retransmits != icsk_retransmits) { + log_err("%s: unexpected bpf_tcp_sock.icsk_retransmits %d != %d", + msg, val.icsk_retransmits, icsk_retransmits); + err++; + } + + return err; +} + +static int connect_to_server(int server_fd) +{ + struct sockaddr_storage addr; + socklen_t len = sizeof(addr); + int fd; + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) { + log_err("Failed to create client socket"); + return -1; + } + + if (getsockname(server_fd, (struct sockaddr *)&addr, &len)) { + log_err("Failed to get server addr"); + goto out; + } + + if (connect(fd, (const struct sockaddr *)&addr, len) < 0) { + log_err("Fail to connect to server"); + goto out; + } + + return fd; + +out: + close(fd); + return -1; +} + +static int run_test(int cgroup_fd, int server_fd) +{ + struct bpf_prog_load_attr attr = { + .prog_type = BPF_PROG_TYPE_SOCK_OPS, + .file = "./tcp_rtt.o", + .expected_attach_type = BPF_CGROUP_SOCK_OPS, + }; + struct bpf_object *obj; + struct bpf_map *map; + int client_fd; + int prog_fd; + int map_fd; + int err; + + err = bpf_prog_load_xattr(&attr, &obj, &prog_fd); + if (err) { + log_err("Failed to load BPF object"); + return -1; + } + + map = bpf_map__next(NULL, obj); + map_fd = bpf_map__fd(map); + + err = bpf_prog_attach(prog_fd, cgroup_fd, BPF_CGROUP_SOCK_OPS, 0); + if (err) { + log_err("Failed to attach BPF program"); + goto close_bpf_object; + } + + client_fd = connect_to_server(server_fd); + if (client_fd < 0) { + err = -1; + goto close_bpf_object; + } + + err += verify_sk(map_fd, client_fd, "syn-ack", + /*invoked=*/1, + /*dsack_dups=*/0, + /*delivered=*/1, + /*delivered_ce=*/0, + /*icsk_retransmits=*/0); + + send_byte(client_fd); + if (wait_for_ack(client_fd, 100) < 0) { + err = -1; + goto close_client_fd; + } + + + err += verify_sk(map_fd, client_fd, "first payload byte", + /*invoked=*/2, + /*dsack_dups=*/0, + /*delivered=*/2, + /*delivered_ce=*/0, + /*icsk_retransmits=*/0); + +close_client_fd: + close(client_fd); + +close_bpf_object: + bpf_object__close(obj); + return err; +} + +static int start_server(void) +{ + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_addr.s_addr = htonl(INADDR_LOOPBACK), + }; + int fd; + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) { + log_err("Failed to create server socket"); + return -1; + } + + if (bind(fd, (const struct sockaddr *)&addr, sizeof(addr)) < 0) { + log_err("Failed to bind socket"); + close(fd); + return -1; + } + + return fd; +} + +static void *server_thread(void *arg) +{ + struct sockaddr_storage addr; + socklen_t len = sizeof(addr); + int fd = *(int *)arg; + int client_fd; + + if (CHECK_FAIL(listen(fd, 1)) < 0) { + perror("Failed to listed on socket"); + return NULL; + } + + client_fd = accept(fd, (struct sockaddr *)&addr, &len); + if (CHECK_FAIL(client_fd < 0)) { + perror("Failed to accept client"); + return NULL; + } + + /* Wait for the next connection (that never arrives) + * to keep this thread alive to prevent calling + * close() on client_fd. + */ + if (CHECK_FAIL(accept(fd, (struct sockaddr *)&addr, &len) >= 0)) { + perror("Unexpected success in second accept"); + return NULL; + } + + close(client_fd); + + return NULL; +} + +void test_tcp_rtt(void) +{ + int server_fd, cgroup_fd; + pthread_t tid; + + cgroup_fd = test__join_cgroup("/tcp_rtt"); + if (CHECK_FAIL(cgroup_fd < 0)) + return; + + server_fd = start_server(); + if (CHECK_FAIL(server_fd < 0)) + goto close_cgroup_fd; + + pthread_create(&tid, NULL, server_thread, (void *)&server_fd); + CHECK_FAIL(run_test(cgroup_fd, server_fd)); + close(server_fd); +close_cgroup_fd: + close(cgroup_fd); +} diff --git a/tools/testing/selftests/bpf/test_tcp_rtt.c b/tools/testing/selftests/bpf/test_tcp_rtt.c deleted file mode 100644 index 93916a69823e..000000000000 --- a/tools/testing/selftests/bpf/test_tcp_rtt.c +++ /dev/null @@ -1,285 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "bpf_rlimit.h" -#include "bpf_util.h" -#include "cgroup_helpers.h" - -#define CG_PATH "/tcp_rtt" - -struct tcp_rtt_storage { - __u32 invoked; - __u32 dsack_dups; - __u32 delivered; - __u32 delivered_ce; - __u32 icsk_retransmits; -}; - -static void send_byte(int fd) -{ - char b = 0x55; - - if (write(fd, &b, sizeof(b)) != 1) - error(1, errno, "Failed to send single byte"); -} - -static int wait_for_ack(int fd, int retries) -{ - struct tcp_info info; - socklen_t optlen; - int i, err; - - for (i = 0; i < retries; i++) { - optlen = sizeof(info); - err = getsockopt(fd, SOL_TCP, TCP_INFO, &info, &optlen); - if (err < 0) { - log_err("Failed to lookup TCP stats"); - return err; - } - - if (info.tcpi_unacked == 0) - return 0; - - usleep(10); - } - - log_err("Did not receive ACK"); - return -1; -} - -static int verify_sk(int map_fd, int client_fd, const char *msg, __u32 invoked, - __u32 dsack_dups, __u32 delivered, __u32 delivered_ce, - __u32 icsk_retransmits) -{ - int err = 0; - struct tcp_rtt_storage val; - - if (bpf_map_lookup_elem(map_fd, &client_fd, &val) < 0) - error(1, errno, "Failed to read socket storage"); - - if (val.invoked != invoked) { - log_err("%s: unexpected bpf_tcp_sock.invoked %d != %d", - msg, val.invoked, invoked); - err++; - } - - if (val.dsack_dups != dsack_dups) { - log_err("%s: unexpected bpf_tcp_sock.dsack_dups %d != %d", - msg, val.dsack_dups, dsack_dups); - err++; - } - - if (val.delivered != delivered) { - log_err("%s: unexpected bpf_tcp_sock.delivered %d != %d", - msg, val.delivered, delivered); - err++; - } - - if (val.delivered_ce != delivered_ce) { - log_err("%s: unexpected bpf_tcp_sock.delivered_ce %d != %d", - msg, val.delivered_ce, delivered_ce); - err++; - } - - if (val.icsk_retransmits != icsk_retransmits) { - log_err("%s: unexpected bpf_tcp_sock.icsk_retransmits %d != %d", - msg, val.icsk_retransmits, icsk_retransmits); - err++; - } - - return err; -} - -static int connect_to_server(int server_fd) -{ - struct sockaddr_storage addr; - socklen_t len = sizeof(addr); - int fd; - - fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) { - log_err("Failed to create client socket"); - return -1; - } - - if (getsockname(server_fd, (struct sockaddr *)&addr, &len)) { - log_err("Failed to get server addr"); - goto out; - } - - if (connect(fd, (const struct sockaddr *)&addr, len) < 0) { - log_err("Fail to connect to server"); - goto out; - } - - return fd; - -out: - close(fd); - return -1; -} - -static int run_test(int cgroup_fd, int server_fd) -{ - struct bpf_prog_load_attr attr = { - .prog_type = BPF_PROG_TYPE_SOCK_OPS, - .file = "./tcp_rtt.o", - .expected_attach_type = BPF_CGROUP_SOCK_OPS, - }; - struct bpf_object *obj; - struct bpf_map *map; - int client_fd; - int prog_fd; - int map_fd; - int err; - - err = bpf_prog_load_xattr(&attr, &obj, &prog_fd); - if (err) { - log_err("Failed to load BPF object"); - return -1; - } - - map = bpf_map__next(NULL, obj); - map_fd = bpf_map__fd(map); - - err = bpf_prog_attach(prog_fd, cgroup_fd, BPF_CGROUP_SOCK_OPS, 0); - if (err) { - log_err("Failed to attach BPF program"); - goto close_bpf_object; - } - - client_fd = connect_to_server(server_fd); - if (client_fd < 0) { - err = -1; - goto close_bpf_object; - } - - err += verify_sk(map_fd, client_fd, "syn-ack", - /*invoked=*/1, - /*dsack_dups=*/0, - /*delivered=*/1, - /*delivered_ce=*/0, - /*icsk_retransmits=*/0); - - send_byte(client_fd); - if (wait_for_ack(client_fd, 100) < 0) { - err = -1; - goto close_client_fd; - } - - - err += verify_sk(map_fd, client_fd, "first payload byte", - /*invoked=*/2, - /*dsack_dups=*/0, - /*delivered=*/2, - /*delivered_ce=*/0, - /*icsk_retransmits=*/0); - -close_client_fd: - close(client_fd); - -close_bpf_object: - bpf_object__close(obj); - return err; -} - -static int start_server(void) -{ - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_addr.s_addr = htonl(INADDR_LOOPBACK), - }; - int fd; - - fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) { - log_err("Failed to create server socket"); - return -1; - } - - if (bind(fd, (const struct sockaddr *)&addr, sizeof(addr)) < 0) { - log_err("Failed to bind socket"); - close(fd); - return -1; - } - - return fd; -} - -static void *server_thread(void *arg) -{ - struct sockaddr_storage addr; - socklen_t len = sizeof(addr); - int fd = *(int *)arg; - int client_fd; - - if (listen(fd, 1) < 0) - error(1, errno, "Failed to listed on socket"); - - client_fd = accept(fd, (struct sockaddr *)&addr, &len); - if (client_fd < 0) - error(1, errno, "Failed to accept client"); - - /* Wait for the next connection (that never arrives) - * to keep this thread alive to prevent calling - * close() on client_fd. - */ - if (accept(fd, (struct sockaddr *)&addr, &len) >= 0) - error(1, errno, "Unexpected success in second accept"); - - close(client_fd); - - return NULL; -} - -int main(int args, char **argv) -{ - int server_fd, cgroup_fd; - int err = EXIT_SUCCESS; - pthread_t tid; - - if (setup_cgroup_environment()) - goto cleanup_obj; - - cgroup_fd = create_and_get_cgroup(CG_PATH); - if (cgroup_fd < 0) - goto cleanup_cgroup_env; - - if (join_cgroup(CG_PATH)) - goto cleanup_cgroup; - - server_fd = start_server(); - if (server_fd < 0) { - err = EXIT_FAILURE; - goto cleanup_cgroup; - } - - pthread_create(&tid, NULL, server_thread, (void *)&server_fd); - - if (run_test(cgroup_fd, server_fd)) - err = EXIT_FAILURE; - - close(server_fd); - - printf("test_sockopt_sk: %s\n", - err == EXIT_SUCCESS ? "PASSED" : "FAILED"); - -cleanup_cgroup: - close(cgroup_fd); -cleanup_cgroup_env: - cleanup_cgroup_environment(); -cleanup_obj: - return err; -} -- cgit v1.2.3-59-g8ed1b From 010764b8856e5ee5056113704dc4b914ebc88f1d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 21 Aug 2019 10:14:03 +0300 Subject: tools/power/x86/intel-speed-select: Fix a read overflow in isst_set_tdp_level_msr() The isst_send_msr_command() function will read 8 bytes but we are passing an address to an int (4 bytes) so it results in a read overflow. Fixes: 3fb4f7cd472c ("tools/power/x86: A tool to validate Intel Speed Select commands") Signed-off-by: Dan Carpenter Acked-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 8de4ac39a008..f724322856ed 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -190,6 +190,7 @@ int isst_get_get_trl(int cpu, int level, int avx_level, int *trl) int isst_set_tdp_level_msr(int cpu, int tdp_level) { + unsigned long long level = tdp_level; int ret; debug_printf("cpu: tdp_level via MSR %d\n", cpu, tdp_level); @@ -202,8 +203,7 @@ int isst_set_tdp_level_msr(int cpu, int tdp_level) if (tdp_level > 2) return -1; /* invalid value */ - ret = isst_send_msr_command(cpu, 0x64b, 1, - (unsigned long long *)&tdp_level); + ret = isst_send_msr_command(cpu, 0x64b, 1, &level); if (ret) return ret; -- cgit v1.2.3-59-g8ed1b From a8dc07448177dddd3947e89fe3904cb3169935c2 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 5 Sep 2019 08:03:03 -0400 Subject: tools/power/x86/intel-speed-select: Fix package typo packag_ should be package_. Signed-off-by: Prarit Bhargava Acked-by: Srinivas Pandruvada Cc: Srinivas Pandruvada Cc: David Arcari Cc: linux-kernel@vger.kernel.org Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-display.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index f368b8323742..0d9a53a5da2d 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -133,7 +133,7 @@ static void format_and_print(FILE *outf, int level, char *header, char *value) last_level = level; } -static void print_packag_info(int cpu, FILE *outf) +static void print_package_info(int cpu, FILE *outf) { char header[256]; @@ -261,7 +261,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, char value[256]; int i, base_level = 1; - print_packag_info(cpu, outf); + print_package_info(cpu, outf); for (i = 0; i <= pkg_dev->levels; ++i) { struct isst_pkg_ctdp_level_info *ctdp_level; @@ -397,7 +397,7 @@ void isst_ctdp_display_information_end(FILE *outf) void isst_pbf_display_information(int cpu, FILE *outf, int level, struct isst_pbf_info *pbf_info) { - print_packag_info(cpu, outf); + print_package_info(cpu, outf); _isst_pbf_display_information(cpu, outf, level, pbf_info, 4); format_and_print(outf, 1, NULL, NULL); } @@ -406,7 +406,7 @@ void isst_fact_display_information(int cpu, FILE *outf, int level, int fact_bucket, int fact_avx, struct isst_fact_info *fact_info) { - print_packag_info(cpu, outf); + print_package_info(cpu, outf); _isst_fact_display_information(cpu, outf, level, fact_bucket, fact_avx, fact_info, 4); format_and_print(outf, 1, NULL, NULL); -- cgit v1.2.3-59-g8ed1b From 43774c0dccb405a0b63a10829d45db4b74c29e40 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 5 Sep 2019 08:03:04 -0400 Subject: tools/power/x86/intel-speed-select: Fix help option typo Help is -h, not --h. Signed-off-by: Prarit Bhargava Acked-by: Srinivas Pandruvada Cc: Srinivas Pandruvada Cc: David Arcari Cc: linux-kernel@vger.kernel.org Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 91c5ad1685a1..d32af8210427 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1491,7 +1491,7 @@ static void usage(void) printf("intel-speed-select [OPTIONS] FEATURE COMMAND COMMAND_ARGUMENTS\n"); printf("\nUse this tool to enumerate and control the Intel Speed Select Technology features,\n"); printf("\nFEATURE : [perf-profile|base-freq|turbo-freq|core-power]\n"); - printf("\nFor help on each feature, use --h|--help\n"); + printf("\nFor help on each feature, use -h|--help\n"); printf("\tFor example: intel-speed-select perf-profile -h\n"); printf("\nFor additional help on each command for a feature, use --h|--help\n"); -- cgit v1.2.3-59-g8ed1b From 3ec2aef1b03eefeffe93817bd04068d3805d4a98 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 5 Sep 2019 08:03:05 -0400 Subject: tools/power/x86/intel-speed-select: Fix cpu-count output I have a system with 28 threads/socket but intel-speed-select reports a cpu-count of 29. Fix an off-by-one error in the cpu_count() function. Signed-off-by: Prarit Bhargava Acked-by: Srinivas Pandruvada Cc: Srinivas Pandruvada Cc: David Arcari Cc: linux-kernel@vger.kernel.org Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index d32af8210427..f81a28c6b586 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -304,7 +304,7 @@ static void set_cpu_present_cpu_mask(void) int get_cpu_count(int pkg_id, int die_id) { if (pkg_id < MAX_PACKAGE_COUNT && die_id < MAX_DIE_PER_PACKAGE) - return cpu_cnt[pkg_id][die_id] + 1; + return cpu_cnt[pkg_id][die_id]; return 0; } -- cgit v1.2.3-59-g8ed1b From dece22a2d5e37cf7c4cda9a7d5f036c9b3fdaccb Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 5 Sep 2019 08:03:06 -0400 Subject: tools/power/x86/intel-speed-select: Simplify output for turbo-freq and base-freq The current output of 'intel-speed-select -c 53 perf-profile info -l 0' shows speed-select-turbo-freq-support:1 speed-select-base-freq-support:1 speed-select-base-freq-enabled:0 speed-select-turbo-freq-enabled:0 Simplify the output to single lines displaying status of disabled, enabled, and unsupported. Signed-off-by: Prarit Bhargava Acked-by: Srinivas Pandruvada Cc: Srinivas Pandruvada Cc: David Arcari Cc: linux-kernel@vger.kernel.org Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-display.c | 30 ++++++++++++----------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 0d9a53a5da2d..3ae693efceaa 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -297,23 +297,25 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, format_and_print(outf, base_level + 4, header, value); snprintf(header, sizeof(header), - "speed-select-turbo-freq-support"); - snprintf(value, sizeof(value), "%d", ctdp_level->fact_support); + "speed-select-turbo-freq"); + if (ctdp_level->fact_support) { + if (ctdp_level->fact_enabled) + snprintf(value, sizeof(value), "enabled"); + else + snprintf(value, sizeof(value), "disabled"); + } else + snprintf(value, sizeof(value), "unsupported"); format_and_print(outf, base_level + 4, header, value); snprintf(header, sizeof(header), - "speed-select-base-freq-support"); - snprintf(value, sizeof(value), "%d", ctdp_level->pbf_support); - format_and_print(outf, base_level + 4, header, value); - - snprintf(header, sizeof(header), - "speed-select-base-freq-enabled"); - snprintf(value, sizeof(value), "%d", ctdp_level->pbf_enabled); - format_and_print(outf, base_level + 4, header, value); - - snprintf(header, sizeof(header), - "speed-select-turbo-freq-enabled"); - snprintf(value, sizeof(value), "%d", ctdp_level->fact_enabled); + "speed-select-base-freq"); + if (ctdp_level->pbf_support) { + if (ctdp_level->pbf_enabled) + snprintf(value, sizeof(value), "enabled"); + else + snprintf(value, sizeof(value), "disabled"); + } else + snprintf(value, sizeof(value), "unsupported"); format_and_print(outf, base_level + 4, header, value); snprintf(header, sizeof(header), "thermal-design-power(W)"); -- cgit v1.2.3-59-g8ed1b From 808088e4a1fb2d27a347db2890d43ae73c75a72f Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 5 Sep 2019 08:03:07 -0400 Subject: tools/power/x86/intel-speed-select: Switch output to MHz These features are introduced on new processors that will never operate in the KHz range. Save some zeros and switch the output to MHz. Signed-off-by: Prarit Bhargava Acked-by: Srinivas Pandruvada Cc: Srinivas Pandruvada Cc: David Arcari Cc: linux-kernel@vger.kernel.org Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-display.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 3ae693efceaa..4ec1924ff7a9 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -6,7 +6,7 @@ #include "isst.h" -#define DISP_FREQ_MULTIPLIER 100000 +#define DISP_FREQ_MULTIPLIER 100 static void printcpumask(int str_len, char *str, int mask_size, cpu_set_t *cpu_mask) @@ -156,7 +156,7 @@ static void _isst_pbf_display_information(int cpu, FILE *outf, int level, snprintf(header, sizeof(header), "speed-select-base-freq"); format_and_print(outf, disp_level, header, NULL); - snprintf(header, sizeof(header), "high-priority-base-frequency(KHz)"); + snprintf(header, sizeof(header), "high-priority-base-frequency(MHz)"); snprintf(value, sizeof(value), "%d", pbf_info->p1_high * DISP_FREQ_MULTIPLIER); format_and_print(outf, disp_level + 1, header, value); @@ -166,7 +166,7 @@ static void _isst_pbf_display_information(int cpu, FILE *outf, int level, pbf_info->core_cpumask); format_and_print(outf, disp_level + 1, header, value); - snprintf(header, sizeof(header), "low-priority-base-frequency(KHz)"); + snprintf(header, sizeof(header), "low-priority-base-frequency(MHz)"); snprintf(value, sizeof(value), "%d", pbf_info->p1_low * DISP_FREQ_MULTIPLIER); format_and_print(outf, disp_level + 1, header, value); @@ -209,7 +209,7 @@ static void _isst_fact_display_information(int cpu, FILE *outf, int level, if (fact_avx & 0x01) { snprintf(header, sizeof(header), - "high-priority-max-frequency(KHz)"); + "high-priority-max-frequency(MHz)"); snprintf(value, sizeof(value), "%d", bucket_info[j].sse_trl * DISP_FREQ_MULTIPLIER); format_and_print(outf, base_level + 2, header, value); @@ -217,7 +217,7 @@ static void _isst_fact_display_information(int cpu, FILE *outf, int level, if (fact_avx & 0x02) { snprintf(header, sizeof(header), - "high-priority-max-avx2-frequency(KHz)"); + "high-priority-max-avx2-frequency(MHz)"); snprintf(value, sizeof(value), "%d", bucket_info[j].avx_trl * DISP_FREQ_MULTIPLIER); format_and_print(outf, base_level + 2, header, value); @@ -225,7 +225,7 @@ static void _isst_fact_display_information(int cpu, FILE *outf, int level, if (fact_avx & 0x04) { snprintf(header, sizeof(header), - "high-priority-max-avx512-frequency(KHz)"); + "high-priority-max-avx512-frequency(MHz)"); snprintf(value, sizeof(value), "%d", bucket_info[j].avx512_trl * DISP_FREQ_MULTIPLIER); @@ -235,19 +235,19 @@ static void _isst_fact_display_information(int cpu, FILE *outf, int level, snprintf(header, sizeof(header), "speed-select-turbo-freq-clip-frequencies"); format_and_print(outf, base_level + 1, header, NULL); - snprintf(header, sizeof(header), "low-priority-max-frequency(KHz)"); + snprintf(header, sizeof(header), "low-priority-max-frequency(MHz)"); snprintf(value, sizeof(value), "%d", fact_info->lp_clipping_ratio_license_sse * DISP_FREQ_MULTIPLIER); format_and_print(outf, base_level + 2, header, value); snprintf(header, sizeof(header), - "low-priority-max-avx2-frequency(KHz)"); + "low-priority-max-avx2-frequency(MHz)"); snprintf(value, sizeof(value), "%d", fact_info->lp_clipping_ratio_license_avx2 * DISP_FREQ_MULTIPLIER); format_and_print(outf, base_level + 2, header, value); snprintf(header, sizeof(header), - "low-priority-max-avx512-frequency(KHz)"); + "low-priority-max-avx512-frequency(MHz)"); snprintf(value, sizeof(value), "%d", fact_info->lp_clipping_ratio_license_avx512 * DISP_FREQ_MULTIPLIER); @@ -291,7 +291,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, snprintf(value, sizeof(value), "%d", ctdp_level->tdp_ratio); format_and_print(outf, base_level + 4, header, value); - snprintf(header, sizeof(header), "base-frequency(KHz)"); + snprintf(header, sizeof(header), "base-frequency(MHz)"); snprintf(value, sizeof(value), "%d", ctdp_level->tdp_ratio * DISP_FREQ_MULTIPLIER); format_and_print(outf, base_level + 4, header, value); -- cgit v1.2.3-59-g8ed1b From 76c2ef35f73913380f32d473a181d68decfca4f4 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 5 Sep 2019 08:03:08 -0400 Subject: tools/power/x86/intel-speed-select: Change turbo ratio output to maximum turbo frequency The intel-speed-select tool currently outputs the turbo ratio for every bucket. Make the output more user-friendly by changing the output to the maximum turbo frequency. Signed-off-by: Prarit Bhargava Acked-by: Srinivas Pandruvada Cc: Srinivas Pandruvada Cc: David Arcari Cc: linux-kernel@vger.kernel.org Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-display.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 4ec1924ff7a9..cfeee0beb78d 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -336,9 +336,11 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, snprintf(value, sizeof(value), "%d", j); format_and_print(outf, base_level + 6, header, value); - snprintf(header, sizeof(header), "turbo-ratio"); + snprintf(header, sizeof(header), + "max-turbo-frequency(MHz)"); snprintf(value, sizeof(value), "%d", - ctdp_level->trl_sse_active_cores[j]); + ctdp_level->trl_sse_active_cores[j] * + DISP_FREQ_MULTIPLIER); format_and_print(outf, base_level + 6, header, value); } snprintf(header, sizeof(header), "turbo-ratio-limits-avx"); @@ -351,9 +353,11 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, snprintf(value, sizeof(value), "%d", j); format_and_print(outf, base_level + 6, header, value); - snprintf(header, sizeof(header), "turbo-ratio"); + snprintf(header, sizeof(header), + "max-turbo-frequency(MHz)"); snprintf(value, sizeof(value), "%d", - ctdp_level->trl_avx_active_cores[j]); + ctdp_level->trl_avx_active_cores[j] * + DISP_FREQ_MULTIPLIER); format_and_print(outf, base_level + 6, header, value); } @@ -367,9 +371,11 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, snprintf(value, sizeof(value), "%d", j); format_and_print(outf, base_level + 6, header, value); - snprintf(header, sizeof(header), "turbo-ratio"); + snprintf(header, sizeof(header), + "max-turbo-frequency(MHz)"); snprintf(value, sizeof(value), "%d", - ctdp_level->trl_avx_512_active_cores[j]); + ctdp_level->trl_avx_512_active_cores[j] * + DISP_FREQ_MULTIPLIER); format_and_print(outf, base_level + 6, header, value); } if (ctdp_level->pbf_support) -- cgit v1.2.3-59-g8ed1b From 49aed155ec1b07f8820cceec7317c597a6f69c6e Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 5 Sep 2019 08:03:09 -0400 Subject: tools/power/x86/intel-speed-select: Output human readable CPU list The intel-speed-select tool currently only outputs a hexidecimal CPU mask, which requires translation for use with kernel parameters such as isolcpus. Along with the CPU mask, output a human readable CPU list. Signed-off-by: Prarit Bhargava Acked-by: Srinivas Pandruvada Cc: Srinivas Pandruvada Cc: David Arcari Cc: linux-kernel@vger.kernel.org Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-display.c | 39 +++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index cfeee0beb78d..890a01bfee4b 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -8,6 +8,33 @@ #define DISP_FREQ_MULTIPLIER 100 +static void printcpulist(int str_len, char *str, int mask_size, + cpu_set_t *cpu_mask) +{ + int i, first, curr_index, index; + + if (!CPU_COUNT_S(mask_size, cpu_mask)) { + snprintf(str, str_len, "none"); + return; + } + + curr_index = 0; + first = 1; + for (i = 0; i < get_topo_max_cpus(); ++i) { + if (!CPU_ISSET_S(i, mask_size, cpu_mask)) + continue; + if (!first) { + index = snprintf(&str[curr_index], + str_len - curr_index, ","); + curr_index += index; + } + index = snprintf(&str[curr_index], str_len - curr_index, "%d", + i); + curr_index += index; + first = 0; + } +} + static void printcpumask(int str_len, char *str, int mask_size, cpu_set_t *cpu_mask) { @@ -166,6 +193,12 @@ static void _isst_pbf_display_information(int cpu, FILE *outf, int level, pbf_info->core_cpumask); format_and_print(outf, disp_level + 1, header, value); + snprintf(header, sizeof(header), "high-priority-cpu-list"); + printcpulist(sizeof(value), value, + pbf_info->core_cpumask_size, + pbf_info->core_cpumask); + format_and_print(outf, disp_level + 1, header, value); + snprintf(header, sizeof(header), "low-priority-base-frequency(MHz)"); snprintf(value, sizeof(value), "%d", pbf_info->p1_low * DISP_FREQ_MULTIPLIER); @@ -287,6 +320,12 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, ctdp_level->core_cpumask); format_and_print(outf, base_level + 4, header, value); + snprintf(header, sizeof(header), "enable-cpu-list"); + printcpulist(sizeof(value), value, + ctdp_level->core_cpumask_size, + ctdp_level->core_cpumask); + format_and_print(outf, base_level + 4, header, value); + snprintf(header, sizeof(header), "thermal-design-power-ratio"); snprintf(value, sizeof(value), "%d", ctdp_level->tdp_ratio); format_and_print(outf, base_level + 4, header, value); -- cgit v1.2.3-59-g8ed1b From 522586a9d5c32b5d7569237eebbfd8241f196419 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 5 Sep 2019 08:03:10 -0400 Subject: tools/power/x86/intel-speed-select: Output success/failed for command output Command output has confusing data, returning "0" on success. For example |# ./intel-speed-select -c 14 turbo-freq enable Intel(R) Speed Select Technology Executing on CPU model:106[0x6a] package-1 die-0 cpu-14 turbo-freq enable:0 To avoid confusion change the command output to 'success' or 'failed'. v2: Remove help output line. Signed-off-by: Prarit Bhargava Acked-by: Srinivas Pandruvada Cc: Srinivas Pandruvada Cc: David Arcari Cc: linux-kernel@vger.kernel.org Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 1 - tools/power/x86/intel-speed-select/isst-display.c | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index f81a28c6b586..78f0cebda1da 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1514,7 +1514,6 @@ static void usage(void) printf("\tResult display uses a common format for each command:\n"); printf("\tResults are formatted in text/JSON with\n"); printf("\t\tPackage, Die, CPU, and command specific results.\n"); - printf("\t\t\tFor Set commands, status is 0 for success and rest for failures\n"); exit(1); } diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 890a01bfee4b..8500cf2997a6 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -519,7 +519,10 @@ void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd, snprintf(header, sizeof(header), "%s", feature); format_and_print(outf, 4, header, NULL); snprintf(header, sizeof(header), "%s", cmd); - snprintf(value, sizeof(value), "%d", result); + if (!result) + snprintf(value, sizeof(value), "success"); + else + snprintf(value, sizeof(value), "failed(error %d)", result); format_and_print(outf, 5, header, value); format_and_print(outf, 1, NULL, NULL); -- cgit v1.2.3-59-g8ed1b From 3bc3d30ca324bfc3045a1a7fe1f5fe5ad5d92fd9 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 5 Sep 2019 08:03:11 -0400 Subject: tools/power/x86/intel-speed-select: Fix memory leak cpumasks are allocated by calling the alloc_cpu_mask() function and are never free'd. They should be free'd after the commands have run. Fix the memory leaks by calling free_cpu_set(). Signed-off-by: Prarit Bhargava Acked-by: Srinivas Pandruvada Cc: Srinivas Pandruvada Cc: David Arcari Cc: linux-kernel@vger.kernel.org Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 78f0cebda1da..59753b3917bb 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -603,6 +603,10 @@ static int isst_fill_platform_info(void) close(fd); + if (isst_platform_info.api_version > supported_api_ver) { + printf("Incompatible API versions; Upgrade of tool is required\n"); + return -1; + } return 0; } @@ -1528,6 +1532,7 @@ static void cmdline(int argc, char **argv) { int opt; int option_index = 0; + int ret; static struct option long_options[] = { { "cpu", required_argument, 0, 'c' }, @@ -1589,13 +1594,14 @@ static void cmdline(int argc, char **argv) set_max_cpu_num(); set_cpu_present_cpu_mask(); set_cpu_target_cpu_mask(); - isst_fill_platform_info(); - if (isst_platform_info.api_version > supported_api_ver) { - printf("Incompatible API versions; Upgrade of tool is required\n"); - exit(0); - } + ret = isst_fill_platform_info(); + if (ret) + goto out; process_command(argc, argv); +out: + free_cpu_set(present_cpumask); + free_cpu_set(target_cpumask); } int main(int argc, char **argv) -- cgit v1.2.3-59-g8ed1b From 1233c7b95c7045905e40c11484493f20ab521d21 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Sun, 8 Sep 2019 07:42:25 -0700 Subject: tools/power/x86/intel-speed-select: Display core count for bucket Read the bucket and core count relationship via MSR and display when displaying turbo ratio limits. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-core.c | 22 ++++++++++++++++++++++ tools/power/x86/intel-speed-select/isst-display.c | 6 +++--- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 26 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index f724322856ed..0bf341ad9697 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -188,6 +188,24 @@ int isst_get_get_trl(int cpu, int level, int avx_level, int *trl) return 0; } +int isst_get_trl_bucket_info(int cpu, unsigned long long *buckets_info) +{ + int ret; + + debug_printf("cpu:%d bucket info via MSR\n", cpu); + + *buckets_info = 0; + + ret = isst_send_msr_command(cpu, 0x1ae, 0, buckets_info); + if (ret) + return ret; + + debug_printf("cpu:%d bucket info via MSR successful 0x%llx\n", cpu, + *buckets_info); + + return 0; +} + int isst_set_tdp_level_msr(int cpu, int tdp_level) { unsigned long long level = tdp_level; @@ -563,6 +581,10 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) if (ret) return ret; + ret = isst_get_trl_bucket_info(cpu, &ctdp_level->buckets_info); + if (ret) + return ret; + ret = isst_get_get_trl(cpu, i, 0, ctdp_level->trl_sse_active_cores); if (ret) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 8500cf2997a6..df4aa99c4e92 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -372,7 +372,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, format_and_print(outf, base_level + 5, header, NULL); snprintf(header, sizeof(header), "core-count"); - snprintf(value, sizeof(value), "%d", j); + snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff); format_and_print(outf, base_level + 6, header, value); snprintf(header, sizeof(header), @@ -389,7 +389,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, format_and_print(outf, base_level + 5, header, NULL); snprintf(header, sizeof(header), "core-count"); - snprintf(value, sizeof(value), "%d", j); + snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff); format_and_print(outf, base_level + 6, header, value); snprintf(header, sizeof(header), @@ -407,7 +407,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, format_and_print(outf, base_level + 5, header, NULL); snprintf(header, sizeof(header), "core-count"); - snprintf(value, sizeof(value), "%d", j); + snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff); format_and_print(outf, base_level + 6, header, value); snprintf(header, sizeof(header), diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 221881761609..2f7f62765eb6 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -134,6 +134,7 @@ struct isst_pkg_ctdp_level_info { size_t core_cpumask_size; cpu_set_t *core_cpumask; int cpu_count; + unsigned long long buckets_info; int trl_sse_active_cores[ISST_TRL_MAX_ACTIVE_CORES]; int trl_avx_active_cores[ISST_TRL_MAX_ACTIVE_CORES]; int trl_avx_512_active_cores[ISST_TRL_MAX_ACTIVE_CORES]; -- cgit v1.2.3-59-g8ed1b From f73b3cc39c84220e6dccd463b5c8279b03514646 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 29 Aug 2019 18:28:49 -0500 Subject: objtool: Clobber user CFLAGS variable If the build user has the CFLAGS variable set in their environment, objtool blindly appends to it, which can cause unexpected behavior. Clobber CFLAGS to ensure consistent objtool compilation behavior. Reported-by: Valdis Kletnieks Tested-by: Valdis Kletnieks Signed-off-by: Josh Poimboeuf Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: https://lkml.kernel.org/r/83a276df209962e6058fcb6c615eef9d401c21bc.1567121311.git.jpoimboe@redhat.com Signed-off-by: Ingo Molnar --- tools/objtool/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index 88158239622b..20f67fcf378d 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -35,7 +35,7 @@ INCLUDES := -I$(srctree)/tools/include \ -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \ -I$(srctree)/tools/objtool/arch/$(ARCH)/include WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed -CFLAGS += -Werror $(WARNINGS) $(KBUILD_HOSTCFLAGS) -g $(INCLUDES) $(LIBELF_FLAGS) +CFLAGS := -Werror $(WARNINGS) $(KBUILD_HOSTCFLAGS) -g $(INCLUDES) $(LIBELF_FLAGS) LDFLAGS += $(LIBELF_LIBS) $(LIBSUBCMD) $(KBUILD_HOSTLDFLAGS) # Allow old libelf to be used: -- cgit v1.2.3-59-g8ed1b From 5079bde790304959bf744c548efdd5be660ea8e2 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 1 Sep 2019 14:48:19 +0200 Subject: perf python: Add missing python/perf.so dependency for libperf The python/perf.so compilation needs libperf ready, otherwise it fails: $ make python/perf.so JOBS=1 BUILD: Doing 'make -j1' parallel build GEN python/perf.so gcc: error: /home/jolsa/kernel/linux-perf/tools/perf/lib/libperf.a: No such file or directory Fixing this with by adding libperf dependency. Signed-off-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190901124822.10132-2-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index f9807d8c005b..2ccc12f3730b 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -567,7 +567,7 @@ all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS) # Create python binding output directory if not already present _dummy := $(shell [ -d '$(OUTPUT)python' ] || mkdir -p '$(OUTPUT)python') -$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST) +$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST) $(LIBPERF) $(QUIET_GEN)LDSHARED="$(CC) -pthread -shared" \ CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS)' \ $(PYTHON_WORD) util/setup.py \ -- cgit v1.2.3-59-g8ed1b From 9eab951f34dbd092ab520bda167f288899858306 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 1 Sep 2019 14:48:21 +0200 Subject: perf tests: Add libperf automated test for 'make -C tools/perf build-test' Add a libperf build test, that is triggered when one does: $ make -C tools/perf build-test Signed-off-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190901124822.10132-4-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/make | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/tests/make b/tools/perf/tests/make index 70c48475896d..6b3afed5d910 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make @@ -327,6 +327,10 @@ make_kernelsrc_tools: (make -C ../../tools $(PARALLEL_OPT) $(K_O_OPT) perf) > $@ 2>&1 && \ test -x $(KERNEL_O)/tools/perf/perf && rm -f $@ || (cat $@ ; false) +make_libperf: + @echo "- make -C lib"; + make -C lib clean >$@ 2>&1; make -C lib >>$@ 2>&1 && rm $@ + FEATURES_DUMP_FILE := $(FULL_O)/BUILD_TEST_FEATURE_DUMP FEATURES_DUMP_FILE_STATIC := $(FULL_O)/BUILD_TEST_FEATURE_DUMP_STATIC @@ -365,5 +369,5 @@ $(foreach t,$(run),$(if $(findstring make_static,$(t)),\ $(eval $(t) := $($(t)) FEATURES_DUMP=$(FEATURES_DUMP_FILE)))) endif -.PHONY: all $(run) $(run_O) tarpkg clean make_kernelsrc make_kernelsrc_tools +.PHONY: all $(run) $(run_O) tarpkg clean make_kernelsrc make_kernelsrc_tools make_libperf endif # ifndef MK -- cgit v1.2.3-59-g8ed1b From 227cb129858a3eb4b874937274b09834ffcc39b0 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 1 Sep 2019 14:48:22 +0200 Subject: libperf: Add missing event.h file to install rule So that this development header is properly installed and can be found by tools linking with libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190901124822.10132-5-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/lib/Makefile b/tools/perf/lib/Makefile index a67efb8d9d39..e325c0503dc6 100644 --- a/tools/perf/lib/Makefile +++ b/tools/perf/lib/Makefile @@ -146,6 +146,7 @@ install_headers: $(call do_install,include/perf/threadmap.h,$(prefix)/include/perf,644); \ $(call do_install,include/perf/evlist.h,$(prefix)/include/perf,644); \ $(call do_install,include/perf/evsel.h,$(prefix)/include/perf,644); + $(call do_install,include/perf/event.h,$(prefix)/include/perf,644); install_pkgconfig: $(LIBPERF_PC) $(call QUIET_INSTALL, $(LIBPERF_PC)) \ -- cgit v1.2.3-59-g8ed1b From 4256d434935e9c85a731823be562785494ca364b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 2 Sep 2019 14:12:53 +0200 Subject: libperf: Adopt perf_cpu_map__max() function From 'perf stat', so that it can be used from multiple places. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Joe Mario Cc: Kan Liang Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190902121255.536-2-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 14 +------------- tools/perf/lib/cpumap.c | 12 ++++++++++++ tools/perf/lib/include/perf/cpumap.h | 1 + tools/perf/lib/libperf.map | 1 + 4 files changed, 15 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 7e17bf9f700a..5bc0c570b7b6 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -822,18 +822,6 @@ static int perf_stat__get_core(struct perf_stat_config *config __maybe_unused, return cpu_map__get_core(map, cpu, NULL); } -static int cpu_map__get_max(struct perf_cpu_map *map) -{ - int i, max = -1; - - for (i = 0; i < map->nr; i++) { - if (map->map[i] > max) - max = map->map[i]; - } - - return max; -} - static int perf_stat__get_aggr(struct perf_stat_config *config, aggr_get_id_t get_id, struct perf_cpu_map *map, int idx) { @@ -928,7 +916,7 @@ static int perf_stat_init_aggr_mode(void) * taking the highest cpu number to be the size of * the aggregation translate cpumap. */ - nr = cpu_map__get_max(evsel_list->core.cpus); + nr = perf_cpu_map__max(evsel_list->core.cpus); stat_config.cpus_aggr_map = perf_cpu_map__empty_new(nr + 1); return stat_config.cpus_aggr_map ? 0 : -ENOMEM; } diff --git a/tools/perf/lib/cpumap.c b/tools/perf/lib/cpumap.c index 1f0e6f334237..2ca1fafa620d 100644 --- a/tools/perf/lib/cpumap.c +++ b/tools/perf/lib/cpumap.c @@ -260,3 +260,15 @@ int perf_cpu_map__idx(struct perf_cpu_map *cpus, int cpu) return -1; } + +int perf_cpu_map__max(struct perf_cpu_map *map) +{ + int i, max = -1; + + for (i = 0; i < map->nr; i++) { + if (map->map[i] > max) + max = map->map[i]; + } + + return max; +} diff --git a/tools/perf/lib/include/perf/cpumap.h b/tools/perf/lib/include/perf/cpumap.h index 8aa995c59498..ac9aa497f84a 100644 --- a/tools/perf/lib/include/perf/cpumap.h +++ b/tools/perf/lib/include/perf/cpumap.h @@ -16,6 +16,7 @@ LIBPERF_API void perf_cpu_map__put(struct perf_cpu_map *map); LIBPERF_API int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx); LIBPERF_API int perf_cpu_map__nr(const struct perf_cpu_map *cpus); LIBPERF_API bool perf_cpu_map__empty(const struct perf_cpu_map *map); +LIBPERF_API int perf_cpu_map__max(struct perf_cpu_map *map); #define perf_cpu_map__for_each_cpu(cpu, idx, cpus) \ for ((idx) = 0, (cpu) = perf_cpu_map__cpu(cpus, idx); \ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index dc4d66363bc4..cd0d17b996c8 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -9,6 +9,7 @@ LIBPERF_0.0.1 { perf_cpu_map__nr; perf_cpu_map__cpu; perf_cpu_map__empty; + perf_cpu_map__max; perf_thread_map__new_dummy; perf_thread_map__set_pid; perf_thread_map__comm; -- cgit v1.2.3-59-g8ed1b From e742bd5cb55ec0be48c5e7b356393a708e7f73c9 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 4 Sep 2019 12:45:54 -0700 Subject: iocost_monitor: Always use strings for json values Json has limited accuracy for numbers and can silently truncate 64bit values, which can be extremely confusing. Let's consistently use string encapsulated values for json output. While at it, convert an unnecesary f-string to str(). Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- tools/cgroup/iocost_monitor.py | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'tools') diff --git a/tools/cgroup/iocost_monitor.py b/tools/cgroup/iocost_monitor.py index 2c9445e966d8..8f6b4ac377bd 100644 --- a/tools/cgroup/iocost_monitor.py +++ b/tools/cgroup/iocost_monitor.py @@ -111,14 +111,14 @@ class IocStat: def dict(self, now): return { 'device' : devname, - 'timestamp' : now, - 'enabled' : self.enabled, - 'running' : self.running, - 'period_ms' : self.period_ms, - 'period_at' : self.period_at, - 'period_vtime_at' : self.vperiod_at, - 'busy_level' : self.busy_level, - 'vrate_pct' : self.vrate_pct, } + 'timestamp' : str(now), + 'enabled' : str(int(self.enabled)), + 'running' : str(int(self.running)), + 'period_ms' : str(self.period_ms), + 'period_at' : str(self.period_at), + 'period_vtime_at' : str(self.vperiod_at), + 'busy_level' : str(self.busy_level), + 'vrate_pct' : str(self.vrate_pct), } def table_preamble_str(self): state = ('RUN' if self.running else 'IDLE') if self.enabled else 'OFF' @@ -171,19 +171,19 @@ class IocgStat: def dict(self, now, path): out = { 'cgroup' : path, - 'timestamp' : now, - 'is_active' : self.is_active, - 'weight' : self.weight, - 'weight_active' : self.active, - 'weight_inuse' : self.inuse, - 'hweight_active_pct' : self.hwa_pct, - 'hweight_inuse_pct' : self.hwi_pct, - 'inflight_pct' : self.inflight_pct, - 'use_delay' : self.use_delay, - 'delay_ms' : self.delay_ms, - 'usage_pct' : self.usage } + 'timestamp' : str(now), + 'is_active' : str(int(self.is_active)), + 'weight' : str(self.weight), + 'weight_active' : str(self.active), + 'weight_inuse' : str(self.inuse), + 'hweight_active_pct' : str(self.hwa_pct), + 'hweight_inuse_pct' : str(self.hwi_pct), + 'inflight_pct' : str(self.inflight_pct), + 'use_delay' : str(self.use_delay), + 'delay_ms' : str(self.delay_ms), + 'usage_pct' : str(self.usage) } for i in range(len(self.usages)): - out[f'usage_pct_{i}'] = f'{self.usages[i]}' + out[f'usage_pct_{i}'] = str(self.usages[i]) return out def table_row_str(self, path): -- cgit v1.2.3-59-g8ed1b From b06f2d35c6b14d956f19eeabe1f257caeb66e38e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 4 Sep 2019 12:45:55 -0700 Subject: iocost_monitor: Report more info with higher accuracy When outputting json: * Don't truncate numbers. * Report address of iocg to ease drilling down further. When outputting table: * Use math.ceil() for delay_ms so that small delays don't read as 0. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- tools/cgroup/iocost_monitor.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/cgroup/iocost_monitor.py b/tools/cgroup/iocost_monitor.py index 8f6b4ac377bd..5d8bac603ffa 100644 --- a/tools/cgroup/iocost_monitor.py +++ b/tools/cgroup/iocost_monitor.py @@ -13,6 +13,7 @@ import sys import re import time import json +import math import drgn from drgn import container_of @@ -95,7 +96,7 @@ class IocStat: self.enabled = ioc.enabled.value_() self.running = ioc.running.value_() == IOC_RUNNING - self.period_ms = round(ioc.period_us.value_() / 1_000) + self.period_ms = ioc.period_us.value_() / 1_000 self.period_at = ioc.period_at.value_() / 1_000_000 self.vperiod_at = ioc.period_at_vtime.value_() / VTIME_PER_SEC self.vrate_pct = ioc.vtime_rate.counter.value_() * 100 / VTIME_PER_USEC @@ -147,6 +148,7 @@ class IocgStat: self.inuse = iocg.inuse.value_() self.hwa_pct = iocg.hweight_active.value_() * 100 / HWEIGHT_WHOLE self.hwi_pct = iocg.hweight_inuse.value_() * 100 / HWEIGHT_WHOLE + self.address = iocg.value_() vdone = iocg.done_vtime.counter.value_() vtime = iocg.vtime.counter.value_() @@ -157,15 +159,15 @@ class IocgStat: else: self.inflight_pct = 0 - self.use_delay = min(blkg.use_delay.counter.value_(), 99) - self.delay_ms = min(round(blkg.delay_nsec.counter.value_() / 1_000_000), 999) + self.use_delay = blkg.use_delay.counter.value_() + self.delay_ms = blkg.delay_nsec.counter.value_() / 1_000_000 usage_idx = iocg.usage_idx.value_() self.usages = [] self.usage = 0 for i in range(NR_USAGE_SLOTS): usage = iocg.usages[(usage_idx + i) % NR_USAGE_SLOTS].value_() - upct = min(usage * 100 / HWEIGHT_WHOLE, 999) + upct = usage * 100 / HWEIGHT_WHOLE self.usages.append(upct) self.usage = max(self.usage, upct) @@ -181,7 +183,8 @@ class IocgStat: 'inflight_pct' : str(self.inflight_pct), 'use_delay' : str(self.use_delay), 'delay_ms' : str(self.delay_ms), - 'usage_pct' : str(self.usage) } + 'usage_pct' : str(self.usage), + 'address' : str(hex(self.address)) } for i in range(len(self.usages)): out[f'usage_pct_{i}'] = str(self.usages[i]) return out @@ -192,9 +195,10 @@ class IocgStat: f'{self.inuse:5}/{self.active:5} ' \ f'{self.hwi_pct:6.2f}/{self.hwa_pct:6.2f} ' \ f'{self.inflight_pct:6.2f} ' \ - f'{self.use_delay:2}*{self.delay_ms:03} ' + f'{min(self.use_delay, 99):2}*'\ + f'{min(math.ceil(self.delay_ms), 999):03} ' for u in self.usages: - out += f'{round(u):03d}:' + out += f'{min(round(u), 999):03d}:' out = out.rstrip(':') return out -- cgit v1.2.3-59-g8ed1b From 7c1ee704a1d6450f92372d57f5b76a458b51c1d4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 4 Sep 2019 12:45:56 -0700 Subject: iocost_monitor: Report debt Report debt and rename del_ms row to delay for consistency. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- block/blk-iocost.c | 6 +++--- tools/cgroup/iocost_monitor.py | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/block/blk-iocost.c b/block/blk-iocost.c index e72e562d4aad..3b39deb8b9f8 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -161,9 +161,9 @@ * https://github.com/osandov/drgn. The ouput looks like the following. * * sdb RUN per=300ms cur_per=234.218:v203.695 busy= +1 vrate= 62.12% - * active weight hweight% inflt% del_ms usages% - * test/a * 50/ 50 33.33/ 33.33 27.65 0*041 033:033:033 - * test/b * 100/ 100 66.67/ 66.67 17.56 0*000 066:079:077 + * active weight hweight% inflt% dbt delay usages% + * test/a * 50/ 50 33.33/ 33.33 27.65 2 0*041 033:033:033 + * test/b * 100/ 100 66.67/ 66.67 17.56 0 0*000 066:079:077 * * - per : Timer period * - cur_per : Internal wall and device vtime clock diff --git a/tools/cgroup/iocost_monitor.py b/tools/cgroup/iocost_monitor.py index 5d8bac603ffa..f79b23582a1d 100644 --- a/tools/cgroup/iocost_monitor.py +++ b/tools/cgroup/iocost_monitor.py @@ -135,7 +135,7 @@ class IocStat: def table_header_str(self): return f'{"":25} active {"weight":>9} {"hweight%":>13} {"inflt%":>6} ' \ - f'{"del_ms":>6} {"usages%"}' + f'{"dbt":>3} {"delay":>6} {"usages%"}' class IocgStat: def __init__(self, iocg): @@ -159,6 +159,7 @@ class IocgStat: else: self.inflight_pct = 0 + self.debt_ms = iocg.abs_vdebt.counter.value_() / VTIME_PER_USEC / 1000 self.use_delay = blkg.use_delay.counter.value_() self.delay_ms = blkg.delay_nsec.counter.value_() / 1_000_000 @@ -181,6 +182,7 @@ class IocgStat: 'hweight_active_pct' : str(self.hwa_pct), 'hweight_inuse_pct' : str(self.hwi_pct), 'inflight_pct' : str(self.inflight_pct), + 'debt_ms' : str(self.debt_ms), 'use_delay' : str(self.use_delay), 'delay_ms' : str(self.delay_ms), 'usage_pct' : str(self.usage), @@ -195,6 +197,7 @@ class IocgStat: f'{self.inuse:5}/{self.active:5} ' \ f'{self.hwi_pct:6.2f}/{self.hwa_pct:6.2f} ' \ f'{self.inflight_pct:6.2f} ' \ + f'{min(math.ceil(self.debt_ms), 999):3} ' \ f'{min(self.use_delay, 99):2}*'\ f'{min(math.ceil(self.delay_ms), 999):03} ' for u in self.usages: -- cgit v1.2.3-59-g8ed1b From 6f62a8223e65c0571e48225d5d7e56de95225bae Mon Sep 17 00:00:00 2001 From: Santosh Sivaraj Date: Wed, 4 Sep 2019 03:13:59 +0530 Subject: seltests/powerpc: Add a selftest for memcpy_mcsafe Appropriate self tests for memcpy_mcsafe Suggested-by: Michael Ellerman Signed-off-by: Santosh Sivaraj Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20190903214359.23887-2-santosh@fossix.org --- tools/testing/selftests/powerpc/copyloops/.gitignore | 1 + tools/testing/selftests/powerpc/copyloops/Makefile | 7 ++++++- tools/testing/selftests/powerpc/copyloops/asm/export.h | 1 + tools/testing/selftests/powerpc/copyloops/memcpy_mcsafe_64.S | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) create mode 120000 tools/testing/selftests/powerpc/copyloops/memcpy_mcsafe_64.S (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/copyloops/.gitignore b/tools/testing/selftests/powerpc/copyloops/.gitignore index de158104912a..12ef5b031974 100644 --- a/tools/testing/selftests/powerpc/copyloops/.gitignore +++ b/tools/testing/selftests/powerpc/copyloops/.gitignore @@ -11,3 +11,4 @@ memcpy_p7_t1 copyuser_64_exc_t0 copyuser_64_exc_t1 copyuser_64_exc_t2 +memcpy_mcsafe_64 diff --git a/tools/testing/selftests/powerpc/copyloops/Makefile b/tools/testing/selftests/powerpc/copyloops/Makefile index 44574f3818b3..0917983a1c78 100644 --- a/tools/testing/selftests/powerpc/copyloops/Makefile +++ b/tools/testing/selftests/powerpc/copyloops/Makefile @@ -12,7 +12,7 @@ ASFLAGS = $(CFLAGS) -Wa,-mpower4 TEST_GEN_PROGS := copyuser_64_t0 copyuser_64_t1 copyuser_64_t2 \ copyuser_p7_t0 copyuser_p7_t1 \ memcpy_64_t0 memcpy_64_t1 memcpy_64_t2 \ - memcpy_p7_t0 memcpy_p7_t1 \ + memcpy_p7_t0 memcpy_p7_t1 memcpy_mcsafe_64 \ copyuser_64_exc_t0 copyuser_64_exc_t1 copyuser_64_exc_t2 EXTRA_SOURCES := validate.c ../harness.c stubs.S @@ -45,6 +45,11 @@ $(OUTPUT)/memcpy_p7_t%: memcpy_power7.S $(EXTRA_SOURCES) -D SELFTEST_CASE=$(subst memcpy_p7_t,,$(notdir $@)) \ -o $@ $^ +$(OUTPUT)/memcpy_mcsafe_64: memcpy_mcsafe_64.S $(EXTRA_SOURCES) + $(CC) $(CPPFLAGS) $(CFLAGS) \ + -D COPY_LOOP=test_memcpy_mcsafe \ + -o $@ $^ + $(OUTPUT)/copyuser_64_exc_t%: copyuser_64.S exc_validate.c ../harness.c \ copy_tofrom_user_reference.S stubs.S $(CC) $(CPPFLAGS) $(CFLAGS) \ diff --git a/tools/testing/selftests/powerpc/copyloops/asm/export.h b/tools/testing/selftests/powerpc/copyloops/asm/export.h index 05c1663c89b0..e6b80d5fbd14 100644 --- a/tools/testing/selftests/powerpc/copyloops/asm/export.h +++ b/tools/testing/selftests/powerpc/copyloops/asm/export.h @@ -1,3 +1,4 @@ /* SPDX-License-Identifier: GPL-2.0 */ #define EXPORT_SYMBOL(x) +#define EXPORT_SYMBOL_GPL(x) #define EXPORT_SYMBOL_KASAN(x) diff --git a/tools/testing/selftests/powerpc/copyloops/memcpy_mcsafe_64.S b/tools/testing/selftests/powerpc/copyloops/memcpy_mcsafe_64.S new file mode 120000 index 000000000000..f0feef3062f6 --- /dev/null +++ b/tools/testing/selftests/powerpc/copyloops/memcpy_mcsafe_64.S @@ -0,0 +1 @@ +../../../../../arch/powerpc/lib/memcpy_mcsafe_64.S \ No newline at end of file -- cgit v1.2.3-59-g8ed1b From 44e9d308a51fbf6d2e5a913f7452a5d5f1902249 Mon Sep 17 00:00:00 2001 From: Roman Gushchin Date: Thu, 12 Sep 2019 10:56:44 -0700 Subject: kselftests: cgroup: add freezer mkdir test Add a new cgroup freezer selftest, which checks that if a cgroup is frozen, their new child cgroups will properly inherit the frozen state. It creates a parent cgroup, freezes it, creates a child cgroup and populates it with a dummy process. Then it checks that both parent and child cgroup are frozen. Signed-off-by: Roman Gushchin Cc: Tejun Heo Cc: Shuah Khan Signed-off-by: Tejun Heo --- tools/testing/selftests/cgroup/test_freezer.c | 54 +++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/cgroup/test_freezer.c b/tools/testing/selftests/cgroup/test_freezer.c index 8219a30853d2..0fc1b6d4b0f9 100644 --- a/tools/testing/selftests/cgroup/test_freezer.c +++ b/tools/testing/selftests/cgroup/test_freezer.c @@ -447,6 +447,59 @@ cleanup: return ret; } +/* + * The test creates a cgroups and freezes it. Then it creates a child cgroup + * and populates it with a task. After that it checks that the child cgroup + * is frozen and the parent cgroup remains frozen too. + */ +static int test_cgfreezer_mkdir(const char *root) +{ + int ret = KSFT_FAIL; + char *parent, *child = NULL; + int pid; + + parent = cg_name(root, "cg_test_mkdir_A"); + if (!parent) + goto cleanup; + + child = cg_name(parent, "cg_test_mkdir_B"); + if (!child) + goto cleanup; + + if (cg_create(parent)) + goto cleanup; + + if (cg_freeze_wait(parent, true)) + goto cleanup; + + if (cg_create(child)) + goto cleanup; + + pid = cg_run_nowait(child, child_fn, NULL); + if (pid < 0) + goto cleanup; + + if (cg_wait_for_proc_count(child, 1)) + goto cleanup; + + if (cg_check_frozen(child, true)) + goto cleanup; + + if (cg_check_frozen(parent, true)) + goto cleanup; + + ret = KSFT_PASS; + +cleanup: + if (child) + cg_destroy(child); + free(child); + if (parent) + cg_destroy(parent); + free(parent); + return ret; +} + /* * The test creates two nested cgroups, freezes the parent * and removes the child. Then it checks that the parent cgroup @@ -815,6 +868,7 @@ struct cgfreezer_test { T(test_cgfreezer_simple), T(test_cgfreezer_tree), T(test_cgfreezer_forkbomb), + T(test_cgfreezer_mkdir), T(test_cgfreezer_rmdir), T(test_cgfreezer_migrate), T(test_cgfreezer_ptrace), -- cgit v1.2.3-59-g8ed1b From 4ce150b6a412f14074400eac5fc39d1a71c4ef0a Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Thu, 12 Sep 2019 18:05:43 +0200 Subject: selftests/bpf: add bpf-gcc support Now that binutils and gcc support for BPF is upstream, make use of it in BPF selftests using alu32-like approach. Share as much as possible of CFLAGS calculation with clang. Fixes only obvious issues, leaving more complex ones for later: - Use gcc-provided bpf-helpers.h instead of manually defining the helpers, change bpf_helpers.h include guard to avoid conflict. - Include for __always_inline. - Add $(OUTPUT)/../usr/include to include path in order to use local kernel headers instead of system kernel headers when building with O=. In order to activate the bpf-gcc support, one needs to configure binutils and gcc with --target=bpf and make them available in $PATH. In particular, gcc must be installed as `bpf-gcc`, which is the default. Right now with binutils 25a2915e8dba and gcc r275589 only a handful of tests work: # ./test_progs_bpf_gcc # Summary: 7/39 PASSED, 1 SKIPPED, 98 FAILED The reason for those failures are as follows: - Build errors: - `error: too many function arguments for eBPF` for __always_inline functions read_str_var and read_map_var - must be inlining issue, and for process_l3_headers_v6, which relies on optimizing away function arguments. - `error: indirect call in function, which are not supported by eBPF` where there are no obvious indirect calls in the source calls, e.g. in __encap_ipip_none. - `error: field 'lock' has incomplete type` for fields of `struct bpf_spin_lock` type - bpf_spin_lock is re#defined by bpf-helpers.h, so its usage is sensitive to order of #includes. - `error: eBPF stack limit exceeded` in sysctl_tcp_mem. - Load errors: - Missing object files due to above build errors. - `libbpf: failed to create map (name: 'test_ver.bss')`. - `libbpf: object file doesn't contain bpf program`. - `libbpf: Program '.text' contains unrecognized relo data pointing to section 0`. - `libbpf: BTF is required, but is missing or corrupted` - no BTF support in gcc yet. Signed-off-by: Ilya Leoshkevich Cc: Jose E. Marchesi Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/Makefile | 65 +++++++++++++++++++------ tools/testing/selftests/bpf/bpf_helpers.h | 24 ++++++--- tools/testing/selftests/bpf/progs/test_tc_edt.c | 1 + 3 files changed, 67 insertions(+), 23 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 7f3196af1ae4..6889c19a628c 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -17,6 +17,7 @@ LLC ?= llc LLVM_OBJCOPY ?= llvm-objcopy LLVM_READELF ?= llvm-readelf BTF_PAHOLE ?= pahole +BPF_GCC ?= $(shell command -v bpf-gcc;) CFLAGS += -g -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(BPFDIR) -I$(GENDIR) $(GENFLAGS) -I../../../include \ -Dbpf_prog_load=bpf_prog_test_load \ -Dbpf_load_program=bpf_test_load_program @@ -46,6 +47,10 @@ ifneq ($(SUBREG_CODEGEN),) TEST_GEN_FILES += $(patsubst %.o,alu32/%.o, $(BPF_OBJ_FILES)) endif +ifneq ($(BPF_GCC),) +TEST_GEN_FILES += $(patsubst %.o,bpf_gcc/%.o, $(BPF_OBJ_FILES)) +endif + # Order correspond to 'make run_tests' order TEST_PROGS := test_kmod.sh \ test_libbpf.sh \ @@ -137,16 +142,19 @@ endif # # Use '-idirafter': Don't interfere with include mechanics except where the # build would have failed anyways. -CLANG_SYS_INCLUDES := $(shell $(CLANG) -v -E - &1 \ +define get_sys_includes +$(shell $(1) -v -E - &1 \ | sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') +endef +CLANG_SYS_INCLUDES = $(call get_sys_includes,$(CLANG)) +BPF_CFLAGS = -I. -I./include/uapi -I../../../include/uapi \ + -I$(OUTPUT)/../usr/include -D__TARGET_ARCH_$(SRCARCH) -CLANG_FLAGS = -I. -I./include/uapi -I../../../include/uapi \ - $(CLANG_SYS_INCLUDES) \ - -Wno-compare-distinct-pointer-types \ - -D__TARGET_ARCH_$(SRCARCH) +CLANG_CFLAGS = $(CLANG_SYS_INCLUDES) \ + -Wno-compare-distinct-pointer-types -$(OUTPUT)/test_l4lb_noinline.o: CLANG_FLAGS += -fno-inline -$(OUTPUT)/test_xdp_noinline.o: CLANG_FLAGS += -fno-inline +$(OUTPUT)/test_l4lb_noinline.o: BPF_CFLAGS += -fno-inline +$(OUTPUT)/test_xdp_noinline.o: BPF_CFLAGS += -fno-inline $(OUTPUT)/test_queue_map.o: test_queue_stack_map.h $(OUTPUT)/test_stack_map.o: test_queue_stack_map.h @@ -163,12 +171,12 @@ BTF_LLVM_PROBE := $(shell echo "int main() { return 0; }" | \ /bin/rm -f ./llvm_btf_verify.o) ifneq ($(BTF_LLVM_PROBE),) - CLANG_FLAGS += -g + BPF_CFLAGS += -g else ifneq ($(BTF_LLC_PROBE),) ifneq ($(BTF_PAHOLE_PROBE),) ifneq ($(BTF_OBJCOPY_PROBE),) - CLANG_FLAGS += -g + BPF_CFLAGS += -g LLC_FLAGS += -mattr=dwarfris DWARF2BTF = y endif @@ -202,8 +210,8 @@ $(ALU32_BUILD_DIR)/test_progs_32: prog_tests/*.c $(ALU32_BUILD_DIR)/%.o: progs/%.c $(ALU32_BUILD_DIR)/test_progs_32 \ | $(ALU32_BUILD_DIR) - ($(CLANG) $(CLANG_FLAGS) -O2 -target bpf -emit-llvm -c $< -o - || \ - echo "clang failed") | \ + ($(CLANG) $(BPF_CFLAGS) $(CLANG_CFLAGS) -O2 -target bpf -emit-llvm \ + -c $< -o - || echo "clang failed") | \ $(LLC) -march=bpf -mattr=+alu32 -mcpu=$(CPU) $(LLC_FLAGS) \ -filetype=obj -o $@ ifeq ($(DWARF2BTF),y) @@ -211,10 +219,37 @@ ifeq ($(DWARF2BTF),y) endif endif +ifneq ($(BPF_GCC),) +GCC_SYS_INCLUDES = $(call get_sys_includes,gcc) +IS_LITTLE_ENDIAN = $(shell $(CC) -dM -E - $(VERIFIER_TESTS_H)) -EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(ALU32_BUILD_DIR) \ +EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(ALU32_BUILD_DIR) $(BPF_GCC_BUILD_DIR) \ $(VERIFIER_TESTS_H) $(PROG_TESTS_H) $(MAP_TESTS_H) \ feature diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h index 6c4930bc6e2e..54a50699bbfd 100644 --- a/tools/testing/selftests/bpf/bpf_helpers.h +++ b/tools/testing/selftests/bpf/bpf_helpers.h @@ -1,12 +1,6 @@ /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ -#ifndef __BPF_HELPERS_H -#define __BPF_HELPERS_H - -/* helper macro to place programs, maps, license in - * different sections in elf_bpf file. Section names - * are interpreted by elf_bpf loader - */ -#define SEC(NAME) __attribute__((section(NAME), used)) +#ifndef __BPF_HELPERS__ +#define __BPF_HELPERS__ #define __uint(name, val) int (*name)[val] #define __type(name, val) val *name @@ -19,6 +13,14 @@ ##__VA_ARGS__); \ }) +#ifdef __clang__ + +/* helper macro to place programs, maps, license in + * different sections in elf_bpf file. Section names + * are interpreted by elf_bpf loader + */ +#define SEC(NAME) __attribute__((section(NAME), used)) + /* helper functions called from eBPF programs written in C */ static void *(*bpf_map_lookup_elem)(void *map, const void *key) = (void *) BPF_FUNC_map_lookup_elem; @@ -256,6 +258,12 @@ struct bpf_map_def { unsigned int numa_node; }; +#else + +#include + +#endif + #define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \ struct ____btf_map_##name { \ type_key key; \ diff --git a/tools/testing/selftests/bpf/progs/test_tc_edt.c b/tools/testing/selftests/bpf/progs/test_tc_edt.c index 3af64c470d64..0961415ba477 100644 --- a/tools/testing/selftests/bpf/progs/test_tc_edt.c +++ b/tools/testing/selftests/bpf/progs/test_tc_edt.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3-59-g8ed1b From d895a0f16fadb26d22ab531c49768f7642ae5c3e Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Fri, 16 Aug 2019 12:53:00 +0200 Subject: bpf: fix accessing bpf_sysctl.file_pos on s390 "ctx:file_pos sysctl:read write ok" fails on s390 with "Read value != nux". This is because verifier rewrites a complete 32-bit bpf_sysctl.file_pos update to a partial update of the first 32 bits of 64-bit *bpf_sysctl_kern.ppos, which is not correct on big-endian systems. Fix by using an offset on big-endian systems. Ditto for bpf_sysctl.file_pos reads. Currently the test does not detect a problem there, since it expects to see 0, which it gets with high probability in error cases, so change it to seek to offset 3 and expect 3 in bpf_sysctl.file_pos. Fixes: e1550bfe0de4 ("bpf: Add file_pos field to bpf_sysctl ctx") Signed-off-by: Ilya Leoshkevich Acked-by: Yonghong Song Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20190816105300.49035-1-iii@linux.ibm.com/ --- include/linux/filter.h | 8 ++++---- kernel/bpf/cgroup.c | 10 ++++++++-- kernel/bpf/verifier.c | 4 ++-- tools/testing/selftests/bpf/test_sysctl.c | 9 ++++++++- 4 files changed, 22 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/include/linux/filter.h b/include/linux/filter.h index 92c6e31fb008..2ce57645f3cd 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -749,14 +749,14 @@ bpf_ctx_narrow_access_ok(u32 off, u32 size, u32 size_default) } static inline u8 -bpf_ctx_narrow_load_shift(u32 off, u32 size, u32 size_default) +bpf_ctx_narrow_access_offset(u32 off, u32 size, u32 size_default) { - u8 load_off = off & (size_default - 1); + u8 access_off = off & (size_default - 1); #ifdef __LITTLE_ENDIAN - return load_off * 8; + return access_off; #else - return (size_default - (load_off + size)) * 8; + return size_default - (access_off + size); #endif } diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index 6a6a154cfa7b..ddd8addcdb5c 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -1334,6 +1334,7 @@ static u32 sysctl_convert_ctx_access(enum bpf_access_type type, struct bpf_prog *prog, u32 *target_size) { struct bpf_insn *insn = insn_buf; + u32 read_size; switch (si->off) { case offsetof(struct bpf_sysctl, write): @@ -1365,7 +1366,9 @@ static u32 sysctl_convert_ctx_access(enum bpf_access_type type, treg, si->dst_reg, offsetof(struct bpf_sysctl_kern, ppos)); *insn++ = BPF_STX_MEM( - BPF_SIZEOF(u32), treg, si->src_reg, 0); + BPF_SIZEOF(u32), treg, si->src_reg, + bpf_ctx_narrow_access_offset( + 0, sizeof(u32), sizeof(loff_t))); *insn++ = BPF_LDX_MEM( BPF_DW, treg, si->dst_reg, offsetof(struct bpf_sysctl_kern, tmp_reg)); @@ -1374,8 +1377,11 @@ static u32 sysctl_convert_ctx_access(enum bpf_access_type type, BPF_FIELD_SIZEOF(struct bpf_sysctl_kern, ppos), si->dst_reg, si->src_reg, offsetof(struct bpf_sysctl_kern, ppos)); + read_size = bpf_size_to_bytes(BPF_SIZE(si->code)); *insn++ = BPF_LDX_MEM( - BPF_SIZE(si->code), si->dst_reg, si->dst_reg, 0); + BPF_SIZE(si->code), si->dst_reg, si->dst_reg, + bpf_ctx_narrow_access_offset( + 0, read_size, sizeof(loff_t))); } *target_size = sizeof(u32); break; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 3fb50757e812..92a4332b041d 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -8619,8 +8619,8 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) } if (is_narrower_load && size < target_size) { - u8 shift = bpf_ctx_narrow_load_shift(off, size, - size_default); + u8 shift = bpf_ctx_narrow_access_offset( + off, size, size_default) * 8; if (ctx_field_size <= 4) { if (shift) insn_buf[cnt++] = BPF_ALU32_IMM(BPF_RSH, diff --git a/tools/testing/selftests/bpf/test_sysctl.c b/tools/testing/selftests/bpf/test_sysctl.c index fc33ae36b760..4f8ec1f10a80 100644 --- a/tools/testing/selftests/bpf/test_sysctl.c +++ b/tools/testing/selftests/bpf/test_sysctl.c @@ -32,6 +32,7 @@ struct sysctl_test { enum bpf_attach_type attach_type; const char *sysctl; int open_flags; + int seek; const char *newval; const char *oldval; enum { @@ -140,7 +141,7 @@ static struct sysctl_test tests[] = { /* If (file_pos == X) */ BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, offsetof(struct bpf_sysctl, file_pos)), - BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 2), + BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 3, 2), /* return ALLOW; */ BPF_MOV64_IMM(BPF_REG_0, 1), @@ -153,6 +154,7 @@ static struct sysctl_test tests[] = { .attach_type = BPF_CGROUP_SYSCTL, .sysctl = "kernel/ostype", .open_flags = O_RDONLY, + .seek = 3, .result = SUCCESS, }, { @@ -1481,6 +1483,11 @@ static int access_sysctl(const char *sysctl_path, if (fd < 0) return fd; + if (test->seek && lseek(fd, test->seek, SEEK_SET) == -1) { + log_err("lseek(%d) failed", test->seek); + goto err; + } + if (test->open_flags == O_RDONLY) { char buf[128]; -- cgit v1.2.3-59-g8ed1b From bd3841cd3bd852e7363218e71e48cb473de4fc06 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Wed, 4 Sep 2019 18:41:00 +0200 Subject: selftests, arm64: add kernel headers path for tags_test tags_test.c relies on PR_SET_TAGGED_ADDR_CTRL/PR_TAGGED_ADDR_ENABLE being present in system headers. When this is not the case the build of this test fails with undeclared identifier errors. Fix by providing the path to the KSFT installed kernel headers in CFLAGS. Reported-by: Cristian Marussi Suggested-by: Cristian Marussi Signed-off-by: Andrey Konovalov Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/testing/selftests/arm64/Makefile b/tools/testing/selftests/arm64/Makefile index a61b2e743e99..f9f79fb272f0 100644 --- a/tools/testing/selftests/arm64/Makefile +++ b/tools/testing/selftests/arm64/Makefile @@ -4,6 +4,7 @@ ARCH ?= $(shell uname -m 2>/dev/null || echo not) ifneq (,$(filter $(ARCH),aarch64 arm64)) +CFLAGS += -I../../../../usr/include/ TEST_GEN_PROGS := tags_test TEST_PROGS := run_tags_test.sh endif -- cgit v1.2.3-59-g8ed1b From 604e3548236de26ed6659b85bda8f27b28a7601b Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Fri, 22 Mar 2019 15:09:23 -0400 Subject: selftests/ftrace: Select an existing function in kprobe_eventname test Running the ftrace selftests on the latest kernel caused the kprobe_eventname test to fail. It was due to the test that searches for a function with at "dot" in the name and adding a probe to that. Unfortunately, for this test, it picked: optimize_nops.isra.2.cold.4 Which happens to be marked as "__init", which means it no longer exists in the kernel! (kallsyms keeps those function names around for tracing purposes) As only functions that still exist are in the available_filter_functions file, as they are removed when the functions are freed at boot or module exit, have the test search for a function with ".isra." in the name as well as being in the available_filter_functions (if the file exists). Link: http://lkml.kernel.org/r/20190322150923.1b58eca5@gandalf.local.home Acked-by: Masami Hiramatsu Signed-off-by: Steven Rostedt (VMware) --- .../selftests/ftrace/test.d/kprobe/kprobe_eventname.tc | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc index 3fb70e01b1fe..3ff236719b6e 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc @@ -24,7 +24,21 @@ test -d events/kprobes2/event2 || exit_failure :;: "Add an event on dot function without name" ;: -FUNC=`grep -m 10 " [tT] .*\.isra\..*$" /proc/kallsyms | tail -n 1 | cut -f 3 -d " "` +find_dot_func() { + if [ ! -f available_filter_functions ]; then + grep -m 10 " [tT] .*\.isra\..*$" /proc/kallsyms | tail -n 1 | cut -f 3 -d " " + return; + fi + + grep " [tT] .*\.isra\..*" /proc/kallsyms | cut -f 3 -d " " | while read f; do + if grep -s $f available_filter_functions; then + echo $f + break + fi + done +} + +FUNC=`find_dot_func | tail -n 1` [ "x" != "x$FUNC" ] || exit_unresolved echo "p $FUNC" > kprobe_events EVENT=`grep $FUNC kprobe_events | cut -f 1 -d " " | cut -f 2 -d:` -- cgit v1.2.3-59-g8ed1b From 44460efe44e05eae2f21e57d06d542bbbb792e65 Mon Sep 17 00:00:00 2001 From: Youquan Song Date: Sat, 14 Sep 2019 12:45:43 -0700 Subject: tools/power/x86/intel-speed-select: Fix high priority core mask over count If the CPU package has the less logical CPU than topo_max_cpus, but un-present CPU's punit_cpu_core will be initiated to 0 and they will be count to core 0 Like below, there are only 10 high priority cores (20 logical CPUs) in the CPU package, but it count to 27 logic CPUs. ./intel-speed-select base-freq info -l 0 | grep mask high-priority-cpu-mask:7f000179,f000179f With the fix patch: ./intel-speed-select base-freq info -l 0 high-priority-cpu-mask:00000179,f000179f Signed-off-by: Youquan Song Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 59753b3917bb..83ac72902b36 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -402,6 +402,9 @@ void set_cpu_mask_from_punit_coremask(int cpu, unsigned long long core_mask, int j; for (j = 0; j < topo_max_cpus; ++j) { + if (!CPU_ISSET_S(j, present_cpumask_size, present_cpumask)) + continue; + if (cpu_map[j].pkg_id == pkg_id && cpu_map[j].die_id == die_id && cpu_map[j].punit_cpu_core == i) { -- cgit v1.2.3-59-g8ed1b From 3c64c81ad1f06823b603e9143193dcb4f3121a2f Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Sat, 14 Sep 2019 12:45:44 -0700 Subject: tools/power/x86/intel-speed-select: Allow online/offline based on tdp Using enable core mask, do online offline CPUs. There is a new option --online|-o for set-config-level. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 60 ++++++++++++++++++++++-- tools/power/x86/intel-speed-select/isst.h | 2 + 2 files changed, 58 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 83ac72902b36..e505aaf2beef 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -38,6 +38,7 @@ static int fact_avx = 0xFF; static unsigned long long fact_trl; static int out_format_json; static int cmd_help; +static int force_online_offline; /* clos related */ static int current_clos = -1; @@ -138,14 +139,14 @@ int out_format_is_json(void) int get_physical_package_id(int cpu) { return parse_int_file( - 1, "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", + 0, "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu); } int get_physical_core_id(int cpu) { return parse_int_file( - 1, "/sys/devices/system/cpu/cpu%d/topology/core_id", cpu); + 0, "/sys/devices/system/cpu/cpu%d/topology/core_id", cpu); } int get_physical_die_id(int cpu) @@ -165,6 +166,26 @@ int get_topo_max_cpus(void) return topo_max_cpus; } +static void set_cpu_online_offline(int cpu, int state) +{ + char buffer[128]; + int fd; + + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/online", cpu); + + fd = open(buffer, O_WRONLY); + if (fd < 0) + err(-1, "%s open failed", buffer); + + if (state) + write(fd, "1\n", 2); + else + write(fd, "0\n", 2); + + close(fd); +} + #define MAX_PACKAGE_COUNT 8 #define MAX_DIE_PER_PACKAGE 2 static void for_each_online_package_in_set(void (*callback)(int, void *, void *, @@ -736,9 +757,34 @@ static void set_tdp_level_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, ret = isst_set_tdp_level(cpu, tdp_level); if (ret) perror("set_tdp_level_for_cpu"); - else + else { isst_display_result(cpu, outf, "perf-profile", "set_tdp_level", ret); + if (force_online_offline) { + struct isst_pkg_ctdp_level_info ctdp_level; + int pkg_id = get_physical_package_id(cpu); + int die_id = get_physical_die_id(cpu); + + fprintf(stderr, "Option is set to online/offline\n"); + ctdp_level.core_cpumask_size = + alloc_cpu_set(&ctdp_level.core_cpumask); + isst_get_coremask_info(cpu, tdp_level, &ctdp_level); + if (ctdp_level.cpu_count) { + int i, max_cpus = get_topo_max_cpus(); + for (i = 0; i < max_cpus; ++i) { + if (pkg_id != get_physical_package_id(i) || die_id != get_physical_die_id(i)) + continue; + if (CPU_ISSET_S(i, ctdp_level.core_cpumask_size, ctdp_level.core_cpumask)) { + fprintf(stderr, "online cpu %d\n", i); + set_cpu_online_offline(i, 1); + } else { + fprintf(stderr, "offline cpu %d\n", i); + set_cpu_online_offline(i, 0); + } + } + } + } + } } static void set_tdp_level(void) @@ -747,6 +793,8 @@ static void set_tdp_level(void) fprintf(stderr, "Set Config TDP level\n"); fprintf(stderr, "\t Arguments: -l|--level : Specify tdp level\n"); + fprintf(stderr, + "\t Optional Arguments: -o | online : online/offline for the tdp level\n"); exit(0); } @@ -1319,6 +1367,7 @@ static void parse_cmd_args(int argc, int start, char **argv) static struct option long_options[] = { { "bucket", required_argument, 0, 'b' }, { "level", required_argument, 0, 'l' }, + { "online", required_argument, 0, 'o' }, { "trl-type", required_argument, 0, 'r' }, { "trl", required_argument, 0, 't' }, { "help", no_argument, 0, 'h' }, @@ -1335,7 +1384,7 @@ static void parse_cmd_args(int argc, int start, char **argv) option_index = start; optind = start + 1; - while ((opt = getopt_long(argc, argv, "b:l:t:c:d:e:n:m:p:w:h", + while ((opt = getopt_long(argc, argv, "b:l:t:c:d:e:n:m:p:w:ho", long_options, &option_index)) != -1) { switch (opt) { case 'b': @@ -1347,6 +1396,9 @@ static void parse_cmd_args(int argc, int start, char **argv) case 'l': tdp_level = atoi(optarg); break; + case 'o': + force_online_offline = 1; + break; case 't': sscanf(optarg, "0x%llx", &fact_trl); break; diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 2f7f62765eb6..668f914d077f 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -187,6 +187,8 @@ extern int isst_send_msr_command(unsigned int cpu, unsigned int command, int write, unsigned long long *req_resp); extern int isst_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev); +extern int isst_get_coremask_info(int cpu, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level); extern int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev); extern void isst_get_process_ctdp_complete(int cpu, -- cgit v1.2.3-59-g8ed1b From e118fbe366d817175b2c47bfa338959bbff5bd37 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Sat, 14 Sep 2019 12:45:45 -0700 Subject: tools/power/x86/intel-speed-select: Format get-assoc information Format the get-assoc command output consistant with other commands. For example: Intel(R) Speed Select Technology Executing on CPU model:142[0x8e] package-0 die-0 cpu-0 get-assoc clos:0 Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 14 +++++++++----- tools/power/x86/intel-speed-select/isst-display.c | 23 +++++++++++++++++++++++ tools/power/x86/intel-speed-select/isst.h | 2 +- 3 files changed, 33 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index e505aaf2beef..c2892d86be36 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1249,7 +1249,7 @@ static void get_clos_assoc_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, if (ret) perror("isst_clos_get_assoc_status"); else - isst_display_result(cpu, outf, "core-power", "get-assoc", clos); + isst_clos_display_assoc_information(cpu, outf, clos); } static void get_clos_assoc(void) @@ -1259,13 +1259,17 @@ static void get_clos_assoc(void) fprintf(stderr, "\tSpecify targeted cpu id with [--cpu|-c]\n"); exit(0); } - if (max_target_cpus) - for_each_online_target_cpu_in_set(get_clos_assoc_for_cpu, NULL, - NULL, NULL, NULL); - else { + + if (!max_target_cpus) { fprintf(stderr, "Invalid target cpu. Specify with [-c|--cpu]\n"); + exit(0); } + + isst_ctdp_display_information_start(outf); + for_each_online_target_cpu_in_set(get_clos_assoc_for_cpu, NULL, + NULL, NULL, NULL); + isst_ctdp_display_information_end(outf); } static struct process_cmd_struct isst_cmds[] = { diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index df4aa99c4e92..bd7aaf27e4de 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -503,6 +503,29 @@ void isst_clos_display_information(int cpu, FILE *outf, int clos, format_and_print(outf, 1, NULL, NULL); } +void isst_clos_display_assoc_information(int cpu, FILE *outf, int clos) +{ + char header[256]; + char value[256]; + + snprintf(header, sizeof(header), "package-%d", + get_physical_package_id(cpu)); + format_and_print(outf, 1, header, NULL); + snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu)); + format_and_print(outf, 2, header, NULL); + snprintf(header, sizeof(header), "cpu-%d", cpu); + format_and_print(outf, 3, header, NULL); + + snprintf(header, sizeof(header), "get-assoc"); + format_and_print(outf, 4, header, NULL); + + snprintf(header, sizeof(header), "clos"); + snprintf(value, sizeof(value), "%d", clos); + format_and_print(outf, 5, header, value); + + format_and_print(outf, 1, NULL, NULL); +} + void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd, int result) { diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 668f914d077f..48655d0dee2d 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -225,7 +225,7 @@ extern int isst_clos_associate(int cpu, int clos); extern int isst_clos_get_assoc_status(int cpu, int *clos_id); extern void isst_clos_display_information(int cpu, FILE *outf, int clos, struct isst_clos_config *clos_config); - +extern void isst_clos_display_assoc_information(int cpu, FILE *outf, int clos); extern int isst_read_reg(unsigned short reg, unsigned int *val); extern int isst_write_reg(int reg, unsigned int val); -- cgit v1.2.3-59-g8ed1b From d2d1f304dc965e6a06e7f105b09bffceb477fccc Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Sat, 14 Sep 2019 12:45:46 -0700 Subject: tools/power/x86/intel-speed-select: Fix some debug prints Fix wrong debug print for cpu, which is displayed as CLOS. Also avoid printing clos id, when user is specify clos as parameter. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index c2892d86be36..889396d676cb 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -508,7 +508,7 @@ int isst_send_mbox_command(unsigned int cpu, unsigned char command, int write = 0; int clos_id, core_id, ret = 0; - debug_printf("CLOS %d\n", cpu); + debug_printf("CPU %d\n", cpu); if (parameter & BIT(MBOX_CMD_WRITE_BIT)) { value = req_data; @@ -1421,7 +1421,6 @@ static void parse_cmd_args(int argc, int start, char **argv) /* CLOS related */ case 'c': current_clos = atoi(optarg); - printf("clos %d\n", current_clos); break; case 'd': clos_desired = atoi(optarg); -- cgit v1.2.3-59-g8ed1b From 188afed9db7db3aefc8c9c33150be2f8f398da9a Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Sat, 14 Sep 2019 12:45:47 -0700 Subject: tools/power/x86/intel-speed-select: Extend core-power command set Add additional command to get the clos enable and priority type. The current info option is actually dumping per clos QOS config, so name the command appropriately to get-config. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 38 ++++++++++++++++++++++- tools/power/x86/intel-speed-select/isst-core.c | 25 +++++++++++++++ tools/power/x86/intel-speed-select/isst-display.c | 28 +++++++++++++++++ tools/power/x86/intel-speed-select/isst.h | 5 +++ 4 files changed, 95 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 889396d676cb..6a54e165672d 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1133,6 +1133,40 @@ static void dump_clos_config(void) isst_ctdp_display_information_end(outf); } +static void get_clos_info_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, + void *arg4) +{ + int enable, ret, prio_type; + + ret = isst_clos_get_clos_information(cpu, &enable, &prio_type); + if (ret) + perror("isst_clos_get_info"); + else + isst_clos_display_clos_information(cpu, outf, enable, prio_type); +} + +static void dump_clos_info(void) +{ + if (cmd_help) { + fprintf(stderr, + "Print Intel Speed Select Technology core power information\n"); + fprintf(stderr, "\tSpecify targeted cpu id with [--cpu|-c]\n"); + exit(0); + } + + if (!max_target_cpus) { + fprintf(stderr, + "Invalid target cpu. Specify with [-c|--cpu]\n"); + exit(0); + } + + isst_ctdp_display_information_start(outf); + for_each_online_target_cpu_in_set(get_clos_info_for_cpu, NULL, + NULL, NULL, NULL); + isst_ctdp_display_information_end(outf); + +} + static void set_clos_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, void *arg4) { @@ -1286,10 +1320,11 @@ static struct process_cmd_struct isst_cmds[] = { { "turbo-freq", "info", dump_fact_config }, { "turbo-freq", "enable", set_fact_enable }, { "turbo-freq", "disable", set_fact_disable }, - { "core-power", "info", dump_clos_config }, + { "core-power", "info", dump_clos_info }, { "core-power", "enable", set_clos_enable }, { "core-power", "disable", set_clos_disable }, { "core-power", "config", set_clos_config }, + { "core-power", "get-config", dump_clos_config }, { "core-power", "assoc", set_clos_assoc }, { "core-power", "get-assoc", get_clos_assoc }, { NULL, NULL, NULL } @@ -1491,6 +1526,7 @@ static void core_power_help(void) printf("\tenable\n"); printf("\tdisable\n"); printf("\tconfig\n"); + printf("\tget-config\n"); printf("\tassoc\n"); printf("\tget-assoc\n"); } diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 0bf341ad9697..6dee5332c9d3 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -619,6 +619,31 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) return 0; } +int isst_clos_get_clos_information(int cpu, int *enable, int *type) +{ + unsigned int resp; + int ret; + + ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, + &resp); + if (ret) + return ret; + + debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp); + + if (resp & BIT(1)) + *enable = 1; + else + *enable = 0; + + if (resp & BIT(2)) + *type = 1; + else + *type = 0; + + return 0; +} + int isst_pm_qos_config(int cpu, int enable_clos, int priority_type) { unsigned int req, resp; diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index bd7aaf27e4de..2e6e5fcdbd7c 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -503,6 +503,34 @@ void isst_clos_display_information(int cpu, FILE *outf, int clos, format_and_print(outf, 1, NULL, NULL); } +void isst_clos_display_clos_information(int cpu, FILE *outf, + int clos_enable, int type) +{ + char header[256]; + char value[256]; + + snprintf(header, sizeof(header), "package-%d", + get_physical_package_id(cpu)); + format_and_print(outf, 1, header, NULL); + snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu)); + format_and_print(outf, 2, header, NULL); + snprintf(header, sizeof(header), "cpu-%d", cpu); + format_and_print(outf, 3, header, NULL); + + snprintf(header, sizeof(header), "core-power"); + format_and_print(outf, 4, header, NULL); + + snprintf(header, sizeof(header), "enable-status"); + snprintf(value, sizeof(value), "%d", clos_enable); + format_and_print(outf, 5, header, value); + + snprintf(header, sizeof(header), "priority-type"); + snprintf(value, sizeof(value), "%d", type); + format_and_print(outf, 5, header, value); + + format_and_print(outf, 1, NULL, NULL); +} + void isst_clos_display_assoc_information(int cpu, FILE *outf, int clos) { char header[256]; diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 48655d0dee2d..09e16a41b57c 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -231,4 +231,9 @@ extern int isst_write_reg(int reg, unsigned int val); extern void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd, int result); + +extern int isst_clos_get_clos_information(int cpu, int *enable, int *type); +extern void isst_clos_display_clos_information(int cpu, FILE *outf, + int clos_enable, int type); + #endif -- cgit v1.2.3-59-g8ed1b From b3abfd778bf1dbdd96f70bd7d00671d027f67c62 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Tue, 17 Sep 2019 17:52:37 -0700 Subject: tools/power/x86/intel-speed-select: Fix perf-profile command output commit "c016ae8f9fa04d361efc8629de49ad3af12b5262 "tools/power/x86/intel-speed-select: Output success/failed for command output" introduced a regression in perf-profile outputs. With this the result field is changed to string interpreting every non zero value as errors. But these commands display on zero (>0) result. For example before this commit the display was: package-1 die-0 cpu-14 get-config-levels:4 Here the get-config-levels is interpreted as error and displayed as error with the above commit: package-1 die-0 cpu-14 get-config-levels:failed(error 4) Fix this issue by not using isst_display_result() to display such results, but define a new function which formats this data and prints. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 4 ++-- tools/power/x86/intel-speed-select/isst-display.c | 20 ++++++++++++++++++++ tools/power/x86/intel-speed-select/isst.h | 3 ++- 3 files changed, 24 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 6a54e165672d..2a9890c8395a 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -673,8 +673,8 @@ static void exec_on_get_ctdp_cpu(int cpu, void *arg1, void *arg2, void *arg3, if (ret) perror("get_tdp_*"); else - isst_display_result(cpu, outf, "perf-profile", (char *)arg3, - *(unsigned int *)arg4); + isst_ctdp_display_core_info(cpu, outf, arg3, + *(unsigned int *)arg4); } #define _get_tdp_level(desc, suffix, object, help) \ diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 2e6e5fcdbd7c..40346d534f78 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -287,6 +287,26 @@ static void _isst_fact_display_information(int cpu, FILE *outf, int level, format_and_print(outf, base_level + 2, header, value); } +void isst_ctdp_display_core_info(int cpu, FILE *outf, char *prefix, + unsigned int val) +{ + char header[256]; + char value[256]; + + snprintf(header, sizeof(header), "package-%d", + get_physical_package_id(cpu)); + format_and_print(outf, 1, header, NULL); + snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu)); + format_and_print(outf, 2, header, NULL); + snprintf(header, sizeof(header), "cpu-%d", cpu); + format_and_print(outf, 3, header, NULL); + + snprintf(value, sizeof(value), "%u", val); + format_and_print(outf, 4, prefix, value); + + format_and_print(outf, 1, NULL, NULL); +} + void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, struct isst_pkg_ctdp *pkg_dev) { diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 09e16a41b57c..d280b27d600d 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -195,6 +195,8 @@ extern void isst_get_process_ctdp_complete(int cpu, struct isst_pkg_ctdp *pkg_dev); extern void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, struct isst_pkg_ctdp *pkg_dev); +extern void isst_ctdp_display_core_info(int cpu, FILE *outf, char *prefix, + unsigned int val); extern void isst_ctdp_display_information_start(FILE *outf); extern void isst_ctdp_display_information_end(FILE *outf); extern void isst_pbf_display_information(int cpu, FILE *outf, int level, @@ -235,5 +237,4 @@ extern void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd, extern int isst_clos_get_clos_information(int cpu, int *enable, int *type); extern void isst_clos_display_clos_information(int cpu, FILE *outf, int clos_enable, int type); - #endif -- cgit v1.2.3-59-g8ed1b From e0973a421c6e9d268db2157bcb8756e7ab4b4313 Mon Sep 17 00:00:00 2001 From: Toke Høiland-Jørgensen Date: Mon, 16 Sep 2019 14:33:42 +0200 Subject: libbpf: Remove getsockopt() check for XDP_OPTIONS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The xsk_socket__create() function fails and returns an error if it cannot get the XDP_OPTIONS through getsockopt(). However, support for XDP_OPTIONS was not added until kernel 5.3, so this means that creating XSK sockets always fails on older kernels. Since the option is just used to set the zero-copy flag in the xsk struct, and that flag is not really used for anything yet, just remove the getsockopt() call until a proper use for it is introduced. Suggested-by: Yonghong Song Signed-off-by: Toke Høiland-Jørgensen Acked-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann --- tools/lib/bpf/xsk.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c index 842c4fd55859..24fa313524fb 100644 --- a/tools/lib/bpf/xsk.c +++ b/tools/lib/bpf/xsk.c @@ -65,7 +65,6 @@ struct xsk_socket { int xsks_map_fd; __u32 queue_id; char ifname[IFNAMSIZ]; - bool zc; }; struct xsk_nl_info { @@ -491,7 +490,6 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname, void *rx_map = NULL, *tx_map = NULL; struct sockaddr_xdp sxdp = {}; struct xdp_mmap_offsets off; - struct xdp_options opts; struct xsk_socket *xsk; socklen_t optlen; int err; @@ -611,15 +609,6 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname, xsk->prog_fd = -1; - optlen = sizeof(opts); - err = getsockopt(xsk->fd, SOL_XDP, XDP_OPTIONS, &opts, &optlen); - if (err) { - err = -errno; - goto out_mmap_tx; - } - - xsk->zc = opts.flags & XDP_OPTIONS_ZEROCOPY; - if (!(xsk->config.libbpf_flags & XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD)) { err = xsk_setup_xdp_prog(xsk); if (err) -- cgit v1.2.3-59-g8ed1b From b78b94b82122208902c0f83805e614e1239f9893 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Wed, 18 Sep 2019 17:55:55 +0900 Subject: selftests/ftrace: Update kprobe event error testcase Update kprobe event error testcase to test if it correctly finds the exact same probe event. Link: http://lkml.kernel.org/r/156879695513.31056.1580235733738840126.stgit@devnote2 Signed-off-by: Masami Hiramatsu Signed-off-by: Steven Rostedt (VMware) --- tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc index 39ef7ac1f51c..8a4025e912cb 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc @@ -95,6 +95,7 @@ echo 'p:kprobes/testevent _do_fork abcd=\1' > kprobe_events check_error 'p:kprobes/testevent _do_fork ^bcd=\1' # DIFF_ARG_TYPE check_error 'p:kprobes/testevent _do_fork ^abcd=\1:u8' # DIFF_ARG_TYPE check_error 'p:kprobes/testevent _do_fork ^abcd=\"foo"' # DIFF_ARG_TYPE +check_error '^p:kprobes/testevent _do_fork' # SAME_PROBE fi exit 0 -- cgit v1.2.3-59-g8ed1b From 864668bfc374dfbf4851ec828b9049e08f9057b1 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 16 Sep 2019 08:26:50 -0400 Subject: selftests: Add test cases for `ip nexthop flush proto XX` Add some test cases to allow the fib_nexthops.sh test code to test the flushing of nexthops based upon the proto passed in upon creation of the nexthop group. Signed-off-by: Donald Sharp Reviewed-by: David Ahern Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/fib_nexthops.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh index f9ebeac1e6f2..796670ebc65b 100755 --- a/tools/testing/selftests/net/fib_nexthops.sh +++ b/tools/testing/selftests/net/fib_nexthops.sh @@ -940,6 +940,20 @@ basic() run_cmd "$IP nexthop add id 104 group 1 dev veth1" log_test $? 2 "Nexthop group and device" + # Tests to ensure that flushing works as expected. + run_cmd "$IP nexthop add id 105 blackhole proto 99" + run_cmd "$IP nexthop add id 106 blackhole proto 100" + run_cmd "$IP nexthop add id 107 blackhole proto 99" + run_cmd "$IP nexthop flush proto 99" + check_nexthop "id 105" "" + check_nexthop "id 106" "id 106 blackhole proto 100" + check_nexthop "id 107" "" + run_cmd "$IP nexthop flush proto 100" + check_nexthop "id 106" "" + + run_cmd "$IP nexthop flush proto 100" + log_test $? 0 "Test proto flush" + run_cmd "$IP nexthop add id 104 group 1 blackhole" log_test $? 2 "Nexthop group and blackhole" -- cgit v1.2.3-59-g8ed1b From 79743bc927f695e5a24f26c31cfe2d69f6ee00f7 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 2 Sep 2019 15:37:21 -0300 Subject: perf jvmti: Link against tools/lib/string.o to have weak strlcpy() That is needed in systems such some S/390 distros. $ readelf -s /tmp/build/perf/jvmti/jvmti-in.o | grep strlcpy 452: 0000000000002990 125 FUNC WEAK DEFAULT 119 strlcpy $ Thanks to Jiri Olsa for fixing up my initial stab at this, I forgot how Makefiles are picky about spaces versus tabs. Reported-by: Thomas Richter Cc: Adrian Hunter Cc: Andreas Krebbel Cc: Jiri Olsa Cc: Namhyung Kim Cc: Sergey Melnikov Link: https://lkml.kernel.org/n/tip-x8vg9sffgb2t1tzqmhkrulh7@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/jvmti/Build | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'tools') diff --git a/tools/perf/jvmti/Build b/tools/perf/jvmti/Build index eaeb8cb5379b..1e148bbdf820 100644 --- a/tools/perf/jvmti/Build +++ b/tools/perf/jvmti/Build @@ -1,8 +1,17 @@ jvmti-y += libjvmti.o jvmti-y += jvmti_agent.o +# For strlcpy +jvmti-y += libstring.o + CFLAGS_jvmti = -fPIC -DPIC -I$(JDIR)/include -I$(JDIR)/include/linux CFLAGS_REMOVE_jvmti = -Wmissing-declarations CFLAGS_REMOVE_jvmti += -Wstrict-prototypes CFLAGS_REMOVE_jvmti += -Wextra CFLAGS_REMOVE_jvmti += -Wwrite-strings + +CFLAGS_libstring.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" + +$(OUTPUT)jvmti/libstring.o: ../lib/string.c FORCE + $(call rule_mkdir) + $(call if_changed_dep,cc_o_c) -- cgit v1.2.3-59-g8ed1b From 9e282b739466dd319667788417426145da62e381 Mon Sep 17 00:00:00 2001 From: James Clark Date: Mon, 2 Sep 2019 16:08:19 +0000 Subject: perf tools: Add PMU event JSON files for ARM Cortex-A76 and, Neoverse N1. The source of the event codes and description text was the Neoverse N1 technical reference manual at: http://infocenter.arm.com/help/topic/com.arm.doc.100616_0301_01_en/neoverse_n1_trm_100616_0301_01_en.pdf The Cortex-A76 shares the same event IDs as the Neoverse N1 and they can be viewed at: https://static.docs.arm.com/100798/0400/cortex_a76_trm_100798_0400_00_en.pdf Signed-off-by: James Clark Cc: "linux-perf-users@vger.kernel.org" Cc: Alexander Shishkin Cc: Jeremy Linton Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Suzuki Poulouse Cc: james clark Cc: nd Link: http://lore.kernel.org/lkml/20190902160713.1425-2-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- .../arch/arm64/arm/cortex-a76-n1/branch.json | 14 ++ .../arch/arm64/arm/cortex-a76-n1/bus.json | 24 +++ .../arch/arm64/arm/cortex-a76-n1/cache.json | 207 +++++++++++++++++++++ .../arch/arm64/arm/cortex-a76-n1/exception.json | 52 ++++++ .../arch/arm64/arm/cortex-a76-n1/instruction.json | 108 +++++++++++ .../arch/arm64/arm/cortex-a76-n1/memory.json | 23 +++ .../arch/arm64/arm/cortex-a76-n1/other.json | 7 + .../arch/arm64/arm/cortex-a76-n1/pipeline.json | 14 ++ tools/perf/pmu-events/arch/arm64/mapfile.csv | 2 + 9 files changed, 451 insertions(+) create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/branch.json create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/bus.json create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/cache.json create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/exception.json create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/instruction.json create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/memory.json create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/other.json create mode 100644 tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/pipeline.json (limited to 'tools') diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/branch.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/branch.json new file mode 100644 index 000000000000..b5e5d055c70d --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/branch.json @@ -0,0 +1,14 @@ +[ + { + "PublicDescription": "Mispredicted or not predicted branch speculatively executed. This event counts any predictable branch instruction which is mispredicted either due to dynamic misprediction or because the MMU is off and the branches are statically predicted not taken.", + "EventCode": "0x10", + "EventName": "BR_MIS_PRED", + "BriefDescription": "Mispredicted or not predicted branch speculatively executed." + }, + { + "PublicDescription": "Predictable branch speculatively executed. This event counts all predictable branches.", + "EventCode": "0x12", + "EventName": "BR_PRED", + "BriefDescription": "Predictable branch speculatively executed." + } +] diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/bus.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/bus.json new file mode 100644 index 000000000000..fce7309ae624 --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/bus.json @@ -0,0 +1,24 @@ +[ + { + "EventCode": "0x11", + "EventName": "CPU_CYCLES", + "BriefDescription": "The number of core clock cycles." + }, + { + "PublicDescription": "Bus access. This event counts for every beat of data transferred over the data channels between the core and the SCU. If both read and write data beats are transferred on a given cycle, this event is counted twice on that cycle. This event counts the sum of BUS_ACCESS_RD and BUS_ACCESS_WR.", + "EventCode": "0x19", + "EventName": "BUS_ACCESS", + "BriefDescription": "Bus access." + }, + { + "EventCode": "0x1D", + "EventName": "BUS_CYCLES", + "BriefDescription": "Bus cycles. This event duplicates CPU_CYCLES." + }, + { + "ArchStdEvent": "BUS_ACCESS_RD" + }, + { + "ArchStdEvent": "BUS_ACCESS_WR" + } +] diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/cache.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/cache.json new file mode 100644 index 000000000000..24594081c199 --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/cache.json @@ -0,0 +1,207 @@ +[ + { + "PublicDescription": "L1 instruction cache refill. This event counts any instruction fetch which misses in the cache.", + "EventCode": "0x01", + "EventName": "L1I_CACHE_REFILL", + "BriefDescription": "L1 instruction cache refill" + }, + { + "PublicDescription": "L1 instruction TLB refill. This event counts any refill of the instruction L1 TLB from the L2 TLB. This includes refills that result in a translation fault.", + "EventCode": "0x02", + "EventName": "L1I_TLB_REFILL", + "BriefDescription": "L1 instruction TLB refill" + }, + { + "PublicDescription": "L1 data cache refill. This event counts any load or store operation or page table walk access which causes data to be read from outside the L1, including accesses which do not allocate into L1.", + "EventCode": "0x03", + "EventName": "L1D_CACHE_REFILL", + "BriefDescription": "L1 data cache refill" + }, + { + "PublicDescription": "L1 data cache access. This event counts any load or store operation or page table walk access which looks up in the L1 data cache. In particular, any access which could count the L1D_CACHE_REFILL event causes this event to count.", + "EventCode": "0x04", + "EventName": "L1D_CACHE", + "BriefDescription": "L1 data cache access" + }, + { + "PublicDescription": "L1 data TLB refill. This event counts any refill of the data L1 TLB from the L2 TLB. This includes refills that result in a translation fault.", + "EventCode": "0x05", + "EventName": "L1D_TLB_REFILL", + "BriefDescription": "L1 data TLB refill" + }, + { + "PublicDescription": "Level 1 instruction cache access or Level 0 Macro-op cache access. This event counts any instruction fetch which accesses the L1 instruction cache or L0 Macro-op cache.", + "EventCode": "0x14", + "EventName": "L1I_CACHE", + "BriefDescription": "L1 instruction cache access" + }, + { + "PublicDescription": "L1 data cache Write-Back. This event counts any write-back of data from the L1 data cache to L2 or L3. This counts both victim line evictions and snoops, including cache maintenance operations.", + "EventCode": "0x15", + "EventName": "L1D_CACHE_WB", + "BriefDescription": "L1 data cache Write-Back" + }, + { + "PublicDescription": "L2 data cache access. This event counts any transaction from L1 which looks up in the L2 cache, and any write-back from the L1 to the L2. Snoops from outside the core and cache maintenance operations are not counted.", + "EventCode": "0x16", + "EventName": "L2D_CACHE", + "BriefDescription": "L2 data cache access" + }, + { + "PublicDescription": "L2 data cache refill. This event counts any cacheable transaction from L1 which causes data to be read from outside the core. L2 refills caused by stashes into L2 should not be counted", + "EventCode": "0x17", + "EventName": "L2D_CACHE_REFILL", + "BriefDescription": "L2 data cache refill" + }, + { + "PublicDescription": "L2 data cache write-back. This event counts any write-back of data from the L2 cache to outside the core. This includes snoops to the L2 which return data, regardless of whether they cause an invalidation. Invalidations from the L2 which do not write data outside of the core and snoops which return data from the L1 are not counted", + "EventCode": "0x18", + "EventName": "L2D_CACHE_WB", + "BriefDescription": "L2 data cache write-back" + }, + { + "PublicDescription": "L2 data cache allocation without refill. This event counts any full cache line write into the L2 cache which does not cause a linefill, including write-backs from L1 to L2 and full-line writes which do not allocate into L1.", + "EventCode": "0x20", + "EventName": "L2D_CACHE_ALLOCATE", + "BriefDescription": "L2 data cache allocation without refill" + }, + { + "PublicDescription": "Level 1 data TLB access. This event counts any load or store operation which accesses the data L1 TLB. If both a load and a store are executed on a cycle, this event counts twice. This event counts regardless of whether the MMU is enabled.", + "EventCode": "0x25", + "EventName": "L1D_TLB", + "BriefDescription": "Level 1 data TLB access." + }, + { + "PublicDescription": "Level 1 instruction TLB access. This event counts any instruction fetch which accesses the instruction L1 TLB.This event counts regardless of whether the MMU is enabled.", + "EventCode": "0x26", + "EventName": "L1I_TLB", + "BriefDescription": "Level 1 instruction TLB access" + }, + { + "PublicDescription": "This event counts any full cache line write into the L3 cache which does not cause a linefill, including write-backs from L2 to L3 and full-line writes which do not allocate into L2", + "EventCode": "0x29", + "EventName": "L3D_CACHE_ALLOCATE", + "BriefDescription": "Allocation without refill" + }, + { + "PublicDescription": "Attributable Level 3 unified cache refill. This event counts for any cacheable read transaction returning datafrom the SCU for which the data source was outside the cluster. Transactions such as ReadUnique are counted here as 'read' transactions, even though they can be generated by store instructions.", + "EventCode": "0x2A", + "EventName": "L3D_CACHE_REFILL", + "BriefDescription": "Attributable Level 3 unified cache refill." + }, + { + "PublicDescription": "Attributable Level 3 unified cache access. This event counts for any cacheable read transaction returning datafrom the SCU, or for any cacheable write to the SCU.", + "EventCode": "0x2B", + "EventName": "L3D_CACHE", + "BriefDescription": "Attributable Level 3 unified cache access." + }, + { + "PublicDescription": "Attributable L2 data or unified TLB refill. This event counts on anyrefill of the L2 TLB, caused by either an instruction or data access.This event does not count if the MMU is disabled.", + "EventCode": "0x2D", + "EventName": "L2D_TLB_REFILL", + "BriefDescription": "Attributable L2 data or unified TLB refill" + }, + { + "PublicDescription": "Attributable L2 data or unified TLB access. This event counts on any access to the L2 TLB (caused by a refill of any of the L1 TLBs). This event does not count if the MMU is disabled.", + "EventCode": "0x2F", + "EventName": "L2D_TLB", + "BriefDescription": "Attributable L2 data or unified TLB access" + }, + { + "PublicDescription": "Access to data TLB that caused a page table walk. This event counts on any data access which causes L2D_TLB_REFILL to count.", + "EventCode": "0x34", + "EventName": "DTLB_WALK", + "BriefDescription": "Access to data TLB that caused a page table walk." + }, + { + "PublicDescription": "Access to instruction TLB that caused a page table walk. This event counts on any instruction access which causes L2D_TLB_REFILL to count.", + "EventCode": "0x35", + "EventName": "ITLB_WALK", + "BriefDescription": "Access to instruction TLB that caused a page table walk." + }, + { + "EventCode": "0x36", + "EventName": "LL_CACHE_RD", + "BriefDescription": "Last level cache access, read" + }, + { + "EventCode": "0x37", + "EventName": "LL_CACHE_MISS_RD", + "BriefDescription": "Last level cache miss, read" + }, + { + "ArchStdEvent": "L1D_CACHE_INVAL" + }, + { + "ArchStdEvent": "L1D_CACHE_RD" + }, + { + "ArchStdEvent": "L1D_CACHE_REFILL_INNER" + }, + { + "ArchStdEvent": "L1D_CACHE_REFILL_OUTER" + }, + { + "ArchStdEvent": "L1D_CACHE_REFILL_RD" + }, + { + "ArchStdEvent": "L1D_CACHE_REFILL_WR" + }, + { + "ArchStdEvent": "L1D_CACHE_WB_CLEAN" + }, + { + "ArchStdEvent": "L1D_CACHE_WB_VICTIM" + }, + { + "ArchStdEvent": "L1D_CACHE_WR" + }, + { + "ArchStdEvent": "L1D_TLB_RD" + }, + { + "ArchStdEvent": "L1D_TLB_REFILL_RD" + }, + { + "ArchStdEvent": "L1D_TLB_REFILL_WR" + }, + { + "ArchStdEvent": "L1D_TLB_WR" + }, + { + "ArchStdEvent": "L2D_CACHE_INVAL" + }, + { + "ArchStdEvent": "L2D_CACHE_RD" + }, + { + "ArchStdEvent": "L2D_CACHE_REFILL_RD" + }, + { + "ArchStdEvent": "L2D_CACHE_REFILL_WR" + }, + { + "ArchStdEvent": "L2D_CACHE_WB_CLEAN" + }, + { + "ArchStdEvent": "L2D_CACHE_WB_VICTIM" + }, + { + "ArchStdEvent": "L2D_CACHE_WR" + }, + { + "ArchStdEvent": "L2D_TLB_RD" + }, + { + "ArchStdEvent": "L2D_TLB_REFILL_RD" + }, + { + "ArchStdEvent": "L2D_TLB_REFILL_WR" + }, + { + "ArchStdEvent": "L2D_TLB_WR" + }, + { + "ArchStdEvent": "L3D_CACHE_RD" + } +] diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/exception.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/exception.json new file mode 100644 index 000000000000..98d29c862320 --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/exception.json @@ -0,0 +1,52 @@ +[ + { + "EventCode": "0x09", + "EventName": "EXC_TAKEN", + "BriefDescription": "Exception taken." + }, + { + "PublicDescription": "Local memory error. This event counts any correctable or uncorrectable memory error (ECC or parity) in the protected core RAMs", + "EventCode": "0x1A", + "EventName": "MEMORY_ERROR", + "BriefDescription": "Local memory error." + }, + { + "ArchStdEvent": "EXC_DABORT" + }, + { + "ArchStdEvent": "EXC_FIQ" + }, + { + "ArchStdEvent": "EXC_HVC" + }, + { + "ArchStdEvent": "EXC_IRQ" + }, + { + "ArchStdEvent": "EXC_PABORT" + }, + { + "ArchStdEvent": "EXC_SMC" + }, + { + "ArchStdEvent": "EXC_SVC" + }, + { + "ArchStdEvent": "EXC_TRAP_DABORT" + }, + { + "ArchStdEvent": "EXC_TRAP_FIQ" + }, + { + "ArchStdEvent": "EXC_TRAP_IRQ" + }, + { + "ArchStdEvent": "EXC_TRAP_OTHER" + }, + { + "ArchStdEvent": "EXC_TRAP_PABORT" + }, + { + "ArchStdEvent": "EXC_UNDEF" + } +] diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/instruction.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/instruction.json new file mode 100644 index 000000000000..c153ac706d8d --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/instruction.json @@ -0,0 +1,108 @@ +[ + { + "PublicDescription": "Software increment. Instruction architecturally executed (condition code check pass).", + "EventCode": "0x00", + "EventName": "SW_INCR", + "BriefDescription": "Software increment." + }, + { + "PublicDescription": "Instruction architecturally executed. This event counts all retired instructions, including those that fail their condition check.", + "EventCode": "0x08", + "EventName": "INST_RETIRED", + "BriefDescription": "Instruction architecturally executed." + }, + { + "EventCode": "0x0A", + "EventName": "EXC_RETURN", + "BriefDescription": "Instruction architecturally executed, condition code check pass, exception return." + }, + { + "PublicDescription": "Instruction architecturally executed, condition code check pass, write to CONTEXTIDR. This event only counts writes to CONTEXTIDR in AArch32 state, and via the CONTEXTIDR_EL1 mnemonic in AArch64 state.", + "EventCode": "0x0B", + "EventName": "CID_WRITE_RETIRED", + "BriefDescription": "Instruction architecturally executed, condition code check pass, write to CONTEXTIDR." + }, + { + "EventCode": "0x1B", + "EventName": "INST_SPEC", + "BriefDescription": "Operation speculatively executed" + }, + { + "PublicDescription": "Instruction architecturally executed, condition code check pass, write to TTBR. This event only counts writes to TTBR0/TTBR1 in AArch32 state and TTBR0_EL1/TTBR1_EL1 in AArch64 state.", + "EventCode": "0x1C", + "EventName": "TTBR_WRITE_RETIRED", + "BriefDescription": "Instruction architecturally executed, condition code check pass, write to TTBR" + }, + { + "PublicDescription": "Instruction architecturally executed, branch. This event counts all branches, taken or not. This excludes exception entries, debug entries and CCFAIL branches.", + "EventCode": "0x21", + "EventName": "BR_RETIRED", + "BriefDescription": "Instruction architecturally executed, branch." + }, + { + "PublicDescription": "Instruction architecturally executed, mispredicted branch. This event counts any branch counted by BR_RETIRED which is not correctly predicted and causes a pipeline flush.", + "EventCode": "0x22", + "EventName": "BR_MIS_PRED_RETIRED", + "BriefDescription": "Instruction architecturally executed, mispredicted branch." + }, + { + "ArchStdEvent": "ASE_SPEC" + }, + { + "ArchStdEvent": "BR_IMMED_SPEC" + }, + { + "ArchStdEvent": "BR_INDIRECT_SPEC" + }, + { + "ArchStdEvent": "BR_RETURN_SPEC" + }, + { + "ArchStdEvent": "CRYPTO_SPEC" + }, + { + "ArchStdEvent": "DMB_SPEC" + }, + { + "ArchStdEvent": "DP_SPEC" + }, + { + "ArchStdEvent": "DSB_SPEC" + }, + { + "ArchStdEvent": "ISB_SPEC" + }, + { + "ArchStdEvent": "LDREX_SPEC" + }, + { + "ArchStdEvent": "LDST_SPEC" + }, + { + "ArchStdEvent": "LD_SPEC" + }, + { + "ArchStdEvent": "PC_WRITE_SPEC" + }, + { + "ArchStdEvent": "RC_LD_SPEC" + }, + { + "ArchStdEvent": "RC_ST_SPEC" + }, + { + "ArchStdEvent": "STREX_FAIL_SPEC" + }, + { + "ArchStdEvent": "STREX_PASS_SPEC" + }, + { + "ArchStdEvent": "STREX_SPEC" + }, + { + "ArchStdEvent": "ST_SPEC" + }, + { + "ArchStdEvent": "VFP_SPEC" + } +] diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/memory.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/memory.json new file mode 100644 index 000000000000..b86643253f19 --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/memory.json @@ -0,0 +1,23 @@ +[ + { + "PublicDescription": "Data memory access. This event counts memory accesses due to load or store instructions. This event counts the sum of MEM_ACCESS_RD and MEM_ACCESS_WR.", + "EventCode": "0x13", + "EventName": "MEM_ACCESS", + "BriefDescription": "Data memory access" + }, + { + "ArchStdEvent": "MEM_ACCESS_RD" + }, + { + "ArchStdEvent": "MEM_ACCESS_WR" + }, + { + "ArchStdEvent": "UNALIGNED_LD_SPEC" + }, + { + "ArchStdEvent": "UNALIGNED_ST_SPEC" + }, + { + "ArchStdEvent": "UNALIGNED_LDST_SPEC" + } +] diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/other.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/other.json new file mode 100644 index 000000000000..8bde029a62d5 --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/other.json @@ -0,0 +1,7 @@ +[ + { + "EventCode": "0x31", + "EventName": "REMOTE_ACCESS", + "BriefDescription": "Access to another socket in a multi-socket system" + } +] diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/pipeline.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/pipeline.json new file mode 100644 index 000000000000..010a647f9d02 --- /dev/null +++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/pipeline.json @@ -0,0 +1,14 @@ +[ + { + "PublicDescription": "No operation issued because of the frontend. The counter counts on any cycle when there are no fetched instructions available to dispatch.", + "EventCode": "0x23", + "EventName": "STALL_FRONTEND", + "BriefDescription": "No operation issued because of the frontend." + }, + { + "PublicDescription": "No operation issued because of the backend. The counter counts on any cycle fetched instructions are not dispatched due to resource constraints.", + "EventCode": "0x24", + "EventName": "STALL_BACKEND", + "BriefDescription": "No operation issued because of the backend." + } +] diff --git a/tools/perf/pmu-events/arch/arm64/mapfile.csv b/tools/perf/pmu-events/arch/arm64/mapfile.csv index 927fcddcb4aa..0d609149b82a 100644 --- a/tools/perf/pmu-events/arch/arm64/mapfile.csv +++ b/tools/perf/pmu-events/arch/arm64/mapfile.csv @@ -16,6 +16,8 @@ 0x00000000420f1000,v1,arm/cortex-a53,core 0x00000000410fd070,v1,arm/cortex-a57-a72,core 0x00000000410fd080,v1,arm/cortex-a57-a72,core +0x00000000410fd0b0,v1,arm/cortex-a76-n1,core +0x00000000410fd0c0,v1,arm/cortex-a76-n1,core 0x00000000420f5160,v1,cavium/thunderx2,core 0x00000000430f0af0,v1,cavium/thunderx2,core 0x00000000480fd010,v1,hisilicon/hip08,core -- cgit v1.2.3-59-g8ed1b From 8fcbeae44fde9756036147664d1e74fab7c9902c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 3 Sep 2019 09:47:53 -0300 Subject: perf tools: Remove needless builtin.h include directives Now that builtin.h isn't included by any other header, we can check where it is really needed, i.e. we can remove it and be sure that it isn't being obtained indirectly. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-mn7jheex85iw9qo6tlv26hb2@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/bench/numa.c | 1 - tools/perf/bench/sched-messaging.c | 1 - tools/perf/bench/sched-pipe.c | 1 - tools/perf/util/jitdump.c | 1 - 4 files changed, 4 deletions(-) (limited to 'tools') diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index 62b8ef4bcb1f..5797253b9700 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c @@ -9,7 +9,6 @@ /* For the CLR_() macros */ #include -#include "../builtin.h" #include #include "../util/cloexec.h" diff --git a/tools/perf/bench/sched-messaging.c b/tools/perf/bench/sched-messaging.c index c63eb9a46346..6e499b32bf00 100644 --- a/tools/perf/bench/sched-messaging.c +++ b/tools/perf/bench/sched-messaging.c @@ -12,7 +12,6 @@ #include "../util/util.h" #include -#include "../builtin.h" #include "bench.h" /* Test groups of 20 processes spraying to 20 receivers */ diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c index 35b07f197d48..edd40aafa318 100644 --- a/tools/perf/bench/sched-pipe.c +++ b/tools/perf/bench/sched-pipe.c @@ -11,7 +11,6 @@ */ #include "../util/util.h" #include -#include "../builtin.h" #include "bench.h" #include diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c index b80f29bfc7bb..00db9957fdb0 100644 --- a/tools/perf/util/jitdump.c +++ b/tools/perf/util/jitdump.c @@ -27,7 +27,6 @@ #include "jit.h" #include "jitdump.h" #include "genelf.h" -#include "../builtin.h" #include #include -- cgit v1.2.3-59-g8ed1b From b22bb139dcb370cd3a7f3c5ae29d55bb69235ace Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 3 Sep 2019 09:57:50 -0300 Subject: perf debug: No need to include ui/util.h Nothing from that file is used in util/debug.h, it is only needed in some places that get it indirectly via including util/debug.h, remove that entanglement. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-hn9v4jdova2nt018fqsjyzun@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/scripts.c | 1 + tools/perf/ui/gtk/setup.c | 3 ++- tools/perf/util/debug.h | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c index 586a21acc13d..3b81075b8da8 100644 --- a/tools/perf/ui/browsers/scripts.c +++ b/tools/perf/ui/browsers/scripts.c @@ -2,6 +2,7 @@ #include "../../builtin.h" #include "../../perf.h" #include "../../util/util.h" +#include "../util.h" #include "../../util/hist.h" #include "../../util/debug.h" #include "../../util/symbol.h" diff --git a/tools/perf/ui/gtk/setup.c b/tools/perf/ui/gtk/setup.c index 1a2616b97b5c..f5eee4d66873 100644 --- a/tools/perf/ui/gtk/setup.c +++ b/tools/perf/ui/gtk/setup.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "gtk.h" -#include "../../util/debug.h" +#include +#include "../util.h" extern struct perf_error_ops perf_gtk_eops; diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index b2deee987ffa..d25ae1c4cee9 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h @@ -3,9 +3,9 @@ #ifndef __PERF_DEBUG_H #define __PERF_DEBUG_H +#include #include #include -#include "../ui/util.h" extern int verbose; extern bool quiet, dump_trace; -- cgit v1.2.3-59-g8ed1b From 4a903c2e151423be9af19c7eb35d4667be21c4c1 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 3 Sep 2019 10:11:53 -0300 Subject: perf tools: Remove debug.h from places where it is not needed Pruning a bit more the includes dependency tree. Building this thing on lots of containers takes time, we better reduce the time per build, each container is doing 6 builds when clang and clang-devel are available, and the plan is to do a 'make -C tools/perf build-test' that have many more. Also helps when doing normal development, as touching some random file will have a much reduced chance of triggering lots of rebuilds. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-r889ur2cxe16m91m2a4pl15p@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm64/util/unwind-libunwind.c | 2 +- tools/perf/arch/powerpc/util/sym-handling.c | 1 - tools/perf/tests/clang.c | 1 - tools/perf/ui/browsers/header.c | 1 - tools/perf/ui/gtk/helpline.c | 1 - tools/perf/ui/gtk/util.c | 1 - tools/perf/ui/helpline.c | 1 - tools/perf/ui/tui/helpline.c | 1 - tools/perf/ui/tui/util.c | 1 - tools/perf/util/branch.c | 1 - tools/perf/util/demangle-java.c | 1 - tools/perf/util/libunwind/arm64.c | 1 - tools/perf/util/libunwind/x86_32.c | 1 - tools/perf/util/target.c | 1 - tools/perf/util/usage.c | 1 - tools/perf/util/zlib.c | 2 -- 16 files changed, 1 insertion(+), 17 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm64/util/unwind-libunwind.c b/tools/perf/arch/arm64/util/unwind-libunwind.c index 002520d4036b..1495a9523a23 100644 --- a/tools/perf/arch/arm64/util/unwind-libunwind.c +++ b/tools/perf/arch/arm64/util/unwind-libunwind.c @@ -5,8 +5,8 @@ #include #include "perf_regs.h" #include "../../util/unwind.h" -#include "../../util/debug.h" #endif +#include "../../util/debug.h" int LIBUNWIND__ARCH_REG_ID(int regnum) { diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c index 8a4b717e0a53..abb7a12d8f93 100644 --- a/tools/perf/arch/powerpc/util/sym-handling.c +++ b/tools/perf/arch/powerpc/util/sym-handling.c @@ -4,7 +4,6 @@ * Copyright (C) 2015 Naveen N. Rao, IBM Corporation */ -#include "debug.h" #include "dso.h" #include "symbol.h" #include "map.h" diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c index f45fe11dcf50..ff2711a40940 100644 --- a/tools/perf/tests/clang.c +++ b/tools/perf/tests/clang.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 #include "tests.h" -#include "debug.h" #include "util.h" #include "c++/clang-c.h" #include diff --git a/tools/perf/ui/browsers/header.c b/tools/perf/ui/browsers/header.c index 0f59a7001479..57e6e4332f74 100644 --- a/tools/perf/ui/browsers/header.c +++ b/tools/perf/ui/browsers/header.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#include "util/debug.h" #include "ui/browser.h" #include "ui/keysyms.h" #include "ui/ui.h" diff --git a/tools/perf/ui/gtk/helpline.c b/tools/perf/ui/gtk/helpline.c index e166da9ec767..e40a006aead8 100644 --- a/tools/perf/ui/gtk/helpline.c +++ b/tools/perf/ui/gtk/helpline.c @@ -6,7 +6,6 @@ #include "gtk.h" #include "../ui.h" #include "../helpline.h" -#include "../../util/debug.h" static void gtk_helpline_pop(void) { diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c index c2c558958b9c..c47f5c387838 100644 --- a/tools/perf/ui/gtk/util.c +++ b/tools/perf/ui/gtk/util.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 #include "../util.h" -#include "../../util/debug.h" #include "gtk.h" #include diff --git a/tools/perf/ui/helpline.c b/tools/perf/ui/helpline.c index 54bcd08df87e..e00901450f91 100644 --- a/tools/perf/ui/helpline.c +++ b/tools/perf/ui/helpline.c @@ -3,7 +3,6 @@ #include #include -#include "../util/debug.h" #include "helpline.h" #include "ui.h" #include "../util/util.h" diff --git a/tools/perf/ui/tui/helpline.c b/tools/perf/ui/tui/helpline.c index 5f188f678c55..298d6af82fdd 100644 --- a/tools/perf/ui/tui/helpline.c +++ b/tools/perf/ui/tui/helpline.c @@ -6,7 +6,6 @@ #include #include -#include "../../util/debug.h" #include "../helpline.h" #include "../ui.h" #include "../libslang.h" diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c index 087d9ab054c8..b98dd0e31dc1 100644 --- a/tools/perf/ui/tui/util.c +++ b/tools/perf/ui/tui/util.c @@ -5,7 +5,6 @@ #include #include -#include "../../util/debug.h" #include "../browser.h" #include "../keysyms.h" #include "../helpline.h" diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c index 9d1e090084a2..52261e5f718a 100644 --- a/tools/perf/util/branch.c +++ b/tools/perf/util/branch.c @@ -1,5 +1,4 @@ #include "util/util.h" -#include "util/debug.h" #include "util/map_symbol.h" #include "util/branch.h" #include diff --git a/tools/perf/util/demangle-java.c b/tools/perf/util/demangle-java.c index 763328c151e9..6fb7f34c0814 100644 --- a/tools/perf/util/demangle-java.c +++ b/tools/perf/util/demangle-java.c @@ -3,7 +3,6 @@ #include #include #include -#include "debug.h" #include "symbol.h" #include "demangle-java.h" diff --git a/tools/perf/util/libunwind/arm64.c b/tools/perf/util/libunwind/arm64.c index 66756e6be111..6b4e5a0892f8 100644 --- a/tools/perf/util/libunwind/arm64.c +++ b/tools/perf/util/libunwind/arm64.c @@ -22,7 +22,6 @@ #define LIBUNWIND__ARCH_REG_SP PERF_REG_ARM64_SP #include "unwind.h" -#include "debug.h" #include "libunwind-aarch64.h" #include <../../../../arch/arm64/include/uapi/asm/perf_regs.h> #include "../../arch/arm64/util/unwind-libunwind.c" diff --git a/tools/perf/util/libunwind/x86_32.c b/tools/perf/util/libunwind/x86_32.c index c5e568188e19..21c216c40a3b 100644 --- a/tools/perf/util/libunwind/x86_32.c +++ b/tools/perf/util/libunwind/x86_32.c @@ -22,7 +22,6 @@ #define LIBUNWIND__ARCH_REG_SP PERF_REG_X86_SP #include "unwind.h" -#include "debug.h" #include "libunwind-x86.h" #include <../../../../arch/x86/include/uapi/asm/perf_regs.h> diff --git a/tools/perf/util/target.c b/tools/perf/util/target.c index 565f7aef7e6c..e152d2bbe3a3 100644 --- a/tools/perf/util/target.c +++ b/tools/perf/util/target.c @@ -7,7 +7,6 @@ #include "target.h" #include "util.h" -#include "debug.h" #include #include diff --git a/tools/perf/util/usage.c b/tools/perf/util/usage.c index 3949a60b00ae..196438ee4c9d 100644 --- a/tools/perf/util/usage.c +++ b/tools/perf/util/usage.c @@ -8,7 +8,6 @@ * Copyright (C) Linus Torvalds, 2005 */ #include "util.h" -#include "debug.h" #include #include #include diff --git a/tools/perf/util/zlib.c b/tools/perf/util/zlib.c index 59d456f716e9..deb6e69adb5a 100644 --- a/tools/perf/util/zlib.c +++ b/tools/perf/util/zlib.c @@ -10,8 +10,6 @@ #include "util/compress.h" #include "util/util.h" -#include "util/debug.h" - #define CHUNK_SIZE 16384 -- cgit v1.2.3-59-g8ed1b From fb71c86cc804b8f490fce1b9140014043ec41858 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 3 Sep 2019 10:56:06 -0300 Subject: perf tools: Remove util.h from where it is not needed Check that it is not needed and remove, fixing up some fallout for places where it was only serving to get something else. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-9h6dg6lsqe2usyqjh5rrues4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 2 +- tools/perf/arch/arm64/util/arm-spe.c | 2 +- tools/perf/arch/arm64/util/dwarf-regs.c | 1 - tools/perf/arch/powerpc/util/dwarf-regs.c | 1 - tools/perf/arch/powerpc/util/header.c | 1 - tools/perf/arch/s390/util/machine.c | 2 +- tools/perf/arch/x86/tests/intel-cqm.c | 1 - tools/perf/arch/x86/tests/rdpmc.c | 2 +- tools/perf/arch/x86/util/intel-bts.c | 2 +- tools/perf/arch/x86/util/intel-pt.c | 2 +- tools/perf/arch/x86/util/machine.c | 2 +- tools/perf/bench/sched-messaging.c | 1 - tools/perf/bench/sched-pipe.c | 1 - tools/perf/builtin-config.c | 1 - tools/perf/builtin-evlist.c | 2 -- tools/perf/builtin-report.c | 2 +- tools/perf/perf.c | 2 +- tools/perf/tests/clang.c | 1 - tools/perf/tests/dso-data.c | 1 - tools/perf/tests/event-times.c | 1 - tools/perf/tests/llvm.c | 1 - tools/perf/tests/mmap-thread-lookup.c | 2 +- tools/perf/tests/parse-events.c | 1 - tools/perf/tests/parse-no-sample-id-all.c | 2 -- tools/perf/tests/perf-hooks.c | 1 - tools/perf/tests/pmu.c | 1 - tools/perf/tests/sample-parsing.c | 1 - tools/perf/tests/topology.c | 1 - tools/perf/tests/vmlinux-kallsyms.c | 2 +- tools/perf/ui/browser.c | 1 - tools/perf/ui/browsers/annotate.c | 1 - tools/perf/ui/browsers/map.c | 1 - tools/perf/ui/browsers/res_sample.c | 2 +- tools/perf/ui/browsers/scripts.c | 2 +- tools/perf/ui/gtk/progress.c | 1 - tools/perf/ui/helpline.c | 1 - tools/perf/ui/hist.c | 1 - tools/perf/ui/setup.c | 2 +- tools/perf/ui/tui/setup.c | 2 +- tools/perf/util/annotate.c | 2 +- tools/perf/util/auxtrace.c | 4 +++- tools/perf/util/branch.c | 1 - tools/perf/util/branch.h | 9 ++++++++- tools/perf/util/build-id.c | 2 +- tools/perf/util/cloexec.c | 2 +- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 1 - tools/perf/util/cs-etm.c | 1 - tools/perf/util/data.c | 3 ++- tools/perf/util/debug.c | 1 - tools/perf/util/demangle-rust.c | 1 - tools/perf/util/dwarf-regs.c | 1 - tools/perf/util/evlist.c | 2 +- tools/perf/util/evsel.c | 1 + tools/perf/util/header.c | 3 ++- tools/perf/util/jitdump.c | 1 - tools/perf/util/llvm-utils.c | 1 + tools/perf/util/lzma.c | 2 +- tools/perf/util/perf-hooks.c | 1 - tools/perf/util/record.c | 1 - tools/perf/util/rwsem.c | 1 + tools/perf/util/s390-sample-raw.c | 1 - tools/perf/util/scripting-engines/trace-event-python.c | 1 - tools/perf/util/session.c | 1 + tools/perf/util/srccode.c | 2 +- tools/perf/util/symbol-elf.c | 2 ++ tools/perf/util/symbol-minimal.c | 3 +-- tools/perf/util/symbol.c | 2 +- tools/perf/util/target.c | 1 - tools/perf/util/trace-event-info.c | 2 +- tools/perf/util/trace-event-read.c | 1 - tools/perf/util/trace-event.c | 1 - tools/perf/util/unwind-libdw.c | 1 - tools/perf/util/unwind-libunwind-local.c | 1 - tools/perf/util/vdso.c | 2 +- tools/perf/util/zlib.c | 2 +- 75 files changed, 47 insertions(+), 73 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index c32db09baf0d..5d120b1e35ed 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -25,7 +25,7 @@ #include "../../util/evsel.h" #include "../../util/pmu.h" #include "../../util/cs-etm.h" -#include "../../util/util.h" +#include "../../util/util.h" // page_size #include "../../util/session.h" #include diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index 4b364692da67..eebbf31f995c 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -16,7 +16,7 @@ #include "../../util/evsel.h" #include "../../util/evlist.h" #include "../../util/session.h" -#include "../../util/util.h" +#include "../../util/util.h" // page_size #include "../../util/pmu.h" #include "../../util/debug.h" #include "../../util/auxtrace.h" diff --git a/tools/perf/arch/arm64/util/dwarf-regs.c b/tools/perf/arch/arm64/util/dwarf-regs.c index b047b882c5b1..917b97d7c5d3 100644 --- a/tools/perf/arch/arm64/util/dwarf-regs.c +++ b/tools/perf/arch/arm64/util/dwarf-regs.c @@ -11,7 +11,6 @@ #include #include /* for struct user_pt_regs */ #include -#include "util.h" struct pt_regs_dwarfnum { const char *name; diff --git a/tools/perf/arch/powerpc/util/dwarf-regs.c b/tools/perf/arch/powerpc/util/dwarf-regs.c index 4952890b9428..0c4f4caf53ac 100644 --- a/tools/perf/arch/powerpc/util/dwarf-regs.c +++ b/tools/perf/arch/powerpc/util/dwarf-regs.c @@ -12,7 +12,6 @@ #include #include #include -#include "util.h" struct pt_regs_dwarfnum { const char *name; diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index 0b242664f5ea..b6b7bc7e31a1 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -6,7 +6,6 @@ #include #include #include "header.h" -#include "util.h" #define mfspr(rn) ({unsigned long rval; \ asm volatile("mfspr %0," __stringify(rn) \ diff --git a/tools/perf/arch/s390/util/machine.c b/tools/perf/arch/s390/util/machine.c index c8c86a0c9b79..df099d6cc3f5 100644 --- a/tools/perf/arch/s390/util/machine.c +++ b/tools/perf/arch/s390/util/machine.c @@ -2,7 +2,7 @@ #include #include #include -#include "util.h" +#include "util.h" // page_size #include "machine.h" #include "api/fs/fs.h" #include "debug.h" diff --git a/tools/perf/arch/x86/tests/intel-cqm.c b/tools/perf/arch/x86/tests/intel-cqm.c index 3b5cc3373821..111c0ab2e7b5 100644 --- a/tools/perf/arch/x86/tests/intel-cqm.c +++ b/tools/perf/arch/x86/tests/intel-cqm.c @@ -5,7 +5,6 @@ #include "evlist.h" #include "evsel.h" #include "arch-tests.h" -#include "util.h" #include #include diff --git a/tools/perf/arch/x86/tests/rdpmc.c b/tools/perf/arch/x86/tests/rdpmc.c index 6e67cee792b1..e7640fb047de 100644 --- a/tools/perf/arch/x86/tests/rdpmc.c +++ b/tools/perf/arch/x86/tests/rdpmc.c @@ -13,7 +13,7 @@ #include "tests/tests.h" #include "cloexec.h" #include "event.h" -#include "util.h" +#include "util.h" // page_size #include "arch-tests.h" static u64 rdpmc(unsigned int counter) diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index d263430c045f..090d90e093df 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -22,7 +22,7 @@ #include "../../util/tsc.h" #include "../../util/auxtrace.h" #include "../../util/intel-bts.h" -#include "../../util/util.h" +#include "../../util/util.h" // page_size #define KiB(x) ((x) * 1024) #define MiB(x) ((x) * 1024 * 1024) diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index cb7cf16af79c..3d041b89f018 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -26,7 +26,7 @@ #include "../../util/record.h" #include "../../util/target.h" #include "../../util/tsc.h" -#include "../../util/util.h" +#include "../../util/util.h" // page_size #include "../../util/intel-pt.h" #define KiB(x) ((x) * 1024) diff --git a/tools/perf/arch/x86/util/machine.c b/tools/perf/arch/x86/util/machine.c index 1e9ec783b9a1..42418040bc07 100644 --- a/tools/perf/arch/x86/util/machine.c +++ b/tools/perf/arch/x86/util/machine.c @@ -3,7 +3,7 @@ #include #include -#include "../../util/util.h" +#include "../../util/util.h" // page_size #include "../../util/machine.h" #include "../../util/map.h" #include "../../util/symbol.h" diff --git a/tools/perf/bench/sched-messaging.c b/tools/perf/bench/sched-messaging.c index 6e499b32bf00..97e4a4fb3362 100644 --- a/tools/perf/bench/sched-messaging.c +++ b/tools/perf/bench/sched-messaging.c @@ -10,7 +10,6 @@ * */ -#include "../util/util.h" #include #include "bench.h" diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c index edd40aafa318..3c88d1f201f1 100644 --- a/tools/perf/bench/sched-pipe.c +++ b/tools/perf/bench/sched-pipe.c @@ -9,7 +9,6 @@ * http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c * Ported to perf by Hitoshi Mitake */ -#include "../util/util.h" #include #include "bench.h" diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index 42d8157e047a..2603015f98be 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -9,7 +9,6 @@ #include "util/cache.h" #include -#include "util/util.h" #include "util/debug.h" #include "util/config.h" #include diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c index 238fa3876805..294494e60e48 100644 --- a/tools/perf/builtin-evlist.c +++ b/tools/perf/builtin-evlist.c @@ -5,8 +5,6 @@ */ #include "builtin.h" -#include "util/util.h" - #include #include "perf.h" diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index b18fab94d38d..3047e5169d9d 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -48,7 +48,7 @@ #include "util/auxtrace.h" #include "util/units.h" #include "util/branch.h" -#include "util/util.h" +#include "util/util.h" // perf_tip() #include "ui/ui.h" #include "ui/progress.h" diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 1193b923e801..bb40a108b8f7 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -20,7 +20,7 @@ #include "util/bpf-loader.h" #include "util/debug.h" #include "util/event.h" -#include "util/util.h" +#include "util/util.h" // page_size, usage() #include "ui/ui.h" #include "perf-sys.h" #include diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c index ff2711a40940..2577d3ed1531 100644 --- a/tools/perf/tests/clang.c +++ b/tools/perf/tests/clang.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 #include "tests.h" -#include "util.h" #include "c++/clang-c.h" #include diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index a4874d4ce7ef..627c1aaf1c9e 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -10,7 +10,6 @@ #include #include #include "dso.h" -#include "util.h" #include "machine.h" #include "symbol.h" #include "tests.h" diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index d824a726906c..0228ba435a2a 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -9,7 +9,6 @@ #include "tests.h" #include "evlist.h" #include "evsel.h" -#include "util.h" #include "debug.h" #include "parse-events.h" #include "thread_map.h" diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c index 022e4c9cf092..ae6cda81c209 100644 --- a/tools/perf/tests/llvm.c +++ b/tools/perf/tests/llvm.c @@ -7,7 +7,6 @@ #include "llvm.h" #include "tests.h" #include "debug.h" -#include "util.h" #ifdef HAVE_LIBBPF_SUPPORT static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz) diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c index 360d70deb855..f72889c13538 100644 --- a/tools/perf/tests/mmap-thread-lookup.c +++ b/tools/perf/tests/mmap-thread-lookup.c @@ -14,7 +14,7 @@ #include "map.h" #include "symbol.h" #include "thread.h" -#include "util.h" +#include "util.h" // page_size #define THREADS 4 diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 02ba696fb87f..c25c8e7b41e5 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -6,7 +6,6 @@ #include "tests.h" #include "debug.h" #include "pmu.h" -#include "util.h" #include #include #include diff --git a/tools/perf/tests/parse-no-sample-id-all.c b/tools/perf/tests/parse-no-sample-id-all.c index 8284752a60c8..adf3c9c4a416 100644 --- a/tools/perf/tests/parse-no-sample-id-all.c +++ b/tools/perf/tests/parse-no-sample-id-all.c @@ -1,4 +1,3 @@ -// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -8,7 +7,6 @@ #include "event.h" #include "evlist.h" #include "header.h" -#include "util.h" #include "debug.h" static int process_event(struct evlist **pevlist, union perf_event *event) diff --git a/tools/perf/tests/perf-hooks.c b/tools/perf/tests/perf-hooks.c index a693bcf017ea..dbc27199c65e 100644 --- a/tools/perf/tests/perf-hooks.c +++ b/tools/perf/tests/perf-hooks.c @@ -4,7 +4,6 @@ #include "tests.h" #include "debug.h" -#include "util.h" #include "perf-hooks.h" static void sigsegv_handler(int sig __maybe_unused) diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c index 14a78898d79e..74379ff1f7fa 100644 --- a/tools/perf/tests/pmu.c +++ b/tools/perf/tests/pmu.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "parse-events.h" #include "pmu.h" -#include "util.h" #include "tests.h" #include #include diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c index 5fcc06817076..e3b965e7a233 100644 --- a/tools/perf/tests/sample-parsing.c +++ b/tools/perf/tests/sample-parsing.c @@ -9,7 +9,6 @@ #include "map_symbol.h" #include "branch.h" -#include "util.h" #include "event.h" #include "evsel.h" #include "debug.h" diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index a4f9f5182b47..c963f301d15e 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -4,7 +4,6 @@ #include #include #include "tests.h" -#include "util.h" #include "session.h" #include "evlist.h" #include "debug.h" diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index 01f434c067c6..7f28775875c2 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -7,7 +7,7 @@ #include "dso.h" #include "map.h" #include "symbol.h" -#include "util.h" +#include "util.h" // page_size #include "tests.h" #include "debug.h" #include "machine.h" diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index f93d40b1c203..781afe42e90e 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#include "../util/util.h" #include "../util/string2.h" #include "../util/config.h" #include "libslang.h" diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index ac74ed2c23a0..82207db8f97c 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -2,7 +2,6 @@ #include "../browser.h" #include "../helpline.h" #include "../ui.h" -#include "../util.h" #include "../../util/annotate.h" #include "../../util/debug.h" #include "../../util/dso.h" diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c index 893b065971f6..3d49b916c9e4 100644 --- a/tools/perf/ui/browsers/map.c +++ b/tools/perf/ui/browsers/map.c @@ -5,7 +5,6 @@ #include #include #include -#include "../../util/util.h" #include "../../util/debug.h" #include "../../util/map.h" #include "../../util/dso.h" diff --git a/tools/perf/ui/browsers/res_sample.c b/tools/perf/ui/browsers/res_sample.c index f16a38fea45e..76d356a18790 100644 --- a/tools/perf/ui/browsers/res_sample.c +++ b/tools/perf/ui/browsers/res_sample.c @@ -7,7 +7,7 @@ #include "config.h" #include "time-utils.h" #include "../util.h" -#include "../../util/util.h" +#include "../../util/util.h" // perf_exe() #include "../../perf.h" #include #include diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c index 3b81075b8da8..fc733a6354d4 100644 --- a/tools/perf/ui/browsers/scripts.c +++ b/tools/perf/ui/browsers/scripts.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "../../builtin.h" #include "../../perf.h" -#include "../../util/util.h" +#include "../../util/util.h" // perf_exe() #include "../util.h" #include "../../util/hist.h" #include "../../util/debug.h" diff --git a/tools/perf/ui/gtk/progress.c b/tools/perf/ui/gtk/progress.c index b6ad8857da78..eea6fcde518a 100644 --- a/tools/perf/ui/gtk/progress.c +++ b/tools/perf/ui/gtk/progress.c @@ -3,7 +3,6 @@ #include "gtk.h" #include "../progress.h" -#include "util.h" static GtkWidget *dialog; static GtkWidget *progress; diff --git a/tools/perf/ui/helpline.c b/tools/perf/ui/helpline.c index e00901450f91..911182b3f5e6 100644 --- a/tools/perf/ui/helpline.c +++ b/tools/perf/ui/helpline.c @@ -5,7 +5,6 @@ #include "helpline.h" #include "ui.h" -#include "../util/util.h" char ui_helpline__current[512]; diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 3e533de7d852..f73675500061 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -8,7 +8,6 @@ #include "../util/callchain.h" #include "../util/debug.h" #include "../util/hist.h" -#include "../util/util.h" #include "../util/sort.h" #include "../util/evsel.h" #include "../util/evlist.h" diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c index c7a86b4be9f5..700335cde618 100644 --- a/tools/perf/ui/setup.c +++ b/tools/perf/ui/setup.c @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include #include "../util/debug.h" #include "../util/hist.h" -#include "../util/util.h" #include "ui.h" pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c index 56651a4f5aa0..e9bfe856a5de 100644 --- a/tools/perf/ui/tui/setup.c +++ b/tools/perf/ui/tui/setup.c @@ -2,13 +2,13 @@ #include #include #include +#include #include #ifdef HAVE_BACKTRACE_SUPPORT #include #endif #include "../../util/debug.h" -#include "../../util/util.h" #include "../../perf.h" #include "../browser.h" #include "../helpline.h" diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 1748f528b6e9..d441cca6a517 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -14,7 +14,7 @@ #include #include #include -#include "util.h" +#include "util.h" // hex_width() #include "ui/ui.h" #include "sort.h" #include "build-id.h" diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 6f25224a3def..7ec0a6caa6cd 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -50,10 +50,12 @@ #include "intel-bts.h" #include "arm-spe.h" #include "s390-cpumsf.h" -#include "util.h" +#include "util.h" // page_size #include +#include #include "symbol/kallsyms.h" +#include static bool auxtrace__dont_decode(struct perf_session *session) { diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c index 52261e5f718a..2285b1eb3128 100644 --- a/tools/perf/util/branch.c +++ b/tools/perf/util/branch.c @@ -1,4 +1,3 @@ -#include "util/util.h" #include "util/map_symbol.h" #include "util/branch.h" #include diff --git a/tools/perf/util/branch.h b/tools/perf/util/branch.h index 06f66dad0b79..88e00d268f6f 100644 --- a/tools/perf/util/branch.h +++ b/tools/perf/util/branch.h @@ -1,8 +1,15 @@ #ifndef _PERF_BRANCH_H #define _PERF_BRANCH_H 1 - +/* + * The linux/stddef.h isn't need here, but is needed for __always_inline used + * in files included from uapi/linux/perf_event.h such as + * /usr/include/linux/swab.h and /usr/include/linux/byteorder/little_endian.h, + * detected in at least musl libc, used in Alpine Linux. -acme + */ #include #include +#include +#include #include #include diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index e5fb77755d9e..7928c398a063 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -7,7 +7,7 @@ * Copyright (C) 2009, 2010 Red Hat Inc. * Copyright (C) 2009, 2010 Arnaldo Carvalho de Melo */ -#include "util.h" +#include "util.h" // copyfile_ns(), lsdir(), mkdir_p(), rm_rf() #include #include #include diff --git a/tools/perf/util/cloexec.c b/tools/perf/util/cloexec.c index 4e904fcb2783..a12872f2856a 100644 --- a/tools/perf/util/cloexec.c +++ b/tools/perf/util/cloexec.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include -#include "util.h" +#include "util.h" // for sched_getcpu() #include "../perf-sys.h" #include "cloexec.h" #include "event.h" diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c index 37d7c492b155..cd92a99eb89d 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -17,7 +17,6 @@ #include "cs-etm.h" #include "cs-etm-decoder.h" #include "intlist.h" -#include "util.h" /* use raw logging */ #ifdef CS_DEBUG_RAW diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 707afdbd9529..f87b9c1c9f9a 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -35,7 +35,6 @@ #include "thread.h" #include "thread-stack.h" #include -#include "util.h" #define MAX_TIMESTAMP (~0ULL) diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c index e75c3a279fe8..88fba2ba549f 100644 --- a/tools/perf/util/data.c +++ b/tools/perf/util/data.c @@ -13,9 +13,10 @@ #include #include "data.h" -#include "util.h" +#include "util.h" // rm_rf_perf_data() #include "debug.h" #include "header.h" +#include static void close_dir(struct perf_data_file *files, int nr) { diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index a1b59bd35519..e55114f0336f 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c @@ -17,7 +17,6 @@ #include "event.h" #include "debug.h" #include "print_binary.h" -#include "util.h" #include "target.h" #include "ui/helpline.h" #include "ui/ui.h" diff --git a/tools/perf/util/demangle-rust.c b/tools/perf/util/demangle-rust.c index 423afbbd386b..a659fc69f73a 100644 --- a/tools/perf/util/demangle-rust.c +++ b/tools/perf/util/demangle-rust.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 #include -#include "util.h" #include "debug.h" #include "demangle-rust.h" diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c index db55eddce8cd..1b49ecee5aff 100644 --- a/tools/perf/util/dwarf-regs.c +++ b/tools/perf/util/dwarf-regs.c @@ -5,7 +5,6 @@ * Written by: Masami Hiramatsu */ -#include #include #include #include diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 095924aa186b..ea9517d506d8 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -16,7 +16,7 @@ #include "evsel.h" #include "debug.h" #include "units.h" -#include "util.h" +#include "util.h" // page_size #include "../perf.h" #include "asm/bug.h" #include "bpf-event.h" diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 85825384f9e8..c194ec787f96 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -45,6 +45,7 @@ #include "../perf-sys.h" #include "util/parse-branch-options.h" #include +#include #include diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index b0c34dda30a0..d85827de1b60 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -42,11 +42,12 @@ #include "tool.h" #include "time-utils.h" #include "units.h" -#include "util.h" +#include "util.h" // page_size, perf_exe() #include "cputopo.h" #include "bpf-event.h" #include +#include /* * magic2 = "PERFILE2" diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c index 00db9957fdb0..9f9c6c6a2fd3 100644 --- a/tools/perf/util/jitdump.c +++ b/tools/perf/util/jitdump.c @@ -15,7 +15,6 @@ #include #include "build-id.h" -#include "util.h" #include "event.h" #include "debug.h" #include "evlist.h" diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c index 55fb4b3b1157..8d04e3d070b1 100644 --- a/tools/perf/util/llvm-utils.c +++ b/tools/perf/util/llvm-utils.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/util/lzma.c b/tools/perf/util/lzma.c index 397447066033..39062df02629 100644 --- a/tools/perf/util/lzma.c +++ b/tools/perf/util/lzma.c @@ -7,10 +7,10 @@ #include #include #include "compress.h" -#include "util.h" #include "debug.h" #include #include +#include #define BUFSIZE 8192 diff --git a/tools/perf/util/perf-hooks.c b/tools/perf/util/perf-hooks.c index e635c594f773..7a0ab3507bd5 100644 --- a/tools/perf/util/perf-hooks.c +++ b/tools/perf/util/perf-hooks.c @@ -12,7 +12,6 @@ #include #include #include -#include "util/util.h" #include "util/debug.h" #include "util/perf-hooks.h" diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 286fe816c0f3..860c48895ab6 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -10,7 +10,6 @@ #include #include #include -#include "util.h" #include "cloexec.h" #include "record.h" #include "../perf-sys.h" diff --git a/tools/perf/util/rwsem.c b/tools/perf/util/rwsem.c index 5e52e7baa7b6..f3d29d8ddc99 100644 --- a/tools/perf/util/rwsem.c +++ b/tools/perf/util/rwsem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "util.h" #include "rwsem.h" diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sample-raw.c index 4d9593e331ea..05b43ab4eeef 100644 --- a/tools/perf/util/s390-sample-raw.c +++ b/tools/perf/util/s390-sample-raw.c @@ -22,7 +22,6 @@ #include #include "debug.h" -#include "util.h" #include "session.h" #include "evlist.h" #include "color.h" diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 666a56e88d8e..bb6828532741 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -37,7 +37,6 @@ #include "../dso.h" #include "../callchain.h" #include "../evsel.h" -#include "../util.h" #include "../event.h" #include "../thread.h" #include "../comm.h" diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index e9e4a04f15db..2b133bc22caa 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -34,6 +34,7 @@ #include "ui/progress.h" #include "../perf.h" #include "arch/common.h" +#include #ifdef HAVE_ZSTD_SUPPORT static int perf_session__process_compressed_event(struct perf_session *session, diff --git a/tools/perf/util/srccode.c b/tools/perf/util/srccode.c index adfcf1ff464c..b402f9ca89ab 100644 --- a/tools/perf/util/srccode.c +++ b/tools/perf/util/srccode.c @@ -15,7 +15,7 @@ #include #include "srccode.h" #include "debug.h" -#include "util.h" +#include "util.h" // page_size #define MAXSRCCACHE (32*1024*1024) #define MAXSRCFILES 64 diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 9428639872a6..8b9199c343dd 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -18,8 +18,10 @@ #include "debug.h" #include "util.h" #include +#include #include #include +#include #ifndef EM_AARCH64 #define EM_AARCH64 183 /* ARM 64 bit */ diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c index 7e2813ec9498..d6e99af263ec 100644 --- a/tools/perf/util/symbol-minimal.c +++ b/tools/perf/util/symbol-minimal.c @@ -1,8 +1,6 @@ -// SPDX-License-Identifier: GPL-2.0 #include "dso.h" #include "symbol.h" #include "symsrc.h" -#include "util.h" #include #include @@ -13,6 +11,7 @@ #include #include #include +#include static bool check_need_swap(int file_endian) { diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 765c75df2904..a8f80e427674 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -19,7 +19,7 @@ #include "build-id.h" #include "cap.h" #include "dso.h" -#include "util.h" +#include "util.h" // lsdir() #include "debug.h" #include "event.h" #include "machine.h" diff --git a/tools/perf/util/target.c b/tools/perf/util/target.c index e152d2bbe3a3..a3db13dea937 100644 --- a/tools/perf/util/target.c +++ b/tools/perf/util/target.c @@ -6,7 +6,6 @@ */ #include "target.h" -#include "util.h" #include #include diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index d63d542b2cde..fe07e7550930 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c @@ -2,7 +2,7 @@ /* * Copyright (C) 2008,2009, Steven Rostedt */ -#include "util.h" +#include "util.h" // page_size #include #include #include diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c index b6c0db068be0..8593d3c200c6 100644 --- a/tools/perf/util/trace-event-read.c +++ b/tools/perf/util/trace-event-read.c @@ -15,7 +15,6 @@ #include #include -#include "util.h" #include "trace-event.h" #include "debug.h" diff --git a/tools/perf/util/trace-event.c b/tools/perf/util/trace-event.c index 01b9d89bf5bf..b3ee651e3d91 100644 --- a/tools/perf/util/trace-event.c +++ b/tools/perf/util/trace-event.c @@ -14,7 +14,6 @@ #include #include "trace-event.h" #include "machine.h" -#include "util.h" /* * global trace_event object used by trace_event__tp_format diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index 9ece188ae48a..15f6e46d7124 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c @@ -17,7 +17,6 @@ #include "event.h" #include "perf_regs.h" #include "callchain.h" -#include "util.h" static char *debuginfo_path; diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c index ebdbb056510c..1800887b2255 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -37,7 +37,6 @@ #include "unwind.h" #include "map.h" #include "symbol.h" -#include "util.h" #include "debug.h" #include "asm/bug.h" #include "dso.h" diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index e5e6599603f4..ba4b4395f35d 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c @@ -11,7 +11,7 @@ #include "vdso.h" #include "dso.h" -#include "util.h" +#include #include "map.h" #include "symbol.h" #include "machine.h" diff --git a/tools/perf/util/zlib.c b/tools/perf/util/zlib.c index deb6e69adb5a..78d2297c1b67 100644 --- a/tools/perf/util/zlib.c +++ b/tools/perf/util/zlib.c @@ -7,9 +7,9 @@ #include #include #include +#include #include "util/compress.h" -#include "util/util.h" #define CHUNK_SIZE 16384 -- cgit v1.2.3-59-g8ed1b From 36f3f450a8dc02d9ba0d31bc31d5b329759ed855 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 10 Sep 2019 16:16:27 +0100 Subject: perf probe: Add missing build-id.h header. It uses things defined in that header and was getting it only indirectly, thru dso.h, fix it. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-7u3sf4j5huhi3mqa1q77524b@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/probe-file.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index d13db55a2feb..b659466ea498 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -16,6 +16,7 @@ #include "strlist.h" #include "strfilter.h" #include "debug.h" +#include "build-id.h" #include "dso.h" #include "color.h" #include "symbol.h" -- cgit v1.2.3-59-g8ed1b From 09aa3b002c8cfcea65b2925ec4ff5a6ccdc44d87 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 10 Sep 2019 16:17:19 +0100 Subject: perf symbols: Add missing dso.h header This was being obtained only indirectly, by luck. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-xeolxwr3iftwfw9kmw26shfe@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol-elf.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 8b9199c343dd..6fbfdf8bf61f 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -7,6 +7,7 @@ #include #include +#include "dso.h" #include "map.h" #include "map_groups.h" #include "symbol.h" -- cgit v1.2.3-59-g8ed1b From 87ffb6c6407023419ae6b2770142b0754d9cbaa1 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 10 Sep 2019 16:29:02 +0100 Subject: perf env: Remove needless cpumap.h header Only a 'struct perf_cmp_map' forward allocation is necessary, fix the places that need the header but were getting it indirectly, by luck, from env.h. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-3sj3n534zghxhk7ygzeaqlx9@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm64/util/header.c | 4 +++- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 1 - tools/perf/bench/epoll-ctl.c | 2 +- tools/perf/bench/epoll-wait.c | 2 +- tools/perf/bench/futex-hash.c | 2 +- tools/perf/bench/futex-lock-pi.c | 2 +- tools/perf/bench/futex-requeue.c | 2 +- tools/perf/bench/futex-wake-parallel.c | 3 ++- tools/perf/bench/futex-wake.c | 2 +- tools/perf/builtin-c2c.c | 1 + tools/perf/builtin-sched.c | 2 ++ tools/perf/tests/bitmap.c | 2 +- tools/perf/tests/code-reading.c | 1 - tools/perf/tests/event_update.c | 1 + tools/perf/tests/keep-tracking.c | 3 +-- tools/perf/tests/mem2node.c | 2 +- tools/perf/tests/mmap-basic.c | 3 +-- tools/perf/tests/openat-syscall-all-cpus.c | 5 +++-- tools/perf/tests/switch-tracking.c | 1 - tools/perf/tests/task-exit.c | 2 +- tools/perf/tests/topology.c | 1 + tools/perf/util/arm-spe.c | 1 - tools/perf/util/auxtrace.c | 1 - tools/perf/util/env.h | 3 ++- tools/perf/util/event.c | 2 ++ tools/perf/util/evsel.c | 2 +- tools/perf/util/intel-bts.c | 1 - tools/perf/util/parse-events.c | 1 - tools/perf/util/pmu.c | 1 - tools/perf/util/python.c | 1 - tools/perf/util/record.c | 1 - tools/perf/util/s390-cpumsf.c | 1 - tools/perf/util/scripting-engines/trace-event-python.c | 1 - tools/perf/util/session.c | 1 - tools/perf/util/stat.c | 1 + tools/perf/util/svghelper.c | 2 +- tools/perf/util/top.c | 1 - 37 files changed, 31 insertions(+), 34 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm64/util/header.c b/tools/perf/arch/arm64/util/header.c index e41defaaa2e6..a32e4b72a98f 100644 --- a/tools/perf/arch/arm64/util/header.c +++ b/tools/perf/arch/arm64/util/header.c @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include "debug.h" #include "header.h" @@ -29,7 +31,7 @@ char *get_cpuid_str(struct perf_pmu *pmu) /* read midr from list of cpus mapped to this pmu */ cpus = perf_cpu_map__get(pmu->cpus); - for (cpu = 0; cpu < cpus->nr; cpu++) { + for (cpu = 0; cpu < perf_cpu_map__nr(cpus); cpu++) { scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d"MIDR, sysfs, cpus->map[cpu]); diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index eb3635941c2b..0a4570b340fa 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -15,7 +15,6 @@ #include "evlist.h" #include "evsel.h" #include "thread_map.h" -#include "cpumap.h" #include "record.h" #include "tsc.h" #include "tests/tests.h" diff --git a/tools/perf/bench/epoll-ctl.c b/tools/perf/bench/epoll-ctl.c index d1caa4a0a12a..bb617e568841 100644 --- a/tools/perf/bench/epoll-ctl.c +++ b/tools/perf/bench/epoll-ctl.c @@ -21,12 +21,12 @@ #include #include #include +#include #include #include "../util/stat.h" #include #include "bench.h" -#include "cpumap.h" #include diff --git a/tools/perf/bench/epoll-wait.c b/tools/perf/bench/epoll-wait.c index f6b4472847d2..7af694437f4e 100644 --- a/tools/perf/bench/epoll-wait.c +++ b/tools/perf/bench/epoll-wait.c @@ -76,12 +76,12 @@ #include #include #include +#include #include #include "../util/stat.h" #include #include "bench.h" -#include "cpumap.h" #include diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c index 80e138904c66..8ba0c3330a9a 100644 --- a/tools/perf/bench/futex-hash.c +++ b/tools/perf/bench/futex-hash.c @@ -20,13 +20,13 @@ #include #include #include +#include #include #include "../util/stat.h" #include #include "bench.h" #include "futex.h" -#include "cpumap.h" #include diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c index c5d6d0abbaa9..d0cae8125423 100644 --- a/tools/perf/bench/futex-lock-pi.c +++ b/tools/perf/bench/futex-lock-pi.c @@ -14,10 +14,10 @@ #include #include #include +#include #include #include "bench.h" #include "futex.h" -#include "cpumap.h" #include #include diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index 75d3418c1a88..a00a6891447a 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c @@ -20,10 +20,10 @@ #include #include #include +#include #include #include "bench.h" #include "futex.h" -#include "cpumap.h" #include #include diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c index 163fe16c275a..a053cf2b7039 100644 --- a/tools/perf/bench/futex-wake-parallel.c +++ b/tools/perf/bench/futex-wake-parallel.c @@ -29,7 +29,8 @@ int bench_futex_wake_parallel(int argc __maybe_unused, const char **argv __maybe #include #include #include "futex.h" -#include "cpumap.h" +#include +#include #include #include diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c index 77dcdc13618a..df810096abfe 100644 --- a/tools/perf/bench/futex-wake.c +++ b/tools/perf/bench/futex-wake.c @@ -20,10 +20,10 @@ #include #include #include +#include #include #include "bench.h" #include "futex.h" -#include "cpumap.h" #include #include diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index b09b12e0976b..61aaacc2aedd 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -20,6 +20,7 @@ #include #include "debug.h" #include "builtin.h" +#include #include #include #include "map_symbol.h" diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index ec96d64aec69..511e19a7aafa 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -3,6 +3,7 @@ #include "perf.h" #include "perf-sys.h" +#include "util/cpumap.h" #include "util/evlist.h" #include "util/evsel.h" #include "util/symbol.h" @@ -36,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c index db2aadff3708..96c137360918 100644 --- a/tools/perf/tests/bitmap.c +++ b/tools/perf/tests/bitmap.c @@ -2,8 +2,8 @@ #include #include #include +#include #include "tests.h" -#include "cpumap.h" #include "debug.h" #define NBITS 100 diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index c1c29e08e7fb..8d9020c46ca9 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -19,7 +19,6 @@ #include "evlist.h" #include "evsel.h" #include "thread_map.h" -#include "cpumap.h" #include "machine.h" #include "map.h" #include "symbol.h" diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index cac4290e233a..317eb8c5ccd4 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -2,6 +2,7 @@ #include #include #include +#include "cpumap.h" #include "evlist.h" #include "evsel.h" #include "header.h" diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 9f0762d987fa..df0fd5a44e04 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -12,7 +12,6 @@ #include "evsel.h" #include "record.h" #include "thread_map.h" -#include "cpumap.h" #include "tests.h" #define CHECK__(x) { \ @@ -143,7 +142,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un found = find_comm(evlist, comm); if (found != 1) { - pr_debug("Seconf time, failed to find tracking event.\n"); + pr_debug("Second time, failed to find tracking event.\n"); goto out_err; } diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c index 7672ade70f20..a258bd51f1a4 100644 --- a/tools/perf/tests/mem2node.c +++ b/tools/perf/tests/mem2node.c @@ -4,7 +4,7 @@ #include #include #include -#include "cpumap.h" +#include #include "debug.h" #include "env.h" #include "mem2node.h" diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 85e1d7337dc0..042757629e90 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -10,7 +10,6 @@ #include "evlist.h" #include "evsel.h" #include "thread_map.h" -#include "cpumap.h" #include "tests.h" #include #include @@ -53,7 +52,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse cpus = perf_cpu_map__new(NULL); if (cpus == NULL) { - pr_debug("cpu_map__new\n"); + pr_debug("perf_cpu_map__new\n"); goto out_free_threads; } diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index 9171f77cd9cd..93c176523e38 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -14,7 +14,8 @@ #include "evsel.h" #include "tests.h" #include "thread_map.h" -#include "cpumap.h" +#include +#include #include "debug.h" #include "stat.h" #include "util/counts.h" @@ -37,7 +38,7 @@ int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int cpus = perf_cpu_map__new(NULL); if (cpus == NULL) { - pr_debug("cpu_map__new\n"); + pr_debug("perf_cpu_map__new\n"); goto out_thread_map_delete; } diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 1a60fa1219f5..3fb1ff7b8a2f 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -14,7 +14,6 @@ #include "evlist.h" #include "evsel.h" #include "thread_map.h" -#include "cpumap.h" #include "record.h" #include "tests.h" diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index f610e8c0a083..088c7708b03a 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -4,12 +4,12 @@ #include "evsel.h" #include "target.h" #include "thread_map.h" -#include "cpumap.h" #include "tests.h" #include #include #include +#include #include static int exited; diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index c963f301d15e..7d845d913d7d 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -3,6 +3,7 @@ #include #include #include +#include "cpumap.h" #include "tests.h" #include "session.h" #include "evlist.h" diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c index 8a7340f6a2a2..53be12b23ff4 100644 --- a/tools/perf/util/arm-spe.c +++ b/tools/perf/util/arm-spe.c @@ -16,7 +16,6 @@ #include #include -#include "cpumap.h" #include "color.h" #include "evsel.h" #include "machine.h" diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 7ec0a6caa6cd..1c0ff5acff83 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -31,7 +31,6 @@ #include "map.h" #include "pmu.h" #include "evsel.h" -#include "cpumap.h" #include "symbol.h" #include "thread_map.h" #include "asm/bug.h" diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h index d8e083d42610..db40906e2937 100644 --- a/tools/perf/util/env.h +++ b/tools/perf/util/env.h @@ -4,9 +4,10 @@ #include #include -#include "cpumap.h" #include "rwsem.h" +struct perf_cpu_map; + struct cpu_topology_map { int socket_id; int die_id; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index f4afbb858ebb..d65ae7cf9316 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -11,6 +12,7 @@ #include #include #include +#include "cpumap.h" #include "dso.h" #include "event.h" #include "debug.h" diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index c194ec787f96..5b40b840624c 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -31,7 +31,7 @@ #include "event.h" #include "evsel.h" #include "evlist.h" -#include "cpumap.h" +#include #include "thread_map.h" #include "target.h" #include "perf_regs.h" diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index aacffa2b0362..15f87a09f4fe 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c @@ -14,7 +14,6 @@ #include #include -#include "cpumap.h" #include "color.h" #include "evsel.h" #include "evlist.h" diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 5ec21d21113c..a33a1d5059a2 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -30,7 +30,6 @@ #include "parse-events-flex.h" #include "pmu.h" #include "thread_map.h" -#include "cpumap.h" #include "probe-file.h" #include "asm/bug.h" #include "util/parse-branch-options.h" diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index fb597fa94234..5608da82ad23 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -20,7 +20,6 @@ #include "debug.h" #include "pmu.h" #include "parse-events.h" -#include "cpumap.h" #include "header.h" #include "pmu-events/pmu-events.h" #include "string2.h" diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 07ca4535e6f7..96dd3333c911 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -11,7 +11,6 @@ #include "callchain.h" #include "evsel.h" #include "event.h" -#include "cpumap.h" #include "print_binary.h" #include "thread_map.h" #include "trace-event.h" diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 860c48895ab6..8a015fc0aba0 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -2,7 +2,6 @@ #include "debug.h" #include "evlist.h" #include "evsel.h" -#include "cpumap.h" #include "parse-events.h" #include #include diff --git a/tools/perf/util/s390-cpumsf.c b/tools/perf/util/s390-cpumsf.c index 24a99909d8b3..6785cd87aa4d 100644 --- a/tools/perf/util/s390-cpumsf.c +++ b/tools/perf/util/s390-cpumsf.c @@ -151,7 +151,6 @@ #include #include -#include "cpumap.h" #include "color.h" #include "evsel.h" #include "evlist.h" diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index bb6828532741..5d341efc3237 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -48,7 +48,6 @@ #include "map.h" #include "symbol.h" #include "thread_map.h" -#include "cpumap.h" #include "print_binary.h" #include "stat.h" #include "mem-events.h" diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 2b133bc22caa..2b583e6adb49 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -22,7 +22,6 @@ #include "symbol.h" #include "session.h" #include "tool.h" -#include "cpumap.h" #include "perf_regs.h" #include "asm/bug.h" #include "auxtrace.h" diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 8f1ea27f976f..d309c1cc13db 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -4,6 +4,7 @@ #include #include #include "counts.h" +#include "cpumap.h" #include "debug.h" #include "header.h" #include "stat.h" diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index 582f4a69cd48..96f941e01681 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c @@ -17,11 +17,11 @@ #include #include #include +#include #include #include "env.h" #include "svghelper.h" -#include "cpumap.h" static u64 first_time, last_time; static u64 turbo_frequency, max_freq; diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c index 51fb574998bb..ef96e3dd6902 100644 --- a/tools/perf/util/top.c +++ b/tools/perf/util/top.c @@ -5,7 +5,6 @@ * Refactored from builtin-top.c, see that files for further copyright notes. */ -#include "cpumap.h" #include "event.h" #include "evlist.h" #include "evsel.h" -- cgit v1.2.3-59-g8ed1b From 278306163882a3557fb2c69fd2cc632a2f9ef601 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 10 Sep 2019 16:42:52 +0100 Subject: perf event: Move perf_event__synthesize* to event.h Where is the perf_event__handler_t typedef they need, which was the only reason for header.h to be including event.h, untangle that. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-outjyzh1o29ndcv9lsqyzt87@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/event.h | 36 ++++++++++++++++++++++++++++++++++++ tools/perf/util/header.h | 42 +++--------------------------------------- 2 files changed, 39 insertions(+), 39 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 47ad81d47b1a..4e6d33c76d57 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -279,6 +279,9 @@ enum { void perf_event__print_totals(void); +struct evlist; +struct evsel; +struct perf_session; struct perf_tool; struct perf_thread_map; struct perf_cpu_map; @@ -290,6 +293,39 @@ typedef int (*perf_event__handler_t)(struct perf_tool *tool, struct perf_sample *sample, struct machine *machine); +int perf_event__synthesize_attr(struct perf_tool *tool, + struct perf_event_attr *attr, u32 ids, u64 *id, + perf_event__handler_t process); +int perf_event__synthesize_attrs(struct perf_tool *tool, + struct evlist *evlist, + perf_event__handler_t process); +int perf_event__synthesize_build_id(struct perf_tool *tool, + struct dso *pos, u16 misc, + perf_event__handler_t process, + struct machine *machine); +int perf_event__synthesize_extra_attr(struct perf_tool *tool, + struct evlist *evsel_list, + perf_event__handler_t process, + bool is_pipe); +int perf_event__synthesize_event_update_cpus(struct perf_tool *tool, + struct evsel *evsel, + perf_event__handler_t process); +int perf_event__synthesize_event_update_name(struct perf_tool *tool, + struct evsel *evsel, + perf_event__handler_t process); +int perf_event__synthesize_event_update_scale(struct perf_tool *tool, + struct evsel *evsel, + perf_event__handler_t process); +int perf_event__synthesize_event_update_unit(struct perf_tool *tool, + struct evsel *evsel, + perf_event__handler_t process); +int perf_event__synthesize_features(struct perf_tool *tool, + struct perf_session *session, + struct evlist *evlist, + perf_event__handler_t process); +int perf_event__synthesize_tracing_data(struct perf_tool *tool, + int fd, struct evlist *evlist, + perf_event__handler_t process); int perf_event__synthesize_thread_map(struct perf_tool *tool, struct perf_thread_map *threads, perf_event__handler_t process, diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 3e48ae3c49b1..999dac41871e 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -5,10 +5,10 @@ #include #include #include +#include // FILE #include #include #include -#include "event.h" #include "env.h" #include "pmu.h" @@ -94,6 +94,8 @@ struct perf_header { struct evlist; struct perf_session; +struct perf_tool; +union perf_event; int perf_session__read_header(struct perf_session *session); int perf_session__write_header(struct perf_session *session, @@ -115,54 +117,16 @@ int perf_header__process_sections(struct perf_header *header, int fd, int perf_header__fprintf_info(struct perf_session *s, FILE *fp, bool full); -int perf_event__synthesize_features(struct perf_tool *tool, - struct perf_session *session, - struct evlist *evlist, - perf_event__handler_t process); - -int perf_event__synthesize_extra_attr(struct perf_tool *tool, - struct evlist *evsel_list, - perf_event__handler_t process, - bool is_pipe); - int perf_event__process_feature(struct perf_session *session, union perf_event *event); - -int perf_event__synthesize_attr(struct perf_tool *tool, - struct perf_event_attr *attr, u32 ids, u64 *id, - perf_event__handler_t process); -int perf_event__synthesize_attrs(struct perf_tool *tool, - struct evlist *evlist, - perf_event__handler_t process); -int perf_event__synthesize_event_update_unit(struct perf_tool *tool, - struct evsel *evsel, - perf_event__handler_t process); -int perf_event__synthesize_event_update_scale(struct perf_tool *tool, - struct evsel *evsel, - perf_event__handler_t process); -int perf_event__synthesize_event_update_name(struct perf_tool *tool, - struct evsel *evsel, - perf_event__handler_t process); -int perf_event__synthesize_event_update_cpus(struct perf_tool *tool, - struct evsel *evsel, - perf_event__handler_t process); int perf_event__process_attr(struct perf_tool *tool, union perf_event *event, struct evlist **pevlist); int perf_event__process_event_update(struct perf_tool *tool, union perf_event *event, struct evlist **pevlist); size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp); - -int perf_event__synthesize_tracing_data(struct perf_tool *tool, - int fd, struct evlist *evlist, - perf_event__handler_t process); int perf_event__process_tracing_data(struct perf_session *session, union perf_event *event); - -int perf_event__synthesize_build_id(struct perf_tool *tool, - struct dso *pos, u16 misc, - perf_event__handler_t process, - struct machine *machine); int perf_event__process_build_id(struct perf_session *session, union perf_event *event); bool is_perf_magic(u64 magic); -- cgit v1.2.3-59-g8ed1b From b251892d6ceafa3c8f8e6835a664e248766b1b3e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 10 Sep 2019 17:17:33 +0100 Subject: perf stat: Move perf_stat_synthesize_config() to event.h Together with the other synthsizers, and rename it to perf_event__synthesize_stat_events(). This allows us to stop including event.h in util/stat.h. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-q5ebhrp44txboobs86htu5r9@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 4 ++-- tools/perf/util/event.h | 5 +++++ tools/perf/util/stat.c | 10 +++++----- tools/perf/util/stat.h | 8 ++------ 4 files changed, 14 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 5bc0c570b7b6..b55e8060810b 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -540,8 +540,8 @@ try_again: if (err < 0) return err; - err = perf_stat_synthesize_config(&stat_config, NULL, evsel_list, - process_synthesized_event, is_pipe); + err = perf_event__synthesize_stat_events(&stat_config, NULL, evsel_list, + process_synthesized_event, is_pipe); if (err < 0) return err; } diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 4e6d33c76d57..89a2404170a0 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -293,6 +293,11 @@ typedef int (*perf_event__handler_t)(struct perf_tool *tool, struct perf_sample *sample, struct machine *machine); +int perf_event__synthesize_stat_events(struct perf_stat_config *config, + struct perf_tool *tool, + struct evlist *evlist, + perf_event__handler_t process, + bool attrs); int perf_event__synthesize_attr(struct perf_tool *tool, struct perf_event_attr *attr, u32 ids, u64 *id, perf_event__handler_t process); diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index d309c1cc13db..2e318d95c528 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -495,11 +495,11 @@ int create_perf_stat_counter(struct evsel *evsel, return perf_evsel__open_per_thread(evsel, evsel->core.threads); } -int perf_stat_synthesize_config(struct perf_stat_config *config, - struct perf_tool *tool, - struct evlist *evlist, - perf_event__handler_t process, - bool attrs) +int perf_event__synthesize_stat_events(struct perf_stat_config *config, + struct perf_tool *tool, + struct evlist *evlist, + perf_event__handler_t process, + bool attrs) { int err; diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 14fe3e548229..0f9c9f6e2041 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -7,8 +7,9 @@ #include #include #include "rblist.h" -#include "event.h" +struct perf_cpu_map; +struct perf_stat_config; struct timespec; struct stats { @@ -210,11 +211,6 @@ size_t perf_event__fprintf_stat_config(union perf_event *event, FILE *fp); int create_perf_stat_counter(struct evsel *evsel, struct perf_stat_config *config, struct target *target); -int perf_stat_synthesize_config(struct perf_stat_config *config, - struct perf_tool *tool, - struct evlist *evlist, - perf_event__handler_t process, - bool attrs); void perf_evlist__print_counters(struct evlist *evlist, struct perf_stat_config *config, -- cgit v1.2.3-59-g8ed1b From 9c9e754fb804828473c5131bb3e7df78bde396e6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 10 Sep 2019 17:24:07 +0100 Subject: perf callchain: Remove needless event.h include All we need is a bunch of struct forward declarations and then add event.h to the only place that was getting it indirectly via callchain.h. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-qq2xhyuxcvx5vmxha9otjd8d@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/powerpc/util/skip-callchain-idx.c | 1 + tools/perf/util/callchain.h | 5 ++++- tools/perf/util/evsel_fprintf.c | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/perf/arch/powerpc/util/skip-callchain-idx.c index fc9c2f5fcd52..3018a054526a 100644 --- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c +++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c @@ -13,6 +13,7 @@ #include "util/callchain.h" #include "util/debug.h" #include "util/dso.h" +#include "util/event.h" // struct ip_callchain #include "util/map.h" #include "util/symbol.h" diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index b042ceef4114..83398e5bbe4b 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -4,12 +4,15 @@ #include #include -#include "event.h" #include "map_symbol.h" #include "branch.h" +struct addr_location; struct evsel; +struct ip_callchain; struct map; +struct perf_sample; +struct thread; #define HELP_PAD "\t\t\t\t" diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c index 496fec01f5d1..a8cbdf4c2753 100644 --- a/tools/perf/util/evsel_fprintf.c +++ b/tools/perf/util/evsel_fprintf.c @@ -4,6 +4,7 @@ #include #include #include "evsel.h" +#include "util/event.h" #include "callchain.h" #include "map.h" #include "strlist.h" -- cgit v1.2.3-59-g8ed1b From 5939cacc60d22161adba3d6c8b3fe88b76e0f6c0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 11 Sep 2019 12:54:33 +0100 Subject: perf python: Remove debug.h We only need to have the prototype for the eprintf() replacement we use in the python binding, provide it and avoid dragging debug.h as a dependency. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-s0gy4ur3drmhsknsddwjco59@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/python.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 96dd3333c911..0ba19dd75510 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -6,7 +6,6 @@ #include #include #include -#include "debug.h" #include "evlist.h" #include "callchain.h" #include "evsel.h" @@ -60,6 +59,8 @@ int parse_callchain_record(const char *arg __maybe_unused, */ int verbose; +int eprintf(int level, int var, const char *fmt, ...); + int eprintf(int level, int var, const char *fmt, ...) { va_list args; -- cgit v1.2.3-59-g8ed1b From 3793d4de06fac8dcd25bf91386cf88415dbe99ad Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 18 Sep 2019 10:09:54 -0300 Subject: perf hist: Add missing 'struct branch_stack' forward declaration Its needed, was being obtained indirectly, fix it. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-srzphk0ehptfn3zqmpkgsi65@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 34803e33dc80..6a186b668303 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -15,6 +15,7 @@ struct addr_location; struct map_symbol; struct mem_info; struct branch_info; +struct branch_stack; struct block_info; struct symbol; struct ui_progress; -- cgit v1.2.3-59-g8ed1b From 3f79132a47035dd4609cc5f47715331dfafaa1fa Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 18 Sep 2019 10:10:43 -0300 Subject: perf annotate: Add missing machine.h include directive We use what is defined there, were getting it by luck, indirectly, fix it. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-56g4jshmktniundmiw7h845k@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 4e4d2e76232e..553c651fa0a2 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -27,6 +27,7 @@ #include "util/sort.h" #include "util/hist.h" #include "util/dso.h" +#include "util/machine.h" #include "util/map.h" #include "util/session.h" #include "util/tool.h" -- cgit v1.2.3-59-g8ed1b From f12be047d981bb802d8cf78eb220db3ee97f0513 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 18 Sep 2019 10:11:20 -0300 Subject: perf sched: Add missing event.h include directive We use what is defined there, were getting it by luck, indirectly, fix it. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-e1cdt9557ctpvs3jb9c16qe6@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-sched.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 511e19a7aafa..f0b828c201cc 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -24,6 +24,7 @@ #include "util/trace-event.h" #include "util/debug.h" +#include "util/event.h" #include #include -- cgit v1.2.3-59-g8ed1b From bd23ac11fe9312bab40e129b402757fd7a23dc8e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 18 Sep 2019 10:12:07 -0300 Subject: perf auxtrace: Add missing 'struct perf_sample' forward declaration Its needed, was being obtained indirectly, fix it. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-c3k1il7sm28old4e22nwlm7l@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/auxtrace.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index 37e70dc01436..1ed902a24a39 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -24,6 +24,7 @@ struct perf_session; struct evlist; struct perf_tool; struct perf_mmap; +struct perf_sample; struct option; struct record_opts; struct perf_record_auxtrace_info; -- cgit v1.2.3-59-g8ed1b From ea49e01cfabd73c94a61649cd04fa524a2beff3c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 18 Sep 2019 11:36:13 -0300 Subject: perf tools: Move event synthesizing routines to separate header Those are the only routines using the perf_event__handler_t typedef and are all related, so move to a separate header to reduce the header dependency tree, lots of places were getting event.h and even stdio.h, limits.h indirectly, so fix those as well. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-yvx9u1mf7baq6cu1abfhbqgs@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/util/archinsn.c | 1 + tools/perf/arch/x86/util/event.c | 2 + tools/perf/arch/x86/util/machine.c | 1 + tools/perf/arch/x86/util/tsc.c | 2 + tools/perf/builtin-inject.c | 1 + tools/perf/builtin-kvm.c | 1 + tools/perf/builtin-record.c | 1 + tools/perf/builtin-stat.c | 1 + tools/perf/builtin-top.c | 1 + tools/perf/builtin-trace.c | 1 + tools/perf/tests/code-reading.c | 1 + tools/perf/tests/cpumap.c | 1 + tools/perf/tests/dwarf-unwind.c | 1 + tools/perf/tests/event_update.c | 1 + tools/perf/tests/hists_common.c | 2 + tools/perf/tests/mmap-thread-lookup.c | 2 + tools/perf/tests/sample-parsing.c | 1 + tools/perf/tests/stat.c | 1 + tools/perf/tests/thread-map.c | 1 + tools/perf/ui/stdio/hist.c | 1 + tools/perf/util/auxtrace.c | 1 + tools/perf/util/auxtrace.h | 17 +---- tools/perf/util/bpf-event.c | 1 + tools/perf/util/bpf-event.h | 15 +---- tools/perf/util/callchain.c | 1 + tools/perf/util/event.c | 1 + tools/perf/util/event.h | 118 +--------------------------------- tools/perf/util/evsel.c | 1 + tools/perf/util/header.c | 1 + tools/perf/util/intel-bts.c | 1 + tools/perf/util/intel-pt.c | 1 + tools/perf/util/machine.c | 10 +++ tools/perf/util/machine.h | 15 ----- tools/perf/util/session.c | 1 + tools/perf/util/session.h | 5 -- tools/perf/util/stat.c | 1 + tools/perf/util/synthetic-events.h | 103 +++++++++++++++++++++++++++++ tools/perf/util/tsc.h | 14 +--- 38 files changed, 154 insertions(+), 177 deletions(-) create mode 100644 tools/perf/util/synthetic-events.h (limited to 'tools') diff --git a/tools/perf/arch/x86/util/archinsn.c b/tools/perf/arch/x86/util/archinsn.c index 9876c7a7ed7c..3e6791531ca5 100644 --- a/tools/perf/arch/x86/util/archinsn.c +++ b/tools/perf/arch/x86/util/archinsn.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "../../../../arch/x86/include/asm/insn.h" #include "archinsn.h" +#include "event.h" #include "machine.h" #include "thread.h" #include "symbol.h" diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/event.c index a3a0b6884779..d357c625c09f 100644 --- a/tools/perf/arch/x86/util/event.c +++ b/tools/perf/arch/x86/util/event.c @@ -3,6 +3,8 @@ #include #include +#include "../../util/event.h" +#include "../../util/synthetic-events.h" #include "../../util/machine.h" #include "../../util/tool.h" #include "../../util/map.h" diff --git a/tools/perf/arch/x86/util/machine.c b/tools/perf/arch/x86/util/machine.c index 42418040bc07..f0c289862f9f 100644 --- a/tools/perf/arch/x86/util/machine.c +++ b/tools/perf/arch/x86/util/machine.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include #include "../../util/util.h" // page_size diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c index c5197a15119b..2f55afb14e1f 100644 --- a/tools/perf/arch/x86/util/tsc.c +++ b/tools/perf/arch/x86/util/tsc.c @@ -8,6 +8,8 @@ #include #include #include "../../../util/debug.h" +#include "../../../util/event.h" +#include "../../../util/synthetic-events.h" #include "../../../util/tsc.h" int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc, diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index c14f40b858bc..23a76cf3846f 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -21,6 +21,7 @@ #include "util/auxtrace.h" #include "util/jit.h" #include "util/symbol.h" +#include "util/synthetic-events.h" #include "util/thread.h" #include diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 0a4fcbe32bf6..ac6d6e061dc5 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -17,6 +17,7 @@ #include "util/debug.h" #include "util/tool.h" #include "util/stat.h" +#include "util/synthetic-events.h" #include "util/top.h" #include "util/data.h" #include "util/ordered-events.h" diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 1447004eee8a..907d4d4677a3 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -38,6 +38,7 @@ #include "util/trigger.h" #include "util/perf-hooks.h" #include "util/cpu-set-sched.h" +#include "util/synthetic-events.h" #include "util/time-utils.h" #include "util/units.h" #include "util/bpf-event.h" diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index b55e8060810b..eece3d1e429a 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -61,6 +61,7 @@ #include "util/tool.h" #include "util/string2.h" #include "util/metricgroup.h" +#include "util/synthetic-events.h" #include "util/target.h" #include "util/time-utils.h" #include "util/top.h" diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 726e3f2dd8c7..b052470f89b4 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -32,6 +32,7 @@ #include "util/map.h" #include "util/session.h" #include "util/symbol.h" +#include "util/synthetic-events.h" #include "util/top.h" #include "util/util.h" #include diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 0f633f0d6be8..f0f735093e21 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -28,6 +28,7 @@ #include "util/dso.h" #include "util/env.h" #include "util/event.h" +#include "util/synthetic-events.h" #include "util/evlist.h" #include "util/evswitch.h" #include diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 8d9020c46ca9..fd02c1f1d976 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -24,6 +24,7 @@ #include "symbol.h" #include "event.h" #include "record.h" +#include "util/synthetic-events.h" #include "thread.h" #include "tests.h" diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index 39493de50117..8a0d236202b0 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -3,6 +3,7 @@ #include #include "cpumap.h" #include "event.h" +#include "util/synthetic-events.h" #include #include #include diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c index 4125255ff637..4f4ecbcbe87e 100644 --- a/tools/perf/tests/dwarf-unwind.c +++ b/tools/perf/tests/dwarf-unwind.c @@ -15,6 +15,7 @@ #include "symbol.h" #include "thread.h" #include "callchain.h" +#include "util/synthetic-events.h" #if defined (__x86_64__) || defined (__i386__) || defined (__powerpc__) #include "arch-tests.h" diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index 317eb8c5ccd4..4bb772e2b73d 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -7,6 +7,7 @@ #include "evsel.h" #include "header.h" #include "machine.h" +#include "util/synthetic-events.h" #include "tool.h" #include "tests.h" #include "debug.h" diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c index de110d8f169b..6f34d08b84e5 100644 --- a/tools/perf/tests/hists_common.c +++ b/tools/perf/tests/hists_common.c @@ -2,6 +2,7 @@ #include #include "util/debug.h" #include "util/dso.h" +#include "util/event.h" // struct perf_sample #include "util/map.h" #include "util/symbol.h" #include "util/sort.h" @@ -10,6 +11,7 @@ #include "util/thread.h" #include "tests/hists_common.h" #include +#include static struct { u32 pid; diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c index f72889c13538..33b496d194f4 100644 --- a/tools/perf/tests/mmap-thread-lookup.c +++ b/tools/perf/tests/mmap-thread-lookup.c @@ -8,11 +8,13 @@ #include #include #include "debug.h" +#include "event.h" #include "tests.h" #include "machine.h" #include "thread_map.h" #include "map.h" #include "symbol.h" +#include "util/synthetic-events.h" #include "thread.h" #include "util.h" // page_size diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c index e3b965e7a233..3a02426db9a6 100644 --- a/tools/perf/tests/sample-parsing.c +++ b/tools/perf/tests/sample-parsing.c @@ -12,6 +12,7 @@ #include "event.h" #include "evsel.h" #include "debug.h" +#include "util/synthetic-events.h" #include "tests.h" diff --git a/tools/perf/tests/stat.c b/tools/perf/tests/stat.c index cc10b4116c9f..c1911501c39c 100644 --- a/tools/perf/tests/stat.c +++ b/tools/perf/tests/stat.c @@ -5,6 +5,7 @@ #include "stat.h" #include "counts.h" #include "debug.h" +#include "util/synthetic-events.h" static bool has_term(struct perf_record_stat_config *config, u64 tag, u64 val) diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c index 39168c57943b..28f51c4bd373 100644 --- a/tools/perf/tests/thread-map.c +++ b/tools/perf/tests/thread-map.c @@ -8,6 +8,7 @@ #include "thread_map.h" #include "debug.h" #include "event.h" +#include "util/synthetic-events.h" #include #include diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index 832ca6cfbe30..5365606e9dad 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c @@ -5,6 +5,7 @@ #include "../../util/callchain.h" #include "../../util/debug.h" +#include "../../util/event.h" #include "../../util/hist.h" #include "../../util/map.h" #include "../../util/map_groups.h" diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 1c0ff5acff83..0e8c89cf7cad 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -32,6 +32,7 @@ #include "pmu.h" #include "evsel.h" #include "symbol.h" +#include "util/synthetic-events.h" #include "thread_map.h" #include "asm/bug.h" #include "auxtrace.h" diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index 1ed902a24a39..b110aec1da4d 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -11,14 +11,13 @@ #include #include #include +#include // FILE #include #include #include #include #include -#include "event.h" - union perf_event; struct perf_session; struct evlist; @@ -27,6 +26,7 @@ struct perf_mmap; struct perf_sample; struct option; struct record_opts; +struct perf_record_auxtrace_error; struct perf_record_auxtrace_info; struct events_stats; @@ -525,10 +525,6 @@ void auxtrace_synth_error(struct perf_record_auxtrace_error *auxtrace_error, int int code, int cpu, pid_t pid, pid_t tid, u64 ip, const char *msg, u64 timestamp); -int perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr, - struct perf_tool *tool, - struct perf_session *session, - perf_event__handler_t process); int perf_event__process_auxtrace_info(struct perf_session *session, union perf_event *event); s64 perf_event__process_auxtrace(struct perf_session *session, @@ -605,15 +601,6 @@ void auxtrace_record__free(struct auxtrace_record *itr __maybe_unused) { } -static inline int -perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr __maybe_unused, - struct perf_tool *tool __maybe_unused, - struct perf_session *session __maybe_unused, - perf_event__handler_t process __maybe_unused) -{ - return -EINVAL; -} - static inline int auxtrace_record__options(struct auxtrace_record *itr __maybe_unused, struct evlist *evlist __maybe_unused, diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 7a3d4b125323..f7ed5d122e22 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -16,6 +16,7 @@ #include "map.h" #include "evlist.h" #include "record.h" +#include "util/synthetic-events.h" #define ptr_to_u64(ptr) ((__u64)(unsigned long)(ptr)) diff --git a/tools/perf/util/bpf-event.h b/tools/perf/util/bpf-event.h index a01c2fd68c03..81fdc88e6c1a 100644 --- a/tools/perf/util/bpf-event.h +++ b/tools/perf/util/bpf-event.h @@ -6,9 +6,9 @@ #include #include #include -#include "event.h" #include +struct bpf_prog_info; struct machine; union perf_event; struct perf_env; @@ -33,11 +33,6 @@ struct btf_node { #ifdef HAVE_LIBBPF_SUPPORT int machine__process_bpf(struct machine *machine, union perf_event *event, struct perf_sample *sample); - -int perf_event__synthesize_bpf_events(struct perf_session *session, - perf_event__handler_t process, - struct machine *machine, - struct record_opts *opts); int bpf_event__add_sb_event(struct evlist **evlist, struct perf_env *env); void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info, @@ -51,14 +46,6 @@ static inline int machine__process_bpf(struct machine *machine __maybe_unused, return 0; } -static inline int perf_event__synthesize_bpf_events(struct perf_session *session __maybe_unused, - perf_event__handler_t process __maybe_unused, - struct machine *machine __maybe_unused, - struct record_opts *opts __maybe_unused) -{ - return 0; -} - static inline int bpf_event__add_sb_event(struct evlist **evlist __maybe_unused, struct perf_env *env __maybe_unused) { diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index c14646c1f2eb..9a9b56ed3f0a 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -23,6 +23,7 @@ #include "debug.h" #include "dso.h" +#include "event.h" #include "hist.h" #include "sort.h" #include "machine.h" diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index d65ae7cf9316..043a08fc7398 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -32,6 +32,7 @@ #include "stat.h" #include "session.h" #include "bpf-event.h" +#include "synthetic-events.h" #include "tool.h" #include "../perf.h" diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 89a2404170a0..a0a0c91cde4a 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -279,95 +279,13 @@ enum { void perf_event__print_totals(void); -struct evlist; -struct evsel; -struct perf_session; -struct perf_tool; -struct perf_thread_map; struct perf_cpu_map; +struct perf_record_stat_config; struct perf_stat_config; -struct perf_counts_values; - -typedef int (*perf_event__handler_t)(struct perf_tool *tool, - union perf_event *event, - struct perf_sample *sample, - struct machine *machine); +struct perf_tool; -int perf_event__synthesize_stat_events(struct perf_stat_config *config, - struct perf_tool *tool, - struct evlist *evlist, - perf_event__handler_t process, - bool attrs); -int perf_event__synthesize_attr(struct perf_tool *tool, - struct perf_event_attr *attr, u32 ids, u64 *id, - perf_event__handler_t process); -int perf_event__synthesize_attrs(struct perf_tool *tool, - struct evlist *evlist, - perf_event__handler_t process); -int perf_event__synthesize_build_id(struct perf_tool *tool, - struct dso *pos, u16 misc, - perf_event__handler_t process, - struct machine *machine); -int perf_event__synthesize_extra_attr(struct perf_tool *tool, - struct evlist *evsel_list, - perf_event__handler_t process, - bool is_pipe); -int perf_event__synthesize_event_update_cpus(struct perf_tool *tool, - struct evsel *evsel, - perf_event__handler_t process); -int perf_event__synthesize_event_update_name(struct perf_tool *tool, - struct evsel *evsel, - perf_event__handler_t process); -int perf_event__synthesize_event_update_scale(struct perf_tool *tool, - struct evsel *evsel, - perf_event__handler_t process); -int perf_event__synthesize_event_update_unit(struct perf_tool *tool, - struct evsel *evsel, - perf_event__handler_t process); -int perf_event__synthesize_features(struct perf_tool *tool, - struct perf_session *session, - struct evlist *evlist, - perf_event__handler_t process); -int perf_event__synthesize_tracing_data(struct perf_tool *tool, - int fd, struct evlist *evlist, - perf_event__handler_t process); -int perf_event__synthesize_thread_map(struct perf_tool *tool, - struct perf_thread_map *threads, - perf_event__handler_t process, - struct machine *machine, bool mmap_data); -int perf_event__synthesize_thread_map2(struct perf_tool *tool, - struct perf_thread_map *threads, - perf_event__handler_t process, - struct machine *machine); -int perf_event__synthesize_cpu_map(struct perf_tool *tool, - struct perf_cpu_map *cpus, - perf_event__handler_t process, - struct machine *machine); -int perf_event__synthesize_threads(struct perf_tool *tool, - perf_event__handler_t process, - struct machine *machine, bool mmap_data, - unsigned int nr_threads_synthesize); -int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, - perf_event__handler_t process, - struct machine *machine); -int perf_event__synthesize_stat_config(struct perf_tool *tool, - struct perf_stat_config *config, - perf_event__handler_t process, - struct machine *machine); void perf_event__read_stat_config(struct perf_stat_config *config, struct perf_record_stat_config *event); -int perf_event__synthesize_stat(struct perf_tool *tool, - u32 cpu, u32 thread, u64 id, - struct perf_counts_values *count, - perf_event__handler_t process, - struct machine *machine); -int perf_event__synthesize_stat_round(struct perf_tool *tool, - u64 time, u64 type, - perf_event__handler_t process, - struct machine *machine); -int perf_event__synthesize_modules(struct perf_tool *tool, - perf_event__handler_t process, - struct machine *machine); int perf_event__process_comm(struct perf_tool *tool, union perf_event *event, @@ -421,10 +339,6 @@ int perf_event__process_bpf(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine); -int perf_tool__process_synth_event(struct perf_tool *tool, - union perf_event *event, - struct machine *machine, - perf_event__handler_t process); int perf_event__process(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, @@ -446,34 +360,6 @@ void thread__resolve(struct thread *thread, struct addr_location *al, const char *perf_event__name(unsigned int id); -size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, - u64 read_format); -int perf_event__synthesize_sample(union perf_event *event, u64 type, - u64 read_format, - const struct perf_sample *sample); - -pid_t perf_event__synthesize_comm(struct perf_tool *tool, - union perf_event *event, pid_t pid, - perf_event__handler_t process, - struct machine *machine); - -int perf_event__synthesize_namespaces(struct perf_tool *tool, - union perf_event *event, - pid_t pid, pid_t tgid, - perf_event__handler_t process, - struct machine *machine); - -int perf_event__synthesize_mmap_events(struct perf_tool *tool, - union perf_event *event, - pid_t pid, pid_t tgid, - perf_event__handler_t process, - struct machine *machine, - bool mmap_data); - -int perf_event__synthesize_extra_kmaps(struct perf_tool *tool, - perf_event__handler_t process, - struct machine *machine); - size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp); size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp); size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 5b40b840624c..5af025c80ec5 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -40,6 +40,7 @@ #include "trace-event.h" #include "stat.h" #include "string2.h" +#include "util/synthetic-events.h" #include "memswap.h" #include "util.h" #include "../perf-sys.h" diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index d85827de1b60..a4a8342eba98 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -45,6 +45,7 @@ #include "util.h" // page_size, perf_exe() #include "cputopo.h" #include "bpf-event.h" +#include "util/synthetic-events.h" #include #include diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index 15f87a09f4fe..3888d4cd3ed1 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c @@ -28,6 +28,7 @@ #include "auxtrace.h" #include "intel-pt-decoder/intel-pt-insn-decoder.h" #include "intel-bts.h" +#include "util/synthetic-events.h" #define MAX_TIMESTAMP (~0ULL) diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 9b56fb74bedf..bcdc0359f7cf 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -33,6 +33,7 @@ #include "tsc.h" #include "intel-pt.h" #include "config.h" +#include "util/synthetic-events.h" #include "time-utils.h" #include "../arch/x86/include/uapi/asm/perf_regs.h" diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index b4749d3eed08..132de5cfb9b9 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -20,6 +20,7 @@ #include "symbol.h" #include "sort.h" #include "strlist.h" +#include "util/synthetic-events.h" #include "target.h" #include "thread.h" #include "util.h" @@ -2624,6 +2625,15 @@ int __machine__synthesize_threads(struct machine *machine, struct perf_tool *too return 0; } +int machine__synthesize_threads(struct machine *machine, struct target *target, + struct perf_thread_map *threads, bool data_mmap, + unsigned int nr_threads_synthesize) +{ + return __machine__synthesize_threads(machine, NULL, target, threads, + perf_event__process, data_mmap, + nr_threads_synthesize); +} + pid_t machine__get_current_tid(struct machine *machine, int cpu) { int nr_cpus = min(machine->env->nr_cpus_online, MAX_NR_CPUS); diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index ffd391a925a6..18e13c0ccd6a 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -6,7 +6,6 @@ #include #include "map_groups.h" #include "dsos.h" -#include "event.h" #include "rwsem.h" struct addr_location; @@ -252,20 +251,6 @@ int machines__for_each_thread(struct machines *machines, int (*fn)(struct thread *thread, void *p), void *priv); -int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, - struct target *target, struct perf_thread_map *threads, - perf_event__handler_t process, bool data_mmap, - unsigned int nr_threads_synthesize); -static inline -int machine__synthesize_threads(struct machine *machine, struct target *target, - struct perf_thread_map *threads, bool data_mmap, - unsigned int nr_threads_synthesize) -{ - return __machine__synthesize_threads(machine, NULL, target, threads, - perf_event__process, data_mmap, - nr_threads_synthesize); -} - pid_t machine__get_current_tid(struct machine *machine, int cpu); int machine__set_current_tid(struct machine *machine, int cpu, pid_t pid, pid_t tid); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 2b583e6adb49..6267613b551d 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -29,6 +29,7 @@ #include "thread-stack.h" #include "sample-raw.h" #include "stat.h" +#include "util/synthetic-events.h" #include "util.h" #include "ui/progress.h" #include "../perf.h" diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index b7aa076ab6fd..b4c9428c18f0 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -138,9 +138,4 @@ int perf_session__deliver_synth_event(struct perf_session *session, int perf_event__process_id_index(struct perf_session *session, union perf_event *event); -int perf_event__synthesize_id_index(struct perf_tool *tool, - perf_event__handler_t process, - struct evlist *evlist, - struct machine *machine); - #endif /* __PERF_SESSION_H */ diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 2e318d95c528..46c8a5027e12 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -12,6 +12,7 @@ #include "target.h" #include "evlist.h" #include "evsel.h" +#include "util/synthetic-events.h" #include "thread_map.h" #include diff --git a/tools/perf/util/synthetic-events.h b/tools/perf/util/synthetic-events.h new file mode 100644 index 000000000000..baead0cdc381 --- /dev/null +++ b/tools/perf/util/synthetic-events.h @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PERF_SYNTHETIC_EVENTS_H +#define __PERF_SYNTHETIC_EVENTS_H + +#include +#include // pid_t +#include +#include + +struct auxtrace_record; +struct dso; +struct evlist; +struct evsel; +struct machine; +struct perf_counts_values; +struct perf_cpu_map; +struct perf_event_attr; +struct perf_event_mmap_page; +struct perf_sample; +struct perf_session; +struct perf_stat_config; +struct perf_thread_map; +struct perf_tool; +struct record_opts; +struct target; + +union perf_event; + +typedef int (*perf_event__handler_t)(struct perf_tool *tool, union perf_event *event, + struct perf_sample *sample, struct machine *machine); + +int perf_event__synthesize_attrs(struct perf_tool *tool, struct evlist *evlist, perf_event__handler_t process); +int perf_event__synthesize_attr(struct perf_tool *tool, struct perf_event_attr *attr, u32 ids, u64 *id, perf_event__handler_t process); +int perf_event__synthesize_build_id(struct perf_tool *tool, struct dso *pos, u16 misc, perf_event__handler_t process, struct machine *machine); +int perf_event__synthesize_cpu_map(struct perf_tool *tool, struct perf_cpu_map *cpus, perf_event__handler_t process, struct machine *machine); +int perf_event__synthesize_event_update_cpus(struct perf_tool *tool, struct evsel *evsel, perf_event__handler_t process); +int perf_event__synthesize_event_update_name(struct perf_tool *tool, struct evsel *evsel, perf_event__handler_t process); +int perf_event__synthesize_event_update_scale(struct perf_tool *tool, struct evsel *evsel, perf_event__handler_t process); +int perf_event__synthesize_event_update_unit(struct perf_tool *tool, struct evsel *evsel, perf_event__handler_t process); +int perf_event__synthesize_extra_attr(struct perf_tool *tool, struct evlist *evsel_list, perf_event__handler_t process, bool is_pipe); +int perf_event__synthesize_extra_kmaps(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine); +int perf_event__synthesize_features(struct perf_tool *tool, struct perf_session *session, struct evlist *evlist, perf_event__handler_t process); +int perf_event__synthesize_id_index(struct perf_tool *tool, perf_event__handler_t process, struct evlist *evlist, struct machine *machine); +int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine); +int perf_event__synthesize_mmap_events(struct perf_tool *tool, union perf_event *event, pid_t pid, pid_t tgid, perf_event__handler_t process, struct machine *machine, bool mmap_data); +int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine); +int perf_event__synthesize_namespaces(struct perf_tool *tool, union perf_event *event, pid_t pid, pid_t tgid, perf_event__handler_t process, struct machine *machine); +int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format, const struct perf_sample *sample); +int perf_event__synthesize_stat_config(struct perf_tool *tool, struct perf_stat_config *config, perf_event__handler_t process, struct machine *machine); +int perf_event__synthesize_stat_events(struct perf_stat_config *config, struct perf_tool *tool, struct evlist *evlist, perf_event__handler_t process, bool attrs); +int perf_event__synthesize_stat_round(struct perf_tool *tool, u64 time, u64 type, perf_event__handler_t process, struct machine *machine); +int perf_event__synthesize_stat(struct perf_tool *tool, u32 cpu, u32 thread, u64 id, struct perf_counts_values *count, perf_event__handler_t process, struct machine *machine); +int perf_event__synthesize_thread_map2(struct perf_tool *tool, struct perf_thread_map *threads, perf_event__handler_t process, struct machine *machine); +int perf_event__synthesize_thread_map(struct perf_tool *tool, struct perf_thread_map *threads, perf_event__handler_t process, struct machine *machine, bool mmap_data); +int perf_event__synthesize_threads(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine, bool mmap_data, unsigned int nr_threads_synthesize); +int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, struct evlist *evlist, perf_event__handler_t process); +int perf_event__synth_time_conv(const struct perf_event_mmap_page *pc, struct perf_tool *tool, perf_event__handler_t process, struct machine *machine); +pid_t perf_event__synthesize_comm(struct perf_tool *tool, union perf_event *event, pid_t pid, perf_event__handler_t process, struct machine *machine); + +int perf_tool__process_synth_event(struct perf_tool *tool, union perf_event *event, struct machine *machine, perf_event__handler_t process); + +size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, u64 read_format); + +int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, + struct target *target, struct perf_thread_map *threads, + perf_event__handler_t process, bool data_mmap, + unsigned int nr_threads_synthesize); +int machine__synthesize_threads(struct machine *machine, struct target *target, + struct perf_thread_map *threads, bool data_mmap, + unsigned int nr_threads_synthesize); + +#ifdef HAVE_AUXTRACE_SUPPORT +int perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr, struct perf_tool *tool, + struct perf_session *session, perf_event__handler_t process); + +#else // HAVE_AUXTRACE_SUPPORT + +#include + +static inline int +perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr __maybe_unused, + struct perf_tool *tool __maybe_unused, + struct perf_session *session __maybe_unused, + perf_event__handler_t process __maybe_unused) +{ + return -EINVAL; +} +#endif // HAVE_AUXTRACE_SUPPORT + +#ifdef HAVE_LIBBPF_SUPPORT +int perf_event__synthesize_bpf_events(struct perf_session *session, perf_event__handler_t process, + struct machine *machine, struct record_opts *opts); +#else // HAVE_LIBBPF_SUPPORT +static inline int perf_event__synthesize_bpf_events(struct perf_session *session __maybe_unused, + perf_event__handler_t process __maybe_unused, + struct machine *machine __maybe_unused, + struct record_opts *opts __maybe_unused) +{ + return 0; +} +#endif // HAVE_LIBBPF_SUPPORT + +#endif // __PERF_SYNTHETIC_EVENTS_H diff --git a/tools/perf/util/tsc.h b/tools/perf/util/tsc.h index e0c3af34ac8d..3c5a632ee57c 100644 --- a/tools/perf/util/tsc.h +++ b/tools/perf/util/tsc.h @@ -4,13 +4,12 @@ #include -#include "event.h" - struct perf_tsc_conversion { u16 time_shift; u32 time_mult; u64 time_zero; }; + struct perf_event_mmap_page; int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc, @@ -20,13 +19,4 @@ u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc); u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc); u64 rdtsc(void); -struct perf_event_mmap_page; -struct perf_tool; -struct machine; - -int perf_event__synth_time_conv(const struct perf_event_mmap_page *pc, - struct perf_tool *tool, - perf_event__handler_t process, - struct machine *machine); - -#endif +#endif // __PERF_TSC_H -- cgit v1.2.3-59-g8ed1b From 5cac8ea3e6e736664ee272f94d9099891e25f782 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 18 Sep 2019 12:28:41 -0300 Subject: perf memswap: Adopt 'struct u64_swap' from evsel.h As it is not used in evsel.h and is a memory swap struct, so fits better in memswap.h. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-wvzxu7a5l3m868ywwphrnnqo@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.h | 5 ----- tools/perf/util/memswap.h | 7 +++++++ 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 68321d10eb2d..74df298acb31 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -179,11 +179,6 @@ struct evsel { } side_band; }; -union u64_swap { - u64 val64; - u32 val32[2]; -}; - struct perf_missing_features { bool sample_id_all; bool exclude_guest; diff --git a/tools/perf/util/memswap.h b/tools/perf/util/memswap.h index 1e29ff903ca9..2c38e8c2d548 100644 --- a/tools/perf/util/memswap.h +++ b/tools/perf/util/memswap.h @@ -2,6 +2,13 @@ #ifndef PERF_MEMSWAP_H_ #define PERF_MEMSWAP_H_ +#include + +union u64_swap { + u64 val64; + u32 val32[2]; +}; + void mem_bswap_64(void *src, int byte_size); void mem_bswap_32(void *src, int byte_size); -- cgit v1.2.3-59-g8ed1b From 055c67ed39887c5563e9540470a4617c1b772aec Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 18 Sep 2019 16:08:52 -0300 Subject: perf tools: Move event synthesizing routines to separate .c file For better grouping, in time we may end up making most of these static, i.e. generalizing the 'perf record' synthesizing code so that based on the target it can do the right thing and call the needed synthesizers. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-s9zxxhk40s95pjng9panet16@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 9 - tools/perf/util/Build | 1 + tools/perf/util/cs-etm.c | 1 + tools/perf/util/event.c | 1108 +-------------------- tools/perf/util/evsel.c | 278 ------ tools/perf/util/header.c | 393 +------- tools/perf/util/header.h | 18 + tools/perf/util/machine.c | 25 - tools/perf/util/namespaces.c | 18 + tools/perf/util/namespaces.h | 2 + tools/perf/util/session.c | 71 -- tools/perf/util/stat.c | 43 - tools/perf/util/synthetic-events.c | 1884 ++++++++++++++++++++++++++++++++++++ 13 files changed, 1928 insertions(+), 1923 deletions(-) create mode 100644 tools/perf/util/synthetic-events.c (limited to 'tools') diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 907d4d4677a3..4bd11c918e73 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1181,15 +1181,6 @@ static void workload_exec_failed_signal(int signo __maybe_unused, static void snapshot_sig_handler(int sig); static void alarm_sig_handler(int sig); -int __weak -perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused, - struct perf_tool *tool __maybe_unused, - perf_event__handler_t process __maybe_unused, - struct machine *machine __maybe_unused) -{ - return 0; -} - static const struct perf_event_mmap_page * perf_evlist__pick_pc(struct evlist *evlist) { diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 0b4d8e0d474c..fd89d6a8cd65 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -86,6 +86,7 @@ perf-y += stat-display.o perf-y += record.o perf-y += srcline.o perf-y += srccode.o +perf-y += synthetic-events.o perf-y += data.o perf-y += tsc.o perf-y += cloexec.o diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index f87b9c1c9f9a..6021974577d5 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -35,6 +35,7 @@ #include "thread.h" #include "thread-stack.h" #include +#include "util/synthetic-events.h" #define MAX_TIMESTAMP (~0ULL) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 043a08fc7398..fc1e5a991008 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -9,7 +8,6 @@ #include #include #include /* To get things like MAP_HUGETLB even on older libc headers */ -#include #include #include #include "cpumap.h" @@ -26,18 +24,16 @@ #include "time-utils.h" #include #include "map.h" +#include "util/namespaces.h" #include "symbol.h" #include "symbol/kallsyms.h" #include "asm/bug.h" #include "stat.h" #include "session.h" #include "bpf-event.h" -#include "synthetic-events.h" #include "tool.h" #include "../perf.h" -#define DEFAULT_PROC_MAP_PARSE_TIMEOUT 500 - static const char *perf_event__names[] = { [0] = "TOTAL", [PERF_RECORD_MMAP] = "MMAP", @@ -78,18 +74,6 @@ static const char *perf_event__names[] = { [PERF_RECORD_COMPRESSED] = "COMPRESSED", }; -static const char *perf_ns__names[] = { - [NET_NS_INDEX] = "net", - [UTS_NS_INDEX] = "uts", - [IPC_NS_INDEX] = "ipc", - [PID_NS_INDEX] = "pid", - [USER_NS_INDEX] = "user", - [MNT_NS_INDEX] = "mnt", - [CGROUP_NS_INDEX] = "cgroup", -}; - -unsigned int proc_map_timeout = DEFAULT_PROC_MAP_PARSE_TIMEOUT; - const char *perf_event__name(unsigned int id) { if (id >= ARRAY_SIZE(perf_event__names)) @@ -99,775 +83,6 @@ const char *perf_event__name(unsigned int id) return perf_event__names[id]; } -static const char *perf_ns__name(unsigned int id) -{ - if (id >= ARRAY_SIZE(perf_ns__names)) - return "UNKNOWN"; - return perf_ns__names[id]; -} - -int perf_tool__process_synth_event(struct perf_tool *tool, - union perf_event *event, - struct machine *machine, - perf_event__handler_t process) -{ - struct perf_sample synth_sample = { - .pid = -1, - .tid = -1, - .time = -1, - .stream_id = -1, - .cpu = -1, - .period = 1, - .cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK, - }; - - return process(tool, event, &synth_sample, machine); -}; - -/* - * Assumes that the first 4095 bytes of /proc/pid/stat contains - * the comm, tgid and ppid. - */ -static int perf_event__get_comm_ids(pid_t pid, char *comm, size_t len, - pid_t *tgid, pid_t *ppid) -{ - char filename[PATH_MAX]; - char bf[4096]; - int fd; - size_t size = 0; - ssize_t n; - char *name, *tgids, *ppids; - - *tgid = -1; - *ppid = -1; - - snprintf(filename, sizeof(filename), "/proc/%d/status", pid); - - fd = open(filename, O_RDONLY); - if (fd < 0) { - pr_debug("couldn't open %s\n", filename); - return -1; - } - - n = read(fd, bf, sizeof(bf) - 1); - close(fd); - if (n <= 0) { - pr_warning("Couldn't get COMM, tigd and ppid for pid %d\n", - pid); - return -1; - } - bf[n] = '\0'; - - name = strstr(bf, "Name:"); - tgids = strstr(bf, "Tgid:"); - ppids = strstr(bf, "PPid:"); - - if (name) { - char *nl; - - name = skip_spaces(name + 5); /* strlen("Name:") */ - nl = strchr(name, '\n'); - if (nl) - *nl = '\0'; - - size = strlen(name); - if (size >= len) - size = len - 1; - memcpy(comm, name, size); - comm[size] = '\0'; - } else { - pr_debug("Name: string not found for pid %d\n", pid); - } - - if (tgids) { - tgids += 5; /* strlen("Tgid:") */ - *tgid = atoi(tgids); - } else { - pr_debug("Tgid: string not found for pid %d\n", pid); - } - - if (ppids) { - ppids += 5; /* strlen("PPid:") */ - *ppid = atoi(ppids); - } else { - pr_debug("PPid: string not found for pid %d\n", pid); - } - - return 0; -} - -static int perf_event__prepare_comm(union perf_event *event, pid_t pid, - struct machine *machine, - pid_t *tgid, pid_t *ppid) -{ - size_t size; - - *ppid = -1; - - memset(&event->comm, 0, sizeof(event->comm)); - - if (machine__is_host(machine)) { - if (perf_event__get_comm_ids(pid, event->comm.comm, - sizeof(event->comm.comm), - tgid, ppid) != 0) { - return -1; - } - } else { - *tgid = machine->pid; - } - - if (*tgid < 0) - return -1; - - event->comm.pid = *tgid; - event->comm.header.type = PERF_RECORD_COMM; - - size = strlen(event->comm.comm) + 1; - size = PERF_ALIGN(size, sizeof(u64)); - memset(event->comm.comm + size, 0, machine->id_hdr_size); - event->comm.header.size = (sizeof(event->comm) - - (sizeof(event->comm.comm) - size) + - machine->id_hdr_size); - event->comm.tid = pid; - - return 0; -} - -pid_t perf_event__synthesize_comm(struct perf_tool *tool, - union perf_event *event, pid_t pid, - perf_event__handler_t process, - struct machine *machine) -{ - pid_t tgid, ppid; - - if (perf_event__prepare_comm(event, pid, machine, &tgid, &ppid) != 0) - return -1; - - if (perf_tool__process_synth_event(tool, event, machine, process) != 0) - return -1; - - return tgid; -} - -static void perf_event__get_ns_link_info(pid_t pid, const char *ns, - struct perf_ns_link_info *ns_link_info) -{ - struct stat64 st; - char proc_ns[128]; - - sprintf(proc_ns, "/proc/%u/ns/%s", pid, ns); - if (stat64(proc_ns, &st) == 0) { - ns_link_info->dev = st.st_dev; - ns_link_info->ino = st.st_ino; - } -} - -int perf_event__synthesize_namespaces(struct perf_tool *tool, - union perf_event *event, - pid_t pid, pid_t tgid, - perf_event__handler_t process, - struct machine *machine) -{ - u32 idx; - struct perf_ns_link_info *ns_link_info; - - if (!tool || !tool->namespace_events) - return 0; - - memset(&event->namespaces, 0, (sizeof(event->namespaces) + - (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + - machine->id_hdr_size)); - - event->namespaces.pid = tgid; - event->namespaces.tid = pid; - - event->namespaces.nr_namespaces = NR_NAMESPACES; - - ns_link_info = event->namespaces.link_info; - - for (idx = 0; idx < event->namespaces.nr_namespaces; idx++) - perf_event__get_ns_link_info(pid, perf_ns__name(idx), - &ns_link_info[idx]); - - event->namespaces.header.type = PERF_RECORD_NAMESPACES; - - event->namespaces.header.size = (sizeof(event->namespaces) + - (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + - machine->id_hdr_size); - - if (perf_tool__process_synth_event(tool, event, machine, process) != 0) - return -1; - - return 0; -} - -static int perf_event__synthesize_fork(struct perf_tool *tool, - union perf_event *event, - pid_t pid, pid_t tgid, pid_t ppid, - perf_event__handler_t process, - struct machine *machine) -{ - memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size); - - /* - * for main thread set parent to ppid from status file. For other - * threads set parent pid to main thread. ie., assume main thread - * spawns all threads in a process - */ - if (tgid == pid) { - event->fork.ppid = ppid; - event->fork.ptid = ppid; - } else { - event->fork.ppid = tgid; - event->fork.ptid = tgid; - } - event->fork.pid = tgid; - event->fork.tid = pid; - event->fork.header.type = PERF_RECORD_FORK; - event->fork.header.misc = PERF_RECORD_MISC_FORK_EXEC; - - event->fork.header.size = (sizeof(event->fork) + machine->id_hdr_size); - - if (perf_tool__process_synth_event(tool, event, machine, process) != 0) - return -1; - - return 0; -} - -int perf_event__synthesize_mmap_events(struct perf_tool *tool, - union perf_event *event, - pid_t pid, pid_t tgid, - perf_event__handler_t process, - struct machine *machine, - bool mmap_data) -{ - char filename[PATH_MAX]; - FILE *fp; - unsigned long long t; - bool truncation = false; - unsigned long long timeout = proc_map_timeout * 1000000ULL; - int rc = 0; - const char *hugetlbfs_mnt = hugetlbfs__mountpoint(); - int hugetlbfs_mnt_len = hugetlbfs_mnt ? strlen(hugetlbfs_mnt) : 0; - - if (machine__is_default_guest(machine)) - return 0; - - snprintf(filename, sizeof(filename), "%s/proc/%d/task/%d/maps", - machine->root_dir, pid, pid); - - fp = fopen(filename, "r"); - if (fp == NULL) { - /* - * We raced with a task exiting - just return: - */ - pr_debug("couldn't open %s\n", filename); - return -1; - } - - event->header.type = PERF_RECORD_MMAP2; - t = rdclock(); - - while (1) { - char bf[BUFSIZ]; - char prot[5]; - char execname[PATH_MAX]; - char anonstr[] = "//anon"; - unsigned int ino; - size_t size; - ssize_t n; - - if (fgets(bf, sizeof(bf), fp) == NULL) - break; - - if ((rdclock() - t) > timeout) { - pr_warning("Reading %s time out. " - "You may want to increase " - "the time limit by --proc-map-timeout\n", - filename); - truncation = true; - goto out; - } - - /* ensure null termination since stack will be reused. */ - strcpy(execname, ""); - - /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */ - n = sscanf(bf, "%"PRI_lx64"-%"PRI_lx64" %s %"PRI_lx64" %x:%x %u %[^\n]\n", - &event->mmap2.start, &event->mmap2.len, prot, - &event->mmap2.pgoff, &event->mmap2.maj, - &event->mmap2.min, - &ino, execname); - - /* - * Anon maps don't have the execname. - */ - if (n < 7) - continue; - - event->mmap2.ino = (u64)ino; - - /* - * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c - */ - if (machine__is_host(machine)) - event->header.misc = PERF_RECORD_MISC_USER; - else - event->header.misc = PERF_RECORD_MISC_GUEST_USER; - - /* map protection and flags bits */ - event->mmap2.prot = 0; - event->mmap2.flags = 0; - if (prot[0] == 'r') - event->mmap2.prot |= PROT_READ; - if (prot[1] == 'w') - event->mmap2.prot |= PROT_WRITE; - if (prot[2] == 'x') - event->mmap2.prot |= PROT_EXEC; - - if (prot[3] == 's') - event->mmap2.flags |= MAP_SHARED; - else - event->mmap2.flags |= MAP_PRIVATE; - - if (prot[2] != 'x') { - if (!mmap_data || prot[0] != 'r') - continue; - - event->header.misc |= PERF_RECORD_MISC_MMAP_DATA; - } - -out: - if (truncation) - event->header.misc |= PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT; - - if (!strcmp(execname, "")) - strcpy(execname, anonstr); - - if (hugetlbfs_mnt_len && - !strncmp(execname, hugetlbfs_mnt, hugetlbfs_mnt_len)) { - strcpy(execname, anonstr); - event->mmap2.flags |= MAP_HUGETLB; - } - - size = strlen(execname) + 1; - memcpy(event->mmap2.filename, execname, size); - size = PERF_ALIGN(size, sizeof(u64)); - event->mmap2.len -= event->mmap.start; - event->mmap2.header.size = (sizeof(event->mmap2) - - (sizeof(event->mmap2.filename) - size)); - memset(event->mmap2.filename + size, 0, machine->id_hdr_size); - event->mmap2.header.size += machine->id_hdr_size; - event->mmap2.pid = tgid; - event->mmap2.tid = pid; - - if (perf_tool__process_synth_event(tool, event, machine, process) != 0) { - rc = -1; - break; - } - - if (truncation) - break; - } - - fclose(fp); - return rc; -} - -int perf_event__synthesize_modules(struct perf_tool *tool, - perf_event__handler_t process, - struct machine *machine) -{ - int rc = 0; - struct map *pos; - struct maps *maps = machine__kernel_maps(machine); - union perf_event *event = zalloc((sizeof(event->mmap) + - machine->id_hdr_size)); - if (event == NULL) { - pr_debug("Not enough memory synthesizing mmap event " - "for kernel modules\n"); - return -1; - } - - event->header.type = PERF_RECORD_MMAP; - - /* - * kernel uses 0 for user space maps, see kernel/perf_event.c - * __perf_event_mmap - */ - if (machine__is_host(machine)) - event->header.misc = PERF_RECORD_MISC_KERNEL; - else - event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; - - for (pos = maps__first(maps); pos; pos = map__next(pos)) { - size_t size; - - if (!__map__is_kmodule(pos)) - continue; - - size = PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64)); - event->mmap.header.type = PERF_RECORD_MMAP; - event->mmap.header.size = (sizeof(event->mmap) - - (sizeof(event->mmap.filename) - size)); - memset(event->mmap.filename + size, 0, machine->id_hdr_size); - event->mmap.header.size += machine->id_hdr_size; - event->mmap.start = pos->start; - event->mmap.len = pos->end - pos->start; - event->mmap.pid = machine->pid; - - memcpy(event->mmap.filename, pos->dso->long_name, - pos->dso->long_name_len + 1); - if (perf_tool__process_synth_event(tool, event, machine, process) != 0) { - rc = -1; - break; - } - } - - free(event); - return rc; -} - -static int __event__synthesize_thread(union perf_event *comm_event, - union perf_event *mmap_event, - union perf_event *fork_event, - union perf_event *namespaces_event, - pid_t pid, int full, - perf_event__handler_t process, - struct perf_tool *tool, - struct machine *machine, - bool mmap_data) -{ - char filename[PATH_MAX]; - DIR *tasks; - struct dirent *dirent; - pid_t tgid, ppid; - int rc = 0; - - /* special case: only send one comm event using passed in pid */ - if (!full) { - tgid = perf_event__synthesize_comm(tool, comm_event, pid, - process, machine); - - if (tgid == -1) - return -1; - - if (perf_event__synthesize_namespaces(tool, namespaces_event, pid, - tgid, process, machine) < 0) - return -1; - - /* - * send mmap only for thread group leader - * see thread__init_map_groups - */ - if (pid == tgid && - perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, - process, machine, mmap_data)) - return -1; - - return 0; - } - - if (machine__is_default_guest(machine)) - return 0; - - snprintf(filename, sizeof(filename), "%s/proc/%d/task", - machine->root_dir, pid); - - tasks = opendir(filename); - if (tasks == NULL) { - pr_debug("couldn't open %s\n", filename); - return 0; - } - - while ((dirent = readdir(tasks)) != NULL) { - char *end; - pid_t _pid; - - _pid = strtol(dirent->d_name, &end, 10); - if (*end) - continue; - - rc = -1; - if (perf_event__prepare_comm(comm_event, _pid, machine, - &tgid, &ppid) != 0) - break; - - if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid, - ppid, process, machine) < 0) - break; - - if (perf_event__synthesize_namespaces(tool, namespaces_event, _pid, - tgid, process, machine) < 0) - break; - - /* - * Send the prepared comm event - */ - if (perf_tool__process_synth_event(tool, comm_event, machine, process) != 0) - break; - - rc = 0; - if (_pid == pid) { - /* process the parent's maps too */ - rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, - process, machine, mmap_data); - if (rc) - break; - } - } - - closedir(tasks); - return rc; -} - -int perf_event__synthesize_thread_map(struct perf_tool *tool, - struct perf_thread_map *threads, - perf_event__handler_t process, - struct machine *machine, - bool mmap_data) -{ - union perf_event *comm_event, *mmap_event, *fork_event; - union perf_event *namespaces_event; - int err = -1, thread, j; - - comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size); - if (comm_event == NULL) - goto out; - - mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size); - if (mmap_event == NULL) - goto out_free_comm; - - fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size); - if (fork_event == NULL) - goto out_free_mmap; - - namespaces_event = malloc(sizeof(namespaces_event->namespaces) + - (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + - machine->id_hdr_size); - if (namespaces_event == NULL) - goto out_free_fork; - - err = 0; - for (thread = 0; thread < threads->nr; ++thread) { - if (__event__synthesize_thread(comm_event, mmap_event, - fork_event, namespaces_event, - perf_thread_map__pid(threads, thread), 0, - process, tool, machine, - mmap_data)) { - err = -1; - break; - } - - /* - * comm.pid is set to thread group id by - * perf_event__synthesize_comm - */ - if ((int) comm_event->comm.pid != perf_thread_map__pid(threads, thread)) { - bool need_leader = true; - - /* is thread group leader in thread_map? */ - for (j = 0; j < threads->nr; ++j) { - if ((int) comm_event->comm.pid == perf_thread_map__pid(threads, j)) { - need_leader = false; - break; - } - } - - /* if not, generate events for it */ - if (need_leader && - __event__synthesize_thread(comm_event, mmap_event, - fork_event, namespaces_event, - comm_event->comm.pid, 0, - process, tool, machine, - mmap_data)) { - err = -1; - break; - } - } - } - free(namespaces_event); -out_free_fork: - free(fork_event); -out_free_mmap: - free(mmap_event); -out_free_comm: - free(comm_event); -out: - return err; -} - -static int __perf_event__synthesize_threads(struct perf_tool *tool, - perf_event__handler_t process, - struct machine *machine, - bool mmap_data, - struct dirent **dirent, - int start, - int num) -{ - union perf_event *comm_event, *mmap_event, *fork_event; - union perf_event *namespaces_event; - int err = -1; - char *end; - pid_t pid; - int i; - - comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size); - if (comm_event == NULL) - goto out; - - mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size); - if (mmap_event == NULL) - goto out_free_comm; - - fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size); - if (fork_event == NULL) - goto out_free_mmap; - - namespaces_event = malloc(sizeof(namespaces_event->namespaces) + - (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + - machine->id_hdr_size); - if (namespaces_event == NULL) - goto out_free_fork; - - for (i = start; i < start + num; i++) { - if (!isdigit(dirent[i]->d_name[0])) - continue; - - pid = (pid_t)strtol(dirent[i]->d_name, &end, 10); - /* only interested in proper numerical dirents */ - if (*end) - continue; - /* - * We may race with exiting thread, so don't stop just because - * one thread couldn't be synthesized. - */ - __event__synthesize_thread(comm_event, mmap_event, fork_event, - namespaces_event, pid, 1, process, - tool, machine, mmap_data); - } - err = 0; - - free(namespaces_event); -out_free_fork: - free(fork_event); -out_free_mmap: - free(mmap_event); -out_free_comm: - free(comm_event); -out: - return err; -} - -struct synthesize_threads_arg { - struct perf_tool *tool; - perf_event__handler_t process; - struct machine *machine; - bool mmap_data; - struct dirent **dirent; - int num; - int start; -}; - -static void *synthesize_threads_worker(void *arg) -{ - struct synthesize_threads_arg *args = arg; - - __perf_event__synthesize_threads(args->tool, args->process, - args->machine, args->mmap_data, - args->dirent, - args->start, args->num); - return NULL; -} - -int perf_event__synthesize_threads(struct perf_tool *tool, - perf_event__handler_t process, - struct machine *machine, - bool mmap_data, - unsigned int nr_threads_synthesize) -{ - struct synthesize_threads_arg *args = NULL; - pthread_t *synthesize_threads = NULL; - char proc_path[PATH_MAX]; - struct dirent **dirent; - int num_per_thread; - int m, n, i, j; - int thread_nr; - int base = 0; - int err = -1; - - - if (machine__is_default_guest(machine)) - return 0; - - snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir); - n = scandir(proc_path, &dirent, 0, alphasort); - if (n < 0) - return err; - - if (nr_threads_synthesize == UINT_MAX) - thread_nr = sysconf(_SC_NPROCESSORS_ONLN); - else - thread_nr = nr_threads_synthesize; - - if (thread_nr <= 1) { - err = __perf_event__synthesize_threads(tool, process, - machine, mmap_data, - dirent, base, n); - goto free_dirent; - } - if (thread_nr > n) - thread_nr = n; - - synthesize_threads = calloc(sizeof(pthread_t), thread_nr); - if (synthesize_threads == NULL) - goto free_dirent; - - args = calloc(sizeof(*args), thread_nr); - if (args == NULL) - goto free_threads; - - num_per_thread = n / thread_nr; - m = n % thread_nr; - for (i = 0; i < thread_nr; i++) { - args[i].tool = tool; - args[i].process = process; - args[i].machine = machine; - args[i].mmap_data = mmap_data; - args[i].dirent = dirent; - } - for (i = 0; i < m; i++) { - args[i].num = num_per_thread + 1; - args[i].start = i * args[i].num; - } - if (i != 0) - base = args[i-1].start + args[i-1].num; - for (j = i; j < thread_nr; j++) { - args[j].num = num_per_thread; - args[j].start = base + (j - i) * args[i].num; - } - - for (i = 0; i < thread_nr; i++) { - if (pthread_create(&synthesize_threads[i], NULL, - synthesize_threads_worker, &args[i])) - goto out_join; - } - err = 0; -out_join: - for (i = 0; i < thread_nr; i++) - pthread_join(synthesize_threads[i], NULL); - free(args); -free_threads: - free(synthesize_threads); -free_dirent: - for (i = 0; i < n; i++) - zfree(&dirent[i]); - free(dirent); - - return err; -} - struct process_symbol_args { const char *name; u64 start; @@ -902,327 +117,6 @@ int kallsyms__get_function_start(const char *kallsyms_filename, return 0; } -int __weak perf_event__synthesize_extra_kmaps(struct perf_tool *tool __maybe_unused, - perf_event__handler_t process __maybe_unused, - struct machine *machine __maybe_unused) -{ - return 0; -} - -static int __perf_event__synthesize_kernel_mmap(struct perf_tool *tool, - perf_event__handler_t process, - struct machine *machine) -{ - size_t size; - struct map *map = machine__kernel_map(machine); - struct kmap *kmap; - int err; - union perf_event *event; - - if (map == NULL) - return -1; - - kmap = map__kmap(map); - if (!kmap->ref_reloc_sym) - return -1; - - /* - * We should get this from /sys/kernel/sections/.text, but till that is - * available use this, and after it is use this as a fallback for older - * kernels. - */ - event = zalloc((sizeof(event->mmap) + machine->id_hdr_size)); - if (event == NULL) { - pr_debug("Not enough memory synthesizing mmap event " - "for kernel modules\n"); - return -1; - } - - if (machine__is_host(machine)) { - /* - * kernel uses PERF_RECORD_MISC_USER for user space maps, - * see kernel/perf_event.c __perf_event_mmap - */ - event->header.misc = PERF_RECORD_MISC_KERNEL; - } else { - event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; - } - - size = snprintf(event->mmap.filename, sizeof(event->mmap.filename), - "%s%s", machine->mmap_name, kmap->ref_reloc_sym->name) + 1; - size = PERF_ALIGN(size, sizeof(u64)); - event->mmap.header.type = PERF_RECORD_MMAP; - event->mmap.header.size = (sizeof(event->mmap) - - (sizeof(event->mmap.filename) - size) + machine->id_hdr_size); - event->mmap.pgoff = kmap->ref_reloc_sym->addr; - event->mmap.start = map->start; - event->mmap.len = map->end - event->mmap.start; - event->mmap.pid = machine->pid; - - err = perf_tool__process_synth_event(tool, event, machine, process); - free(event); - - return err; -} - -int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, - perf_event__handler_t process, - struct machine *machine) -{ - int err; - - err = __perf_event__synthesize_kernel_mmap(tool, process, machine); - if (err < 0) - return err; - - return perf_event__synthesize_extra_kmaps(tool, process, machine); -} - -int perf_event__synthesize_thread_map2(struct perf_tool *tool, - struct perf_thread_map *threads, - perf_event__handler_t process, - struct machine *machine) -{ - union perf_event *event; - int i, err, size; - - size = sizeof(event->thread_map); - size += threads->nr * sizeof(event->thread_map.entries[0]); - - event = zalloc(size); - if (!event) - return -ENOMEM; - - event->header.type = PERF_RECORD_THREAD_MAP; - event->header.size = size; - event->thread_map.nr = threads->nr; - - for (i = 0; i < threads->nr; i++) { - struct perf_record_thread_map_entry *entry = &event->thread_map.entries[i]; - char *comm = perf_thread_map__comm(threads, i); - - if (!comm) - comm = (char *) ""; - - entry->pid = perf_thread_map__pid(threads, i); - strncpy((char *) &entry->comm, comm, sizeof(entry->comm)); - } - - err = process(tool, event, NULL, machine); - - free(event); - return err; -} - -static void synthesize_cpus(struct cpu_map_entries *cpus, - struct perf_cpu_map *map) -{ - int i; - - cpus->nr = map->nr; - - for (i = 0; i < map->nr; i++) - cpus->cpu[i] = map->map[i]; -} - -static void synthesize_mask(struct perf_record_record_cpu_map *mask, - struct perf_cpu_map *map, int max) -{ - int i; - - mask->nr = BITS_TO_LONGS(max); - mask->long_size = sizeof(long); - - for (i = 0; i < map->nr; i++) - set_bit(map->map[i], mask->mask); -} - -static size_t cpus_size(struct perf_cpu_map *map) -{ - return sizeof(struct cpu_map_entries) + map->nr * sizeof(u16); -} - -static size_t mask_size(struct perf_cpu_map *map, int *max) -{ - int i; - - *max = 0; - - for (i = 0; i < map->nr; i++) { - /* bit possition of the cpu is + 1 */ - int bit = map->map[i] + 1; - - if (bit > *max) - *max = bit; - } - - return sizeof(struct perf_record_record_cpu_map) + BITS_TO_LONGS(*max) * sizeof(long); -} - -void *cpu_map_data__alloc(struct perf_cpu_map *map, size_t *size, u16 *type, int *max) -{ - size_t size_cpus, size_mask; - bool is_dummy = perf_cpu_map__empty(map); - - /* - * Both array and mask data have variable size based - * on the number of cpus and their actual values. - * The size of the 'struct perf_record_cpu_map_data' is: - * - * array = size of 'struct cpu_map_entries' + - * number of cpus * sizeof(u64) - * - * mask = size of 'struct perf_record_record_cpu_map' + - * maximum cpu bit converted to size of longs - * - * and finaly + the size of 'struct perf_record_cpu_map_data'. - */ - size_cpus = cpus_size(map); - size_mask = mask_size(map, max); - - if (is_dummy || (size_cpus < size_mask)) { - *size += size_cpus; - *type = PERF_CPU_MAP__CPUS; - } else { - *size += size_mask; - *type = PERF_CPU_MAP__MASK; - } - - *size += sizeof(struct perf_record_cpu_map_data); - *size = PERF_ALIGN(*size, sizeof(u64)); - return zalloc(*size); -} - -void cpu_map_data__synthesize(struct perf_record_cpu_map_data *data, struct perf_cpu_map *map, - u16 type, int max) -{ - data->type = type; - - switch (type) { - case PERF_CPU_MAP__CPUS: - synthesize_cpus((struct cpu_map_entries *) data->data, map); - break; - case PERF_CPU_MAP__MASK: - synthesize_mask((struct perf_record_record_cpu_map *)data->data, map, max); - default: - break; - }; -} - -static struct perf_record_cpu_map *cpu_map_event__new(struct perf_cpu_map *map) -{ - size_t size = sizeof(struct perf_record_cpu_map); - struct perf_record_cpu_map *event; - int max; - u16 type; - - event = cpu_map_data__alloc(map, &size, &type, &max); - if (!event) - return NULL; - - event->header.type = PERF_RECORD_CPU_MAP; - event->header.size = size; - event->data.type = type; - - cpu_map_data__synthesize(&event->data, map, type, max); - return event; -} - -int perf_event__synthesize_cpu_map(struct perf_tool *tool, - struct perf_cpu_map *map, - perf_event__handler_t process, - struct machine *machine) -{ - struct perf_record_cpu_map *event; - int err; - - event = cpu_map_event__new(map); - if (!event) - return -ENOMEM; - - err = process(tool, (union perf_event *) event, NULL, machine); - - free(event); - return err; -} - -int perf_event__synthesize_stat_config(struct perf_tool *tool, - struct perf_stat_config *config, - perf_event__handler_t process, - struct machine *machine) -{ - struct perf_record_stat_config *event; - int size, i = 0, err; - - size = sizeof(*event); - size += (PERF_STAT_CONFIG_TERM__MAX * sizeof(event->data[0])); - - event = zalloc(size); - if (!event) - return -ENOMEM; - - event->header.type = PERF_RECORD_STAT_CONFIG; - event->header.size = size; - event->nr = PERF_STAT_CONFIG_TERM__MAX; - -#define ADD(__term, __val) \ - event->data[i].tag = PERF_STAT_CONFIG_TERM__##__term; \ - event->data[i].val = __val; \ - i++; - - ADD(AGGR_MODE, config->aggr_mode) - ADD(INTERVAL, config->interval) - ADD(SCALE, config->scale) - - WARN_ONCE(i != PERF_STAT_CONFIG_TERM__MAX, - "stat config terms unbalanced\n"); -#undef ADD - - err = process(tool, (union perf_event *) event, NULL, machine); - - free(event); - return err; -} - -int perf_event__synthesize_stat(struct perf_tool *tool, - u32 cpu, u32 thread, u64 id, - struct perf_counts_values *count, - perf_event__handler_t process, - struct machine *machine) -{ - struct perf_record_stat event; - - event.header.type = PERF_RECORD_STAT; - event.header.size = sizeof(event); - event.header.misc = 0; - - event.id = id; - event.cpu = cpu; - event.thread = thread; - event.val = count->val; - event.ena = count->ena; - event.run = count->run; - - return process(tool, (union perf_event *) &event, NULL, machine); -} - -int perf_event__synthesize_stat_round(struct perf_tool *tool, - u64 evtime, u64 type, - perf_event__handler_t process, - struct machine *machine) -{ - struct perf_record_stat_round event; - - event.header.type = PERF_RECORD_STAT_ROUND; - event.header.size = sizeof(event); - event.header.misc = 0; - - event.time = evtime; - event.type = type; - - return process(tool, (union perf_event *) &event, NULL, machine); -} - void perf_event__read_stat_config(struct perf_stat_config *config, struct perf_record_stat_config *event) { diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 5af025c80ec5..8e335d168503 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -40,7 +40,6 @@ #include "trace-event.h" #include "stat.h" #include "string2.h" -#include "util/synthetic-events.h" #include "memswap.h" #include "util.h" #include "../perf-sys.h" @@ -2421,283 +2420,6 @@ int perf_evsel__parse_sample_timestamp(struct evsel *evsel, return 0; } -size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, - u64 read_format) -{ - size_t sz, result = sizeof(struct perf_record_sample); - - if (type & PERF_SAMPLE_IDENTIFIER) - result += sizeof(u64); - - if (type & PERF_SAMPLE_IP) - result += sizeof(u64); - - if (type & PERF_SAMPLE_TID) - result += sizeof(u64); - - if (type & PERF_SAMPLE_TIME) - result += sizeof(u64); - - if (type & PERF_SAMPLE_ADDR) - result += sizeof(u64); - - if (type & PERF_SAMPLE_ID) - result += sizeof(u64); - - if (type & PERF_SAMPLE_STREAM_ID) - result += sizeof(u64); - - if (type & PERF_SAMPLE_CPU) - result += sizeof(u64); - - if (type & PERF_SAMPLE_PERIOD) - result += sizeof(u64); - - if (type & PERF_SAMPLE_READ) { - result += sizeof(u64); - if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) - result += sizeof(u64); - if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) - result += sizeof(u64); - /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */ - if (read_format & PERF_FORMAT_GROUP) { - sz = sample->read.group.nr * - sizeof(struct sample_read_value); - result += sz; - } else { - result += sizeof(u64); - } - } - - if (type & PERF_SAMPLE_CALLCHAIN) { - sz = (sample->callchain->nr + 1) * sizeof(u64); - result += sz; - } - - if (type & PERF_SAMPLE_RAW) { - result += sizeof(u32); - result += sample->raw_size; - } - - if (type & PERF_SAMPLE_BRANCH_STACK) { - sz = sample->branch_stack->nr * sizeof(struct branch_entry); - sz += sizeof(u64); - result += sz; - } - - if (type & PERF_SAMPLE_REGS_USER) { - if (sample->user_regs.abi) { - result += sizeof(u64); - sz = hweight64(sample->user_regs.mask) * sizeof(u64); - result += sz; - } else { - result += sizeof(u64); - } - } - - if (type & PERF_SAMPLE_STACK_USER) { - sz = sample->user_stack.size; - result += sizeof(u64); - if (sz) { - result += sz; - result += sizeof(u64); - } - } - - if (type & PERF_SAMPLE_WEIGHT) - result += sizeof(u64); - - if (type & PERF_SAMPLE_DATA_SRC) - result += sizeof(u64); - - if (type & PERF_SAMPLE_TRANSACTION) - result += sizeof(u64); - - if (type & PERF_SAMPLE_REGS_INTR) { - if (sample->intr_regs.abi) { - result += sizeof(u64); - sz = hweight64(sample->intr_regs.mask) * sizeof(u64); - result += sz; - } else { - result += sizeof(u64); - } - } - - if (type & PERF_SAMPLE_PHYS_ADDR) - result += sizeof(u64); - - return result; -} - -int perf_event__synthesize_sample(union perf_event *event, u64 type, - u64 read_format, - const struct perf_sample *sample) -{ - __u64 *array; - size_t sz; - /* - * used for cross-endian analysis. See git commit 65014ab3 - * for why this goofiness is needed. - */ - union u64_swap u; - - array = event->sample.array; - - if (type & PERF_SAMPLE_IDENTIFIER) { - *array = sample->id; - array++; - } - - if (type & PERF_SAMPLE_IP) { - *array = sample->ip; - array++; - } - - if (type & PERF_SAMPLE_TID) { - u.val32[0] = sample->pid; - u.val32[1] = sample->tid; - *array = u.val64; - array++; - } - - if (type & PERF_SAMPLE_TIME) { - *array = sample->time; - array++; - } - - if (type & PERF_SAMPLE_ADDR) { - *array = sample->addr; - array++; - } - - if (type & PERF_SAMPLE_ID) { - *array = sample->id; - array++; - } - - if (type & PERF_SAMPLE_STREAM_ID) { - *array = sample->stream_id; - array++; - } - - if (type & PERF_SAMPLE_CPU) { - u.val32[0] = sample->cpu; - u.val32[1] = 0; - *array = u.val64; - array++; - } - - if (type & PERF_SAMPLE_PERIOD) { - *array = sample->period; - array++; - } - - if (type & PERF_SAMPLE_READ) { - if (read_format & PERF_FORMAT_GROUP) - *array = sample->read.group.nr; - else - *array = sample->read.one.value; - array++; - - if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) { - *array = sample->read.time_enabled; - array++; - } - - if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) { - *array = sample->read.time_running; - array++; - } - - /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */ - if (read_format & PERF_FORMAT_GROUP) { - sz = sample->read.group.nr * - sizeof(struct sample_read_value); - memcpy(array, sample->read.group.values, sz); - array = (void *)array + sz; - } else { - *array = sample->read.one.id; - array++; - } - } - - if (type & PERF_SAMPLE_CALLCHAIN) { - sz = (sample->callchain->nr + 1) * sizeof(u64); - memcpy(array, sample->callchain, sz); - array = (void *)array + sz; - } - - if (type & PERF_SAMPLE_RAW) { - u.val32[0] = sample->raw_size; - *array = u.val64; - array = (void *)array + sizeof(u32); - - memcpy(array, sample->raw_data, sample->raw_size); - array = (void *)array + sample->raw_size; - } - - if (type & PERF_SAMPLE_BRANCH_STACK) { - sz = sample->branch_stack->nr * sizeof(struct branch_entry); - sz += sizeof(u64); - memcpy(array, sample->branch_stack, sz); - array = (void *)array + sz; - } - - if (type & PERF_SAMPLE_REGS_USER) { - if (sample->user_regs.abi) { - *array++ = sample->user_regs.abi; - sz = hweight64(sample->user_regs.mask) * sizeof(u64); - memcpy(array, sample->user_regs.regs, sz); - array = (void *)array + sz; - } else { - *array++ = 0; - } - } - - if (type & PERF_SAMPLE_STACK_USER) { - sz = sample->user_stack.size; - *array++ = sz; - if (sz) { - memcpy(array, sample->user_stack.data, sz); - array = (void *)array + sz; - *array++ = sz; - } - } - - if (type & PERF_SAMPLE_WEIGHT) { - *array = sample->weight; - array++; - } - - if (type & PERF_SAMPLE_DATA_SRC) { - *array = sample->data_src; - array++; - } - - if (type & PERF_SAMPLE_TRANSACTION) { - *array = sample->transaction; - array++; - } - - if (type & PERF_SAMPLE_REGS_INTR) { - if (sample->intr_regs.abi) { - *array++ = sample->intr_regs.abi; - sz = hweight64(sample->intr_regs.mask) * sizeof(u64); - memcpy(array, sample->intr_regs.regs, sz); - array = (void *)array + sz; - } else { - *array++ = 0; - } - } - - if (type & PERF_SAMPLE_PHYS_ADDR) { - *array = sample->phys_addr; - array++; - } - - return 0; -} - struct tep_format_field *perf_evsel__field(struct evsel *evsel, const char *name) { return tep_find_field(evsel->tp_format, name); diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index a4a8342eba98..5722ff717777 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -45,7 +45,6 @@ #include "util.h" // page_size, perf_exe() #include "cputopo.h" #include "bpf-event.h" -#include "util/synthetic-events.h" #include #include @@ -72,15 +71,6 @@ struct perf_file_attr { struct perf_file_section ids; }; -struct feat_fd { - struct perf_header *ph; - int fd; - void *buf; /* Either buf != NULL or fd >= 0 */ - ssize_t offset; - size_t size; - struct evsel *events; -}; - void perf_header__set_feat(struct perf_header *header, int feat) { set_bit(feat, header->adds_features); @@ -2825,15 +2815,6 @@ static int process_compressed(struct feat_fd *ff, return 0; } -struct feature_ops { - int (*write)(struct feat_fd *ff, struct evlist *evlist); - void (*print)(struct feat_fd *ff, FILE *fp); - int (*process)(struct feat_fd *ff, void *data); - const char *name; - bool full_only; - bool synthesize; -}; - #define FEAT_OPR(n, func, __full_only) \ [HEADER_##n] = { \ .name = __stringify(n), \ @@ -2860,8 +2841,10 @@ struct feature_ops { #define process_branch_stack NULL #define process_stat NULL +// Only used in util/synthetic-events.c +const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE]; -static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = { +const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE] = { FEAT_OPN(TRACING_DATA, tracing_data, false), FEAT_OPN(BUILD_ID, build_id, false), FEAT_OPR(HOSTNAME, hostname, false), @@ -3658,105 +3641,6 @@ out_delete_evlist: return -ENOMEM; } -int perf_event__synthesize_attr(struct perf_tool *tool, - struct perf_event_attr *attr, u32 ids, u64 *id, - perf_event__handler_t process) -{ - union perf_event *ev; - size_t size; - int err; - - size = sizeof(struct perf_event_attr); - size = PERF_ALIGN(size, sizeof(u64)); - size += sizeof(struct perf_event_header); - size += ids * sizeof(u64); - - ev = zalloc(size); - - if (ev == NULL) - return -ENOMEM; - - ev->attr.attr = *attr; - memcpy(ev->attr.id, id, ids * sizeof(u64)); - - ev->attr.header.type = PERF_RECORD_HEADER_ATTR; - ev->attr.header.size = (u16)size; - - if (ev->attr.header.size == size) - err = process(tool, ev, NULL, NULL); - else - err = -E2BIG; - - free(ev); - - return err; -} - -int perf_event__synthesize_features(struct perf_tool *tool, - struct perf_session *session, - struct evlist *evlist, - perf_event__handler_t process) -{ - struct perf_header *header = &session->header; - struct feat_fd ff; - struct perf_record_header_feature *fe; - size_t sz, sz_hdr; - int feat, ret; - - sz_hdr = sizeof(fe->header); - sz = sizeof(union perf_event); - /* get a nice alignment */ - sz = PERF_ALIGN(sz, page_size); - - memset(&ff, 0, sizeof(ff)); - - ff.buf = malloc(sz); - if (!ff.buf) - return -ENOMEM; - - ff.size = sz - sz_hdr; - ff.ph = &session->header; - - for_each_set_bit(feat, header->adds_features, HEADER_FEAT_BITS) { - if (!feat_ops[feat].synthesize) { - pr_debug("No record header feature for header :%d\n", feat); - continue; - } - - ff.offset = sizeof(*fe); - - ret = feat_ops[feat].write(&ff, evlist); - if (ret || ff.offset <= (ssize_t)sizeof(*fe)) { - pr_debug("Error writing feature\n"); - continue; - } - /* ff.buf may have changed due to realloc in do_write() */ - fe = ff.buf; - memset(fe, 0, sizeof(*fe)); - - fe->feat_id = feat; - fe->header.type = PERF_RECORD_HEADER_FEATURE; - fe->header.size = ff.offset; - - ret = process(tool, ff.buf, NULL, NULL); - if (ret) { - free(ff.buf); - return ret; - } - } - - /* Send HEADER_LAST_FEATURE mark. */ - fe = ff.buf; - fe->feat_id = HEADER_LAST_FEATURE; - fe->header.type = PERF_RECORD_HEADER_FEATURE; - fe->header.size = sizeof(*fe); - - ret = process(tool, ff.buf, NULL, NULL); - - free(ff.buf); - return ret; -} - int perf_event__process_feature(struct perf_session *session, union perf_event *event) { @@ -3799,113 +3683,6 @@ int perf_event__process_feature(struct perf_session *session, return 0; } -static struct perf_record_event_update * -event_update_event__new(size_t size, u64 type, u64 id) -{ - struct perf_record_event_update *ev; - - size += sizeof(*ev); - size = PERF_ALIGN(size, sizeof(u64)); - - ev = zalloc(size); - if (ev) { - ev->header.type = PERF_RECORD_EVENT_UPDATE; - ev->header.size = (u16)size; - ev->type = type; - ev->id = id; - } - return ev; -} - -int -perf_event__synthesize_event_update_unit(struct perf_tool *tool, - struct evsel *evsel, - perf_event__handler_t process) -{ - struct perf_record_event_update *ev; - size_t size = strlen(evsel->unit); - int err; - - ev = event_update_event__new(size + 1, PERF_EVENT_UPDATE__UNIT, evsel->id[0]); - if (ev == NULL) - return -ENOMEM; - - strlcpy(ev->data, evsel->unit, size + 1); - err = process(tool, (union perf_event *)ev, NULL, NULL); - free(ev); - return err; -} - -int -perf_event__synthesize_event_update_scale(struct perf_tool *tool, - struct evsel *evsel, - perf_event__handler_t process) -{ - struct perf_record_event_update *ev; - struct perf_record_event_update_scale *ev_data; - int err; - - ev = event_update_event__new(sizeof(*ev_data), PERF_EVENT_UPDATE__SCALE, evsel->id[0]); - if (ev == NULL) - return -ENOMEM; - - ev_data = (struct perf_record_event_update_scale *)ev->data; - ev_data->scale = evsel->scale; - err = process(tool, (union perf_event*) ev, NULL, NULL); - free(ev); - return err; -} - -int -perf_event__synthesize_event_update_name(struct perf_tool *tool, - struct evsel *evsel, - perf_event__handler_t process) -{ - struct perf_record_event_update *ev; - size_t len = strlen(evsel->name); - int err; - - ev = event_update_event__new(len + 1, PERF_EVENT_UPDATE__NAME, evsel->id[0]); - if (ev == NULL) - return -ENOMEM; - - strlcpy(ev->data, evsel->name, len + 1); - err = process(tool, (union perf_event*) ev, NULL, NULL); - free(ev); - return err; -} - -int -perf_event__synthesize_event_update_cpus(struct perf_tool *tool, - struct evsel *evsel, - perf_event__handler_t process) -{ - size_t size = sizeof(struct perf_record_event_update); - struct perf_record_event_update *ev; - int max, err; - u16 type; - - if (!evsel->core.own_cpus) - return 0; - - ev = cpu_map_data__alloc(evsel->core.own_cpus, &size, &type, &max); - if (!ev) - return -ENOMEM; - - ev->header.type = PERF_RECORD_EVENT_UPDATE; - ev->header.size = (u16)size; - ev->type = PERF_EVENT_UPDATE__CPUS; - ev->id = evsel->id[0]; - - cpu_map_data__synthesize((struct perf_record_cpu_map_data *)ev->data, - evsel->core.own_cpus, - type, max); - - err = process(tool, (union perf_event*) ev, NULL, NULL); - free(ev); - return err; -} - size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp) { struct perf_record_event_update *ev = &event->event_update; @@ -3945,93 +3722,6 @@ size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp) return ret; } -int perf_event__synthesize_attrs(struct perf_tool *tool, - struct evlist *evlist, - perf_event__handler_t process) -{ - struct evsel *evsel; - int err = 0; - - evlist__for_each_entry(evlist, evsel) { - err = perf_event__synthesize_attr(tool, &evsel->core.attr, evsel->ids, - evsel->id, process); - if (err) { - pr_debug("failed to create perf header attribute\n"); - return err; - } - } - - return err; -} - -static bool has_unit(struct evsel *counter) -{ - return counter->unit && *counter->unit; -} - -static bool has_scale(struct evsel *counter) -{ - return counter->scale != 1; -} - -int perf_event__synthesize_extra_attr(struct perf_tool *tool, - struct evlist *evsel_list, - perf_event__handler_t process, - bool is_pipe) -{ - struct evsel *counter; - int err; - - /* - * Synthesize other events stuff not carried within - * attr event - unit, scale, name - */ - evlist__for_each_entry(evsel_list, counter) { - if (!counter->supported) - continue; - - /* - * Synthesize unit and scale only if it's defined. - */ - if (has_unit(counter)) { - err = perf_event__synthesize_event_update_unit(tool, counter, process); - if (err < 0) { - pr_err("Couldn't synthesize evsel unit.\n"); - return err; - } - } - - if (has_scale(counter)) { - err = perf_event__synthesize_event_update_scale(tool, counter, process); - if (err < 0) { - pr_err("Couldn't synthesize evsel counter.\n"); - return err; - } - } - - if (counter->core.own_cpus) { - err = perf_event__synthesize_event_update_cpus(tool, counter, process); - if (err < 0) { - pr_err("Couldn't synthesize evsel cpus.\n"); - return err; - } - } - - /* - * Name is needed only for pipe output, - * perf.data carries event names. - */ - if (is_pipe) { - err = perf_event__synthesize_event_update_name(tool, counter, process); - if (err < 0) { - pr_err("Couldn't synthesize evsel name.\n"); - return err; - } - } - } - return 0; -} - int perf_event__process_attr(struct perf_tool *tool __maybe_unused, union perf_event *event, struct evlist **pevlist) @@ -4116,55 +3806,6 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused, return 0; } -int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, - struct evlist *evlist, - perf_event__handler_t process) -{ - union perf_event ev; - struct tracing_data *tdata; - ssize_t size = 0, aligned_size = 0, padding; - struct feat_fd ff; - int err __maybe_unused = 0; - - /* - * We are going to store the size of the data followed - * by the data contents. Since the fd descriptor is a pipe, - * we cannot seek back to store the size of the data once - * we know it. Instead we: - * - * - write the tracing data to the temp file - * - get/write the data size to pipe - * - write the tracing data from the temp file - * to the pipe - */ - tdata = tracing_data_get(&evlist->core.entries, fd, true); - if (!tdata) - return -1; - - memset(&ev, 0, sizeof(ev)); - - ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA; - size = tdata->size; - aligned_size = PERF_ALIGN(size, sizeof(u64)); - padding = aligned_size - size; - ev.tracing_data.header.size = sizeof(ev.tracing_data); - ev.tracing_data.size = aligned_size; - - process(tool, &ev, NULL, NULL); - - /* - * The put function will copy all the tracing data - * stored in temp file to the pipe. - */ - tracing_data_put(tdata); - - ff = (struct feat_fd){ .fd = fd }; - if (write_padded(&ff, NULL, 0, padding)) - return -1; - - return aligned_size; -} - int perf_event__process_tracing_data(struct perf_session *session, union perf_event *event) { @@ -4204,34 +3845,6 @@ int perf_event__process_tracing_data(struct perf_session *session, return size_read + padding; } -int perf_event__synthesize_build_id(struct perf_tool *tool, - struct dso *pos, u16 misc, - perf_event__handler_t process, - struct machine *machine) -{ - union perf_event ev; - size_t len; - int err = 0; - - if (!pos->hit) - return err; - - memset(&ev, 0, sizeof(ev)); - - len = pos->long_name_len + 1; - len = PERF_ALIGN(len, NAME_ALIGN); - memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id)); - ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID; - ev.build_id.header.misc = misc; - ev.build_id.pid = machine->pid; - ev.build_id.header.size = sizeof(ev.build_id) + len; - memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len); - - err = process(tool, &ev, NULL, machine); - - return err; -} - int perf_event__process_build_id(struct perf_session *session, union perf_event *event) { diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 999dac41871e..ca53a929e9fd 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -92,6 +92,24 @@ struct perf_header { struct perf_env env; }; +struct feat_fd { + struct perf_header *ph; + int fd; + void *buf; /* Either buf != NULL or fd >= 0 */ + ssize_t offset; + size_t size; + struct evsel *events; +}; + +struct perf_header_feature_ops { + int (*write)(struct feat_fd *ff, struct evlist *evlist); + void (*print)(struct feat_fd *ff, FILE *fp); + int (*process)(struct feat_fd *ff, void *data); + const char *name; + bool full_only; + bool synthesize; +}; + struct evlist; struct perf_session; struct perf_tool; diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 132de5cfb9b9..0535338f2d7a 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -20,7 +20,6 @@ #include "symbol.h" #include "sort.h" #include "strlist.h" -#include "util/synthetic-events.h" #include "target.h" #include "thread.h" #include "util.h" @@ -2610,30 +2609,6 @@ int machines__for_each_thread(struct machines *machines, return rc; } -int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, - struct target *target, struct perf_thread_map *threads, - perf_event__handler_t process, bool data_mmap, - unsigned int nr_threads_synthesize) -{ - if (target__has_task(target)) - return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap); - else if (target__has_cpu(target)) - return perf_event__synthesize_threads(tool, process, - machine, data_mmap, - nr_threads_synthesize); - /* command specified */ - return 0; -} - -int machine__synthesize_threads(struct machine *machine, struct target *target, - struct perf_thread_map *threads, bool data_mmap, - unsigned int nr_threads_synthesize) -{ - return __machine__synthesize_threads(machine, NULL, target, threads, - perf_event__process, data_mmap, - nr_threads_synthesize); -} - pid_t machine__get_current_tid(struct machine *machine, int cpu) { int nr_cpus = min(machine->env->nr_cpus_online, MAX_NR_CPUS); diff --git a/tools/perf/util/namespaces.c b/tools/perf/util/namespaces.c index 99be15dd2b6b..285d6f30d912 100644 --- a/tools/perf/util/namespaces.c +++ b/tools/perf/util/namespaces.c @@ -17,8 +17,26 @@ #include #include #include +#include #include +static const char *perf_ns__names[] = { + [NET_NS_INDEX] = "net", + [UTS_NS_INDEX] = "uts", + [IPC_NS_INDEX] = "ipc", + [PID_NS_INDEX] = "pid", + [USER_NS_INDEX] = "user", + [MNT_NS_INDEX] = "mnt", + [CGROUP_NS_INDEX] = "cgroup", +}; + +const char *perf_ns__name(unsigned int id) +{ + if (id >= ARRAY_SIZE(perf_ns__names)) + return "UNKNOWN"; + return perf_ns__names[id]; +} + struct namespaces *namespaces__new(struct perf_record_namespaces *event) { struct namespaces *namespaces; diff --git a/tools/perf/util/namespaces.h b/tools/perf/util/namespaces.h index 40edef56cb52..4b33f684eddd 100644 --- a/tools/perf/util/namespaces.h +++ b/tools/perf/util/namespaces.h @@ -66,4 +66,6 @@ static inline void __nsinfo__zput(struct nsinfo **nsip) #define nsinfo__zput(nsi) __nsinfo__zput(&nsi) +const char *perf_ns__name(unsigned int id); + #endif /* __PERF_NAMESPACES_H */ diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 6267613b551d..58b5bc34ba12 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -29,7 +29,6 @@ #include "thread-stack.h" #include "sample-raw.h" #include "stat.h" -#include "util/synthetic-events.h" #include "util.h" #include "ui/progress.h" #include "../perf.h" @@ -2413,73 +2412,3 @@ int perf_event__process_id_index(struct perf_session *session, } return 0; } - -int perf_event__synthesize_id_index(struct perf_tool *tool, - perf_event__handler_t process, - struct evlist *evlist, - struct machine *machine) -{ - union perf_event *ev; - struct evsel *evsel; - size_t nr = 0, i = 0, sz, max_nr, n; - int err; - - pr_debug2("Synthesizing id index\n"); - - max_nr = (UINT16_MAX - sizeof(struct perf_record_id_index)) / - sizeof(struct id_index_entry); - - evlist__for_each_entry(evlist, evsel) - nr += evsel->ids; - - n = nr > max_nr ? max_nr : nr; - sz = sizeof(struct perf_record_id_index) + n * sizeof(struct id_index_entry); - ev = zalloc(sz); - if (!ev) - return -ENOMEM; - - ev->id_index.header.type = PERF_RECORD_ID_INDEX; - ev->id_index.header.size = sz; - ev->id_index.nr = n; - - evlist__for_each_entry(evlist, evsel) { - u32 j; - - for (j = 0; j < evsel->ids; j++) { - struct id_index_entry *e; - struct perf_sample_id *sid; - - if (i >= n) { - err = process(tool, ev, NULL, machine); - if (err) - goto out_err; - nr -= n; - i = 0; - } - - e = &ev->id_index.entries[i++]; - - e->id = evsel->id[j]; - - sid = perf_evlist__id2sid(evlist, e->id); - if (!sid) { - free(ev); - return -ENOENT; - } - - e->idx = sid->idx; - e->cpu = sid->cpu; - e->tid = sid->tid; - } - } - - sz = sizeof(struct perf_record_id_index) + nr * sizeof(struct id_index_entry); - ev->id_index.header.size = sz; - ev->id_index.nr = nr; - - err = process(tool, ev, NULL, machine); -out_err: - free(ev); - - return err; -} diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 46c8a5027e12..06571209cb0b 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -12,7 +12,6 @@ #include "target.h" #include "evlist.h" #include "evsel.h" -#include "util/synthetic-events.h" #include "thread_map.h" #include @@ -495,45 +494,3 @@ int create_perf_stat_counter(struct evsel *evsel, return perf_evsel__open_per_thread(evsel, evsel->core.threads); } - -int perf_event__synthesize_stat_events(struct perf_stat_config *config, - struct perf_tool *tool, - struct evlist *evlist, - perf_event__handler_t process, - bool attrs) -{ - int err; - - if (attrs) { - err = perf_event__synthesize_attrs(tool, evlist, process); - if (err < 0) { - pr_err("Couldn't synthesize attrs.\n"); - return err; - } - } - - err = perf_event__synthesize_extra_attr(tool, evlist, process, - attrs); - - err = perf_event__synthesize_thread_map2(tool, evlist->core.threads, - process, NULL); - if (err < 0) { - pr_err("Couldn't synthesize thread map.\n"); - return err; - } - - err = perf_event__synthesize_cpu_map(tool, evlist->core.cpus, - process, NULL); - if (err < 0) { - pr_err("Couldn't synthesize thread map.\n"); - return err; - } - - err = perf_event__synthesize_stat_config(tool, config, process, NULL); - if (err < 0) { - pr_err("Couldn't synthesize config.\n"); - return err; - } - - return 0; -} diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c new file mode 100644 index 000000000000..8322028a9a97 --- /dev/null +++ b/tools/perf/util/synthetic-events.c @@ -0,0 +1,1884 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include "util/debug.h" +#include "util/dso.h" +#include "util/event.h" +#include "util/evlist.h" +#include "util/machine.h" +#include "util/map.h" +#include "util/map_symbol.h" +#include "util/branch.h" +#include "util/memswap.h" +#include "util/namespaces.h" +#include "util/session.h" +#include "util/stat.h" +#include "util/symbol.h" +#include "util/synthetic-events.h" +#include "util/target.h" +#include "util/time-utils.h" +#include "util/util.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* To get things like MAP_HUGETLB even on older libc headers */ +#include +#include +#include +#include +#include + +#define DEFAULT_PROC_MAP_PARSE_TIMEOUT 500 + +unsigned int proc_map_timeout = DEFAULT_PROC_MAP_PARSE_TIMEOUT; + +int perf_tool__process_synth_event(struct perf_tool *tool, + union perf_event *event, + struct machine *machine, + perf_event__handler_t process) +{ + struct perf_sample synth_sample = { + .pid = -1, + .tid = -1, + .time = -1, + .stream_id = -1, + .cpu = -1, + .period = 1, + .cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK, + }; + + return process(tool, event, &synth_sample, machine); +}; + +/* + * Assumes that the first 4095 bytes of /proc/pid/stat contains + * the comm, tgid and ppid. + */ +static int perf_event__get_comm_ids(pid_t pid, char *comm, size_t len, + pid_t *tgid, pid_t *ppid) +{ + char filename[PATH_MAX]; + char bf[4096]; + int fd; + size_t size = 0; + ssize_t n; + char *name, *tgids, *ppids; + + *tgid = -1; + *ppid = -1; + + snprintf(filename, sizeof(filename), "/proc/%d/status", pid); + + fd = open(filename, O_RDONLY); + if (fd < 0) { + pr_debug("couldn't open %s\n", filename); + return -1; + } + + n = read(fd, bf, sizeof(bf) - 1); + close(fd); + if (n <= 0) { + pr_warning("Couldn't get COMM, tigd and ppid for pid %d\n", + pid); + return -1; + } + bf[n] = '\0'; + + name = strstr(bf, "Name:"); + tgids = strstr(bf, "Tgid:"); + ppids = strstr(bf, "PPid:"); + + if (name) { + char *nl; + + name = skip_spaces(name + 5); /* strlen("Name:") */ + nl = strchr(name, '\n'); + if (nl) + *nl = '\0'; + + size = strlen(name); + if (size >= len) + size = len - 1; + memcpy(comm, name, size); + comm[size] = '\0'; + } else { + pr_debug("Name: string not found for pid %d\n", pid); + } + + if (tgids) { + tgids += 5; /* strlen("Tgid:") */ + *tgid = atoi(tgids); + } else { + pr_debug("Tgid: string not found for pid %d\n", pid); + } + + if (ppids) { + ppids += 5; /* strlen("PPid:") */ + *ppid = atoi(ppids); + } else { + pr_debug("PPid: string not found for pid %d\n", pid); + } + + return 0; +} + +static int perf_event__prepare_comm(union perf_event *event, pid_t pid, + struct machine *machine, + pid_t *tgid, pid_t *ppid) +{ + size_t size; + + *ppid = -1; + + memset(&event->comm, 0, sizeof(event->comm)); + + if (machine__is_host(machine)) { + if (perf_event__get_comm_ids(pid, event->comm.comm, + sizeof(event->comm.comm), + tgid, ppid) != 0) { + return -1; + } + } else { + *tgid = machine->pid; + } + + if (*tgid < 0) + return -1; + + event->comm.pid = *tgid; + event->comm.header.type = PERF_RECORD_COMM; + + size = strlen(event->comm.comm) + 1; + size = PERF_ALIGN(size, sizeof(u64)); + memset(event->comm.comm + size, 0, machine->id_hdr_size); + event->comm.header.size = (sizeof(event->comm) - + (sizeof(event->comm.comm) - size) + + machine->id_hdr_size); + event->comm.tid = pid; + + return 0; +} + +pid_t perf_event__synthesize_comm(struct perf_tool *tool, + union perf_event *event, pid_t pid, + perf_event__handler_t process, + struct machine *machine) +{ + pid_t tgid, ppid; + + if (perf_event__prepare_comm(event, pid, machine, &tgid, &ppid) != 0) + return -1; + + if (perf_tool__process_synth_event(tool, event, machine, process) != 0) + return -1; + + return tgid; +} + +static void perf_event__get_ns_link_info(pid_t pid, const char *ns, + struct perf_ns_link_info *ns_link_info) +{ + struct stat64 st; + char proc_ns[128]; + + sprintf(proc_ns, "/proc/%u/ns/%s", pid, ns); + if (stat64(proc_ns, &st) == 0) { + ns_link_info->dev = st.st_dev; + ns_link_info->ino = st.st_ino; + } +} + +int perf_event__synthesize_namespaces(struct perf_tool *tool, + union perf_event *event, + pid_t pid, pid_t tgid, + perf_event__handler_t process, + struct machine *machine) +{ + u32 idx; + struct perf_ns_link_info *ns_link_info; + + if (!tool || !tool->namespace_events) + return 0; + + memset(&event->namespaces, 0, (sizeof(event->namespaces) + + (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + + machine->id_hdr_size)); + + event->namespaces.pid = tgid; + event->namespaces.tid = pid; + + event->namespaces.nr_namespaces = NR_NAMESPACES; + + ns_link_info = event->namespaces.link_info; + + for (idx = 0; idx < event->namespaces.nr_namespaces; idx++) + perf_event__get_ns_link_info(pid, perf_ns__name(idx), + &ns_link_info[idx]); + + event->namespaces.header.type = PERF_RECORD_NAMESPACES; + + event->namespaces.header.size = (sizeof(event->namespaces) + + (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + + machine->id_hdr_size); + + if (perf_tool__process_synth_event(tool, event, machine, process) != 0) + return -1; + + return 0; +} + +static int perf_event__synthesize_fork(struct perf_tool *tool, + union perf_event *event, + pid_t pid, pid_t tgid, pid_t ppid, + perf_event__handler_t process, + struct machine *machine) +{ + memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size); + + /* + * for main thread set parent to ppid from status file. For other + * threads set parent pid to main thread. ie., assume main thread + * spawns all threads in a process + */ + if (tgid == pid) { + event->fork.ppid = ppid; + event->fork.ptid = ppid; + } else { + event->fork.ppid = tgid; + event->fork.ptid = tgid; + } + event->fork.pid = tgid; + event->fork.tid = pid; + event->fork.header.type = PERF_RECORD_FORK; + event->fork.header.misc = PERF_RECORD_MISC_FORK_EXEC; + + event->fork.header.size = (sizeof(event->fork) + machine->id_hdr_size); + + if (perf_tool__process_synth_event(tool, event, machine, process) != 0) + return -1; + + return 0; +} + +int perf_event__synthesize_mmap_events(struct perf_tool *tool, + union perf_event *event, + pid_t pid, pid_t tgid, + perf_event__handler_t process, + struct machine *machine, + bool mmap_data) +{ + char filename[PATH_MAX]; + FILE *fp; + unsigned long long t; + bool truncation = false; + unsigned long long timeout = proc_map_timeout * 1000000ULL; + int rc = 0; + const char *hugetlbfs_mnt = hugetlbfs__mountpoint(); + int hugetlbfs_mnt_len = hugetlbfs_mnt ? strlen(hugetlbfs_mnt) : 0; + + if (machine__is_default_guest(machine)) + return 0; + + snprintf(filename, sizeof(filename), "%s/proc/%d/task/%d/maps", + machine->root_dir, pid, pid); + + fp = fopen(filename, "r"); + if (fp == NULL) { + /* + * We raced with a task exiting - just return: + */ + pr_debug("couldn't open %s\n", filename); + return -1; + } + + event->header.type = PERF_RECORD_MMAP2; + t = rdclock(); + + while (1) { + char bf[BUFSIZ]; + char prot[5]; + char execname[PATH_MAX]; + char anonstr[] = "//anon"; + unsigned int ino; + size_t size; + ssize_t n; + + if (fgets(bf, sizeof(bf), fp) == NULL) + break; + + if ((rdclock() - t) > timeout) { + pr_warning("Reading %s time out. " + "You may want to increase " + "the time limit by --proc-map-timeout\n", + filename); + truncation = true; + goto out; + } + + /* ensure null termination since stack will be reused. */ + strcpy(execname, ""); + + /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */ + n = sscanf(bf, "%"PRI_lx64"-%"PRI_lx64" %s %"PRI_lx64" %x:%x %u %[^\n]\n", + &event->mmap2.start, &event->mmap2.len, prot, + &event->mmap2.pgoff, &event->mmap2.maj, + &event->mmap2.min, + &ino, execname); + + /* + * Anon maps don't have the execname. + */ + if (n < 7) + continue; + + event->mmap2.ino = (u64)ino; + + /* + * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c + */ + if (machine__is_host(machine)) + event->header.misc = PERF_RECORD_MISC_USER; + else + event->header.misc = PERF_RECORD_MISC_GUEST_USER; + + /* map protection and flags bits */ + event->mmap2.prot = 0; + event->mmap2.flags = 0; + if (prot[0] == 'r') + event->mmap2.prot |= PROT_READ; + if (prot[1] == 'w') + event->mmap2.prot |= PROT_WRITE; + if (prot[2] == 'x') + event->mmap2.prot |= PROT_EXEC; + + if (prot[3] == 's') + event->mmap2.flags |= MAP_SHARED; + else + event->mmap2.flags |= MAP_PRIVATE; + + if (prot[2] != 'x') { + if (!mmap_data || prot[0] != 'r') + continue; + + event->header.misc |= PERF_RECORD_MISC_MMAP_DATA; + } + +out: + if (truncation) + event->header.misc |= PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT; + + if (!strcmp(execname, "")) + strcpy(execname, anonstr); + + if (hugetlbfs_mnt_len && + !strncmp(execname, hugetlbfs_mnt, hugetlbfs_mnt_len)) { + strcpy(execname, anonstr); + event->mmap2.flags |= MAP_HUGETLB; + } + + size = strlen(execname) + 1; + memcpy(event->mmap2.filename, execname, size); + size = PERF_ALIGN(size, sizeof(u64)); + event->mmap2.len -= event->mmap.start; + event->mmap2.header.size = (sizeof(event->mmap2) - + (sizeof(event->mmap2.filename) - size)); + memset(event->mmap2.filename + size, 0, machine->id_hdr_size); + event->mmap2.header.size += machine->id_hdr_size; + event->mmap2.pid = tgid; + event->mmap2.tid = pid; + + if (perf_tool__process_synth_event(tool, event, machine, process) != 0) { + rc = -1; + break; + } + + if (truncation) + break; + } + + fclose(fp); + return rc; +} + +int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t process, + struct machine *machine) +{ + int rc = 0; + struct map *pos; + struct maps *maps = machine__kernel_maps(machine); + union perf_event *event = zalloc((sizeof(event->mmap) + + machine->id_hdr_size)); + if (event == NULL) { + pr_debug("Not enough memory synthesizing mmap event " + "for kernel modules\n"); + return -1; + } + + event->header.type = PERF_RECORD_MMAP; + + /* + * kernel uses 0 for user space maps, see kernel/perf_event.c + * __perf_event_mmap + */ + if (machine__is_host(machine)) + event->header.misc = PERF_RECORD_MISC_KERNEL; + else + event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; + + for (pos = maps__first(maps); pos; pos = map__next(pos)) { + size_t size; + + if (!__map__is_kmodule(pos)) + continue; + + size = PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64)); + event->mmap.header.type = PERF_RECORD_MMAP; + event->mmap.header.size = (sizeof(event->mmap) - + (sizeof(event->mmap.filename) - size)); + memset(event->mmap.filename + size, 0, machine->id_hdr_size); + event->mmap.header.size += machine->id_hdr_size; + event->mmap.start = pos->start; + event->mmap.len = pos->end - pos->start; + event->mmap.pid = machine->pid; + + memcpy(event->mmap.filename, pos->dso->long_name, + pos->dso->long_name_len + 1); + if (perf_tool__process_synth_event(tool, event, machine, process) != 0) { + rc = -1; + break; + } + } + + free(event); + return rc; +} + +static int __event__synthesize_thread(union perf_event *comm_event, + union perf_event *mmap_event, + union perf_event *fork_event, + union perf_event *namespaces_event, + pid_t pid, int full, perf_event__handler_t process, + struct perf_tool *tool, struct machine *machine, bool mmap_data) +{ + char filename[PATH_MAX]; + DIR *tasks; + struct dirent *dirent; + pid_t tgid, ppid; + int rc = 0; + + /* special case: only send one comm event using passed in pid */ + if (!full) { + tgid = perf_event__synthesize_comm(tool, comm_event, pid, + process, machine); + + if (tgid == -1) + return -1; + + if (perf_event__synthesize_namespaces(tool, namespaces_event, pid, + tgid, process, machine) < 0) + return -1; + + /* + * send mmap only for thread group leader + * see thread__init_map_groups + */ + if (pid == tgid && + perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, + process, machine, mmap_data)) + return -1; + + return 0; + } + + if (machine__is_default_guest(machine)) + return 0; + + snprintf(filename, sizeof(filename), "%s/proc/%d/task", + machine->root_dir, pid); + + tasks = opendir(filename); + if (tasks == NULL) { + pr_debug("couldn't open %s\n", filename); + return 0; + } + + while ((dirent = readdir(tasks)) != NULL) { + char *end; + pid_t _pid; + + _pid = strtol(dirent->d_name, &end, 10); + if (*end) + continue; + + rc = -1; + if (perf_event__prepare_comm(comm_event, _pid, machine, + &tgid, &ppid) != 0) + break; + + if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid, + ppid, process, machine) < 0) + break; + + if (perf_event__synthesize_namespaces(tool, namespaces_event, _pid, + tgid, process, machine) < 0) + break; + + /* + * Send the prepared comm event + */ + if (perf_tool__process_synth_event(tool, comm_event, machine, process) != 0) + break; + + rc = 0; + if (_pid == pid) { + /* process the parent's maps too */ + rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, + process, machine, mmap_data); + if (rc) + break; + } + } + + closedir(tasks); + return rc; +} + +int perf_event__synthesize_thread_map(struct perf_tool *tool, + struct perf_thread_map *threads, + perf_event__handler_t process, + struct machine *machine, + bool mmap_data) +{ + union perf_event *comm_event, *mmap_event, *fork_event; + union perf_event *namespaces_event; + int err = -1, thread, j; + + comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size); + if (comm_event == NULL) + goto out; + + mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size); + if (mmap_event == NULL) + goto out_free_comm; + + fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size); + if (fork_event == NULL) + goto out_free_mmap; + + namespaces_event = malloc(sizeof(namespaces_event->namespaces) + + (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + + machine->id_hdr_size); + if (namespaces_event == NULL) + goto out_free_fork; + + err = 0; + for (thread = 0; thread < threads->nr; ++thread) { + if (__event__synthesize_thread(comm_event, mmap_event, + fork_event, namespaces_event, + perf_thread_map__pid(threads, thread), 0, + process, tool, machine, + mmap_data)) { + err = -1; + break; + } + + /* + * comm.pid is set to thread group id by + * perf_event__synthesize_comm + */ + if ((int) comm_event->comm.pid != perf_thread_map__pid(threads, thread)) { + bool need_leader = true; + + /* is thread group leader in thread_map? */ + for (j = 0; j < threads->nr; ++j) { + if ((int) comm_event->comm.pid == perf_thread_map__pid(threads, j)) { + need_leader = false; + break; + } + } + + /* if not, generate events for it */ + if (need_leader && + __event__synthesize_thread(comm_event, mmap_event, + fork_event, namespaces_event, + comm_event->comm.pid, 0, + process, tool, machine, + mmap_data)) { + err = -1; + break; + } + } + } + free(namespaces_event); +out_free_fork: + free(fork_event); +out_free_mmap: + free(mmap_event); +out_free_comm: + free(comm_event); +out: + return err; +} + +static int __perf_event__synthesize_threads(struct perf_tool *tool, + perf_event__handler_t process, + struct machine *machine, + bool mmap_data, + struct dirent **dirent, + int start, + int num) +{ + union perf_event *comm_event, *mmap_event, *fork_event; + union perf_event *namespaces_event; + int err = -1; + char *end; + pid_t pid; + int i; + + comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size); + if (comm_event == NULL) + goto out; + + mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size); + if (mmap_event == NULL) + goto out_free_comm; + + fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size); + if (fork_event == NULL) + goto out_free_mmap; + + namespaces_event = malloc(sizeof(namespaces_event->namespaces) + + (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + + machine->id_hdr_size); + if (namespaces_event == NULL) + goto out_free_fork; + + for (i = start; i < start + num; i++) { + if (!isdigit(dirent[i]->d_name[0])) + continue; + + pid = (pid_t)strtol(dirent[i]->d_name, &end, 10); + /* only interested in proper numerical dirents */ + if (*end) + continue; + /* + * We may race with exiting thread, so don't stop just because + * one thread couldn't be synthesized. + */ + __event__synthesize_thread(comm_event, mmap_event, fork_event, + namespaces_event, pid, 1, process, + tool, machine, mmap_data); + } + err = 0; + + free(namespaces_event); +out_free_fork: + free(fork_event); +out_free_mmap: + free(mmap_event); +out_free_comm: + free(comm_event); +out: + return err; +} + +struct synthesize_threads_arg { + struct perf_tool *tool; + perf_event__handler_t process; + struct machine *machine; + bool mmap_data; + struct dirent **dirent; + int num; + int start; +}; + +static void *synthesize_threads_worker(void *arg) +{ + struct synthesize_threads_arg *args = arg; + + __perf_event__synthesize_threads(args->tool, args->process, + args->machine, args->mmap_data, + args->dirent, + args->start, args->num); + return NULL; +} + +int perf_event__synthesize_threads(struct perf_tool *tool, + perf_event__handler_t process, + struct machine *machine, + bool mmap_data, + unsigned int nr_threads_synthesize) +{ + struct synthesize_threads_arg *args = NULL; + pthread_t *synthesize_threads = NULL; + char proc_path[PATH_MAX]; + struct dirent **dirent; + int num_per_thread; + int m, n, i, j; + int thread_nr; + int base = 0; + int err = -1; + + + if (machine__is_default_guest(machine)) + return 0; + + snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir); + n = scandir(proc_path, &dirent, 0, alphasort); + if (n < 0) + return err; + + if (nr_threads_synthesize == UINT_MAX) + thread_nr = sysconf(_SC_NPROCESSORS_ONLN); + else + thread_nr = nr_threads_synthesize; + + if (thread_nr <= 1) { + err = __perf_event__synthesize_threads(tool, process, + machine, mmap_data, + dirent, base, n); + goto free_dirent; + } + if (thread_nr > n) + thread_nr = n; + + synthesize_threads = calloc(sizeof(pthread_t), thread_nr); + if (synthesize_threads == NULL) + goto free_dirent; + + args = calloc(sizeof(*args), thread_nr); + if (args == NULL) + goto free_threads; + + num_per_thread = n / thread_nr; + m = n % thread_nr; + for (i = 0; i < thread_nr; i++) { + args[i].tool = tool; + args[i].process = process; + args[i].machine = machine; + args[i].mmap_data = mmap_data; + args[i].dirent = dirent; + } + for (i = 0; i < m; i++) { + args[i].num = num_per_thread + 1; + args[i].start = i * args[i].num; + } + if (i != 0) + base = args[i-1].start + args[i-1].num; + for (j = i; j < thread_nr; j++) { + args[j].num = num_per_thread; + args[j].start = base + (j - i) * args[i].num; + } + + for (i = 0; i < thread_nr; i++) { + if (pthread_create(&synthesize_threads[i], NULL, + synthesize_threads_worker, &args[i])) + goto out_join; + } + err = 0; +out_join: + for (i = 0; i < thread_nr; i++) + pthread_join(synthesize_threads[i], NULL); + free(args); +free_threads: + free(synthesize_threads); +free_dirent: + for (i = 0; i < n; i++) + zfree(&dirent[i]); + free(dirent); + + return err; +} + +int __weak perf_event__synthesize_extra_kmaps(struct perf_tool *tool __maybe_unused, + perf_event__handler_t process __maybe_unused, + struct machine *machine __maybe_unused) +{ + return 0; +} + +static int __perf_event__synthesize_kernel_mmap(struct perf_tool *tool, + perf_event__handler_t process, + struct machine *machine) +{ + size_t size; + struct map *map = machine__kernel_map(machine); + struct kmap *kmap; + int err; + union perf_event *event; + + if (map == NULL) + return -1; + + kmap = map__kmap(map); + if (!kmap->ref_reloc_sym) + return -1; + + /* + * We should get this from /sys/kernel/sections/.text, but till that is + * available use this, and after it is use this as a fallback for older + * kernels. + */ + event = zalloc((sizeof(event->mmap) + machine->id_hdr_size)); + if (event == NULL) { + pr_debug("Not enough memory synthesizing mmap event " + "for kernel modules\n"); + return -1; + } + + if (machine__is_host(machine)) { + /* + * kernel uses PERF_RECORD_MISC_USER for user space maps, + * see kernel/perf_event.c __perf_event_mmap + */ + event->header.misc = PERF_RECORD_MISC_KERNEL; + } else { + event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; + } + + size = snprintf(event->mmap.filename, sizeof(event->mmap.filename), + "%s%s", machine->mmap_name, kmap->ref_reloc_sym->name) + 1; + size = PERF_ALIGN(size, sizeof(u64)); + event->mmap.header.type = PERF_RECORD_MMAP; + event->mmap.header.size = (sizeof(event->mmap) - + (sizeof(event->mmap.filename) - size) + machine->id_hdr_size); + event->mmap.pgoff = kmap->ref_reloc_sym->addr; + event->mmap.start = map->start; + event->mmap.len = map->end - event->mmap.start; + event->mmap.pid = machine->pid; + + err = perf_tool__process_synth_event(tool, event, machine, process); + free(event); + + return err; +} + +int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, + perf_event__handler_t process, + struct machine *machine) +{ + int err; + + err = __perf_event__synthesize_kernel_mmap(tool, process, machine); + if (err < 0) + return err; + + return perf_event__synthesize_extra_kmaps(tool, process, machine); +} + +int perf_event__synthesize_thread_map2(struct perf_tool *tool, + struct perf_thread_map *threads, + perf_event__handler_t process, + struct machine *machine) +{ + union perf_event *event; + int i, err, size; + + size = sizeof(event->thread_map); + size += threads->nr * sizeof(event->thread_map.entries[0]); + + event = zalloc(size); + if (!event) + return -ENOMEM; + + event->header.type = PERF_RECORD_THREAD_MAP; + event->header.size = size; + event->thread_map.nr = threads->nr; + + for (i = 0; i < threads->nr; i++) { + struct perf_record_thread_map_entry *entry = &event->thread_map.entries[i]; + char *comm = perf_thread_map__comm(threads, i); + + if (!comm) + comm = (char *) ""; + + entry->pid = perf_thread_map__pid(threads, i); + strncpy((char *) &entry->comm, comm, sizeof(entry->comm)); + } + + err = process(tool, event, NULL, machine); + + free(event); + return err; +} + +static void synthesize_cpus(struct cpu_map_entries *cpus, + struct perf_cpu_map *map) +{ + int i; + + cpus->nr = map->nr; + + for (i = 0; i < map->nr; i++) + cpus->cpu[i] = map->map[i]; +} + +static void synthesize_mask(struct perf_record_record_cpu_map *mask, + struct perf_cpu_map *map, int max) +{ + int i; + + mask->nr = BITS_TO_LONGS(max); + mask->long_size = sizeof(long); + + for (i = 0; i < map->nr; i++) + set_bit(map->map[i], mask->mask); +} + +static size_t cpus_size(struct perf_cpu_map *map) +{ + return sizeof(struct cpu_map_entries) + map->nr * sizeof(u16); +} + +static size_t mask_size(struct perf_cpu_map *map, int *max) +{ + int i; + + *max = 0; + + for (i = 0; i < map->nr; i++) { + /* bit possition of the cpu is + 1 */ + int bit = map->map[i] + 1; + + if (bit > *max) + *max = bit; + } + + return sizeof(struct perf_record_record_cpu_map) + BITS_TO_LONGS(*max) * sizeof(long); +} + +void *cpu_map_data__alloc(struct perf_cpu_map *map, size_t *size, u16 *type, int *max) +{ + size_t size_cpus, size_mask; + bool is_dummy = perf_cpu_map__empty(map); + + /* + * Both array and mask data have variable size based + * on the number of cpus and their actual values. + * The size of the 'struct perf_record_cpu_map_data' is: + * + * array = size of 'struct cpu_map_entries' + + * number of cpus * sizeof(u64) + * + * mask = size of 'struct perf_record_record_cpu_map' + + * maximum cpu bit converted to size of longs + * + * and finaly + the size of 'struct perf_record_cpu_map_data'. + */ + size_cpus = cpus_size(map); + size_mask = mask_size(map, max); + + if (is_dummy || (size_cpus < size_mask)) { + *size += size_cpus; + *type = PERF_CPU_MAP__CPUS; + } else { + *size += size_mask; + *type = PERF_CPU_MAP__MASK; + } + + *size += sizeof(struct perf_record_cpu_map_data); + *size = PERF_ALIGN(*size, sizeof(u64)); + return zalloc(*size); +} + +void cpu_map_data__synthesize(struct perf_record_cpu_map_data *data, struct perf_cpu_map *map, + u16 type, int max) +{ + data->type = type; + + switch (type) { + case PERF_CPU_MAP__CPUS: + synthesize_cpus((struct cpu_map_entries *) data->data, map); + break; + case PERF_CPU_MAP__MASK: + synthesize_mask((struct perf_record_record_cpu_map *)data->data, map, max); + default: + break; + }; +} + +static struct perf_record_cpu_map *cpu_map_event__new(struct perf_cpu_map *map) +{ + size_t size = sizeof(struct perf_record_cpu_map); + struct perf_record_cpu_map *event; + int max; + u16 type; + + event = cpu_map_data__alloc(map, &size, &type, &max); + if (!event) + return NULL; + + event->header.type = PERF_RECORD_CPU_MAP; + event->header.size = size; + event->data.type = type; + + cpu_map_data__synthesize(&event->data, map, type, max); + return event; +} + +int perf_event__synthesize_cpu_map(struct perf_tool *tool, + struct perf_cpu_map *map, + perf_event__handler_t process, + struct machine *machine) +{ + struct perf_record_cpu_map *event; + int err; + + event = cpu_map_event__new(map); + if (!event) + return -ENOMEM; + + err = process(tool, (union perf_event *) event, NULL, machine); + + free(event); + return err; +} + +int perf_event__synthesize_stat_config(struct perf_tool *tool, + struct perf_stat_config *config, + perf_event__handler_t process, + struct machine *machine) +{ + struct perf_record_stat_config *event; + int size, i = 0, err; + + size = sizeof(*event); + size += (PERF_STAT_CONFIG_TERM__MAX * sizeof(event->data[0])); + + event = zalloc(size); + if (!event) + return -ENOMEM; + + event->header.type = PERF_RECORD_STAT_CONFIG; + event->header.size = size; + event->nr = PERF_STAT_CONFIG_TERM__MAX; + +#define ADD(__term, __val) \ + event->data[i].tag = PERF_STAT_CONFIG_TERM__##__term; \ + event->data[i].val = __val; \ + i++; + + ADD(AGGR_MODE, config->aggr_mode) + ADD(INTERVAL, config->interval) + ADD(SCALE, config->scale) + + WARN_ONCE(i != PERF_STAT_CONFIG_TERM__MAX, + "stat config terms unbalanced\n"); +#undef ADD + + err = process(tool, (union perf_event *) event, NULL, machine); + + free(event); + return err; +} + +int perf_event__synthesize_stat(struct perf_tool *tool, + u32 cpu, u32 thread, u64 id, + struct perf_counts_values *count, + perf_event__handler_t process, + struct machine *machine) +{ + struct perf_record_stat event; + + event.header.type = PERF_RECORD_STAT; + event.header.size = sizeof(event); + event.header.misc = 0; + + event.id = id; + event.cpu = cpu; + event.thread = thread; + event.val = count->val; + event.ena = count->ena; + event.run = count->run; + + return process(tool, (union perf_event *) &event, NULL, machine); +} + +int perf_event__synthesize_stat_round(struct perf_tool *tool, + u64 evtime, u64 type, + perf_event__handler_t process, + struct machine *machine) +{ + struct perf_record_stat_round event; + + event.header.type = PERF_RECORD_STAT_ROUND; + event.header.size = sizeof(event); + event.header.misc = 0; + + event.time = evtime; + event.type = type; + + return process(tool, (union perf_event *) &event, NULL, machine); +} + +size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, u64 read_format) +{ + size_t sz, result = sizeof(struct perf_record_sample); + + if (type & PERF_SAMPLE_IDENTIFIER) + result += sizeof(u64); + + if (type & PERF_SAMPLE_IP) + result += sizeof(u64); + + if (type & PERF_SAMPLE_TID) + result += sizeof(u64); + + if (type & PERF_SAMPLE_TIME) + result += sizeof(u64); + + if (type & PERF_SAMPLE_ADDR) + result += sizeof(u64); + + if (type & PERF_SAMPLE_ID) + result += sizeof(u64); + + if (type & PERF_SAMPLE_STREAM_ID) + result += sizeof(u64); + + if (type & PERF_SAMPLE_CPU) + result += sizeof(u64); + + if (type & PERF_SAMPLE_PERIOD) + result += sizeof(u64); + + if (type & PERF_SAMPLE_READ) { + result += sizeof(u64); + if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) + result += sizeof(u64); + if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) + result += sizeof(u64); + /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */ + if (read_format & PERF_FORMAT_GROUP) { + sz = sample->read.group.nr * + sizeof(struct sample_read_value); + result += sz; + } else { + result += sizeof(u64); + } + } + + if (type & PERF_SAMPLE_CALLCHAIN) { + sz = (sample->callchain->nr + 1) * sizeof(u64); + result += sz; + } + + if (type & PERF_SAMPLE_RAW) { + result += sizeof(u32); + result += sample->raw_size; + } + + if (type & PERF_SAMPLE_BRANCH_STACK) { + sz = sample->branch_stack->nr * sizeof(struct branch_entry); + sz += sizeof(u64); + result += sz; + } + + if (type & PERF_SAMPLE_REGS_USER) { + if (sample->user_regs.abi) { + result += sizeof(u64); + sz = hweight64(sample->user_regs.mask) * sizeof(u64); + result += sz; + } else { + result += sizeof(u64); + } + } + + if (type & PERF_SAMPLE_STACK_USER) { + sz = sample->user_stack.size; + result += sizeof(u64); + if (sz) { + result += sz; + result += sizeof(u64); + } + } + + if (type & PERF_SAMPLE_WEIGHT) + result += sizeof(u64); + + if (type & PERF_SAMPLE_DATA_SRC) + result += sizeof(u64); + + if (type & PERF_SAMPLE_TRANSACTION) + result += sizeof(u64); + + if (type & PERF_SAMPLE_REGS_INTR) { + if (sample->intr_regs.abi) { + result += sizeof(u64); + sz = hweight64(sample->intr_regs.mask) * sizeof(u64); + result += sz; + } else { + result += sizeof(u64); + } + } + + if (type & PERF_SAMPLE_PHYS_ADDR) + result += sizeof(u64); + + return result; +} + +int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format, + const struct perf_sample *sample) +{ + __u64 *array; + size_t sz; + /* + * used for cross-endian analysis. See git commit 65014ab3 + * for why this goofiness is needed. + */ + union u64_swap u; + + array = event->sample.array; + + if (type & PERF_SAMPLE_IDENTIFIER) { + *array = sample->id; + array++; + } + + if (type & PERF_SAMPLE_IP) { + *array = sample->ip; + array++; + } + + if (type & PERF_SAMPLE_TID) { + u.val32[0] = sample->pid; + u.val32[1] = sample->tid; + *array = u.val64; + array++; + } + + if (type & PERF_SAMPLE_TIME) { + *array = sample->time; + array++; + } + + if (type & PERF_SAMPLE_ADDR) { + *array = sample->addr; + array++; + } + + if (type & PERF_SAMPLE_ID) { + *array = sample->id; + array++; + } + + if (type & PERF_SAMPLE_STREAM_ID) { + *array = sample->stream_id; + array++; + } + + if (type & PERF_SAMPLE_CPU) { + u.val32[0] = sample->cpu; + u.val32[1] = 0; + *array = u.val64; + array++; + } + + if (type & PERF_SAMPLE_PERIOD) { + *array = sample->period; + array++; + } + + if (type & PERF_SAMPLE_READ) { + if (read_format & PERF_FORMAT_GROUP) + *array = sample->read.group.nr; + else + *array = sample->read.one.value; + array++; + + if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) { + *array = sample->read.time_enabled; + array++; + } + + if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) { + *array = sample->read.time_running; + array++; + } + + /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */ + if (read_format & PERF_FORMAT_GROUP) { + sz = sample->read.group.nr * + sizeof(struct sample_read_value); + memcpy(array, sample->read.group.values, sz); + array = (void *)array + sz; + } else { + *array = sample->read.one.id; + array++; + } + } + + if (type & PERF_SAMPLE_CALLCHAIN) { + sz = (sample->callchain->nr + 1) * sizeof(u64); + memcpy(array, sample->callchain, sz); + array = (void *)array + sz; + } + + if (type & PERF_SAMPLE_RAW) { + u.val32[0] = sample->raw_size; + *array = u.val64; + array = (void *)array + sizeof(u32); + + memcpy(array, sample->raw_data, sample->raw_size); + array = (void *)array + sample->raw_size; + } + + if (type & PERF_SAMPLE_BRANCH_STACK) { + sz = sample->branch_stack->nr * sizeof(struct branch_entry); + sz += sizeof(u64); + memcpy(array, sample->branch_stack, sz); + array = (void *)array + sz; + } + + if (type & PERF_SAMPLE_REGS_USER) { + if (sample->user_regs.abi) { + *array++ = sample->user_regs.abi; + sz = hweight64(sample->user_regs.mask) * sizeof(u64); + memcpy(array, sample->user_regs.regs, sz); + array = (void *)array + sz; + } else { + *array++ = 0; + } + } + + if (type & PERF_SAMPLE_STACK_USER) { + sz = sample->user_stack.size; + *array++ = sz; + if (sz) { + memcpy(array, sample->user_stack.data, sz); + array = (void *)array + sz; + *array++ = sz; + } + } + + if (type & PERF_SAMPLE_WEIGHT) { + *array = sample->weight; + array++; + } + + if (type & PERF_SAMPLE_DATA_SRC) { + *array = sample->data_src; + array++; + } + + if (type & PERF_SAMPLE_TRANSACTION) { + *array = sample->transaction; + array++; + } + + if (type & PERF_SAMPLE_REGS_INTR) { + if (sample->intr_regs.abi) { + *array++ = sample->intr_regs.abi; + sz = hweight64(sample->intr_regs.mask) * sizeof(u64); + memcpy(array, sample->intr_regs.regs, sz); + array = (void *)array + sz; + } else { + *array++ = 0; + } + } + + if (type & PERF_SAMPLE_PHYS_ADDR) { + *array = sample->phys_addr; + array++; + } + + return 0; +} + +int perf_event__synthesize_id_index(struct perf_tool *tool, perf_event__handler_t process, + struct evlist *evlist, struct machine *machine) +{ + union perf_event *ev; + struct evsel *evsel; + size_t nr = 0, i = 0, sz, max_nr, n; + int err; + + pr_debug2("Synthesizing id index\n"); + + max_nr = (UINT16_MAX - sizeof(struct perf_record_id_index)) / + sizeof(struct id_index_entry); + + evlist__for_each_entry(evlist, evsel) + nr += evsel->ids; + + n = nr > max_nr ? max_nr : nr; + sz = sizeof(struct perf_record_id_index) + n * sizeof(struct id_index_entry); + ev = zalloc(sz); + if (!ev) + return -ENOMEM; + + ev->id_index.header.type = PERF_RECORD_ID_INDEX; + ev->id_index.header.size = sz; + ev->id_index.nr = n; + + evlist__for_each_entry(evlist, evsel) { + u32 j; + + for (j = 0; j < evsel->ids; j++) { + struct id_index_entry *e; + struct perf_sample_id *sid; + + if (i >= n) { + err = process(tool, ev, NULL, machine); + if (err) + goto out_err; + nr -= n; + i = 0; + } + + e = &ev->id_index.entries[i++]; + + e->id = evsel->id[j]; + + sid = perf_evlist__id2sid(evlist, e->id); + if (!sid) { + free(ev); + return -ENOENT; + } + + e->idx = sid->idx; + e->cpu = sid->cpu; + e->tid = sid->tid; + } + } + + sz = sizeof(struct perf_record_id_index) + nr * sizeof(struct id_index_entry); + ev->id_index.header.size = sz; + ev->id_index.nr = nr; + + err = process(tool, ev, NULL, machine); +out_err: + free(ev); + + return err; +} + +int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, + struct target *target, struct perf_thread_map *threads, + perf_event__handler_t process, bool data_mmap, + unsigned int nr_threads_synthesize) +{ + if (target__has_task(target)) + return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap); + else if (target__has_cpu(target)) + return perf_event__synthesize_threads(tool, process, + machine, data_mmap, + nr_threads_synthesize); + /* command specified */ + return 0; +} + +int machine__synthesize_threads(struct machine *machine, struct target *target, + struct perf_thread_map *threads, bool data_mmap, + unsigned int nr_threads_synthesize) +{ + return __machine__synthesize_threads(machine, NULL, target, threads, + perf_event__process, data_mmap, + nr_threads_synthesize); +} + +static struct perf_record_event_update *event_update_event__new(size_t size, u64 type, u64 id) +{ + struct perf_record_event_update *ev; + + size += sizeof(*ev); + size = PERF_ALIGN(size, sizeof(u64)); + + ev = zalloc(size); + if (ev) { + ev->header.type = PERF_RECORD_EVENT_UPDATE; + ev->header.size = (u16)size; + ev->type = type; + ev->id = id; + } + return ev; +} + +int perf_event__synthesize_event_update_unit(struct perf_tool *tool, struct evsel *evsel, + perf_event__handler_t process) +{ + size_t size = strlen(evsel->unit); + struct perf_record_event_update *ev; + int err; + + ev = event_update_event__new(size + 1, PERF_EVENT_UPDATE__UNIT, evsel->id[0]); + if (ev == NULL) + return -ENOMEM; + + strlcpy(ev->data, evsel->unit, size + 1); + err = process(tool, (union perf_event *)ev, NULL, NULL); + free(ev); + return err; +} + +int perf_event__synthesize_event_update_scale(struct perf_tool *tool, struct evsel *evsel, + perf_event__handler_t process) +{ + struct perf_record_event_update *ev; + struct perf_record_event_update_scale *ev_data; + int err; + + ev = event_update_event__new(sizeof(*ev_data), PERF_EVENT_UPDATE__SCALE, evsel->id[0]); + if (ev == NULL) + return -ENOMEM; + + ev_data = (struct perf_record_event_update_scale *)ev->data; + ev_data->scale = evsel->scale; + err = process(tool, (union perf_event *)ev, NULL, NULL); + free(ev); + return err; +} + +int perf_event__synthesize_event_update_name(struct perf_tool *tool, struct evsel *evsel, + perf_event__handler_t process) +{ + struct perf_record_event_update *ev; + size_t len = strlen(evsel->name); + int err; + + ev = event_update_event__new(len + 1, PERF_EVENT_UPDATE__NAME, evsel->id[0]); + if (ev == NULL) + return -ENOMEM; + + strlcpy(ev->data, evsel->name, len + 1); + err = process(tool, (union perf_event *)ev, NULL, NULL); + free(ev); + return err; +} + +int perf_event__synthesize_event_update_cpus(struct perf_tool *tool, struct evsel *evsel, + perf_event__handler_t process) +{ + size_t size = sizeof(struct perf_record_event_update); + struct perf_record_event_update *ev; + int max, err; + u16 type; + + if (!evsel->core.own_cpus) + return 0; + + ev = cpu_map_data__alloc(evsel->core.own_cpus, &size, &type, &max); + if (!ev) + return -ENOMEM; + + ev->header.type = PERF_RECORD_EVENT_UPDATE; + ev->header.size = (u16)size; + ev->type = PERF_EVENT_UPDATE__CPUS; + ev->id = evsel->id[0]; + + cpu_map_data__synthesize((struct perf_record_cpu_map_data *)ev->data, + evsel->core.own_cpus, type, max); + + err = process(tool, (union perf_event *)ev, NULL, NULL); + free(ev); + return err; +} + +int perf_event__synthesize_attrs(struct perf_tool *tool, struct evlist *evlist, + perf_event__handler_t process) +{ + struct evsel *evsel; + int err = 0; + + evlist__for_each_entry(evlist, evsel) { + err = perf_event__synthesize_attr(tool, &evsel->core.attr, evsel->ids, + evsel->id, process); + if (err) { + pr_debug("failed to create perf header attribute\n"); + return err; + } + } + + return err; +} + +static bool has_unit(struct evsel *evsel) +{ + return evsel->unit && *evsel->unit; +} + +static bool has_scale(struct evsel *evsel) +{ + return evsel->scale != 1; +} + +int perf_event__synthesize_extra_attr(struct perf_tool *tool, struct evlist *evsel_list, + perf_event__handler_t process, bool is_pipe) +{ + struct evsel *evsel; + int err; + + /* + * Synthesize other events stuff not carried within + * attr event - unit, scale, name + */ + evlist__for_each_entry(evsel_list, evsel) { + if (!evsel->supported) + continue; + + /* + * Synthesize unit and scale only if it's defined. + */ + if (has_unit(evsel)) { + err = perf_event__synthesize_event_update_unit(tool, evsel, process); + if (err < 0) { + pr_err("Couldn't synthesize evsel unit.\n"); + return err; + } + } + + if (has_scale(evsel)) { + err = perf_event__synthesize_event_update_scale(tool, evsel, process); + if (err < 0) { + pr_err("Couldn't synthesize evsel evsel.\n"); + return err; + } + } + + if (evsel->core.own_cpus) { + err = perf_event__synthesize_event_update_cpus(tool, evsel, process); + if (err < 0) { + pr_err("Couldn't synthesize evsel cpus.\n"); + return err; + } + } + + /* + * Name is needed only for pipe output, + * perf.data carries event names. + */ + if (is_pipe) { + err = perf_event__synthesize_event_update_name(tool, evsel, process); + if (err < 0) { + pr_err("Couldn't synthesize evsel name.\n"); + return err; + } + } + } + return 0; +} + +int perf_event__synthesize_attr(struct perf_tool *tool, struct perf_event_attr *attr, + u32 ids, u64 *id, perf_event__handler_t process) +{ + union perf_event *ev; + size_t size; + int err; + + size = sizeof(struct perf_event_attr); + size = PERF_ALIGN(size, sizeof(u64)); + size += sizeof(struct perf_event_header); + size += ids * sizeof(u64); + + ev = zalloc(size); + + if (ev == NULL) + return -ENOMEM; + + ev->attr.attr = *attr; + memcpy(ev->attr.id, id, ids * sizeof(u64)); + + ev->attr.header.type = PERF_RECORD_HEADER_ATTR; + ev->attr.header.size = (u16)size; + + if (ev->attr.header.size == size) + err = process(tool, ev, NULL, NULL); + else + err = -E2BIG; + + free(ev); + + return err; +} + +int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, struct evlist *evlist, + perf_event__handler_t process) +{ + union perf_event ev; + struct tracing_data *tdata; + ssize_t size = 0, aligned_size = 0, padding; + struct feat_fd ff; + + /* + * We are going to store the size of the data followed + * by the data contents. Since the fd descriptor is a pipe, + * we cannot seek back to store the size of the data once + * we know it. Instead we: + * + * - write the tracing data to the temp file + * - get/write the data size to pipe + * - write the tracing data from the temp file + * to the pipe + */ + tdata = tracing_data_get(&evlist->core.entries, fd, true); + if (!tdata) + return -1; + + memset(&ev, 0, sizeof(ev)); + + ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA; + size = tdata->size; + aligned_size = PERF_ALIGN(size, sizeof(u64)); + padding = aligned_size - size; + ev.tracing_data.header.size = sizeof(ev.tracing_data); + ev.tracing_data.size = aligned_size; + + process(tool, &ev, NULL, NULL); + + /* + * The put function will copy all the tracing data + * stored in temp file to the pipe. + */ + tracing_data_put(tdata); + + ff = (struct feat_fd){ .fd = fd }; + if (write_padded(&ff, NULL, 0, padding)) + return -1; + + return aligned_size; +} + +int perf_event__synthesize_build_id(struct perf_tool *tool, struct dso *pos, u16 misc, + perf_event__handler_t process, struct machine *machine) +{ + union perf_event ev; + size_t len; + + if (!pos->hit) + return 0; + + memset(&ev, 0, sizeof(ev)); + + len = pos->long_name_len + 1; + len = PERF_ALIGN(len, NAME_ALIGN); + memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id)); + ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID; + ev.build_id.header.misc = misc; + ev.build_id.pid = machine->pid; + ev.build_id.header.size = sizeof(ev.build_id) + len; + memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len); + + return process(tool, &ev, NULL, machine); +} + +int perf_event__synthesize_stat_events(struct perf_stat_config *config, struct perf_tool *tool, + struct evlist *evlist, perf_event__handler_t process, bool attrs) +{ + int err; + + if (attrs) { + err = perf_event__synthesize_attrs(tool, evlist, process); + if (err < 0) { + pr_err("Couldn't synthesize attrs.\n"); + return err; + } + } + + err = perf_event__synthesize_extra_attr(tool, evlist, process, attrs); + err = perf_event__synthesize_thread_map2(tool, evlist->core.threads, process, NULL); + if (err < 0) { + pr_err("Couldn't synthesize thread map.\n"); + return err; + } + + err = perf_event__synthesize_cpu_map(tool, evlist->core.cpus, process, NULL); + if (err < 0) { + pr_err("Couldn't synthesize thread map.\n"); + return err; + } + + err = perf_event__synthesize_stat_config(tool, config, process, NULL); + if (err < 0) { + pr_err("Couldn't synthesize config.\n"); + return err; + } + + return 0; +} + +int __weak perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused, + struct perf_tool *tool __maybe_unused, + perf_event__handler_t process __maybe_unused, + struct machine *machine __maybe_unused) +{ + return 0; +} + +extern const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE]; + +int perf_event__synthesize_features(struct perf_tool *tool, struct perf_session *session, + struct evlist *evlist, perf_event__handler_t process) +{ + struct perf_header *header = &session->header; + struct perf_record_header_feature *fe; + struct feat_fd ff; + size_t sz, sz_hdr; + int feat, ret; + + sz_hdr = sizeof(fe->header); + sz = sizeof(union perf_event); + /* get a nice alignment */ + sz = PERF_ALIGN(sz, page_size); + + memset(&ff, 0, sizeof(ff)); + + ff.buf = malloc(sz); + if (!ff.buf) + return -ENOMEM; + + ff.size = sz - sz_hdr; + ff.ph = &session->header; + + for_each_set_bit(feat, header->adds_features, HEADER_FEAT_BITS) { + if (!feat_ops[feat].synthesize) { + pr_debug("No record header feature for header :%d\n", feat); + continue; + } + + ff.offset = sizeof(*fe); + + ret = feat_ops[feat].write(&ff, evlist); + if (ret || ff.offset <= (ssize_t)sizeof(*fe)) { + pr_debug("Error writing feature\n"); + continue; + } + /* ff.buf may have changed due to realloc in do_write() */ + fe = ff.buf; + memset(fe, 0, sizeof(*fe)); + + fe->feat_id = feat; + fe->header.type = PERF_RECORD_HEADER_FEATURE; + fe->header.size = ff.offset; + + ret = process(tool, ff.buf, NULL, NULL); + if (ret) { + free(ff.buf); + return ret; + } + } + + /* Send HEADER_LAST_FEATURE mark. */ + fe = ff.buf; + fe->feat_id = HEADER_LAST_FEATURE; + fe->header.type = PERF_RECORD_HEADER_FEATURE; + fe->header.size = sizeof(*fe); + + ret = process(tool, ff.buf, NULL, NULL); + + free(ff.buf); + return ret; +} -- cgit v1.2.3-59-g8ed1b From b295c3e39c1383e06ba1db4dd836018502e2ff3a Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 18 Sep 2019 16:34:07 +0300 Subject: tools lib traceevent: Convert remaining %p[fF] users to %p[sS] There are no in-kernel %p[fF] users left. Convert the traceevent tool, too, to align with the kernel. Signed-off-by: Sakari Ailus Cc: Andy Shevchenko Cc: devicetree@vger.kernel.org Cc: Heikki Krogerus Cc: Jiri Olsa Cc: Joe Perches Cc: linux-acpi@vger.kernel.org Cc: linux-trace-devel@vger.kernel.org Cc: Namhyung Kim Cc: Petr Mladek Cc: Rafael J. Wysocki Cc: Rob Herring Cc: Steven Rostedt (VMware) Cc: Tzvetomir Stoyanov Link: http://lore.kernel.org/lkml/20190918133419.7969-2-sakari.ailus@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- .../Documentation/libtraceevent-func_apis.txt | 10 +++++----- tools/lib/traceevent/event-parse.c | 18 ++++++++++++++---- 2 files changed, 19 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt b/tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt index 38bfea30a5f6..f6aca0df2151 100644 --- a/tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt +++ b/tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt @@ -59,12 +59,12 @@ parser context. The _tep_register_function()_ function registers a function name mapped to an address and (optional) module. This mapping is used in case the function tracer -or events have "%pF" or "%pS" parameter in its format string. It is common to -pass in the kallsyms function names with their corresponding addresses with this +or events have "%pS" parameter in its format string. It is common to pass in +the kallsyms function names with their corresponding addresses with this function. The _tep_ argument is the trace event parser context. The _name_ is -the name of the function, the string is copied internally. The _addr_ is -the start address of the function. The _mod_ is the kernel module -the function may be in (NULL for none). +the name of the function, the string is copied internally. The _addr_ is the +start address of the function. The _mod_ is the kernel module the function may +be in (NULL for none). The _tep_register_print_string()_ function registers a string by the address it was stored in the kernel. Some strings internal to the kernel with static diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index bb22238debfe..6f842af4550b 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -4367,10 +4367,20 @@ static struct tep_print_arg *make_bprint_args(char *fmt, void *data, int size, s switch (*ptr) { case 's': case 'S': - case 'f': - case 'F': case 'x': break; + case 'f': + case 'F': + /* + * Pre-5.5 kernels use %pf and + * %pF for printing symbols + * while kernels since 5.5 use + * %pfw for fwnodes. So check + * %p[fF] isn't followed by 'w'. + */ + if (ptr[1] != 'w') + break; + /* fall through */ default: /* * Older kernels do not process @@ -4487,12 +4497,12 @@ get_bprint_format(void *data, int size __maybe_unused, printk = find_printk(tep, addr); if (!printk) { - if (asprintf(&format, "%%pf: (NO FORMAT FOUND at %llx)\n", addr) < 0) + if (asprintf(&format, "%%ps: (NO FORMAT FOUND at %llx)\n", addr) < 0) return NULL; return format; } - if (asprintf(&format, "%s: %s", "%pf", printk->printk) < 0) + if (asprintf(&format, "%s: %s", "%ps", printk->printk) < 0) return NULL; return format; -- cgit v1.2.3-59-g8ed1b From b63fd11cced17fcb8e133def29001b0f6aaa5e06 Mon Sep 17 00:00:00 2001 From: Srikar Dronamraju Date: Wed, 4 Sep 2019 15:17:37 +0530 Subject: perf stat: Reset previous counts on repeat with interval When using 'perf stat' with repeat and interval option, it shows wrong values for events. The wrong values will be shown for the first interval on the second and subsequent repetitions. Without the fix: # perf stat -r 3 -I 2000 -e faults -e sched:sched_switch -a sleep 5 2.000282489 53 faults 2.000282489 513 sched:sched_switch 4.005478208 3,721 faults 4.005478208 2,666 sched:sched_switch 5.025470933 395 faults 5.025470933 1,307 sched:sched_switch 2.009602825 1,84,46,74,40,73,70,95,47,520 faults <------ 2.009602825 1,84,46,74,40,73,70,95,49,568 sched:sched_switch <------ 4.019612206 4,730 faults 4.019612206 2,746 sched:sched_switch 5.039615484 3,953 faults 5.039615484 1,496 sched:sched_switch 2.000274620 1,84,46,74,40,73,70,95,47,520 faults <------ 2.000274620 1,84,46,74,40,73,70,95,47,520 sched:sched_switch <------ 4.000480342 4,282 faults 4.000480342 2,303 sched:sched_switch 5.000916811 1,322 faults 5.000916811 1,064 sched:sched_switch # prev_raw_counts is allocated when using intervals. This is used when calculating the difference in the counts of events when using interval. The current counts are stored in prev_raw_counts to calculate the differences in the next iteration. On the first interval of the second and subsequent repetitions, prev_raw_counts would be the values stored in the last interval of the previous repetitions, while the current counts will only be for the first interval of the current repetition. Hence there is a possibility of events showing up as big number. Fix this by resetting prev_raw_counts whenever perf stat repeats the command. With the fix: # perf stat -r 3 -I 2000 -e faults -e sched:sched_switch -a sleep 5 2.019349347 2,597 faults 2.019349347 2,753 sched:sched_switch 4.019577372 3,098 faults 4.019577372 2,532 sched:sched_switch 5.019415481 1,879 faults 5.019415481 1,356 sched:sched_switch 2.000178813 8,468 faults 2.000178813 2,254 sched:sched_switch 4.000404621 7,440 faults 4.000404621 1,266 sched:sched_switch 5.040196079 2,458 faults 5.040196079 556 sched:sched_switch 2.000191939 6,870 faults 2.000191939 1,170 sched:sched_switch 4.000414103 541 faults 4.000414103 902 sched:sched_switch 5.000809863 450 faults 5.000809863 364 sched:sched_switch # Committer notes: This was broken since the cset introducing the --interval feature, i.e. --repeat + --interval wasn't tested at that point, add the Fixes tag so that automatic scripts can pick this up. Fixes: 13370a9b5bb8 ("perf stat: Add interval printing") Signed-off-by: Srikar Dronamraju Acked-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Tested-by: Ravi Bangoria Cc: Namhyung Kim Cc: Naveen N. Rao Cc: Stephane Eranian Cc: stable@vger.kernel.org # v3.9+ Link: http://lore.kernel.org/lkml/20190904094738.9558-2-srikar@linux.vnet.ibm.com [ Fixed up conflicts with libperf, i.e. some perf_{evsel,evlist} lost the 'perf' prefix ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 3 +++ tools/perf/util/stat.c | 17 +++++++++++++++++ tools/perf/util/stat.h | 1 + 3 files changed, 21 insertions(+) (limited to 'tools') diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index eece3d1e429a..fa4b148ecfca 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1952,6 +1952,9 @@ int cmd_stat(int argc, const char **argv) fprintf(output, "[ perf stat: executing run #%d ... ]\n", run_idx + 1); + if (run_idx != 0) + perf_evlist__reset_prev_raw_counts(evsel_list); + status = run_perf_stat(argc, argv, run_idx); if (forever && status != -1) { print_counters(NULL, argc, argv); diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 06571209cb0b..fcd54342c04c 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -162,6 +162,15 @@ static void perf_evsel__free_prev_raw_counts(struct evsel *evsel) evsel->prev_raw_counts = NULL; } +static void perf_evsel__reset_prev_raw_counts(struct evsel *evsel) +{ + if (evsel->prev_raw_counts) { + evsel->prev_raw_counts->aggr.val = 0; + evsel->prev_raw_counts->aggr.ena = 0; + evsel->prev_raw_counts->aggr.run = 0; + } +} + static int perf_evsel__alloc_stats(struct evsel *evsel, bool alloc_raw) { int ncpus = perf_evsel__nr_cpus(evsel); @@ -212,6 +221,14 @@ void perf_evlist__reset_stats(struct evlist *evlist) } } +void perf_evlist__reset_prev_raw_counts(struct evlist *evlist) +{ + struct evsel *evsel; + + evlist__for_each_entry(evlist, evsel) + perf_evsel__reset_prev_raw_counts(evsel); +} + static void zero_per_pkg(struct evsel *counter) { if (counter->per_pkg_mask) diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 0f9c9f6e2041..edbeb2f63e8d 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -193,6 +193,7 @@ void perf_stat__collect_metric_expr(struct evlist *); int perf_evlist__alloc_stats(struct evlist *evlist, bool alloc_raw); void perf_evlist__free_stats(struct evlist *evlist); void perf_evlist__reset_stats(struct evlist *evlist); +void perf_evlist__reset_prev_raw_counts(struct evlist *evlist); int perf_stat_process_counter(struct perf_stat_config *config, struct evsel *counter); -- cgit v1.2.3-59-g8ed1b From 443f2d5ba13d65ccfd879460f77941875159d154 Mon Sep 17 00:00:00 2001 From: Srikar Dronamraju Date: Wed, 4 Sep 2019 15:17:38 +0530 Subject: perf stat: Fix a segmentation fault when using repeat forever Observe a segmentation fault when 'perf stat' is asked to repeat forever with the interval option. Without fix: # perf stat -r 0 -I 5000 -e cycles -a sleep 10 # time counts unit events 5.000211692 3,13,89,82,34,157 cycles 10.000380119 1,53,98,52,22,294 cycles 10.040467280 17,16,79,265 cycles Segmentation fault This problem was only observed when we use forever option aka -r 0 and works with limited repeats. Calling print_counter with ts being set to NULL, is not a correct option when interval is set. Hence avoid print_counter(NULL,..) if interval is set. With fix: # perf stat -r 0 -I 5000 -e cycles -a sleep 10 # time counts unit events 5.019866622 3,15,14,43,08,697 cycles 10.039865756 3,15,16,31,95,261 cycles 10.059950628 1,26,05,47,158 cycles 5.009902655 3,14,52,62,33,932 cycles 10.019880228 3,14,52,22,89,154 cycles 10.030543876 66,90,18,333 cycles 5.009848281 3,14,51,98,25,437 cycles 10.029854402 3,15,14,93,04,918 cycles 5.009834177 3,14,51,95,92,316 cycles Committer notes: Did the 'git bisect' to find the cset introducing the problem to add the Fixes tag below, and at that time the problem reproduced as: (gdb) run stat -r0 -I500 sleep 1 Program received signal SIGSEGV, Segmentation fault. print_interval (prefix=prefix@entry=0x7fffffffc8d0 "", ts=ts@entry=0x0) at builtin-stat.c:866 866 sprintf(prefix, "%6lu.%09lu%s", ts->tv_sec, ts->tv_nsec, csv_sep); (gdb) bt #0 print_interval (prefix=prefix@entry=0x7fffffffc8d0 "", ts=ts@entry=0x0) at builtin-stat.c:866 #1 0x000000000041860a in print_counters (ts=ts@entry=0x0, argc=argc@entry=2, argv=argv@entry=0x7fffffffd640) at builtin-stat.c:938 #2 0x0000000000419a7f in cmd_stat (argc=2, argv=0x7fffffffd640, prefix=) at builtin-stat.c:1411 #3 0x000000000045c65a in run_builtin (p=p@entry=0x6291b8 , argc=argc@entry=5, argv=argv@entry=0x7fffffffd640) at perf.c:370 #4 0x000000000045c893 in handle_internal_command (argc=5, argv=0x7fffffffd640) at perf.c:429 #5 0x000000000045c8f1 in run_argv (argcp=argcp@entry=0x7fffffffd4ac, argv=argv@entry=0x7fffffffd4a0) at perf.c:473 #6 0x000000000045cac9 in main (argc=, argv=) at perf.c:588 (gdb) Mostly the same as just before this patch: Program received signal SIGSEGV, Segmentation fault. 0x00000000005874a7 in print_interval (config=0xa1f2a0 , evlist=0xbc9b90, prefix=0x7fffffffd1c0 "`", ts=0x0) at util/stat-display.c:964 964 sprintf(prefix, "%6lu.%09lu%s", ts->tv_sec, ts->tv_nsec, config->csv_sep); (gdb) bt #0 0x00000000005874a7 in print_interval (config=0xa1f2a0 , evlist=0xbc9b90, prefix=0x7fffffffd1c0 "`", ts=0x0) at util/stat-display.c:964 #1 0x0000000000588047 in perf_evlist__print_counters (evlist=0xbc9b90, config=0xa1f2a0 , _target=0xa1f0c0 , ts=0x0, argc=2, argv=0x7fffffffd670) at util/stat-display.c:1172 #2 0x000000000045390f in print_counters (ts=0x0, argc=2, argv=0x7fffffffd670) at builtin-stat.c:656 #3 0x0000000000456bb5 in cmd_stat (argc=2, argv=0x7fffffffd670) at builtin-stat.c:1960 #4 0x00000000004dd2e0 in run_builtin (p=0xa30e00 , argc=5, argv=0x7fffffffd670) at perf.c:310 #5 0x00000000004dd54d in handle_internal_command (argc=5, argv=0x7fffffffd670) at perf.c:362 #6 0x00000000004dd694 in run_argv (argcp=0x7fffffffd4cc, argv=0x7fffffffd4c0) at perf.c:406 #7 0x00000000004dda11 in main (argc=5, argv=0x7fffffffd670) at perf.c:531 (gdb) Fixes: d4f63a4741a8 ("perf stat: Introduce print_counters function") Signed-off-by: Srikar Dronamraju Acked-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Tested-by: Ravi Bangoria Cc: Namhyung Kim Cc: Naveen N. Rao Cc: stable@vger.kernel.org # v4.2+ Link: http://lore.kernel.org/lkml/20190904094738.9558-3-srikar@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index fa4b148ecfca..60cdd383af81 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1956,7 +1956,7 @@ int cmd_stat(int argc, const char **argv) perf_evlist__reset_prev_raw_counts(evsel_list); status = run_perf_stat(argc, argv, run_idx); - if (forever && status != -1) { + if (forever && status != -1 && !interval) { print_counters(NULL, argc, argv); perf_stat__reset_stats(); } -- cgit v1.2.3-59-g8ed1b From ce095c9ac293d1683f9fedb214811727dff0d508 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 11 Sep 2019 16:21:48 +0100 Subject: perf test: Fix spelling mistake "allos" -> "allocate" There is a spelling mistake in a TEST_ASSERT_VAL message. Fix it. Signed-off-by: Colin King Reviewed-by: Mukesh Ojha Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: kernel-janitors@vger.kernel.org Link: http://lore.kernel.org/lkml/20190911152148.17031-1-colin.king@canonical.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/event_update.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index 4bb772e2b73d..0497d900ced2 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -94,7 +94,7 @@ int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unu evsel = perf_evlist__first(evlist); - TEST_ASSERT_VAL("failed to allos ids", + TEST_ASSERT_VAL("failed to allocate ids", !perf_evsel__alloc_id(evsel, 1, 1)); perf_evlist__id_add(evlist, evsel, 0, 0, 123); -- cgit v1.2.3-59-g8ed1b From 8067b3da970baa12e6045400fdf009673b8dd3c2 Mon Sep 17 00:00:00 2001 From: Anju T Sudhakar Date: Thu, 18 Jul 2019 23:47:47 +0530 Subject: perf kvm: Move kvm-stat header file from conditional inclusion to common include section Move kvm-stat header file to the common include section, and make the definitions in the header file under the conditional inclusion `#ifdef HAVE_KVM_STAT_SUPPORT`. This helps to define other 'perf kvm' related function prototypes in kvm-stat header file, which may not need kvm-stat support. Signed-off-by: Anju T Sudhakar Reviewed-By: Ravi Bangoria Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linuxppc-dev@lists.ozlabs.org Link: http://lore.kernel.org/lkml/20190718181749.30612-1-anju@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kvm.c | 2 +- tools/perf/util/kvm-stat.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index ac6d6e061dc5..2b822be87673 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -21,6 +21,7 @@ #include "util/top.h" #include "util/data.h" #include "util/ordered-events.h" +#include "util/kvm-stat.h" #include "ui/ui.h" #include @@ -59,7 +60,6 @@ static const char *get_filename_for_perf_kvm(void) } #ifdef HAVE_KVM_STAT_SUPPORT -#include "util/kvm-stat.h" void exit_event_get_key(struct evsel *evsel, struct perf_sample *sample, diff --git a/tools/perf/util/kvm-stat.h b/tools/perf/util/kvm-stat.h index 46913637085b..8fd6ec20662c 100644 --- a/tools/perf/util/kvm-stat.h +++ b/tools/perf/util/kvm-stat.h @@ -2,6 +2,8 @@ #ifndef __PERF_KVM_STAT_H #define __PERF_KVM_STAT_H +#ifdef HAVE_KVM_STAT_SUPPORT + #include "tool.h" #include "stat.h" #include "record.h" @@ -144,5 +146,6 @@ extern const int decode_str_len; extern const char *kvm_exit_reason; extern const char *kvm_entry_trace; extern const char *kvm_exit_trace; +#endif /* HAVE_KVM_STAT_SUPPORT */ #endif /* __PERF_KVM_STAT_H */ -- cgit v1.2.3-59-g8ed1b From 124eb5f82bf9395419b20205c4dcc1b8fcda7f29 Mon Sep 17 00:00:00 2001 From: Anju T Sudhakar Date: Thu, 18 Jul 2019 23:47:48 +0530 Subject: perf kvm: Add arch neutral function to choose event for perf kvm record 'perf kvm record' uses 'cycles'(if the user did not specify any event) as the default event to profile the guest. This will not provide any proper samples from the guest incase of powerpc architecture, since in powerpc the PMUs are controlled by the guest rather than the host. Patch adds a function to pick an arch specific event for 'perf kvm record', instead of selecting 'cycles' as a default event for all architectures. For powerpc this function checks for any user specified event, and if there isn't any it returns invalid instead of proceeding with 'cycles' event. Signed-off-by: Anju T Sudhakar Reviewed-by: Ravi Bangoria Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linuxppc-dev@lists.ozlabs.org Link: http://lore.kernel.org/lkml/20190718181749.30612-2-anju@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/powerpc/util/kvm-stat.c | 37 +++++++++++++++++++++++++++++++++ tools/perf/builtin-kvm.c | 12 ++++++++++- tools/perf/util/kvm-stat.h | 1 + 3 files changed, 49 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/arch/powerpc/util/kvm-stat.c b/tools/perf/arch/powerpc/util/kvm-stat.c index f0dbf7b075c8..ec5b771029e4 100644 --- a/tools/perf/arch/powerpc/util/kvm-stat.c +++ b/tools/perf/arch/powerpc/util/kvm-stat.c @@ -8,6 +8,7 @@ #include "book3s_hv_exits.h" #include "book3s_hcalls.h" +#include #define NR_TPS 4 @@ -172,3 +173,39 @@ int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused) return ret; } + +/* + * Incase of powerpc architecture, pmu registers are programmable + * by guest kernel. So monitoring guest via host may not provide + * valid samples. It is better to fail the "perf kvm record" + * with default "cycles" event to monitor guest in powerpc. + * + * Function to parse the arguments and return appropriate values. + */ +int kvm_add_default_arch_event(int *argc, const char **argv) +{ + const char **tmp; + bool event = false; + int i, j = *argc; + + const struct option event_options[] = { + OPT_BOOLEAN('e', "event", &event, NULL), + OPT_END() + }; + + tmp = calloc(j + 1, sizeof(char *)); + if (!tmp) + return -EINVAL; + + for (i = 0; i < j; i++) + tmp[i] = argv[i]; + + parse_options(j, tmp, event_options, NULL, PARSE_OPT_KEEP_UNKNOWN); + if (!event) { + free(tmp); + return -EINVAL; + } + + free(tmp); + return 0; +} diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 2b822be87673..6e3e36658900 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1514,11 +1514,21 @@ perf_stat: } #endif /* HAVE_KVM_STAT_SUPPORT */ +int __weak kvm_add_default_arch_event(int *argc __maybe_unused, + const char **argv __maybe_unused) +{ + return 0; +} + static int __cmd_record(const char *file_name, int argc, const char **argv) { - int rec_argc, i = 0, j; + int rec_argc, i = 0, j, ret; const char **rec_argv; + ret = kvm_add_default_arch_event(&argc, argv); + if (ret) + return -EINVAL; + rec_argc = argc + 2; rec_argv = calloc(rec_argc + 1, sizeof(char *)); rec_argv[i++] = strdup("record"); diff --git a/tools/perf/util/kvm-stat.h b/tools/perf/util/kvm-stat.h index 8fd6ec20662c..6f0fa05b62b6 100644 --- a/tools/perf/util/kvm-stat.h +++ b/tools/perf/util/kvm-stat.h @@ -148,4 +148,5 @@ extern const char *kvm_entry_trace; extern const char *kvm_exit_trace; #endif /* HAVE_KVM_STAT_SUPPORT */ +extern int kvm_add_default_arch_event(int *argc, const char **argv); #endif /* __PERF_KVM_STAT_H */ -- cgit v1.2.3-59-g8ed1b From 2bff2b828502b5e5d5ea5a52643d3542053df03f Mon Sep 17 00:00:00 2001 From: Anju T Sudhakar Date: Thu, 18 Jul 2019 23:47:49 +0530 Subject: perf kvm stat: Set 'trace_cycles' as default event for 'perf kvm record' in powerpc Use 'trace_imc/trace_cycles' as the default event for 'perf kvm record' in powerpc. Signed-off-by: Anju T Sudhakar Reviewed-by: Ravi Bangoria Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linuxppc-dev@lists.ozlabs.org Link: http://lore.kernel.org/lkml/20190718181749.30612-3-anju@linux.vnet.ibm.com [ Add missing pmu.h header, needed because this patch uses pmu_have_event() ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/powerpc/util/kvm-stat.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/powerpc/util/kvm-stat.c b/tools/perf/arch/powerpc/util/kvm-stat.c index ec5b771029e4..9cc1c4a9dec4 100644 --- a/tools/perf/arch/powerpc/util/kvm-stat.c +++ b/tools/perf/arch/powerpc/util/kvm-stat.c @@ -5,6 +5,7 @@ #include "util/debug.h" #include "util/evsel.h" #include "util/evlist.h" +#include "util/pmu.h" #include "book3s_hv_exits.h" #include "book3s_hcalls.h" @@ -177,8 +178,9 @@ int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused) /* * Incase of powerpc architecture, pmu registers are programmable * by guest kernel. So monitoring guest via host may not provide - * valid samples. It is better to fail the "perf kvm record" - * with default "cycles" event to monitor guest in powerpc. + * valid samples with default 'cycles' event. It is better to use + * 'trace_imc/trace_cycles' event for guest profiling, since it + * can track the guest instruction pointer in the trace-record. * * Function to parse the arguments and return appropriate values. */ @@ -202,8 +204,14 @@ int kvm_add_default_arch_event(int *argc, const char **argv) parse_options(j, tmp, event_options, NULL, PARSE_OPT_KEEP_UNKNOWN); if (!event) { - free(tmp); - return -EINVAL; + if (pmu_have_event("trace_imc", "trace_cycles")) { + argv[j++] = strdup("-e"); + argv[j++] = strdup("trace_imc/trace_cycles/"); + *argc += 2; + } else { + free(tmp); + return -EINVAL; + } } free(tmp); -- cgit v1.2.3-59-g8ed1b From b117b9b48b24cbb090dd3844b563b464d60a6278 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 5 Sep 2019 11:09:24 +0200 Subject: perf tests: Fix static build test Disable the potentional shared library features, which breaks static build if they are enabled and detected: jvmti and vdso libraries. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190905090924.GA1949@krava Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/make | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/tests/make b/tools/perf/tests/make index 6b3afed5d910..c850d1664c56 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make @@ -100,7 +100,7 @@ make_install_info := install-info make_install_pdf := install-pdf make_install_prefix := install prefix=/tmp/krava make_install_prefix_slash := install prefix=/tmp/krava/ -make_static := LDFLAGS=-static +make_static := LDFLAGS=-static NO_PERF_READ_VDSO32=1 NO_PERF_READ_VDSOX32=1 NO_JVMTI=1 # all the NO_* variable combined make_minimal := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 -- cgit v1.2.3-59-g8ed1b From 7b678ccdf5f608c408e1368e525ed191ca456bcf Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 20 Sep 2019 14:40:30 -0300 Subject: tools headers uapi: Sync prctl.h with the kernel sources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To get the changes in: 63f0c6037965 ("arm64: Introduce prctl() options to control the tagged user addresses ABI") that introduces prctl options that then automagically gets catched by the prctl cmd table generator, and thus supported in the 'perf trace' prctl beautifier for the 'option' argument: $ tools/perf/trace/beauty/prctl_option.sh > after $ diff -u before after --- before 2019-09-20 14:38:41.386720870 -0300 +++ after 2019-09-20 14:40:02.583990802 -0300 @@ -49,6 +49,8 @@ [52] = "GET_SPECULATION_CTRL", [53] = "SET_SPECULATION_CTRL", [54] = "PAC_RESET_KEYS", + [55] = "SET_TAGGED_ADDR_CTRL", + [56] = "GET_TAGGED_ADDR_CTRL", }; static const char *prctl_set_mm_options[] = { [1] = "START_CODE", $ For now just the translation of 55 and 56 to the respecting strings are done, more work needed to allow for filters to be used using strings. This, for instance, already works: # perf record -e syscalls:sys_enter_close --filter="fd==4" # perf script | head -5 gpm 1018 [006] 21327.171436: syscalls:sys_enter_close: fd: 0x00000004 gpm 1018 [006] 21329.171583: syscalls:sys_enter_close: fd: 0x00000004 bash 4882 [002] 21330.785496: syscalls:sys_enter_close: fd: 0x00000004 bash 20672 [001] 21330.785719: syscalls:sys_enter_close: fd: 0x00000004 find 20672 [001] 21330.789082: syscalls:sys_enter_close: fd: 0x00000004 # perf record -e syscalls:sys_enter_close --filter="fd>=4" ^C[ perf record: Woken up 1 times to write data ] # perf script | head -5 gpm 1018 [005] 21401.178501: syscalls:sys_enter_close: fd: 0x00000004 gsd-housekeepin 2287 [006] 21402.225365: syscalls:sys_enter_close: fd: 0x0000000b gsd-housekeepin 2287 [006] 21402.226234: syscalls:sys_enter_close: fd: 0x0000000b gsd-housekeepin 2287 [006] 21402.227255: syscalls:sys_enter_close: fd: 0x0000000b gsd-housekeepin 2287 [006] 21402.228088: syscalls:sys_enter_close: fd: 0x0000000b # Being able to pass something like: # perf record -e syscalls:sys_enter_prctl --filter="option=*TAGGED_ADDR*" Should be easy enough, first using tracepoint filters, then via the augmented_raw_syscalls.c BPF method. This addresses this perf build warning: Warning: Kernel ABI header at 'tools/include/uapi/linux/prctl.h' differs from latest version at 'include/uapi/linux/prctl.h' diff -u tools/include/uapi/linux/prctl.h include/uapi/linux/prctl.h Cc: Adrian Hunter Cc: Brendan Gregg Cc: Catalin Marinas Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Cc: Will Deacon Link: https://lkml.kernel.org/n/tip-y8u8kvflooyo9x0if1g3jska@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/linux/prctl.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/include/uapi/linux/prctl.h b/tools/include/uapi/linux/prctl.h index 094bb03b9cc2..7da1b37b27aa 100644 --- a/tools/include/uapi/linux/prctl.h +++ b/tools/include/uapi/linux/prctl.h @@ -181,7 +181,7 @@ struct prctl_mm_map { #define PR_GET_THP_DISABLE 42 /* - * Tell the kernel to start/stop helping userspace manage bounds tables. + * No longer implemented, but left here to ensure the numbers stay reserved: */ #define PR_MPX_ENABLE_MANAGEMENT 43 #define PR_MPX_DISABLE_MANAGEMENT 44 @@ -229,4 +229,9 @@ struct prctl_mm_map { # define PR_PAC_APDBKEY (1UL << 3) # define PR_PAC_APGAKEY (1UL << 4) +/* Tagged user address controls for arm64 */ +#define PR_SET_TAGGED_ADDR_CTRL 55 +#define PR_GET_TAGGED_ADDR_CTRL 56 +# define PR_TAGGED_ADDR_ENABLE (1UL << 0) + #endif /* _LINUX_PRCTL_H */ -- cgit v1.2.3-59-g8ed1b From 9846f1366489e1a30d871a5c3198b14394365be7 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 20 Sep 2019 14:52:24 -0300 Subject: tools uapi asm-generic: Sync unistd.h with the kernel sources To pick the change from: 78e05972c5e6 ("ipc: fix semtimedop for generic 32-bit architectures") Which doesn't trigger any change in tooling and silences this perf build warning: Warning: Kernel ABI header at 'tools/include/uapi/asm-generic/unistd.h' differs from latest version at 'include/uapi/asm-generic/unistd.h' diff -u tools/include/uapi/asm-generic/unistd.h include/uapi/asm-generic/unistd.h Cc: Adrian Hunter Cc: Arnd Bergmann Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-hpnjuyjzoudltqe7dvbokqdt@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/asm-generic/unistd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/include/uapi/asm-generic/unistd.h b/tools/include/uapi/asm-generic/unistd.h index 1be0e798e362..1fc8faa6e973 100644 --- a/tools/include/uapi/asm-generic/unistd.h +++ b/tools/include/uapi/asm-generic/unistd.h @@ -569,7 +569,7 @@ __SYSCALL(__NR_semget, sys_semget) __SC_COMP(__NR_semctl, sys_semctl, compat_sys_semctl) #if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32 #define __NR_semtimedop 192 -__SC_COMP(__NR_semtimedop, sys_semtimedop, sys_semtimedop_time32) +__SC_3264(__NR_semtimedop, sys_semtimedop_time32, sys_semtimedop) #endif #define __NR_semop 193 __SYSCALL(__NR_semop, sys_semop) -- cgit v1.2.3-59-g8ed1b From 761830a03c5c99fc0a7142e16cf0811cb68bd7af Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 20 Sep 2019 14:56:47 -0300 Subject: tools arch x86 uapi: Synch asm/unistd.h with the kernel sources To pick up the change in: 45e29d119e99 ("x86/syscalls: Make __X32_SYSCALL_BIT be unsigned long") That doesn't trigger any changes in tooling and silences this perf build warning: Warning: Kernel ABI header at 'tools/arch/x86/include/uapi/asm/unistd.h' differs from latest version at 'arch/x86/include/uapi/asm/unistd.h' diff -u tools/arch/x86/include/uapi/asm/unistd.h arch/x86/include/uapi/asm/unistd.h Cc: Adrian Hunter Cc: Andy Lutomirski Cc: Jiri Olsa Cc: Namhyung Kim Cc: Thomas Gleixner Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/x86/include/uapi/asm/unistd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/arch/x86/include/uapi/asm/unistd.h b/tools/arch/x86/include/uapi/asm/unistd.h index 30d7d04d72d6..196fdd02b8b1 100644 --- a/tools/arch/x86/include/uapi/asm/unistd.h +++ b/tools/arch/x86/include/uapi/asm/unistd.h @@ -3,7 +3,7 @@ #define _UAPI_ASM_X86_UNISTD_H /* x32 syscall flag bit */ -#define __X32_SYSCALL_BIT 0x40000000 +#define __X32_SYSCALL_BIT 0x40000000UL #ifndef __KERNEL__ # ifdef __i386__ -- cgit v1.2.3-59-g8ed1b From 40f1c039c7c6de913ee04eac585102e2fce7f6f7 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 20 Sep 2019 15:00:49 -0300 Subject: tools arch x86: Sync asm/cpufeatures.h with the kernel sources To pick up the changes from: b4dd4f6e3648 ("x86/vmware: Add a header file for hypercall definitions") f36cf386e3fe ("x86/speculation/swapgs: Exclude ATOMs from speculation through SWAPGS") be261ffce6f1 ("x86: Remove X86_FEATURE_MFENCE_RDTSC") 018ebca8bd70 ("x86/cpufeatures: Enable a new AVX512 CPU feature") These don't cause any changes in tooling, just silences this perf build warning: Warning: Kernel ABI header at 'tools/arch/x86/include/asm/cpufeatures.h' differs from latest version at 'arch/x86/include/asm/cpufeatures.h' diff -u tools/arch/x86/include/asm/cpufeatures.h arch/x86/include/asm/cpufeatures.h To clarify, updating those files cause these bits of tools/perf to rebuild: CC /tmp/build/perf/bench/mem-memcpy-x86-64-asm.o CC /tmp/build/perf/bench/mem-memset-x86-64-asm.o INSTALL GTK UI LD /tmp/build/perf/bench/perf-in.o Those use just: $ grep FEATURE tools/arch/x86/lib/mem*.S tools/arch/x86/lib/memcpy_64.S: ALTERNATIVE_2 "jmp memcpy_orig", "", X86_FEATURE_REP_GOOD, \ tools/arch/x86/lib/memcpy_64.S: "jmp memcpy_erms", X86_FEATURE_ERMS tools/arch/x86/lib/memset_64.S: ALTERNATIVE_2 "jmp memset_orig", "", X86_FEATURE_REP_GOOD, \ tools/arch/x86/lib/memset_64.S: "jmp memset_erms", X86_FEATURE_ERMS $ I.e. none of the feature defines added/removed by the patches above. Cc: Adrian Hunter Cc: Borislav Petkov Cc: Gayatri Kammela Cc: Jiri Olsa Cc: Josh Poimboeuf Cc: Namhyung Kim Cc: Thomas Gleixner Cc: Thomas Hellstrom Link: https://lkml.kernel.org/n/tip-pq63abgknsaeov23p80d8gjv@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/x86/include/asm/cpufeatures.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h index 5171b9c7ca3e..0652d3eed9bd 100644 --- a/tools/arch/x86/include/asm/cpufeatures.h +++ b/tools/arch/x86/include/asm/cpufeatures.h @@ -231,6 +231,8 @@ #define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer VMMCALL to VMCALL */ #define X86_FEATURE_XENPV ( 8*32+16) /* "" Xen paravirtual guest */ #define X86_FEATURE_EPT_AD ( 8*32+17) /* Intel Extended Page Table access-dirty bit */ +#define X86_FEATURE_VMCALL ( 8*32+18) /* "" Hypervisor supports the VMCALL instruction */ +#define X86_FEATURE_VMW_VMMCALL ( 8*32+19) /* "" VMware prefers VMMCALL hypercall instruction */ /* Intel-defined CPU features, CPUID level 0x00000007:0 (EBX), word 9 */ #define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* RDFSBASE, WRFSBASE, RDGSBASE, WRGSBASE instructions*/ @@ -354,6 +356,7 @@ /* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */ #define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */ #define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */ +#define X86_FEATURE_AVX512_VP2INTERSECT (18*32+ 8) /* AVX-512 Intersect for D/Q */ #define X86_FEATURE_MD_CLEAR (18*32+10) /* VERW clears CPU buffers */ #define X86_FEATURE_TSX_FORCE_ABORT (18*32+13) /* "" TSX_FORCE_ABORT */ #define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */ -- cgit v1.2.3-59-g8ed1b From 0216234c2eed1367a318daeb9f4a97d8217412a0 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 12 Sep 2019 12:52:35 +0200 Subject: perf tools: Fix segfault in cpu_cache_level__read() We release wrong pointer on error path in cpu_cache_level__read function, leading to segfault: (gdb) r record ls Starting program: /root/perf/tools/perf/perf record ls ... [ perf record: Woken up 1 times to write data ] double free or corruption (out) Thread 1 "perf" received signal SIGABRT, Aborted. 0x00007ffff7463798 in raise () from /lib64/power9/libc.so.6 (gdb) bt #0 0x00007ffff7463798 in raise () from /lib64/power9/libc.so.6 #1 0x00007ffff7443bac in abort () from /lib64/power9/libc.so.6 #2 0x00007ffff74af8bc in __libc_message () from /lib64/power9/libc.so.6 #3 0x00007ffff74b92b8 in malloc_printerr () from /lib64/power9/libc.so.6 #4 0x00007ffff74bb874 in _int_free () from /lib64/power9/libc.so.6 #5 0x0000000010271260 in __zfree (ptr=0x7fffffffa0b0) at ../../lib/zalloc.. #6 0x0000000010139340 in cpu_cache_level__read (cache=0x7fffffffa090, cac.. #7 0x0000000010143c90 in build_caches (cntp=0x7fffffffa118, size= Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Cc: stable@vger.kernel.org: # v4.6+ Link: http://lore.kernel.org/lkml/20190912105235.10689-1-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/header.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 5722ff717777..0167f9697172 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1073,7 +1073,7 @@ static int cpu_cache_level__read(struct cpu_cache_level *cache, u32 cpu, u16 lev scnprintf(file, PATH_MAX, "%s/shared_cpu_list", path); if (sysfs__read_str(file, &cache->map, &len)) { - zfree(&cache->map); + zfree(&cache->size); zfree(&cache->type); return -1; } -- cgit v1.2.3-59-g8ed1b From 1a375ae7659ab740d4c885ea98c1659b8a6e2071 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 19 Sep 2019 12:41:10 +0900 Subject: perf probe: Skip same probe address for a given line Fix to skip making a same probe address on given line. Since a DWARF line info contains several entries for one line with different column, perf probe will make a different probe on same address if user specifies a probe point by "function:line" or "file:line". e.g. $ perf probe -D kernel_read:8 p:probe/kernel_read_L8 kernel_read+39 p:probe/kernel_read_L8_1 kernel_read+39 This skips such duplicated probe addresses. Committer testing: # uname -a Linux quaco 5.3.0+ #2 SMP Thu Sep 19 16:13:22 -03 2019 x86_64 x86_64 x86_64 GNU/Linux # Before: # perf probe -D kernel_read:8 p:probe/kernel_read _text+3115191 p:probe/kernel_read_1 _text+3115191 # After: # perf probe -D kernel_read:8 p:probe/kernel_read _text+3115191 # Signed-off-by: Masami Hiramatsu Tested-by: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lore.kernel.org/lkml/156886447061.10772.4261569305869149178.stgit@devnote2 Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/probe-finder.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'tools') diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 505905fc21c5..cd9f95e5044e 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -1245,6 +1245,17 @@ static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf, return n; } +static bool trace_event_finder_overlap(struct trace_event_finder *tf) +{ + int i; + + for (i = 0; i < tf->ntevs; i++) { + if (tf->pf.addr == tf->tevs[i].point.address) + return true; + } + return false; +} + /* Add a found probe point into trace event list */ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) { @@ -1255,6 +1266,14 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) struct perf_probe_arg *args = NULL; int ret, i; + /* + * For some reason (e.g. different column assigned to same address) + * This callback can be called with the address which already passed. + * Ignore it first. + */ + if (trace_event_finder_overlap(tf)) + return 0; + /* Check number of tevs */ if (tf->ntevs == tf->max_tevs) { pr_warning("Too many( > %d) probe point found.\n", -- cgit v1.2.3-59-g8ed1b From 9e6124d9d635957b56717f85219a88701617253f Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Mon, 16 Sep 2019 01:44:40 +0900 Subject: perf probe: Fix to clear tev->nargs in clear_probe_trace_event() Since add_probe_trace_event() can reuse tf->tevs[i] after calling clear_probe_trace_event(), this can make perf-probe crash if the 1st attempt of probe event finding fails to find an event argument, and the 2nd attempt fails to find probe point. E.g. $ perf probe -D "task_pid_nr tsk" Failed to find 'tsk' in this function. Failed to get entry address of warn_bad_vsyscall Segmentation fault (core dumped) Committer testing: After the patch: $ perf probe -D "task_pid_nr tsk" Failed to find 'tsk' in this function. Failed to get entry address of warn_bad_vsyscall Failed to get entry address of signal_fault Failed to get entry address of show_signal Failed to get entry address of umip_printk Failed to get entry address of __bad_area_nosemaphore Failed to get entry address of sock_set_timeout Failed to get entry address of tcp_recvmsg Probe point 'task_pid_nr' not found. Error: Failed to add events. $ Fixes: 092b1f0b5f9f ("perf probe: Clear probe_trace_event when add_probe_trace_event() fails") Signed-off-by: Masami Hiramatsu Tested-by: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lore.kernel.org/lkml/156856587999.25775.5145779959474477595.stgit@devnote2 Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/probe-event.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index b8e0967c5c21..91cab5f669d2 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2331,6 +2331,7 @@ void clear_probe_trace_event(struct probe_trace_event *tev) } } zfree(&tev->args); + tev->nargs = 0; } struct kprobe_blacklist_node { -- cgit v1.2.3-59-g8ed1b From 6ef81c55a2b6584cb642917f5fdf3632ef44b670 Mon Sep 17 00:00:00 2001 From: Mamatha Inamdar Date: Thu, 22 Aug 2019 12:50:49 +0530 Subject: perf session: Return error code for perf_session__new() function on failure This patch is to return error code of perf_new_session function on failure instead of NULL. Test Results: Before Fix: $ perf c2c report -input failed to open nput: No such file or directory $ echo $? 0 $ After Fix: $ perf c2c report -input failed to open nput: No such file or directory $ echo $? 254 $ Committer notes: Fix 'perf tests topology' case, where we use that TEST_ASSERT_VAL(..., session), i.e. we need to pass zero in case of failure, which was the case before when NULL was returned by perf_session__new() for failure, but now we need to negate the result of IS_ERR(session) to respect that TEST_ASSERT_VAL) expectation of zero meaning failure. Reported-by: Nageswara R Sastry Signed-off-by: Mamatha Inamdar Tested-by: Arnaldo Carvalho de Melo Tested-by: Nageswara R Sastry Acked-by: Ravi Bangoria Reviewed-by: Jiri Olsa Reviewed-by: Mukesh Ojha Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Budankov Cc: Greg Kroah-Hartman Cc: Jeremie Galarneau Cc: Kate Stewart Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Shawn Landden Cc: Song Liu Cc: Thomas Gleixner Cc: Tzvetomir Stoyanov Link: http://lore.kernel.org/lkml/20190822071223.17892.45782.stgit@localhost.localdomain Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 5 +++-- tools/perf/builtin-buildid-cache.c | 5 +++-- tools/perf/builtin-buildid-list.c | 5 +++-- tools/perf/builtin-c2c.c | 6 ++++-- tools/perf/builtin-diff.c | 9 +++++---- tools/perf/builtin-evlist.c | 5 +++-- tools/perf/builtin-inject.c | 5 +++-- tools/perf/builtin-kmem.c | 5 +++-- tools/perf/builtin-kvm.c | 9 +++++---- tools/perf/builtin-lock.c | 5 +++-- tools/perf/builtin-mem.c | 5 +++-- tools/perf/builtin-record.c | 5 +++-- tools/perf/builtin-report.c | 4 ++-- tools/perf/builtin-sched.c | 11 ++++++----- tools/perf/builtin-script.c | 9 +++++---- tools/perf/builtin-stat.c | 11 ++++++----- tools/perf/builtin-timechart.c | 5 +++-- tools/perf/builtin-top.c | 5 +++-- tools/perf/builtin-trace.c | 4 ++-- tools/perf/tests/topology.c | 5 +++-- tools/perf/util/data-convert-bt.c | 5 ++++- tools/perf/util/session.c | 15 +++++++++++---- 22 files changed, 86 insertions(+), 57 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 553c651fa0a2..8db8fc9bddef 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -40,6 +40,7 @@ #include #include #include +#include struct perf_annotate { struct perf_tool tool; @@ -584,8 +585,8 @@ int cmd_annotate(int argc, const char **argv) data.path = input_name; annotate.session = perf_session__new(&data, false, &annotate.tool); - if (annotate.session == NULL) - return -1; + if (IS_ERR(annotate.session)) + return PTR_ERR(annotate.session); annotate.has_br_stack = perf_header__has_feat(&annotate.session->header, HEADER_BRANCH_STACK); diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index 1a69eb565dc0..39efa51d7fb3 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -28,6 +28,7 @@ #include "util/util.h" #include "util/probe-file.h" #include +#include static int build_id_cache__kcore_buildid(const char *proc_dir, char *sbuildid) { @@ -422,8 +423,8 @@ int cmd_buildid_cache(int argc, const char **argv) data.force = force; session = perf_session__new(&data, false, NULL); - if (session == NULL) - return -1; + if (IS_ERR(session)) + return PTR_ERR(session); } if (symbol__init(session ? &session->header.env : NULL) < 0) diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index 5a0d8b378cb5..e3ef75583514 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -18,6 +18,7 @@ #include "util/symbol.h" #include "util/data.h" #include +#include static int sysfs__fprintf_build_id(FILE *fp) { @@ -65,8 +66,8 @@ static int perf_session__list_build_ids(bool force, bool with_hits) goto out; session = perf_session__new(&data, false, &build_id__mark_dso_hit_ops); - if (session == NULL) - return -1; + if (IS_ERR(session)) + return PTR_ERR(session); /* * We take all buildids when the file contains AUX area tracing data diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index 61aaacc2aedd..3542b6ab9813 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -2781,8 +2782,9 @@ static int perf_c2c__report(int argc, const char **argv) } session = perf_session__new(&data, 0, &c2c.tool); - if (session == NULL) { - pr_debug("No memory for session\n"); + if (IS_ERR(session)) { + err = PTR_ERR(session); + pr_debug("Error creating perf session\n"); goto out; } diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 827e4800d862..c37a78677955 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -23,6 +23,7 @@ #include "util/time-utils.h" #include "util/annotate.h" #include "util/map.h" +#include #include #include #include @@ -1153,9 +1154,9 @@ static int check_file_brstack(void) data__for_each_file(i, d) { d->session = perf_session__new(&d->data, false, &pdiff.tool); - if (!d->session) { + if (IS_ERR(d->session)) { pr_err("Failed to open %s\n", d->data.path); - return -1; + return PTR_ERR(d->session); } has_br_stack = perf_header__has_feat(&d->session->header, @@ -1185,9 +1186,9 @@ static int __cmd_diff(void) data__for_each_file(i, d) { d->session = perf_session__new(&d->data, false, &pdiff.tool); - if (!d->session) { + if (IS_ERR(d->session)) { + ret = PTR_ERR(d->session); pr_err("Failed to open %s\n", d->data.path); - ret = -1; goto out_delete; } diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c index 294494e60e48..60509ce4dd28 100644 --- a/tools/perf/builtin-evlist.c +++ b/tools/perf/builtin-evlist.c @@ -15,6 +15,7 @@ #include "util/session.h" #include "util/data.h" #include "util/debug.h" +#include static int __cmd_evlist(const char *file_name, struct perf_attr_details *details) { @@ -28,8 +29,8 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details bool has_tracepoint = false; session = perf_session__new(&data, 0, NULL); - if (session == NULL) - return -1; + if (IS_ERR(session)) + return PTR_ERR(session); evlist__for_each_entry(session->evlist, pos) { perf_evsel__fprintf(pos, details, stdout); diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 23a76cf3846f..372ecb3e2c06 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -23,6 +23,7 @@ #include "util/symbol.h" #include "util/synthetic-events.h" #include "util/thread.h" +#include #include @@ -835,8 +836,8 @@ int cmd_inject(int argc, const char **argv) data.path = inject.input_name; inject.session = perf_session__new(&data, true, &inject.tool); - if (inject.session == NULL) - return -1; + if (IS_ERR(inject.session)) + return PTR_ERR(inject.session); if (zstd_init(&(inject.session->zstd_data), 0) < 0) pr_warning("Decompression initialization failed.\n"); diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index b5682beaad72..1e61e353f579 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -14,6 +14,7 @@ #include "util/tool.h" #include "util/callchain.h" #include "util/time-utils.h" +#include #include #include @@ -1956,8 +1957,8 @@ int cmd_kmem(int argc, const char **argv) data.path = input_name; kmem_session = session = perf_session__new(&data, false, &perf_kmem); - if (session == NULL) - return -1; + if (IS_ERR(session)) + return PTR_ERR(session); ret = -1; diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 6e3e36658900..c4b22e1b0a40 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -1091,9 +1092,9 @@ static int read_events(struct perf_kvm_stat *kvm) kvm->tool = eops; kvm->session = perf_session__new(&file, false, &kvm->tool); - if (!kvm->session) { + if (IS_ERR(kvm->session)) { pr_err("Initializing perf session failed\n"); - return -1; + return PTR_ERR(kvm->session); } symbol__init(&kvm->session->header.env); @@ -1446,8 +1447,8 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, * perf session */ kvm->session = perf_session__new(&data, false, &kvm->tool); - if (kvm->session == NULL) { - err = -1; + if (IS_ERR(kvm->session)) { + err = PTR_ERR(kvm->session); goto out; } kvm->session->evlist = kvm->evlist; diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 4c2b7f437cdf..474dfd59d7eb 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -30,6 +30,7 @@ #include #include #include +#include static struct perf_session *session; @@ -872,9 +873,9 @@ static int __cmd_report(bool display_info) }; session = perf_session__new(&data, false, &eops); - if (!session) { + if (IS_ERR(session)) { pr_err("Initializing perf session failed\n"); - return -1; + return PTR_ERR(session); } symbol__init(&session->header.env); diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 27d2bde943a8..a13f5817d6fc 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -17,6 +17,7 @@ #include "util/dso.h" #include "util/map.h" #include "util/symbol.h" +#include #define MEM_OPERATION_LOAD 0x1 #define MEM_OPERATION_STORE 0x2 @@ -249,8 +250,8 @@ static int report_raw_events(struct perf_mem *mem) struct perf_session *session = perf_session__new(&data, false, &mem->tool); - if (session == NULL) - return -1; + if (IS_ERR(session)) + return PTR_ERR(session); if (mem->cpu_list) { ret = perf_session__cpu_bitmap(session, mem->cpu_list, diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 4bd11c918e73..3f66a49a997f 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -1354,9 +1355,9 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) } session = perf_session__new(data, false, tool); - if (session == NULL) { + if (IS_ERR(session)) { pr_err("Perf session creation failed.\n"); - return -1; + return PTR_ERR(session); } fd = perf_data__fd(data); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 3047e5169d9d..aae0e57c60fb 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -1269,8 +1269,8 @@ int cmd_report(int argc, const char **argv) repeat: session = perf_session__new(&data, false, &report.tool); - if (session == NULL) - return -1; + if (IS_ERR(session)) + return PTR_ERR(session); ret = evswitch__init(&report.evswitch, session->evlist, stderr); if (ret) diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index f0b828c201cc..079e67a36904 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -1797,9 +1798,9 @@ static int perf_sched__read_events(struct perf_sched *sched) int rc = -1; session = perf_session__new(&data, false, &sched->tool); - if (session == NULL) { - pr_debug("No Memory for session\n"); - return -1; + if (IS_ERR(session)) { + pr_debug("Error creating perf session"); + return PTR_ERR(session); } symbol__init(&session->header.env); @@ -2989,8 +2990,8 @@ static int perf_sched__timehist(struct perf_sched *sched) symbol_conf.use_callchain = sched->show_callchain; session = perf_session__new(&data, false, &sched->tool); - if (session == NULL) - return -ENOMEM; + if (IS_ERR(session)) + return PTR_ERR(session); evlist = session->evlist; diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index e079b34201f2..a17a9306bdf6 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -52,6 +52,7 @@ #include #include #include +#include #include "util/record.h" #include "util/util.h" #include "perf.h" @@ -3083,8 +3084,8 @@ int find_scripts(char **scripts_array, char **scripts_path_array, int num, int i = 0; session = perf_session__new(&data, false, NULL); - if (!session) - return -1; + if (IS_ERR(session)) + return PTR_ERR(session); snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path()); @@ -3754,8 +3755,8 @@ int cmd_script(int argc, const char **argv) } session = perf_session__new(&data, false, &script.tool); - if (session == NULL) - return -1; + if (IS_ERR(session)) + return PTR_ERR(session); if (header || header_only) { script.tool.show_feat_hdr = SHOW_FEAT_HEADER; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 60cdd383af81..f7d13326b830 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -83,6 +83,7 @@ #include #include #include +#include #include #include @@ -1436,9 +1437,9 @@ static int __cmd_record(int argc, const char **argv) } session = perf_session__new(data, false, NULL); - if (session == NULL) { - pr_err("Perf session creation failed.\n"); - return -1; + if (IS_ERR(session)) { + pr_err("Perf session creation failed\n"); + return PTR_ERR(session); } init_features(session); @@ -1635,8 +1636,8 @@ static int __cmd_report(int argc, const char **argv) perf_stat.data.mode = PERF_DATA_MODE_READ; session = perf_session__new(&perf_stat.data, false, &perf_stat.tool); - if (session == NULL) - return -1; + if (IS_ERR(session)) + return PTR_ERR(session); perf_stat.session = session; stat_config.output = stderr; diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index e0e822695a29..9e84fae9b096 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -35,6 +35,7 @@ #include "util/tool.h" #include "util/data.h" #include "util/debug.h" +#include #ifdef LACKS_OPEN_MEMSTREAM_PROTOTYPE FILE *open_memstream(char **ptr, size_t *sizeloc); @@ -1601,8 +1602,8 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name) &tchart->tool); int ret = -EINVAL; - if (session == NULL) - return -1; + if (IS_ERR(session)) + return PTR_ERR(session); symbol__init(&session->header.env); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index b052470f89b4..8da3c939e6b0 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -77,6 +77,7 @@ #include #include #include +#include #include @@ -1672,8 +1673,8 @@ int cmd_top(int argc, const char **argv) } top.session = perf_session__new(NULL, false, NULL); - if (top.session == NULL) { - status = -1; + if (IS_ERR(top.session)) { + status = PTR_ERR(top.session); goto out_delete_evlist; } diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index f0f735093e21..a292658b4232 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3585,8 +3585,8 @@ static int trace__replay(struct trace *trace) trace->multiple_threads = true; session = perf_session__new(&data, false, &trace->tool); - if (session == NULL) - return -1; + if (IS_ERR(session)) + return PTR_ERR(session); if (trace->opts.target.pid) symbol_conf.pid_list_str = strdup(trace->opts.target.pid); diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index 7d845d913d7d..4a800499d7c3 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -8,6 +8,7 @@ #include "session.h" #include "evlist.h" #include "debug.h" +#include #define TEMPL "/tmp/perf-test-XXXXXX" #define DATA_SIZE 10 @@ -39,7 +40,7 @@ static int session_write_header(char *path) }; session = perf_session__new(&data, false, NULL); - TEST_ASSERT_VAL("can't get session", session); + TEST_ASSERT_VAL("can't get session", !IS_ERR(session)); session->evlist = perf_evlist__new_default(); TEST_ASSERT_VAL("can't get evlist", session->evlist); @@ -70,7 +71,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map) int i; session = perf_session__new(&data, false, NULL); - TEST_ASSERT_VAL("can't get session", session); + TEST_ASSERT_VAL("can't get session", !IS_ERR(session)); /* On platforms with large numbers of CPUs process_cpu_topology() * might issue an error while reading the perf.data file section diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 0c268449959c..dbc772bfb04e 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -30,6 +30,7 @@ #include "machine.h" #include "config.h" #include +#include #define pr_N(n, fmt, ...) \ eprintf(n, debug_data_convert, fmt, ##__VA_ARGS__) @@ -1619,8 +1620,10 @@ int bt_convert__perf2ctf(const char *input, const char *path, err = -1; /* perf.data session */ session = perf_session__new(&data, 0, &c.tool); - if (!session) + if (IS_ERR(session)) { + err = PTR_ERR(session); goto free_writer; + } if (c.queue_size) { ordered_events__set_alloc_size(&session->ordered_events, diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 58b5bc34ba12..a621c73bad42 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -34,6 +34,7 @@ #include "../perf.h" #include "arch/common.h" #include +#include #ifdef HAVE_ZSTD_SUPPORT static int perf_session__process_compressed_event(struct perf_session *session, @@ -187,6 +188,7 @@ static int ordered_events__deliver_event(struct ordered_events *oe, struct perf_session *perf_session__new(struct perf_data *data, bool repipe, struct perf_tool *tool) { + int ret = -ENOMEM; struct perf_session *session = zalloc(sizeof(*session)); if (!session) @@ -201,13 +203,15 @@ struct perf_session *perf_session__new(struct perf_data *data, perf_env__init(&session->header.env); if (data) { - if (perf_data__open(data)) + ret = perf_data__open(data); + if (ret < 0) goto out_delete; session->data = data; if (perf_data__is_read(data)) { - if (perf_session__open(session) < 0) + ret = perf_session__open(session); + if (ret < 0) goto out_delete; /* @@ -222,8 +226,11 @@ struct perf_session *perf_session__new(struct perf_data *data, perf_evlist__init_trace_event_sample_raw(session->evlist); /* Open the directory data. */ - if (data->is_dir && perf_data__open_dir(data)) + if (data->is_dir) { + ret = perf_data__open_dir(data); + if (ret) goto out_delete; + } } } else { session->machines.host.env = &perf_env; @@ -256,7 +263,7 @@ struct perf_session *perf_session__new(struct perf_data *data, out_delete: perf_session__delete(session); out: - return NULL; + return ERR_PTR(ret); } static void perf_session__delete_threads(struct perf_session *session) -- cgit v1.2.3-59-g8ed1b From a003365cab64b0f7988ac3ccb1da895ce0bece5e Mon Sep 17 00:00:00 2001 From: Gustavo Romero Date: Wed, 4 Sep 2019 00:55:29 -0400 Subject: powerpc/tm: Add tm-poison test Add TM selftest to check if FP or VEC register values from one process can leak into another process when both run on the same CPU. Signed-off-by: Gustavo Romero Signed-off-by: Michael Neuling Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20190904045529.23002-3-gromero@linux.vnet.ibm.com --- tools/testing/selftests/powerpc/tm/.gitignore | 1 + tools/testing/selftests/powerpc/tm/Makefile | 2 +- tools/testing/selftests/powerpc/tm/tm-poison.c | 179 +++++++++++++++++++++++++ 3 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/tm/tm-poison.c (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/tm/.gitignore b/tools/testing/selftests/powerpc/tm/.gitignore index 951fe855f7cd..98f2708d86cc 100644 --- a/tools/testing/selftests/powerpc/tm/.gitignore +++ b/tools/testing/selftests/powerpc/tm/.gitignore @@ -17,3 +17,4 @@ tm-vmx-unavail tm-unavailable tm-trap tm-sigreturn +tm-poison diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile index c0734ed0ef56..b15a1a325bd0 100644 --- a/tools/testing/selftests/powerpc/tm/Makefile +++ b/tools/testing/selftests/powerpc/tm/Makefile @@ -5,7 +5,7 @@ SIGNAL_CONTEXT_CHK_TESTS := tm-signal-context-chk-gpr tm-signal-context-chk-fpu TEST_GEN_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack \ tm-vmxcopy tm-fork tm-tar tm-tmspr tm-vmx-unavail tm-unavailable tm-trap \ $(SIGNAL_CONTEXT_CHK_TESTS) tm-sigreturn tm-signal-sigreturn-nt \ - tm-signal-context-force-tm + tm-signal-context-force-tm tm-poison top_srcdir = ../../../../.. include ../../lib.mk diff --git a/tools/testing/selftests/powerpc/tm/tm-poison.c b/tools/testing/selftests/powerpc/tm/tm-poison.c new file mode 100644 index 000000000000..977558497c16 --- /dev/null +++ b/tools/testing/selftests/powerpc/tm/tm-poison.c @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2019, Gustavo Romero, Michael Neuling, IBM Corp. + * + * This test will spawn two processes. Both will be attached to the same + * CPU (CPU 0). The child will be in a loop writing to FP register f31 and + * VMX/VEC/Altivec register vr31 a known value, called poison, calling + * sched_yield syscall after to allow the parent to switch on the CPU. + * Parent will set f31 and vr31 to 1 and in a loop will check if f31 and + * vr31 remain 1 as expected until a given timeout (2m). If the issue is + * present child's poison will leak into parent's f31 or vr31 registers, + * otherwise, poison will never leak into parent's f31 and vr31 registers. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tm.h" + +int tm_poison_test(void) +{ + int pid; + cpu_set_t cpuset; + uint64_t poison = 0xdeadbeefc0dec0fe; + uint64_t unknown = 0; + bool fail_fp = false; + bool fail_vr = false; + + SKIP_IF(!have_htm()); + + /* Attach both Child and Parent to CPU 0 */ + CPU_ZERO(&cpuset); + CPU_SET(0, &cpuset); + sched_setaffinity(0, sizeof(cpuset), &cpuset); + + pid = fork(); + if (!pid) { + /** + * child + */ + while (1) { + sched_yield(); + asm ( + "mtvsrd 31, %[poison];" // f31 = poison + "mtvsrd 63, %[poison];" // vr31 = poison + + : : [poison] "r" (poison) : ); + } + } + + /** + * parent + */ + asm ( + /* + * Set r3, r4, and f31 to known value 1 before entering + * in transaction. They won't be written after that. + */ + " li 3, 0x1 ;" + " li 4, 0x1 ;" + " mtvsrd 31, 4 ;" + + /* + * The Time Base (TB) is a 64-bit counter register that is + * independent of the CPU clock and which is incremented + * at a frequency of 512000000 Hz, so every 1.953125ns. + * So it's necessary 120s/0.000000001953125s = 61440000000 + * increments to get a 2 minutes timeout. Below we set that + * value in r5 and then use r6 to track initial TB value, + * updating TB values in r7 at every iteration and comparing it + * to r6. When r7 (current) - r6 (initial) > 61440000000 we bail + * out since for sure we spent already 2 minutes in the loop. + * SPR 268 is the TB register. + */ + " lis 5, 14 ;" + " ori 5, 5, 19996 ;" + " sldi 5, 5, 16 ;" // r5 = 61440000000 + + " mfspr 6, 268 ;" // r6 (TB initial) + "1: mfspr 7, 268 ;" // r7 (TB current) + " subf 7, 6, 7 ;" // r7 - r6 > 61440000000 ? + " cmpd 7, 5 ;" + " bgt 3f ;" // yes, exit + + /* + * Main loop to check f31 + */ + " tbegin. ;" // no, try again + " beq 1b ;" // restart if no timeout + " mfvsrd 3, 31 ;" // read f31 + " cmpd 3, 4 ;" // f31 == 1 ? + " bne 2f ;" // broken :-( + " tabort. 3 ;" // try another transaction + "2: tend. ;" // commit transaction + "3: mr %[unknown], 3 ;" // record r3 + + : [unknown] "=r" (unknown) + : + : "cr0", "r3", "r4", "r5", "r6", "r7", "vs31" + + ); + + /* + * On leak 'unknown' will contain 'poison' value from child, + * otherwise (no leak) 'unknown' will contain the same value + * as r3 before entering in transactional mode, i.e. 0x1. + */ + fail_fp = unknown != 0x1; + if (fail_fp) + printf("Unknown value %#"PRIx64" leaked into f31!\n", unknown); + else + printf("Good, no poison or leaked value into FP registers\n"); + + asm ( + /* + * Set r3, r4, and vr31 to known value 1 before entering + * in transaction. They won't be written after that. + */ + " li 3, 0x1 ;" + " li 4, 0x1 ;" + " mtvsrd 63, 4 ;" + + " lis 5, 14 ;" + " ori 5, 5, 19996 ;" + " sldi 5, 5, 16 ;" // r5 = 61440000000 + + " mfspr 6, 268 ;" // r6 (TB initial) + "1: mfspr 7, 268 ;" // r7 (TB current) + " subf 7, 6, 7 ;" // r7 - r6 > 61440000000 ? + " cmpd 7, 5 ;" + " bgt 3f ;" // yes, exit + + /* + * Main loop to check vr31 + */ + " tbegin. ;" // no, try again + " beq 1b ;" // restart if no timeout + " mfvsrd 3, 63 ;" // read vr31 + " cmpd 3, 4 ;" // vr31 == 1 ? + " bne 2f ;" // broken :-( + " tabort. 3 ;" // try another transaction + "2: tend. ;" // commit transaction + "3: mr %[unknown], 3 ;" // record r3 + + : [unknown] "=r" (unknown) + : + : "cr0", "r3", "r4", "r5", "r6", "r7", "vs63" + + ); + + /* + * On leak 'unknown' will contain 'poison' value from child, + * otherwise (no leak) 'unknown' will contain the same value + * as r3 before entering in transactional mode, i.e. 0x1. + */ + fail_vr = unknown != 0x1; + if (fail_vr) + printf("Unknown value %#"PRIx64" leaked into vr31!\n", unknown); + else + printf("Good, no poison or leaked value into VEC registers\n"); + + kill(pid, SIGKILL); + + return (fail_fp | fail_vr); +} + +int main(int argc, char *argv[]) +{ + /* Test completes in about 4m */ + test_harness_set_timeout(250); + return test_harness(tm_poison_test, "tm_poison_test"); +} -- cgit v1.2.3-59-g8ed1b From 0360894a05ed52be268e3c4d40b2df9d94975fa6 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Tue, 17 Sep 2019 10:30:21 -0700 Subject: selftests: Update fib_tests to handle missing ping6 Some distributions (e.g., debian buster) do not install ping6. Re-use the hook in pmtu.sh to detect this and fallback to ping. Fixes: a0e11da78f48 ("fib_tests: Add tests for metrics on routes") Signed-off-by: David Ahern Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/fib_tests.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh index 4465fc2dae14..cba83a12da82 100755 --- a/tools/testing/selftests/net/fib_tests.sh +++ b/tools/testing/selftests/net/fib_tests.sh @@ -17,6 +17,8 @@ PAUSE=no IP="ip -netns ns1" NS_EXEC="ip netns exec ns1" +which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping) + log_test() { local rc=$1 @@ -1086,7 +1088,7 @@ ipv6_route_metrics_test() log_test $rc 0 "Multipath route with mtu metric" $IP -6 ro add 2001:db8:104::/64 via 2001:db8:101::2 mtu 1300 - run_cmd "ip netns exec ns1 ping6 -w1 -c1 -s 1500 2001:db8:104::1" + run_cmd "ip netns exec ns1 ${ping6} -w1 -c1 -s 1500 2001:db8:104::1" log_test $? 0 "Using route with mtu metric" run_cmd "$IP -6 ro add 2001:db8:114::/64 via 2001:db8:101::2 congctl lock foo" -- cgit v1.2.3-59-g8ed1b From e84622ce24482f6e9c1bf29d3bdd556eb587ff41 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Tue, 17 Sep 2019 10:30:35 -0700 Subject: selftests: Update fib_nexthop_multiprefix to handle missing ping6 Some distributions (e.g., debian buster) do not install ping6. Re-use the hook in pmtu.sh to detect this and fallback to ping. Fixes: 735ab2f65dce ("selftests: Add test with multiple prefixes using single nexthop") Signed-off-by: David Ahern Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/fib_nexthop_multiprefix.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/net/fib_nexthop_multiprefix.sh b/tools/testing/selftests/net/fib_nexthop_multiprefix.sh index e6828732843e..9dc35a16e415 100755 --- a/tools/testing/selftests/net/fib_nexthop_multiprefix.sh +++ b/tools/testing/selftests/net/fib_nexthop_multiprefix.sh @@ -15,6 +15,8 @@ PAUSE_ON_FAIL=no VERBOSE=0 +which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping) + ################################################################################ # helpers @@ -200,7 +202,7 @@ validate_v6_exception() local rc if [ ${ping_sz} != "0" ]; then - run_cmd ip netns exec h0 ping6 -s ${ping_sz} -c5 -w5 ${dst} + run_cmd ip netns exec h0 ${ping6} -s ${ping_sz} -c5 -w5 ${dst} fi if [ "$VERBOSE" = "1" ]; then @@ -243,7 +245,7 @@ do run_cmd taskset -c ${c} ip netns exec h0 ping -c1 -w1 172.16.10${i}.1 [ $? -ne 0 ] && printf "\nERROR: ping to h${i} failed\n" && ret=1 - run_cmd taskset -c ${c} ip netns exec h0 ping6 -c1 -w1 2001:db8:10${i}::1 + run_cmd taskset -c ${c} ip netns exec h0 ${ping6} -c1 -w1 2001:db8:10${i}::1 [ $? -ne 0 ] && printf "\nERROR: ping6 to h${i} failed\n" && ret=1 [ $ret -ne 0 ] && break -- cgit v1.2.3-59-g8ed1b From 4ec8d984895fef43abfc896c8a3346aca7a66649 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Fri, 20 Sep 2019 16:03:56 -0700 Subject: perf record: Fix priv level with branch sampling for paranoid=2 Now that the default perf_events paranoid level is set to 2, a regular user cannot monitor kernel level activity anymore. As such, with the following cmdline: $ perf record -e cycles date The perf tool first tries cycles:uk but then falls back to cycles:u as can be seen in the perf report --header-only output: cmdline : /export/hda3/tmp/perf.tip record -e cycles ls event : name = cycles:u, , id = { 436186, ... } This is okay as long as there is way to learn the priv level was changed internally by the tool. But consider a similar example: $ perf record -b -e cycles date Error: You may not have permission to collect stats. Consider tweaking /proc/sys/kernel/perf_event_paranoid, which controls use of the performance events system by unprivileged users (without CAP_SYS_ADMIN). ... Why is that treated differently given that the branch sampling inherits the priv level of the first event in this case, i.e., cycles:u? It turns out that the branch sampling code is more picky and also checks exclude_hv. In the fallback path, perf record is setting exclude_kernel = 1, but it does not change exclude_hv. This does not seem to match the restriction imposed by paranoid = 2. This patch fixes the problem by forcing exclude_hv = 1 in the fallback for paranoid=2. With this in place: $ perf record -b -e cycles date cmdline : /export/hda3/tmp/perf.tip record -b -e cycles ls event : name = cycles:u, , id = { 436847, ... } And the command succeeds as expected. V2 fix a white space. Committer testing: After aplying the patch we get: [acme@quaco ~]$ perf record -b -e cycles date WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted, check /proc/sys/kernel/kptr_restrict and /proc/sys/kernel/perf_event_paranoid. Samples in kernel functions may not be resolved if a suitable vmlinux file is not found in the buildid cache or in the vmlinux path. Samples in kernel modules won't be resolved at all. If some relocation was applied (e.g. kexec) symbols may be misresolved even with a suitable vmlinux or kallsyms file. Mon 23 Sep 2019 11:00:59 AM -03 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.005 MB perf.data (14 samples) ] [acme@quaco ~]$ perf evlist -v cycles:u: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD|BRANCH_STACK, read_format: ID, disabled: 1, inherit: 1, exclude_kernel: 1, exclude_hv: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, ksymbol: 1, bpf_event: 1, branch_sample_type: ANY [acme@quaco ~]$ That warning about restricted kernel maps will be suppressed in a follow up patch, as perf_event_attr.exclude_kernel is set, i.e. no samples for the kernel will be taken and thus no need for those maps. Signed-off-by: Stephane Eranian Acked-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190920230356.41420-1-eranian@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 8e335d168503..502bc3d50e0d 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2535,9 +2535,11 @@ bool perf_evsel__fallback(struct evsel *evsel, int err, if (evsel->name) free(evsel->name); evsel->name = new_name; - scnprintf(msg, msgsize, -"kernel.perf_event_paranoid=%d, trying to fall back to excluding kernel samples", paranoid); + scnprintf(msg, msgsize, "kernel.perf_event_paranoid=%d, trying " + "to fall back to excluding kernel and hypervisor " + " samples", paranoid); evsel->core.attr.exclude_kernel = 1; + evsel->core.attr.exclude_hv = 1; return true; } -- cgit v1.2.3-59-g8ed1b From c8b567c8a96a35acff746b1eef6f859e2a9fc195 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 23 Sep 2019 11:07:29 -0300 Subject: perf record: Move restricted maps check to after a possible fallback to not collect kernel samples Before: [acme@quaco ~]$ perf record -b -e cycles date WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted, check /proc/sys/kernel/kptr_restrict and /proc/sys/kernel/perf_event_paranoid. Samples in kernel functions may not be resolved if a suitable vmlinux file is not found in the buildid cache or in the vmlinux path. Samples in kernel modules won't be resolved at all. If some relocation was applied (e.g. kexec) symbols may be misresolved even with a suitable vmlinux or kallsyms file. Mon 23 Sep 2019 11:00:59 AM -03 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.005 MB perf.data (14 samples) ] [acme@quaco ~]$ But we did a fallback and exclude_kernel was set, so no need for resolving kernel symbols: $ perf evlist -v cycles:u: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD|BRANCH_STACK, read_format: ID, disabled: 1, inherit: 1, exclude_kernel: 1, exclude_hv: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, ksymbol: 1, bpf_event: 1, branch_sample_type: ANY $ After: [acme@quaco ~]$ perf record -b -e cycles date Mon 23 Sep 2019 11:07:18 AM -03 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.007 MB perf.data (16 samples) ] [acme@quaco ~]$ perf evlist -v cycles:u: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|PERIOD|BRANCH_STACK, read_format: ID, disabled: 1, inherit: 1, exclude_kernel: 1, exclude_hv: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, ksymbol: 1, bpf_event: 1, branch_sample_type: ANY [acme@quaco ~]$ No needless warning is emitted. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Stephane Eranian Link: https://lkml.kernel.org/n/tip-5yqnr8xcqwhr15xktj2097ac@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 3f66a49a997f..1e1f97139f16 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -788,6 +788,17 @@ try_again: pos->supported = true; } + if (symbol_conf.kptr_restrict && !perf_evlist__exclude_kernel(evlist)) { + pr_warning( +"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n" +"check /proc/sys/kernel/kptr_restrict and /proc/sys/kernel/perf_event_paranoid.\n\n" +"Samples in kernel functions may not be resolved if a suitable vmlinux\n" +"file is not found in the buildid cache or in the vmlinux path.\n\n" +"Samples in kernel modules won't be resolved at all.\n\n" +"If some relocation was applied (e.g. kexec) symbols may be misresolved\n" +"even with a suitable vmlinux or kallsyms file.\n\n"); + } + if (perf_evlist__apply_filters(evlist, &pos)) { pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n", pos->filter, perf_evsel__name(pos), errno, @@ -2364,16 +2375,6 @@ int cmd_record(int argc, const char **argv) err = -ENOMEM; - if (symbol_conf.kptr_restrict && !perf_evlist__exclude_kernel(rec->evlist)) - pr_warning( -"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n" -"check /proc/sys/kernel/kptr_restrict and /proc/sys/kernel/perf_event_paranoid.\n\n" -"Samples in kernel functions may not be resolved if a suitable vmlinux\n" -"file is not found in the buildid cache or in the vmlinux path.\n\n" -"Samples in kernel modules won't be resolved at all.\n\n" -"If some relocation was applied (e.g. kexec) symbols may be misresolved\n" -"even with a suitable vmlinux or kallsyms file.\n\n"); - if (rec->no_buildid_cache || rec->no_buildid) { disable_buildid_cache(); } else if (rec->switch_output.enabled) { -- cgit v1.2.3-59-g8ed1b From 88282297fff00796e81f5e67734a6afdfb31fbc4 Mon Sep 17 00:00:00 2001 From: Tycho Andersen Date: Mon, 26 Aug 2019 08:43:02 -0600 Subject: selftests/seccomp: fix build on older kernels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The seccomp selftest goes to some length to build against older kernel headers, viz. all the #ifdefs at the beginning of the file. Commit 201766a20e30 ("ptrace: add PTRACE_GET_SYSCALL_INFO request") introduces some additional macros, but doesn't do the #ifdef dance. Let's add that dance here to avoid: gcc -Wl,-no-as-needed -Wall seccomp_bpf.c -lpthread -o seccomp_bpf In file included from seccomp_bpf.c:51: seccomp_bpf.c: In function ‘tracer_ptrace’: seccomp_bpf.c:1787:20: error: ‘PTRACE_EVENTMSG_SYSCALL_ENTRY’ undeclared (first use in this function); did you mean ‘PTRACE_EVENT_CLONE’? EXPECT_EQ(entry ? PTRACE_EVENTMSG_SYSCALL_ENTRY ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../kselftest_harness.h:608:13: note: in definition of macro ‘__EXPECT’ __typeof__(_expected) __exp = (_expected); \ ^~~~~~~~~ seccomp_bpf.c:1787:2: note: in expansion of macro ‘EXPECT_EQ’ EXPECT_EQ(entry ? PTRACE_EVENTMSG_SYSCALL_ENTRY ^~~~~~~~~ seccomp_bpf.c:1787:20: note: each undeclared identifier is reported only once for each function it appears in EXPECT_EQ(entry ? PTRACE_EVENTMSG_SYSCALL_ENTRY ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../kselftest_harness.h:608:13: note: in definition of macro ‘__EXPECT’ __typeof__(_expected) __exp = (_expected); \ ^~~~~~~~~ seccomp_bpf.c:1787:2: note: in expansion of macro ‘EXPECT_EQ’ EXPECT_EQ(entry ? PTRACE_EVENTMSG_SYSCALL_ENTRY ^~~~~~~~~ seccomp_bpf.c:1788:6: error: ‘PTRACE_EVENTMSG_SYSCALL_EXIT’ undeclared (first use in this function); did you mean ‘PTRACE_EVENT_EXIT’? : PTRACE_EVENTMSG_SYSCALL_EXIT, msg); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../kselftest_harness.h:608:13: note: in definition of macro ‘__EXPECT’ __typeof__(_expected) __exp = (_expected); \ ^~~~~~~~~ seccomp_bpf.c:1787:2: note: in expansion of macro ‘EXPECT_EQ’ EXPECT_EQ(entry ? PTRACE_EVENTMSG_SYSCALL_ENTRY ^~~~~~~~~ make: *** [Makefile:12: seccomp_bpf] Error 1 [skhan@linuxfoundation.org: Fix checkpatch error in commit log] Signed-off-by: Tycho Andersen Fixes: 201766a20e30 ("ptrace: add PTRACE_GET_SYSCALL_INFO request") Acked-by: Kees Cook Signed-off-by: Shuah Khan --- tools/testing/selftests/seccomp/seccomp_bpf.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 6ef7f16c4cf5..7f8b5c8982e3 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -199,6 +199,11 @@ struct seccomp_notif_sizes { }; #endif +#ifndef PTRACE_EVENTMSG_SYSCALL_ENTRY +#define PTRACE_EVENTMSG_SYSCALL_ENTRY 1 +#define PTRACE_EVENTMSG_SYSCALL_EXIT 2 +#endif + #ifndef seccomp int seccomp(unsigned int op, unsigned int flags, void *args) { -- cgit v1.2.3-59-g8ed1b From a4864a33f56caa6592acc69a6d265f3f3dca5eae Mon Sep 17 00:00:00 2001 From: "George G. Davis" Date: Fri, 30 Aug 2019 15:32:23 -0400 Subject: selftests: watchdog: Add optional file argument Some systems have multiple watchdog devices where the first device registered is assigned to the /dev/watchdog device file. In order to test other watchdog devices, add an optional file argument for selecting non-default watchdog devices for testing. Tested-by: Eugeniu Rosca Signed-off-by: George G. Davis Signed-off-by: Shuah Khan --- tools/testing/selftests/watchdog/watchdog-test.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/watchdog/watchdog-test.c b/tools/testing/selftests/watchdog/watchdog-test.c index c2333c78cf04..6a68b486dd61 100644 --- a/tools/testing/selftests/watchdog/watchdog-test.c +++ b/tools/testing/selftests/watchdog/watchdog-test.c @@ -19,7 +19,7 @@ int fd; const char v = 'V'; -static const char sopts[] = "bdehp:t:Tn:NL"; +static const char sopts[] = "bdehp:t:Tn:NLf:"; static const struct option lopts[] = { {"bootstatus", no_argument, NULL, 'b'}, {"disable", no_argument, NULL, 'd'}, @@ -31,6 +31,7 @@ static const struct option lopts[] = { {"pretimeout", required_argument, NULL, 'n'}, {"getpretimeout", no_argument, NULL, 'N'}, {"gettimeleft", no_argument, NULL, 'L'}, + {"file", required_argument, NULL, 'f'}, {NULL, no_argument, NULL, 0x0} }; @@ -69,6 +70,8 @@ static void term(int sig) static void usage(char *progname) { printf("Usage: %s [options]\n", progname); + printf(" -f, --file Open watchdog device file\n"); + printf(" Default is /dev/watchdog\n"); printf(" -b, --bootstatus Get last boot status (Watchdog/POR)\n"); printf(" -d, --disable Turn off the watchdog timer\n"); printf(" -e, --enable Turn on the watchdog timer\n"); @@ -92,14 +95,20 @@ int main(int argc, char *argv[]) int ret; int c; int oneshot = 0; + char *file = "/dev/watchdog"; setbuf(stdout, NULL); - fd = open("/dev/watchdog", O_WRONLY); + while ((c = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) { + if (c == 'f') + file = optarg; + } + + fd = open(file, O_WRONLY); if (fd == -1) { if (errno == ENOENT) - printf("Watchdog device not enabled.\n"); + printf("Watchdog device (%s) not found.\n", file); else if (errno == EACCES) printf("Run watchdog as root.\n"); else @@ -108,6 +117,8 @@ int main(int argc, char *argv[]) exit(-1); } + optind = 0; + while ((c = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) { switch (c) { case 'b': @@ -190,6 +201,9 @@ int main(int argc, char *argv[]) else printf("WDIOC_GETTIMELEFT error '%s'\n", strerror(errno)); break; + case 'f': + /* Handled above */ + break; default: usage(argv[0]); -- cgit v1.2.3-59-g8ed1b From 861f47b07b0523f00ffb8159684e7c840390b96e Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sat, 3 Aug 2019 09:01:26 +0900 Subject: selftest/ftrace: Fix typo in trigger-snapshot.tc This patch fixes a spelling typo in trigger-snapshot.tc [skhan@linuxfoundation.org: Fix typo in commit log] Signed-off-by: Masanari Iida Acked-by: Steven Rostedt (VMware) Signed-off-by: Shuah Khan --- tools/testing/selftests/ftrace/test.d/trigger/trigger-snapshot.tc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/ftrace/test.d/trigger/trigger-snapshot.tc b/tools/testing/selftests/ftrace/test.d/trigger/trigger-snapshot.tc index 7717c0a09686..ac738500d17f 100644 --- a/tools/testing/selftests/ftrace/test.d/trigger/trigger-snapshot.tc +++ b/tools/testing/selftests/ftrace/test.d/trigger/trigger-snapshot.tc @@ -28,7 +28,7 @@ if [ -z "$FEATURE" ]; then exit_unsupported fi -echo "Test snapshot tigger" +echo "Test snapshot trigger" echo 0 > snapshot echo 1 > events/sched/sched_process_fork/enable ( echo "forked") -- cgit v1.2.3-59-g8ed1b From a54344ace273cd7fa182c287719b109cfd9e8613 Mon Sep 17 00:00:00 2001 From: "George G. Davis" Date: Fri, 30 Aug 2019 18:31:33 -0400 Subject: selftests: watchdog: cleanup whitespace in usage options Convert hard spaces to tabs in usage options. Suggested-by: Shuah Khan Signed-off-by: George G. Davis Signed-off-by: Shuah Khan --- tools/testing/selftests/watchdog/watchdog-test.c | 25 ++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/watchdog/watchdog-test.c b/tools/testing/selftests/watchdog/watchdog-test.c index 6a68b486dd61..afff120c7be6 100644 --- a/tools/testing/selftests/watchdog/watchdog-test.c +++ b/tools/testing/selftests/watchdog/watchdog-test.c @@ -70,18 +70,19 @@ static void term(int sig) static void usage(char *progname) { printf("Usage: %s [options]\n", progname); - printf(" -f, --file Open watchdog device file\n"); - printf(" Default is /dev/watchdog\n"); - printf(" -b, --bootstatus Get last boot status (Watchdog/POR)\n"); - printf(" -d, --disable Turn off the watchdog timer\n"); - printf(" -e, --enable Turn on the watchdog timer\n"); - printf(" -h, --help Print the help message\n"); - printf(" -p, --pingrate=P Set ping rate to P seconds (default %d)\n", DEFAULT_PING_RATE); - printf(" -t, --timeout=T Set timeout to T seconds\n"); - printf(" -T, --gettimeout Get the timeout\n"); - printf(" -n, --pretimeout=T Set the pretimeout to T seconds\n"); - printf(" -N, --getpretimeout Get the pretimeout\n"); - printf(" -L, --gettimeleft Get the time left until timer expires\n"); + printf(" -f, --file\t\tOpen watchdog device file\n"); + printf("\t\t\tDefault is /dev/watchdog\n"); + printf(" -b, --bootstatus\tGet last boot status (Watchdog/POR)\n"); + printf(" -d, --disable\t\tTurn off the watchdog timer\n"); + printf(" -e, --enable\t\tTurn on the watchdog timer\n"); + printf(" -h, --help\t\tPrint the help message\n"); + printf(" -p, --pingrate=P\tSet ping rate to P seconds (default %d)\n", + DEFAULT_PING_RATE); + printf(" -t, --timeout=T\tSet timeout to T seconds\n"); + printf(" -T, --gettimeout\tGet the timeout\n"); + printf(" -n, --pretimeout=T\tSet the pretimeout to T seconds\n"); + printf(" -N, --getpretimeout\tGet the pretimeout\n"); + printf(" -L, --gettimeleft\tGet the time left until timer expires\n"); printf("\n"); printf("Parameters are parsed left-to-right in real-time.\n"); printf("Example: %s -d -t 10 -p 5 -e\n", progname); -- cgit v1.2.3-59-g8ed1b From 955a0f3310081731a1756a1d7bd742600ee69ffc Mon Sep 17 00:00:00 2001 From: Anders Roxell Date: Wed, 14 Aug 2019 13:16:51 +0200 Subject: selftests: livepatch: add missing fragments to config When generating config with 'make defconfig kselftest-merge' fragment CONFIG_TEST_LIVEPATCH=m isn't set. Rework to enable CONFIG_LIVEPATCH and CONFIG_DYNAMIC_DEBUG as well. Signed-off-by: Anders Roxell Signed-off-by: Shuah Khan --- tools/testing/selftests/livepatch/config | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/livepatch/config b/tools/testing/selftests/livepatch/config index 0dd7700464a8..ad23100cb27c 100644 --- a/tools/testing/selftests/livepatch/config +++ b/tools/testing/selftests/livepatch/config @@ -1 +1,3 @@ +CONFIG_LIVEPATCH=y +CONFIG_DYNAMIC_DEBUG=y CONFIG_TEST_LIVEPATCH=m -- cgit v1.2.3-59-g8ed1b From 721cb3c8bc8890e824b7be53bf951960ff7811f9 Mon Sep 17 00:00:00 2001 From: Anders Roxell Date: Wed, 14 Aug 2019 13:14:35 +0200 Subject: selftests: tpm2: install python files Both test_smoke.sh and test_space.sh require tpm2.py and tpm2_test.py. Rework so that tpm2.py and tpm2_test.py gets installed, added them to the variable TEST_PROGS_EXTENDED. Signed-off-by: Anders Roxell Signed-off-by: Shuah Khan --- tools/testing/selftests/tpm2/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/testing/selftests/tpm2/Makefile b/tools/testing/selftests/tpm2/Makefile index 9dd848427a7b..1a5db1eb8ed5 100644 --- a/tools/testing/selftests/tpm2/Makefile +++ b/tools/testing/selftests/tpm2/Makefile @@ -2,3 +2,4 @@ include ../lib.mk TEST_PROGS := test_smoke.sh test_space.sh +TEST_PROGS_EXTENDED := tpm2.py tpm2_tests.py -- cgit v1.2.3-59-g8ed1b From 12c386b2308344f2ce8819ad11aab466166f276d Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Fri, 30 Aug 2019 09:36:16 +0800 Subject: KVM: selftests: Move vm type into _vm_create() internally Rather than passing the vm type from the top level to the end of vm creation, let's simply keep that as an internal of kvm_vm struct and decide the type in _vm_create(). Several reasons for doing this: - The vm type is only decided by physical address width and currently only used in aarch64, so we've got enough information as long as we're passing vm_guest_mode into _vm_create(), - This removes a loop dependency between the vm->type and creation of vms. That's why now we need to parse vm_guest_mode twice sometimes, once in run_test() and then again in _vm_create(). The follow up patches will move on to clean up that as well so we can have a single place to decide guest machine types and so. Note that this patch will slightly change the behavior of aarch64 tests in that previously most vm_create() callers will directly pass in type==0 into _vm_create() but now the type will depend on vm_guest_mode, however it shouldn't affect any user because all vm_create() users of aarch64 will be using VM_MODE_DEFAULT guest mode (which is VM_MODE_P40V48_4K) so at last type will still be zero. Reviewed-by: Andrew Jones Signed-off-by: Peter Xu Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/dirty_log_test.c | 13 +++---------- tools/testing/selftests/kvm/include/kvm_util.h | 3 +-- tools/testing/selftests/kvm/lib/kvm_util.c | 21 +++++++++++++-------- 3 files changed, 17 insertions(+), 20 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/dirty_log_test.c b/tools/testing/selftests/kvm/dirty_log_test.c index dc3346e090f5..6737b26b975e 100644 --- a/tools/testing/selftests/kvm/dirty_log_test.c +++ b/tools/testing/selftests/kvm/dirty_log_test.c @@ -249,14 +249,12 @@ static void vm_dirty_log_verify(unsigned long *bmap) } static struct kvm_vm *create_vm(enum vm_guest_mode mode, uint32_t vcpuid, - uint64_t extra_mem_pages, void *guest_code, - unsigned long type) + uint64_t extra_mem_pages, void *guest_code) { struct kvm_vm *vm; uint64_t extra_pg_pages = extra_mem_pages / 512 * 2; - vm = _vm_create(mode, DEFAULT_GUEST_PHY_PAGES + extra_pg_pages, - O_RDWR, type); + vm = _vm_create(mode, DEFAULT_GUEST_PHY_PAGES + extra_pg_pages, O_RDWR); kvm_vm_elf_load(vm, program_invocation_name, 0, 0); #ifdef __x86_64__ vm_create_irqchip(vm); @@ -273,7 +271,6 @@ static void run_test(enum vm_guest_mode mode, unsigned long iterations, struct kvm_vm *vm; uint64_t max_gfn; unsigned long *bmap; - unsigned long type = 0; switch (mode) { case VM_MODE_P52V48_4K: @@ -314,10 +311,6 @@ static void run_test(enum vm_guest_mode mode, unsigned long iterations, * bits we can change to 39. */ guest_pa_bits = 39; -#endif -#ifdef __aarch64__ - if (guest_pa_bits != 40) - type = KVM_VM_TYPE_ARM_IPA_SIZE(guest_pa_bits); #endif max_gfn = (1ul << (guest_pa_bits - guest_page_shift)) - 1; guest_page_size = (1ul << guest_page_shift); @@ -351,7 +344,7 @@ static void run_test(enum vm_guest_mode mode, unsigned long iterations, bmap = bitmap_alloc(host_num_pages); host_bmap_track = bitmap_alloc(host_num_pages); - vm = create_vm(mode, VCPU_ID, guest_num_pages, guest_code, type); + vm = create_vm(mode, VCPU_ID, guest_num_pages, guest_code); #ifdef USE_CLEAR_DIRTY_LOG struct kvm_enable_cap cap = {}; diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index 5463b7896a0a..b2c15135f596 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -60,8 +60,7 @@ int kvm_check_cap(long cap); int vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_cap *cap); struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm); -struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages, - int perm, unsigned long type); +struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm); void kvm_vm_free(struct kvm_vm *vmp); void kvm_vm_restart(struct kvm_vm *vmp, int perm); void kvm_vm_release(struct kvm_vm *vmp); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 6e49bb039376..34a8a6572c7c 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -84,7 +84,7 @@ int vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_cap *cap) return ret; } -static void vm_open(struct kvm_vm *vm, int perm, unsigned long type) +static void vm_open(struct kvm_vm *vm, int perm) { vm->kvm_fd = open(KVM_DEV_PATH, perm); if (vm->kvm_fd < 0) @@ -95,7 +95,7 @@ static void vm_open(struct kvm_vm *vm, int perm, unsigned long type) exit(KSFT_SKIP); } - vm->fd = ioctl(vm->kvm_fd, KVM_CREATE_VM, type); + vm->fd = ioctl(vm->kvm_fd, KVM_CREATE_VM, vm->type); TEST_ASSERT(vm->fd >= 0, "KVM_CREATE_VM ioctl failed, " "rc: %i errno: %i", vm->fd, errno); } @@ -130,8 +130,7 @@ _Static_assert(sizeof(vm_guest_mode_string)/sizeof(char *) == NUM_VM_MODES, * descriptor to control the created VM is created with the permissions * given by perm (e.g. O_RDWR). */ -struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages, - int perm, unsigned long type) +struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm) { struct kvm_vm *vm; @@ -139,8 +138,7 @@ struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages, TEST_ASSERT(vm != NULL, "Insufficient Memory"); vm->mode = mode; - vm->type = type; - vm_open(vm, perm, type); + vm->type = 0; /* Setup mode specific traits. */ switch (vm->mode) { @@ -190,6 +188,13 @@ struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages, TEST_ASSERT(false, "Unknown guest mode, mode: 0x%x", mode); } +#ifdef __aarch64__ + if (vm->pa_bits != 40) + vm->type = KVM_VM_TYPE_ARM_IPA_SIZE(vm->pa_bits); +#endif + + vm_open(vm, perm); + /* Limit to VA-bit canonical virtual addresses. */ vm->vpages_valid = sparsebit_alloc(); sparsebit_set_num(vm->vpages_valid, @@ -212,7 +217,7 @@ struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages, struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm) { - return _vm_create(mode, phy_pages, perm, 0); + return _vm_create(mode, phy_pages, perm); } /* @@ -232,7 +237,7 @@ void kvm_vm_restart(struct kvm_vm *vmp, int perm) { struct userspace_mem_region *region; - vm_open(vmp, perm, vmp->type); + vm_open(vmp, perm); if (vmp->has_irqchip) vm_create_irqchip(vmp); -- cgit v1.2.3-59-g8ed1b From 338eb29876b9e571273175f167fcd58d9441ac8e Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Fri, 30 Aug 2019 09:36:17 +0800 Subject: KVM: selftests: Create VM earlier for dirty log test Since we've just removed the dependency of vm type in previous patch, now we can create the vm much earlier. Note that to move it earlier we used an approximation of number of extra pages but it should be fine. This prepares for the follow up patches to finally remove the duplication of guest mode parsings. Reviewed-by: Andrew Jones Signed-off-by: Peter Xu Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/dirty_log_test.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/dirty_log_test.c b/tools/testing/selftests/kvm/dirty_log_test.c index 6737b26b975e..cf2099abb121 100644 --- a/tools/testing/selftests/kvm/dirty_log_test.c +++ b/tools/testing/selftests/kvm/dirty_log_test.c @@ -263,6 +263,9 @@ static struct kvm_vm *create_vm(enum vm_guest_mode mode, uint32_t vcpuid, return vm; } +#define DIRTY_MEM_BITS 30 /* 1G */ +#define PAGE_SHIFT_4K 12 + static void run_test(enum vm_guest_mode mode, unsigned long iterations, unsigned long interval, uint64_t phys_offset) { @@ -272,6 +275,18 @@ static void run_test(enum vm_guest_mode mode, unsigned long iterations, uint64_t max_gfn; unsigned long *bmap; + /* + * We reserve page table for 2 times of extra dirty mem which + * will definitely cover the original (1G+) test range. Here + * we do the calculation with 4K page size which is the + * smallest so the page number will be enough for all archs + * (e.g., 64K page size guest will need even less memory for + * page tables). + */ + vm = create_vm(mode, VCPU_ID, + 2ul << (DIRTY_MEM_BITS - PAGE_SHIFT_4K), + guest_code); + switch (mode) { case VM_MODE_P52V48_4K: guest_pa_bits = 52; @@ -318,7 +333,7 @@ static void run_test(enum vm_guest_mode mode, unsigned long iterations, * A little more than 1G of guest page sized pages. Cover the * case where the size is not aligned to 64 pages. */ - guest_num_pages = (1ul << (30 - guest_page_shift)) + 16; + guest_num_pages = (1ul << (DIRTY_MEM_BITS - guest_page_shift)) + 16; #ifdef __s390x__ /* Round up to multiple of 1M (segment size) */ guest_num_pages = (guest_num_pages + 0xff) & ~0xffUL; @@ -344,8 +359,6 @@ static void run_test(enum vm_guest_mode mode, unsigned long iterations, bmap = bitmap_alloc(host_num_pages); host_bmap_track = bitmap_alloc(host_num_pages); - vm = create_vm(mode, VCPU_ID, guest_num_pages, guest_code); - #ifdef USE_CLEAR_DIRTY_LOG struct kvm_enable_cap cap = {}; -- cgit v1.2.3-59-g8ed1b From 567a9f1e9deb273a2c02dd18c254208537fcefaa Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Fri, 30 Aug 2019 09:36:18 +0800 Subject: KVM: selftests: Introduce VM_MODE_PXXV48_4K The naming VM_MODE_P52V48_4K is explicit but unclear when used on x86_64 machines, because x86_64 machines are having various physical address width rather than some static values. Here's some examples: - Intel Xeon E3-1220: 36 bits - Intel Core i7-8650: 39 bits - AMD EPYC 7251: 48 bits All of them are using 48 bits linear address width but with totally different physical address width (and most of the old machines should be less than 52 bits). Let's create a new guest mode called VM_MODE_PXXV48_4K for current x86_64 tests and make it as the default to replace the old naming of VM_MODE_P52V48_4K because it shows more clearly that the PA width is not really a constant. Meanwhile we also stop assuming all the x86 machines are having 52 bits PA width but instead we fetch the real vm->pa_bits from CPUID 0x80000008 during runtime. We currently make this exclusively used by x86_64 but no other arch. As a slight touch up, moving DEBUG macro from dirty_log_test.c to kvm_util.h so lib can use it too. Signed-off-by: Peter Xu Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/dirty_log_test.c | 5 ++-- tools/testing/selftests/kvm/include/kvm_util.h | 11 +++++++- .../selftests/kvm/include/x86_64/processor.h | 3 +++ .../testing/selftests/kvm/lib/aarch64/processor.c | 3 +++ tools/testing/selftests/kvm/lib/kvm_util.c | 29 ++++++++++++++++----- tools/testing/selftests/kvm/lib/x86_64/processor.c | 30 +++++++++++++++++++--- 6 files changed, 67 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/dirty_log_test.c b/tools/testing/selftests/kvm/dirty_log_test.c index cf2099abb121..12c36fa356a8 100644 --- a/tools/testing/selftests/kvm/dirty_log_test.c +++ b/tools/testing/selftests/kvm/dirty_log_test.c @@ -19,8 +19,6 @@ #include "kvm_util.h" #include "processor.h" -#define DEBUG printf - #define VCPU_ID 1 /* The memory slot index to track dirty pages */ @@ -289,6 +287,7 @@ static void run_test(enum vm_guest_mode mode, unsigned long iterations, switch (mode) { case VM_MODE_P52V48_4K: + case VM_MODE_PXXV48_4K: guest_pa_bits = 52; guest_page_shift = 12; break; @@ -488,7 +487,7 @@ int main(int argc, char *argv[]) #endif #ifdef __x86_64__ - vm_guest_mode_params_init(VM_MODE_P52V48_4K, true, true); + vm_guest_mode_params_init(VM_MODE_PXXV48_4K, true, true); #endif #ifdef __aarch64__ vm_guest_mode_params_init(VM_MODE_P40V48_4K, true, true); diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index b2c15135f596..ef3259c5e856 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -24,6 +24,12 @@ struct kvm_vm; typedef uint64_t vm_paddr_t; /* Virtual Machine (Guest) physical address */ typedef uint64_t vm_vaddr_t; /* Virtual Machine (Guest) virtual address */ +#ifndef NDEBUG +#define DEBUG(...) printf(__VA_ARGS__); +#else +#define DEBUG(...) +#endif + /* Minimum allocated guest virtual and physical addresses */ #define KVM_UTIL_MIN_VADDR 0x2000 @@ -38,11 +44,14 @@ enum vm_guest_mode { VM_MODE_P48V48_64K, VM_MODE_P40V48_4K, VM_MODE_P40V48_64K, + VM_MODE_PXXV48_4K, /* For 48bits VA but ANY bits PA */ NUM_VM_MODES, }; -#ifdef __aarch64__ +#if defined(__aarch64__) #define VM_MODE_DEFAULT VM_MODE_P40V48_4K +#elif defined(__x86_64__) +#define VM_MODE_DEFAULT VM_MODE_PXXV48_4K #else #define VM_MODE_DEFAULT VM_MODE_P52V48_4K #endif diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h index 80d19740d2dc..0c17f2ee685e 100644 --- a/tools/testing/selftests/kvm/include/x86_64/processor.h +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h @@ -325,6 +325,9 @@ uint64_t vcpu_get_msr(struct kvm_vm *vm, uint32_t vcpuid, uint64_t msr_index); void vcpu_set_msr(struct kvm_vm *vm, uint32_t vcpuid, uint64_t msr_index, uint64_t msr_value); +uint32_t kvm_get_cpuid_max(void); +void kvm_get_cpu_address_width(unsigned int *pa_bits, unsigned int *va_bits); + /* * Basic CPU control in CR0 */ diff --git a/tools/testing/selftests/kvm/lib/aarch64/processor.c b/tools/testing/selftests/kvm/lib/aarch64/processor.c index 486400a97374..86036a59a668 100644 --- a/tools/testing/selftests/kvm/lib/aarch64/processor.c +++ b/tools/testing/selftests/kvm/lib/aarch64/processor.c @@ -264,6 +264,9 @@ void aarch64_vcpu_setup(struct kvm_vm *vm, int vcpuid, struct kvm_vcpu_init *ini case VM_MODE_P52V48_4K: TEST_ASSERT(false, "AArch64 does not support 4K sized pages " "with 52-bit physical address ranges"); + case VM_MODE_PXXV48_4K: + TEST_ASSERT(false, "AArch64 does not support 4K sized pages " + "with ANY-bit physical address ranges"); case VM_MODE_P52V48_64K: tcr_el1 |= 1ul << 14; /* TG0 = 64KB */ tcr_el1 |= 6ul << 32; /* IPS = 52 bits */ diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 34a8a6572c7c..bb8f993b25fb 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -8,6 +8,7 @@ #include "test_util.h" #include "kvm_util.h" #include "kvm_util_internal.h" +#include "processor.h" #include #include @@ -101,12 +102,13 @@ static void vm_open(struct kvm_vm *vm, int perm) } const char * const vm_guest_mode_string[] = { - "PA-bits:52, VA-bits:48, 4K pages", - "PA-bits:52, VA-bits:48, 64K pages", - "PA-bits:48, VA-bits:48, 4K pages", - "PA-bits:48, VA-bits:48, 64K pages", - "PA-bits:40, VA-bits:48, 4K pages", - "PA-bits:40, VA-bits:48, 64K pages", + "PA-bits:52, VA-bits:48, 4K pages", + "PA-bits:52, VA-bits:48, 64K pages", + "PA-bits:48, VA-bits:48, 4K pages", + "PA-bits:48, VA-bits:48, 64K pages", + "PA-bits:40, VA-bits:48, 4K pages", + "PA-bits:40, VA-bits:48, 64K pages", + "PA-bits:ANY, VA-bits:48, 4K pages", }; _Static_assert(sizeof(vm_guest_mode_string)/sizeof(char *) == NUM_VM_MODES, "Missing new mode strings?"); @@ -184,6 +186,21 @@ struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm) vm->page_size = 0x10000; vm->page_shift = 16; break; + case VM_MODE_PXXV48_4K: +#ifdef __x86_64__ + kvm_get_cpu_address_width(&vm->pa_bits, &vm->va_bits); + TEST_ASSERT(vm->va_bits == 48, "Linear address width " + "(%d bits) not supported", vm->va_bits); + vm->pgtable_levels = 4; + vm->page_size = 0x1000; + vm->page_shift = 12; + DEBUG("Guest physical address width detected: %d\n", + vm->pa_bits); +#else + TEST_ASSERT(false, "VM_MODE_PXXV48_4K not supported on " + "non-x86 platforms"); +#endif + break; default: TEST_ASSERT(false, "Unknown guest mode, mode: 0x%x", mode); } diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c index 0a5e487dbc50..c53dbc6bc568 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c @@ -228,7 +228,7 @@ void sregs_dump(FILE *stream, struct kvm_sregs *sregs, void virt_pgd_alloc(struct kvm_vm *vm, uint32_t pgd_memslot) { - TEST_ASSERT(vm->mode == VM_MODE_P52V48_4K, "Attempt to use " + TEST_ASSERT(vm->mode == VM_MODE_PXXV48_4K, "Attempt to use " "unknown or unsupported guest mode, mode: 0x%x", vm->mode); /* If needed, create page map l4 table. */ @@ -261,7 +261,7 @@ void virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, uint16_t index[4]; struct pageMapL4Entry *pml4e; - TEST_ASSERT(vm->mode == VM_MODE_P52V48_4K, "Attempt to use " + TEST_ASSERT(vm->mode == VM_MODE_PXXV48_4K, "Attempt to use " "unknown or unsupported guest mode, mode: 0x%x", vm->mode); TEST_ASSERT((vaddr % vm->page_size) == 0, @@ -547,7 +547,7 @@ vm_paddr_t addr_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva) struct pageDirectoryEntry *pde; struct pageTableEntry *pte; - TEST_ASSERT(vm->mode == VM_MODE_P52V48_4K, "Attempt to use " + TEST_ASSERT(vm->mode == VM_MODE_PXXV48_4K, "Attempt to use " "unknown or unsupported guest mode, mode: 0x%x", vm->mode); index[0] = (gva >> 12) & 0x1ffu; @@ -621,7 +621,7 @@ static void vcpu_setup(struct kvm_vm *vm, int vcpuid, int pgd_memslot, int gdt_m kvm_setup_gdt(vm, &sregs.gdt, gdt_memslot, pgd_memslot); switch (vm->mode) { - case VM_MODE_P52V48_4K: + case VM_MODE_PXXV48_4K: sregs.cr0 = X86_CR0_PE | X86_CR0_NE | X86_CR0_PG; sregs.cr4 |= X86_CR4_PAE | X86_CR4_OSFXSR; sregs.efer |= (EFER_LME | EFER_LMA | EFER_NX); @@ -1157,3 +1157,25 @@ bool is_intel_cpu(void) chunk = (const uint32_t *)("GenuineIntel"); return (ebx == chunk[0] && edx == chunk[1] && ecx == chunk[2]); } + +uint32_t kvm_get_cpuid_max(void) +{ + return kvm_get_supported_cpuid_entry(0x80000000)->eax; +} + +void kvm_get_cpu_address_width(unsigned int *pa_bits, unsigned int *va_bits) +{ + struct kvm_cpuid_entry2 *entry; + bool pae; + + /* SDM 4.1.4 */ + if (kvm_get_cpuid_max() < 0x80000008) { + pae = kvm_get_supported_cpuid_entry(1)->edx & (1 << 6); + *pa_bits = pae ? 36 : 32; + *va_bits = 32; + } else { + entry = kvm_get_supported_cpuid_entry(0x80000008); + *pa_bits = entry->eax & 0xff; + *va_bits = (entry->eax >> 8) & 0xff; + } +} -- cgit v1.2.3-59-g8ed1b From 52200d0d944e473142271773c41f5f490f3a821f Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Fri, 30 Aug 2019 09:36:19 +0800 Subject: KVM: selftests: Remove duplicate guest mode handling Remove the duplication code in run_test() of dirty_log_test because after some reordering of functions now we can directly use the outcome of vm_create(). Meanwhile, with the new VM_MODE_PXXV48_4K, we can safely revert b442324b58 too where we stick the x86_64 PA width to 39 bits for dirty_log_test. Reviewed-by: Andrew Jones Signed-off-by: Peter Xu Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/dirty_log_test.c | 52 +++----------------------- tools/testing/selftests/kvm/include/kvm_util.h | 4 ++ tools/testing/selftests/kvm/lib/kvm_util.c | 17 +++++++++ 3 files changed, 26 insertions(+), 47 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/dirty_log_test.c b/tools/testing/selftests/kvm/dirty_log_test.c index 12c36fa356a8..5614222a6628 100644 --- a/tools/testing/selftests/kvm/dirty_log_test.c +++ b/tools/testing/selftests/kvm/dirty_log_test.c @@ -267,10 +267,8 @@ static struct kvm_vm *create_vm(enum vm_guest_mode mode, uint32_t vcpuid, static void run_test(enum vm_guest_mode mode, unsigned long iterations, unsigned long interval, uint64_t phys_offset) { - unsigned int guest_pa_bits, guest_page_shift; pthread_t vcpu_thread; struct kvm_vm *vm; - uint64_t max_gfn; unsigned long *bmap; /* @@ -285,54 +283,13 @@ static void run_test(enum vm_guest_mode mode, unsigned long iterations, 2ul << (DIRTY_MEM_BITS - PAGE_SHIFT_4K), guest_code); - switch (mode) { - case VM_MODE_P52V48_4K: - case VM_MODE_PXXV48_4K: - guest_pa_bits = 52; - guest_page_shift = 12; - break; - case VM_MODE_P52V48_64K: - guest_pa_bits = 52; - guest_page_shift = 16; - break; - case VM_MODE_P48V48_4K: - guest_pa_bits = 48; - guest_page_shift = 12; - break; - case VM_MODE_P48V48_64K: - guest_pa_bits = 48; - guest_page_shift = 16; - break; - case VM_MODE_P40V48_4K: - guest_pa_bits = 40; - guest_page_shift = 12; - break; - case VM_MODE_P40V48_64K: - guest_pa_bits = 40; - guest_page_shift = 16; - break; - default: - TEST_ASSERT(false, "Unknown guest mode, mode: 0x%x", mode); - } - - DEBUG("Testing guest mode: %s\n", vm_guest_mode_string(mode)); - -#ifdef __x86_64__ - /* - * FIXME - * The x86_64 kvm selftests framework currently only supports a - * single PML4 which restricts the number of physical address - * bits we can change to 39. - */ - guest_pa_bits = 39; -#endif - max_gfn = (1ul << (guest_pa_bits - guest_page_shift)) - 1; - guest_page_size = (1ul << guest_page_shift); + guest_page_size = vm_get_page_size(vm); /* * A little more than 1G of guest page sized pages. Cover the * case where the size is not aligned to 64 pages. */ - guest_num_pages = (1ul << (DIRTY_MEM_BITS - guest_page_shift)) + 16; + guest_num_pages = (1ul << (DIRTY_MEM_BITS - + vm_get_page_shift(vm))) + 16; #ifdef __s390x__ /* Round up to multiple of 1M (segment size) */ guest_num_pages = (guest_num_pages + 0xff) & ~0xffUL; @@ -342,7 +299,8 @@ static void run_test(enum vm_guest_mode mode, unsigned long iterations, !!((guest_num_pages * guest_page_size) % host_page_size); if (!phys_offset) { - guest_test_phys_mem = (max_gfn - guest_num_pages) * guest_page_size; + guest_test_phys_mem = (vm_get_max_gfn(vm) - + guest_num_pages) * guest_page_size; guest_test_phys_mem &= ~(host_page_size - 1); } else { guest_test_phys_mem = phys_offset; diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index ef3259c5e856..29cccaf96baf 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -154,6 +154,10 @@ void vm_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid, void *guest_code); bool vm_is_unrestricted_guest(struct kvm_vm *vm); +unsigned int vm_get_page_size(struct kvm_vm *vm); +unsigned int vm_get_page_shift(struct kvm_vm *vm); +unsigned int vm_get_max_gfn(struct kvm_vm *vm); + struct kvm_userspace_memory_region * kvm_userspace_memory_region_find(struct kvm_vm *vm, uint64_t start, uint64_t end); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index bb8f993b25fb..80a338b5403c 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -136,6 +136,8 @@ struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm) { struct kvm_vm *vm; + DEBUG("Testing guest mode: %s\n", vm_guest_mode_string(mode)); + vm = calloc(1, sizeof(*vm)); TEST_ASSERT(vm != NULL, "Insufficient Memory"); @@ -1650,3 +1652,18 @@ bool vm_is_unrestricted_guest(struct kvm_vm *vm) return val == 'Y'; } + +unsigned int vm_get_page_size(struct kvm_vm *vm) +{ + return vm->page_size; +} + +unsigned int vm_get_page_shift(struct kvm_vm *vm) +{ + return vm->page_shift; +} + +unsigned int vm_get_max_gfn(struct kvm_vm *vm) +{ + return vm->max_gfn; +} -- cgit v1.2.3-59-g8ed1b From e738772e29214019f506372dd1162723b7a4d507 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 16 Sep 2019 18:22:58 +0200 Subject: KVM: selftests: hyperv_cpuid: add check for NoNonArchitecturalCoreSharing bit The bit is supposed to be '1' when SMT is not supported or forcefully disabled and '0' otherwise. Signed-off-by: Vitaly Kuznetsov Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c | 27 +++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c b/tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c index ee59831fbc98..443a2b54645b 100644 --- a/tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c +++ b/tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c @@ -26,6 +26,25 @@ static void guest_code(void) { } +static int smt_possible(void) +{ + char buf[16]; + FILE *f; + bool res = 1; + + f = fopen("/sys/devices/system/cpu/smt/control", "r"); + if (f) { + if (fread(buf, sizeof(*buf), sizeof(buf), f) > 0) { + if (!strncmp(buf, "forceoff", 8) || + !strncmp(buf, "notsupported", 12)) + res = 0; + } + fclose(f); + } + + return res; +} + static void test_hv_cpuid(struct kvm_cpuid2 *hv_cpuid_entries, int evmcs_enabled) { @@ -59,6 +78,14 @@ static void test_hv_cpuid(struct kvm_cpuid2 *hv_cpuid_entries, TEST_ASSERT(!entry->padding[0] && !entry->padding[1] && !entry->padding[2], "padding should be zero"); + if (entry->function == 0x40000004) { + int nononarchcs = !!(entry->eax & (1UL << 18)); + + TEST_ASSERT(nononarchcs == !smt_possible(), + "NoNonArchitecturalCoreSharing bit" + " doesn't reflect SMT setting"); + } + /* * If needed for debug: * fprintf(stdout, -- cgit v1.2.3-59-g8ed1b From 59f08896f058a92f03a0041b397a1a227c5e8529 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 17 Sep 2019 21:21:49 -0700 Subject: libnvdimm/nfit_test: Fix acpi_handle redefinition After commit 62974fc389b3 ("libnvdimm: Enable unit test infrastructure compile checks"), clang warns: In file included from ../drivers/nvdimm/../../tools/testing/nvdimm/test/iomap.c:15: ../drivers/nvdimm/../../tools/testing/nvdimm/test/nfit_test.h:206:15: warning: redefinition of typedef 'acpi_handle' is a C11 feature [-Wtypedef-redefinition] typedef void *acpi_handle; ^ ../include/acpi/actypes.h:424:15: note: previous definition is here typedef void *acpi_handle; /* Actually a ptr to a NS Node */ ^ 1 warning generated. The include chain: iomap.c -> linux/acpi.h -> acpi/acpi.h -> acpi/actypes.h nfit_test.h Avoid this by including linux/acpi.h in nfit_test.h, which allows us to remove both the typedef and the forward declaration of acpi_object. Link: https://github.com/ClangBuiltLinux/linux/issues/660 Signed-off-by: Nathan Chancellor Reviewed-by: Ira Weiny Link: https://lore.kernel.org/r/20190918042148.77553-1-natechancellor@gmail.com Signed-off-by: Dan Williams --- tools/testing/nvdimm/test/nfit_test.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/testing/nvdimm/test/nfit_test.h b/tools/testing/nvdimm/test/nfit_test.h index 448d686da8b1..0bf5640f1f07 100644 --- a/tools/testing/nvdimm/test/nfit_test.h +++ b/tools/testing/nvdimm/test/nfit_test.h @@ -4,6 +4,7 @@ */ #ifndef __NFIT_TEST_H__ #define __NFIT_TEST_H__ +#include #include #include #include @@ -202,9 +203,6 @@ struct nd_intel_lss { __u32 status; } __packed; -union acpi_object; -typedef void *acpi_handle; - typedef struct nfit_test_resource *(*nfit_test_lookup_fn)(resource_size_t); typedef union acpi_object *(*nfit_test_evaluate_dsm_fn)(acpi_handle handle, const guid_t *guid, u64 rev, u64 func, -- cgit v1.2.3-59-g8ed1b From 93cad5f789951eaa27c3392b15294b4e51253944 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 24 Sep 2019 09:22:54 +0530 Subject: selftests/powerpc: Add test case for tlbie vs mtpidr ordering issue Signed-off-by: Aneesh Kumar K.V [mpe: Some minor fixes to make it build] Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20190924035254.24612-4-aneesh.kumar@linux.ibm.com --- tools/testing/selftests/powerpc/mm/Makefile | 2 + tools/testing/selftests/powerpc/mm/tlbie_test.c | 734 ++++++++++++++++++++++++ 2 files changed, 736 insertions(+) create mode 100644 tools/testing/selftests/powerpc/mm/tlbie_test.c (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/mm/Makefile b/tools/testing/selftests/powerpc/mm/Makefile index f1fbc15800c4..ed1565809d2b 100644 --- a/tools/testing/selftests/powerpc/mm/Makefile +++ b/tools/testing/selftests/powerpc/mm/Makefile @@ -4,6 +4,7 @@ noarg: TEST_GEN_PROGS := hugetlb_vs_thp_test subpage_prot prot_sao segv_errors wild_bctr \ large_vm_fork_separation +TEST_GEN_PROGS_EXTENDED := tlbie_test TEST_GEN_FILES := tempfile top_srcdir = ../../../../.. @@ -19,3 +20,4 @@ $(OUTPUT)/large_vm_fork_separation: CFLAGS += -m64 $(OUTPUT)/tempfile: dd if=/dev/zero of=$@ bs=64k count=1 +$(OUTPUT)/tlbie_test: LDLIBS += -lpthread diff --git a/tools/testing/selftests/powerpc/mm/tlbie_test.c b/tools/testing/selftests/powerpc/mm/tlbie_test.c new file mode 100644 index 000000000000..9868a5ddd847 --- /dev/null +++ b/tools/testing/selftests/powerpc/mm/tlbie_test.c @@ -0,0 +1,734 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Copyright 2019, Nick Piggin, Gautham R. Shenoy, Aneesh Kumar K.V, IBM Corp. + */ + +/* + * + * Test tlbie/mtpidr race. We have 4 threads doing flush/load/compare/store + * sequence in a loop. The same threads also rung a context switch task + * that does sched_yield() in loop. + * + * The snapshot thread mark the mmap area PROT_READ in between, make a copy + * and copy it back to the original area. This helps us to detect if any + * store continued to happen after we marked the memory PROT_READ. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static inline void dcbf(volatile unsigned int *addr) +{ + __asm__ __volatile__ ("dcbf %y0; sync" : : "Z"(*(unsigned char *)addr) : "memory"); +} + +static void err_msg(char *msg) +{ + + time_t now; + time(&now); + printf("=================================\n"); + printf(" Error: %s\n", msg); + printf(" %s", ctime(&now)); + printf("=================================\n"); + exit(1); +} + +static char *map1; +static char *map2; +static pid_t rim_process_pid; + +/* + * A "rim-sequence" is defined to be the sequence of the following + * operations performed on a memory word: + * 1) FLUSH the contents of that word. + * 2) LOAD the contents of that word. + * 3) COMPARE the contents of that word with the content that was + * previously stored at that word + * 4) STORE new content into that word. + * + * The threads in this test that perform the rim-sequence are termed + * as rim_threads. + */ + +/* + * A "corruption" is defined to be the failed COMPARE operation in a + * rim-sequence. + * + * A rim_thread that detects a corruption informs about it to all the + * other rim_threads, and the mem_snapshot thread. + */ +static volatile unsigned int corruption_found; + +/* + * This defines the maximum number of rim_threads in this test. + * + * The THREAD_ID_BITS denote the number of bits required + * to represent the thread_ids [0..MAX_THREADS - 1]. + * We are being a bit paranoid here and set it to 8 bits, + * though 6 bits suffice. + * + */ +#define MAX_THREADS 64 +#define THREAD_ID_BITS 8 +#define THREAD_ID_MASK ((1 << THREAD_ID_BITS) - 1) +static unsigned int rim_thread_ids[MAX_THREADS]; +static pthread_t rim_threads[MAX_THREADS]; + + +/* + * Each rim_thread works on an exclusive "chunk" of size + * RIM_CHUNK_SIZE. + * + * The ith rim_thread works on the ith chunk. + * + * The ith chunk begins at + * map1 + (i * RIM_CHUNK_SIZE) + */ +#define RIM_CHUNK_SIZE 1024 +#define BITS_PER_BYTE 8 +#define WORD_SIZE (sizeof(unsigned int)) +#define WORD_BITS (WORD_SIZE * BITS_PER_BYTE) +#define WORDS_PER_CHUNK (RIM_CHUNK_SIZE/WORD_SIZE) + +static inline char *compute_chunk_start_addr(unsigned int thread_id) +{ + char *chunk_start; + + chunk_start = (char *)((unsigned long)map1 + + (thread_id * RIM_CHUNK_SIZE)); + + return chunk_start; +} + +/* + * The "word-offset" of a word-aligned address inside a chunk, is + * defined to be the number of words that precede the address in that + * chunk. + * + * WORD_OFFSET_BITS denote the number of bits required to represent + * the word-offsets of all the word-aligned addresses of a chunk. + */ +#define WORD_OFFSET_BITS (__builtin_ctz(WORDS_PER_CHUNK)) +#define WORD_OFFSET_MASK ((1 << WORD_OFFSET_BITS) - 1) + +static inline unsigned int compute_word_offset(char *start, unsigned int *addr) +{ + unsigned int delta_bytes, ret; + delta_bytes = (unsigned long)addr - (unsigned long)start; + + ret = delta_bytes/WORD_SIZE; + + return ret; +} + +/* + * A "sweep" is defined to be the sequential execution of the + * rim-sequence by a rim_thread on its chunk one word at a time, + * starting from the first word of its chunk and ending with the last + * word of its chunk. + * + * Each sweep of a rim_thread is uniquely identified by a sweep_id. + * SWEEP_ID_BITS denote the number of bits required to represent + * the sweep_ids of rim_threads. + * + * As to why SWEEP_ID_BITS are computed as a function of THREAD_ID_BITS, + * WORD_OFFSET_BITS, and WORD_BITS, see the "store-pattern" below. + */ +#define SWEEP_ID_BITS (WORD_BITS - (THREAD_ID_BITS + WORD_OFFSET_BITS)) +#define SWEEP_ID_MASK ((1 << SWEEP_ID_BITS) - 1) + +/* + * A "store-pattern" is the word-pattern that is stored into a word + * location in the 4)STORE step of the rim-sequence. + * + * In the store-pattern, we shall encode: + * + * - The thread-id of the rim_thread performing the store + * (The most significant THREAD_ID_BITS) + * + * - The word-offset of the address into which the store is being + * performed (The next WORD_OFFSET_BITS) + * + * - The sweep_id of the current sweep in which the store is + * being performed. (The lower SWEEP_ID_BITS) + * + * Store Pattern: 32 bits + * |------------------|--------------------|---------------------------------| + * | Thread id | Word offset | sweep_id | + * |------------------|--------------------|---------------------------------| + * THREAD_ID_BITS WORD_OFFSET_BITS SWEEP_ID_BITS + * + * In the store pattern, the (Thread-id + Word-offset) uniquely identify the + * address to which the store is being performed i.e, + * address == map1 + + * (Thread-id * RIM_CHUNK_SIZE) + (Word-offset * WORD_SIZE) + * + * And the sweep_id in the store pattern identifies the time when the + * store was performed by the rim_thread. + * + * We shall use this property in the 3)COMPARE step of the + * rim-sequence. + */ +#define SWEEP_ID_SHIFT 0 +#define WORD_OFFSET_SHIFT (SWEEP_ID_BITS) +#define THREAD_ID_SHIFT (WORD_OFFSET_BITS + SWEEP_ID_BITS) + +/* + * Compute the store pattern for a given thread with id @tid, at + * location @addr in the sweep identified by @sweep_id + */ +static inline unsigned int compute_store_pattern(unsigned int tid, + unsigned int *addr, + unsigned int sweep_id) +{ + unsigned int ret = 0; + char *start = compute_chunk_start_addr(tid); + unsigned int word_offset = compute_word_offset(start, addr); + + ret += (tid & THREAD_ID_MASK) << THREAD_ID_SHIFT; + ret += (word_offset & WORD_OFFSET_MASK) << WORD_OFFSET_SHIFT; + ret += (sweep_id & SWEEP_ID_MASK) << SWEEP_ID_SHIFT; + return ret; +} + +/* Extract the thread-id from the given store-pattern */ +static inline unsigned int extract_tid(unsigned int pattern) +{ + unsigned int ret; + + ret = (pattern >> THREAD_ID_SHIFT) & THREAD_ID_MASK; + return ret; +} + +/* Extract the word-offset from the given store-pattern */ +static inline unsigned int extract_word_offset(unsigned int pattern) +{ + unsigned int ret; + + ret = (pattern >> WORD_OFFSET_SHIFT) & WORD_OFFSET_MASK; + + return ret; +} + +/* Extract the sweep-id from the given store-pattern */ +static inline unsigned int extract_sweep_id(unsigned int pattern) + +{ + unsigned int ret; + + ret = (pattern >> SWEEP_ID_SHIFT) & SWEEP_ID_MASK; + + return ret; +} + +/************************************************************ + * * + * Logging the output of the verification * + * * + ************************************************************/ +#define LOGDIR_NAME_SIZE 100 +static char logdir[LOGDIR_NAME_SIZE]; + +static FILE *fp[MAX_THREADS]; +static const char logfilename[] ="Thread-%02d-Chunk"; + +static inline void start_verification_log(unsigned int tid, + unsigned int *addr, + unsigned int cur_sweep_id, + unsigned int prev_sweep_id) +{ + FILE *f; + char logfile[30]; + char path[LOGDIR_NAME_SIZE + 30]; + char separator[2] = "/"; + char *chunk_start = compute_chunk_start_addr(tid); + unsigned int size = RIM_CHUNK_SIZE; + + sprintf(logfile, logfilename, tid); + strcpy(path, logdir); + strcat(path, separator); + strcat(path, logfile); + f = fopen(path, "w"); + + if (!f) { + err_msg("Unable to create logfile\n"); + } + + fp[tid] = f; + + fprintf(f, "----------------------------------------------------------\n"); + fprintf(f, "PID = %d\n", rim_process_pid); + fprintf(f, "Thread id = %02d\n", tid); + fprintf(f, "Chunk Start Addr = 0x%016lx\n", (unsigned long)chunk_start); + fprintf(f, "Chunk Size = %d\n", size); + fprintf(f, "Next Store Addr = 0x%016lx\n", (unsigned long)addr); + fprintf(f, "Current sweep-id = 0x%08x\n", cur_sweep_id); + fprintf(f, "Previous sweep-id = 0x%08x\n", prev_sweep_id); + fprintf(f, "----------------------------------------------------------\n"); +} + +static inline void log_anamoly(unsigned int tid, unsigned int *addr, + unsigned int expected, unsigned int observed) +{ + FILE *f = fp[tid]; + + fprintf(f, "Thread %02d: Addr 0x%lx: Expected 0x%x, Observed 0x%x\n", + tid, (unsigned long)addr, expected, observed); + fprintf(f, "Thread %02d: Expected Thread id = %02d\n", tid, extract_tid(expected)); + fprintf(f, "Thread %02d: Observed Thread id = %02d\n", tid, extract_tid(observed)); + fprintf(f, "Thread %02d: Expected Word offset = %03d\n", tid, extract_word_offset(expected)); + fprintf(f, "Thread %02d: Observed Word offset = %03d\n", tid, extract_word_offset(observed)); + fprintf(f, "Thread %02d: Expected sweep-id = 0x%x\n", tid, extract_sweep_id(expected)); + fprintf(f, "Thread %02d: Observed sweep-id = 0x%x\n", tid, extract_sweep_id(observed)); + fprintf(f, "----------------------------------------------------------\n"); +} + +static inline void end_verification_log(unsigned int tid, unsigned nr_anamolies) +{ + FILE *f = fp[tid]; + char logfile[30]; + char path[LOGDIR_NAME_SIZE + 30]; + char separator[] = "/"; + + fclose(f); + + if (nr_anamolies == 0) { + remove(path); + return; + } + + sprintf(logfile, logfilename, tid); + strcpy(path, logdir); + strcat(path, separator); + strcat(path, logfile); + + printf("Thread %02d chunk has %d corrupted words. For details check %s\n", + tid, nr_anamolies, path); +} + +/* + * When a COMPARE step of a rim-sequence fails, the rim_thread informs + * everyone else via the shared_memory pointed to by + * corruption_found variable. On seeing this, every thread verifies the + * content of its chunk as follows. + * + * Suppose a thread identified with @tid was about to store (but not + * yet stored) to @next_store_addr in its current sweep identified + * @cur_sweep_id. Let @prev_sweep_id indicate the previous sweep_id. + * + * This implies that for all the addresses @addr < @next_store_addr, + * Thread @tid has already performed a store as part of its current + * sweep. Hence we expect the content of such @addr to be: + * |-------------------------------------------------| + * | tid | word_offset(addr) | cur_sweep_id | + * |-------------------------------------------------| + * + * Since Thread @tid is yet to perform stores on address + * @next_store_addr and above, we expect the content of such an + * address @addr to be: + * |-------------------------------------------------| + * | tid | word_offset(addr) | prev_sweep_id | + * |-------------------------------------------------| + * + * The verifier function @verify_chunk does this verification and logs + * any anamolies that it finds. + */ +static void verify_chunk(unsigned int tid, unsigned int *next_store_addr, + unsigned int cur_sweep_id, + unsigned int prev_sweep_id) +{ + unsigned int *iter_ptr; + unsigned int size = RIM_CHUNK_SIZE; + unsigned int expected; + unsigned int observed; + char *chunk_start = compute_chunk_start_addr(tid); + + int nr_anamolies = 0; + + start_verification_log(tid, next_store_addr, + cur_sweep_id, prev_sweep_id); + + for (iter_ptr = (unsigned int *)chunk_start; + (unsigned long)iter_ptr < (unsigned long)chunk_start + size; + iter_ptr++) { + unsigned int expected_sweep_id; + + if (iter_ptr < next_store_addr) { + expected_sweep_id = cur_sweep_id; + } else { + expected_sweep_id = prev_sweep_id; + } + + expected = compute_store_pattern(tid, iter_ptr, expected_sweep_id); + + dcbf((volatile unsigned int*)iter_ptr); //Flush before reading + observed = *iter_ptr; + + if (observed != expected) { + nr_anamolies++; + log_anamoly(tid, iter_ptr, expected, observed); + } + } + + end_verification_log(tid, nr_anamolies); +} + +static void set_pthread_cpu(pthread_t th, int cpu) +{ + cpu_set_t run_cpu_mask; + struct sched_param param; + + CPU_ZERO(&run_cpu_mask); + CPU_SET(cpu, &run_cpu_mask); + pthread_setaffinity_np(th, sizeof(cpu_set_t), &run_cpu_mask); + + param.sched_priority = 1; + if (0 && sched_setscheduler(0, SCHED_FIFO, ¶m) == -1) { + /* haven't reproduced with this setting, it kills random preemption which may be a factor */ + fprintf(stderr, "could not set SCHED_FIFO, run as root?\n"); + } +} + +static void set_mycpu(int cpu) +{ + cpu_set_t run_cpu_mask; + struct sched_param param; + + CPU_ZERO(&run_cpu_mask); + CPU_SET(cpu, &run_cpu_mask); + sched_setaffinity(0, sizeof(cpu_set_t), &run_cpu_mask); + + param.sched_priority = 1; + if (0 && sched_setscheduler(0, SCHED_FIFO, ¶m) == -1) { + fprintf(stderr, "could not set SCHED_FIFO, run as root?\n"); + } +} + +static volatile int segv_wait; + +static void segv_handler(int signo, siginfo_t *info, void *extra) +{ + while (segv_wait) { + sched_yield(); + } + +} + +static void set_segv_handler(void) +{ + struct sigaction sa; + + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = segv_handler; + + if (sigaction(SIGSEGV, &sa, NULL) == -1) { + perror("sigaction"); + exit(EXIT_FAILURE); + } +} + +int timeout = 0; +/* + * This function is executed by every rim_thread. + * + * This function performs sweeps over the exclusive chunks of the + * rim_threads executing the rim-sequence one word at a time. + */ +static void *rim_fn(void *arg) +{ + unsigned int tid = *((unsigned int *)arg); + + int size = RIM_CHUNK_SIZE; + char *chunk_start = compute_chunk_start_addr(tid); + + unsigned int prev_sweep_id; + unsigned int cur_sweep_id = 0; + + /* word access */ + unsigned int pattern = cur_sweep_id; + unsigned int *pattern_ptr = &pattern; + unsigned int *w_ptr, read_data; + + set_segv_handler(); + + /* + * Let us initialize the chunk: + * + * Each word-aligned address addr in the chunk, + * is initialized to : + * |-------------------------------------------------| + * | tid | word_offset(addr) | 0 | + * |-------------------------------------------------| + */ + for (w_ptr = (unsigned int *)chunk_start; + (unsigned long)w_ptr < (unsigned long)(chunk_start) + size; + w_ptr++) { + + *pattern_ptr = compute_store_pattern(tid, w_ptr, cur_sweep_id); + *w_ptr = *pattern_ptr; + } + + while (!corruption_found && !timeout) { + prev_sweep_id = cur_sweep_id; + cur_sweep_id = cur_sweep_id + 1; + + for (w_ptr = (unsigned int *)chunk_start; + (unsigned long)w_ptr < (unsigned long)(chunk_start) + size; + w_ptr++) { + unsigned int old_pattern; + + /* + * Compute the pattern that we would have + * stored at this location in the previous + * sweep. + */ + old_pattern = compute_store_pattern(tid, w_ptr, prev_sweep_id); + + /* + * FLUSH:Ensure that we flush the contents of + * the cache before loading + */ + dcbf((volatile unsigned int*)w_ptr); //Flush + + /* LOAD: Read the value */ + read_data = *w_ptr; //Load + + /* + * COMPARE: Is it the same as what we had stored + * in the previous sweep ? It better be! + */ + if (read_data != old_pattern) { + /* No it isn't! Tell everyone */ + corruption_found = 1; + } + + /* + * Before performing a store, let us check if + * any rim_thread has found a corruption. + */ + if (corruption_found || timeout) { + /* + * Yes. Someone (including us!) has found + * a corruption :( + * + * Let us verify that our chunk is + * correct. + */ + /* But first, let us allow the dust to settle down! */ + verify_chunk(tid, w_ptr, cur_sweep_id, prev_sweep_id); + + return 0; + } + + /* + * Compute the new pattern that we are going + * to write to this location + */ + *pattern_ptr = compute_store_pattern(tid, w_ptr, cur_sweep_id); + + /* + * STORE: Now let us write this pattern into + * the location + */ + *w_ptr = *pattern_ptr; + } + } + + return NULL; +} + + +static unsigned long start_cpu = 0; +static unsigned long nrthreads = 4; + +static pthread_t mem_snapshot_thread; + +static void *mem_snapshot_fn(void *arg) +{ + int page_size = getpagesize(); + size_t size = page_size; + void *tmp = malloc(size); + + while (!corruption_found && !timeout) { + /* Stop memory migration once corruption is found */ + segv_wait = 1; + + mprotect(map1, size, PROT_READ); + + /* + * Load from the working alias (map1). Loading from map2 + * also fails. + */ + memcpy(tmp, map1, size); + + /* + * Stores must go via map2 which has write permissions, but + * the corrupted data tends to be seen in the snapshot buffer, + * so corruption does not appear to be introduced at the + * copy-back via map2 alias here. + */ + memcpy(map2, tmp, size); + /* + * Before releasing other threads, must ensure the copy + * back to + */ + asm volatile("sync" ::: "memory"); + mprotect(map1, size, PROT_READ|PROT_WRITE); + asm volatile("sync" ::: "memory"); + segv_wait = 0; + + usleep(1); /* This value makes a big difference */ + } + + return 0; +} + +void alrm_sighandler(int sig) +{ + timeout = 1; +} + +int main(int argc, char *argv[]) +{ + int c; + int page_size = getpagesize(); + time_t now; + int i, dir_error; + pthread_attr_t attr; + key_t shm_key = (key_t) getpid(); + int shmid, run_time = 20 * 60; + struct sigaction sa_alrm; + + snprintf(logdir, LOGDIR_NAME_SIZE, + "/tmp/logdir-%u", (unsigned int)getpid()); + while ((c = getopt(argc, argv, "r:hn:l:t:")) != -1) { + switch(c) { + case 'r': + start_cpu = strtoul(optarg, NULL, 10); + break; + case 'h': + printf("%s [-r ] [-n ] [-l ] [-t ]\n", argv[0]); + exit(0); + break; + case 'n': + nrthreads = strtoul(optarg, NULL, 10); + break; + case 'l': + strncpy(logdir, optarg, LOGDIR_NAME_SIZE); + break; + case 't': + run_time = strtoul(optarg, NULL, 10); + break; + default: + printf("invalid option\n"); + exit(0); + break; + } + } + + if (nrthreads > MAX_THREADS) + nrthreads = MAX_THREADS; + + shmid = shmget(shm_key, page_size, IPC_CREAT|0666); + if (shmid < 0) { + err_msg("Failed shmget\n"); + } + + map1 = shmat(shmid, NULL, 0); + if (map1 == (void *) -1) { + err_msg("Failed shmat"); + } + + map2 = shmat(shmid, NULL, 0); + if (map2 == (void *) -1) { + err_msg("Failed shmat"); + } + + dir_error = mkdir(logdir, 0755); + + if (dir_error) { + err_msg("Failed mkdir"); + } + + printf("start_cpu list:%lu\n", start_cpu); + printf("number of worker threads:%lu + 1 snapshot thread\n", nrthreads); + printf("Allocated address:0x%016lx + secondary map:0x%016lx\n", (unsigned long)map1, (unsigned long)map2); + printf("logdir at : %s\n", logdir); + printf("Timeout: %d seconds\n", run_time); + + time(&now); + printf("=================================\n"); + printf(" Starting Test\n"); + printf(" %s", ctime(&now)); + printf("=================================\n"); + + for (i = 0; i < nrthreads; i++) { + if (1 && !fork()) { + prctl(PR_SET_PDEATHSIG, SIGKILL); + set_mycpu(start_cpu + i); + for (;;) + sched_yield(); + exit(0); + } + } + + + sa_alrm.sa_handler = &alrm_sighandler; + sigemptyset(&sa_alrm.sa_mask); + sa_alrm.sa_flags = 0; + + if (sigaction(SIGALRM, &sa_alrm, 0) == -1) { + err_msg("Failed signal handler registration\n"); + } + + alarm(run_time); + + pthread_attr_init(&attr); + for (i = 0; i < nrthreads; i++) { + rim_thread_ids[i] = i; + pthread_create(&rim_threads[i], &attr, rim_fn, &rim_thread_ids[i]); + set_pthread_cpu(rim_threads[i], start_cpu + i); + } + + pthread_create(&mem_snapshot_thread, &attr, mem_snapshot_fn, map1); + set_pthread_cpu(mem_snapshot_thread, start_cpu + i); + + + pthread_join(mem_snapshot_thread, NULL); + for (i = 0; i < nrthreads; i++) { + pthread_join(rim_threads[i], NULL); + } + + if (!timeout) { + time(&now); + printf("=================================\n"); + printf(" Data Corruption Detected\n"); + printf(" %s", ctime(&now)); + printf(" See logfiles in %s\n", logdir); + printf("=================================\n"); + return 1; + } + return 0; +} -- cgit v1.2.3-59-g8ed1b From 981c107cbb420ee028f8ecd155352cfd6351c246 Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Tue, 10 Sep 2019 21:11:37 +0100 Subject: selftests/tpm2: Add the missing TEST_FILES assignment The Python files required by the selftests are not packaged because of the missing assignment to TEST_FILES. Add the assignment. Cc: stable@vger.kernel.org Fixes: 6ea3dfe1e073 ("selftests: add TPM 2.0 tests") Signed-off-by: Jarkko Sakkinen Reviewed-by: Petr Vorel --- tools/testing/selftests/tpm2/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/testing/selftests/tpm2/Makefile b/tools/testing/selftests/tpm2/Makefile index 9dd848427a7b..bf401f725eef 100644 --- a/tools/testing/selftests/tpm2/Makefile +++ b/tools/testing/selftests/tpm2/Makefile @@ -2,3 +2,4 @@ include ../lib.mk TEST_PROGS := test_smoke.sh test_space.sh +TEST_FILES := tpm2.py tpm2_tests.py -- cgit v1.2.3-59-g8ed1b From 34cd83bb8a468b24d9a13adbfb5ad645c552b8e2 Mon Sep 17 00:00:00 2001 From: Petr Vorel Date: Wed, 11 Sep 2019 11:34:42 +0200 Subject: selftests/tpm2: Add log and *.pyc to .gitignore Fixes: 6ea3dfe1e073 ("selftests: add TPM 2.0 tests") Signed-off-by: Petr Vorel Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- tools/testing/selftests/.gitignore | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/.gitignore b/tools/testing/selftests/.gitignore index 8059ce834247..61df01cdf0b2 100644 --- a/tools/testing/selftests/.gitignore +++ b/tools/testing/selftests/.gitignore @@ -2,3 +2,5 @@ gpiogpio-event-mon gpiogpio-hammer gpioinclude/ gpiolsgpio +tpm2/SpaceTest.log +tpm2/*.pyc -- cgit v1.2.3-59-g8ed1b From faef87494139cf2cc4d188d5730251ade9b2022d Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Thu, 19 Sep 2019 15:43:02 -0500 Subject: perf vendor events amd: Add L3 cache events for Family 17h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow users to symbolically specify L3 events for Family 17h processors using the existing AMD Uncore driver. Source of events descriptions are from section 2.1.15.4.1 "L3 Cache PMC Events" of the latest Family 17h PPR, available here: https://www.amd.com/system/files/TechDocs/55570-B1_PUB.zip Opnly BriefDescriptions added, since they show with and without the -v and --details flags. Tested with: # perf stat -e l3_request_g1.caching_l3_cache_accesses,amd_l3/event=0x01,umask=0x80/,l3_comb_clstr_state.request_miss,amd_l3/event=0x06,umask=0x01/ perf bench mem memcpy -s 4mb -l 100 -f default ... 7,006,831 l3_request_g1.caching_l3_cache_accesses 7,006,830 amd_l3/event=0x01,umask=0x80/ 366,530 l3_comb_clstr_state.request_miss 366,568 amd_l3/event=0x06,umask=0x01/ Signed-off-by: Kim Phillips Reviewed-by: Andi Kleen Cc: Alexander Shishkin Cc: Andi Kleen Cc: Borislav Petkov Cc: Janakarajan Natarajan Cc: Jin Yao Cc: Jiri Olsa Cc: Kan Liang Cc: Luke Mujica Cc: Martin LiÅ¡ka Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190919204306.12598-1-kim.phillips@amd.com Signed-off-by: Arnaldo Carvalho de Melo --- .../perf/pmu-events/arch/x86/amdfam17h/cache.json | 42 ++++++++++++++++++++++ tools/perf/pmu-events/jevents.c | 1 + 2 files changed, 43 insertions(+) (limited to 'tools') diff --git a/tools/perf/pmu-events/arch/x86/amdfam17h/cache.json b/tools/perf/pmu-events/arch/x86/amdfam17h/cache.json index fad4af9142cb..6221a840fcea 100644 --- a/tools/perf/pmu-events/arch/x86/amdfam17h/cache.json +++ b/tools/perf/pmu-events/arch/x86/amdfam17h/cache.json @@ -283,5 +283,47 @@ "BriefDescription": "Total cycles spent with one or more fill requests in flight from L2.", "PublicDescription": "Total cycles spent with one or more fill requests in flight from L2.", "UMask": "0x1" + }, + { + "EventName": "l3_request_g1.caching_l3_cache_accesses", + "EventCode": "0x01", + "BriefDescription": "Caching: L3 cache accesses", + "UMask": "0x80", + "Unit": "L3PMC" + }, + { + "EventName": "l3_lookup_state.all_l3_req_typs", + "EventCode": "0x04", + "BriefDescription": "All L3 Request Types", + "UMask": "0xff", + "Unit": "L3PMC" + }, + { + "EventName": "l3_comb_clstr_state.other_l3_miss_typs", + "EventCode": "0x06", + "BriefDescription": "Other L3 Miss Request Types", + "UMask": "0xfe", + "Unit": "L3PMC" + }, + { + "EventName": "l3_comb_clstr_state.request_miss", + "EventCode": "0x06", + "BriefDescription": "L3 cache misses", + "UMask": "0x01", + "Unit": "L3PMC" + }, + { + "EventName": "xi_sys_fill_latency", + "EventCode": "0x90", + "BriefDescription": "L3 Cache Miss Latency. Total cycles for all transactions divided by 16. Ignores SliceMask and ThreadMask.", + "UMask": "0x00", + "Unit": "L3PMC" + }, + { + "EventName": "xi_ccx_sdp_req1.all_l3_miss_req_typs", + "EventCode": "0x9a", + "BriefDescription": "All L3 Miss Request Types. Ignores SliceMask and ThreadMask.", + "UMask": "0x3f", + "Unit": "L3PMC" } ] diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index d413761621b0..9e37287da924 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -239,6 +239,7 @@ static struct map { { "hisi_sccl,ddrc", "hisi_sccl,ddrc" }, { "hisi_sccl,hha", "hisi_sccl,hha" }, { "hisi_sccl,l3c", "hisi_sccl,l3c" }, + { "L3PMC", "amd_l3" }, {} }; -- cgit v1.2.3-59-g8ed1b From 0c03d3aa255b5d3a7b64051a79f6e9f487194a9f Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Thu, 19 Sep 2019 15:43:03 -0500 Subject: perf vendor events amd: Remove redundant '[' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the redundant '['. 'perf list' output before: ex_ret_brn [[Retired Branch Instructions] 'perf list' output after: ex_ret_brn [Retired Branch Instructions] Fixes: 98c07a8f74f8 ("perf vendor events amd: perf PMU events for AMD Family 17h") Signed-off-by: Kim Phillips Reviewed-by: Andi Kleen Cc: Alexander Shishkin Cc: Borislav Petkov Cc: Janakarajan Natarajan Cc: Jin Yao Cc: Jiri Olsa Cc: Kan Liang Cc: Luke Mujica Cc: Martin LiÅ¡ka Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190919204306.12598-2-kim.phillips@amd.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/pmu-events/arch/x86/amdfam17h/core.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/pmu-events/arch/x86/amdfam17h/core.json b/tools/perf/pmu-events/arch/x86/amdfam17h/core.json index 7b285b0a7f35..1079544eeed5 100644 --- a/tools/perf/pmu-events/arch/x86/amdfam17h/core.json +++ b/tools/perf/pmu-events/arch/x86/amdfam17h/core.json @@ -13,7 +13,7 @@ { "EventName": "ex_ret_brn", "EventCode": "0xc2", - "BriefDescription": "[Retired Branch Instructions.", + "BriefDescription": "Retired Branch Instructions.", "PublicDescription": "The number of branch instructions retired. This includes all types of architectural control flow changes, including exceptions and interrupts." }, { -- cgit v1.2.3-59-g8ed1b From 93125562ce385fc0322e010003767d656677bdef Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Thu, 19 Sep 2019 15:43:04 -0500 Subject: perf vendor events: Minor fixes to the README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some grammatical fixes, and updates to some path references that have since changed. Signed-off-by: Kim Phillips Reviewed-by: Andi Kleen Cc: Alexander Shishkin Cc: Borislav Petkov Cc: Janakarajan Natarajan Cc: Jin Yao Cc: Jiri Olsa Cc: Kan Liang Cc: Luke Mujica Cc: Martin LiÅ¡ka Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190919204306.12598-3-kim.phillips@amd.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/pmu-events/README | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/perf/pmu-events/README b/tools/perf/pmu-events/README index e62b09b6a844..de7efa2cebd1 100644 --- a/tools/perf/pmu-events/README +++ b/tools/perf/pmu-events/README @@ -30,9 +30,9 @@ the topic. Eg: "Floating-point.json". All the topic JSON files for a CPU model/family should be in a separate sub directory. Thus for the Silvermont X86 CPU: - $ ls tools/perf/pmu-events/arch/x86/Silvermont_core - Cache.json Memory.json Virtual-Memory.json - Frontend.json Pipeline.json + $ ls tools/perf/pmu-events/arch/x86/silvermont + cache.json memory.json virtual-memory.json + frontend.json pipeline.json The JSONs folder for a CPU model/family may be placed in the root arch folder, or may be placed in a vendor sub-folder under the arch folder @@ -94,7 +94,7 @@ users to specify events by their name: where 'pm_1plus_ppc_cmpl' is a Power8 PMU event. -However some errors in processing may cause the perf build to fail. +However some errors in processing may cause the alias build to fail. Mapfile format =============== @@ -119,7 +119,7 @@ where: Header line The header line is the first line in the file, which is - always _IGNORED_. It can empty. + always _IGNORED_. It can be empty. CPUID: CPUID is an arch-specific char string, that can be used @@ -138,15 +138,15 @@ where: files, relative to the directory containing the mapfile.csv Type: - indicates whether the events or "core" or "uncore" events. + indicates whether the events are "core" or "uncore" events. Eg: - $ grep Silvermont tools/perf/pmu-events/arch/x86/mapfile.csv - GenuineIntel-6-37,V13,Silvermont_core,core - GenuineIntel-6-4D,V13,Silvermont_core,core - GenuineIntel-6-4C,V13,Silvermont_core,core + $ grep silvermont tools/perf/pmu-events/arch/x86/mapfile.csv + GenuineIntel-6-37,v13,silvermont,core + GenuineIntel-6-4D,v13,silvermont,core + GenuineIntel-6-4C,v13,silvermont,core i.e the three CPU models use the JSON files (i.e PMU events) listed - in the directory 'tools/perf/pmu-events/arch/x86/Silvermont_core'. + in the directory 'tools/perf/pmu-events/arch/x86/silvermont'. -- cgit v1.2.3-59-g8ed1b From 8788d36950dae26074dc63b46eab3debb4b210b4 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Thu, 19 Sep 2019 15:43:05 -0500 Subject: perf list: Allow plurals for metric, metricgroup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enhance usability by allowing the same plurality used in the output title, for the command line parameter. BEFORE, perf deceitfully acts as if there are no metrics to be had: $ perf list metrics List of pre-defined events (to be used in -e): Metric Groups: $ But singular 'metric' shows a list of metrics: $ perf list metric List of pre-defined events (to be used in -e): Metrics: IPC [Instructions Per Cycle (per logical thread)] UPI [Uops Per Instruction] AFTER, when asking for 'metrics', we actually see the metrics get listed: $ perf list metrics List of pre-defined events (to be used in -e): Metrics: IPC [Instructions Per Cycle (per logical thread)] UPI [Uops Per Instruction] Fixes: 71b0acce78d1 ("perf list: Add metric groups to perf list") Signed-off-by: Kim Phillips Reviewed-by: Andi Kleen Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Borislav Petkov Cc: Janakarajan Natarajan Cc: Jin Yao Cc: Jiri Olsa Cc: Kan Liang Cc: Luke Mujica Cc: Martin LiÅ¡ka Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190919204306.12598-4-kim.phillips@amd.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-list.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index e290f6b348d8..08e62ae9d37e 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -81,9 +81,9 @@ int cmd_list(int argc, const char **argv) long_desc_flag, details_flag); else if (strcmp(argv[i], "sdt") == 0) print_sdt_events(NULL, NULL, raw_dump); - else if (strcmp(argv[i], "metric") == 0) + else if (strcmp(argv[i], "metric") == 0 || strcmp(argv[i], "metrics") == 0) metricgroup__print(true, false, NULL, raw_dump, details_flag); - else if (strcmp(argv[i], "metricgroup") == 0) + else if (strcmp(argv[i], "metricgroup") == 0 || strcmp(argv[i], "metricgroups") == 0) metricgroup__print(false, true, NULL, raw_dump, details_flag); else if ((sep = strchr(argv[i], ':')) != NULL) { int sep_idx; -- cgit v1.2.3-59-g8ed1b From 5c8da72dc21eff32deb00638e547e2c247ebbfb0 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Thu, 19 Sep 2019 16:51:19 -0400 Subject: libtraceevent: Round up in tep_print_event() time precision When testing the output of the old trace-cmd compared to the one that uses the updated tep_print_event() logic, it was different in that the time stamp precision in the old format would round up to the nearest precision, where as the new logic truncates. Bring back the old method of rounding up. Signed-off-by: Steven Rostedt (VMware) Cc: Jiri Olsa Cc: Tzvetomir Stoyanov Cc: linux trace devel Link: http://lore.kernel.org/lkml/20190919165119.5efa5de6@gandalf.local.home Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 6f842af4550b..d948475585ce 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -5527,8 +5527,10 @@ static void print_event_time(struct tep_handle *tep, struct trace_seq *s, if (divstr && isdigit(*(divstr + 1))) div = atoi(divstr + 1); time = record->ts; - if (div) + if (div) { + time += div / 2; time /= div; + } pr = prec; while (pr--) p10 *= 10; -- cgit v1.2.3-59-g8ed1b From 4ab91deacc9b8611fdae9055f926c8f99dde8411 Mon Sep 17 00:00:00 2001 From: Tzvetomir Stoyanov Date: Thu, 19 Sep 2019 17:23:36 -0400 Subject: libtraceevent: Man pages for libtraceevent event print related API Added new man page, describing tep_print_event() libtraceevent API. Signed-off-by: Tzvetomir Stoyanov Cc: Andrew Morton Cc: Jiri Olsa Cc: Namhyung Kim Cc: linux-trace-devel@vger.kernel.org Link: http://lore.kernel.org/linux-trace-devel/20190801075012.22098-1-tz.stoyanov@gmail.com Link: http://lore.kernel.org/lkml/20190919212541.553160178@goodmis.org Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Arnaldo Carvalho de Melo --- .../Documentation/libtraceevent-event_print.txt | 130 +++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 tools/lib/traceevent/Documentation/libtraceevent-event_print.txt (limited to 'tools') diff --git a/tools/lib/traceevent/Documentation/libtraceevent-event_print.txt b/tools/lib/traceevent/Documentation/libtraceevent-event_print.txt new file mode 100644 index 000000000000..2c6a61811118 --- /dev/null +++ b/tools/lib/traceevent/Documentation/libtraceevent-event_print.txt @@ -0,0 +1,130 @@ +libtraceevent(3) +================ + +NAME +---- +tep_print_event - Writes event information into a trace sequence. + +SYNOPSIS +-------- +[verse] +-- +*#include * +*#include * + +void *tep_print_event*(struct tep_handle pass:[*]_tep_, struct trace_seqpass:[*]_s_, struct tep_record pass:[*]_record_, const char pass:[*]_fmt_, _..._) +-- + +DESCRIPTION +----------- + +The _tep_print_event()_ function parses the event information of the given +_record_ and writes it into the trace sequence _s_, according to the format +string _fmt_. The desired information is specified after the format string. +The _fmt_ is printf-like format string, following arguments are supported: +[verse] +-- + TEP_PRINT_PID, "%d" - PID of the event. + TEP_PRINT_CPU, "%d" - Event CPU. + TEP_PRINT_COMM, "%s" - Event command string. + TEP_PRINT_NAME, "%s" - Event name. + TEP_PRINT_LATENCY, "%s" - Latency of the event. It prints 4 or more + fields - interrupt state, scheduling state, + current context, and preemption count. + Field 1 is the interrupt enabled state: + d : Interrupts are disabled + . : Interrupts are enabled + X : The architecture does not support this + information + Field 2 is the "need resched" state. + N : The task is set to call the scheduler when + possible, as another higher priority task + may need to be scheduled in. + . : The task is not set to call the scheduler. + Field 3 is the context state. + . : Normal context + s : Soft interrupt context + h : Hard interrupt context + H : Hard interrupt context which triggered + during soft interrupt context. + z : NMI context + Z : NMI context which triggered during hard + interrupt context + Field 4 is the preemption count. + . : The preempt count is zero. + On preemptible kernels (where the task can be scheduled + out in arbitrary locations while in kernel context), the + preempt count, when non zero, will prevent the kernel + from scheduling out the current task. The preempt count + number is displayed when it is not zero. + Depending on the kernel, it may show other fields + (lock depth, or migration disabled, which are unique to + specialized kernels). + TEP_PRINT_TIME, %d - event time stamp. A divisor and precision can be + specified as part of this format string: + "%precision.divisord". Example: + "%3.1000d" - divide the time by 1000 and print the first + 3 digits before the dot. Thus, the time stamp + "123456000" will be printed as "123.456" + TEP_PRINT_INFO, "%s" - event information. + TEP_PRINT_INFO_RAW, "%s" - event information, in raw format. + +-- +EXAMPLE +------- +[source,c] +-- +#include +#include +... +struct trace_seq seq; +trace_seq_init(&seq); +struct tep_handle *tep = tep_alloc(); +... +void print_my_event(struct tep_record *record) +{ + trace_seq_reset(&seq); + tep_print_event(tep, s, record, "%16s-%-5d [%03d] %s %6.1000d %s %s", + TEP_PRINT_COMM, TEP_PRINT_PID, TEP_PRINT_CPU, + TEP_PRINT_LATENCY, TEP_PRINT_TIME, TEP_PRINT_NAME, + TEP_PRINT_INFO); +} +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*trace-seq.h* + Header file to include in order to have access to trace sequences related APIs. + Trace sequences are used to allow a function to call several other functions + to create a string of data to use. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +_libtraceevent(3)_, _trace-cmd(1)_ + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* , author of *libtraceevent*. +*Tzvetomir Stoyanov* , author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git -- cgit v1.2.3-59-g8ed1b From 38f76c31368b7a8b88659c178f9e620b02660a70 Mon Sep 17 00:00:00 2001 From: "Tzvetomir Stoyanov (VMware)" Date: Thu, 19 Sep 2019 17:23:37 -0400 Subject: libtraceevent: Man pages fix, rename tep_ref_get() to tep_get_ref() The tep_ref_get() was renamed to tep_get_ref(), to be more consistent with the other tep_ref_* APIs. However, in the man pages the API is still with the old name. The documentation is fixed to reflect the actual name of the API. Signed-off-by: Tzvetomir Stoyanov (VMware) Cc: Andrew Morton Cc: Jiri Olsa Cc: Namhyung Kim Cc: Tzvetomir Stoyanov (VMware) Cc: linux-trace-devel@vger.kernel.org Link: http://lore.kernel.org/linux-trace-devel/20190808113636.13299-2-tz.stoyanov@gmail.com Link: http://lore.kernel.org/lkml/20190919212541.697034573@goodmis.org Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/Documentation/libtraceevent-handle.txt | 8 ++++---- tools/lib/traceevent/Documentation/libtraceevent.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/lib/traceevent/Documentation/libtraceevent-handle.txt b/tools/lib/traceevent/Documentation/libtraceevent-handle.txt index 8d568316847d..45b20172e262 100644 --- a/tools/lib/traceevent/Documentation/libtraceevent-handle.txt +++ b/tools/lib/traceevent/Documentation/libtraceevent-handle.txt @@ -3,7 +3,7 @@ libtraceevent(3) NAME ---- -tep_alloc, tep_free,tep_ref, tep_unref,tep_ref_get - Create, destroy, manage +tep_alloc, tep_free,tep_ref, tep_unref,tep_get_ref - Create, destroy, manage references of trace event parser context. SYNOPSIS @@ -16,7 +16,7 @@ struct tep_handle pass:[*]*tep_alloc*(void); void *tep_free*(struct tep_handle pass:[*]_tep_); void *tep_ref*(struct tep_handle pass:[*]_tep_); void *tep_unref*(struct tep_handle pass:[*]_tep_); -int *tep_ref_get*(struct tep_handle pass:[*]_tep_); +int *tep_get_ref*(struct tep_handle pass:[*]_tep_); -- DESCRIPTION @@ -57,9 +57,9 @@ EXAMPLE ... struct tep_handle *tep = tep_alloc(); ... -int ref = tep_ref_get(tep); +int ref = tep_get_ref(tep); tep_ref(tep); -if ( (ref+1) != tep_ref_get(tep)) { +if ( (ref+1) != tep_get_ref(tep)) { /* Something wrong happened, the counter is not incremented by 1 */ } tep_unref(tep); diff --git a/tools/lib/traceevent/Documentation/libtraceevent.txt b/tools/lib/traceevent/Documentation/libtraceevent.txt index fbd977b47de1..00519503c8de 100644 --- a/tools/lib/traceevent/Documentation/libtraceevent.txt +++ b/tools/lib/traceevent/Documentation/libtraceevent.txt @@ -16,7 +16,7 @@ Management of tep handler data structure and access of its members: void *tep_free*(struct tep_handle pass:[*]_tep_); void *tep_ref*(struct tep_handle pass:[*]_tep_); void *tep_unref*(struct tep_handle pass:[*]_tep_); - int *tep_ref_get*(struct tep_handle pass:[*]_tep_); + int *tep_get_ref*(struct tep_handle pass:[*]_tep_); void *tep_set_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_); void *tep_clear_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_); bool *tep_test_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flags_); -- cgit v1.2.3-59-g8ed1b From f8d16387fffba1c7c88b5570b09891ba8a26cfd5 Mon Sep 17 00:00:00 2001 From: "Tzvetomir Stoyanov (VMware)" Date: Thu, 19 Sep 2019 17:23:38 -0400 Subject: libtraceevent: Man pages fix, changes in event printing APIs APIs for printing various trace event information were redesigned to be more simple. However, the main libtraceevent man page was not updated with those changes. The documentation is updated to describe the new event print API. Signed-off-by: Tzvetomir Stoyanov (VMware) Cc: Andrew Morton Cc: Jiri Olsa Cc: Namhyung Kim Cc: Tzvetomir Stoyanov (VMware) Cc: linux-trace-devel@vger.kernel.org Link: http://lore.kernel.org/linux-trace-devel/20190808113636.13299-3-tz.stoyanov@gmail.com Link: http://lore.kernel.org/lkml/20190919212541.869643036@goodmis.org Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/Documentation/libtraceevent.txt | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/lib/traceevent/Documentation/libtraceevent.txt b/tools/lib/traceevent/Documentation/libtraceevent.txt index 00519503c8de..d530a7ce8fb2 100644 --- a/tools/lib/traceevent/Documentation/libtraceevent.txt +++ b/tools/lib/traceevent/Documentation/libtraceevent.txt @@ -26,15 +26,12 @@ Management of tep handler data structure and access of its members: void *tep_set_long_size*(struct tep_handle pass:[*]_tep_, int _long_size_); int *tep_get_page_size*(struct tep_handle pass:[*]_tep_); void *tep_set_page_size*(struct tep_handle pass:[*]_tep_, int _page_size_); - bool *tep_is_latency_format*(struct tep_handle pass:[*]_tep_); - void *tep_set_latency_format*(struct tep_handle pass:[*]_tep_, int _lat_); int *tep_get_header_page_size*(struct tep_handle pass:[*]_tep_); int *tep_get_header_timestamp_size*(struct tep_handle pass:[*]_tep_); bool *tep_is_old_format*(struct tep_handle pass:[*]_tep_); int *tep_strerror*(struct tep_handle pass:[*]_tep_, enum tep_errno _errnum_, char pass:[*]_buf_, size_t _buflen_); Register / unregister APIs: - int *tep_register_trace_clock*(struct tep_handle pass:[*]_tep_, const char pass:[*]_trace_clock_); int *tep_register_function*(struct tep_handle pass:[*]_tep_, char pass:[*]_name_, unsigned long long _addr_, char pass:[*]_mod_); int *tep_register_event_handler*(struct tep_handle pass:[*]_tep_, int _id_, const char pass:[*]_sys_name_, const char pass:[*]_event_name_, tep_event_handler_func _func_, void pass:[*]_context_); int *tep_unregister_event_handler*(struct tep_handle pass:[*]tep, int id, const char pass:[*]sys_name, const char pass:[*]event_name, tep_event_handler_func func, void pass:[*]_context_); @@ -57,14 +54,7 @@ Event related APIs: int *tep_get_events_count*(struct tep_handle pass:[*]_tep_); struct tep_event pass:[*]pass:[*]*tep_list_events*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_); struct tep_event pass:[*]pass:[*]*tep_list_events_copy*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_); - -Event printing: - void *tep_print_event*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_record pass:[*]_record_, bool _use_trace_clock_); - void *tep_print_event_data*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, struct tep_record pass:[*]_record_); - void *tep_event_info*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, struct tep_record pass:[*]_record_); - void *tep_print_event_task*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, struct tep_record pass:[*]_record_); - void *tep_print_event_time*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, struct tep_record pass:[*]record, bool _use_trace_clock_); - void *tep_set_print_raw*(struct tep_handle pass:[*]_tep_, int _print_raw_); + void *tep_print_event*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_record pass:[*]_record_, const char pass:[*]_fmt_, _..._); Event finding: struct tep_event pass:[*]*tep_find_event*(struct tep_handle pass:[*]_tep_, int _id_); @@ -116,7 +106,6 @@ Filter management: int *tep_filter_compare*(struct tep_event_filter pass:[*]_filter1_, struct tep_event_filter pass:[*]_filter2_); Parsing various data from the records: - void *tep_data_latency_format*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_record pass:[*]_record_); int *tep_data_type*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); int *tep_data_pid*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); int *tep_data_preempt_count*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); -- cgit v1.2.3-59-g8ed1b From d69094f364d012f6d0be712969e6a6a355b69e84 Mon Sep 17 00:00:00 2001 From: "Tzvetomir Stoyanov (VMware)" Date: Thu, 19 Sep 2019 17:23:39 -0400 Subject: libtraceevent: Add tep_get_event() in event-parse.h The tep_get_event() function is an official libtracevent API, described in the library man pages. However, it cannot be used by the library users because it is not declared in the event-parse.h file, where all libtracevent APIs are. The function declaration is added in event-parse.h file. Signed-off-by: Tzvetomir Stoyanov (VMware) Cc: Andrew Morton Cc: Jiri Olsa Cc: Namhyung Kim Cc: Tzvetomir Stoyanov (VMware) Cc: linux-trace-devel@vger.kernel.org Link: http://lore.kernel.org/linux-trace-devel/20190808113721.13539-1-tz.stoyanov@gmail.com Link: http://lore.kernel.org/lkml/20190919212542.058025937@goodmis.org Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index d438ee44289f..b77837f75a0d 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h @@ -441,6 +441,8 @@ int tep_register_print_string(struct tep_handle *tep, const char *fmt, unsigned long long addr); bool tep_is_pid_registered(struct tep_handle *tep, int pid); +struct tep_event *tep_get_event(struct tep_handle *tep, int index); + #define TEP_PRINT_INFO "INFO" #define TEP_PRINT_INFO_RAW "INFO_RAW" #define TEP_PRINT_COMM "COMM" -- cgit v1.2.3-59-g8ed1b From 077faf3dc7cc13c3bd784613304bf38696b591da Mon Sep 17 00:00:00 2001 From: "Tzvetomir Stoyanov (VMware)" Date: Thu, 19 Sep 2019 17:23:41 -0400 Subject: libtraceevent: Move traceevent plugins in its own subdirectory All traceevent plugins code is moved to tools/lib/traceevent/plugins subdirectory. It makes traceevent implementation in trace-cmd and in kernel tree consistent. There is no changes in the way libtraceevent and plugins are compiled and installed. Committer notes: Applied fixup provided by Steven, fixing the tools/perf/Makefile.perf target for the plugin dynamic list file. Problem noticed when cross building to aarch64 from a Ubuntu 19.04 container. Suggested-by: Steven Rostedt (VMware) Signed-off-by: Tzvetomir Stoyanov (VMware) Cc: Andrew Morton Cc: Jiri Olsa Cc: Namhyung Kim Cc: Tzvetomir Stoyanov (VMware) Cc: linux-trace-devel@vger.kernel.org Link: http://lore.kernel.org/lkml/20190923115929.453b68f1@oasis.local.home Link: http://lore.kernel.org/lkml/20190919212542.377333393@goodmis.org Link: http://lore.kernel.org/linux-trace-devel/20190917105055.18983-1-tz.stoyanov@gmail.com Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/Build | 11 - tools/lib/traceevent/Makefile | 94 +--- tools/lib/traceevent/plugin_cfg80211.c | 43 -- tools/lib/traceevent/plugin_function.c | 195 -------- tools/lib/traceevent/plugin_hrtimer.c | 89 ---- tools/lib/traceevent/plugin_jbd2.c | 76 --- tools/lib/traceevent/plugin_kmem.c | 95 ---- tools/lib/traceevent/plugin_kvm.c | 523 --------------------- tools/lib/traceevent/plugin_mac80211.c | 103 ---- tools/lib/traceevent/plugin_sched_switch.c | 161 ------- tools/lib/traceevent/plugin_scsi.c | 434 ----------------- tools/lib/traceevent/plugin_xen.c | 138 ------ tools/lib/traceevent/plugins/Build | 10 + tools/lib/traceevent/plugins/Makefile | 222 +++++++++ tools/lib/traceevent/plugins/plugin_cfg80211.c | 43 ++ tools/lib/traceevent/plugins/plugin_function.c | 195 ++++++++ tools/lib/traceevent/plugins/plugin_hrtimer.c | 89 ++++ tools/lib/traceevent/plugins/plugin_jbd2.c | 76 +++ tools/lib/traceevent/plugins/plugin_kmem.c | 95 ++++ tools/lib/traceevent/plugins/plugin_kvm.c | 523 +++++++++++++++++++++ tools/lib/traceevent/plugins/plugin_mac80211.c | 103 ++++ tools/lib/traceevent/plugins/plugin_sched_switch.c | 161 +++++++ tools/lib/traceevent/plugins/plugin_scsi.c | 434 +++++++++++++++++ tools/lib/traceevent/plugins/plugin_xen.c | 138 ++++++ tools/perf/Makefile.perf | 4 +- 25 files changed, 2107 insertions(+), 1948 deletions(-) delete mode 100644 tools/lib/traceevent/plugin_cfg80211.c delete mode 100644 tools/lib/traceevent/plugin_function.c delete mode 100644 tools/lib/traceevent/plugin_hrtimer.c delete mode 100644 tools/lib/traceevent/plugin_jbd2.c delete mode 100644 tools/lib/traceevent/plugin_kmem.c delete mode 100644 tools/lib/traceevent/plugin_kvm.c delete mode 100644 tools/lib/traceevent/plugin_mac80211.c delete mode 100644 tools/lib/traceevent/plugin_sched_switch.c delete mode 100644 tools/lib/traceevent/plugin_scsi.c delete mode 100644 tools/lib/traceevent/plugin_xen.c create mode 100644 tools/lib/traceevent/plugins/Build create mode 100644 tools/lib/traceevent/plugins/Makefile create mode 100644 tools/lib/traceevent/plugins/plugin_cfg80211.c create mode 100644 tools/lib/traceevent/plugins/plugin_function.c create mode 100644 tools/lib/traceevent/plugins/plugin_hrtimer.c create mode 100644 tools/lib/traceevent/plugins/plugin_jbd2.c create mode 100644 tools/lib/traceevent/plugins/plugin_kmem.c create mode 100644 tools/lib/traceevent/plugins/plugin_kvm.c create mode 100644 tools/lib/traceevent/plugins/plugin_mac80211.c create mode 100644 tools/lib/traceevent/plugins/plugin_sched_switch.c create mode 100644 tools/lib/traceevent/plugins/plugin_scsi.c create mode 100644 tools/lib/traceevent/plugins/plugin_xen.c (limited to 'tools') diff --git a/tools/lib/traceevent/Build b/tools/lib/traceevent/Build index ba54bfce0b0b..f9a5d79578f5 100644 --- a/tools/lib/traceevent/Build +++ b/tools/lib/traceevent/Build @@ -6,14 +6,3 @@ libtraceevent-y += parse-utils.o libtraceevent-y += kbuffer-parse.o libtraceevent-y += tep_strerror.o libtraceevent-y += event-parse-api.o - -plugin_jbd2-y += plugin_jbd2.o -plugin_hrtimer-y += plugin_hrtimer.o -plugin_kmem-y += plugin_kmem.o -plugin_kvm-y += plugin_kvm.o -plugin_mac80211-y += plugin_mac80211.o -plugin_sched_switch-y += plugin_sched_switch.o -plugin_function-y += plugin_function.o -plugin_xen-y += plugin_xen.o -plugin_scsi-y += plugin_scsi.o -plugin_cfg80211-y += plugin_cfg80211.o diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index a39cdd0d890d..5315f3787f8d 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile @@ -58,30 +58,6 @@ export man_dir man_dir_SQ INSTALL export DESTDIR DESTDIR_SQ export EVENT_PARSE_VERSION -set_plugin_dir := 1 - -# Set plugin_dir to preffered global plugin location -# If we install under $HOME directory we go under -# $(HOME)/.local/lib/traceevent/plugins -# -# We dont set PLUGIN_DIR in case we install under $HOME -# directory, because by default the code looks under: -# $(HOME)/.local/lib/traceevent/plugins by default. -# -ifeq ($(plugin_dir),) -ifeq ($(prefix),$(HOME)) -override plugin_dir = $(HOME)/.local/lib/traceevent/plugins -set_plugin_dir := 0 -else -override plugin_dir = $(libdir)/traceevent/plugins -endif -endif - -ifeq ($(set_plugin_dir),1) -PLUGIN_DIR = -DPLUGIN_DIR="$(plugin_dir)" -PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))' -endif - include ../../scripts/Makefile.include # copy a bit from Linux kbuild @@ -105,7 +81,6 @@ export prefix libdir src obj # Shell quotes libdir_SQ = $(subst ','\'',$(libdir)) libdir_relative_SQ = $(subst ','\'',$(libdir_relative)) -plugin_dir_SQ = $(subst ','\'',$(plugin_dir)) CONFIG_INCLUDES = CONFIG_LIBS = @@ -151,29 +126,14 @@ MAKEOVERRIDES= export srctree OUTPUT CC LD CFLAGS V build := -f $(srctree)/tools/build/Makefile.build dir=. obj -PLUGINS = plugin_jbd2.so -PLUGINS += plugin_hrtimer.so -PLUGINS += plugin_kmem.so -PLUGINS += plugin_kvm.so -PLUGINS += plugin_mac80211.so -PLUGINS += plugin_sched_switch.so -PLUGINS += plugin_function.so -PLUGINS += plugin_xen.so -PLUGINS += plugin_scsi.so -PLUGINS += plugin_cfg80211.so - -PLUGINS := $(addprefix $(OUTPUT),$(PLUGINS)) -PLUGINS_IN := $(PLUGINS:.so=-in.o) - TE_IN := $(OUTPUT)libtraceevent-in.o LIB_TARGET := $(addprefix $(OUTPUT),$(LIB_TARGET)) -DYNAMIC_LIST_FILE := $(OUTPUT)libtraceevent-dynamic-list -CMD_TARGETS = $(LIB_TARGET) $(PLUGINS) $(DYNAMIC_LIST_FILE) +CMD_TARGETS = $(LIB_TARGET) TARGETS = $(CMD_TARGETS) -all: all_cmd +all: all_cmd plugins all_cmd: $(CMD_TARGETS) @@ -188,17 +148,6 @@ $(OUTPUT)libtraceevent.so.$(EVENT_PARSE_VERSION): $(TE_IN) $(OUTPUT)libtraceevent.a: $(TE_IN) $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ -$(OUTPUT)libtraceevent-dynamic-list: $(PLUGINS) - $(QUIET_GEN)$(call do_generate_dynamic_list_file, $(PLUGINS), $@) - -plugins: $(PLUGINS) - -__plugin_obj = $(notdir $@) - plugin_obj = $(__plugin_obj:-in.o=) - -$(PLUGINS_IN): force - $(Q)$(MAKE) $(build)=$(plugin_obj) - $(OUTPUT)%.so: $(OUTPUT)%-in.o $(QUIET_LINK)$(CC) $(CFLAGS) -shared $(LDFLAGS) -nostartfiles -o $@ $^ @@ -258,25 +207,6 @@ define do_install $(INSTALL) $(if $3,-m $3,) $1 '$(DESTDIR_SQ)$2' endef -define do_install_plugins - for plugin in $1; do \ - $(call do_install,$$plugin,$(plugin_dir_SQ)); \ - done -endef - -define do_generate_dynamic_list_file - symbol_type=`$(NM) -u -D $1 | awk 'NF>1 {print $$1}' | \ - xargs echo "U w W" | tr 'w ' 'W\n' | sort -u | xargs echo`;\ - if [ "$$symbol_type" = "U W" ];then \ - (echo '{'; \ - $(NM) -u -D $1 | awk 'NF>1 {print "\t"$$2";"}' | sort -u;\ - echo '};'; \ - ) > $2; \ - else \ - (echo Either missing one of [$1] or bad version of $(NM)) 1>&2;\ - fi -endef - PKG_CONFIG_FILE = libtraceevent.pc define do_install_pkgconfig_file if [ -n "${pkgconfig_dir}" ]; then \ @@ -296,10 +226,6 @@ install_lib: all_cmd install_plugins install_headers install_pkgconfig $(call do_install_mkdir,$(libdir_SQ)); \ cp -fpR $(LIB_INSTALL) $(DESTDIR)$(libdir_SQ) -install_plugins: $(PLUGINS) - $(call QUIET_INSTALL, trace_plugins) \ - $(call do_install_plugins, $(PLUGINS)) - install_pkgconfig: $(call QUIET_INSTALL, $(PKG_CONFIG_FILE)) \ $(call do_install_pkgconfig_file,$(prefix)) @@ -313,7 +239,7 @@ install_headers: install: install_lib -clean: +clean: clean_plugins $(call QUIET_CLEAN, libtraceevent) \ $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d .*.cmd; \ $(RM) TRACEEVENT-CFLAGS tags TAGS; \ @@ -351,7 +277,19 @@ help: @echo ' doc-install - install the man pages' @echo ' doc-uninstall - uninstall the man pages' @echo'' -PHONY += force plugins + +PHONY += plugins +plugins: + $(call descend,plugins) + +PHONY += install_plugins +install_plugins: + $(call descend,plugins,install) + +PHONY += clean_plugins +clean_plugins: + $(call descend,plugins,clean) + force: # Declare the contents of the .PHONY variable as phony. We keep that diff --git a/tools/lib/traceevent/plugin_cfg80211.c b/tools/lib/traceevent/plugin_cfg80211.c deleted file mode 100644 index 3d43b56a6c98..000000000000 --- a/tools/lib/traceevent/plugin_cfg80211.c +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include -#include -#include "event-parse.h" - -/* - * From glibc endian.h, for older systems where it is not present, e.g.: RHEL5, - * Fedora6. - */ -#ifndef le16toh -# if __BYTE_ORDER == __LITTLE_ENDIAN -# define le16toh(x) (x) -# else -# define le16toh(x) __bswap_16 (x) -# endif -#endif - - -static unsigned long long -process___le16_to_cpup(struct trace_seq *s, unsigned long long *args) -{ - uint16_t *val = (uint16_t *) (unsigned long) args[0]; - return val ? (long long) le16toh(*val) : 0; -} - -int TEP_PLUGIN_LOADER(struct tep_handle *tep) -{ - tep_register_print_function(tep, - process___le16_to_cpup, - TEP_FUNC_ARG_INT, - "__le16_to_cpup", - TEP_FUNC_ARG_PTR, - TEP_FUNC_ARG_VOID); - return 0; -} - -void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) -{ - tep_unregister_print_function(tep, process___le16_to_cpup, - "__le16_to_cpup"); -} diff --git a/tools/lib/traceevent/plugin_function.c b/tools/lib/traceevent/plugin_function.c deleted file mode 100644 index 7770fcb78e0f..000000000000 --- a/tools/lib/traceevent/plugin_function.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License (not later!) - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ -#include -#include -#include - -#include "event-parse.h" -#include "event-utils.h" -#include "trace-seq.h" - -static struct func_stack { - int size; - char **stack; -} *fstack; - -static int cpus = -1; - -#define STK_BLK 10 - -struct tep_plugin_option plugin_options[] = -{ - { - .name = "parent", - .plugin_alias = "ftrace", - .description = - "Print parent of functions for function events", - }, - { - .name = "indent", - .plugin_alias = "ftrace", - .description = - "Try to show function call indents, based on parents", - .set = 1, - }, - { - .name = NULL, - } -}; - -static struct tep_plugin_option *ftrace_parent = &plugin_options[0]; -static struct tep_plugin_option *ftrace_indent = &plugin_options[1]; - -static void add_child(struct func_stack *stack, const char *child, int pos) -{ - int i; - - if (!child) - return; - - if (pos < stack->size) - free(stack->stack[pos]); - else { - char **ptr; - - ptr = realloc(stack->stack, sizeof(char *) * - (stack->size + STK_BLK)); - if (!ptr) { - warning("could not allocate plugin memory\n"); - return; - } - - stack->stack = ptr; - - for (i = stack->size; i < stack->size + STK_BLK; i++) - stack->stack[i] = NULL; - stack->size += STK_BLK; - } - - stack->stack[pos] = strdup(child); -} - -static int add_and_get_index(const char *parent, const char *child, int cpu) -{ - int i; - - if (cpu < 0) - return 0; - - if (cpu > cpus) { - struct func_stack *ptr; - - ptr = realloc(fstack, sizeof(*fstack) * (cpu + 1)); - if (!ptr) { - warning("could not allocate plugin memory\n"); - return 0; - } - - fstack = ptr; - - /* Account for holes in the cpu count */ - for (i = cpus + 1; i <= cpu; i++) - memset(&fstack[i], 0, sizeof(fstack[i])); - cpus = cpu; - } - - for (i = 0; i < fstack[cpu].size && fstack[cpu].stack[i]; i++) { - if (strcmp(parent, fstack[cpu].stack[i]) == 0) { - add_child(&fstack[cpu], child, i+1); - return i; - } - } - - /* Not found */ - add_child(&fstack[cpu], parent, 0); - add_child(&fstack[cpu], child, 1); - return 0; -} - -static int function_handler(struct trace_seq *s, struct tep_record *record, - struct tep_event *event, void *context) -{ - struct tep_handle *tep = event->tep; - unsigned long long function; - unsigned long long pfunction; - const char *func; - const char *parent; - int index = 0; - - if (tep_get_field_val(s, event, "ip", record, &function, 1)) - return trace_seq_putc(s, '!'); - - func = tep_find_function(tep, function); - - if (tep_get_field_val(s, event, "parent_ip", record, &pfunction, 1)) - return trace_seq_putc(s, '!'); - - parent = tep_find_function(tep, pfunction); - - if (parent && ftrace_indent->set) - index = add_and_get_index(parent, func, record->cpu); - - trace_seq_printf(s, "%*s", index*3, ""); - - if (func) - trace_seq_printf(s, "%s", func); - else - trace_seq_printf(s, "0x%llx", function); - - if (ftrace_parent->set) { - trace_seq_printf(s, " <-- "); - if (parent) - trace_seq_printf(s, "%s", parent); - else - trace_seq_printf(s, "0x%llx", pfunction); - } - - return 0; -} - -int TEP_PLUGIN_LOADER(struct tep_handle *tep) -{ - tep_register_event_handler(tep, -1, "ftrace", "function", - function_handler, NULL); - - tep_plugin_add_options("ftrace", plugin_options); - - return 0; -} - -void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) -{ - int i, x; - - tep_unregister_event_handler(tep, -1, "ftrace", "function", - function_handler, NULL); - - for (i = 0; i <= cpus; i++) { - for (x = 0; x < fstack[i].size && fstack[i].stack[x]; x++) - free(fstack[i].stack[x]); - free(fstack[i].stack); - } - - tep_plugin_remove_options(plugin_options); - - free(fstack); - fstack = NULL; - cpus = -1; -} diff --git a/tools/lib/traceevent/plugin_hrtimer.c b/tools/lib/traceevent/plugin_hrtimer.c deleted file mode 100644 index bb434e0ed03a..000000000000 --- a/tools/lib/traceevent/plugin_hrtimer.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2009 Red Hat Inc, Steven Rostedt - * Copyright (C) 2009 Johannes Berg - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License (not later!) - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ -#include -#include -#include - -#include "event-parse.h" -#include "trace-seq.h" - -static int timer_expire_handler(struct trace_seq *s, - struct tep_record *record, - struct tep_event *event, void *context) -{ - trace_seq_printf(s, "hrtimer="); - - if (tep_print_num_field(s, "0x%llx", event, "timer", - record, 0) == -1) - tep_print_num_field(s, "0x%llx", event, "hrtimer", - record, 1); - - trace_seq_printf(s, " now="); - - tep_print_num_field(s, "%llu", event, "now", record, 1); - - tep_print_func_field(s, " function=%s", event, "function", - record, 0); - return 0; -} - -static int timer_start_handler(struct trace_seq *s, - struct tep_record *record, - struct tep_event *event, void *context) -{ - trace_seq_printf(s, "hrtimer="); - - if (tep_print_num_field(s, "0x%llx", event, "timer", - record, 0) == -1) - tep_print_num_field(s, "0x%llx", event, "hrtimer", - record, 1); - - tep_print_func_field(s, " function=%s", event, "function", - record, 0); - - trace_seq_printf(s, " expires="); - tep_print_num_field(s, "%llu", event, "expires", record, 1); - - trace_seq_printf(s, " softexpires="); - tep_print_num_field(s, "%llu", event, "softexpires", record, 1); - return 0; -} - -int TEP_PLUGIN_LOADER(struct tep_handle *tep) -{ - tep_register_event_handler(tep, -1, - "timer", "hrtimer_expire_entry", - timer_expire_handler, NULL); - - tep_register_event_handler(tep, -1, "timer", "hrtimer_start", - timer_start_handler, NULL); - return 0; -} - -void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) -{ - tep_unregister_event_handler(tep, -1, - "timer", "hrtimer_expire_entry", - timer_expire_handler, NULL); - - tep_unregister_event_handler(tep, -1, "timer", "hrtimer_start", - timer_start_handler, NULL); -} diff --git a/tools/lib/traceevent/plugin_jbd2.c b/tools/lib/traceevent/plugin_jbd2.c deleted file mode 100644 index 04fc125f38cb..000000000000 --- a/tools/lib/traceevent/plugin_jbd2.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2010 Red Hat Inc, Steven Rostedt - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License (not later!) - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ -#include -#include -#include - -#include "event-parse.h" -#include "trace-seq.h" - -#define MINORBITS 20 -#define MINORMASK ((1U << MINORBITS) - 1) - -#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS)) -#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK)) - -static unsigned long long -process_jbd2_dev_to_name(struct trace_seq *s, unsigned long long *args) -{ - unsigned int dev = args[0]; - - trace_seq_printf(s, "%d:%d", MAJOR(dev), MINOR(dev)); - return 0; -} - -static unsigned long long -process_jiffies_to_msecs(struct trace_seq *s, unsigned long long *args) -{ - unsigned long long jiffies = args[0]; - - trace_seq_printf(s, "%lld", jiffies); - return jiffies; -} - -int TEP_PLUGIN_LOADER(struct tep_handle *tep) -{ - tep_register_print_function(tep, - process_jbd2_dev_to_name, - TEP_FUNC_ARG_STRING, - "jbd2_dev_to_name", - TEP_FUNC_ARG_INT, - TEP_FUNC_ARG_VOID); - - tep_register_print_function(tep, - process_jiffies_to_msecs, - TEP_FUNC_ARG_LONG, - "jiffies_to_msecs", - TEP_FUNC_ARG_LONG, - TEP_FUNC_ARG_VOID); - return 0; -} - -void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) -{ - tep_unregister_print_function(tep, process_jbd2_dev_to_name, - "jbd2_dev_to_name"); - - tep_unregister_print_function(tep, process_jiffies_to_msecs, - "jiffies_to_msecs"); -} diff --git a/tools/lib/traceevent/plugin_kmem.c b/tools/lib/traceevent/plugin_kmem.c deleted file mode 100644 index edaec5d962c3..000000000000 --- a/tools/lib/traceevent/plugin_kmem.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2009 Red Hat Inc, Steven Rostedt - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License (not later!) - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ -#include -#include -#include - -#include "event-parse.h" -#include "trace-seq.h" - -static int call_site_handler(struct trace_seq *s, struct tep_record *record, - struct tep_event *event, void *context) -{ - struct tep_format_field *field; - unsigned long long val, addr; - void *data = record->data; - const char *func; - - field = tep_find_field(event, "call_site"); - if (!field) - return 1; - - if (tep_read_number_field(field, data, &val)) - return 1; - - func = tep_find_function(event->tep, val); - if (!func) - return 1; - - addr = tep_find_function_address(event->tep, val); - - trace_seq_printf(s, "(%s+0x%x) ", func, (int)(val - addr)); - return 1; -} - -int TEP_PLUGIN_LOADER(struct tep_handle *tep) -{ - tep_register_event_handler(tep, -1, "kmem", "kfree", - call_site_handler, NULL); - - tep_register_event_handler(tep, -1, "kmem", "kmalloc", - call_site_handler, NULL); - - tep_register_event_handler(tep, -1, "kmem", "kmalloc_node", - call_site_handler, NULL); - - tep_register_event_handler(tep, -1, "kmem", "kmem_cache_alloc", - call_site_handler, NULL); - - tep_register_event_handler(tep, -1, "kmem", - "kmem_cache_alloc_node", - call_site_handler, NULL); - - tep_register_event_handler(tep, -1, "kmem", "kmem_cache_free", - call_site_handler, NULL); - return 0; -} - -void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) -{ - tep_unregister_event_handler(tep, -1, "kmem", "kfree", - call_site_handler, NULL); - - tep_unregister_event_handler(tep, -1, "kmem", "kmalloc", - call_site_handler, NULL); - - tep_unregister_event_handler(tep, -1, "kmem", "kmalloc_node", - call_site_handler, NULL); - - tep_unregister_event_handler(tep, -1, "kmem", "kmem_cache_alloc", - call_site_handler, NULL); - - tep_unregister_event_handler(tep, -1, "kmem", - "kmem_cache_alloc_node", - call_site_handler, NULL); - - tep_unregister_event_handler(tep, -1, "kmem", "kmem_cache_free", - call_site_handler, NULL); -} diff --git a/tools/lib/traceevent/plugin_kvm.c b/tools/lib/traceevent/plugin_kvm.c deleted file mode 100644 index c8e623065a7e..000000000000 --- a/tools/lib/traceevent/plugin_kvm.c +++ /dev/null @@ -1,523 +0,0 @@ -/* - * Copyright (C) 2009 Red Hat Inc, Steven Rostedt - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License (not later!) - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ -#include -#include -#include -#include - -#include "event-parse.h" -#include "trace-seq.h" - -#ifdef HAVE_UDIS86 - -#include - -static ud_t ud; - -static void init_disassembler(void) -{ - ud_init(&ud); - ud_set_syntax(&ud, UD_SYN_ATT); -} - -static const char *disassemble(unsigned char *insn, int len, uint64_t rip, - int cr0_pe, int eflags_vm, - int cs_d, int cs_l) -{ - int mode; - - if (!cr0_pe) - mode = 16; - else if (eflags_vm) - mode = 16; - else if (cs_l) - mode = 64; - else if (cs_d) - mode = 32; - else - mode = 16; - - ud_set_pc(&ud, rip); - ud_set_mode(&ud, mode); - ud_set_input_buffer(&ud, insn, len); - ud_disassemble(&ud); - return ud_insn_asm(&ud); -} - -#else - -static void init_disassembler(void) -{ -} - -static const char *disassemble(unsigned char *insn, int len, uint64_t rip, - int cr0_pe, int eflags_vm, - int cs_d, int cs_l) -{ - static char out[15*3+1]; - int i; - - for (i = 0; i < len; ++i) - sprintf(out + i * 3, "%02x ", insn[i]); - out[len*3-1] = '\0'; - return out; -} - -#endif - - -#define VMX_EXIT_REASONS \ - _ER(EXCEPTION_NMI, 0) \ - _ER(EXTERNAL_INTERRUPT, 1) \ - _ER(TRIPLE_FAULT, 2) \ - _ER(PENDING_INTERRUPT, 7) \ - _ER(NMI_WINDOW, 8) \ - _ER(TASK_SWITCH, 9) \ - _ER(CPUID, 10) \ - _ER(HLT, 12) \ - _ER(INVD, 13) \ - _ER(INVLPG, 14) \ - _ER(RDPMC, 15) \ - _ER(RDTSC, 16) \ - _ER(VMCALL, 18) \ - _ER(VMCLEAR, 19) \ - _ER(VMLAUNCH, 20) \ - _ER(VMPTRLD, 21) \ - _ER(VMPTRST, 22) \ - _ER(VMREAD, 23) \ - _ER(VMRESUME, 24) \ - _ER(VMWRITE, 25) \ - _ER(VMOFF, 26) \ - _ER(VMON, 27) \ - _ER(CR_ACCESS, 28) \ - _ER(DR_ACCESS, 29) \ - _ER(IO_INSTRUCTION, 30) \ - _ER(MSR_READ, 31) \ - _ER(MSR_WRITE, 32) \ - _ER(MWAIT_INSTRUCTION, 36) \ - _ER(MONITOR_INSTRUCTION, 39) \ - _ER(PAUSE_INSTRUCTION, 40) \ - _ER(MCE_DURING_VMENTRY, 41) \ - _ER(TPR_BELOW_THRESHOLD, 43) \ - _ER(APIC_ACCESS, 44) \ - _ER(EOI_INDUCED, 45) \ - _ER(EPT_VIOLATION, 48) \ - _ER(EPT_MISCONFIG, 49) \ - _ER(INVEPT, 50) \ - _ER(PREEMPTION_TIMER, 52) \ - _ER(WBINVD, 54) \ - _ER(XSETBV, 55) \ - _ER(APIC_WRITE, 56) \ - _ER(INVPCID, 58) \ - _ER(PML_FULL, 62) \ - _ER(XSAVES, 63) \ - _ER(XRSTORS, 64) - -#define SVM_EXIT_REASONS \ - _ER(EXIT_READ_CR0, 0x000) \ - _ER(EXIT_READ_CR3, 0x003) \ - _ER(EXIT_READ_CR4, 0x004) \ - _ER(EXIT_READ_CR8, 0x008) \ - _ER(EXIT_WRITE_CR0, 0x010) \ - _ER(EXIT_WRITE_CR3, 0x013) \ - _ER(EXIT_WRITE_CR4, 0x014) \ - _ER(EXIT_WRITE_CR8, 0x018) \ - _ER(EXIT_READ_DR0, 0x020) \ - _ER(EXIT_READ_DR1, 0x021) \ - _ER(EXIT_READ_DR2, 0x022) \ - _ER(EXIT_READ_DR3, 0x023) \ - _ER(EXIT_READ_DR4, 0x024) \ - _ER(EXIT_READ_DR5, 0x025) \ - _ER(EXIT_READ_DR6, 0x026) \ - _ER(EXIT_READ_DR7, 0x027) \ - _ER(EXIT_WRITE_DR0, 0x030) \ - _ER(EXIT_WRITE_DR1, 0x031) \ - _ER(EXIT_WRITE_DR2, 0x032) \ - _ER(EXIT_WRITE_DR3, 0x033) \ - _ER(EXIT_WRITE_DR4, 0x034) \ - _ER(EXIT_WRITE_DR5, 0x035) \ - _ER(EXIT_WRITE_DR6, 0x036) \ - _ER(EXIT_WRITE_DR7, 0x037) \ - _ER(EXIT_EXCP_BASE, 0x040) \ - _ER(EXIT_INTR, 0x060) \ - _ER(EXIT_NMI, 0x061) \ - _ER(EXIT_SMI, 0x062) \ - _ER(EXIT_INIT, 0x063) \ - _ER(EXIT_VINTR, 0x064) \ - _ER(EXIT_CR0_SEL_WRITE, 0x065) \ - _ER(EXIT_IDTR_READ, 0x066) \ - _ER(EXIT_GDTR_READ, 0x067) \ - _ER(EXIT_LDTR_READ, 0x068) \ - _ER(EXIT_TR_READ, 0x069) \ - _ER(EXIT_IDTR_WRITE, 0x06a) \ - _ER(EXIT_GDTR_WRITE, 0x06b) \ - _ER(EXIT_LDTR_WRITE, 0x06c) \ - _ER(EXIT_TR_WRITE, 0x06d) \ - _ER(EXIT_RDTSC, 0x06e) \ - _ER(EXIT_RDPMC, 0x06f) \ - _ER(EXIT_PUSHF, 0x070) \ - _ER(EXIT_POPF, 0x071) \ - _ER(EXIT_CPUID, 0x072) \ - _ER(EXIT_RSM, 0x073) \ - _ER(EXIT_IRET, 0x074) \ - _ER(EXIT_SWINT, 0x075) \ - _ER(EXIT_INVD, 0x076) \ - _ER(EXIT_PAUSE, 0x077) \ - _ER(EXIT_HLT, 0x078) \ - _ER(EXIT_INVLPG, 0x079) \ - _ER(EXIT_INVLPGA, 0x07a) \ - _ER(EXIT_IOIO, 0x07b) \ - _ER(EXIT_MSR, 0x07c) \ - _ER(EXIT_TASK_SWITCH, 0x07d) \ - _ER(EXIT_FERR_FREEZE, 0x07e) \ - _ER(EXIT_SHUTDOWN, 0x07f) \ - _ER(EXIT_VMRUN, 0x080) \ - _ER(EXIT_VMMCALL, 0x081) \ - _ER(EXIT_VMLOAD, 0x082) \ - _ER(EXIT_VMSAVE, 0x083) \ - _ER(EXIT_STGI, 0x084) \ - _ER(EXIT_CLGI, 0x085) \ - _ER(EXIT_SKINIT, 0x086) \ - _ER(EXIT_RDTSCP, 0x087) \ - _ER(EXIT_ICEBP, 0x088) \ - _ER(EXIT_WBINVD, 0x089) \ - _ER(EXIT_MONITOR, 0x08a) \ - _ER(EXIT_MWAIT, 0x08b) \ - _ER(EXIT_MWAIT_COND, 0x08c) \ - _ER(EXIT_NPF, 0x400) \ - _ER(EXIT_ERR, -1) - -#define _ER(reason, val) { #reason, val }, -struct str_values { - const char *str; - int val; -}; - -static struct str_values vmx_exit_reasons[] = { - VMX_EXIT_REASONS - { NULL, -1} -}; - -static struct str_values svm_exit_reasons[] = { - SVM_EXIT_REASONS - { NULL, -1} -}; - -static struct isa_exit_reasons { - unsigned isa; - struct str_values *strings; -} isa_exit_reasons[] = { - { .isa = 1, .strings = vmx_exit_reasons }, - { .isa = 2, .strings = svm_exit_reasons }, - { } -}; - -static const char *find_exit_reason(unsigned isa, int val) -{ - struct str_values *strings = NULL; - int i; - - for (i = 0; isa_exit_reasons[i].strings; ++i) - if (isa_exit_reasons[i].isa == isa) { - strings = isa_exit_reasons[i].strings; - break; - } - if (!strings) - return "UNKNOWN-ISA"; - for (i = 0; strings[i].val >= 0; i++) - if (strings[i].val == val) - break; - - return strings[i].str; -} - -static int print_exit_reason(struct trace_seq *s, struct tep_record *record, - struct tep_event *event, const char *field) -{ - unsigned long long isa; - unsigned long long val; - const char *reason; - - if (tep_get_field_val(s, event, field, record, &val, 1) < 0) - return -1; - - if (tep_get_field_val(s, event, "isa", record, &isa, 0) < 0) - isa = 1; - - reason = find_exit_reason(isa, val); - if (reason) - trace_seq_printf(s, "reason %s", reason); - else - trace_seq_printf(s, "reason UNKNOWN (%llu)", val); - return 0; -} - -static int kvm_exit_handler(struct trace_seq *s, struct tep_record *record, - struct tep_event *event, void *context) -{ - unsigned long long info1 = 0, info2 = 0; - - if (print_exit_reason(s, record, event, "exit_reason") < 0) - return -1; - - tep_print_num_field(s, " rip 0x%lx", event, "guest_rip", record, 1); - - if (tep_get_field_val(s, event, "info1", record, &info1, 0) >= 0 - && tep_get_field_val(s, event, "info2", record, &info2, 0) >= 0) - trace_seq_printf(s, " info %llx %llx", info1, info2); - - return 0; -} - -#define KVM_EMUL_INSN_F_CR0_PE (1 << 0) -#define KVM_EMUL_INSN_F_EFL_VM (1 << 1) -#define KVM_EMUL_INSN_F_CS_D (1 << 2) -#define KVM_EMUL_INSN_F_CS_L (1 << 3) - -static int kvm_emulate_insn_handler(struct trace_seq *s, - struct tep_record *record, - struct tep_event *event, void *context) -{ - unsigned long long rip, csbase, len, flags, failed; - int llen; - uint8_t *insn; - const char *disasm; - - if (tep_get_field_val(s, event, "rip", record, &rip, 1) < 0) - return -1; - - if (tep_get_field_val(s, event, "csbase", record, &csbase, 1) < 0) - return -1; - - if (tep_get_field_val(s, event, "len", record, &len, 1) < 0) - return -1; - - if (tep_get_field_val(s, event, "flags", record, &flags, 1) < 0) - return -1; - - if (tep_get_field_val(s, event, "failed", record, &failed, 1) < 0) - return -1; - - insn = tep_get_field_raw(s, event, "insn", record, &llen, 1); - if (!insn) - return -1; - - disasm = disassemble(insn, len, rip, - flags & KVM_EMUL_INSN_F_CR0_PE, - flags & KVM_EMUL_INSN_F_EFL_VM, - flags & KVM_EMUL_INSN_F_CS_D, - flags & KVM_EMUL_INSN_F_CS_L); - - trace_seq_printf(s, "%llx:%llx: %s%s", csbase, rip, disasm, - failed ? " FAIL" : ""); - return 0; -} - - -static int kvm_nested_vmexit_inject_handler(struct trace_seq *s, struct tep_record *record, - struct tep_event *event, void *context) -{ - if (print_exit_reason(s, record, event, "exit_code") < 0) - return -1; - - tep_print_num_field(s, " info1 %llx", event, "exit_info1", record, 1); - tep_print_num_field(s, " info2 %llx", event, "exit_info2", record, 1); - tep_print_num_field(s, " int_info %llx", event, "exit_int_info", record, 1); - tep_print_num_field(s, " int_info_err %llx", event, "exit_int_info_err", record, 1); - - return 0; -} - -static int kvm_nested_vmexit_handler(struct trace_seq *s, struct tep_record *record, - struct tep_event *event, void *context) -{ - tep_print_num_field(s, "rip %llx ", event, "rip", record, 1); - - return kvm_nested_vmexit_inject_handler(s, record, event, context); -} - -union kvm_mmu_page_role { - unsigned word; - struct { - unsigned level:4; - unsigned cr4_pae:1; - unsigned quadrant:2; - unsigned direct:1; - unsigned access:3; - unsigned invalid:1; - unsigned nxe:1; - unsigned cr0_wp:1; - unsigned smep_and_not_wp:1; - unsigned smap_and_not_wp:1; - unsigned pad_for_nice_hex_output:8; - unsigned smm:8; - }; -}; - -static int kvm_mmu_print_role(struct trace_seq *s, struct tep_record *record, - struct tep_event *event, void *context) -{ - unsigned long long val; - static const char *access_str[] = { - "---", "--x", "w--", "w-x", "-u-", "-ux", "wu-", "wux" - }; - union kvm_mmu_page_role role; - - if (tep_get_field_val(s, event, "role", record, &val, 1) < 0) - return -1; - - role.word = (int)val; - - /* - * We can only use the structure if file is of the same - * endianness. - */ - if (tep_is_file_bigendian(event->tep) == - tep_is_local_bigendian(event->tep)) { - - trace_seq_printf(s, "%u q%u%s %s%s %spae %snxe %swp%s%s%s", - role.level, - role.quadrant, - role.direct ? " direct" : "", - access_str[role.access], - role.invalid ? " invalid" : "", - role.cr4_pae ? "" : "!", - role.nxe ? "" : "!", - role.cr0_wp ? "" : "!", - role.smep_and_not_wp ? " smep" : "", - role.smap_and_not_wp ? " smap" : "", - role.smm ? " smm" : ""); - } else - trace_seq_printf(s, "WORD: %08x", role.word); - - tep_print_num_field(s, " root %u ", event, - "root_count", record, 1); - - if (tep_get_field_val(s, event, "unsync", record, &val, 1) < 0) - return -1; - - trace_seq_printf(s, "%s%c", val ? "unsync" : "sync", 0); - return 0; -} - -static int kvm_mmu_get_page_handler(struct trace_seq *s, - struct tep_record *record, - struct tep_event *event, void *context) -{ - unsigned long long val; - - if (tep_get_field_val(s, event, "created", record, &val, 1) < 0) - return -1; - - trace_seq_printf(s, "%s ", val ? "new" : "existing"); - - if (tep_get_field_val(s, event, "gfn", record, &val, 1) < 0) - return -1; - - trace_seq_printf(s, "sp gfn %llx ", val); - return kvm_mmu_print_role(s, record, event, context); -} - -#define PT_WRITABLE_SHIFT 1 -#define PT_WRITABLE_MASK (1ULL << PT_WRITABLE_SHIFT) - -static unsigned long long -process_is_writable_pte(struct trace_seq *s, unsigned long long *args) -{ - unsigned long pte = args[0]; - return pte & PT_WRITABLE_MASK; -} - -int TEP_PLUGIN_LOADER(struct tep_handle *tep) -{ - init_disassembler(); - - tep_register_event_handler(tep, -1, "kvm", "kvm_exit", - kvm_exit_handler, NULL); - - tep_register_event_handler(tep, -1, "kvm", "kvm_emulate_insn", - kvm_emulate_insn_handler, NULL); - - tep_register_event_handler(tep, -1, "kvm", "kvm_nested_vmexit", - kvm_nested_vmexit_handler, NULL); - - tep_register_event_handler(tep, -1, "kvm", "kvm_nested_vmexit_inject", - kvm_nested_vmexit_inject_handler, NULL); - - tep_register_event_handler(tep, -1, "kvmmmu", "kvm_mmu_get_page", - kvm_mmu_get_page_handler, NULL); - - tep_register_event_handler(tep, -1, "kvmmmu", "kvm_mmu_sync_page", - kvm_mmu_print_role, NULL); - - tep_register_event_handler(tep, -1, - "kvmmmu", "kvm_mmu_unsync_page", - kvm_mmu_print_role, NULL); - - tep_register_event_handler(tep, -1, "kvmmmu", "kvm_mmu_zap_page", - kvm_mmu_print_role, NULL); - - tep_register_event_handler(tep, -1, "kvmmmu", - "kvm_mmu_prepare_zap_page", kvm_mmu_print_role, - NULL); - - tep_register_print_function(tep, - process_is_writable_pte, - TEP_FUNC_ARG_INT, - "is_writable_pte", - TEP_FUNC_ARG_LONG, - TEP_FUNC_ARG_VOID); - return 0; -} - -void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) -{ - tep_unregister_event_handler(tep, -1, "kvm", "kvm_exit", - kvm_exit_handler, NULL); - - tep_unregister_event_handler(tep, -1, "kvm", "kvm_emulate_insn", - kvm_emulate_insn_handler, NULL); - - tep_unregister_event_handler(tep, -1, "kvm", "kvm_nested_vmexit", - kvm_nested_vmexit_handler, NULL); - - tep_unregister_event_handler(tep, -1, "kvm", "kvm_nested_vmexit_inject", - kvm_nested_vmexit_inject_handler, NULL); - - tep_unregister_event_handler(tep, -1, "kvmmmu", "kvm_mmu_get_page", - kvm_mmu_get_page_handler, NULL); - - tep_unregister_event_handler(tep, -1, "kvmmmu", "kvm_mmu_sync_page", - kvm_mmu_print_role, NULL); - - tep_unregister_event_handler(tep, -1, - "kvmmmu", "kvm_mmu_unsync_page", - kvm_mmu_print_role, NULL); - - tep_unregister_event_handler(tep, -1, "kvmmmu", "kvm_mmu_zap_page", - kvm_mmu_print_role, NULL); - - tep_unregister_event_handler(tep, -1, "kvmmmu", - "kvm_mmu_prepare_zap_page", kvm_mmu_print_role, - NULL); - - tep_unregister_print_function(tep, process_is_writable_pte, - "is_writable_pte"); -} diff --git a/tools/lib/traceevent/plugin_mac80211.c b/tools/lib/traceevent/plugin_mac80211.c deleted file mode 100644 index 884303c26b5c..000000000000 --- a/tools/lib/traceevent/plugin_mac80211.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2009 Johannes Berg - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License (not later!) - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ -#include -#include -#include - -#include "event-parse.h" -#include "trace-seq.h" - -#define INDENT 65 - -static void print_string(struct trace_seq *s, struct tep_event *event, - const char *name, const void *data) -{ - struct tep_format_field *f = tep_find_field(event, name); - int offset; - int length; - - if (!f) { - trace_seq_printf(s, "NOTFOUND:%s", name); - return; - } - - offset = f->offset; - length = f->size; - - if (!strncmp(f->type, "__data_loc", 10)) { - unsigned long long v; - if (tep_read_number_field(f, data, &v)) { - trace_seq_printf(s, "invalid_data_loc"); - return; - } - offset = v & 0xffff; - length = v >> 16; - } - - trace_seq_printf(s, "%.*s", length, (char *)data + offset); -} - -#define SF(fn) tep_print_num_field(s, fn ":%d", event, fn, record, 0) -#define SFX(fn) tep_print_num_field(s, fn ":%#x", event, fn, record, 0) -#define SP() trace_seq_putc(s, ' ') - -static int drv_bss_info_changed(struct trace_seq *s, - struct tep_record *record, - struct tep_event *event, void *context) -{ - void *data = record->data; - - print_string(s, event, "wiphy_name", data); - trace_seq_printf(s, " vif:"); - print_string(s, event, "vif_name", data); - tep_print_num_field(s, "(%d)", event, "vif_type", record, 1); - - trace_seq_printf(s, "\n%*s", INDENT, ""); - SF("assoc"); SP(); - SF("aid"); SP(); - SF("cts"); SP(); - SF("shortpre"); SP(); - SF("shortslot"); SP(); - SF("dtimper"); SP(); - trace_seq_printf(s, "\n%*s", INDENT, ""); - SF("bcnint"); SP(); - SFX("assoc_cap"); SP(); - SFX("basic_rates"); SP(); - SF("enable_beacon"); - trace_seq_printf(s, "\n%*s", INDENT, ""); - SF("ht_operation_mode"); - - return 0; -} - -int TEP_PLUGIN_LOADER(struct tep_handle *tep) -{ - tep_register_event_handler(tep, -1, "mac80211", - "drv_bss_info_changed", - drv_bss_info_changed, NULL); - return 0; -} - -void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) -{ - tep_unregister_event_handler(tep, -1, "mac80211", - "drv_bss_info_changed", - drv_bss_info_changed, NULL); -} diff --git a/tools/lib/traceevent/plugin_sched_switch.c b/tools/lib/traceevent/plugin_sched_switch.c deleted file mode 100644 index 957389a0ff7a..000000000000 --- a/tools/lib/traceevent/plugin_sched_switch.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License (not later!) - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ -#include -#include -#include - -#include "event-parse.h" -#include "trace-seq.h" - -static void write_state(struct trace_seq *s, int val) -{ - const char states[] = "SDTtZXxW"; - int found = 0; - int i; - - for (i = 0; i < (sizeof(states) - 1); i++) { - if (!(val & (1 << i))) - continue; - - if (found) - trace_seq_putc(s, '|'); - - found = 1; - trace_seq_putc(s, states[i]); - } - - if (!found) - trace_seq_putc(s, 'R'); -} - -static void write_and_save_comm(struct tep_format_field *field, - struct tep_record *record, - struct trace_seq *s, int pid) -{ - const char *comm; - int len; - - comm = (char *)(record->data + field->offset); - len = s->len; - trace_seq_printf(s, "%.*s", - field->size, comm); - - /* make sure the comm has a \0 at the end. */ - trace_seq_terminate(s); - comm = &s->buffer[len]; - - /* Help out the comm to ids. This will handle dups */ - tep_register_comm(field->event->tep, comm, pid); -} - -static int sched_wakeup_handler(struct trace_seq *s, - struct tep_record *record, - struct tep_event *event, void *context) -{ - struct tep_format_field *field; - unsigned long long val; - - if (tep_get_field_val(s, event, "pid", record, &val, 1)) - return trace_seq_putc(s, '!'); - - field = tep_find_any_field(event, "comm"); - if (field) { - write_and_save_comm(field, record, s, val); - trace_seq_putc(s, ':'); - } - trace_seq_printf(s, "%lld", val); - - if (tep_get_field_val(s, event, "prio", record, &val, 0) == 0) - trace_seq_printf(s, " [%lld]", val); - - if (tep_get_field_val(s, event, "success", record, &val, 1) == 0) - trace_seq_printf(s, " success=%lld", val); - - if (tep_get_field_val(s, event, "target_cpu", record, &val, 0) == 0) - trace_seq_printf(s, " CPU:%03llu", val); - - return 0; -} - -static int sched_switch_handler(struct trace_seq *s, - struct tep_record *record, - struct tep_event *event, void *context) -{ - struct tep_format_field *field; - unsigned long long val; - - if (tep_get_field_val(s, event, "prev_pid", record, &val, 1)) - return trace_seq_putc(s, '!'); - - field = tep_find_any_field(event, "prev_comm"); - if (field) { - write_and_save_comm(field, record, s, val); - trace_seq_putc(s, ':'); - } - trace_seq_printf(s, "%lld ", val); - - if (tep_get_field_val(s, event, "prev_prio", record, &val, 0) == 0) - trace_seq_printf(s, "[%d] ", (int) val); - - if (tep_get_field_val(s, event, "prev_state", record, &val, 0) == 0) - write_state(s, val); - - trace_seq_puts(s, " ==> "); - - if (tep_get_field_val(s, event, "next_pid", record, &val, 1)) - return trace_seq_putc(s, '!'); - - field = tep_find_any_field(event, "next_comm"); - if (field) { - write_and_save_comm(field, record, s, val); - trace_seq_putc(s, ':'); - } - trace_seq_printf(s, "%lld", val); - - if (tep_get_field_val(s, event, "next_prio", record, &val, 0) == 0) - trace_seq_printf(s, " [%d]", (int) val); - - return 0; -} - -int TEP_PLUGIN_LOADER(struct tep_handle *tep) -{ - tep_register_event_handler(tep, -1, "sched", "sched_switch", - sched_switch_handler, NULL); - - tep_register_event_handler(tep, -1, "sched", "sched_wakeup", - sched_wakeup_handler, NULL); - - tep_register_event_handler(tep, -1, "sched", "sched_wakeup_new", - sched_wakeup_handler, NULL); - return 0; -} - -void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) -{ - tep_unregister_event_handler(tep, -1, "sched", "sched_switch", - sched_switch_handler, NULL); - - tep_unregister_event_handler(tep, -1, "sched", "sched_wakeup", - sched_wakeup_handler, NULL); - - tep_unregister_event_handler(tep, -1, "sched", "sched_wakeup_new", - sched_wakeup_handler, NULL); -} diff --git a/tools/lib/traceevent/plugin_scsi.c b/tools/lib/traceevent/plugin_scsi.c deleted file mode 100644 index 5d0387a4b65a..000000000000 --- a/tools/lib/traceevent/plugin_scsi.c +++ /dev/null @@ -1,434 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include -#include "event-parse.h" -#include "trace-seq.h" - -typedef unsigned long sector_t; -typedef uint64_t u64; -typedef unsigned int u32; - -/* - * SCSI opcodes - */ -#define TEST_UNIT_READY 0x00 -#define REZERO_UNIT 0x01 -#define REQUEST_SENSE 0x03 -#define FORMAT_UNIT 0x04 -#define READ_BLOCK_LIMITS 0x05 -#define REASSIGN_BLOCKS 0x07 -#define INITIALIZE_ELEMENT_STATUS 0x07 -#define READ_6 0x08 -#define WRITE_6 0x0a -#define SEEK_6 0x0b -#define READ_REVERSE 0x0f -#define WRITE_FILEMARKS 0x10 -#define SPACE 0x11 -#define INQUIRY 0x12 -#define RECOVER_BUFFERED_DATA 0x14 -#define MODE_SELECT 0x15 -#define RESERVE 0x16 -#define RELEASE 0x17 -#define COPY 0x18 -#define ERASE 0x19 -#define MODE_SENSE 0x1a -#define START_STOP 0x1b -#define RECEIVE_DIAGNOSTIC 0x1c -#define SEND_DIAGNOSTIC 0x1d -#define ALLOW_MEDIUM_REMOVAL 0x1e - -#define READ_FORMAT_CAPACITIES 0x23 -#define SET_WINDOW 0x24 -#define READ_CAPACITY 0x25 -#define READ_10 0x28 -#define WRITE_10 0x2a -#define SEEK_10 0x2b -#define POSITION_TO_ELEMENT 0x2b -#define WRITE_VERIFY 0x2e -#define VERIFY 0x2f -#define SEARCH_HIGH 0x30 -#define SEARCH_EQUAL 0x31 -#define SEARCH_LOW 0x32 -#define SET_LIMITS 0x33 -#define PRE_FETCH 0x34 -#define READ_POSITION 0x34 -#define SYNCHRONIZE_CACHE 0x35 -#define LOCK_UNLOCK_CACHE 0x36 -#define READ_DEFECT_DATA 0x37 -#define MEDIUM_SCAN 0x38 -#define COMPARE 0x39 -#define COPY_VERIFY 0x3a -#define WRITE_BUFFER 0x3b -#define READ_BUFFER 0x3c -#define UPDATE_BLOCK 0x3d -#define READ_LONG 0x3e -#define WRITE_LONG 0x3f -#define CHANGE_DEFINITION 0x40 -#define WRITE_SAME 0x41 -#define UNMAP 0x42 -#define READ_TOC 0x43 -#define READ_HEADER 0x44 -#define GET_EVENT_STATUS_NOTIFICATION 0x4a -#define LOG_SELECT 0x4c -#define LOG_SENSE 0x4d -#define XDWRITEREAD_10 0x53 -#define MODE_SELECT_10 0x55 -#define RESERVE_10 0x56 -#define RELEASE_10 0x57 -#define MODE_SENSE_10 0x5a -#define PERSISTENT_RESERVE_IN 0x5e -#define PERSISTENT_RESERVE_OUT 0x5f -#define VARIABLE_LENGTH_CMD 0x7f -#define REPORT_LUNS 0xa0 -#define SECURITY_PROTOCOL_IN 0xa2 -#define MAINTENANCE_IN 0xa3 -#define MAINTENANCE_OUT 0xa4 -#define MOVE_MEDIUM 0xa5 -#define EXCHANGE_MEDIUM 0xa6 -#define READ_12 0xa8 -#define SERVICE_ACTION_OUT_12 0xa9 -#define WRITE_12 0xaa -#define SERVICE_ACTION_IN_12 0xab -#define WRITE_VERIFY_12 0xae -#define VERIFY_12 0xaf -#define SEARCH_HIGH_12 0xb0 -#define SEARCH_EQUAL_12 0xb1 -#define SEARCH_LOW_12 0xb2 -#define SECURITY_PROTOCOL_OUT 0xb5 -#define READ_ELEMENT_STATUS 0xb8 -#define SEND_VOLUME_TAG 0xb6 -#define WRITE_LONG_2 0xea -#define EXTENDED_COPY 0x83 -#define RECEIVE_COPY_RESULTS 0x84 -#define ACCESS_CONTROL_IN 0x86 -#define ACCESS_CONTROL_OUT 0x87 -#define READ_16 0x88 -#define WRITE_16 0x8a -#define READ_ATTRIBUTE 0x8c -#define WRITE_ATTRIBUTE 0x8d -#define VERIFY_16 0x8f -#define SYNCHRONIZE_CACHE_16 0x91 -#define WRITE_SAME_16 0x93 -#define SERVICE_ACTION_BIDIRECTIONAL 0x9d -#define SERVICE_ACTION_IN_16 0x9e -#define SERVICE_ACTION_OUT_16 0x9f -/* values for service action in */ -#define SAI_READ_CAPACITY_16 0x10 -#define SAI_GET_LBA_STATUS 0x12 -/* values for VARIABLE_LENGTH_CMD service action codes - * see spc4r17 Section D.3.5, table D.7 and D.8 */ -#define VLC_SA_RECEIVE_CREDENTIAL 0x1800 -/* values for maintenance in */ -#define MI_REPORT_IDENTIFYING_INFORMATION 0x05 -#define MI_REPORT_TARGET_PGS 0x0a -#define MI_REPORT_ALIASES 0x0b -#define MI_REPORT_SUPPORTED_OPERATION_CODES 0x0c -#define MI_REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS 0x0d -#define MI_REPORT_PRIORITY 0x0e -#define MI_REPORT_TIMESTAMP 0x0f -#define MI_MANAGEMENT_PROTOCOL_IN 0x10 -/* value for MI_REPORT_TARGET_PGS ext header */ -#define MI_EXT_HDR_PARAM_FMT 0x20 -/* values for maintenance out */ -#define MO_SET_IDENTIFYING_INFORMATION 0x06 -#define MO_SET_TARGET_PGS 0x0a -#define MO_CHANGE_ALIASES 0x0b -#define MO_SET_PRIORITY 0x0e -#define MO_SET_TIMESTAMP 0x0f -#define MO_MANAGEMENT_PROTOCOL_OUT 0x10 -/* values for variable length command */ -#define XDREAD_32 0x03 -#define XDWRITE_32 0x04 -#define XPWRITE_32 0x06 -#define XDWRITEREAD_32 0x07 -#define READ_32 0x09 -#define VERIFY_32 0x0a -#define WRITE_32 0x0b -#define WRITE_SAME_32 0x0d - -#define SERVICE_ACTION16(cdb) (cdb[1] & 0x1f) -#define SERVICE_ACTION32(cdb) ((cdb[8] << 8) | cdb[9]) - -static const char * -scsi_trace_misc(struct trace_seq *, unsigned char *, int); - -static const char * -scsi_trace_rw6(struct trace_seq *p, unsigned char *cdb, int len) -{ - const char *ret = p->buffer + p->len; - sector_t lba = 0, txlen = 0; - - lba |= ((cdb[1] & 0x1F) << 16); - lba |= (cdb[2] << 8); - lba |= cdb[3]; - txlen = cdb[4]; - - trace_seq_printf(p, "lba=%llu txlen=%llu", - (unsigned long long)lba, (unsigned long long)txlen); - trace_seq_putc(p, 0); - return ret; -} - -static const char * -scsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len) -{ - const char *ret = p->buffer + p->len; - sector_t lba = 0, txlen = 0; - - lba |= (cdb[2] << 24); - lba |= (cdb[3] << 16); - lba |= (cdb[4] << 8); - lba |= cdb[5]; - txlen |= (cdb[7] << 8); - txlen |= cdb[8]; - - trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u", - (unsigned long long)lba, (unsigned long long)txlen, - cdb[1] >> 5); - - if (cdb[0] == WRITE_SAME) - trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1); - - trace_seq_putc(p, 0); - return ret; -} - -static const char * -scsi_trace_rw12(struct trace_seq *p, unsigned char *cdb, int len) -{ - const char *ret = p->buffer + p->len; - sector_t lba = 0, txlen = 0; - - lba |= (cdb[2] << 24); - lba |= (cdb[3] << 16); - lba |= (cdb[4] << 8); - lba |= cdb[5]; - txlen |= (cdb[6] << 24); - txlen |= (cdb[7] << 16); - txlen |= (cdb[8] << 8); - txlen |= cdb[9]; - - trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u", - (unsigned long long)lba, (unsigned long long)txlen, - cdb[1] >> 5); - trace_seq_putc(p, 0); - return ret; -} - -static const char * -scsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len) -{ - const char *ret = p->buffer + p->len; - sector_t lba = 0, txlen = 0; - - lba |= ((u64)cdb[2] << 56); - lba |= ((u64)cdb[3] << 48); - lba |= ((u64)cdb[4] << 40); - lba |= ((u64)cdb[5] << 32); - lba |= (cdb[6] << 24); - lba |= (cdb[7] << 16); - lba |= (cdb[8] << 8); - lba |= cdb[9]; - txlen |= (cdb[10] << 24); - txlen |= (cdb[11] << 16); - txlen |= (cdb[12] << 8); - txlen |= cdb[13]; - - trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u", - (unsigned long long)lba, (unsigned long long)txlen, - cdb[1] >> 5); - - if (cdb[0] == WRITE_SAME_16) - trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1); - - trace_seq_putc(p, 0); - return ret; -} - -static const char * -scsi_trace_rw32(struct trace_seq *p, unsigned char *cdb, int len) -{ - const char *ret = p->buffer + p->len, *cmd; - sector_t lba = 0, txlen = 0; - u32 ei_lbrt = 0; - - switch (SERVICE_ACTION32(cdb)) { - case READ_32: - cmd = "READ"; - break; - case VERIFY_32: - cmd = "VERIFY"; - break; - case WRITE_32: - cmd = "WRITE"; - break; - case WRITE_SAME_32: - cmd = "WRITE_SAME"; - break; - default: - trace_seq_printf(p, "UNKNOWN"); - goto out; - } - - lba |= ((u64)cdb[12] << 56); - lba |= ((u64)cdb[13] << 48); - lba |= ((u64)cdb[14] << 40); - lba |= ((u64)cdb[15] << 32); - lba |= (cdb[16] << 24); - lba |= (cdb[17] << 16); - lba |= (cdb[18] << 8); - lba |= cdb[19]; - ei_lbrt |= (cdb[20] << 24); - ei_lbrt |= (cdb[21] << 16); - ei_lbrt |= (cdb[22] << 8); - ei_lbrt |= cdb[23]; - txlen |= (cdb[28] << 24); - txlen |= (cdb[29] << 16); - txlen |= (cdb[30] << 8); - txlen |= cdb[31]; - - trace_seq_printf(p, "%s_32 lba=%llu txlen=%llu protect=%u ei_lbrt=%u", - cmd, (unsigned long long)lba, - (unsigned long long)txlen, cdb[10] >> 5, ei_lbrt); - - if (SERVICE_ACTION32(cdb) == WRITE_SAME_32) - trace_seq_printf(p, " unmap=%u", cdb[10] >> 3 & 1); - -out: - trace_seq_putc(p, 0); - return ret; -} - -static const char * -scsi_trace_unmap(struct trace_seq *p, unsigned char *cdb, int len) -{ - const char *ret = p->buffer + p->len; - unsigned int regions = cdb[7] << 8 | cdb[8]; - - trace_seq_printf(p, "regions=%u", (regions - 8) / 16); - trace_seq_putc(p, 0); - return ret; -} - -static const char * -scsi_trace_service_action_in(struct trace_seq *p, unsigned char *cdb, int len) -{ - const char *ret = p->buffer + p->len, *cmd; - sector_t lba = 0; - u32 alloc_len = 0; - - switch (SERVICE_ACTION16(cdb)) { - case SAI_READ_CAPACITY_16: - cmd = "READ_CAPACITY_16"; - break; - case SAI_GET_LBA_STATUS: - cmd = "GET_LBA_STATUS"; - break; - default: - trace_seq_printf(p, "UNKNOWN"); - goto out; - } - - lba |= ((u64)cdb[2] << 56); - lba |= ((u64)cdb[3] << 48); - lba |= ((u64)cdb[4] << 40); - lba |= ((u64)cdb[5] << 32); - lba |= (cdb[6] << 24); - lba |= (cdb[7] << 16); - lba |= (cdb[8] << 8); - lba |= cdb[9]; - alloc_len |= (cdb[10] << 24); - alloc_len |= (cdb[11] << 16); - alloc_len |= (cdb[12] << 8); - alloc_len |= cdb[13]; - - trace_seq_printf(p, "%s lba=%llu alloc_len=%u", cmd, - (unsigned long long)lba, alloc_len); - -out: - trace_seq_putc(p, 0); - return ret; -} - -static const char * -scsi_trace_varlen(struct trace_seq *p, unsigned char *cdb, int len) -{ - switch (SERVICE_ACTION32(cdb)) { - case READ_32: - case VERIFY_32: - case WRITE_32: - case WRITE_SAME_32: - return scsi_trace_rw32(p, cdb, len); - default: - return scsi_trace_misc(p, cdb, len); - } -} - -static const char * -scsi_trace_misc(struct trace_seq *p, unsigned char *cdb, int len) -{ - const char *ret = p->buffer + p->len; - - trace_seq_printf(p, "-"); - trace_seq_putc(p, 0); - return ret; -} - -const char * -scsi_trace_parse_cdb(struct trace_seq *p, unsigned char *cdb, int len) -{ - switch (cdb[0]) { - case READ_6: - case WRITE_6: - return scsi_trace_rw6(p, cdb, len); - case READ_10: - case VERIFY: - case WRITE_10: - case WRITE_SAME: - return scsi_trace_rw10(p, cdb, len); - case READ_12: - case VERIFY_12: - case WRITE_12: - return scsi_trace_rw12(p, cdb, len); - case READ_16: - case VERIFY_16: - case WRITE_16: - case WRITE_SAME_16: - return scsi_trace_rw16(p, cdb, len); - case UNMAP: - return scsi_trace_unmap(p, cdb, len); - case SERVICE_ACTION_IN_16: - return scsi_trace_service_action_in(p, cdb, len); - case VARIABLE_LENGTH_CMD: - return scsi_trace_varlen(p, cdb, len); - default: - return scsi_trace_misc(p, cdb, len); - } -} - -unsigned long long process_scsi_trace_parse_cdb(struct trace_seq *s, - unsigned long long *args) -{ - scsi_trace_parse_cdb(s, (unsigned char *) (unsigned long) args[1], args[2]); - return 0; -} - -int TEP_PLUGIN_LOADER(struct tep_handle *tep) -{ - tep_register_print_function(tep, - process_scsi_trace_parse_cdb, - TEP_FUNC_ARG_STRING, - "scsi_trace_parse_cdb", - TEP_FUNC_ARG_PTR, - TEP_FUNC_ARG_PTR, - TEP_FUNC_ARG_INT, - TEP_FUNC_ARG_VOID); - return 0; -} - -void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) -{ - tep_unregister_print_function(tep, process_scsi_trace_parse_cdb, - "scsi_trace_parse_cdb"); -} diff --git a/tools/lib/traceevent/plugin_xen.c b/tools/lib/traceevent/plugin_xen.c deleted file mode 100644 index 993b208d0323..000000000000 --- a/tools/lib/traceevent/plugin_xen.c +++ /dev/null @@ -1,138 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include -#include "event-parse.h" -#include "trace-seq.h" - -#define __HYPERVISOR_set_trap_table 0 -#define __HYPERVISOR_mmu_update 1 -#define __HYPERVISOR_set_gdt 2 -#define __HYPERVISOR_stack_switch 3 -#define __HYPERVISOR_set_callbacks 4 -#define __HYPERVISOR_fpu_taskswitch 5 -#define __HYPERVISOR_sched_op_compat 6 -#define __HYPERVISOR_dom0_op 7 -#define __HYPERVISOR_set_debugreg 8 -#define __HYPERVISOR_get_debugreg 9 -#define __HYPERVISOR_update_descriptor 10 -#define __HYPERVISOR_memory_op 12 -#define __HYPERVISOR_multicall 13 -#define __HYPERVISOR_update_va_mapping 14 -#define __HYPERVISOR_set_timer_op 15 -#define __HYPERVISOR_event_channel_op_compat 16 -#define __HYPERVISOR_xen_version 17 -#define __HYPERVISOR_console_io 18 -#define __HYPERVISOR_physdev_op_compat 19 -#define __HYPERVISOR_grant_table_op 20 -#define __HYPERVISOR_vm_assist 21 -#define __HYPERVISOR_update_va_mapping_otherdomain 22 -#define __HYPERVISOR_iret 23 /* x86 only */ -#define __HYPERVISOR_vcpu_op 24 -#define __HYPERVISOR_set_segment_base 25 /* x86/64 only */ -#define __HYPERVISOR_mmuext_op 26 -#define __HYPERVISOR_acm_op 27 -#define __HYPERVISOR_nmi_op 28 -#define __HYPERVISOR_sched_op 29 -#define __HYPERVISOR_callback_op 30 -#define __HYPERVISOR_xenoprof_op 31 -#define __HYPERVISOR_event_channel_op 32 -#define __HYPERVISOR_physdev_op 33 -#define __HYPERVISOR_hvm_op 34 -#define __HYPERVISOR_tmem_op 38 - -/* Architecture-specific hypercall definitions. */ -#define __HYPERVISOR_arch_0 48 -#define __HYPERVISOR_arch_1 49 -#define __HYPERVISOR_arch_2 50 -#define __HYPERVISOR_arch_3 51 -#define __HYPERVISOR_arch_4 52 -#define __HYPERVISOR_arch_5 53 -#define __HYPERVISOR_arch_6 54 -#define __HYPERVISOR_arch_7 55 - -#define N(x) [__HYPERVISOR_##x] = "("#x")" -static const char *xen_hypercall_names[] = { - N(set_trap_table), - N(mmu_update), - N(set_gdt), - N(stack_switch), - N(set_callbacks), - N(fpu_taskswitch), - N(sched_op_compat), - N(dom0_op), - N(set_debugreg), - N(get_debugreg), - N(update_descriptor), - N(memory_op), - N(multicall), - N(update_va_mapping), - N(set_timer_op), - N(event_channel_op_compat), - N(xen_version), - N(console_io), - N(physdev_op_compat), - N(grant_table_op), - N(vm_assist), - N(update_va_mapping_otherdomain), - N(iret), - N(vcpu_op), - N(set_segment_base), - N(mmuext_op), - N(acm_op), - N(nmi_op), - N(sched_op), - N(callback_op), - N(xenoprof_op), - N(event_channel_op), - N(physdev_op), - N(hvm_op), - -/* Architecture-specific hypercall definitions. */ - N(arch_0), - N(arch_1), - N(arch_2), - N(arch_3), - N(arch_4), - N(arch_5), - N(arch_6), - N(arch_7), -}; -#undef N - -#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) - -static const char *xen_hypercall_name(unsigned op) -{ - if (op < ARRAY_SIZE(xen_hypercall_names) && - xen_hypercall_names[op] != NULL) - return xen_hypercall_names[op]; - - return ""; -} - -unsigned long long process_xen_hypercall_name(struct trace_seq *s, - unsigned long long *args) -{ - unsigned int op = args[0]; - - trace_seq_printf(s, "%s", xen_hypercall_name(op)); - return 0; -} - -int TEP_PLUGIN_LOADER(struct tep_handle *tep) -{ - tep_register_print_function(tep, - process_xen_hypercall_name, - TEP_FUNC_ARG_STRING, - "xen_hypercall_name", - TEP_FUNC_ARG_INT, - TEP_FUNC_ARG_VOID); - return 0; -} - -void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) -{ - tep_unregister_print_function(tep, process_xen_hypercall_name, - "xen_hypercall_name"); -} diff --git a/tools/lib/traceevent/plugins/Build b/tools/lib/traceevent/plugins/Build new file mode 100644 index 000000000000..210d26910613 --- /dev/null +++ b/tools/lib/traceevent/plugins/Build @@ -0,0 +1,10 @@ +plugin_jbd2-y += plugin_jbd2.o +plugin_hrtimer-y += plugin_hrtimer.o +plugin_kmem-y += plugin_kmem.o +plugin_kvm-y += plugin_kvm.o +plugin_mac80211-y += plugin_mac80211.o +plugin_sched_switch-y += plugin_sched_switch.o +plugin_function-y += plugin_function.o +plugin_xen-y += plugin_xen.o +plugin_scsi-y += plugin_scsi.o +plugin_cfg80211-y += plugin_cfg80211.o diff --git a/tools/lib/traceevent/plugins/Makefile b/tools/lib/traceevent/plugins/Makefile new file mode 100644 index 000000000000..f440989fa55e --- /dev/null +++ b/tools/lib/traceevent/plugins/Makefile @@ -0,0 +1,222 @@ +# SPDX-License-Identifier: GPL-2.0 + +#MAKEFLAGS += --no-print-directory + + +# Makefiles suck: This macro sets a default value of $(2) for the +# variable named by $(1), unless the variable has been set by +# environment or command line. This is necessary for CC and AR +# because make sets default values, so the simpler ?= approach +# won't work as expected. +define allow-override + $(if $(or $(findstring environment,$(origin $(1))),\ + $(findstring command line,$(origin $(1)))),,\ + $(eval $(1) = $(2))) +endef + +# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix. +$(call allow-override,CC,$(CROSS_COMPILE)gcc) +$(call allow-override,AR,$(CROSS_COMPILE)ar) +$(call allow-override,NM,$(CROSS_COMPILE)nm) +$(call allow-override,PKG_CONFIG,pkg-config) + +EXT = -std=gnu99 +INSTALL = install + +# Use DESTDIR for installing into a different root directory. +# This is useful for building a package. The program will be +# installed in this directory as if it was the root directory. +# Then the build tool can move it later. +DESTDIR ?= +DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' + +LP64 := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1) +ifeq ($(LP64), 1) + libdir_relative = lib64 +else + libdir_relative = lib +endif + +prefix ?= /usr/local +libdir = $(prefix)/$(libdir_relative) + +set_plugin_dir := 1 + +# Set plugin_dir to preffered global plugin location +# If we install under $HOME directory we go under +# $(HOME)/.local/lib/traceevent/plugins +# +# We dont set PLUGIN_DIR in case we install under $HOME +# directory, because by default the code looks under: +# $(HOME)/.local/lib/traceevent/plugins by default. +# +ifeq ($(plugin_dir),) +ifeq ($(prefix),$(HOME)) +override plugin_dir = $(HOME)/.local/lib/traceevent/plugins +set_plugin_dir := 0 +else +override plugin_dir = $(libdir)/traceevent/plugins +endif +endif + +ifeq ($(set_plugin_dir),1) +PLUGIN_DIR = -DPLUGIN_DIR="$(plugin_dir)" +PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))' +endif + +include ../../../scripts/Makefile.include + +# copy a bit from Linux kbuild + +ifeq ("$(origin V)", "command line") + VERBOSE = $(V) +endif +ifndef VERBOSE + VERBOSE = 0 +endif + +ifeq ($(srctree),) +srctree := $(patsubst %/,%,$(dir $(CURDIR))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +#$(info Determined 'srctree' to be $(srctree)) +endif + +export prefix libdir src obj + +# Shell quotes +plugin_dir_SQ = $(subst ','\'',$(plugin_dir)) + +CONFIG_INCLUDES = +CONFIG_LIBS = +CONFIG_FLAGS = + +OBJ = $@ +N = + +INCLUDES = -I. -I.. -I $(srctree)/tools/include $(CONFIG_INCLUDES) + +# Set compile option CFLAGS +ifdef EXTRA_CFLAGS + CFLAGS := $(EXTRA_CFLAGS) +else + CFLAGS := -g -Wall +endif + +# Append required CFLAGS +override CFLAGS += -fPIC +override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ) +override CFLAGS += $(udis86-flags) -D_GNU_SOURCE + +ifeq ($(VERBOSE),1) + Q = +else + Q = @ +endif + +# Disable command line variables (CFLAGS) override from top +# level Makefile (perf), otherwise build Makefile will get +# the same command line setup. +MAKEOVERRIDES= + +export srctree OUTPUT CC LD CFLAGS V + +build := -f $(srctree)/tools/build/Makefile.build dir=. obj + +DYNAMIC_LIST_FILE := $(OUTPUT)libtraceevent-dynamic-list + +PLUGINS = plugin_jbd2.so +PLUGINS += plugin_hrtimer.so +PLUGINS += plugin_kmem.so +PLUGINS += plugin_kvm.so +PLUGINS += plugin_mac80211.so +PLUGINS += plugin_sched_switch.so +PLUGINS += plugin_function.so +PLUGINS += plugin_xen.so +PLUGINS += plugin_scsi.so +PLUGINS += plugin_cfg80211.so + +PLUGINS := $(addprefix $(OUTPUT),$(PLUGINS)) +PLUGINS_IN := $(PLUGINS:.so=-in.o) + +plugins: $(PLUGINS) $(DYNAMIC_LIST_FILE) + +__plugin_obj = $(notdir $@) + plugin_obj = $(__plugin_obj:-in.o=) + +$(PLUGINS_IN): force + $(Q)$(MAKE) $(build)=$(plugin_obj) + +$(OUTPUT)libtraceevent-dynamic-list: $(PLUGINS) + $(QUIET_GEN)$(call do_generate_dynamic_list_file, $(PLUGINS), $@) + +$(OUTPUT)%.so: $(OUTPUT)%-in.o + $(QUIET_LINK)$(CC) $(CFLAGS) -shared $(LDFLAGS) -nostartfiles -o $@ $^ + +define update_dir + (echo $1 > $@.tmp; \ + if [ -r $@ ] && cmp -s $@ $@.tmp; then \ + rm -f $@.tmp; \ + else \ + echo ' UPDATE $@'; \ + mv -f $@.tmp $@; \ + fi); +endef + +tags: force + $(RM) tags + find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \ + --regex-c++='/_PE\(([^,)]*).*/TEP_ERRNO__\1/' + +TAGS: force + $(RM) TAGS + find . -name '*.[ch]' | xargs etags \ + --regex='/_PE(\([^,)]*\).*/TEP_ERRNO__\1/' + +define do_install_mkdir + if [ ! -d '$(DESTDIR_SQ)$1' ]; then \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$1'; \ + fi +endef + +define do_install + $(call do_install_mkdir,$2); \ + $(INSTALL) $(if $3,-m $3,) $1 '$(DESTDIR_SQ)$2' +endef + +define do_install_plugins + for plugin in $1; do \ + $(call do_install,$$plugin,$(plugin_dir_SQ)); \ + done +endef + +define do_generate_dynamic_list_file + symbol_type=`$(NM) -u -D $1 | awk 'NF>1 {print $$1}' | \ + xargs echo "U w W" | tr 'w ' 'W\n' | sort -u | xargs echo`;\ + if [ "$$symbol_type" = "U W" ];then \ + (echo '{'; \ + $(NM) -u -D $1 | awk 'NF>1 {print "\t"$$2";"}' | sort -u;\ + echo '};'; \ + ) > $2; \ + else \ + (echo Either missing one of [$1] or bad version of $(NM)) 1>&2;\ + fi +endef + +install: $(PLUGINS) + $(call QUIET_INSTALL, trace_plugins) \ + $(call do_install_plugins, $(PLUGINS)) + +clean: + $(call QUIET_CLEAN, trace_plugins) \ + $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d .*.cmd; \ + $(RM) $(OUTPUT)libtraceevent-dynamic-list \ + $(RM) TRACEEVENT-CFLAGS tags TAGS; + +PHONY += force plugins +force: + +# Declare the contents of the .PHONY variable as phony. We keep that +# information in a variable so we can use it in if_changed and friends. +.PHONY: $(PHONY) diff --git a/tools/lib/traceevent/plugins/plugin_cfg80211.c b/tools/lib/traceevent/plugins/plugin_cfg80211.c new file mode 100644 index 000000000000..3d43b56a6c98 --- /dev/null +++ b/tools/lib/traceevent/plugins/plugin_cfg80211.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include "event-parse.h" + +/* + * From glibc endian.h, for older systems where it is not present, e.g.: RHEL5, + * Fedora6. + */ +#ifndef le16toh +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define le16toh(x) (x) +# else +# define le16toh(x) __bswap_16 (x) +# endif +#endif + + +static unsigned long long +process___le16_to_cpup(struct trace_seq *s, unsigned long long *args) +{ + uint16_t *val = (uint16_t *) (unsigned long) args[0]; + return val ? (long long) le16toh(*val) : 0; +} + +int TEP_PLUGIN_LOADER(struct tep_handle *tep) +{ + tep_register_print_function(tep, + process___le16_to_cpup, + TEP_FUNC_ARG_INT, + "__le16_to_cpup", + TEP_FUNC_ARG_PTR, + TEP_FUNC_ARG_VOID); + return 0; +} + +void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) +{ + tep_unregister_print_function(tep, process___le16_to_cpup, + "__le16_to_cpup"); +} diff --git a/tools/lib/traceevent/plugins/plugin_function.c b/tools/lib/traceevent/plugins/plugin_function.c new file mode 100644 index 000000000000..7770fcb78e0f --- /dev/null +++ b/tools/lib/traceevent/plugins/plugin_function.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include + +#include "event-parse.h" +#include "event-utils.h" +#include "trace-seq.h" + +static struct func_stack { + int size; + char **stack; +} *fstack; + +static int cpus = -1; + +#define STK_BLK 10 + +struct tep_plugin_option plugin_options[] = +{ + { + .name = "parent", + .plugin_alias = "ftrace", + .description = + "Print parent of functions for function events", + }, + { + .name = "indent", + .plugin_alias = "ftrace", + .description = + "Try to show function call indents, based on parents", + .set = 1, + }, + { + .name = NULL, + } +}; + +static struct tep_plugin_option *ftrace_parent = &plugin_options[0]; +static struct tep_plugin_option *ftrace_indent = &plugin_options[1]; + +static void add_child(struct func_stack *stack, const char *child, int pos) +{ + int i; + + if (!child) + return; + + if (pos < stack->size) + free(stack->stack[pos]); + else { + char **ptr; + + ptr = realloc(stack->stack, sizeof(char *) * + (stack->size + STK_BLK)); + if (!ptr) { + warning("could not allocate plugin memory\n"); + return; + } + + stack->stack = ptr; + + for (i = stack->size; i < stack->size + STK_BLK; i++) + stack->stack[i] = NULL; + stack->size += STK_BLK; + } + + stack->stack[pos] = strdup(child); +} + +static int add_and_get_index(const char *parent, const char *child, int cpu) +{ + int i; + + if (cpu < 0) + return 0; + + if (cpu > cpus) { + struct func_stack *ptr; + + ptr = realloc(fstack, sizeof(*fstack) * (cpu + 1)); + if (!ptr) { + warning("could not allocate plugin memory\n"); + return 0; + } + + fstack = ptr; + + /* Account for holes in the cpu count */ + for (i = cpus + 1; i <= cpu; i++) + memset(&fstack[i], 0, sizeof(fstack[i])); + cpus = cpu; + } + + for (i = 0; i < fstack[cpu].size && fstack[cpu].stack[i]; i++) { + if (strcmp(parent, fstack[cpu].stack[i]) == 0) { + add_child(&fstack[cpu], child, i+1); + return i; + } + } + + /* Not found */ + add_child(&fstack[cpu], parent, 0); + add_child(&fstack[cpu], child, 1); + return 0; +} + +static int function_handler(struct trace_seq *s, struct tep_record *record, + struct tep_event *event, void *context) +{ + struct tep_handle *tep = event->tep; + unsigned long long function; + unsigned long long pfunction; + const char *func; + const char *parent; + int index = 0; + + if (tep_get_field_val(s, event, "ip", record, &function, 1)) + return trace_seq_putc(s, '!'); + + func = tep_find_function(tep, function); + + if (tep_get_field_val(s, event, "parent_ip", record, &pfunction, 1)) + return trace_seq_putc(s, '!'); + + parent = tep_find_function(tep, pfunction); + + if (parent && ftrace_indent->set) + index = add_and_get_index(parent, func, record->cpu); + + trace_seq_printf(s, "%*s", index*3, ""); + + if (func) + trace_seq_printf(s, "%s", func); + else + trace_seq_printf(s, "0x%llx", function); + + if (ftrace_parent->set) { + trace_seq_printf(s, " <-- "); + if (parent) + trace_seq_printf(s, "%s", parent); + else + trace_seq_printf(s, "0x%llx", pfunction); + } + + return 0; +} + +int TEP_PLUGIN_LOADER(struct tep_handle *tep) +{ + tep_register_event_handler(tep, -1, "ftrace", "function", + function_handler, NULL); + + tep_plugin_add_options("ftrace", plugin_options); + + return 0; +} + +void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) +{ + int i, x; + + tep_unregister_event_handler(tep, -1, "ftrace", "function", + function_handler, NULL); + + for (i = 0; i <= cpus; i++) { + for (x = 0; x < fstack[i].size && fstack[i].stack[x]; x++) + free(fstack[i].stack[x]); + free(fstack[i].stack); + } + + tep_plugin_remove_options(plugin_options); + + free(fstack); + fstack = NULL; + cpus = -1; +} diff --git a/tools/lib/traceevent/plugins/plugin_hrtimer.c b/tools/lib/traceevent/plugins/plugin_hrtimer.c new file mode 100644 index 000000000000..bb434e0ed03a --- /dev/null +++ b/tools/lib/traceevent/plugins/plugin_hrtimer.c @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2009 Red Hat Inc, Steven Rostedt + * Copyright (C) 2009 Johannes Berg + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include + +#include "event-parse.h" +#include "trace-seq.h" + +static int timer_expire_handler(struct trace_seq *s, + struct tep_record *record, + struct tep_event *event, void *context) +{ + trace_seq_printf(s, "hrtimer="); + + if (tep_print_num_field(s, "0x%llx", event, "timer", + record, 0) == -1) + tep_print_num_field(s, "0x%llx", event, "hrtimer", + record, 1); + + trace_seq_printf(s, " now="); + + tep_print_num_field(s, "%llu", event, "now", record, 1); + + tep_print_func_field(s, " function=%s", event, "function", + record, 0); + return 0; +} + +static int timer_start_handler(struct trace_seq *s, + struct tep_record *record, + struct tep_event *event, void *context) +{ + trace_seq_printf(s, "hrtimer="); + + if (tep_print_num_field(s, "0x%llx", event, "timer", + record, 0) == -1) + tep_print_num_field(s, "0x%llx", event, "hrtimer", + record, 1); + + tep_print_func_field(s, " function=%s", event, "function", + record, 0); + + trace_seq_printf(s, " expires="); + tep_print_num_field(s, "%llu", event, "expires", record, 1); + + trace_seq_printf(s, " softexpires="); + tep_print_num_field(s, "%llu", event, "softexpires", record, 1); + return 0; +} + +int TEP_PLUGIN_LOADER(struct tep_handle *tep) +{ + tep_register_event_handler(tep, -1, + "timer", "hrtimer_expire_entry", + timer_expire_handler, NULL); + + tep_register_event_handler(tep, -1, "timer", "hrtimer_start", + timer_start_handler, NULL); + return 0; +} + +void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) +{ + tep_unregister_event_handler(tep, -1, + "timer", "hrtimer_expire_entry", + timer_expire_handler, NULL); + + tep_unregister_event_handler(tep, -1, "timer", "hrtimer_start", + timer_start_handler, NULL); +} diff --git a/tools/lib/traceevent/plugins/plugin_jbd2.c b/tools/lib/traceevent/plugins/plugin_jbd2.c new file mode 100644 index 000000000000..04fc125f38cb --- /dev/null +++ b/tools/lib/traceevent/plugins/plugin_jbd2.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2010 Red Hat Inc, Steven Rostedt + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include + +#include "event-parse.h" +#include "trace-seq.h" + +#define MINORBITS 20 +#define MINORMASK ((1U << MINORBITS) - 1) + +#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS)) +#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK)) + +static unsigned long long +process_jbd2_dev_to_name(struct trace_seq *s, unsigned long long *args) +{ + unsigned int dev = args[0]; + + trace_seq_printf(s, "%d:%d", MAJOR(dev), MINOR(dev)); + return 0; +} + +static unsigned long long +process_jiffies_to_msecs(struct trace_seq *s, unsigned long long *args) +{ + unsigned long long jiffies = args[0]; + + trace_seq_printf(s, "%lld", jiffies); + return jiffies; +} + +int TEP_PLUGIN_LOADER(struct tep_handle *tep) +{ + tep_register_print_function(tep, + process_jbd2_dev_to_name, + TEP_FUNC_ARG_STRING, + "jbd2_dev_to_name", + TEP_FUNC_ARG_INT, + TEP_FUNC_ARG_VOID); + + tep_register_print_function(tep, + process_jiffies_to_msecs, + TEP_FUNC_ARG_LONG, + "jiffies_to_msecs", + TEP_FUNC_ARG_LONG, + TEP_FUNC_ARG_VOID); + return 0; +} + +void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) +{ + tep_unregister_print_function(tep, process_jbd2_dev_to_name, + "jbd2_dev_to_name"); + + tep_unregister_print_function(tep, process_jiffies_to_msecs, + "jiffies_to_msecs"); +} diff --git a/tools/lib/traceevent/plugins/plugin_kmem.c b/tools/lib/traceevent/plugins/plugin_kmem.c new file mode 100644 index 000000000000..edaec5d962c3 --- /dev/null +++ b/tools/lib/traceevent/plugins/plugin_kmem.c @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2009 Red Hat Inc, Steven Rostedt + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include + +#include "event-parse.h" +#include "trace-seq.h" + +static int call_site_handler(struct trace_seq *s, struct tep_record *record, + struct tep_event *event, void *context) +{ + struct tep_format_field *field; + unsigned long long val, addr; + void *data = record->data; + const char *func; + + field = tep_find_field(event, "call_site"); + if (!field) + return 1; + + if (tep_read_number_field(field, data, &val)) + return 1; + + func = tep_find_function(event->tep, val); + if (!func) + return 1; + + addr = tep_find_function_address(event->tep, val); + + trace_seq_printf(s, "(%s+0x%x) ", func, (int)(val - addr)); + return 1; +} + +int TEP_PLUGIN_LOADER(struct tep_handle *tep) +{ + tep_register_event_handler(tep, -1, "kmem", "kfree", + call_site_handler, NULL); + + tep_register_event_handler(tep, -1, "kmem", "kmalloc", + call_site_handler, NULL); + + tep_register_event_handler(tep, -1, "kmem", "kmalloc_node", + call_site_handler, NULL); + + tep_register_event_handler(tep, -1, "kmem", "kmem_cache_alloc", + call_site_handler, NULL); + + tep_register_event_handler(tep, -1, "kmem", + "kmem_cache_alloc_node", + call_site_handler, NULL); + + tep_register_event_handler(tep, -1, "kmem", "kmem_cache_free", + call_site_handler, NULL); + return 0; +} + +void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) +{ + tep_unregister_event_handler(tep, -1, "kmem", "kfree", + call_site_handler, NULL); + + tep_unregister_event_handler(tep, -1, "kmem", "kmalloc", + call_site_handler, NULL); + + tep_unregister_event_handler(tep, -1, "kmem", "kmalloc_node", + call_site_handler, NULL); + + tep_unregister_event_handler(tep, -1, "kmem", "kmem_cache_alloc", + call_site_handler, NULL); + + tep_unregister_event_handler(tep, -1, "kmem", + "kmem_cache_alloc_node", + call_site_handler, NULL); + + tep_unregister_event_handler(tep, -1, "kmem", "kmem_cache_free", + call_site_handler, NULL); +} diff --git a/tools/lib/traceevent/plugins/plugin_kvm.c b/tools/lib/traceevent/plugins/plugin_kvm.c new file mode 100644 index 000000000000..c8e623065a7e --- /dev/null +++ b/tools/lib/traceevent/plugins/plugin_kvm.c @@ -0,0 +1,523 @@ +/* + * Copyright (C) 2009 Red Hat Inc, Steven Rostedt + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include +#include + +#include "event-parse.h" +#include "trace-seq.h" + +#ifdef HAVE_UDIS86 + +#include + +static ud_t ud; + +static void init_disassembler(void) +{ + ud_init(&ud); + ud_set_syntax(&ud, UD_SYN_ATT); +} + +static const char *disassemble(unsigned char *insn, int len, uint64_t rip, + int cr0_pe, int eflags_vm, + int cs_d, int cs_l) +{ + int mode; + + if (!cr0_pe) + mode = 16; + else if (eflags_vm) + mode = 16; + else if (cs_l) + mode = 64; + else if (cs_d) + mode = 32; + else + mode = 16; + + ud_set_pc(&ud, rip); + ud_set_mode(&ud, mode); + ud_set_input_buffer(&ud, insn, len); + ud_disassemble(&ud); + return ud_insn_asm(&ud); +} + +#else + +static void init_disassembler(void) +{ +} + +static const char *disassemble(unsigned char *insn, int len, uint64_t rip, + int cr0_pe, int eflags_vm, + int cs_d, int cs_l) +{ + static char out[15*3+1]; + int i; + + for (i = 0; i < len; ++i) + sprintf(out + i * 3, "%02x ", insn[i]); + out[len*3-1] = '\0'; + return out; +} + +#endif + + +#define VMX_EXIT_REASONS \ + _ER(EXCEPTION_NMI, 0) \ + _ER(EXTERNAL_INTERRUPT, 1) \ + _ER(TRIPLE_FAULT, 2) \ + _ER(PENDING_INTERRUPT, 7) \ + _ER(NMI_WINDOW, 8) \ + _ER(TASK_SWITCH, 9) \ + _ER(CPUID, 10) \ + _ER(HLT, 12) \ + _ER(INVD, 13) \ + _ER(INVLPG, 14) \ + _ER(RDPMC, 15) \ + _ER(RDTSC, 16) \ + _ER(VMCALL, 18) \ + _ER(VMCLEAR, 19) \ + _ER(VMLAUNCH, 20) \ + _ER(VMPTRLD, 21) \ + _ER(VMPTRST, 22) \ + _ER(VMREAD, 23) \ + _ER(VMRESUME, 24) \ + _ER(VMWRITE, 25) \ + _ER(VMOFF, 26) \ + _ER(VMON, 27) \ + _ER(CR_ACCESS, 28) \ + _ER(DR_ACCESS, 29) \ + _ER(IO_INSTRUCTION, 30) \ + _ER(MSR_READ, 31) \ + _ER(MSR_WRITE, 32) \ + _ER(MWAIT_INSTRUCTION, 36) \ + _ER(MONITOR_INSTRUCTION, 39) \ + _ER(PAUSE_INSTRUCTION, 40) \ + _ER(MCE_DURING_VMENTRY, 41) \ + _ER(TPR_BELOW_THRESHOLD, 43) \ + _ER(APIC_ACCESS, 44) \ + _ER(EOI_INDUCED, 45) \ + _ER(EPT_VIOLATION, 48) \ + _ER(EPT_MISCONFIG, 49) \ + _ER(INVEPT, 50) \ + _ER(PREEMPTION_TIMER, 52) \ + _ER(WBINVD, 54) \ + _ER(XSETBV, 55) \ + _ER(APIC_WRITE, 56) \ + _ER(INVPCID, 58) \ + _ER(PML_FULL, 62) \ + _ER(XSAVES, 63) \ + _ER(XRSTORS, 64) + +#define SVM_EXIT_REASONS \ + _ER(EXIT_READ_CR0, 0x000) \ + _ER(EXIT_READ_CR3, 0x003) \ + _ER(EXIT_READ_CR4, 0x004) \ + _ER(EXIT_READ_CR8, 0x008) \ + _ER(EXIT_WRITE_CR0, 0x010) \ + _ER(EXIT_WRITE_CR3, 0x013) \ + _ER(EXIT_WRITE_CR4, 0x014) \ + _ER(EXIT_WRITE_CR8, 0x018) \ + _ER(EXIT_READ_DR0, 0x020) \ + _ER(EXIT_READ_DR1, 0x021) \ + _ER(EXIT_READ_DR2, 0x022) \ + _ER(EXIT_READ_DR3, 0x023) \ + _ER(EXIT_READ_DR4, 0x024) \ + _ER(EXIT_READ_DR5, 0x025) \ + _ER(EXIT_READ_DR6, 0x026) \ + _ER(EXIT_READ_DR7, 0x027) \ + _ER(EXIT_WRITE_DR0, 0x030) \ + _ER(EXIT_WRITE_DR1, 0x031) \ + _ER(EXIT_WRITE_DR2, 0x032) \ + _ER(EXIT_WRITE_DR3, 0x033) \ + _ER(EXIT_WRITE_DR4, 0x034) \ + _ER(EXIT_WRITE_DR5, 0x035) \ + _ER(EXIT_WRITE_DR6, 0x036) \ + _ER(EXIT_WRITE_DR7, 0x037) \ + _ER(EXIT_EXCP_BASE, 0x040) \ + _ER(EXIT_INTR, 0x060) \ + _ER(EXIT_NMI, 0x061) \ + _ER(EXIT_SMI, 0x062) \ + _ER(EXIT_INIT, 0x063) \ + _ER(EXIT_VINTR, 0x064) \ + _ER(EXIT_CR0_SEL_WRITE, 0x065) \ + _ER(EXIT_IDTR_READ, 0x066) \ + _ER(EXIT_GDTR_READ, 0x067) \ + _ER(EXIT_LDTR_READ, 0x068) \ + _ER(EXIT_TR_READ, 0x069) \ + _ER(EXIT_IDTR_WRITE, 0x06a) \ + _ER(EXIT_GDTR_WRITE, 0x06b) \ + _ER(EXIT_LDTR_WRITE, 0x06c) \ + _ER(EXIT_TR_WRITE, 0x06d) \ + _ER(EXIT_RDTSC, 0x06e) \ + _ER(EXIT_RDPMC, 0x06f) \ + _ER(EXIT_PUSHF, 0x070) \ + _ER(EXIT_POPF, 0x071) \ + _ER(EXIT_CPUID, 0x072) \ + _ER(EXIT_RSM, 0x073) \ + _ER(EXIT_IRET, 0x074) \ + _ER(EXIT_SWINT, 0x075) \ + _ER(EXIT_INVD, 0x076) \ + _ER(EXIT_PAUSE, 0x077) \ + _ER(EXIT_HLT, 0x078) \ + _ER(EXIT_INVLPG, 0x079) \ + _ER(EXIT_INVLPGA, 0x07a) \ + _ER(EXIT_IOIO, 0x07b) \ + _ER(EXIT_MSR, 0x07c) \ + _ER(EXIT_TASK_SWITCH, 0x07d) \ + _ER(EXIT_FERR_FREEZE, 0x07e) \ + _ER(EXIT_SHUTDOWN, 0x07f) \ + _ER(EXIT_VMRUN, 0x080) \ + _ER(EXIT_VMMCALL, 0x081) \ + _ER(EXIT_VMLOAD, 0x082) \ + _ER(EXIT_VMSAVE, 0x083) \ + _ER(EXIT_STGI, 0x084) \ + _ER(EXIT_CLGI, 0x085) \ + _ER(EXIT_SKINIT, 0x086) \ + _ER(EXIT_RDTSCP, 0x087) \ + _ER(EXIT_ICEBP, 0x088) \ + _ER(EXIT_WBINVD, 0x089) \ + _ER(EXIT_MONITOR, 0x08a) \ + _ER(EXIT_MWAIT, 0x08b) \ + _ER(EXIT_MWAIT_COND, 0x08c) \ + _ER(EXIT_NPF, 0x400) \ + _ER(EXIT_ERR, -1) + +#define _ER(reason, val) { #reason, val }, +struct str_values { + const char *str; + int val; +}; + +static struct str_values vmx_exit_reasons[] = { + VMX_EXIT_REASONS + { NULL, -1} +}; + +static struct str_values svm_exit_reasons[] = { + SVM_EXIT_REASONS + { NULL, -1} +}; + +static struct isa_exit_reasons { + unsigned isa; + struct str_values *strings; +} isa_exit_reasons[] = { + { .isa = 1, .strings = vmx_exit_reasons }, + { .isa = 2, .strings = svm_exit_reasons }, + { } +}; + +static const char *find_exit_reason(unsigned isa, int val) +{ + struct str_values *strings = NULL; + int i; + + for (i = 0; isa_exit_reasons[i].strings; ++i) + if (isa_exit_reasons[i].isa == isa) { + strings = isa_exit_reasons[i].strings; + break; + } + if (!strings) + return "UNKNOWN-ISA"; + for (i = 0; strings[i].val >= 0; i++) + if (strings[i].val == val) + break; + + return strings[i].str; +} + +static int print_exit_reason(struct trace_seq *s, struct tep_record *record, + struct tep_event *event, const char *field) +{ + unsigned long long isa; + unsigned long long val; + const char *reason; + + if (tep_get_field_val(s, event, field, record, &val, 1) < 0) + return -1; + + if (tep_get_field_val(s, event, "isa", record, &isa, 0) < 0) + isa = 1; + + reason = find_exit_reason(isa, val); + if (reason) + trace_seq_printf(s, "reason %s", reason); + else + trace_seq_printf(s, "reason UNKNOWN (%llu)", val); + return 0; +} + +static int kvm_exit_handler(struct trace_seq *s, struct tep_record *record, + struct tep_event *event, void *context) +{ + unsigned long long info1 = 0, info2 = 0; + + if (print_exit_reason(s, record, event, "exit_reason") < 0) + return -1; + + tep_print_num_field(s, " rip 0x%lx", event, "guest_rip", record, 1); + + if (tep_get_field_val(s, event, "info1", record, &info1, 0) >= 0 + && tep_get_field_val(s, event, "info2", record, &info2, 0) >= 0) + trace_seq_printf(s, " info %llx %llx", info1, info2); + + return 0; +} + +#define KVM_EMUL_INSN_F_CR0_PE (1 << 0) +#define KVM_EMUL_INSN_F_EFL_VM (1 << 1) +#define KVM_EMUL_INSN_F_CS_D (1 << 2) +#define KVM_EMUL_INSN_F_CS_L (1 << 3) + +static int kvm_emulate_insn_handler(struct trace_seq *s, + struct tep_record *record, + struct tep_event *event, void *context) +{ + unsigned long long rip, csbase, len, flags, failed; + int llen; + uint8_t *insn; + const char *disasm; + + if (tep_get_field_val(s, event, "rip", record, &rip, 1) < 0) + return -1; + + if (tep_get_field_val(s, event, "csbase", record, &csbase, 1) < 0) + return -1; + + if (tep_get_field_val(s, event, "len", record, &len, 1) < 0) + return -1; + + if (tep_get_field_val(s, event, "flags", record, &flags, 1) < 0) + return -1; + + if (tep_get_field_val(s, event, "failed", record, &failed, 1) < 0) + return -1; + + insn = tep_get_field_raw(s, event, "insn", record, &llen, 1); + if (!insn) + return -1; + + disasm = disassemble(insn, len, rip, + flags & KVM_EMUL_INSN_F_CR0_PE, + flags & KVM_EMUL_INSN_F_EFL_VM, + flags & KVM_EMUL_INSN_F_CS_D, + flags & KVM_EMUL_INSN_F_CS_L); + + trace_seq_printf(s, "%llx:%llx: %s%s", csbase, rip, disasm, + failed ? " FAIL" : ""); + return 0; +} + + +static int kvm_nested_vmexit_inject_handler(struct trace_seq *s, struct tep_record *record, + struct tep_event *event, void *context) +{ + if (print_exit_reason(s, record, event, "exit_code") < 0) + return -1; + + tep_print_num_field(s, " info1 %llx", event, "exit_info1", record, 1); + tep_print_num_field(s, " info2 %llx", event, "exit_info2", record, 1); + tep_print_num_field(s, " int_info %llx", event, "exit_int_info", record, 1); + tep_print_num_field(s, " int_info_err %llx", event, "exit_int_info_err", record, 1); + + return 0; +} + +static int kvm_nested_vmexit_handler(struct trace_seq *s, struct tep_record *record, + struct tep_event *event, void *context) +{ + tep_print_num_field(s, "rip %llx ", event, "rip", record, 1); + + return kvm_nested_vmexit_inject_handler(s, record, event, context); +} + +union kvm_mmu_page_role { + unsigned word; + struct { + unsigned level:4; + unsigned cr4_pae:1; + unsigned quadrant:2; + unsigned direct:1; + unsigned access:3; + unsigned invalid:1; + unsigned nxe:1; + unsigned cr0_wp:1; + unsigned smep_and_not_wp:1; + unsigned smap_and_not_wp:1; + unsigned pad_for_nice_hex_output:8; + unsigned smm:8; + }; +}; + +static int kvm_mmu_print_role(struct trace_seq *s, struct tep_record *record, + struct tep_event *event, void *context) +{ + unsigned long long val; + static const char *access_str[] = { + "---", "--x", "w--", "w-x", "-u-", "-ux", "wu-", "wux" + }; + union kvm_mmu_page_role role; + + if (tep_get_field_val(s, event, "role", record, &val, 1) < 0) + return -1; + + role.word = (int)val; + + /* + * We can only use the structure if file is of the same + * endianness. + */ + if (tep_is_file_bigendian(event->tep) == + tep_is_local_bigendian(event->tep)) { + + trace_seq_printf(s, "%u q%u%s %s%s %spae %snxe %swp%s%s%s", + role.level, + role.quadrant, + role.direct ? " direct" : "", + access_str[role.access], + role.invalid ? " invalid" : "", + role.cr4_pae ? "" : "!", + role.nxe ? "" : "!", + role.cr0_wp ? "" : "!", + role.smep_and_not_wp ? " smep" : "", + role.smap_and_not_wp ? " smap" : "", + role.smm ? " smm" : ""); + } else + trace_seq_printf(s, "WORD: %08x", role.word); + + tep_print_num_field(s, " root %u ", event, + "root_count", record, 1); + + if (tep_get_field_val(s, event, "unsync", record, &val, 1) < 0) + return -1; + + trace_seq_printf(s, "%s%c", val ? "unsync" : "sync", 0); + return 0; +} + +static int kvm_mmu_get_page_handler(struct trace_seq *s, + struct tep_record *record, + struct tep_event *event, void *context) +{ + unsigned long long val; + + if (tep_get_field_val(s, event, "created", record, &val, 1) < 0) + return -1; + + trace_seq_printf(s, "%s ", val ? "new" : "existing"); + + if (tep_get_field_val(s, event, "gfn", record, &val, 1) < 0) + return -1; + + trace_seq_printf(s, "sp gfn %llx ", val); + return kvm_mmu_print_role(s, record, event, context); +} + +#define PT_WRITABLE_SHIFT 1 +#define PT_WRITABLE_MASK (1ULL << PT_WRITABLE_SHIFT) + +static unsigned long long +process_is_writable_pte(struct trace_seq *s, unsigned long long *args) +{ + unsigned long pte = args[0]; + return pte & PT_WRITABLE_MASK; +} + +int TEP_PLUGIN_LOADER(struct tep_handle *tep) +{ + init_disassembler(); + + tep_register_event_handler(tep, -1, "kvm", "kvm_exit", + kvm_exit_handler, NULL); + + tep_register_event_handler(tep, -1, "kvm", "kvm_emulate_insn", + kvm_emulate_insn_handler, NULL); + + tep_register_event_handler(tep, -1, "kvm", "kvm_nested_vmexit", + kvm_nested_vmexit_handler, NULL); + + tep_register_event_handler(tep, -1, "kvm", "kvm_nested_vmexit_inject", + kvm_nested_vmexit_inject_handler, NULL); + + tep_register_event_handler(tep, -1, "kvmmmu", "kvm_mmu_get_page", + kvm_mmu_get_page_handler, NULL); + + tep_register_event_handler(tep, -1, "kvmmmu", "kvm_mmu_sync_page", + kvm_mmu_print_role, NULL); + + tep_register_event_handler(tep, -1, + "kvmmmu", "kvm_mmu_unsync_page", + kvm_mmu_print_role, NULL); + + tep_register_event_handler(tep, -1, "kvmmmu", "kvm_mmu_zap_page", + kvm_mmu_print_role, NULL); + + tep_register_event_handler(tep, -1, "kvmmmu", + "kvm_mmu_prepare_zap_page", kvm_mmu_print_role, + NULL); + + tep_register_print_function(tep, + process_is_writable_pte, + TEP_FUNC_ARG_INT, + "is_writable_pte", + TEP_FUNC_ARG_LONG, + TEP_FUNC_ARG_VOID); + return 0; +} + +void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) +{ + tep_unregister_event_handler(tep, -1, "kvm", "kvm_exit", + kvm_exit_handler, NULL); + + tep_unregister_event_handler(tep, -1, "kvm", "kvm_emulate_insn", + kvm_emulate_insn_handler, NULL); + + tep_unregister_event_handler(tep, -1, "kvm", "kvm_nested_vmexit", + kvm_nested_vmexit_handler, NULL); + + tep_unregister_event_handler(tep, -1, "kvm", "kvm_nested_vmexit_inject", + kvm_nested_vmexit_inject_handler, NULL); + + tep_unregister_event_handler(tep, -1, "kvmmmu", "kvm_mmu_get_page", + kvm_mmu_get_page_handler, NULL); + + tep_unregister_event_handler(tep, -1, "kvmmmu", "kvm_mmu_sync_page", + kvm_mmu_print_role, NULL); + + tep_unregister_event_handler(tep, -1, + "kvmmmu", "kvm_mmu_unsync_page", + kvm_mmu_print_role, NULL); + + tep_unregister_event_handler(tep, -1, "kvmmmu", "kvm_mmu_zap_page", + kvm_mmu_print_role, NULL); + + tep_unregister_event_handler(tep, -1, "kvmmmu", + "kvm_mmu_prepare_zap_page", kvm_mmu_print_role, + NULL); + + tep_unregister_print_function(tep, process_is_writable_pte, + "is_writable_pte"); +} diff --git a/tools/lib/traceevent/plugins/plugin_mac80211.c b/tools/lib/traceevent/plugins/plugin_mac80211.c new file mode 100644 index 000000000000..884303c26b5c --- /dev/null +++ b/tools/lib/traceevent/plugins/plugin_mac80211.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2009 Johannes Berg + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include + +#include "event-parse.h" +#include "trace-seq.h" + +#define INDENT 65 + +static void print_string(struct trace_seq *s, struct tep_event *event, + const char *name, const void *data) +{ + struct tep_format_field *f = tep_find_field(event, name); + int offset; + int length; + + if (!f) { + trace_seq_printf(s, "NOTFOUND:%s", name); + return; + } + + offset = f->offset; + length = f->size; + + if (!strncmp(f->type, "__data_loc", 10)) { + unsigned long long v; + if (tep_read_number_field(f, data, &v)) { + trace_seq_printf(s, "invalid_data_loc"); + return; + } + offset = v & 0xffff; + length = v >> 16; + } + + trace_seq_printf(s, "%.*s", length, (char *)data + offset); +} + +#define SF(fn) tep_print_num_field(s, fn ":%d", event, fn, record, 0) +#define SFX(fn) tep_print_num_field(s, fn ":%#x", event, fn, record, 0) +#define SP() trace_seq_putc(s, ' ') + +static int drv_bss_info_changed(struct trace_seq *s, + struct tep_record *record, + struct tep_event *event, void *context) +{ + void *data = record->data; + + print_string(s, event, "wiphy_name", data); + trace_seq_printf(s, " vif:"); + print_string(s, event, "vif_name", data); + tep_print_num_field(s, "(%d)", event, "vif_type", record, 1); + + trace_seq_printf(s, "\n%*s", INDENT, ""); + SF("assoc"); SP(); + SF("aid"); SP(); + SF("cts"); SP(); + SF("shortpre"); SP(); + SF("shortslot"); SP(); + SF("dtimper"); SP(); + trace_seq_printf(s, "\n%*s", INDENT, ""); + SF("bcnint"); SP(); + SFX("assoc_cap"); SP(); + SFX("basic_rates"); SP(); + SF("enable_beacon"); + trace_seq_printf(s, "\n%*s", INDENT, ""); + SF("ht_operation_mode"); + + return 0; +} + +int TEP_PLUGIN_LOADER(struct tep_handle *tep) +{ + tep_register_event_handler(tep, -1, "mac80211", + "drv_bss_info_changed", + drv_bss_info_changed, NULL); + return 0; +} + +void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) +{ + tep_unregister_event_handler(tep, -1, "mac80211", + "drv_bss_info_changed", + drv_bss_info_changed, NULL); +} diff --git a/tools/lib/traceevent/plugins/plugin_sched_switch.c b/tools/lib/traceevent/plugins/plugin_sched_switch.c new file mode 100644 index 000000000000..957389a0ff7a --- /dev/null +++ b/tools/lib/traceevent/plugins/plugin_sched_switch.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include + +#include "event-parse.h" +#include "trace-seq.h" + +static void write_state(struct trace_seq *s, int val) +{ + const char states[] = "SDTtZXxW"; + int found = 0; + int i; + + for (i = 0; i < (sizeof(states) - 1); i++) { + if (!(val & (1 << i))) + continue; + + if (found) + trace_seq_putc(s, '|'); + + found = 1; + trace_seq_putc(s, states[i]); + } + + if (!found) + trace_seq_putc(s, 'R'); +} + +static void write_and_save_comm(struct tep_format_field *field, + struct tep_record *record, + struct trace_seq *s, int pid) +{ + const char *comm; + int len; + + comm = (char *)(record->data + field->offset); + len = s->len; + trace_seq_printf(s, "%.*s", + field->size, comm); + + /* make sure the comm has a \0 at the end. */ + trace_seq_terminate(s); + comm = &s->buffer[len]; + + /* Help out the comm to ids. This will handle dups */ + tep_register_comm(field->event->tep, comm, pid); +} + +static int sched_wakeup_handler(struct trace_seq *s, + struct tep_record *record, + struct tep_event *event, void *context) +{ + struct tep_format_field *field; + unsigned long long val; + + if (tep_get_field_val(s, event, "pid", record, &val, 1)) + return trace_seq_putc(s, '!'); + + field = tep_find_any_field(event, "comm"); + if (field) { + write_and_save_comm(field, record, s, val); + trace_seq_putc(s, ':'); + } + trace_seq_printf(s, "%lld", val); + + if (tep_get_field_val(s, event, "prio", record, &val, 0) == 0) + trace_seq_printf(s, " [%lld]", val); + + if (tep_get_field_val(s, event, "success", record, &val, 1) == 0) + trace_seq_printf(s, " success=%lld", val); + + if (tep_get_field_val(s, event, "target_cpu", record, &val, 0) == 0) + trace_seq_printf(s, " CPU:%03llu", val); + + return 0; +} + +static int sched_switch_handler(struct trace_seq *s, + struct tep_record *record, + struct tep_event *event, void *context) +{ + struct tep_format_field *field; + unsigned long long val; + + if (tep_get_field_val(s, event, "prev_pid", record, &val, 1)) + return trace_seq_putc(s, '!'); + + field = tep_find_any_field(event, "prev_comm"); + if (field) { + write_and_save_comm(field, record, s, val); + trace_seq_putc(s, ':'); + } + trace_seq_printf(s, "%lld ", val); + + if (tep_get_field_val(s, event, "prev_prio", record, &val, 0) == 0) + trace_seq_printf(s, "[%d] ", (int) val); + + if (tep_get_field_val(s, event, "prev_state", record, &val, 0) == 0) + write_state(s, val); + + trace_seq_puts(s, " ==> "); + + if (tep_get_field_val(s, event, "next_pid", record, &val, 1)) + return trace_seq_putc(s, '!'); + + field = tep_find_any_field(event, "next_comm"); + if (field) { + write_and_save_comm(field, record, s, val); + trace_seq_putc(s, ':'); + } + trace_seq_printf(s, "%lld", val); + + if (tep_get_field_val(s, event, "next_prio", record, &val, 0) == 0) + trace_seq_printf(s, " [%d]", (int) val); + + return 0; +} + +int TEP_PLUGIN_LOADER(struct tep_handle *tep) +{ + tep_register_event_handler(tep, -1, "sched", "sched_switch", + sched_switch_handler, NULL); + + tep_register_event_handler(tep, -1, "sched", "sched_wakeup", + sched_wakeup_handler, NULL); + + tep_register_event_handler(tep, -1, "sched", "sched_wakeup_new", + sched_wakeup_handler, NULL); + return 0; +} + +void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) +{ + tep_unregister_event_handler(tep, -1, "sched", "sched_switch", + sched_switch_handler, NULL); + + tep_unregister_event_handler(tep, -1, "sched", "sched_wakeup", + sched_wakeup_handler, NULL); + + tep_unregister_event_handler(tep, -1, "sched", "sched_wakeup_new", + sched_wakeup_handler, NULL); +} diff --git a/tools/lib/traceevent/plugins/plugin_scsi.c b/tools/lib/traceevent/plugins/plugin_scsi.c new file mode 100644 index 000000000000..5d0387a4b65a --- /dev/null +++ b/tools/lib/traceevent/plugins/plugin_scsi.c @@ -0,0 +1,434 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include "event-parse.h" +#include "trace-seq.h" + +typedef unsigned long sector_t; +typedef uint64_t u64; +typedef unsigned int u32; + +/* + * SCSI opcodes + */ +#define TEST_UNIT_READY 0x00 +#define REZERO_UNIT 0x01 +#define REQUEST_SENSE 0x03 +#define FORMAT_UNIT 0x04 +#define READ_BLOCK_LIMITS 0x05 +#define REASSIGN_BLOCKS 0x07 +#define INITIALIZE_ELEMENT_STATUS 0x07 +#define READ_6 0x08 +#define WRITE_6 0x0a +#define SEEK_6 0x0b +#define READ_REVERSE 0x0f +#define WRITE_FILEMARKS 0x10 +#define SPACE 0x11 +#define INQUIRY 0x12 +#define RECOVER_BUFFERED_DATA 0x14 +#define MODE_SELECT 0x15 +#define RESERVE 0x16 +#define RELEASE 0x17 +#define COPY 0x18 +#define ERASE 0x19 +#define MODE_SENSE 0x1a +#define START_STOP 0x1b +#define RECEIVE_DIAGNOSTIC 0x1c +#define SEND_DIAGNOSTIC 0x1d +#define ALLOW_MEDIUM_REMOVAL 0x1e + +#define READ_FORMAT_CAPACITIES 0x23 +#define SET_WINDOW 0x24 +#define READ_CAPACITY 0x25 +#define READ_10 0x28 +#define WRITE_10 0x2a +#define SEEK_10 0x2b +#define POSITION_TO_ELEMENT 0x2b +#define WRITE_VERIFY 0x2e +#define VERIFY 0x2f +#define SEARCH_HIGH 0x30 +#define SEARCH_EQUAL 0x31 +#define SEARCH_LOW 0x32 +#define SET_LIMITS 0x33 +#define PRE_FETCH 0x34 +#define READ_POSITION 0x34 +#define SYNCHRONIZE_CACHE 0x35 +#define LOCK_UNLOCK_CACHE 0x36 +#define READ_DEFECT_DATA 0x37 +#define MEDIUM_SCAN 0x38 +#define COMPARE 0x39 +#define COPY_VERIFY 0x3a +#define WRITE_BUFFER 0x3b +#define READ_BUFFER 0x3c +#define UPDATE_BLOCK 0x3d +#define READ_LONG 0x3e +#define WRITE_LONG 0x3f +#define CHANGE_DEFINITION 0x40 +#define WRITE_SAME 0x41 +#define UNMAP 0x42 +#define READ_TOC 0x43 +#define READ_HEADER 0x44 +#define GET_EVENT_STATUS_NOTIFICATION 0x4a +#define LOG_SELECT 0x4c +#define LOG_SENSE 0x4d +#define XDWRITEREAD_10 0x53 +#define MODE_SELECT_10 0x55 +#define RESERVE_10 0x56 +#define RELEASE_10 0x57 +#define MODE_SENSE_10 0x5a +#define PERSISTENT_RESERVE_IN 0x5e +#define PERSISTENT_RESERVE_OUT 0x5f +#define VARIABLE_LENGTH_CMD 0x7f +#define REPORT_LUNS 0xa0 +#define SECURITY_PROTOCOL_IN 0xa2 +#define MAINTENANCE_IN 0xa3 +#define MAINTENANCE_OUT 0xa4 +#define MOVE_MEDIUM 0xa5 +#define EXCHANGE_MEDIUM 0xa6 +#define READ_12 0xa8 +#define SERVICE_ACTION_OUT_12 0xa9 +#define WRITE_12 0xaa +#define SERVICE_ACTION_IN_12 0xab +#define WRITE_VERIFY_12 0xae +#define VERIFY_12 0xaf +#define SEARCH_HIGH_12 0xb0 +#define SEARCH_EQUAL_12 0xb1 +#define SEARCH_LOW_12 0xb2 +#define SECURITY_PROTOCOL_OUT 0xb5 +#define READ_ELEMENT_STATUS 0xb8 +#define SEND_VOLUME_TAG 0xb6 +#define WRITE_LONG_2 0xea +#define EXTENDED_COPY 0x83 +#define RECEIVE_COPY_RESULTS 0x84 +#define ACCESS_CONTROL_IN 0x86 +#define ACCESS_CONTROL_OUT 0x87 +#define READ_16 0x88 +#define WRITE_16 0x8a +#define READ_ATTRIBUTE 0x8c +#define WRITE_ATTRIBUTE 0x8d +#define VERIFY_16 0x8f +#define SYNCHRONIZE_CACHE_16 0x91 +#define WRITE_SAME_16 0x93 +#define SERVICE_ACTION_BIDIRECTIONAL 0x9d +#define SERVICE_ACTION_IN_16 0x9e +#define SERVICE_ACTION_OUT_16 0x9f +/* values for service action in */ +#define SAI_READ_CAPACITY_16 0x10 +#define SAI_GET_LBA_STATUS 0x12 +/* values for VARIABLE_LENGTH_CMD service action codes + * see spc4r17 Section D.3.5, table D.7 and D.8 */ +#define VLC_SA_RECEIVE_CREDENTIAL 0x1800 +/* values for maintenance in */ +#define MI_REPORT_IDENTIFYING_INFORMATION 0x05 +#define MI_REPORT_TARGET_PGS 0x0a +#define MI_REPORT_ALIASES 0x0b +#define MI_REPORT_SUPPORTED_OPERATION_CODES 0x0c +#define MI_REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS 0x0d +#define MI_REPORT_PRIORITY 0x0e +#define MI_REPORT_TIMESTAMP 0x0f +#define MI_MANAGEMENT_PROTOCOL_IN 0x10 +/* value for MI_REPORT_TARGET_PGS ext header */ +#define MI_EXT_HDR_PARAM_FMT 0x20 +/* values for maintenance out */ +#define MO_SET_IDENTIFYING_INFORMATION 0x06 +#define MO_SET_TARGET_PGS 0x0a +#define MO_CHANGE_ALIASES 0x0b +#define MO_SET_PRIORITY 0x0e +#define MO_SET_TIMESTAMP 0x0f +#define MO_MANAGEMENT_PROTOCOL_OUT 0x10 +/* values for variable length command */ +#define XDREAD_32 0x03 +#define XDWRITE_32 0x04 +#define XPWRITE_32 0x06 +#define XDWRITEREAD_32 0x07 +#define READ_32 0x09 +#define VERIFY_32 0x0a +#define WRITE_32 0x0b +#define WRITE_SAME_32 0x0d + +#define SERVICE_ACTION16(cdb) (cdb[1] & 0x1f) +#define SERVICE_ACTION32(cdb) ((cdb[8] << 8) | cdb[9]) + +static const char * +scsi_trace_misc(struct trace_seq *, unsigned char *, int); + +static const char * +scsi_trace_rw6(struct trace_seq *p, unsigned char *cdb, int len) +{ + const char *ret = p->buffer + p->len; + sector_t lba = 0, txlen = 0; + + lba |= ((cdb[1] & 0x1F) << 16); + lba |= (cdb[2] << 8); + lba |= cdb[3]; + txlen = cdb[4]; + + trace_seq_printf(p, "lba=%llu txlen=%llu", + (unsigned long long)lba, (unsigned long long)txlen); + trace_seq_putc(p, 0); + return ret; +} + +static const char * +scsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len) +{ + const char *ret = p->buffer + p->len; + sector_t lba = 0, txlen = 0; + + lba |= (cdb[2] << 24); + lba |= (cdb[3] << 16); + lba |= (cdb[4] << 8); + lba |= cdb[5]; + txlen |= (cdb[7] << 8); + txlen |= cdb[8]; + + trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u", + (unsigned long long)lba, (unsigned long long)txlen, + cdb[1] >> 5); + + if (cdb[0] == WRITE_SAME) + trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1); + + trace_seq_putc(p, 0); + return ret; +} + +static const char * +scsi_trace_rw12(struct trace_seq *p, unsigned char *cdb, int len) +{ + const char *ret = p->buffer + p->len; + sector_t lba = 0, txlen = 0; + + lba |= (cdb[2] << 24); + lba |= (cdb[3] << 16); + lba |= (cdb[4] << 8); + lba |= cdb[5]; + txlen |= (cdb[6] << 24); + txlen |= (cdb[7] << 16); + txlen |= (cdb[8] << 8); + txlen |= cdb[9]; + + trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u", + (unsigned long long)lba, (unsigned long long)txlen, + cdb[1] >> 5); + trace_seq_putc(p, 0); + return ret; +} + +static const char * +scsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len) +{ + const char *ret = p->buffer + p->len; + sector_t lba = 0, txlen = 0; + + lba |= ((u64)cdb[2] << 56); + lba |= ((u64)cdb[3] << 48); + lba |= ((u64)cdb[4] << 40); + lba |= ((u64)cdb[5] << 32); + lba |= (cdb[6] << 24); + lba |= (cdb[7] << 16); + lba |= (cdb[8] << 8); + lba |= cdb[9]; + txlen |= (cdb[10] << 24); + txlen |= (cdb[11] << 16); + txlen |= (cdb[12] << 8); + txlen |= cdb[13]; + + trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u", + (unsigned long long)lba, (unsigned long long)txlen, + cdb[1] >> 5); + + if (cdb[0] == WRITE_SAME_16) + trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1); + + trace_seq_putc(p, 0); + return ret; +} + +static const char * +scsi_trace_rw32(struct trace_seq *p, unsigned char *cdb, int len) +{ + const char *ret = p->buffer + p->len, *cmd; + sector_t lba = 0, txlen = 0; + u32 ei_lbrt = 0; + + switch (SERVICE_ACTION32(cdb)) { + case READ_32: + cmd = "READ"; + break; + case VERIFY_32: + cmd = "VERIFY"; + break; + case WRITE_32: + cmd = "WRITE"; + break; + case WRITE_SAME_32: + cmd = "WRITE_SAME"; + break; + default: + trace_seq_printf(p, "UNKNOWN"); + goto out; + } + + lba |= ((u64)cdb[12] << 56); + lba |= ((u64)cdb[13] << 48); + lba |= ((u64)cdb[14] << 40); + lba |= ((u64)cdb[15] << 32); + lba |= (cdb[16] << 24); + lba |= (cdb[17] << 16); + lba |= (cdb[18] << 8); + lba |= cdb[19]; + ei_lbrt |= (cdb[20] << 24); + ei_lbrt |= (cdb[21] << 16); + ei_lbrt |= (cdb[22] << 8); + ei_lbrt |= cdb[23]; + txlen |= (cdb[28] << 24); + txlen |= (cdb[29] << 16); + txlen |= (cdb[30] << 8); + txlen |= cdb[31]; + + trace_seq_printf(p, "%s_32 lba=%llu txlen=%llu protect=%u ei_lbrt=%u", + cmd, (unsigned long long)lba, + (unsigned long long)txlen, cdb[10] >> 5, ei_lbrt); + + if (SERVICE_ACTION32(cdb) == WRITE_SAME_32) + trace_seq_printf(p, " unmap=%u", cdb[10] >> 3 & 1); + +out: + trace_seq_putc(p, 0); + return ret; +} + +static const char * +scsi_trace_unmap(struct trace_seq *p, unsigned char *cdb, int len) +{ + const char *ret = p->buffer + p->len; + unsigned int regions = cdb[7] << 8 | cdb[8]; + + trace_seq_printf(p, "regions=%u", (regions - 8) / 16); + trace_seq_putc(p, 0); + return ret; +} + +static const char * +scsi_trace_service_action_in(struct trace_seq *p, unsigned char *cdb, int len) +{ + const char *ret = p->buffer + p->len, *cmd; + sector_t lba = 0; + u32 alloc_len = 0; + + switch (SERVICE_ACTION16(cdb)) { + case SAI_READ_CAPACITY_16: + cmd = "READ_CAPACITY_16"; + break; + case SAI_GET_LBA_STATUS: + cmd = "GET_LBA_STATUS"; + break; + default: + trace_seq_printf(p, "UNKNOWN"); + goto out; + } + + lba |= ((u64)cdb[2] << 56); + lba |= ((u64)cdb[3] << 48); + lba |= ((u64)cdb[4] << 40); + lba |= ((u64)cdb[5] << 32); + lba |= (cdb[6] << 24); + lba |= (cdb[7] << 16); + lba |= (cdb[8] << 8); + lba |= cdb[9]; + alloc_len |= (cdb[10] << 24); + alloc_len |= (cdb[11] << 16); + alloc_len |= (cdb[12] << 8); + alloc_len |= cdb[13]; + + trace_seq_printf(p, "%s lba=%llu alloc_len=%u", cmd, + (unsigned long long)lba, alloc_len); + +out: + trace_seq_putc(p, 0); + return ret; +} + +static const char * +scsi_trace_varlen(struct trace_seq *p, unsigned char *cdb, int len) +{ + switch (SERVICE_ACTION32(cdb)) { + case READ_32: + case VERIFY_32: + case WRITE_32: + case WRITE_SAME_32: + return scsi_trace_rw32(p, cdb, len); + default: + return scsi_trace_misc(p, cdb, len); + } +} + +static const char * +scsi_trace_misc(struct trace_seq *p, unsigned char *cdb, int len) +{ + const char *ret = p->buffer + p->len; + + trace_seq_printf(p, "-"); + trace_seq_putc(p, 0); + return ret; +} + +const char * +scsi_trace_parse_cdb(struct trace_seq *p, unsigned char *cdb, int len) +{ + switch (cdb[0]) { + case READ_6: + case WRITE_6: + return scsi_trace_rw6(p, cdb, len); + case READ_10: + case VERIFY: + case WRITE_10: + case WRITE_SAME: + return scsi_trace_rw10(p, cdb, len); + case READ_12: + case VERIFY_12: + case WRITE_12: + return scsi_trace_rw12(p, cdb, len); + case READ_16: + case VERIFY_16: + case WRITE_16: + case WRITE_SAME_16: + return scsi_trace_rw16(p, cdb, len); + case UNMAP: + return scsi_trace_unmap(p, cdb, len); + case SERVICE_ACTION_IN_16: + return scsi_trace_service_action_in(p, cdb, len); + case VARIABLE_LENGTH_CMD: + return scsi_trace_varlen(p, cdb, len); + default: + return scsi_trace_misc(p, cdb, len); + } +} + +unsigned long long process_scsi_trace_parse_cdb(struct trace_seq *s, + unsigned long long *args) +{ + scsi_trace_parse_cdb(s, (unsigned char *) (unsigned long) args[1], args[2]); + return 0; +} + +int TEP_PLUGIN_LOADER(struct tep_handle *tep) +{ + tep_register_print_function(tep, + process_scsi_trace_parse_cdb, + TEP_FUNC_ARG_STRING, + "scsi_trace_parse_cdb", + TEP_FUNC_ARG_PTR, + TEP_FUNC_ARG_PTR, + TEP_FUNC_ARG_INT, + TEP_FUNC_ARG_VOID); + return 0; +} + +void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) +{ + tep_unregister_print_function(tep, process_scsi_trace_parse_cdb, + "scsi_trace_parse_cdb"); +} diff --git a/tools/lib/traceevent/plugins/plugin_xen.c b/tools/lib/traceevent/plugins/plugin_xen.c new file mode 100644 index 000000000000..993b208d0323 --- /dev/null +++ b/tools/lib/traceevent/plugins/plugin_xen.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include "event-parse.h" +#include "trace-seq.h" + +#define __HYPERVISOR_set_trap_table 0 +#define __HYPERVISOR_mmu_update 1 +#define __HYPERVISOR_set_gdt 2 +#define __HYPERVISOR_stack_switch 3 +#define __HYPERVISOR_set_callbacks 4 +#define __HYPERVISOR_fpu_taskswitch 5 +#define __HYPERVISOR_sched_op_compat 6 +#define __HYPERVISOR_dom0_op 7 +#define __HYPERVISOR_set_debugreg 8 +#define __HYPERVISOR_get_debugreg 9 +#define __HYPERVISOR_update_descriptor 10 +#define __HYPERVISOR_memory_op 12 +#define __HYPERVISOR_multicall 13 +#define __HYPERVISOR_update_va_mapping 14 +#define __HYPERVISOR_set_timer_op 15 +#define __HYPERVISOR_event_channel_op_compat 16 +#define __HYPERVISOR_xen_version 17 +#define __HYPERVISOR_console_io 18 +#define __HYPERVISOR_physdev_op_compat 19 +#define __HYPERVISOR_grant_table_op 20 +#define __HYPERVISOR_vm_assist 21 +#define __HYPERVISOR_update_va_mapping_otherdomain 22 +#define __HYPERVISOR_iret 23 /* x86 only */ +#define __HYPERVISOR_vcpu_op 24 +#define __HYPERVISOR_set_segment_base 25 /* x86/64 only */ +#define __HYPERVISOR_mmuext_op 26 +#define __HYPERVISOR_acm_op 27 +#define __HYPERVISOR_nmi_op 28 +#define __HYPERVISOR_sched_op 29 +#define __HYPERVISOR_callback_op 30 +#define __HYPERVISOR_xenoprof_op 31 +#define __HYPERVISOR_event_channel_op 32 +#define __HYPERVISOR_physdev_op 33 +#define __HYPERVISOR_hvm_op 34 +#define __HYPERVISOR_tmem_op 38 + +/* Architecture-specific hypercall definitions. */ +#define __HYPERVISOR_arch_0 48 +#define __HYPERVISOR_arch_1 49 +#define __HYPERVISOR_arch_2 50 +#define __HYPERVISOR_arch_3 51 +#define __HYPERVISOR_arch_4 52 +#define __HYPERVISOR_arch_5 53 +#define __HYPERVISOR_arch_6 54 +#define __HYPERVISOR_arch_7 55 + +#define N(x) [__HYPERVISOR_##x] = "("#x")" +static const char *xen_hypercall_names[] = { + N(set_trap_table), + N(mmu_update), + N(set_gdt), + N(stack_switch), + N(set_callbacks), + N(fpu_taskswitch), + N(sched_op_compat), + N(dom0_op), + N(set_debugreg), + N(get_debugreg), + N(update_descriptor), + N(memory_op), + N(multicall), + N(update_va_mapping), + N(set_timer_op), + N(event_channel_op_compat), + N(xen_version), + N(console_io), + N(physdev_op_compat), + N(grant_table_op), + N(vm_assist), + N(update_va_mapping_otherdomain), + N(iret), + N(vcpu_op), + N(set_segment_base), + N(mmuext_op), + N(acm_op), + N(nmi_op), + N(sched_op), + N(callback_op), + N(xenoprof_op), + N(event_channel_op), + N(physdev_op), + N(hvm_op), + +/* Architecture-specific hypercall definitions. */ + N(arch_0), + N(arch_1), + N(arch_2), + N(arch_3), + N(arch_4), + N(arch_5), + N(arch_6), + N(arch_7), +}; +#undef N + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +static const char *xen_hypercall_name(unsigned op) +{ + if (op < ARRAY_SIZE(xen_hypercall_names) && + xen_hypercall_names[op] != NULL) + return xen_hypercall_names[op]; + + return ""; +} + +unsigned long long process_xen_hypercall_name(struct trace_seq *s, + unsigned long long *args) +{ + unsigned int op = args[0]; + + trace_seq_printf(s, "%s", xen_hypercall_name(op)); + return 0; +} + +int TEP_PLUGIN_LOADER(struct tep_handle *tep) +{ + tep_register_print_function(tep, + process_xen_hypercall_name, + TEP_FUNC_ARG_STRING, + "xen_hypercall_name", + TEP_FUNC_ARG_INT, + TEP_FUNC_ARG_VOID); + return 0; +} + +void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) +{ + tep_unregister_print_function(tep, process_xen_hypercall_name, + "xen_hypercall_name"); +} diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 2ccc12f3730b..902c792f326a 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -292,7 +292,7 @@ endif LIBTRACEEVENT = $(TE_PATH)libtraceevent.a export LIBTRACEEVENT -LIBTRACEEVENT_DYNAMIC_LIST = $(TE_PATH)libtraceevent-dynamic-list +LIBTRACEEVENT_DYNAMIC_LIST = $(TE_PATH)plugins/libtraceevent-dynamic-list # # The static build has no dynsym table, so this does not work for @@ -737,7 +737,7 @@ libtraceevent_plugins: FORCE $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) plugins $(LIBTRACEEVENT_DYNAMIC_LIST): libtraceevent_plugins - $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent-dynamic-list + $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)plugins/libtraceevent-dynamic-list $(LIBTRACEEVENT)-clean: $(call QUIET_CLEAN, libtraceevent) -- cgit v1.2.3-59-g8ed1b From 33c96400dcd34d572299b8106e1b0460a1b8bae9 Mon Sep 17 00:00:00 2001 From: Tzvetomir Stoyanov Date: Thu, 19 Sep 2019 17:23:40 -0400 Subject: libtraceevent: Man pages for tep plugins APIs Create man pages for libtraceevent APIs: tep_load_plugins(), tep_unload_plugin() Signed-off-by: Tzvetomir Stoyanov Cc: Andrew Morton Cc: Jiri Olsa Cc: Namhyung Kim Cc: linux-trace-devel@vger.kernel.org Link: http://lore.kernel.org/linux-trace-devel/20190903133434.30417-1-tz.stoyanov@gmail.com Link: http://lore.kernel.org/lkml/20190919212542.216189588@goodmis.org Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Arnaldo Carvalho de Melo --- .../Documentation/libtraceevent-plugins.txt | 99 ++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 tools/lib/traceevent/Documentation/libtraceevent-plugins.txt (limited to 'tools') diff --git a/tools/lib/traceevent/Documentation/libtraceevent-plugins.txt b/tools/lib/traceevent/Documentation/libtraceevent-plugins.txt new file mode 100644 index 000000000000..596032ade31f --- /dev/null +++ b/tools/lib/traceevent/Documentation/libtraceevent-plugins.txt @@ -0,0 +1,99 @@ +libtraceevent(3) +================ + +NAME +---- +tep_load_plugins, tep_unload_plugins - Load / unload traceevent plugins. + +SYNOPSIS +-------- +[verse] +-- +*#include * + +struct tep_plugin_list pass:[*]*tep_load_plugins*(struct tep_handle pass:[*]_tep_); +void *tep_unload_plugins*(struct tep_plugin_list pass:[*]_plugin_list_, struct tep_handle pass:[*]_tep_); +-- + +DESCRIPTION +----------- +The _tep_load_plugins()_ function loads all plugins, located in the plugin +directories. The _tep_ argument is trace event parser context. +The plugin directories are : +[verse] +-- + - System's plugin directory, defined at the library compile time. It + depends on the library installation prefix and usually is + _(install_preffix)/lib/traceevent/plugins_ + - Directory, defined by the environment variable _TRACEEVENT_PLUGIN_DIR_ + - User's plugin directory, located at _~/.local/lib/traceevent/plugins_ +-- +Loading of plugins can be controlled by the _tep_flags_, using the +_tep_set_flag()_ API: +[verse] +-- + _TEP_DISABLE_SYS_PLUGINS_ - do not load plugins, located in + the system's plugin directory. + _TEP_DISABLE_PLUGINS_ - do not load any plugins. +-- +The _tep_set_flag()_ API needs to be called before _tep_load_plugins()_, if +loading of all plugins is not the desired case. + +The _tep_unload_plugins()_ function unloads the plugins, previously loaded by +_tep_load_plugins()_. The _tep_ argument is trace event parser context. The +_plugin_list_ is the list of loaded plugins, returned by +the _tep_load_plugins()_ function. + +RETURN VALUE +------------ +The _tep_load_plugins()_ function returns a list of successfully loaded plugins, +or NULL in case no plugins are loaded. + +EXAMPLE +------- +[source,c] +-- +#include +... +struct tep_handle *tep = tep_alloc(); +... +struct tep_plugin_list *plugins = tep_load_plugins(tep); +if (plugins == NULL) { + /* no plugins are loaded */ +} +... +tep_unload_plugins(plugins, tep); +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +_libtraceevent(3)_, _trace-cmd(1)_, _tep_set_flag(3)_ + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* , author of *libtraceevent*. +*Tzvetomir Stoyanov* , author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git -- cgit v1.2.3-59-g8ed1b From 058bd857845a9675cfaf4bc2ca831ec7953b58f1 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 12 Sep 2019 10:57:18 +0200 Subject: tools: Add missing stdio.h include to asm/bug.h header We have a direct fprintf() call in the header, so we need stdio.h include, otherwise it could fail compilation if there's no prior stdio.h include directive. Signed-off-by: Jiri Olsa Link: http://lkml.kernel.org/n/tip-8hvjgh24olfsa4non0a3ohnq@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/asm/bug.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/include/asm/bug.h b/tools/include/asm/bug.h index bbd75ac8b202..550223f0a6e6 100644 --- a/tools/include/asm/bug.h +++ b/tools/include/asm/bug.h @@ -3,6 +3,7 @@ #define _TOOLS_ASM_BUG_H #include +#include #define __WARN_printf(arg...) do { fprintf(stderr, arg); } while (0) -- cgit v1.2.3-59-g8ed1b From a583053299c1e66e6202b494cbc3acd93cedc4cc Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 27 Jul 2019 20:30:53 +0200 Subject: perf tools: Rename 'struct perf_mmap' to 'struct mmap' Rename 'struct perf_evlist' to 'struct evlist', so we don't have a name clash when we add 'struct perf_mmap' to libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-4-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-record.c | 34 +++++++++--------- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c | 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/util/auxtrace.c | 6 ++-- tools/perf/util/auxtrace.h | 8 ++--- tools/perf/util/evlist.c | 14 ++++---- tools/perf/util/evlist.h | 4 +-- tools/perf/util/mmap.c | 54 ++++++++++++++-------------- tools/perf/util/mmap.h | 32 ++++++++--------- tools/perf/util/python.c | 6 ++-- 22 files changed, 93 insertions(+), 93 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index 0a4570b340fa..c83abb1ed0ff 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -65,7 +65,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe union perf_event *event; u64 test_tsc, comm1_tsc, comm2_tsc; u64 test_time, comm1_time = 0, comm2_time = 0; - struct perf_mmap *md; + struct mmap *md; threads = thread_map__new(-1, getpid(), UINT_MAX); CHECK_NOT_NULL__(threads); diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index c4b22e1b0a40..7354b77e9137 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -750,7 +750,7 @@ static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx, { struct evlist *evlist = kvm->evlist; union perf_event *event; - struct perf_mmap *md; + struct mmap *md; u64 timestamp; s64 n = 0; int err; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 1e1f97139f16..1528fb686f96 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -119,7 +119,7 @@ static bool switch_output_time(struct record *rec) trigger_is_ready(&switch_output_trigger); } -static int record__write(struct record *rec, struct perf_mmap *map __maybe_unused, +static int record__write(struct record *rec, struct mmap *map __maybe_unused, void *bf, size_t size) { struct perf_data_file *file = &rec->session->data->file; @@ -168,7 +168,7 @@ static int record__aio_write(struct aiocb *cblock, int trace_fd, return rc; } -static int record__aio_complete(struct perf_mmap *md, struct aiocb *cblock) +static int record__aio_complete(struct mmap *md, struct aiocb *cblock) { void *rem_buf; off_t rem_off; @@ -214,7 +214,7 @@ static int record__aio_complete(struct perf_mmap *md, struct aiocb *cblock) return rc; } -static int record__aio_sync(struct perf_mmap *md, bool sync_all) +static int record__aio_sync(struct mmap *md, bool sync_all) { struct aiocb **aiocb = md->aio.aiocb; struct aiocb *cblocks = md->aio.cblocks; @@ -255,7 +255,7 @@ struct record_aio { size_t size; }; -static int record__aio_pushfn(struct perf_mmap *map, void *to, void *buf, size_t size) +static int record__aio_pushfn(struct mmap *map, void *to, void *buf, size_t size) { struct record_aio *aio = to; @@ -300,7 +300,7 @@ static int record__aio_pushfn(struct perf_mmap *map, void *to, void *buf, size_t return size; } -static int record__aio_push(struct record *rec, struct perf_mmap *map, off_t *off) +static int record__aio_push(struct record *rec, struct mmap *map, off_t *off) { int ret, idx; int trace_fd = rec->session->data->file.fd; @@ -351,13 +351,13 @@ static void record__aio_mmap_read_sync(struct record *rec) { int i; struct evlist *evlist = rec->evlist; - struct perf_mmap *maps = evlist->mmap; + struct mmap *maps = evlist->mmap; if (!record__aio_enabled(rec)) return; for (i = 0; i < evlist->nr_mmaps; i++) { - struct perf_mmap *map = &maps[i]; + struct mmap *map = &maps[i]; if (map->base) record__aio_sync(map, true); @@ -387,7 +387,7 @@ static int record__aio_parse(const struct option *opt, #else /* HAVE_AIO_SUPPORT */ static int nr_cblocks_max = 0; -static int record__aio_push(struct record *rec __maybe_unused, struct perf_mmap *map __maybe_unused, +static int record__aio_push(struct record *rec __maybe_unused, struct mmap *map __maybe_unused, off_t *off __maybe_unused) { return -1; @@ -482,7 +482,7 @@ static int process_synthesized_event(struct perf_tool *tool, return record__write(rec, NULL, event, event->header.size); } -static int record__pushfn(struct perf_mmap *map, void *to, void *bf, size_t size) +static int record__pushfn(struct mmap *map, void *to, void *bf, size_t size) { struct record *rec = to; @@ -527,7 +527,7 @@ static void record__sig_exit(void) #ifdef HAVE_AUXTRACE_SUPPORT static int record__process_auxtrace(struct perf_tool *tool, - struct perf_mmap *map, + struct mmap *map, union perf_event *event, void *data1, size_t len1, void *data2, size_t len2) { @@ -565,7 +565,7 @@ static int record__process_auxtrace(struct perf_tool *tool, } static int record__auxtrace_mmap_read(struct record *rec, - struct perf_mmap *map) + struct mmap *map) { int ret; @@ -581,7 +581,7 @@ static int record__auxtrace_mmap_read(struct record *rec, } static int record__auxtrace_mmap_read_snapshot(struct record *rec, - struct perf_mmap *map) + struct mmap *map) { int ret; @@ -603,7 +603,7 @@ static int record__auxtrace_read_snapshot_all(struct record *rec) int rc = 0; for (i = 0; i < rec->evlist->nr_mmaps; i++) { - struct perf_mmap *map = &rec->evlist->mmap[i]; + struct mmap *map = &rec->evlist->mmap[i]; if (!map->auxtrace_mmap.base) continue; @@ -668,7 +668,7 @@ static int record__auxtrace_init(struct record *rec) static inline int record__auxtrace_mmap_read(struct record *rec __maybe_unused, - struct perf_mmap *map __maybe_unused) + struct mmap *map __maybe_unused) { return 0; } @@ -901,7 +901,7 @@ static struct perf_event_header finished_round_event = { .type = PERF_RECORD_FINISHED_ROUND, }; -static void record__adjust_affinity(struct record *rec, struct perf_mmap *map) +static void record__adjust_affinity(struct record *rec, struct mmap *map) { if (rec->opts.affinity != PERF_AFFINITY_SYS && !CPU_EQUAL(&rec->affinity_mask, &map->affinity_mask)) { @@ -948,7 +948,7 @@ static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist, u64 bytes_written = rec->bytes_written; int i; int rc = 0; - struct perf_mmap *maps; + struct mmap *maps; int trace_fd = rec->data.file.fd; off_t off = 0; @@ -967,7 +967,7 @@ static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist, for (i = 0; i < evlist->nr_mmaps; i++) { u64 flush = 0; - struct perf_mmap *map = &maps[i]; + struct mmap *map = &maps[i]; if (map->base) { record__adjust_affinity(rec, map); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 8da3c939e6b0..834a927107c4 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -863,7 +863,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx) { struct record_opts *opts = &top->record_opts; struct evlist *evlist = top->evlist; - struct perf_mmap *md; + struct mmap *md; union perf_event *event; md = opts->overwrite ? &evlist->overwrite_mmap[idx] : &evlist->mmap[idx]; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index a292658b4232..2f853870d68d 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3444,7 +3444,7 @@ again: for (i = 0; i < evlist->nr_mmaps; i++) { union perf_event *event; - struct perf_mmap *md; + struct mmap *md; md = &evlist->mmap[i]; if (perf_mmap__read_init(md) < 0) diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index a637a4a90760..0a046096e6f4 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -33,7 +33,7 @@ static int count_samples(struct evlist *evlist, int *sample_count, int i; for (i = 0; i < evlist->nr_mmaps; i++) { - struct perf_mmap *map = &evlist->overwrite_mmap[i]; + struct mmap *map = &evlist->overwrite_mmap[i]; union perf_event *event; perf_mmap__read_init(map); diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index fc102e4f403e..cf9776aceb82 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -180,7 +180,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void), for (i = 0; i < evlist->nr_mmaps; i++) { union perf_event *event; - struct perf_mmap *md; + struct mmap *md; md = &evlist->mmap[i]; if (perf_mmap__read_init(md) < 0) diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index fd02c1f1d976..df96cbb9ffe5 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -419,7 +419,7 @@ static int process_events(struct machine *machine, struct evlist *evlist, struct state *state) { union perf_event *event; - struct perf_mmap *md; + struct mmap *md; int i, ret; for (i = 0; i < evlist->nr_mmaps; i++) { diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index df0fd5a44e04..67a87f507bbd 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -31,7 +31,7 @@ static int find_comm(struct evlist *evlist, const char *comm) { union perf_event *event; - struct perf_mmap *md; + struct mmap *md; int i, found; found = 0; diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 042757629e90..accca3d78fa3 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -42,7 +42,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse expected_nr_events[nsyscalls], i, j; struct evsel *evsels[nsyscalls], *evsel; char sbuf[STRERR_BUFSIZE]; - struct perf_mmap *md; + struct mmap *md; threads = thread_map__new(-1, getpid(), UINT_MAX); if (threads == NULL) { diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index b71167b43dda..e5ef74d4e925 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -88,7 +88,7 @@ int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest for (i = 0; i < evlist->nr_mmaps; i++) { union perf_event *event; - struct perf_mmap *md; + struct mmap *md; md = &evlist->mmap[i]; if (perf_mmap__read_init(md) < 0) diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index e1b42292cf7f..49d2d4c5956d 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -166,7 +166,7 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus for (i = 0; i < evlist->nr_mmaps; i++) { union perf_event *event; - struct perf_mmap *md; + struct mmap *md; md = &evlist->mmap[i]; if (perf_mmap__read_init(md) < 0) diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 97694a040986..7abe0b6aabb7 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -42,7 +42,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) }; struct perf_cpu_map *cpus; struct perf_thread_map *threads; - struct perf_mmap *md; + struct mmap *md; attr.sample_freq = 500; diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 3fb1ff7b8a2f..e7888ddd69a3 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -263,7 +263,7 @@ static int process_events(struct evlist *evlist, unsigned pos, cnt = 0; LIST_HEAD(events); struct event_node *events_array, *node; - struct perf_mmap *md; + struct mmap *md; int i, ret; for (i = 0; i < evlist->nr_mmaps; i++) { diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 088c7708b03a..cff99707cc9d 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -51,7 +51,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused char sbuf[STRERR_BUFSIZE]; struct perf_cpu_map *cpus; struct perf_thread_map *threads; - struct perf_mmap *md; + struct mmap *md; signal(SIGCHLD, sig_handler); diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 0e8c89cf7cad..1d22ffd972ac 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -1228,7 +1228,7 @@ int perf_event__process_auxtrace_error(struct perf_session *session, return 0; } -static int __auxtrace_mmap__read(struct perf_mmap *map, +static int __auxtrace_mmap__read(struct mmap *map, struct auxtrace_record *itr, struct perf_tool *tool, process_auxtrace_t fn, bool snapshot, size_t snapshot_size) @@ -1339,13 +1339,13 @@ static int __auxtrace_mmap__read(struct perf_mmap *map, return 1; } -int auxtrace_mmap__read(struct perf_mmap *map, struct auxtrace_record *itr, +int auxtrace_mmap__read(struct mmap *map, struct auxtrace_record *itr, struct perf_tool *tool, process_auxtrace_t fn) { return __auxtrace_mmap__read(map, itr, tool, fn, false, 0); } -int auxtrace_mmap__read_snapshot(struct perf_mmap *map, +int auxtrace_mmap__read_snapshot(struct mmap *map, struct auxtrace_record *itr, struct perf_tool *tool, process_auxtrace_t fn, size_t snapshot_size) diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index b110aec1da4d..f201f36bc35f 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -22,7 +22,7 @@ union perf_event; struct perf_session; struct evlist; struct perf_tool; -struct perf_mmap; +struct mmap; struct perf_sample; struct option; struct record_opts; @@ -445,14 +445,14 @@ void auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp, bool per_cpu); typedef int (*process_auxtrace_t)(struct perf_tool *tool, - struct perf_mmap *map, + struct mmap *map, union perf_event *event, void *data1, size_t len1, void *data2, size_t len2); -int auxtrace_mmap__read(struct perf_mmap *map, struct auxtrace_record *itr, +int auxtrace_mmap__read(struct mmap *map, struct auxtrace_record *itr, struct perf_tool *tool, process_auxtrace_t fn); -int auxtrace_mmap__read_snapshot(struct perf_mmap *map, +int auxtrace_mmap__read_snapshot(struct mmap *map, struct auxtrace_record *itr, struct perf_tool *tool, process_auxtrace_t fn, size_t snapshot_size); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index ea9517d506d8..ceab9fb7f7f9 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -423,7 +423,7 @@ int perf_evlist__alloc_pollfd(struct evlist *evlist) } static int __perf_evlist__add_pollfd(struct evlist *evlist, int fd, - struct perf_mmap *map, short revent) + struct mmap *map, short revent) { int pos = fdarray__add(&evlist->pollfd, fd, revent | POLLERR | POLLHUP); /* @@ -447,7 +447,7 @@ int perf_evlist__add_pollfd(struct evlist *evlist, int fd) static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd, void *arg __maybe_unused) { - struct perf_mmap *map = fda->priv[fd].ptr; + struct mmap *map = fda->priv[fd].ptr; if (map) perf_mmap__put(map); @@ -693,16 +693,16 @@ void perf_evlist__munmap(struct evlist *evlist) zfree(&evlist->overwrite_mmap); } -static struct perf_mmap *perf_evlist__alloc_mmap(struct evlist *evlist, +static struct mmap *perf_evlist__alloc_mmap(struct evlist *evlist, bool overwrite) { int i; - struct perf_mmap *map; + struct mmap *map; evlist->nr_mmaps = perf_cpu_map__nr(evlist->core.cpus); if (perf_cpu_map__empty(evlist->core.cpus)) evlist->nr_mmaps = perf_thread_map__nr(evlist->core.threads); - map = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap)); + map = zalloc(evlist->nr_mmaps * sizeof(struct mmap)); if (!map) return NULL; @@ -741,7 +741,7 @@ static int perf_evlist__mmap_per_evsel(struct evlist *evlist, int idx, int evlist_cpu = cpu_map__cpu(evlist->core.cpus, cpu_idx); evlist__for_each_entry(evlist, evsel) { - struct perf_mmap *maps = evlist->mmap; + struct mmap *maps = evlist->mmap; int *output = _output; int fd; int cpu; @@ -1847,7 +1847,7 @@ static void *perf_evlist__poll_thread(void *arg) perf_evlist__poll(evlist, 1000); for (i = 0; i < evlist->nr_mmaps; i++) { - struct perf_mmap *map = &evlist->mmap[i]; + struct mmap *map = &evlist->mmap[i]; union perf_event *event; if (perf_mmap__read_init(map)) diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index a55f0f2546e5..129786361572 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -39,8 +39,8 @@ struct evlist { pid_t pid; } workload; struct fdarray pollfd; - struct perf_mmap *mmap; - struct perf_mmap *overwrite_mmap; + struct mmap *mmap; + struct mmap *overwrite_mmap; struct evsel *selected; struct events_stats stats; struct perf_env *env; diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 33c5b5495482..f3b7c8b0fa90 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -22,13 +22,13 @@ #include "../perf.h" #include "util.h" /* page_size */ -size_t perf_mmap__mmap_len(struct perf_mmap *map) +size_t perf_mmap__mmap_len(struct mmap *map) { return map->mask + 1 + page_size; } /* When check_messup is true, 'end' must points to a good entry */ -static union perf_event *perf_mmap__read(struct perf_mmap *map, +static union perf_event *perf_mmap__read(struct mmap *map, u64 *startp, u64 end) { unsigned char *data = map->base + page_size; @@ -82,7 +82,7 @@ static union perf_event *perf_mmap__read(struct perf_mmap *map, * } * perf_mmap__read_done() */ -union perf_event *perf_mmap__read_event(struct perf_mmap *map) +union perf_event *perf_mmap__read_event(struct mmap *map) { union perf_event *event; @@ -104,17 +104,17 @@ union perf_event *perf_mmap__read_event(struct perf_mmap *map) return event; } -static bool perf_mmap__empty(struct perf_mmap *map) +static bool perf_mmap__empty(struct mmap *map) { return perf_mmap__read_head(map) == map->prev && !map->auxtrace_mmap.base; } -void perf_mmap__get(struct perf_mmap *map) +void perf_mmap__get(struct mmap *map) { refcount_inc(&map->refcnt); } -void perf_mmap__put(struct perf_mmap *map) +void perf_mmap__put(struct mmap *map) { BUG_ON(map->base && refcount_read(&map->refcnt) == 0); @@ -122,7 +122,7 @@ void perf_mmap__put(struct perf_mmap *map) perf_mmap__munmap(map); } -void perf_mmap__consume(struct perf_mmap *map) +void perf_mmap__consume(struct mmap *map) { if (!map->overwrite) { u64 old = map->prev; @@ -161,13 +161,13 @@ void __weak auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp __mayb } #ifdef HAVE_AIO_SUPPORT -static int perf_mmap__aio_enabled(struct perf_mmap *map) +static int perf_mmap__aio_enabled(struct mmap *map) { return map->aio.nr_cblocks > 0; } #ifdef HAVE_LIBNUMA_SUPPORT -static int perf_mmap__aio_alloc(struct perf_mmap *map, int idx) +static int perf_mmap__aio_alloc(struct mmap *map, int idx) { map->aio.data[idx] = mmap(NULL, perf_mmap__mmap_len(map), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); @@ -179,7 +179,7 @@ static int perf_mmap__aio_alloc(struct perf_mmap *map, int idx) return 0; } -static void perf_mmap__aio_free(struct perf_mmap *map, int idx) +static void perf_mmap__aio_free(struct mmap *map, int idx) { if (map->aio.data[idx]) { munmap(map->aio.data[idx], perf_mmap__mmap_len(map)); @@ -187,7 +187,7 @@ static void perf_mmap__aio_free(struct perf_mmap *map, int idx) } } -static int perf_mmap__aio_bind(struct perf_mmap *map, int idx, int cpu, int affinity) +static int perf_mmap__aio_bind(struct mmap *map, int idx, int cpu, int affinity) { void *data; size_t mmap_len; @@ -207,7 +207,7 @@ static int perf_mmap__aio_bind(struct perf_mmap *map, int idx, int cpu, int affi return 0; } #else /* !HAVE_LIBNUMA_SUPPORT */ -static int perf_mmap__aio_alloc(struct perf_mmap *map, int idx) +static int perf_mmap__aio_alloc(struct mmap *map, int idx) { map->aio.data[idx] = malloc(perf_mmap__mmap_len(map)); if (map->aio.data[idx] == NULL) @@ -216,19 +216,19 @@ static int perf_mmap__aio_alloc(struct perf_mmap *map, int idx) return 0; } -static void perf_mmap__aio_free(struct perf_mmap *map, int idx) +static void perf_mmap__aio_free(struct mmap *map, int idx) { zfree(&(map->aio.data[idx])); } -static int perf_mmap__aio_bind(struct perf_mmap *map __maybe_unused, int idx __maybe_unused, +static int perf_mmap__aio_bind(struct mmap *map __maybe_unused, int idx __maybe_unused, int cpu __maybe_unused, int affinity __maybe_unused) { return 0; } #endif -static int perf_mmap__aio_mmap(struct perf_mmap *map, struct mmap_params *mp) +static int perf_mmap__aio_mmap(struct mmap *map, struct mmap_params *mp) { int delta_max, i, prio, ret; @@ -282,7 +282,7 @@ static int perf_mmap__aio_mmap(struct perf_mmap *map, struct mmap_params *mp) return 0; } -static void perf_mmap__aio_munmap(struct perf_mmap *map) +static void perf_mmap__aio_munmap(struct mmap *map) { int i; @@ -294,23 +294,23 @@ static void perf_mmap__aio_munmap(struct perf_mmap *map) zfree(&map->aio.aiocb); } #else /* !HAVE_AIO_SUPPORT */ -static int perf_mmap__aio_enabled(struct perf_mmap *map __maybe_unused) +static int perf_mmap__aio_enabled(struct mmap *map __maybe_unused) { return 0; } -static int perf_mmap__aio_mmap(struct perf_mmap *map __maybe_unused, +static int perf_mmap__aio_mmap(struct mmap *map __maybe_unused, struct mmap_params *mp __maybe_unused) { return 0; } -static void perf_mmap__aio_munmap(struct perf_mmap *map __maybe_unused) +static void perf_mmap__aio_munmap(struct mmap *map __maybe_unused) { } #endif -void perf_mmap__munmap(struct perf_mmap *map) +void perf_mmap__munmap(struct mmap *map) { perf_mmap__aio_munmap(map); if (map->data != NULL) { @@ -343,7 +343,7 @@ static void build_node_mask(int node, cpu_set_t *mask) } } -static void perf_mmap__setup_affinity_mask(struct perf_mmap *map, struct mmap_params *mp) +static void perf_mmap__setup_affinity_mask(struct mmap *map, struct mmap_params *mp) { CPU_ZERO(&map->affinity_mask); if (mp->affinity == PERF_AFFINITY_NODE && cpu__max_node() > 1) @@ -352,7 +352,7 @@ static void perf_mmap__setup_affinity_mask(struct perf_mmap *map, struct mmap_pa CPU_SET(map->cpu, &map->affinity_mask); } -int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd, int cpu) +int perf_mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu) { /* * The last one will be done at perf_mmap__consume(), so that we @@ -440,7 +440,7 @@ static int overwrite_rb_find_range(void *buf, int mask, u64 *start, u64 *end) /* * Report the start and end of the available data in ringbuffer */ -static int __perf_mmap__read_init(struct perf_mmap *md) +static int __perf_mmap__read_init(struct mmap *md) { u64 head = perf_mmap__read_head(md); u64 old = md->prev; @@ -474,7 +474,7 @@ static int __perf_mmap__read_init(struct perf_mmap *md) return 0; } -int perf_mmap__read_init(struct perf_mmap *map) +int perf_mmap__read_init(struct mmap *map) { /* * Check if event was unmapped due to a POLLHUP/POLLERR. @@ -485,8 +485,8 @@ int perf_mmap__read_init(struct perf_mmap *map) return __perf_mmap__read_init(map); } -int perf_mmap__push(struct perf_mmap *md, void *to, - int push(struct perf_mmap *map, void *to, void *buf, size_t size)) +int perf_mmap__push(struct mmap *md, void *to, + int push(struct mmap *map, void *to, void *buf, size_t size)) { u64 head = perf_mmap__read_head(md); unsigned char *data = md->base + page_size; @@ -532,7 +532,7 @@ out: * The last perf_mmap__read() will set tail to map->prev. * Need to correct the map->prev to head which is the end of next read. */ -void perf_mmap__read_done(struct perf_mmap *map) +void perf_mmap__read_done(struct mmap *map) { /* * Check if event was unmapped due to a POLLHUP/POLLERR. diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index 3857a49e8f96..01524608a984 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -15,11 +15,11 @@ struct aiocb; /** - * struct perf_mmap - perf's ring buffer mmap details + * struct mmap - perf's ring buffer mmap details * * @refcnt - e.g. code using PERF_EVENT_IOC_SET_OUTPUT to share this */ -struct perf_mmap { +struct mmap { void *base; int mask; int fd; @@ -78,33 +78,33 @@ struct mmap_params { struct auxtrace_mmap_params auxtrace_mp; }; -int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd, int cpu); -void perf_mmap__munmap(struct perf_mmap *map); +int perf_mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu); +void perf_mmap__munmap(struct mmap *map); -void perf_mmap__get(struct perf_mmap *map); -void perf_mmap__put(struct perf_mmap *map); +void perf_mmap__get(struct mmap *map); +void perf_mmap__put(struct mmap *map); -void perf_mmap__consume(struct perf_mmap *map); +void perf_mmap__consume(struct mmap *map); -static inline u64 perf_mmap__read_head(struct perf_mmap *mm) +static inline u64 perf_mmap__read_head(struct mmap *mm) { return ring_buffer_read_head(mm->base); } -static inline void perf_mmap__write_tail(struct perf_mmap *md, u64 tail) +static inline void perf_mmap__write_tail(struct mmap *md, u64 tail) { ring_buffer_write_tail(md->base, tail); } -union perf_event *perf_mmap__read_forward(struct perf_mmap *map); +union perf_event *perf_mmap__read_forward(struct mmap *map); -union perf_event *perf_mmap__read_event(struct perf_mmap *map); +union perf_event *perf_mmap__read_event(struct mmap *map); -int perf_mmap__push(struct perf_mmap *md, void *to, - int push(struct perf_mmap *map, void *to, void *buf, size_t size)); +int perf_mmap__push(struct mmap *md, void *to, + int push(struct mmap *map, void *to, void *buf, size_t size)); -size_t perf_mmap__mmap_len(struct perf_mmap *map); +size_t perf_mmap__mmap_len(struct mmap *map); -int perf_mmap__read_init(struct perf_mmap *md); -void perf_mmap__read_done(struct perf_mmap *map); +int perf_mmap__read_init(struct mmap *md); +void perf_mmap__read_done(struct mmap *map); #endif /*__PERF_MMAP_H */ diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 0ba19dd75510..1e1247cffea8 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -984,12 +984,12 @@ static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist, return Py_BuildValue("i", evlist->core.nr_entries); } -static struct perf_mmap *get_md(struct evlist *evlist, int cpu) +static struct mmap *get_md(struct evlist *evlist, int cpu) { int i; for (i = 0; i < evlist->nr_mmaps; i++) { - struct perf_mmap *md = &evlist->mmap[i]; + struct mmap *md = &evlist->mmap[i]; if (md->cpu == cpu) return md; @@ -1005,7 +1005,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, union perf_event *event; int sample_id_all = 1, cpu; static char *kwlist[] = { "cpu", "sample_id_all", NULL }; - struct perf_mmap *md; + struct mmap *md; int err; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist, -- cgit v1.2.3-59-g8ed1b From 9521b5f2d9d3e3fd6092fb9d7b00c914e7fa7d33 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 28 Jul 2019 12:45:35 +0200 Subject: perf tools: Rename perf_evlist__mmap() to evlist__mmap() Rename perf_evlist__mmap() to evlist__mmap(), so we don't have a name clash when we add perf_evlist__mmap() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-5-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-record.c | 6 +++--- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/backward-ring-buffer.c | 4 ++-- tools/perf/tests/bpf.c | 4 ++-- tools/perf/tests/code-reading.c | 4 ++-- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c | 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 4 ++-- tools/perf/tests/perf-record.c | 4 ++-- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 4 ++-- tools/perf/tests/task-exit.c | 2 +- tools/perf/util/evlist.c | 30 ++++++++++++++-------------- tools/perf/util/evlist.h | 8 ++++---- tools/perf/util/python.c | 2 +- 18 files changed, 43 insertions(+), 43 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index c83abb1ed0ff..42ae47525a76 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -90,7 +90,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe CHECK__(evlist__open(evlist)); - CHECK__(perf_evlist__mmap(evlist, UINT_MAX)); + CHECK__(evlist__mmap(evlist, UINT_MAX)); pc = evlist->mmap[0].base; ret = perf_read_tsc_conversion(pc, &tc); diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 7354b77e9137..72debb7bd20d 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1060,7 +1060,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm) goto out; } - if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages) < 0) { + if (evlist__mmap(evlist, kvm->opts.mmap_pages) < 0) { ui__error("Failed to mmap the events: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); evlist__close(evlist); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 1528fb686f96..093d9ab5633e 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -439,7 +439,7 @@ static int record__mmap_flush_parse(const struct option *opt, if (!opts->mmap_flush) opts->mmap_flush = MMAP_FLUSH_DEFAULT; - flush_max = perf_evlist__mmap_size(opts->mmap_pages); + flush_max = evlist__mmap_size(opts->mmap_pages); flush_max /= 4; if (opts->mmap_flush > flush_max) opts->mmap_flush = flush_max; @@ -707,7 +707,7 @@ static int record__mmap_evlist(struct record *rec, if (opts->affinity != PERF_AFFINITY_SYS) cpu__setup_cpunode_map(); - if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, + if (evlist__mmap_ex(evlist, opts->mmap_pages, opts->auxtrace_mmap_pages, opts->auxtrace_snapshot_mode, opts->nr_cblocks, opts->affinity, @@ -1980,7 +1980,7 @@ out_free: static void switch_output_size_warn(struct record *rec) { - u64 wakeup_size = perf_evlist__mmap_size(rec->opts.mmap_pages); + u64 wakeup_size = evlist__mmap_size(rec->opts.mmap_pages); struct switch_output *s = &rec->switch_output; wakeup_size /= 2; diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 834a927107c4..771b3ff47dc3 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1042,7 +1042,7 @@ try_again: } } - if (perf_evlist__mmap(evlist, opts->mmap_pages) < 0) { + if (evlist__mmap(evlist, opts->mmap_pages) < 0) { ui__error("Failed to mmap with %d (%s)\n", errno, str_error_r(errno, msg, sizeof(msg))); goto out_err; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 2f853870d68d..ff989351567d 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3409,7 +3409,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (trace->dump.map) bpf_map__fprintf(trace->dump.map, trace->output); - err = perf_evlist__mmap(evlist, trace->opts.mmap_pages); + err = evlist__mmap(evlist, trace->opts.mmap_pages); if (err < 0) goto out_error_mmap; diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 0a046096e6f4..f1eb7e9c1d7d 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -63,9 +63,9 @@ static int do_test(struct evlist *evlist, int mmap_pages, int err; char sbuf[STRERR_BUFSIZE]; - err = perf_evlist__mmap(evlist, mmap_pages); + err = evlist__mmap(evlist, mmap_pages); if (err < 0) { - pr_debug("perf_evlist__mmap: %s\n", + pr_debug("evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); return TEST_FAIL; } diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index cf9776aceb82..964731915498 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -167,9 +167,9 @@ static int do_test(struct bpf_object *obj, int (*func)(void), goto out_delete_evlist; } - err = perf_evlist__mmap(evlist, opts.mmap_pages); + err = evlist__mmap(evlist, opts.mmap_pages); if (err < 0) { - pr_debug("perf_evlist__mmap: %s\n", + pr_debug("evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; } diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index df96cbb9ffe5..413783b69006 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -685,9 +685,9 @@ static int do_test_code_reading(bool try_kcore) break; } - ret = perf_evlist__mmap(evlist, UINT_MAX); + ret = evlist__mmap(evlist, UINT_MAX); if (ret < 0) { - pr_debug("perf_evlist__mmap failed\n"); + pr_debug("evlist__mmap failed\n"); goto out_put; } diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 67a87f507bbd..8e2ec5f72042 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -104,7 +104,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un goto out_err; } - CHECK__(perf_evlist__mmap(evlist, UINT_MAX)); + CHECK__(evlist__mmap(evlist, UINT_MAX)); /* * First, test that a 'comm' event can be found when the event is diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index accca3d78fa3..4d42e455feb7 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -99,7 +99,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse expected_nr_events[i] = 1 + rand() % 127; } - if (perf_evlist__mmap(evlist, 128) < 0) { + if (evlist__mmap(evlist, 128) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index e5ef74d4e925..5c2576174ae9 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -69,9 +69,9 @@ int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest goto out_delete_evlist; } - err = perf_evlist__mmap(evlist, UINT_MAX); + err = evlist__mmap(evlist, UINT_MAX); if (err < 0) { - pr_debug("perf_evlist__mmap: %s\n", + pr_debug("evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; } diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 49d2d4c5956d..669fd88e7f30 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -143,9 +143,9 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus * fds in the same CPU to be injected in the same mmap ring buffer * (using ioctl(PERF_EVENT_IOC_SET_OUTPUT)). */ - err = perf_evlist__mmap(evlist, opts.mmap_pages); + err = evlist__mmap(evlist, opts.mmap_pages); if (err < 0) { - pr_debug("perf_evlist__mmap: %s\n", + pr_debug("evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; } diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 7abe0b6aabb7..fbff60815be8 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -82,7 +82,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) goto out_delete_evlist; } - err = perf_evlist__mmap(evlist, 128); + err = evlist__mmap(evlist, 128); if (err < 0) { pr_debug("failed to mmap event: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index e7888ddd69a3..c92e287e0f53 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -460,9 +460,9 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ goto out; } - err = perf_evlist__mmap(evlist, UINT_MAX); + err = evlist__mmap(evlist, UINT_MAX); if (err) { - pr_debug("perf_evlist__mmap failed!\n"); + pr_debug("evlist__mmap failed!\n"); goto out_err; } diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index cff99707cc9d..718838b5e724 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -106,7 +106,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused goto out_delete_evlist; } - if (perf_evlist__mmap(evlist, 128) < 0) { + if (evlist__mmap(evlist, 128) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index ceab9fb7f7f9..e8afe4fdc1b2 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -732,7 +732,7 @@ perf_evlist__should_poll(struct evlist *evlist __maybe_unused, return true; } -static int perf_evlist__mmap_per_evsel(struct evlist *evlist, int idx, +static int evlist__mmap_per_evsel(struct evlist *evlist, int idx, struct mmap_params *mp, int cpu_idx, int thread, int *_output, int *_output_overwrite) { @@ -810,7 +810,7 @@ static int perf_evlist__mmap_per_evsel(struct evlist *evlist, int idx, return 0; } -static int perf_evlist__mmap_per_cpu(struct evlist *evlist, +static int evlist__mmap_per_cpu(struct evlist *evlist, struct mmap_params *mp) { int cpu, thread; @@ -826,7 +826,7 @@ static int perf_evlist__mmap_per_cpu(struct evlist *evlist, true); for (thread = 0; thread < nr_threads; thread++) { - if (perf_evlist__mmap_per_evsel(evlist, cpu, mp, cpu, + if (evlist__mmap_per_evsel(evlist, cpu, mp, cpu, thread, &output, &output_overwrite)) goto out_unmap; } @@ -839,7 +839,7 @@ out_unmap: return -1; } -static int perf_evlist__mmap_per_thread(struct evlist *evlist, +static int evlist__mmap_per_thread(struct evlist *evlist, struct mmap_params *mp) { int thread; @@ -853,7 +853,7 @@ static int perf_evlist__mmap_per_thread(struct evlist *evlist, auxtrace_mmap_params__set_idx(&mp->auxtrace_mp, evlist, thread, false); - if (perf_evlist__mmap_per_evsel(evlist, thread, mp, 0, thread, + if (evlist__mmap_per_evsel(evlist, thread, mp, 0, thread, &output, &output_overwrite)) goto out_unmap; } @@ -888,7 +888,7 @@ unsigned long perf_event_mlock_kb_in_pages(void) return pages; } -size_t perf_evlist__mmap_size(unsigned long pages) +size_t evlist__mmap_size(unsigned long pages) { if (pages == UINT_MAX) pages = perf_event_mlock_kb_in_pages(); @@ -971,7 +971,7 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, } /** - * perf_evlist__mmap_ex - Create mmaps to receive events. + * evlist__mmap_ex - Create mmaps to receive events. * @evlist: list of events * @pages: map length in pages * @overwrite: overwrite older events? @@ -979,7 +979,7 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, * @auxtrace_overwrite - overwrite older auxtrace data? * * If @overwrite is %false the user needs to signal event consumption using - * perf_mmap__write_tail(). Using perf_evlist__mmap_read() does this + * perf_mmap__write_tail(). Using evlist__mmap_read() does this * automatically. * * Similarly, if @auxtrace_overwrite is %false the user needs to signal data @@ -987,7 +987,7 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, * * Return: %0 on success, negative error code otherwise. */ -int perf_evlist__mmap_ex(struct evlist *evlist, unsigned int pages, +int evlist__mmap_ex(struct evlist *evlist, unsigned int pages, unsigned int auxtrace_pages, bool auxtrace_overwrite, int nr_cblocks, int affinity, int flush, int comp_level) @@ -1011,7 +1011,7 @@ int perf_evlist__mmap_ex(struct evlist *evlist, unsigned int pages, if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) return -ENOMEM; - evlist->mmap_len = perf_evlist__mmap_size(pages); + evlist->mmap_len = evlist__mmap_size(pages); pr_debug("mmap size %zuB\n", evlist->mmap_len); mp.mask = evlist->mmap_len - page_size - 1; @@ -1026,14 +1026,14 @@ int perf_evlist__mmap_ex(struct evlist *evlist, unsigned int pages, } if (perf_cpu_map__empty(cpus)) - return perf_evlist__mmap_per_thread(evlist, &mp); + return evlist__mmap_per_thread(evlist, &mp); - return perf_evlist__mmap_per_cpu(evlist, &mp); + return evlist__mmap_per_cpu(evlist, &mp); } -int perf_evlist__mmap(struct evlist *evlist, unsigned int pages) +int evlist__mmap(struct evlist *evlist, unsigned int pages) { - return perf_evlist__mmap_ex(evlist, pages, 0, false, 0, PERF_AFFINITY_SYS, 1, 0); + return evlist__mmap_ex(evlist, pages, 0, false, 0, PERF_AFFINITY_SYS, 1, 0); } int perf_evlist__create_maps(struct evlist *evlist, struct target *target) @@ -1889,7 +1889,7 @@ int perf_evlist__start_sb_thread(struct evlist *evlist, goto out_delete_evlist; } - if (perf_evlist__mmap(evlist, UINT_MAX)) + if (evlist__mmap(evlist, UINT_MAX)) goto out_delete_evlist; evlist__for_each_entry(evlist, counter) { diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 129786361572..aaf06182c1b8 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -139,7 +139,7 @@ struct perf_sample_id *perf_evlist__id2sid(struct evlist *evlist, u64 id); void perf_evlist__toggle_bkw_mmap(struct evlist *evlist, enum bkw_mmap_state state); -void perf_evlist__mmap_consume(struct evlist *evlist, int idx); +void evlist__mmap_consume(struct evlist *evlist, int idx); int evlist__open(struct evlist *evlist); void evlist__close(struct evlist *evlist); @@ -170,14 +170,14 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, unsigned long perf_event_mlock_kb_in_pages(void); -int perf_evlist__mmap_ex(struct evlist *evlist, unsigned int pages, +int evlist__mmap_ex(struct evlist *evlist, unsigned int pages, unsigned int auxtrace_pages, bool auxtrace_overwrite, int nr_cblocks, int affinity, int flush, int comp_level); -int perf_evlist__mmap(struct evlist *evlist, unsigned int pages); +int evlist__mmap(struct evlist *evlist, unsigned int pages); void perf_evlist__munmap(struct evlist *evlist); -size_t perf_evlist__mmap_size(unsigned long pages); +size_t evlist__mmap_size(unsigned long pages); void evlist__disable(struct evlist *evlist); void evlist__enable(struct evlist *evlist); diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 1e1247cffea8..b102d174b868 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -899,7 +899,7 @@ static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist, &pages, &overwrite)) return NULL; - if (perf_evlist__mmap(evlist, pages) < 0) { + if (evlist__mmap(evlist, pages) < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } -- cgit v1.2.3-59-g8ed1b From db6b7b138506ad537edd12d98f674722a643c150 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 16 Aug 2019 16:19:55 +0200 Subject: perf tools: Rename perf_evlist__munmap() to evlist__munmap() Rename perf_evlist__munmap() to evlist__munmap(), so we don't have a name clash when we add perf_evlist__munmap() in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-6-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/util/evlist.c | 12 ++++++------ tools/perf/util/evlist.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index f1eb7e9c1d7d..3073a68d17b9 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -75,7 +75,7 @@ static int do_test(struct evlist *evlist, int mmap_pages, evlist__disable(evlist); err = count_samples(evlist, sample_count, comm_count); - perf_evlist__munmap(evlist); + evlist__munmap(evlist); return err; } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index e8afe4fdc1b2..888472c7bf9c 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -149,7 +149,7 @@ void evlist__delete(struct evlist *evlist) if (evlist == NULL) return; - perf_evlist__munmap(evlist); + evlist__munmap(evlist); evlist__close(evlist); perf_cpu_map__put(evlist->core.cpus); perf_thread_map__put(evlist->core.threads); @@ -673,7 +673,7 @@ static int perf_evlist__resume(struct evlist *evlist) return perf_evlist__set_paused(evlist, false); } -static void perf_evlist__munmap_nofree(struct evlist *evlist) +static void evlist__munmap_nofree(struct evlist *evlist) { int i; @@ -686,9 +686,9 @@ static void perf_evlist__munmap_nofree(struct evlist *evlist) perf_mmap__munmap(&evlist->overwrite_mmap[i]); } -void perf_evlist__munmap(struct evlist *evlist) +void evlist__munmap(struct evlist *evlist) { - perf_evlist__munmap_nofree(evlist); + evlist__munmap_nofree(evlist); zfree(&evlist->mmap); zfree(&evlist->overwrite_mmap); } @@ -835,7 +835,7 @@ static int evlist__mmap_per_cpu(struct evlist *evlist, return 0; out_unmap: - perf_evlist__munmap_nofree(evlist); + evlist__munmap_nofree(evlist); return -1; } @@ -861,7 +861,7 @@ static int evlist__mmap_per_thread(struct evlist *evlist, return 0; out_unmap: - perf_evlist__munmap_nofree(evlist); + evlist__munmap_nofree(evlist); return -1; } diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index aaf06182c1b8..f07501602353 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -175,7 +175,7 @@ int evlist__mmap_ex(struct evlist *evlist, unsigned int pages, bool auxtrace_overwrite, int nr_cblocks, int affinity, int flush, int comp_level); int evlist__mmap(struct evlist *evlist, unsigned int pages); -void perf_evlist__munmap(struct evlist *evlist); +void evlist__munmap(struct evlist *evlist); size_t evlist__mmap_size(unsigned long pages); -- cgit v1.2.3-59-g8ed1b From d50cf36115a08e668b4a0919a6807c3f9a9e8db8 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 16 Aug 2019 16:21:46 +0200 Subject: perf tools: Rename perf_evlist__alloc_mmap() to evlist__alloc_mmap() Rename perf_evlist__alloc_mmap() to evlist__alloc_mmap(), so we don't have a name clash when we add perf_evlist__alloc_mmap() to libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-7-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 888472c7bf9c..5bde2e5bf0e3 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -693,8 +693,8 @@ void evlist__munmap(struct evlist *evlist) zfree(&evlist->overwrite_mmap); } -static struct mmap *perf_evlist__alloc_mmap(struct evlist *evlist, - bool overwrite) +static struct mmap *evlist__alloc_mmap(struct evlist *evlist, + bool overwrite) { int i; struct mmap *map; @@ -752,7 +752,7 @@ static int evlist__mmap_per_evsel(struct evlist *evlist, int idx, maps = evlist->overwrite_mmap; if (!maps) { - maps = perf_evlist__alloc_mmap(evlist, true); + maps = evlist__alloc_mmap(evlist, true); if (!maps) return -1; evlist->overwrite_mmap = maps; @@ -1004,7 +1004,7 @@ int evlist__mmap_ex(struct evlist *evlist, unsigned int pages, .comp_level = comp_level }; if (!evlist->mmap) - evlist->mmap = perf_evlist__alloc_mmap(evlist, false); + evlist->mmap = evlist__alloc_mmap(evlist, false); if (!evlist->mmap) return -ENOMEM; -- cgit v1.2.3-59-g8ed1b From 470579b0211d370fd3bd7c2f2b2b098f1ca1ae65 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 2 Sep 2019 14:34:52 +0200 Subject: perf tools: Rename perf_evlist__exit() to evlist__exit() Rename perf_evlist__exit() to evlist__exit(), so we don't have a name clash when we add perf_evlist__exit() to libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-8-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 4 ++-- tools/perf/util/evlist.h | 2 +- tools/perf/util/python.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 5bde2e5bf0e3..4c5b7040c02b 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -137,7 +137,7 @@ static void perf_evlist__purge(struct evlist *evlist) evlist->core.nr_entries = 0; } -void perf_evlist__exit(struct evlist *evlist) +void evlist__exit(struct evlist *evlist) { zfree(&evlist->mmap); zfree(&evlist->overwrite_mmap); @@ -156,7 +156,7 @@ void evlist__delete(struct evlist *evlist) evlist->core.cpus = NULL; evlist->core.threads = NULL; perf_evlist__purge(evlist); - perf_evlist__exit(evlist); + evlist__exit(evlist); free(evlist); } diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index f07501602353..b33c5d67410a 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -65,7 +65,7 @@ struct evlist *perf_evlist__new_default(void); struct evlist *perf_evlist__new_dummy(void); void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, struct perf_thread_map *threads); -void perf_evlist__exit(struct evlist *evlist); +void evlist__exit(struct evlist *evlist); void evlist__delete(struct evlist *evlist); void evlist__add(struct evlist *evlist, struct evsel *entry); diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index b102d174b868..60a6b6e8e176 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -884,7 +884,7 @@ static int pyrf_evlist__init(struct pyrf_evlist *pevlist, static void pyrf_evlist__delete(struct pyrf_evlist *pevlist) { - perf_evlist__exit(&pevlist->evlist); + evlist__exit(&pevlist->evlist); Py_TYPE(pevlist)->tp_free((PyObject*)pevlist); } -- cgit v1.2.3-59-g8ed1b From e6b1878d4eea85ab453e4b198cbb26a34614fdc0 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 5 Sep 2019 10:11:37 +0200 Subject: perf tools: Rename perf_evlist__purge() to evlist__purge() Rename (perf_evlist__purge) to evlist__purge(), so we don't have a name clash when we add (perf_evlist__purge) in libperf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-9-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4c5b7040c02b..c96c743cc1d2 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -124,7 +124,7 @@ static void perf_evlist__update_id_pos(struct evlist *evlist) perf_evlist__set_id_pos(evlist); } -static void perf_evlist__purge(struct evlist *evlist) +static void evlist__purge(struct evlist *evlist) { struct evsel *pos, *n; @@ -155,7 +155,7 @@ void evlist__delete(struct evlist *evlist) perf_thread_map__put(evlist->core.threads); evlist->core.cpus = NULL; evlist->core.threads = NULL; - perf_evlist__purge(evlist); + evlist__purge(evlist); evlist__exit(evlist); free(evlist); } -- cgit v1.2.3-59-g8ed1b From d80a5540bccb4a9e7bd49d249056ce4c7d385ff3 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 18 Aug 2019 23:02:58 +0200 Subject: libperf: Link libapi.a in libperf.so Linking libapi.a in libperf.so, because we are about to use some of the API functions in it. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-10-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/Makefile | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/Makefile b/tools/perf/lib/Makefile index e325c0503dc6..54466cc84544 100644 --- a/tools/perf/lib/Makefile +++ b/tools/perf/lib/Makefile @@ -59,7 +59,13 @@ else CFLAGS := -g -Wall endif -INCLUDES = -I$(srctree)/tools/perf/lib/include -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(SRCARCH)/include/ -I$(srctree)/tools/arch/$(SRCARCH)/include/uapi -I$(srctree)/tools/include/uapi +INCLUDES = \ +-I$(srctree)/tools/perf/lib/include \ +-I$(srctree)/tools/lib/ \ +-I$(srctree)/tools/include \ +-I$(srctree)/tools/arch/$(SRCARCH)/include/ \ +-I$(srctree)/tools/arch/$(SRCARCH)/include/uapi \ +-I$(srctree)/tools/include/uapi # Append required CFLAGS override CFLAGS += $(EXTRA_WARNINGS) @@ -88,13 +94,34 @@ LIBPERF_PC := $(OUTPUT)libperf.pc LIBPERF_ALL := $(LIBPERF_A) $(OUTPUT)libperf.so* +LIB_DIR := $(srctree)/tools/lib/api/ + +ifneq ($(OUTPUT),) +ifneq ($(subdir),) + API_PATH=$(OUTPUT)/../lib/api/ +else + API_PATH=$(OUTPUT) +endif +else + API_PATH=$(LIB_DIR) +endif + +LIBAPI = $(API_PATH)libapi.a + +$(LIBAPI): FORCE + $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) $(OUTPUT)libapi.a + +$(LIBAPI)-clean: + $(call QUIET_CLEAN, libapi) + $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null + $(LIBPERF_IN): FORCE $(Q)$(MAKE) $(build)=libperf $(LIBPERF_A): $(LIBPERF_IN) $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIBPERF_IN) -$(LIBPERF_SO): $(LIBPERF_IN) +$(LIBPERF_SO): $(LIBPERF_IN) $(LIBAPI) $(QUIET_LINK)$(CC) --shared -Wl,-soname,libperf.so \ -Wl,--version-script=$(VERSION_SCRIPT) $^ -o $@ @ln -sf $(@F) $(OUTPUT)libperf.so @@ -106,7 +133,7 @@ libs: $(LIBPERF_A) $(LIBPERF_SO) $(LIBPERF_PC) all: fixdep $(Q)$(MAKE) libs -clean: +clean: $(LIBAPI)-clean $(call QUIET_CLEAN, libperf) $(RM) $(LIBPERF_A) \ *.o *~ *.a *.so *.so.$(VERSION) *.so.$(LIBPERF_VERSION) .*.d .*.cmd LIBPERF-CFLAGS $(LIBPERF_PC) $(Q)$(MAKE) -C tests clean -- cgit v1.2.3-59-g8ed1b From e0fcfb086fbbb6233de1062d4b2f05e9afedab3b Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 23 Sep 2019 12:20:38 -0300 Subject: perf evlist: Adopt backwards ring buffer state enum As this isn't used at all in mmap.h but in evlist.h, so to cut down the header dependency tree, move it to where it is used. Also add mmap.h to the places using it but previously getting it indirectly via evlist.h. Add missing pthread.h to evlist.h, as it has a pthread_t struct member and was getting the header via mmap.h. Noticed while processing a Jiri's libperf batch touching mmap.h, where almost everything gets rebuilt because evlist.h is so popular, so cut down't this rebuild the world party. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Song Liu Link: https://lkml.kernel.org/n/tip-he0uljeftl0xfveh3d6vtode@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/s390/util/auxtrace.c | 1 + tools/perf/arch/x86/tests/perf-time-to-tsc.c | 1 + tools/perf/arch/x86/util/intel-bts.c | 1 + tools/perf/arch/x86/util/intel-pt.c | 1 + tools/perf/builtin-kvm.c | 1 + tools/perf/builtin-record.c | 1 + tools/perf/builtin-top.c | 1 + tools/perf/builtin-trace.c | 1 + tools/perf/tests/backward-ring-buffer.c | 1 + tools/perf/tests/bpf.c | 1 + tools/perf/tests/code-reading.c | 1 + tools/perf/tests/hists_link.c | 1 + tools/perf/tests/keep-tracking.c | 1 + tools/perf/tests/mmap-basic.c | 1 + tools/perf/tests/openat-syscall-tp-fields.c | 1 + tools/perf/tests/perf-record.c | 1 + tools/perf/tests/sw-clock.c | 1 + tools/perf/tests/switch-tracking.c | 1 + tools/perf/tests/task-exit.c | 1 + tools/perf/ui/gtk/hists.c | 1 + tools/perf/util/annotate.c | 1 + tools/perf/util/auxtrace.c | 1 + tools/perf/util/evlist.c | 1 + tools/perf/util/evlist.h | 30 +++++++++++++++++++++++++++- tools/perf/util/mmap.h | 28 -------------------------- tools/perf/util/parse-events.c | 1 + 26 files changed, 53 insertions(+), 29 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/s390/util/auxtrace.c b/tools/perf/arch/s390/util/auxtrace.c index b0fb70e38960..0db5c58c98e8 100644 --- a/tools/perf/arch/s390/util/auxtrace.c +++ b/tools/perf/arch/s390/util/auxtrace.c @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index 42ae47525a76..e1dd5f8894ba 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -17,6 +17,7 @@ #include "thread_map.h" #include "record.h" #include "tsc.h" +#include "util/mmap.h" #include "tests/tests.h" #include "arch-tests.h" diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index 090d90e093df..64b409dad6e2 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -15,6 +15,7 @@ #include "../../util/event.h" #include "../../util/evsel.h" #include "../../util/evlist.h" +#include "../../util/mmap.h" #include "../../util/session.h" #include "../../util/pmu.h" #include "../../util/debug.h" diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 3d041b89f018..6c139611d231 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -18,6 +18,7 @@ #include "../../util/evlist.h" #include "../../util/evsel.h" #include "../../util/cpumap.h" +#include "../../util/mmap.h" #include #include "../../util/parse-events.h" #include "../../util/pmu.h" diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 72debb7bd20d..30852848ed9c 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -5,6 +5,7 @@ #include "util/build-id.h" #include "util/evsel.h" #include "util/evlist.h" +#include "util/mmap.h" #include "util/term.h" #include "util/symbol.h" #include "util/thread.h" diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 093d9ab5633e..1bb3d91c6599 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -20,6 +20,7 @@ #include "util/evlist.h" #include "util/evsel.h" #include "util/debug.h" +#include "util/mmap.h" #include "util/target.h" #include "util/session.h" #include "util/tool.h" diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 771b3ff47dc3..e637a08655db 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -30,6 +30,7 @@ #include "util/event.h" #include "util/machine.h" #include "util/map.h" +#include "util/mmap.h" #include "util/session.h" #include "util/symbol.h" #include "util/synthetic-events.h" diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index ff989351567d..c44280358e58 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -31,6 +31,7 @@ #include "util/synthetic-events.h" #include "util/evlist.h" #include "util/evswitch.h" +#include "util/mmap.h" #include #include #include "util/machine.h" diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 3073a68d17b9..c59d3752d48d 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -10,6 +10,7 @@ #include "tests.h" #include "debug.h" #include "parse-events.h" +#include "util/mmap.h" #include #include diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 964731915498..3c8533fdbce5 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -19,6 +19,7 @@ #include "llvm.h" #include "debug.h" #include "parse-events.h" +#include "util/mmap.h" #define NR_ITERS 111 #define PERF_TEST_BPF_PATH "/sys/fs/bpf/perf_test" diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 413783b69006..bc6db3e7a1c5 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -24,6 +24,7 @@ #include "symbol.h" #include "event.h" #include "record.h" +#include "util/mmap.h" #include "util/synthetic-events.h" #include "thread.h" diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index 8be4d0b61e3a..1a3bdc0a2d14 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -8,6 +8,7 @@ #include "machine.h" #include "parse-events.h" #include "hists_common.h" +#include "util/mmap.h" #include #include diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 8e2ec5f72042..c6030fdf7d4c 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -13,6 +13,7 @@ #include "record.h" #include "thread_map.h" #include "tests.h" +#include "util/mmap.h" #define CHECK__(x) { \ while ((x) < 0) { \ diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 4d42e455feb7..3a22dce991ba 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -11,6 +11,7 @@ #include "evsel.h" #include "thread_map.h" #include "tests.h" +#include "util/mmap.h" #include #include #include diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index 5c2576174ae9..e20eaadb1a35 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -11,6 +11,7 @@ #include "record.h" #include "tests.h" #include "debug.h" +#include "util/mmap.h" #include #ifndef O_DIRECTORY diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 669fd88e7f30..ea8bcaa13ea5 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -11,6 +11,7 @@ #include "debug.h" #include "record.h" #include "tests.h" +#include "util/mmap.h" static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp) { diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index fbff60815be8..84519df87f30 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -12,6 +12,7 @@ #include "util/evsel.h" #include "util/evlist.h" #include "util/cpumap.h" +#include "util/mmap.h" #include "util/thread_map.h" #include diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index c92e287e0f53..e5c3f2ee223a 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -16,6 +16,7 @@ #include "thread_map.h" #include "record.h" #include "tests.h" +#include "util/mmap.h" static int spin_sleep(void) { diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 718838b5e724..7fc39af48a76 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -5,6 +5,7 @@ #include "target.h" #include "thread_map.h" #include "tests.h" +#include "util/mmap.h" #include #include diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index 6c2efc10bf5c..ed1a97b2c4b0 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c @@ -8,6 +8,7 @@ #include "../string2.h" #include "gtk.h" #include +#include #include #define MAX_COLUMNS 32 diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index d441cca6a517..69d0a1991b29 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -34,6 +34,7 @@ #include "bpf-event.h" #include "block-range.h" #include "string2.h" +#include "util/mmap.h" #include "arch/common.h" #include #include diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 1d22ffd972ac..4bd92f5bfb5f 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -51,6 +51,7 @@ #include "arm-spe.h" #include "s390-cpumsf.h" #include "util.h" // page_size +#include "util/mmap.h" #include #include diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index c96c743cc1d2..f700dbe043b7 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -10,6 +10,7 @@ #include #include #include "cpumap.h" +#include "util/mmap.h" #include "thread_map.h" #include "target.h" #include "evlist.h" diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index b33c5d67410a..8b9c35efea67 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -11,7 +11,7 @@ #include #include "events_stats.h" #include "evsel.h" -#include "mmap.h" +#include #include #include @@ -20,6 +20,34 @@ struct thread_map; struct perf_cpu_map; struct record_opts; +/* + * State machine of bkw_mmap_state: + * + * .________________(forbid)_____________. + * | V + * NOTREADY --(0)--> RUNNING --(1)--> DATA_PENDING --(2)--> EMPTY + * ^ ^ | ^ | + * | |__(forbid)____/ |___(forbid)___/| + * | | + * \_________________(3)_______________/ + * + * NOTREADY : Backward ring buffers are not ready + * RUNNING : Backward ring buffers are recording + * DATA_PENDING : We are required to collect data from backward ring buffers + * EMPTY : We have collected data from backward ring buffers. + * + * (0): Setup backward ring buffer + * (1): Pause ring buffers for reading + * (2): Read from ring buffers + * (3): Resume ring buffers for recording + */ +enum bkw_mmap_state { + BKW_MMAP_NOTREADY, + BKW_MMAP_RUNNING, + BKW_MMAP_DATA_PENDING, + BKW_MMAP_EMPTY, +}; + #define PERF_EVLIST__HLIST_BITS 8 #define PERF_EVLIST__HLIST_SIZE (1 << PERF_EVLIST__HLIST_BITS) diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index 01524608a984..ab086ede044a 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -45,34 +45,6 @@ struct mmap { int comp_level; }; -/* - * State machine of bkw_mmap_state: - * - * .________________(forbid)_____________. - * | V - * NOTREADY --(0)--> RUNNING --(1)--> DATA_PENDING --(2)--> EMPTY - * ^ ^ | ^ | - * | |__(forbid)____/ |___(forbid)___/| - * | | - * \_________________(3)_______________/ - * - * NOTREADY : Backward ring buffers are not ready - * RUNNING : Backward ring buffers are recording - * DATA_PENDING : We are required to collect data from backward ring buffers - * EMPTY : We have collected data from backward ring buffers. - * - * (0): Setup backward ring buffer - * (1): Pause ring buffers for reading - * (2): Read from ring buffers - * (3): Resume ring buffers for recording - */ -enum bkw_mmap_state { - BKW_MMAP_NOTREADY, - BKW_MMAP_RUNNING, - BKW_MMAP_DATA_PENDING, - BKW_MMAP_EMPTY, -}; - struct mmap_params { int prot, mask, nr_cblocks, affinity, flush, comp_level; struct auxtrace_mmap_params auxtrace_mp; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index a33a1d5059a2..9cf1371c90a3 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -34,6 +34,7 @@ #include "asm/bug.h" #include "util/parse-branch-options.h" #include "metricgroup.h" +#include "util/mmap.h" #define MAX_NAME_LEN 100 -- cgit v1.2.3-59-g8ed1b From 547740f7b357cd91cca1fab5d7bf3a37469f7587 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 27 Jul 2019 22:07:44 +0200 Subject: libperf: Add perf_mmap struct Add the perf_mmap struct to libperf. The definition is added into: include/internal/mmap.h which is not to be included by users, but shared within perf and libperf. Committer notes: Remove unnecessary includes from tools/perf/lib/include/internal/mmap.h, those will be readded as they become necessary, later in the series. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-11-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/arch/x86/util/intel-bts.c | 2 +- tools/perf/arch/x86/util/intel-pt.c | 2 +- tools/perf/builtin-record.c | 14 +++++++------- tools/perf/lib/include/internal/mmap.h | 14 ++++++++++++++ tools/perf/util/mmap.c | 22 +++++++++++----------- tools/perf/util/mmap.h | 7 ++++--- 7 files changed, 39 insertions(+), 24 deletions(-) create mode 100644 tools/perf/lib/include/internal/mmap.h (limited to 'tools') diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index e1dd5f8894ba..bd404db94b3a 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -93,7 +93,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe CHECK__(evlist__mmap(evlist, UINT_MAX)); - pc = evlist->mmap[0].base; + pc = evlist->mmap[0].core.base; ret = perf_read_tsc_conversion(pc, &tc); if (ret) { if (ret == -EOPNOTSUPP) { diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index 64b409dad6e2..130925141369 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -78,7 +78,7 @@ static int intel_bts_info_fill(struct auxtrace_record *itr, if (!session->evlist->nr_mmaps) return -EINVAL; - pc = session->evlist->mmap[0].base; + pc = session->evlist->mmap[0].core.base; if (pc) { err = perf_read_tsc_conversion(pc, &tc); if (err) { diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 6c139611d231..34d7118bf390 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -355,7 +355,7 @@ static int intel_pt_info_fill(struct auxtrace_record *itr, if (!session->evlist->nr_mmaps) return -EINVAL; - pc = session->evlist->mmap[0].base; + pc = session->evlist->mmap[0].core.base; if (pc) { err = perf_read_tsc_conversion(pc, &tc); if (err) { diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 1bb3d91c6599..2520c0212275 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -261,7 +261,7 @@ static int record__aio_pushfn(struct mmap *map, void *to, void *buf, size_t size struct record_aio *aio = to; /* - * map->base data pointed by buf is copied into free map->aio.data[] buffer + * map->core.base data pointed by buf is copied into free map->aio.data[] buffer * to release space in the kernel buffer as fast as possible, calling * perf_mmap__consume() from perf_mmap__push() function. * @@ -360,7 +360,7 @@ static void record__aio_mmap_read_sync(struct record *rec) for (i = 0; i < evlist->nr_mmaps; i++) { struct mmap *map = &maps[i]; - if (map->base) + if (map->core.base) record__aio_sync(map, true); } } @@ -970,7 +970,7 @@ static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist, u64 flush = 0; struct mmap *map = &maps[i]; - if (map->base) { + if (map->core.base) { record__adjust_affinity(rec, map); if (synch) { flush = map->flush; @@ -1198,10 +1198,10 @@ static const struct perf_event_mmap_page * perf_evlist__pick_pc(struct evlist *evlist) { if (evlist) { - if (evlist->mmap && evlist->mmap[0].base) - return evlist->mmap[0].base; - if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].base) - return evlist->overwrite_mmap[0].base; + if (evlist->mmap && evlist->mmap[0].core.base) + return evlist->mmap[0].core.base; + if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].core.base) + return evlist->overwrite_mmap[0].core.base; } return NULL; } diff --git a/tools/perf/lib/include/internal/mmap.h b/tools/perf/lib/include/internal/mmap.h new file mode 100644 index 000000000000..2ef051901f48 --- /dev/null +++ b/tools/perf/lib/include/internal/mmap.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LIBPERF_INTERNAL_MMAP_H +#define __LIBPERF_INTERNAL_MMAP_H + +/** + * struct perf_mmap - perf's ring buffer mmap details + * + * @refcnt - e.g. code using PERF_EVENT_IOC_SET_OUTPUT to share this + */ +struct perf_mmap { + void *base; +}; + +#endif /* __LIBPERF_INTERNAL_MMAP_H */ diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index f3b7c8b0fa90..76190b2edd78 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -31,7 +31,7 @@ size_t perf_mmap__mmap_len(struct mmap *map) static union perf_event *perf_mmap__read(struct mmap *map, u64 *startp, u64 end) { - unsigned char *data = map->base + page_size; + unsigned char *data = map->core.base + page_size; union perf_event *event = NULL; int diff = end - *startp; @@ -116,7 +116,7 @@ void perf_mmap__get(struct mmap *map) void perf_mmap__put(struct mmap *map) { - BUG_ON(map->base && refcount_read(&map->refcnt) == 0); + BUG_ON(map->core.base && refcount_read(&map->refcnt) == 0); if (refcount_dec_and_test(&map->refcnt)) perf_mmap__munmap(map); @@ -317,9 +317,9 @@ void perf_mmap__munmap(struct mmap *map) munmap(map->data, perf_mmap__mmap_len(map)); map->data = NULL; } - if (map->base != NULL) { - munmap(map->base, perf_mmap__mmap_len(map)); - map->base = NULL; + if (map->core.base != NULL) { + munmap(map->core.base, perf_mmap__mmap_len(map)); + map->core.base = NULL; map->fd = -1; refcount_set(&map->refcnt, 0); } @@ -370,12 +370,12 @@ int perf_mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu) refcount_set(&map->refcnt, 2); map->prev = 0; map->mask = mp->mask; - map->base = mmap(NULL, perf_mmap__mmap_len(map), mp->prot, + map->core.base = mmap(NULL, perf_mmap__mmap_len(map), mp->prot, MAP_SHARED, fd, 0); - if (map->base == MAP_FAILED) { + if (map->core.base == MAP_FAILED) { pr_debug2("failed to mmap perf event ring buffer, error %d\n", errno); - map->base = NULL; + map->core.base = NULL; return -1; } map->fd = fd; @@ -399,7 +399,7 @@ int perf_mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu) } if (auxtrace_mmap__mmap(&map->auxtrace_mmap, - &mp->auxtrace_mp, map->base, fd)) + &mp->auxtrace_mp, map->core.base, fd)) return -1; return perf_mmap__aio_mmap(map, mp); @@ -444,7 +444,7 @@ static int __perf_mmap__read_init(struct mmap *md) { u64 head = perf_mmap__read_head(md); u64 old = md->prev; - unsigned char *data = md->base + page_size; + unsigned char *data = md->core.base + page_size; unsigned long size; md->start = md->overwrite ? head : old; @@ -489,7 +489,7 @@ int perf_mmap__push(struct mmap *md, void *to, int push(struct mmap *map, void *to, void *buf, size_t size)) { u64 head = perf_mmap__read_head(md); - unsigned char *data = md->base + page_size; + unsigned char *data = md->core.base + page_size; unsigned long size; void *buf; int rc = 0; diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index ab086ede044a..d2f0ce581e2c 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -1,6 +1,7 @@ #ifndef __PERF_MMAP_H #define __PERF_MMAP_H 1 +#include #include #include #include @@ -20,7 +21,7 @@ struct aiocb; * @refcnt - e.g. code using PERF_EVENT_IOC_SET_OUTPUT to share this */ struct mmap { - void *base; + struct perf_mmap core; int mask; int fd; int cpu; @@ -60,12 +61,12 @@ void perf_mmap__consume(struct mmap *map); static inline u64 perf_mmap__read_head(struct mmap *mm) { - return ring_buffer_read_head(mm->base); + return ring_buffer_read_head(mm->core.base); } static inline void perf_mmap__write_tail(struct mmap *md, u64 tail) { - ring_buffer_write_tail(md->base, tail); + ring_buffer_write_tail(md->core.base, tail); } union perf_event *perf_mmap__read_forward(struct mmap *map); -- cgit v1.2.3-59-g8ed1b From 4fd0cef2c7b6469abfeef1f9bd056265ce369b13 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 27 Jul 2019 22:27:55 +0200 Subject: libperf: Add 'mask' to struct perf_mmap Move 'mask' from tools/perf's mmap to libperf's perf_mmap struct. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-12-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/internal/mmap.h | 1 + tools/perf/util/mmap.c | 24 ++++++++++++------------ tools/perf/util/mmap.h | 1 - 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/internal/mmap.h b/tools/perf/lib/include/internal/mmap.h index 2ef051901f48..1caa1e8ee5c6 100644 --- a/tools/perf/lib/include/internal/mmap.h +++ b/tools/perf/lib/include/internal/mmap.h @@ -9,6 +9,7 @@ */ struct perf_mmap { void *base; + int mask; }; #endif /* __LIBPERF_INTERNAL_MMAP_H */ diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 76190b2edd78..702e8e0b90ea 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -24,7 +24,7 @@ size_t perf_mmap__mmap_len(struct mmap *map) { - return map->mask + 1 + page_size; + return map->core.mask + 1 + page_size; } /* When check_messup is true, 'end' must points to a good entry */ @@ -38,7 +38,7 @@ static union perf_event *perf_mmap__read(struct mmap *map, if (diff >= (int)sizeof(event->header)) { size_t size; - event = (union perf_event *)&data[*startp & map->mask]; + event = (union perf_event *)&data[*startp & map->core.mask]; size = event->header.size; if (size < sizeof(event->header) || diff < (int)size) @@ -48,14 +48,14 @@ static union perf_event *perf_mmap__read(struct mmap *map, * Event straddles the mmap boundary -- header should always * be inside due to u64 alignment of output. */ - if ((*startp & map->mask) + size != ((*startp + size) & map->mask)) { + if ((*startp & map->core.mask) + size != ((*startp + size) & map->core.mask)) { unsigned int offset = *startp; unsigned int len = min(sizeof(*event), size), cpy; void *dst = map->event_copy; do { - cpy = min(map->mask + 1 - (offset & map->mask), len); - memcpy(dst, &data[offset & map->mask], cpy); + cpy = min(map->core.mask + 1 - (offset & map->core.mask), len); + memcpy(dst, &data[offset & map->core.mask], cpy); offset += cpy; dst += cpy; len -= cpy; @@ -369,7 +369,7 @@ int perf_mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu) */ refcount_set(&map->refcnt, 2); map->prev = 0; - map->mask = mp->mask; + map->core.mask = mp->mask; map->core.base = mmap(NULL, perf_mmap__mmap_len(map), mp->prot, MAP_SHARED, fd, 0); if (map->core.base == MAP_FAILED) { @@ -454,7 +454,7 @@ static int __perf_mmap__read_init(struct mmap *md) return -EAGAIN; size = md->end - md->start; - if (size > (unsigned long)(md->mask) + 1) { + if (size > (unsigned long)(md->core.mask) + 1) { if (!md->overwrite) { WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); @@ -467,7 +467,7 @@ static int __perf_mmap__read_init(struct mmap *md) * Backward ring buffer is full. We still have a chance to read * most of data from it. */ - if (overwrite_rb_find_range(data, md->mask, &md->start, &md->end)) + if (overwrite_rb_find_range(data, md->core.mask, &md->start, &md->end)) return -EINVAL; } @@ -500,9 +500,9 @@ int perf_mmap__push(struct mmap *md, void *to, size = md->end - md->start; - if ((md->start & md->mask) + size != (md->end & md->mask)) { - buf = &data[md->start & md->mask]; - size = md->mask + 1 - (md->start & md->mask); + if ((md->start & md->core.mask) + size != (md->end & md->core.mask)) { + buf = &data[md->start & md->core.mask]; + size = md->core.mask + 1 - (md->start & md->core.mask); md->start += size; if (push(md, to, buf, size) < 0) { @@ -511,7 +511,7 @@ int perf_mmap__push(struct mmap *md, void *to, } } - buf = &data[md->start & md->mask]; + buf = &data[md->start & md->core.mask]; size = md->end - md->start; md->start += size; diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index d2f0ce581e2c..370138e395fc 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -22,7 +22,6 @@ struct aiocb; */ struct mmap { struct perf_mmap core; - int mask; int fd; int cpu; refcount_t refcnt; -- cgit v1.2.3-59-g8ed1b From 2cf07b294a604aecd6b583e60724eaa1607f0fbc Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 27 Jul 2019 22:31:17 +0200 Subject: libperf: Add 'fd' to struct perf_mmap Move 'fd' from tools/perf's mmap to libperf's perf_mmap struct. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-13-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/internal/mmap.h | 1 + tools/perf/util/evlist.c | 4 ++-- tools/perf/util/mmap.c | 4 ++-- tools/perf/util/mmap.h | 1 - 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/internal/mmap.h b/tools/perf/lib/include/internal/mmap.h index 1caa1e8ee5c6..892cbd401d8d 100644 --- a/tools/perf/lib/include/internal/mmap.h +++ b/tools/perf/lib/include/internal/mmap.h @@ -10,6 +10,7 @@ struct perf_mmap { void *base; int mask; + int fd; }; #endif /* __LIBPERF_INTERNAL_MMAP_H */ diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index f700dbe043b7..a4e1c19c969f 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -652,7 +652,7 @@ static int perf_evlist__set_paused(struct evlist *evlist, bool value) return 0; for (i = 0; i < evlist->nr_mmaps; i++) { - int fd = evlist->overwrite_mmap[i].fd; + int fd = evlist->overwrite_mmap[i].core.fd; int err; if (fd < 0) @@ -708,7 +708,7 @@ static struct mmap *evlist__alloc_mmap(struct evlist *evlist, return NULL; for (i = 0; i < evlist->nr_mmaps; i++) { - map[i].fd = -1; + map[i].core.fd = -1; map[i].overwrite = overwrite; /* * When the perf_mmap() call is made we grab one refcount, plus diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 702e8e0b90ea..40bf124cb658 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -320,7 +320,7 @@ void perf_mmap__munmap(struct mmap *map) if (map->core.base != NULL) { munmap(map->core.base, perf_mmap__mmap_len(map)); map->core.base = NULL; - map->fd = -1; + map->core.fd = -1; refcount_set(&map->refcnt, 0); } auxtrace_mmap__munmap(&map->auxtrace_mmap); @@ -378,7 +378,7 @@ int perf_mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu) map->core.base = NULL; return -1; } - map->fd = fd; + map->core.fd = fd; map->cpu = cpu; perf_mmap__setup_affinity_mask(map, mp); diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index 370138e395fc..de991194af8d 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -22,7 +22,6 @@ struct aiocb; */ struct mmap { struct perf_mmap core; - int fd; int cpu; refcount_t refcnt; u64 prev; -- cgit v1.2.3-59-g8ed1b From 56a94706cd7233b158ab13e5ac93f5a97ca88941 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 27 Jul 2019 22:33:20 +0200 Subject: libperf: Add 'cpu' to struct perf_mmap Move 'cpu' from tools/perf's mmap to libperf's perf_mmap struct. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-14-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/internal/mmap.h | 1 + tools/perf/util/mmap.c | 8 ++++---- tools/perf/util/mmap.h | 1 - tools/perf/util/python.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/internal/mmap.h b/tools/perf/lib/include/internal/mmap.h index 892cbd401d8d..f7d1809fa34c 100644 --- a/tools/perf/lib/include/internal/mmap.h +++ b/tools/perf/lib/include/internal/mmap.h @@ -11,6 +11,7 @@ struct perf_mmap { void *base; int mask; int fd; + int cpu; }; #endif /* __LIBPERF_INTERNAL_MMAP_H */ diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 40bf124cb658..dc8320891344 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -256,7 +256,7 @@ static int perf_mmap__aio_mmap(struct mmap *map, struct mmap_params *mp) pr_debug2("failed to allocate data buffer area, error %m"); return -1; } - ret = perf_mmap__aio_bind(map, i, map->cpu, mp->affinity); + ret = perf_mmap__aio_bind(map, i, map->core.cpu, mp->affinity); if (ret == -1) return -1; /* @@ -347,9 +347,9 @@ static void perf_mmap__setup_affinity_mask(struct mmap *map, struct mmap_params { CPU_ZERO(&map->affinity_mask); if (mp->affinity == PERF_AFFINITY_NODE && cpu__max_node() > 1) - build_node_mask(cpu__get_node(map->cpu), &map->affinity_mask); + build_node_mask(cpu__get_node(map->core.cpu), &map->affinity_mask); else if (mp->affinity == PERF_AFFINITY_CPU) - CPU_SET(map->cpu, &map->affinity_mask); + CPU_SET(map->core.cpu, &map->affinity_mask); } int perf_mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu) @@ -379,7 +379,7 @@ int perf_mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu) return -1; } map->core.fd = fd; - map->cpu = cpu; + map->core.cpu = cpu; perf_mmap__setup_affinity_mask(map, mp); diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index de991194af8d..8ab779c98f4d 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -22,7 +22,6 @@ struct aiocb; */ struct mmap { struct perf_mmap core; - int cpu; refcount_t refcnt; u64 prev; u64 start; diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 60a6b6e8e176..ba4085d7ae9f 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -991,7 +991,7 @@ static struct mmap *get_md(struct evlist *evlist, int cpu) for (i = 0; i < evlist->nr_mmaps; i++) { struct mmap *md = &evlist->mmap[i]; - if (md->cpu == cpu) + if (md->core.cpu == cpu) return md; } -- cgit v1.2.3-59-g8ed1b From e03edfeac0330eaa2b19b82fc942611c1abf2120 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 27 Jul 2019 22:35:35 +0200 Subject: libperf: Add 'refcnt' to struct perf_mmap Move 'refcnt' from tools/perf's mmap to libperf's perf_mmap struct. Committer notes: Add the refcount.h include directive here, now it is needed. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-15-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/internal/mmap.h | 3 +++ tools/perf/util/evlist.c | 2 +- tools/perf/util/mmap.c | 18 +++++++++--------- tools/perf/util/mmap.h | 1 - 4 files changed, 13 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/internal/mmap.h b/tools/perf/lib/include/internal/mmap.h index f7d1809fa34c..e6fb850ba47a 100644 --- a/tools/perf/lib/include/internal/mmap.h +++ b/tools/perf/lib/include/internal/mmap.h @@ -2,6 +2,8 @@ #ifndef __LIBPERF_INTERNAL_MMAP_H #define __LIBPERF_INTERNAL_MMAP_H +#include + /** * struct perf_mmap - perf's ring buffer mmap details * @@ -12,6 +14,7 @@ struct perf_mmap { int mask; int fd; int cpu; + refcount_t refcnt; }; #endif /* __LIBPERF_INTERNAL_MMAP_H */ diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index a4e1c19c969f..d987e0e5d62b 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -719,7 +719,7 @@ static struct mmap *evlist__alloc_mmap(struct evlist *evlist, * Each PERF_EVENT_IOC_SET_OUTPUT points to this mmap and * thus does perf_mmap__get() on it. */ - refcount_set(&map[i].refcnt, 0); + refcount_set(&map[i].core.refcnt, 0); } return map; } diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index dc8320891344..d6406d216cfe 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -89,7 +89,7 @@ union perf_event *perf_mmap__read_event(struct mmap *map) /* * Check if event was unmapped due to a POLLHUP/POLLERR. */ - if (!refcount_read(&map->refcnt)) + if (!refcount_read(&map->core.refcnt)) return NULL; /* non-overwirte doesn't pause the ringbuffer */ @@ -111,14 +111,14 @@ static bool perf_mmap__empty(struct mmap *map) void perf_mmap__get(struct mmap *map) { - refcount_inc(&map->refcnt); + refcount_inc(&map->core.refcnt); } void perf_mmap__put(struct mmap *map) { - BUG_ON(map->core.base && refcount_read(&map->refcnt) == 0); + BUG_ON(map->core.base && refcount_read(&map->core.refcnt) == 0); - if (refcount_dec_and_test(&map->refcnt)) + if (refcount_dec_and_test(&map->core.refcnt)) perf_mmap__munmap(map); } @@ -130,7 +130,7 @@ void perf_mmap__consume(struct mmap *map) perf_mmap__write_tail(map, old); } - if (refcount_read(&map->refcnt) == 1 && perf_mmap__empty(map)) + if (refcount_read(&map->core.refcnt) == 1 && perf_mmap__empty(map)) perf_mmap__put(map); } @@ -321,7 +321,7 @@ void perf_mmap__munmap(struct mmap *map) munmap(map->core.base, perf_mmap__mmap_len(map)); map->core.base = NULL; map->core.fd = -1; - refcount_set(&map->refcnt, 0); + refcount_set(&map->core.refcnt, 0); } auxtrace_mmap__munmap(&map->auxtrace_mmap); } @@ -367,7 +367,7 @@ int perf_mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu) * evlist layer can't just drop it when filtering events in * perf_evlist__filter_pollfd(). */ - refcount_set(&map->refcnt, 2); + refcount_set(&map->core.refcnt, 2); map->prev = 0; map->core.mask = mp->mask; map->core.base = mmap(NULL, perf_mmap__mmap_len(map), mp->prot, @@ -479,7 +479,7 @@ int perf_mmap__read_init(struct mmap *map) /* * Check if event was unmapped due to a POLLHUP/POLLERR. */ - if (!refcount_read(&map->refcnt)) + if (!refcount_read(&map->core.refcnt)) return -ENOENT; return __perf_mmap__read_init(map); @@ -537,7 +537,7 @@ void perf_mmap__read_done(struct mmap *map) /* * Check if event was unmapped due to a POLLHUP/POLLERR. */ - if (!refcount_read(&map->refcnt)) + if (!refcount_read(&map->core.refcnt)) return; map->prev = perf_mmap__read_head(map); diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index 8ab779c98f4d..5febd22fbe2e 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -22,7 +22,6 @@ struct aiocb; */ struct mmap { struct perf_mmap core; - refcount_t refcnt; u64 prev; u64 start; u64 end; -- cgit v1.2.3-59-g8ed1b From ebe4d72bba86a499ea0935c58ba1c2aea5aafb43 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 27 Jul 2019 22:39:53 +0200 Subject: libperf: Add prev/start/end to struct perf_mmap Move prev/start/end from tools/perf's mmap to libperf's perf_mmap struct. Committer notes: Add linux/types.h as we use u64. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-16-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/internal/mmap.h | 4 +++ tools/perf/util/mmap.c | 50 +++++++++++++++++----------------- tools/perf/util/mmap.h | 3 -- 3 files changed, 29 insertions(+), 28 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/internal/mmap.h b/tools/perf/lib/include/internal/mmap.h index e6fb850ba47a..ebf5b93754fd 100644 --- a/tools/perf/lib/include/internal/mmap.h +++ b/tools/perf/lib/include/internal/mmap.h @@ -3,6 +3,7 @@ #define __LIBPERF_INTERNAL_MMAP_H #include +#include /** * struct perf_mmap - perf's ring buffer mmap details @@ -15,6 +16,9 @@ struct perf_mmap { int fd; int cpu; refcount_t refcnt; + u64 prev; + u64 start; + u64 end; }; #endif /* __LIBPERF_INTERNAL_MMAP_H */ diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index d6406d216cfe..6ce70ff005cb 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -94,19 +94,19 @@ union perf_event *perf_mmap__read_event(struct mmap *map) /* non-overwirte doesn't pause the ringbuffer */ if (!map->overwrite) - map->end = perf_mmap__read_head(map); + map->core.end = perf_mmap__read_head(map); - event = perf_mmap__read(map, &map->start, map->end); + event = perf_mmap__read(map, &map->core.start, map->core.end); if (!map->overwrite) - map->prev = map->start; + map->core.prev = map->core.start; return event; } static bool perf_mmap__empty(struct mmap *map) { - return perf_mmap__read_head(map) == map->prev && !map->auxtrace_mmap.base; + return perf_mmap__read_head(map) == map->core.prev && !map->auxtrace_mmap.base; } void perf_mmap__get(struct mmap *map) @@ -125,7 +125,7 @@ void perf_mmap__put(struct mmap *map) void perf_mmap__consume(struct mmap *map) { if (!map->overwrite) { - u64 old = map->prev; + u64 old = map->core.prev; perf_mmap__write_tail(map, old); } @@ -368,7 +368,7 @@ int perf_mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu) * perf_evlist__filter_pollfd(). */ refcount_set(&map->core.refcnt, 2); - map->prev = 0; + map->core.prev = 0; map->core.mask = mp->mask; map->core.base = mmap(NULL, perf_mmap__mmap_len(map), mp->prot, MAP_SHARED, fd, 0); @@ -443,22 +443,22 @@ static int overwrite_rb_find_range(void *buf, int mask, u64 *start, u64 *end) static int __perf_mmap__read_init(struct mmap *md) { u64 head = perf_mmap__read_head(md); - u64 old = md->prev; + u64 old = md->core.prev; unsigned char *data = md->core.base + page_size; unsigned long size; - md->start = md->overwrite ? head : old; - md->end = md->overwrite ? old : head; + md->core.start = md->overwrite ? head : old; + md->core.end = md->overwrite ? old : head; - if ((md->end - md->start) < md->flush) + if ((md->core.end - md->core.start) < md->flush) return -EAGAIN; - size = md->end - md->start; + size = md->core.end - md->core.start; if (size > (unsigned long)(md->core.mask) + 1) { if (!md->overwrite) { WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); - md->prev = head; + md->core.prev = head; perf_mmap__consume(md); return -EAGAIN; } @@ -467,7 +467,7 @@ static int __perf_mmap__read_init(struct mmap *md) * Backward ring buffer is full. We still have a chance to read * most of data from it. */ - if (overwrite_rb_find_range(data, md->core.mask, &md->start, &md->end)) + if (overwrite_rb_find_range(data, md->core.mask, &md->core.start, &md->core.end)) return -EINVAL; } @@ -498,12 +498,12 @@ int perf_mmap__push(struct mmap *md, void *to, if (rc < 0) return (rc == -EAGAIN) ? 1 : -1; - size = md->end - md->start; + size = md->core.end - md->core.start; - if ((md->start & md->core.mask) + size != (md->end & md->core.mask)) { - buf = &data[md->start & md->core.mask]; - size = md->core.mask + 1 - (md->start & md->core.mask); - md->start += size; + if ((md->core.start & md->core.mask) + size != (md->core.end & md->core.mask)) { + buf = &data[md->core.start & md->core.mask]; + size = md->core.mask + 1 - (md->core.start & md->core.mask); + md->core.start += size; if (push(md, to, buf, size) < 0) { rc = -1; @@ -511,16 +511,16 @@ int perf_mmap__push(struct mmap *md, void *to, } } - buf = &data[md->start & md->core.mask]; - size = md->end - md->start; - md->start += size; + buf = &data[md->core.start & md->core.mask]; + size = md->core.end - md->core.start; + md->core.start += size; if (push(md, to, buf, size) < 0) { rc = -1; goto out; } - md->prev = head; + md->core.prev = head; perf_mmap__consume(md); out: return rc; @@ -529,8 +529,8 @@ out: /* * Mandatory for overwrite mode * The direction of overwrite mode is backward. - * The last perf_mmap__read() will set tail to map->prev. - * Need to correct the map->prev to head which is the end of next read. + * The last perf_mmap__read() will set tail to map->core.prev. + * Need to correct the map->core.prev to head which is the end of next read. */ void perf_mmap__read_done(struct mmap *map) { @@ -540,5 +540,5 @@ void perf_mmap__read_done(struct mmap *map) if (!refcount_read(&map->core.refcnt)) return; - map->prev = perf_mmap__read_head(map); + map->core.prev = perf_mmap__read_head(map); } diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index 5febd22fbe2e..a3dd53f2bfb8 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -22,9 +22,6 @@ struct aiocb; */ struct mmap { struct perf_mmap core; - u64 prev; - u64 start; - u64 end; bool overwrite; struct auxtrace_mmap auxtrace_mmap; char event_copy[PERF_SAMPLE_MAX_SIZE] __aligned(8); -- cgit v1.2.3-59-g8ed1b From 8df7a869818ec278969d34e4792985f12b24f23d Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 27 Jul 2019 22:42:56 +0200 Subject: libperf: Add 'overwrite' to 'struct perf_mmap' Move 'overwrite' from tools/perf's mmap to libperf's perf_mmap struct. Committer notes: Add stdbool.h as we start using 'bool'. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-17-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/internal/mmap.h | 2 ++ tools/perf/util/evlist.c | 2 +- tools/perf/util/mmap.c | 12 ++++++------ tools/perf/util/mmap.h | 1 - 4 files changed, 9 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/internal/mmap.h b/tools/perf/lib/include/internal/mmap.h index ebf5b93754fd..47c09f375fb6 100644 --- a/tools/perf/lib/include/internal/mmap.h +++ b/tools/perf/lib/include/internal/mmap.h @@ -4,6 +4,7 @@ #include #include +#include /** * struct perf_mmap - perf's ring buffer mmap details @@ -19,6 +20,7 @@ struct perf_mmap { u64 prev; u64 start; u64 end; + bool overwrite; }; #endif /* __LIBPERF_INTERNAL_MMAP_H */ diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index d987e0e5d62b..16d47a420bc2 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -709,7 +709,7 @@ static struct mmap *evlist__alloc_mmap(struct evlist *evlist, for (i = 0; i < evlist->nr_mmaps; i++) { map[i].core.fd = -1; - map[i].overwrite = overwrite; + map[i].core.overwrite = overwrite; /* * When the perf_mmap() call is made we grab one refcount, plus * one extra to let perf_mmap__consume() get the last diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 6ce70ff005cb..a8850ce2c2ff 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -93,12 +93,12 @@ union perf_event *perf_mmap__read_event(struct mmap *map) return NULL; /* non-overwirte doesn't pause the ringbuffer */ - if (!map->overwrite) + if (!map->core.overwrite) map->core.end = perf_mmap__read_head(map); event = perf_mmap__read(map, &map->core.start, map->core.end); - if (!map->overwrite) + if (!map->core.overwrite) map->core.prev = map->core.start; return event; @@ -124,7 +124,7 @@ void perf_mmap__put(struct mmap *map) void perf_mmap__consume(struct mmap *map) { - if (!map->overwrite) { + if (!map->core.overwrite) { u64 old = map->core.prev; perf_mmap__write_tail(map, old); @@ -447,15 +447,15 @@ static int __perf_mmap__read_init(struct mmap *md) unsigned char *data = md->core.base + page_size; unsigned long size; - md->core.start = md->overwrite ? head : old; - md->core.end = md->overwrite ? old : head; + md->core.start = md->core.overwrite ? head : old; + md->core.end = md->core.overwrite ? old : head; if ((md->core.end - md->core.start) < md->flush) return -EAGAIN; size = md->core.end - md->core.start; if (size > (unsigned long)(md->core.mask) + 1) { - if (!md->overwrite) { + if (!md->core.overwrite) { WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); md->core.prev = head; diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index a3dd53f2bfb8..d3e74c8da51a 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -22,7 +22,6 @@ struct aiocb; */ struct mmap { struct perf_mmap core; - bool overwrite; struct auxtrace_mmap auxtrace_mmap; char event_copy[PERF_SAMPLE_MAX_SIZE] __aligned(8); #ifdef HAVE_AIO_SUPPORT -- cgit v1.2.3-59-g8ed1b From 4443e6d7704ee85412e5cb0a0181d7ceee7e984f Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 27 Jul 2019 22:47:58 +0200 Subject: libperf: Add 'event_copy' to 'struct perf_mmap' Move 'event_copy' from tools/perf's mmap to libperf's perf_mmap struct. Committer notes: Add linux/compiler.h as we need it for '__aligned'. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-18-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/internal/mmap.h | 5 +++++ tools/perf/util/mmap.c | 4 ++-- tools/perf/util/mmap.h | 1 - 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/internal/mmap.h b/tools/perf/lib/include/internal/mmap.h index 47c09f375fb6..10653b6e864e 100644 --- a/tools/perf/lib/include/internal/mmap.h +++ b/tools/perf/lib/include/internal/mmap.h @@ -2,10 +2,14 @@ #ifndef __LIBPERF_INTERNAL_MMAP_H #define __LIBPERF_INTERNAL_MMAP_H +#include #include #include #include +/* perf sample has 16 bits size limit */ +#define PERF_SAMPLE_MAX_SIZE (1 << 16) + /** * struct perf_mmap - perf's ring buffer mmap details * @@ -21,6 +25,7 @@ struct perf_mmap { u64 start; u64 end; bool overwrite; + char event_copy[PERF_SAMPLE_MAX_SIZE] __aligned(8); }; #endif /* __LIBPERF_INTERNAL_MMAP_H */ diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index a8850ce2c2ff..4b8ec8dd79c5 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -51,7 +51,7 @@ static union perf_event *perf_mmap__read(struct mmap *map, if ((*startp & map->core.mask) + size != ((*startp + size) & map->core.mask)) { unsigned int offset = *startp; unsigned int len = min(sizeof(*event), size), cpy; - void *dst = map->event_copy; + void *dst = map->core.event_copy; do { cpy = min(map->core.mask + 1 - (offset & map->core.mask), len); @@ -61,7 +61,7 @@ static union perf_event *perf_mmap__read(struct mmap *map, len -= cpy; } while (len); - event = (union perf_event *)map->event_copy; + event = (union perf_event *)map->core.event_copy; } *startp += size; diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index d3e74c8da51a..75c77fa57121 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -23,7 +23,6 @@ struct aiocb; struct mmap { struct perf_mmap core; struct auxtrace_mmap auxtrace_mmap; - char event_copy[PERF_SAMPLE_MAX_SIZE] __aligned(8); #ifdef HAVE_AIO_SUPPORT struct { void **data; -- cgit v1.2.3-59-g8ed1b From 65aa2e6bae3658cbc84c2e628a5c0ca163686204 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 27 Aug 2019 16:05:18 +0200 Subject: libperf: Add 'flush' to 'struct perf_mmap' Move 'flush' from tools/perf's mmap to libperf's perf_mmap struct. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-19-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 10 +++++----- tools/perf/lib/include/internal/mmap.h | 1 + tools/perf/util/mmap.c | 4 ++-- tools/perf/util/mmap.h | 1 - 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 2520c0212275..06738efd9820 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -973,13 +973,13 @@ static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist, if (map->core.base) { record__adjust_affinity(rec, map); if (synch) { - flush = map->flush; - map->flush = 1; + flush = map->core.flush; + map->core.flush = 1; } if (!record__aio_enabled(rec)) { if (perf_mmap__push(map, rec, record__pushfn) < 0) { if (synch) - map->flush = flush; + map->core.flush = flush; rc = -1; goto out; } @@ -987,13 +987,13 @@ static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist, if (record__aio_push(rec, map, &off) < 0) { record__aio_set_pos(trace_fd, off); if (synch) - map->flush = flush; + map->core.flush = flush; rc = -1; goto out; } } if (synch) - map->flush = flush; + map->core.flush = flush; } if (map->auxtrace_mmap.base && !rec->opts.auxtrace_snapshot_mode && diff --git a/tools/perf/lib/include/internal/mmap.h b/tools/perf/lib/include/internal/mmap.h index 10653b6e864e..ba1e519c15b9 100644 --- a/tools/perf/lib/include/internal/mmap.h +++ b/tools/perf/lib/include/internal/mmap.h @@ -25,6 +25,7 @@ struct perf_mmap { u64 start; u64 end; bool overwrite; + u64 flush; char event_copy[PERF_SAMPLE_MAX_SIZE] __aligned(8); }; diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 4b8ec8dd79c5..4cc3b54b2f73 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -383,7 +383,7 @@ int perf_mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu) perf_mmap__setup_affinity_mask(map, mp); - map->flush = mp->flush; + map->core.flush = mp->flush; map->comp_level = mp->comp_level; @@ -450,7 +450,7 @@ static int __perf_mmap__read_init(struct mmap *md) md->core.start = md->core.overwrite ? head : old; md->core.end = md->core.overwrite ? old : head; - if ((md->core.end - md->core.start) < md->flush) + if ((md->core.end - md->core.start) < md->core.flush) return -EAGAIN; size = md->core.end - md->core.start; diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index 75c77fa57121..e567c1c875bd 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -32,7 +32,6 @@ struct mmap { } aio; #endif cpu_set_t affinity_mask; - u64 flush; void *data; int comp_level; }; -- cgit v1.2.3-59-g8ed1b From 648b5af3f3ae7f4fad7395c8dc84cb79eafe2ba9 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 6 Aug 2019 11:35:19 +0200 Subject: libperf: Move 'system_wide' from 'struct evsel' to 'struct perf_evsel' Move the 'system_wide 'member from perf's evsel to libperf's perf_evsel. Committer notes: Added stdbool.h as we now use bool here. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-20-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/util/intel-pt.c | 4 ++-- tools/perf/builtin-script.c | 2 +- tools/perf/builtin-stat.c | 4 ++-- tools/perf/lib/include/internal/evsel.h | 2 ++ tools/perf/tests/switch-tracking.c | 6 +++--- tools/perf/util/evlist.c | 10 +++++----- tools/perf/util/evsel.c | 8 ++++---- tools/perf/util/evsel.h | 1 - tools/perf/util/parse-events.c | 2 +- tools/perf/util/stat.c | 2 +- 10 files changed, 21 insertions(+), 20 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 34d7118bf390..1aa86a88884a 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -422,7 +422,7 @@ static int intel_pt_track_switches(struct evlist *evlist) perf_evsel__set_sample_bit(evsel, CPU); perf_evsel__set_sample_bit(evsel, TIME); - evsel->system_wide = true; + evsel->core.system_wide = true; evsel->no_aux_samples = true; evsel->immediate = true; @@ -723,7 +723,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, switch_evsel->core.attr.sample_period = 1; switch_evsel->core.attr.context_switch = 1; - switch_evsel->system_wide = true; + switch_evsel->core.system_wide = true; switch_evsel->no_aux_samples = true; switch_evsel->immediate = true; diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index a17a9306bdf6..e7a49e2d7575 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1916,7 +1916,7 @@ static void __process_stat(struct evsel *counter, u64 tstamp) int cpu, thread; static int header_printed; - if (counter->system_wide) + if (counter->core.system_wide) nthreads = 1; if (!header_printed) { diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index f7d13326b830..0d55eb6bd6e2 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -278,7 +278,7 @@ static int read_counter(struct evsel *counter, struct timespec *rs) if (!counter->supported) return -ENOENT; - if (counter->system_wide) + if (counter->core.system_wide) nthreads = 1; for (thread = 0; thread < nthreads; thread++) { @@ -1671,7 +1671,7 @@ static void setup_system_wide(int forks) struct evsel *counter; evlist__for_each_entry(evsel_list, counter) { - if (!counter->system_wide) + if (!counter->core.system_wide) return; } diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h index 8b854d1c9b45..1bff789b0923 100644 --- a/tools/perf/lib/include/internal/evsel.h +++ b/tools/perf/lib/include/internal/evsel.h @@ -4,6 +4,7 @@ #include #include +#include struct perf_cpu_map; struct perf_thread_map; @@ -18,6 +19,7 @@ struct perf_evsel { /* parse modifier helper */ int nr_members; + bool system_wide; }; int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index e5c3f2ee223a..de700aad1fed 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -144,7 +144,7 @@ static int process_sample_event(struct evlist *evlist, return err; /* * Check for no missing sched_switch events i.e. that the - * evsel->system_wide flag has worked. + * evsel->core.system_wide flag has worked. */ if (switch_tracking->tids[cpu] != -1 && switch_tracking->tids[cpu] != prev_tid) { @@ -316,7 +316,7 @@ out_free_nodes: * * This function implements a test that checks that sched_switch events and * tracking events can be recorded for a workload (current process) using the - * evsel->system_wide and evsel->tracking flags (respectively) with other events + * evsel->core.system_wide and evsel->tracking flags (respectively) with other events * sometimes enabled or disabled. */ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_unused) @@ -396,7 +396,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ perf_evsel__set_sample_bit(switch_evsel, CPU); perf_evsel__set_sample_bit(switch_evsel, TIME); - switch_evsel->system_wide = true; + switch_evsel->core.system_wide = true; switch_evsel->no_aux_samples = true; switch_evsel->immediate = true; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 16d47a420bc2..16866533745c 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -319,7 +319,7 @@ int perf_evlist__add_newtp(struct evlist *evlist, static int perf_evlist__nr_threads(struct evlist *evlist, struct evsel *evsel) { - if (evsel->system_wide) + if (evsel->core.system_wide) return 1; else return perf_thread_map__nr(evlist->core.threads); @@ -410,7 +410,7 @@ int perf_evlist__alloc_pollfd(struct evlist *evlist) struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { - if (evsel->system_wide) + if (evsel->core.system_wide) nfds += nr_cpus; else nfds += nr_cpus * nr_threads; @@ -536,7 +536,7 @@ static void perf_evlist__set_sid_idx(struct evlist *evlist, sid->cpu = evlist->core.cpus->map[cpu]; else sid->cpu = -1; - if (!evsel->system_wide && evlist->core.threads && thread >= 0) + if (!evsel->core.system_wide && evlist->core.threads && thread >= 0) sid->tid = perf_thread_map__pid(evlist->core.threads, thread); else sid->tid = -1; @@ -763,7 +763,7 @@ static int evlist__mmap_per_evsel(struct evlist *evlist, int idx, mp->prot &= ~PROT_WRITE; } - if (evsel->system_wide && thread) + if (evsel->core.system_wide && thread) continue; cpu = perf_cpu_map__idx(evsel->core.cpus, evlist_cpu); @@ -793,7 +793,7 @@ static int evlist__mmap_per_evsel(struct evlist *evlist, int idx, * other events, so it should not need to be polled anyway. * Therefore don't add it for polling. */ - if (!evsel->system_wide && + if (!evsel->core.system_wide && __perf_evlist__add_pollfd(evlist, fd, &maps[idx], revent) < 0) { perf_mmap__put(&maps[idx]); return -1; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 502bc3d50e0d..566c9413246c 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1232,7 +1232,7 @@ int perf_evsel__alloc_id(struct evsel *evsel, int ncpus, int nthreads) if (ncpus == 0 || nthreads == 0) return 0; - if (evsel->system_wide) + if (evsel->core.system_wide) nthreads = 1; evsel->sample_id = xyarray__new(ncpus, nthreads, sizeof(struct perf_sample_id)); @@ -1663,7 +1663,7 @@ static bool ignore_missing_thread(struct evsel *evsel, return false; /* The system wide setup does not work with threads. */ - if (evsel->system_wide) + if (evsel->core.system_wide) return false; /* The -ESRCH is perf event syscall errno for pid's not found. */ @@ -1772,7 +1772,7 @@ int evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus, threads = empty_thread_map; } - if (evsel->system_wide) + if (evsel->core.system_wide) nthreads = 1; else nthreads = threads->nr; @@ -1819,7 +1819,7 @@ retry_sample_id: for (thread = 0; thread < nthreads; thread++) { int fd, group_fd; - if (!evsel->cgrp && !evsel->system_wide) + if (!evsel->cgrp && !evsel->core.system_wide) pid = perf_thread_map__pid(threads, thread); group_fd = get_group_fd(evsel, cpu, thread); diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 74df298acb31..f757ff449a17 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -146,7 +146,6 @@ struct evsel { bool disabled; bool no_aux_samples; bool immediate; - bool system_wide; bool tracking; bool per_pkg; bool precise_max; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 9cf1371c90a3..d7aebe9b005d 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -335,7 +335,7 @@ __add_event(struct list_head *list, int *idx, (*idx)++; evsel->core.cpus = perf_cpu_map__get(cpus); evsel->core.own_cpus = perf_cpu_map__get(cpus); - evsel->system_wide = pmu ? pmu->is_uncore : false; + evsel->core.system_wide = pmu ? pmu->is_uncore : false; evsel->auto_merge_stats = auto_merge_stats; if (name) diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index fcd54342c04c..ebdd130557fb 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -336,7 +336,7 @@ static int process_counter_maps(struct perf_stat_config *config, int ncpus = perf_evsel__nr_cpus(counter); int cpu, thread; - if (counter->system_wide) + if (counter->core.system_wide) nthreads = 1; for (thread = 0; thread < nthreads; thread++) { -- cgit v1.2.3-59-g8ed1b From c976ee11a0e1b3ba5e63e734dbf4b19154e39fab Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Jul 2019 13:04:59 +0200 Subject: libperf: Move 'nr_mmaps' from 'struct evlist' to 'struct perf_evlist' Moving 'nr_mmaps' from 'struct evlist' to 'struct perf_evlist', it will be used in following patches. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-21-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 2 +- tools/perf/arch/arm64/util/arm-spe.c | 2 +- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/arch/x86/util/intel-bts.c | 2 +- tools/perf/arch/x86/util/intel-pt.c | 2 +- tools/perf/builtin-kvm.c | 2 +- tools/perf/builtin-record.c | 6 +++--- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/lib/include/internal/evlist.h | 1 + tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/bpf.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/util/evlist.c | 16 ++++++++-------- tools/perf/util/evlist.h | 1 - tools/perf/util/python.c | 2 +- 20 files changed, 28 insertions(+), 28 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 5d120b1e35ed..051e9066fb38 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -648,7 +648,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr, if (priv_size != cs_etm_info_priv_size(itr, session->evlist)) return -EINVAL; - if (!session->evlist->nr_mmaps) + if (!session->evlist->core.nr_mmaps) return -EINVAL; /* If the cpu_map is empty all online CPUs are involved */ diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index eebbf31f995c..9302c6566f53 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -51,7 +51,7 @@ static int arm_spe_info_fill(struct auxtrace_record *itr, if (priv_size != ARM_SPE_AUXTRACE_PRIV_SIZE) return -EINVAL; - if (!session->evlist->nr_mmaps) + if (!session->evlist->core.nr_mmaps) return -EINVAL; auxtrace_info->type = PERF_AUXTRACE_ARM_SPE; diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index bd404db94b3a..10b7acebc0eb 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -115,7 +115,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe evlist__disable(evlist); - for (i = 0; i < evlist->nr_mmaps; i++) { + for (i = 0; i < evlist->core.nr_mmaps; i++) { md = &evlist->mmap[i]; if (perf_mmap__read_init(md) < 0) continue; diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index 130925141369..e81535c8e9c5 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -75,7 +75,7 @@ static int intel_bts_info_fill(struct auxtrace_record *itr, if (priv_size != INTEL_BTS_AUXTRACE_PRIV_SIZE) return -EINVAL; - if (!session->evlist->nr_mmaps) + if (!session->evlist->core.nr_mmaps) return -EINVAL; pc = session->evlist->mmap[0].core.base; diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 1aa86a88884a..886b3ac60f23 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -352,7 +352,7 @@ static int intel_pt_info_fill(struct auxtrace_record *itr, filter = intel_pt_find_filter(session->evlist, ptr->intel_pt_pmu); filter_str_len = filter ? strlen(filter) : 0; - if (!session->evlist->nr_mmaps) + if (!session->evlist->core.nr_mmaps) return -EINVAL; pc = session->evlist->mmap[0].core.base; diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 30852848ed9c..e2b42efc86fa 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -802,7 +802,7 @@ static int perf_kvm__mmap_read(struct perf_kvm_stat *kvm) s64 n, ntotal = 0; u64 flush_time = ULLONG_MAX, mmap_time; - for (i = 0; i < kvm->evlist->nr_mmaps; i++) { + for (i = 0; i < kvm->evlist->core.nr_mmaps; i++) { n = perf_kvm__mmap_read_idx(kvm, i, &mmap_time); if (n < 0) return -1; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 06738efd9820..8577bf33a556 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -357,7 +357,7 @@ static void record__aio_mmap_read_sync(struct record *rec) if (!record__aio_enabled(rec)) return; - for (i = 0; i < evlist->nr_mmaps; i++) { + for (i = 0; i < evlist->core.nr_mmaps; i++) { struct mmap *map = &maps[i]; if (map->core.base) @@ -603,7 +603,7 @@ static int record__auxtrace_read_snapshot_all(struct record *rec) int i; int rc = 0; - for (i = 0; i < rec->evlist->nr_mmaps; i++) { + for (i = 0; i < rec->evlist->core.nr_mmaps; i++) { struct mmap *map = &rec->evlist->mmap[i]; if (!map->auxtrace_mmap.base) @@ -966,7 +966,7 @@ static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist, if (record__aio_enabled(rec)) off = record__aio_get_pos(trace_fd); - for (i = 0; i < evlist->nr_mmaps; i++) { + for (i = 0; i < evlist->core.nr_mmaps; i++) { u64 flush = 0; struct mmap *map = &maps[i]; diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index e637a08655db..474b9860cfd4 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -904,7 +904,7 @@ static void perf_top__mmap_read(struct perf_top *top) if (overwrite) perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_DATA_PENDING); - for (i = 0; i < top->evlist->nr_mmaps; i++) + for (i = 0; i < top->evlist->core.nr_mmaps; i++) perf_top__mmap_read_idx(top, i); if (overwrite) { diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index c44280358e58..91c73c7472ba 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3443,7 +3443,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) again: before = trace->nr_events; - for (i = 0; i < evlist->nr_mmaps; i++) { + for (i = 0; i < evlist->core.nr_mmaps; i++) { union perf_event *event; struct mmap *md; diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h index 448891f06e3e..035c1e1cc324 100644 --- a/tools/perf/lib/include/internal/evlist.h +++ b/tools/perf/lib/include/internal/evlist.h @@ -13,6 +13,7 @@ struct perf_evlist { bool has_user_cpus; struct perf_cpu_map *cpus; struct perf_thread_map *threads; + int nr_mmaps; }; /** diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index c59d3752d48d..338cd9faa835 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -33,7 +33,7 @@ static int count_samples(struct evlist *evlist, int *sample_count, { int i; - for (i = 0; i < evlist->nr_mmaps; i++) { + for (i = 0; i < evlist->core.nr_mmaps; i++) { struct mmap *map = &evlist->overwrite_mmap[i]; union perf_event *event; diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 3c8533fdbce5..1eb0bffaed6c 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -179,7 +179,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void), (*func)(); evlist__disable(evlist); - for (i = 0; i < evlist->nr_mmaps; i++) { + for (i = 0; i < evlist->core.nr_mmaps; i++) { union perf_event *event; struct mmap *md; diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index bc6db3e7a1c5..7dac69a375f9 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -423,7 +423,7 @@ static int process_events(struct machine *machine, struct evlist *evlist, struct mmap *md; int i, ret; - for (i = 0; i < evlist->nr_mmaps; i++) { + for (i = 0; i < evlist->core.nr_mmaps; i++) { md = &evlist->mmap[i]; if (perf_mmap__read_init(md) < 0) continue; diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index c6030fdf7d4c..bd4ae8e5cd5d 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -36,7 +36,7 @@ static int find_comm(struct evlist *evlist, const char *comm) int i, found; found = 0; - for (i = 0; i < evlist->nr_mmaps; i++) { + for (i = 0; i < evlist->core.nr_mmaps; i++) { md = &evlist->mmap[i]; if (perf_mmap__read_init(md) < 0) continue; diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index e20eaadb1a35..4629fa33c8ad 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -87,7 +87,7 @@ int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest while (1) { int before = nr_events; - for (i = 0; i < evlist->nr_mmaps; i++) { + for (i = 0; i < evlist->core.nr_mmaps; i++) { union perf_event *event; struct mmap *md; diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index ea8bcaa13ea5..199a66444e60 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -165,7 +165,7 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus while (1) { int before = total_events; - for (i = 0; i < evlist->nr_mmaps; i++) { + for (i = 0; i < evlist->core.nr_mmaps; i++) { union perf_event *event; struct mmap *md; diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index de700aad1fed..30a70db6473d 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -267,7 +267,7 @@ static int process_events(struct evlist *evlist, struct mmap *md; int i, ret; - for (i = 0; i < evlist->nr_mmaps; i++) { + for (i = 0; i < evlist->core.nr_mmaps; i++) { md = &evlist->mmap[i]; if (perf_mmap__read_init(md) < 0) continue; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 16866533745c..d147834fbe60 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -651,7 +651,7 @@ static int perf_evlist__set_paused(struct evlist *evlist, bool value) if (!evlist->overwrite_mmap) return 0; - for (i = 0; i < evlist->nr_mmaps; i++) { + for (i = 0; i < evlist->core.nr_mmaps; i++) { int fd = evlist->overwrite_mmap[i].core.fd; int err; @@ -679,11 +679,11 @@ static void evlist__munmap_nofree(struct evlist *evlist) int i; if (evlist->mmap) - for (i = 0; i < evlist->nr_mmaps; i++) + for (i = 0; i < evlist->core.nr_mmaps; i++) perf_mmap__munmap(&evlist->mmap[i]); if (evlist->overwrite_mmap) - for (i = 0; i < evlist->nr_mmaps; i++) + for (i = 0; i < evlist->core.nr_mmaps; i++) perf_mmap__munmap(&evlist->overwrite_mmap[i]); } @@ -700,14 +700,14 @@ static struct mmap *evlist__alloc_mmap(struct evlist *evlist, int i; struct mmap *map; - evlist->nr_mmaps = perf_cpu_map__nr(evlist->core.cpus); + evlist->core.nr_mmaps = perf_cpu_map__nr(evlist->core.cpus); if (perf_cpu_map__empty(evlist->core.cpus)) - evlist->nr_mmaps = perf_thread_map__nr(evlist->core.threads); - map = zalloc(evlist->nr_mmaps * sizeof(struct mmap)); + evlist->core.nr_mmaps = perf_thread_map__nr(evlist->core.threads); + map = zalloc(evlist->core.nr_mmaps * sizeof(struct mmap)); if (!map) return NULL; - for (i = 0; i < evlist->nr_mmaps; i++) { + for (i = 0; i < evlist->core.nr_mmaps; i++) { map[i].core.fd = -1; map[i].core.overwrite = overwrite; /* @@ -1847,7 +1847,7 @@ static void *perf_evlist__poll_thread(void *arg) if (!draining) perf_evlist__poll(evlist, 1000); - for (i = 0; i < evlist->nr_mmaps; i++) { + for (i = 0; i < evlist->core.nr_mmaps; i++) { struct mmap *map = &evlist->mmap[i]; union perf_event *event; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 8b9c35efea67..816b72a2b1e5 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -55,7 +55,6 @@ struct evlist { struct perf_evlist core; struct hlist_head heads[PERF_EVLIST__HLIST_SIZE]; int nr_groups; - int nr_mmaps; bool enabled; size_t mmap_len; int id_pos; diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index ba4085d7ae9f..62144b97e17b 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -988,7 +988,7 @@ static struct mmap *get_md(struct evlist *evlist, int cpu) { int i; - for (i = 0; i < evlist->nr_mmaps; i++) { + for (i = 0; i < evlist->core.nr_mmaps; i++) { struct mmap *md = &evlist->mmap[i]; if (md->core.cpu == cpu) -- cgit v1.2.3-59-g8ed1b From f6fa437577937265dacd4637608f4cf0a1a928dc Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 6 Aug 2019 15:14:05 +0200 Subject: libperf: Move 'mmap_len' from 'struct evlist' to 'struct perf_evlist' Moving 'mmap_len' from 'struct evlist' to 'struct perf_evlist' it will be used in following patches. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-22-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 2 +- tools/perf/lib/include/internal/evlist.h | 1 + tools/perf/util/evlist.c | 10 +++++----- tools/perf/util/evlist.h | 1 - 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 8577bf33a556..94997144547d 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1412,7 +1412,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) err = -1; goto out_child; } - session->header.env.comp_mmap_len = session->evlist->mmap_len; + session->header.env.comp_mmap_len = session->evlist->core.mmap_len; err = bpf__apply_obj_config(); if (err) { diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h index 035c1e1cc324..01b813616440 100644 --- a/tools/perf/lib/include/internal/evlist.h +++ b/tools/perf/lib/include/internal/evlist.h @@ -14,6 +14,7 @@ struct perf_evlist { struct perf_cpu_map *cpus; struct perf_thread_map *threads; int nr_mmaps; + size_t mmap_len; }; /** diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index d147834fbe60..4d8cde099e10 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1012,11 +1012,11 @@ int evlist__mmap_ex(struct evlist *evlist, unsigned int pages, if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) return -ENOMEM; - evlist->mmap_len = evlist__mmap_size(pages); - pr_debug("mmap size %zuB\n", evlist->mmap_len); - mp.mask = evlist->mmap_len - page_size - 1; + evlist->core.mmap_len = evlist__mmap_size(pages); + pr_debug("mmap size %zuB\n", evlist->core.mmap_len); + mp.mask = evlist->core.mmap_len - page_size - 1; - auxtrace_mmap_params__init(&mp.auxtrace_mp, evlist->mmap_len, + auxtrace_mmap_params__init(&mp.auxtrace_mp, evlist->core.mmap_len, auxtrace_pages, auxtrace_overwrite); evlist__for_each_entry(evlist, evsel) { @@ -1600,7 +1600,7 @@ out_default: int perf_evlist__strerror_mmap(struct evlist *evlist, int err, char *buf, size_t size) { char sbuf[STRERR_BUFSIZE], *emsg = str_error_r(err, sbuf, sizeof(sbuf)); - int pages_attempted = evlist->mmap_len / 1024, pages_max_per_user, printed = 0; + int pages_attempted = evlist->core.mmap_len / 1024, pages_max_per_user, printed = 0; switch (err) { case EPERM: diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 816b72a2b1e5..765cee8bced1 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -56,7 +56,6 @@ struct evlist { struct hlist_head heads[PERF_EVLIST__HLIST_SIZE]; int nr_groups; bool enabled; - size_t mmap_len; int id_pos; int is_pos; u64 combined_sample_type; -- cgit v1.2.3-59-g8ed1b From 40cb2d5141bdd52b3c00bb78799118c4606947ac Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 6 Aug 2019 11:28:02 +0200 Subject: libperf: Move 'pollfd' from 'struct evlist' to 'struct perf_evlist' Moving 'pollfd' from 'struct evlist' to 'struct perf_evlist' it will be used in following patches. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-23-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kvm.c | 2 +- tools/perf/lib/include/internal/evlist.h | 2 ++ tools/perf/util/evlist.c | 18 +++++++++--------- tools/perf/util/evlist.h | 1 - tools/perf/util/python.c | 6 +++--- 5 files changed, 15 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index e2b42efc86fa..710a2898ed6c 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -981,7 +981,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm) evlist__enable(kvm->evlist); while (!done) { - struct fdarray *fda = &kvm->evlist->pollfd; + struct fdarray *fda = &kvm->evlist->core.pollfd; int rc; rc = perf_kvm__mmap_read(kvm); diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h index 01b813616440..8a4eb66fbf3a 100644 --- a/tools/perf/lib/include/internal/evlist.h +++ b/tools/perf/lib/include/internal/evlist.h @@ -3,6 +3,7 @@ #define __LIBPERF_INTERNAL_EVLIST_H #include +#include struct perf_cpu_map; struct perf_thread_map; @@ -15,6 +16,7 @@ struct perf_evlist { struct perf_thread_map *threads; int nr_mmaps; size_t mmap_len; + struct fdarray pollfd; }; /** diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4d8cde099e10..13595e8e6b4b 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -61,7 +61,7 @@ void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, INIT_HLIST_HEAD(&evlist->heads[i]); perf_evlist__init(&evlist->core); perf_evlist__set_maps(&evlist->core, cpus, threads); - fdarray__init(&evlist->pollfd, 64); + fdarray__init(&evlist->core.pollfd, 64); evlist->workload.pid = -1; evlist->bkw_mmap_state = BKW_MMAP_NOTREADY; } @@ -142,7 +142,7 @@ void evlist__exit(struct evlist *evlist) { zfree(&evlist->mmap); zfree(&evlist->overwrite_mmap); - fdarray__exit(&evlist->pollfd); + fdarray__exit(&evlist->core.pollfd); } void evlist__delete(struct evlist *evlist) @@ -416,8 +416,8 @@ int perf_evlist__alloc_pollfd(struct evlist *evlist) nfds += nr_cpus * nr_threads; } - if (fdarray__available_entries(&evlist->pollfd) < nfds && - fdarray__grow(&evlist->pollfd, nfds) < 0) + if (fdarray__available_entries(&evlist->core.pollfd) < nfds && + fdarray__grow(&evlist->core.pollfd, nfds) < 0) return -ENOMEM; return 0; @@ -426,13 +426,13 @@ int perf_evlist__alloc_pollfd(struct evlist *evlist) static int __perf_evlist__add_pollfd(struct evlist *evlist, int fd, struct mmap *map, short revent) { - int pos = fdarray__add(&evlist->pollfd, fd, revent | POLLERR | POLLHUP); + int pos = fdarray__add(&evlist->core.pollfd, fd, revent | POLLERR | POLLHUP); /* * Save the idx so that when we filter out fds POLLHUP'ed we can * close the associated evlist->mmap[] entry. */ if (pos >= 0) { - evlist->pollfd.priv[pos].ptr = map; + evlist->core.pollfd.priv[pos].ptr = map; fcntl(fd, F_SETFL, O_NONBLOCK); } @@ -456,13 +456,13 @@ static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd, int perf_evlist__filter_pollfd(struct evlist *evlist, short revents_and_mask) { - return fdarray__filter(&evlist->pollfd, revents_and_mask, + return fdarray__filter(&evlist->core.pollfd, revents_and_mask, perf_evlist__munmap_filtered, NULL); } int perf_evlist__poll(struct evlist *evlist, int timeout) { - return fdarray__poll(&evlist->pollfd, timeout); + return fdarray__poll(&evlist->core.pollfd, timeout); } static void perf_evlist__id_hash(struct evlist *evlist, @@ -1009,7 +1009,7 @@ int evlist__mmap_ex(struct evlist *evlist, unsigned int pages, if (!evlist->mmap) return -ENOMEM; - if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) + if (evlist->core.pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) return -ENOMEM; evlist->core.mmap_len = evlist__mmap_size(pages); diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 765cee8bced1..4fcdf93eb19c 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -64,7 +64,6 @@ struct evlist { int cork_fd; pid_t pid; } workload; - struct fdarray pollfd; struct mmap *mmap; struct mmap *overwrite_mmap; struct evsel *selected; diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 62144b97e17b..fcbafb1e8d9d 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -935,17 +935,17 @@ static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist, PyObject *list = PyList_New(0); int i; - for (i = 0; i < evlist->pollfd.nr; ++i) { + for (i = 0; i < evlist->core.pollfd.nr; ++i) { PyObject *file; #if PY_MAJOR_VERSION < 3 - FILE *fp = fdopen(evlist->pollfd.entries[i].fd, "r"); + FILE *fp = fdopen(evlist->core.pollfd.entries[i].fd, "r"); if (fp == NULL) goto free_list; file = PyFile_FromFile(fp, "perf", "r", NULL); #else - file = PyFile_FromFd(evlist->pollfd.entries[i].fd, "perf", "r", -1, + file = PyFile_FromFd(evlist->core.pollfd.entries[i].fd, "perf", "r", -1, NULL, NULL, NULL, 0); #endif if (file == NULL) -- cgit v1.2.3-59-g8ed1b From fee92b4442f135495d4fc59a0b9418490d4ac0ba Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 23 Sep 2019 15:10:35 -0300 Subject: libperf: Add missing 'struct xyarray' forward declaration We were getting it by luck, from files included before internal/evsel.h where it is being included. Fixes: 9dfcb7599084 ("libperf: Move fd array from perf's evsel to lobperf's perf_evsel class") Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lkml.kernel.org/n/tip-r8ukhxprpkflbd2k9vcc42v1@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/internal/evsel.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h index 1bff789b0923..60daee6db914 100644 --- a/tools/perf/lib/include/internal/evsel.h +++ b/tools/perf/lib/include/internal/evsel.h @@ -8,6 +8,7 @@ struct perf_cpu_map; struct perf_thread_map; +struct xyarray; struct perf_evsel { struct list_head node; -- cgit v1.2.3-59-g8ed1b From 8cd36f3ef4926165bc5e5af6f7d7b45f0e14a1f4 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 2 Sep 2019 22:04:12 +0200 Subject: libperf: Move 'sample_id' from 'struct evsel' to 'struct perf_evsel' Move 'sample_id' array from 'struct evsel' to libperf's 'struct perf_evsel'. Committer notes: Removed the 'struct xyarray' from util/evsel.h, not needed anymore there. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-24-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 2 +- tools/perf/lib/include/internal/evsel.h | 1 + tools/perf/util/evlist.c | 4 ++-- tools/perf/util/evsel.c | 12 ++++++------ tools/perf/util/evsel.h | 2 -- 5 files changed, 10 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 0d55eb6bd6e2..468fc49420ce 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -235,7 +235,7 @@ static int write_stat_round_event(u64 tm, u64 type) #define WRITE_STAT_ROUND_EVENT(time, interval) \ write_stat_round_event(time, PERF_STAT_ROUND_TYPE__ ## interval) -#define SID(e, x, y) xyarray__entry(e->sample_id, x, y) +#define SID(e, x, y) xyarray__entry(e->core.sample_id, x, y) static int perf_evsel__write_stat_event(struct evsel *counter, u32 cpu, u32 thread, diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h index 60daee6db914..1ddb969f7807 100644 --- a/tools/perf/lib/include/internal/evsel.h +++ b/tools/perf/lib/include/internal/evsel.h @@ -17,6 +17,7 @@ struct perf_evsel { struct perf_cpu_map *own_cpus; struct perf_thread_map *threads; struct xyarray *fd; + struct xyarray *sample_id; /* parse modifier helper */ int nr_members; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 13595e8e6b4b..84b409802298 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -50,7 +50,7 @@ int sigqueue(pid_t pid, int sig, const union sigval value); #endif #define FD(e, x, y) (*(int *)xyarray__entry(e->core.fd, x, y)) -#define SID(e, x, y) xyarray__entry(e->sample_id, x, y) +#define SID(e, x, y) xyarray__entry(e->core.sample_id, x, y) void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, struct perf_thread_map *threads) @@ -1021,7 +1021,7 @@ int evlist__mmap_ex(struct evlist *evlist, unsigned int pages, evlist__for_each_entry(evlist, evsel) { if ((evsel->core.attr.read_format & PERF_FORMAT_ID) && - evsel->sample_id == NULL && + evsel->core.sample_id == NULL && perf_evsel__alloc_id(evsel, perf_cpu_map__nr(cpus), threads->nr) < 0) return -ENOMEM; } diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 566c9413246c..cb1ada8cf4a4 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1235,14 +1235,14 @@ int perf_evsel__alloc_id(struct evsel *evsel, int ncpus, int nthreads) if (evsel->core.system_wide) nthreads = 1; - evsel->sample_id = xyarray__new(ncpus, nthreads, sizeof(struct perf_sample_id)); - if (evsel->sample_id == NULL) + evsel->core.sample_id = xyarray__new(ncpus, nthreads, sizeof(struct perf_sample_id)); + if (evsel->core.sample_id == NULL) return -ENOMEM; evsel->id = zalloc(ncpus * nthreads * sizeof(u64)); if (evsel->id == NULL) { - xyarray__delete(evsel->sample_id); - evsel->sample_id = NULL; + xyarray__delete(evsel->core.sample_id); + evsel->core.sample_id = NULL; return -ENOMEM; } @@ -1251,8 +1251,8 @@ int perf_evsel__alloc_id(struct evsel *evsel, int ncpus, int nthreads) static void perf_evsel__free_id(struct evsel *evsel) { - xyarray__delete(evsel->sample_id); - evsel->sample_id = NULL; + xyarray__delete(evsel->core.sample_id); + evsel->core.sample_id = NULL; zfree(&evsel->id); evsel->ids = 0; } diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index f757ff449a17..2d2c6cad81f8 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -96,7 +96,6 @@ enum perf_tool_event { struct bpf_object; struct perf_counts; -struct xyarray; /** struct evsel - event selector * @@ -117,7 +116,6 @@ struct evsel { struct perf_evsel core; struct evlist *evlist; char *filter; - struct xyarray *sample_id; u64 *id; struct perf_counts *counts; struct perf_counts *prev_raw_counts; -- cgit v1.2.3-59-g8ed1b From deaf321913a7b1d440c5cd5c7766d47381c9b21b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 2 Sep 2019 22:12:26 +0200 Subject: libperf: Move 'id' from 'struct evsel' to 'struct perf_evsel' Move the 'id' array from 'struct evsel' to libperf's 'struct perf_evsel'. Committer note: Fix the tools/perf/util/cs-etm.c build, i.e. aarch64's CoreSight. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-25-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/internal/evsel.h | 1 + tools/perf/util/cs-etm.c | 2 +- tools/perf/util/evlist.c | 2 +- tools/perf/util/evsel.c | 6 +++--- tools/perf/util/evsel.h | 1 - tools/perf/util/header.c | 10 +++++----- tools/perf/util/intel-bts.c | 2 +- tools/perf/util/intel-pt.c | 8 ++++---- tools/perf/util/synthetic-events.c | 12 ++++++------ 9 files changed, 22 insertions(+), 22 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h index 1ddb969f7807..e7171948c347 100644 --- a/tools/perf/lib/include/internal/evsel.h +++ b/tools/perf/lib/include/internal/evsel.h @@ -18,6 +18,7 @@ struct perf_evsel { struct perf_thread_map *threads; struct xyarray *fd; struct xyarray *sample_id; + u64 *id; /* parse modifier helper */ int nr_members; diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 6021974577d5..4ba0f871f086 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -1298,7 +1298,7 @@ static int cs_etm__synth_events(struct cs_etm_auxtrace *etm, attr.read_format = evsel->core.attr.read_format; /* create new id val to be a fixed offset from evsel id */ - id = evsel->id[0] + 1000000000; + id = evsel->core.id[0] + 1000000000; if (!id) id = 1; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 84b409802298..24f03f245525 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -482,7 +482,7 @@ void perf_evlist__id_add(struct evlist *evlist, struct evsel *evsel, int cpu, int thread, u64 id) { perf_evlist__id_hash(evlist, evsel, cpu, thread, id); - evsel->id[evsel->ids++] = id; + evsel->core.id[evsel->ids++] = id; } int perf_evlist__id_add_fd(struct evlist *evlist, diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index cb1ada8cf4a4..9c1b4f4a5fa3 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1239,8 +1239,8 @@ int perf_evsel__alloc_id(struct evsel *evsel, int ncpus, int nthreads) if (evsel->core.sample_id == NULL) return -ENOMEM; - evsel->id = zalloc(ncpus * nthreads * sizeof(u64)); - if (evsel->id == NULL) { + evsel->core.id = zalloc(ncpus * nthreads * sizeof(u64)); + if (evsel->core.id == NULL) { xyarray__delete(evsel->core.sample_id); evsel->core.sample_id = NULL; return -ENOMEM; @@ -1253,7 +1253,7 @@ static void perf_evsel__free_id(struct evsel *evsel) { xyarray__delete(evsel->core.sample_id); evsel->core.sample_id = NULL; - zfree(&evsel->id); + zfree(&evsel->core.id); evsel->ids = 0; } diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 2d2c6cad81f8..0d2aa933ceb3 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -116,7 +116,6 @@ struct evsel { struct perf_evsel core; struct evlist *evlist; char *filter; - u64 *id; struct perf_counts *counts; struct perf_counts *prev_raw_counts; int idx; diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 0167f9697172..2b0681ab08aa 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -530,7 +530,7 @@ static int write_event_desc(struct feat_fd *ff, /* * write unique ids for this event */ - ret = do_write(ff, evsel->id, evsel->ids * sizeof(u64)); + ret = do_write(ff, evsel->core.id, evsel->ids * sizeof(u64)); if (ret < 0) return ret; } @@ -1590,7 +1590,7 @@ static void free_event_desc(struct evsel *events) for (evsel = events; evsel->core.attr.size; evsel++) { zfree(&evsel->name); - zfree(&evsel->id); + zfree(&evsel->core.id); } free(events); @@ -1657,7 +1657,7 @@ static struct evsel *read_event_desc(struct feat_fd *ff) if (!id) goto error; evsel->ids = nr; - evsel->id = id; + evsel->core.id = id; for (j = 0 ; j < nr; j++) { if (do_read_u64(ff, id)) @@ -1701,7 +1701,7 @@ static void print_event_desc(struct feat_fd *ff, FILE *fp) if (evsel->ids) { fprintf(fp, ", id = {"); - for (j = 0, id = evsel->id; j < evsel->ids; j++, id++) { + for (j = 0, id = evsel->core.id; j < evsel->ids; j++, id++) { if (j) fputc(',', fp); fprintf(fp, " %"PRIu64, *id); @@ -3068,7 +3068,7 @@ int perf_session__write_header(struct perf_session *session, evlist__for_each_entry(session->evlist, evsel) { evsel->id_offset = lseek(fd, 0, SEEK_CUR); - err = do_write(&ff, evsel->id, evsel->ids * sizeof(u64)); + err = do_write(&ff, evsel->core.id, evsel->ids * sizeof(u64)); if (err < 0) { pr_debug("failed to write perf header\n"); return err; diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index 3888d4cd3ed1..c94360cd9c00 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c @@ -795,7 +795,7 @@ static int intel_bts_synth_events(struct intel_bts *bts, attr.sample_id_all = evsel->core.attr.sample_id_all; attr.read_format = evsel->core.attr.read_format; - id = evsel->id[0] + 1000000000; + id = evsel->core.id[0] + 1000000000; if (!id) id = 1; diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index bcdc0359f7cf..24ca5d5908ca 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -1705,7 +1705,7 @@ static int intel_pt_synth_pebs_sample(struct intel_pt_queue *ptq) struct intel_pt *pt = ptq->pt; struct evsel *evsel = pt->pebs_evsel; u64 sample_type = evsel->core.attr.sample_type; - u64 id = evsel->id[0]; + u64 id = evsel->core.id[0]; u8 cpumode; if (intel_pt_skip_event(pt)) @@ -2720,7 +2720,7 @@ static void intel_pt_set_event_name(struct evlist *evlist, u64 id, struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { - if (evsel->id && evsel->id[0] == id) { + if (evsel->core.id && evsel->core.id[0] == id) { if (evsel->name) zfree(&evsel->name); evsel->name = strdup(name); @@ -2776,7 +2776,7 @@ static int intel_pt_synth_events(struct intel_pt *pt, attr.sample_id_all = evsel->core.attr.sample_id_all; attr.read_format = evsel->core.attr.read_format; - id = evsel->id[0] + 1000000000; + id = evsel->core.id[0] + 1000000000; if (!id) id = 1; @@ -2903,7 +2903,7 @@ static void intel_pt_setup_pebs_events(struct intel_pt *pt) return; evlist__for_each_entry(pt->session->evlist, evsel) { - if (evsel->core.attr.aux_output && evsel->id) { + if (evsel->core.attr.aux_output && evsel->core.id) { pt->sample_pebs = true; pt->pebs_evsel = evsel; return; diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index 8322028a9a97..907ac3971959 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -1442,7 +1442,7 @@ int perf_event__synthesize_id_index(struct perf_tool *tool, perf_event__handler_ e = &ev->id_index.entries[i++]; - e->id = evsel->id[j]; + e->id = evsel->core.id[j]; sid = perf_evlist__id2sid(evlist, e->id); if (!sid) { @@ -1515,7 +1515,7 @@ int perf_event__synthesize_event_update_unit(struct perf_tool *tool, struct evse struct perf_record_event_update *ev; int err; - ev = event_update_event__new(size + 1, PERF_EVENT_UPDATE__UNIT, evsel->id[0]); + ev = event_update_event__new(size + 1, PERF_EVENT_UPDATE__UNIT, evsel->core.id[0]); if (ev == NULL) return -ENOMEM; @@ -1532,7 +1532,7 @@ int perf_event__synthesize_event_update_scale(struct perf_tool *tool, struct evs struct perf_record_event_update_scale *ev_data; int err; - ev = event_update_event__new(sizeof(*ev_data), PERF_EVENT_UPDATE__SCALE, evsel->id[0]); + ev = event_update_event__new(sizeof(*ev_data), PERF_EVENT_UPDATE__SCALE, evsel->core.id[0]); if (ev == NULL) return -ENOMEM; @@ -1550,7 +1550,7 @@ int perf_event__synthesize_event_update_name(struct perf_tool *tool, struct evse size_t len = strlen(evsel->name); int err; - ev = event_update_event__new(len + 1, PERF_EVENT_UPDATE__NAME, evsel->id[0]); + ev = event_update_event__new(len + 1, PERF_EVENT_UPDATE__NAME, evsel->core.id[0]); if (ev == NULL) return -ENOMEM; @@ -1578,7 +1578,7 @@ int perf_event__synthesize_event_update_cpus(struct perf_tool *tool, struct evse ev->header.type = PERF_RECORD_EVENT_UPDATE; ev->header.size = (u16)size; ev->type = PERF_EVENT_UPDATE__CPUS; - ev->id = evsel->id[0]; + ev->id = evsel->core.id[0]; cpu_map_data__synthesize((struct perf_record_cpu_map_data *)ev->data, evsel->core.own_cpus, type, max); @@ -1596,7 +1596,7 @@ int perf_event__synthesize_attrs(struct perf_tool *tool, struct evlist *evlist, evlist__for_each_entry(evlist, evsel) { err = perf_event__synthesize_attr(tool, &evsel->core.attr, evsel->ids, - evsel->id, process); + evsel->core.id, process); if (err) { pr_debug("failed to create perf header attribute\n"); return err; -- cgit v1.2.3-59-g8ed1b From e7eb9002d4513ac4a26c756b72e6c25bf063baf2 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 2 Sep 2019 22:15:47 +0200 Subject: libperf: Move 'ids' from 'struct evsel' to 'struct perf_evsel' Move 'ids' from 'struct evsel' to libperf's 'struct perf_evsel'. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-26-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/internal/evsel.h | 1 + tools/perf/util/evlist.c | 2 +- tools/perf/util/evsel.c | 2 +- tools/perf/util/evsel.h | 1 - tools/perf/util/header.c | 14 +++++++------- tools/perf/util/intel-bts.c | 2 +- tools/perf/util/intel-pt.c | 2 +- tools/perf/util/synthetic-events.c | 6 +++--- 8 files changed, 15 insertions(+), 15 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h index e7171948c347..385766f06591 100644 --- a/tools/perf/lib/include/internal/evsel.h +++ b/tools/perf/lib/include/internal/evsel.h @@ -19,6 +19,7 @@ struct perf_evsel { struct xyarray *fd; struct xyarray *sample_id; u64 *id; + u32 ids; /* parse modifier helper */ int nr_members; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 24f03f245525..5e43fb9da359 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -482,7 +482,7 @@ void perf_evlist__id_add(struct evlist *evlist, struct evsel *evsel, int cpu, int thread, u64 id) { perf_evlist__id_hash(evlist, evsel, cpu, thread, id); - evsel->core.id[evsel->ids++] = id; + evsel->core.id[evsel->core.ids++] = id; } int perf_evlist__id_add_fd(struct evlist *evlist, diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 9c1b4f4a5fa3..55638eb9299c 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1254,7 +1254,7 @@ static void perf_evsel__free_id(struct evsel *evsel) xyarray__delete(evsel->core.sample_id); evsel->core.sample_id = NULL; zfree(&evsel->core.id); - evsel->ids = 0; + evsel->core.ids = 0; } static void perf_evsel__free_config_terms(struct evsel *evsel) diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 0d2aa933ceb3..ed64395ec340 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -119,7 +119,6 @@ struct evsel { struct perf_counts *counts; struct perf_counts *prev_raw_counts; int idx; - u32 ids; unsigned long max_events; unsigned long nr_events_printed; char *name; diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 2b0681ab08aa..498f6a825656 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -516,7 +516,7 @@ static int write_event_desc(struct feat_fd *ff, * copy into an nri to be independent of the * type of ids, */ - nri = evsel->ids; + nri = evsel->core.ids; ret = do_write(ff, &nri, sizeof(nri)); if (ret < 0) return ret; @@ -530,7 +530,7 @@ static int write_event_desc(struct feat_fd *ff, /* * write unique ids for this event */ - ret = do_write(ff, evsel->core.id, evsel->ids * sizeof(u64)); + ret = do_write(ff, evsel->core.id, evsel->core.ids * sizeof(u64)); if (ret < 0) return ret; } @@ -1656,7 +1656,7 @@ static struct evsel *read_event_desc(struct feat_fd *ff) id = calloc(nr, sizeof(*id)); if (!id) goto error; - evsel->ids = nr; + evsel->core.ids = nr; evsel->core.id = id; for (j = 0 ; j < nr; j++) { @@ -1699,9 +1699,9 @@ static void print_event_desc(struct feat_fd *ff, FILE *fp) for (evsel = events; evsel->core.attr.size; evsel++) { fprintf(fp, "# event : name = %s, ", evsel->name); - if (evsel->ids) { + if (evsel->core.ids) { fprintf(fp, ", id = {"); - for (j = 0, id = evsel->core.id; j < evsel->ids; j++, id++) { + for (j = 0, id = evsel->core.id; j < evsel->core.ids; j++, id++) { if (j) fputc(',', fp); fprintf(fp, " %"PRIu64, *id); @@ -3068,7 +3068,7 @@ int perf_session__write_header(struct perf_session *session, evlist__for_each_entry(session->evlist, evsel) { evsel->id_offset = lseek(fd, 0, SEEK_CUR); - err = do_write(&ff, evsel->core.id, evsel->ids * sizeof(u64)); + err = do_write(&ff, evsel->core.id, evsel->core.ids * sizeof(u64)); if (err < 0) { pr_debug("failed to write perf header\n"); return err; @@ -3082,7 +3082,7 @@ int perf_session__write_header(struct perf_session *session, .attr = evsel->core.attr, .ids = { .offset = evsel->id_offset, - .size = evsel->ids * sizeof(u64), + .size = evsel->core.ids * sizeof(u64), } }; err = do_write(&ff, &f_attr, sizeof(f_attr)); diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index c94360cd9c00..34cb380d19a3 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c @@ -768,7 +768,7 @@ static int intel_bts_synth_events(struct intel_bts *bts, int err; evlist__for_each_entry(evlist, evsel) { - if (evsel->core.attr.type == bts->pmu_type && evsel->ids) { + if (evsel->core.attr.type == bts->pmu_type && evsel->core.ids) { found = true; break; } diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 24ca5d5908ca..a1c9eb6d4f40 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -2735,7 +2735,7 @@ static struct evsel *intel_pt_evsel(struct intel_pt *pt, struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { - if (evsel->core.attr.type == pt->pmu_type && evsel->ids) + if (evsel->core.attr.type == pt->pmu_type && evsel->core.ids) return evsel; } diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index 907ac3971959..96ed008c2775 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -1413,7 +1413,7 @@ int perf_event__synthesize_id_index(struct perf_tool *tool, perf_event__handler_ sizeof(struct id_index_entry); evlist__for_each_entry(evlist, evsel) - nr += evsel->ids; + nr += evsel->core.ids; n = nr > max_nr ? max_nr : nr; sz = sizeof(struct perf_record_id_index) + n * sizeof(struct id_index_entry); @@ -1428,7 +1428,7 @@ int perf_event__synthesize_id_index(struct perf_tool *tool, perf_event__handler_ evlist__for_each_entry(evlist, evsel) { u32 j; - for (j = 0; j < evsel->ids; j++) { + for (j = 0; j < evsel->core.ids; j++) { struct id_index_entry *e; struct perf_sample_id *sid; @@ -1595,7 +1595,7 @@ int perf_event__synthesize_attrs(struct perf_tool *tool, struct evlist *evlist, int err = 0; evlist__for_each_entry(evlist, evsel) { - err = perf_event__synthesize_attr(tool, &evsel->core.attr, evsel->ids, + err = perf_event__synthesize_attr(tool, &evsel->core.attr, evsel->core.ids, evsel->core.id, process); if (err) { pr_debug("failed to create perf header attribute\n"); -- cgit v1.2.3-59-g8ed1b From 1d5af02d7a92acaa877ab0fbec0756114852720a Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 2 Sep 2019 22:20:12 +0200 Subject: libperf: Move 'heads' from 'struct evlist' to 'struct perf_evlist' Move 'heads' hash table from 'struct evlist' to 'struct perf_evlist'. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-27-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evlist.c | 4 ++++ tools/perf/lib/include/internal/evlist.h | 4 ++++ tools/perf/util/evlist.c | 10 +++------- tools/perf/util/evlist.h | 4 ---- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c index f4dc9a208332..2bdd9d2c79d9 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/perf/lib/evlist.c @@ -11,6 +11,10 @@ void perf_evlist__init(struct perf_evlist *evlist) { + int i; + + for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i) + INIT_HLIST_HEAD(&evlist->heads[i]); INIT_LIST_HEAD(&evlist->entries); evlist->nr_entries = 0; } diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h index 8a4eb66fbf3a..c5a06890fd6a 100644 --- a/tools/perf/lib/include/internal/evlist.h +++ b/tools/perf/lib/include/internal/evlist.h @@ -5,6 +5,9 @@ #include #include +#define PERF_EVLIST__HLIST_BITS 8 +#define PERF_EVLIST__HLIST_SIZE (1 << PERF_EVLIST__HLIST_BITS) + struct perf_cpu_map; struct perf_thread_map; @@ -17,6 +20,7 @@ struct perf_evlist { int nr_mmaps; size_t mmap_len; struct fdarray pollfd; + struct hlist_head heads[PERF_EVLIST__HLIST_SIZE]; }; /** diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 5e43fb9da359..c6af7c622612 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -55,10 +55,6 @@ int sigqueue(pid_t pid, int sig, const union sigval value); void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, struct perf_thread_map *threads) { - int i; - - for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i) - INIT_HLIST_HEAD(&evlist->heads[i]); perf_evlist__init(&evlist->core); perf_evlist__set_maps(&evlist->core, cpus, threads); fdarray__init(&evlist->core.pollfd, 64); @@ -475,7 +471,7 @@ static void perf_evlist__id_hash(struct evlist *evlist, sid->id = id; sid->evsel = evsel; hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS); - hlist_add_head(&sid->node, &evlist->heads[hash]); + hlist_add_head(&sid->node, &evlist->core.heads[hash]); } void perf_evlist__id_add(struct evlist *evlist, struct evsel *evsel, @@ -549,7 +545,7 @@ struct perf_sample_id *perf_evlist__id2sid(struct evlist *evlist, u64 id) int hash; hash = hash_64(id, PERF_EVLIST__HLIST_BITS); - head = &evlist->heads[hash]; + head = &evlist->core.heads[hash]; hlist_for_each_entry(sid, head, node) if (sid->id == id) @@ -635,7 +631,7 @@ struct evsel *perf_evlist__event2evsel(struct evlist *evlist, return first; hash = hash_64(id, PERF_EVLIST__HLIST_BITS); - head = &evlist->heads[hash]; + head = &evlist->core.heads[hash]; hlist_for_each_entry(sid, head, node) { if (sid->id == id) diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 4fcdf93eb19c..ad9c0ba57a91 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -48,12 +48,8 @@ enum bkw_mmap_state { BKW_MMAP_EMPTY, }; -#define PERF_EVLIST__HLIST_BITS 8 -#define PERF_EVLIST__HLIST_SIZE (1 << PERF_EVLIST__HLIST_BITS) - struct evlist { struct perf_evlist core; - struct hlist_head heads[PERF_EVLIST__HLIST_SIZE]; int nr_groups; bool enabled; int id_pos; -- cgit v1.2.3-59-g8ed1b From 70c20369ee95ef8b6887944194cfb74a5a8d1fe3 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 3 Sep 2019 10:34:29 +0200 Subject: libperf: Add perf_evsel__alloc_id/perf_evsel__free_id functions Add perf_evsel__alloc_id()/perf_evsel__free_id() functions to libperf as internal functions. Move 'struct perf_sample_id' to internal/evsel.h header and change 'struct perf_sample_id::evsel' to 'struct perf_evsel' and the related code that touches it. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-28-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evsel.c | 30 +++++++++++++++++++++++++++ tools/perf/lib/include/internal/evsel.h | 27 +++++++++++++++++++++++++ tools/perf/tests/event_update.c | 2 +- tools/perf/util/evlist.c | 10 ++++----- tools/perf/util/evsel.c | 36 +++------------------------------ tools/perf/util/evsel.h | 25 ----------------------- tools/perf/util/header.c | 4 ++-- tools/perf/util/session.c | 4 +++- 8 files changed, 71 insertions(+), 67 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/evsel.c b/tools/perf/lib/evsel.c index 24abc80dd767..a8cb582e2721 100644 --- a/tools/perf/lib/evsel.c +++ b/tools/perf/lib/evsel.c @@ -230,3 +230,33 @@ struct perf_event_attr *perf_evsel__attr(struct perf_evsel *evsel) { return &evsel->attr; } + +int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads) +{ + if (ncpus == 0 || nthreads == 0) + return 0; + + if (evsel->system_wide) + nthreads = 1; + + evsel->sample_id = xyarray__new(ncpus, nthreads, sizeof(struct perf_sample_id)); + if (evsel->sample_id == NULL) + return -ENOMEM; + + evsel->id = zalloc(ncpus * nthreads * sizeof(u64)); + if (evsel->id == NULL) { + xyarray__delete(evsel->sample_id); + evsel->sample_id = NULL; + return -ENOMEM; + } + + return 0; +} + +void perf_evsel__free_id(struct perf_evsel *evsel) +{ + xyarray__delete(evsel->sample_id); + evsel->sample_id = NULL; + zfree(&evsel->id); + evsel->ids = 0; +} diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h index 385766f06591..a69b8299c36f 100644 --- a/tools/perf/lib/include/internal/evsel.h +++ b/tools/perf/lib/include/internal/evsel.h @@ -5,11 +5,35 @@ #include #include #include +#include struct perf_cpu_map; struct perf_thread_map; struct xyarray; +/* + * Per fd, to map back from PERF_SAMPLE_ID to evsel, only used when there are + * more than one entry in the evlist. + */ +struct perf_sample_id { + struct hlist_node node; + u64 id; + struct perf_evsel *evsel; + /* + * 'idx' will be used for AUX area sampling. A sample will have AUX area + * data that will be queued for decoding, where there are separate + * queues for each CPU (per-cpu tracing) or task (per-thread tracing). + * The sample ID can be used to lookup 'idx' which is effectively the + * queue number. + */ + int idx; + int cpu; + pid_t tid; + + /* Holds total ID period value for PERF_SAMPLE_READ processing. */ + u64 period; +}; + struct perf_evsel { struct list_head node; struct perf_event_attr attr; @@ -32,4 +56,7 @@ void perf_evsel__free_fd(struct perf_evsel *evsel); int perf_evsel__read_size(struct perf_evsel *evsel); int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter); +int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads); +void perf_evsel__free_id(struct perf_evsel *evsel); + #endif /* __LIBPERF_INTERNAL_EVSEL_H */ diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index 0497d900ced2..cf4f90170f90 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -95,7 +95,7 @@ int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unu evsel = perf_evlist__first(evlist); TEST_ASSERT_VAL("failed to allocate ids", - !perf_evsel__alloc_id(evsel, 1, 1)); + !perf_evsel__alloc_id(&evsel->core, 1, 1)); perf_evlist__id_add(evlist, evsel, 0, 0, 123); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index c6af7c622612..559db38594a8 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -469,7 +469,7 @@ static void perf_evlist__id_hash(struct evlist *evlist, struct perf_sample_id *sid = SID(evsel, cpu, thread); sid->id = id; - sid->evsel = evsel; + sid->evsel = &evsel->core; hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS); hlist_add_head(&sid->node, &evlist->core.heads[hash]); } @@ -563,7 +563,7 @@ struct evsel *perf_evlist__id2evsel(struct evlist *evlist, u64 id) sid = perf_evlist__id2sid(evlist, id); if (sid) - return sid->evsel; + return container_of(sid->evsel, struct evsel, core); if (!perf_evlist__sample_id_all(evlist)) return perf_evlist__first(evlist); @@ -581,7 +581,7 @@ struct evsel *perf_evlist__id2evsel_strict(struct evlist *evlist, sid = perf_evlist__id2sid(evlist, id); if (sid) - return sid->evsel; + return container_of(sid->evsel, struct evsel, core); return NULL; } @@ -635,7 +635,7 @@ struct evsel *perf_evlist__event2evsel(struct evlist *evlist, hlist_for_each_entry(sid, head, node) { if (sid->id == id) - return sid->evsel; + return container_of(sid->evsel, struct evsel, core); } return NULL; } @@ -1018,7 +1018,7 @@ int evlist__mmap_ex(struct evlist *evlist, unsigned int pages, evlist__for_each_entry(evlist, evsel) { if ((evsel->core.attr.read_format & PERF_FORMAT_ID) && evsel->core.sample_id == NULL && - perf_evsel__alloc_id(evsel, perf_cpu_map__nr(cpus), threads->nr) < 0) + perf_evsel__alloc_id(&evsel->core, perf_cpu_map__nr(cpus), threads->nr) < 0) return -ENOMEM; } diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 55638eb9299c..a4a492f11849 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1227,36 +1227,6 @@ int evsel__disable(struct evsel *evsel) return err; } -int perf_evsel__alloc_id(struct evsel *evsel, int ncpus, int nthreads) -{ - if (ncpus == 0 || nthreads == 0) - return 0; - - if (evsel->core.system_wide) - nthreads = 1; - - evsel->core.sample_id = xyarray__new(ncpus, nthreads, sizeof(struct perf_sample_id)); - if (evsel->core.sample_id == NULL) - return -ENOMEM; - - evsel->core.id = zalloc(ncpus * nthreads * sizeof(u64)); - if (evsel->core.id == NULL) { - xyarray__delete(evsel->core.sample_id); - evsel->core.sample_id = NULL; - return -ENOMEM; - } - - return 0; -} - -static void perf_evsel__free_id(struct evsel *evsel) -{ - xyarray__delete(evsel->core.sample_id); - evsel->core.sample_id = NULL; - zfree(&evsel->core.id); - evsel->core.ids = 0; -} - static void perf_evsel__free_config_terms(struct evsel *evsel) { struct perf_evsel_config_term *term, *h; @@ -1273,7 +1243,7 @@ void perf_evsel__exit(struct evsel *evsel) assert(evsel->evlist == NULL); perf_evsel__free_counts(evsel); perf_evsel__free_fd(&evsel->core); - perf_evsel__free_id(evsel); + perf_evsel__free_id(&evsel->core); perf_evsel__free_config_terms(evsel); cgroup__put(evsel->cgrp); perf_cpu_map__put(evsel->core.cpus); @@ -1992,7 +1962,7 @@ out_close: void evsel__close(struct evsel *evsel) { perf_evsel__close(&evsel->core); - perf_evsel__free_id(evsel); + perf_evsel__free_id(&evsel->core); } int perf_evsel__open_per_cpu(struct evsel *evsel, @@ -2706,7 +2676,7 @@ int perf_evsel__store_ids(struct evsel *evsel, struct evlist *evlist) struct perf_cpu_map *cpus = evsel->core.cpus; struct perf_thread_map *threads = evsel->core.threads; - if (perf_evsel__alloc_id(evsel, cpus->nr, threads->nr)) + if (perf_evsel__alloc_id(&evsel->core, cpus->nr, threads->nr)) return -ENOMEM; return store_evsel_ids(evsel, evlist); diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index ed64395ec340..a5b29ac10da0 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -17,29 +17,6 @@ struct addr_location; struct evsel; union perf_event; -/* - * Per fd, to map back from PERF_SAMPLE_ID to evsel, only used when there are - * more than one entry in the evlist. - */ -struct perf_sample_id { - struct hlist_node node; - u64 id; - struct evsel *evsel; - /* - * 'idx' will be used for AUX area sampling. A sample will have AUX area - * data that will be queued for decoding, where there are separate - * queues for each CPU (per-cpu tracing) or task (per-thread tracing). - * The sample ID can be used to lookup 'idx' which is effectively the - * queue number. - */ - int idx; - int cpu; - pid_t tid; - - /* Holds total ID period value for PERF_SAMPLE_READ processing. */ - u64 period; -}; - struct cgroup; /* @@ -272,8 +249,6 @@ const char *perf_evsel__name(struct evsel *evsel); const char *perf_evsel__group_name(struct evsel *evsel); int perf_evsel__group_desc(struct evsel *evsel, char *buf, size_t size); -int perf_evsel__alloc_id(struct evsel *evsel, int ncpus, int nthreads); - void __perf_evsel__set_sample_bit(struct evsel *evsel, enum perf_event_sample_format bit); void __perf_evsel__reset_sample_bit(struct evsel *evsel, diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 498f6a825656..fc5eac41e102 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -3609,7 +3609,7 @@ int perf_session__read_header(struct perf_session *session) * for allocating the perf_sample_id table we fake 1 cpu and * hattr->ids threads. */ - if (perf_evsel__alloc_id(evsel, 1, nr_ids)) + if (perf_evsel__alloc_id(&evsel->core, 1, nr_ids)) goto out_delete_evlist; lseek(fd, f_attr.ids.offset, SEEK_SET); @@ -3750,7 +3750,7 @@ int perf_event__process_attr(struct perf_tool *tool __maybe_unused, * for allocating the perf_sample_id table we fake 1 cpu and * hattr->ids threads. */ - if (perf_evsel__alloc_id(evsel, 1, n_ids)) + if (perf_evsel__alloc_id(&evsel->core, 1, n_ids)) return -ENOMEM; for (i = 0; i < n_ids; i++) { diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index a621c73bad42..84a30ff3968a 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1324,6 +1324,7 @@ static int deliver_sample_value(struct evlist *evlist, struct machine *machine) { struct perf_sample_id *sid = perf_evlist__id2sid(evlist, v->id); + struct evsel *evsel; if (sid) { sample->id = v->id; @@ -1343,7 +1344,8 @@ static int deliver_sample_value(struct evlist *evlist, if (!sample->period) return 0; - return tool->sample(tool, event, sample, sid->evsel, machine); + evsel = container_of(sid->evsel, struct evsel, core); + return tool->sample(tool, event, sample, evsel, machine); } static int deliver_sample_group(struct evlist *evlist, -- cgit v1.2.3-59-g8ed1b From 515dbe48f6202147fb7c88aac48c43f49db1c793 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 3 Sep 2019 10:39:52 +0200 Subject: libperf: Add perf_evlist__first()/last() functions Add perf_evlist__first()/last() functions to libperf, as internal functions and rename perf's origins to evlist__first/last. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-29-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 2 +- tools/perf/arch/arm64/util/arm-spe.c | 2 +- tools/perf/arch/x86/tests/intel-cqm.c | 4 +- tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +- tools/perf/arch/x86/util/intel-bts.c | 2 +- tools/perf/arch/x86/util/intel-pt.c | 6 +- tools/perf/builtin-record.c | 4 +- tools/perf/builtin-script.c | 2 +- tools/perf/builtin-top.c | 10 +-- tools/perf/builtin-trace.c | 2 +- tools/perf/lib/include/internal/evlist.h | 11 +++ tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/event-times.c | 14 ++-- tools/perf/tests/event_update.c | 2 +- tools/perf/tests/evsel-roundtrip-name.c | 2 +- tools/perf/tests/hists_cumulate.c | 2 +- tools/perf/tests/hists_link.c | 4 +- tools/perf/tests/hists_output.c | 2 +- tools/perf/tests/keep-tracking.c | 4 +- tools/perf/tests/parse-events.c | 116 +++++++++++++-------------- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/switch-tracking.c | 14 ++-- tools/perf/tests/task-exit.c | 2 +- tools/perf/ui/browsers/hists.c | 6 +- tools/perf/util/bpf-loader.c | 2 +- tools/perf/util/evlist.c | 24 +++--- tools/perf/util/evlist.h | 13 ++- tools/perf/util/jitdump.c | 2 +- tools/perf/util/parse-events.c | 4 +- tools/perf/util/record.c | 6 +- tools/perf/util/sort.c | 2 +- tools/perf/util/top.c | 2 +- 32 files changed, 145 insertions(+), 129 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 051e9066fb38..6654bcfc1224 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -416,7 +416,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, if (err) goto out; - tracking_evsel = perf_evlist__last(evlist); + tracking_evsel = evlist__last(evlist); perf_evlist__set_tracking_event(evlist, tracking_evsel); tracking_evsel->core.attr.freq = 0; diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index 9302c6566f53..745f2d50ee82 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -129,7 +129,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr, if (err) return err; - tracking_evsel = perf_evlist__last(evlist); + tracking_evsel = evlist__last(evlist); perf_evlist__set_tracking_event(evlist, tracking_evsel); tracking_evsel->core.attr.freq = 0; diff --git a/tools/perf/arch/x86/tests/intel-cqm.c b/tools/perf/arch/x86/tests/intel-cqm.c index 111c0ab2e7b5..0329b9168fae 100644 --- a/tools/perf/arch/x86/tests/intel-cqm.c +++ b/tools/perf/arch/x86/tests/intel-cqm.c @@ -62,9 +62,9 @@ int test__intel_cqm_count_nmi_context(struct test *test __maybe_unused, int subt goto out; } - evsel = perf_evlist__first(evlist); + evsel = evlist__first(evlist); if (!evsel) { - pr_debug("perf_evlist__first failed\n"); + pr_debug("evlist__first failed\n"); goto out; } diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index 10b7acebc0eb..fa947952c16a 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -83,7 +83,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe perf_evlist__config(evlist, &opts, NULL); - evsel = perf_evlist__first(evlist); + evsel = evlist__first(evlist); evsel->core.attr.comm = 1; evsel->core.attr.disabled = 1; diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index e81535c8e9c5..e2c7095327db 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -231,7 +231,7 @@ static int intel_bts_recording_options(struct auxtrace_record *itr, if (err) return err; - tracking_evsel = perf_evlist__last(evlist); + tracking_evsel = evlist__last(evlist); perf_evlist__set_tracking_event(evlist, tracking_evsel); diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 886b3ac60f23..84a65524c418 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -417,7 +417,7 @@ static int intel_pt_track_switches(struct evlist *evlist) return err; } - evsel = perf_evlist__last(evlist); + evsel = evlist__last(evlist); perf_evsel__set_sample_bit(evsel, CPU); perf_evsel__set_sample_bit(evsel, TIME); @@ -717,7 +717,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, if (err) return err; - switch_evsel = perf_evlist__last(evlist); + switch_evsel = evlist__last(evlist); switch_evsel->core.attr.freq = 0; switch_evsel->core.attr.sample_period = 1; @@ -775,7 +775,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, if (err) return err; - tracking_evsel = perf_evlist__last(evlist); + tracking_evsel = evlist__last(evlist); perf_evlist__set_tracking_event(evlist, tracking_evsel); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 94997144547d..48600c90cc7e 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -756,9 +756,9 @@ static int record__open(struct record *rec) if (perf_evlist__add_dummy(evlist)) return -ENOMEM; - pos = perf_evlist__first(evlist); + pos = evlist__first(evlist); pos->tracking = 0; - pos = perf_evlist__last(evlist); + pos = evlist__last(evlist); pos->tracking = 1; pos->core.attr.enable_on_exec = 1; } diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index e7a49e2d7575..22c1d114014c 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -2043,7 +2043,7 @@ static int process_attr(struct perf_tool *tool, union perf_event *event, return err; evlist = *pevlist; - evsel = perf_evlist__last(*pevlist); + evsel = evlist__last(*pevlist); if (!evsel->priv) { if (scr->per_event_dump) { diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 474b9860cfd4..73bf79053ae3 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -531,7 +531,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c) prompt_integer(&counter, "Enter details event counter"); if (counter >= top->evlist->core.nr_entries) { - top->sym_evsel = perf_evlist__first(top->evlist); + top->sym_evsel = evlist__first(top->evlist); fprintf(stderr, "Sorry, no such event, using %s.\n", perf_evsel__name(top->sym_evsel)); sleep(1); break; @@ -540,7 +540,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c) if (top->sym_evsel->idx == counter) break; } else - top->sym_evsel = perf_evlist__first(top->evlist); + top->sym_evsel = evlist__first(top->evlist); break; case 'f': prompt_integer(&top->count_filter, "Enter display event count filter"); @@ -962,7 +962,7 @@ static int perf_top__overwrite_check(struct perf_top *top) /* has term for current event */ if ((overwrite < 0) && (set >= 0)) { /* if it's first event, set overwrite */ - if (evsel == perf_evlist__first(evlist)) + if (evsel == evlist__first(evlist)) overwrite = set; else return -1; @@ -986,7 +986,7 @@ static int perf_top_overwrite_fallback(struct perf_top *top, return 0; /* only fall back when first event fails */ - if (evsel != perf_evlist__first(evlist)) + if (evsel != evlist__first(evlist)) return 0; evlist__for_each_entry(evlist, counter) @@ -1644,7 +1644,7 @@ int cmd_top(int argc, const char **argv) goto out_delete_evlist; } - top.sym_evsel = perf_evlist__first(top.evlist); + top.sym_evsel = evlist__first(top.evlist); if (!callchain_param.enabled) { symbol_conf.cumulate_callchain = false; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 91c73c7472ba..97667287f573 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3427,7 +3427,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) trace->multiple_threads = perf_thread_map__pid(evlist->core.threads, 0) == -1 || evlist->core.threads->nr > 1 || - perf_evlist__first(evlist)->core.attr.inherit; + evlist__first(evlist)->core.attr.inherit; /* * Now that we already used evsel->core.attr to ask the kernel to setup the diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h index c5a06890fd6a..16ae6d6cfb39 100644 --- a/tools/perf/lib/include/internal/evlist.h +++ b/tools/perf/lib/include/internal/evlist.h @@ -4,6 +4,7 @@ #include #include +#include #define PERF_EVLIST__HLIST_BITS 8 #define PERF_EVLIST__HLIST_SIZE (1 << PERF_EVLIST__HLIST_BITS) @@ -55,4 +56,14 @@ struct perf_evlist { #define perf_evlist__for_each_entry_reverse(evlist, evsel) \ __perf_evlist__for_each_entry_reverse(&(evlist)->entries, evsel) +static inline struct perf_evsel *perf_evlist__first(struct perf_evlist *evlist) +{ + return list_entry(evlist->entries.next, struct perf_evsel, node); +} + +static inline struct perf_evsel *perf_evlist__last(struct perf_evlist *evlist) +{ + return list_entry(evlist->entries.prev, struct perf_evsel, node); +} + #endif /* __LIBPERF_INTERNAL_EVLIST_H */ diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 7dac69a375f9..f5764a3890b9 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -652,7 +652,7 @@ static int do_test_code_reading(bool try_kcore) perf_evlist__config(evlist, &opts, NULL); - evsel = perf_evlist__first(evlist); + evsel = evlist__first(evlist); evsel->core.attr.comm = 1; evsel->core.attr.disabled = 1; diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 0228ba435a2a..1ee8704e2284 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -16,7 +16,7 @@ static int attach__enable_on_exec(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__last(evlist); + struct evsel *evsel = evlist__last(evlist); struct target target = { .uid = UINT_MAX, }; @@ -58,7 +58,7 @@ static int detach__enable_on_exec(struct evlist *evlist) static int attach__current_disabled(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__last(evlist); + struct evsel *evsel = evlist__last(evlist); struct perf_thread_map *threads; int err; @@ -84,7 +84,7 @@ static int attach__current_disabled(struct evlist *evlist) static int attach__current_enabled(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__last(evlist); + struct evsel *evsel = evlist__last(evlist); struct perf_thread_map *threads; int err; @@ -104,14 +104,14 @@ static int attach__current_enabled(struct evlist *evlist) static int detach__disable(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__last(evlist); + struct evsel *evsel = evlist__last(evlist); return evsel__enable(evsel); } static int attach__cpu_disabled(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__last(evlist); + struct evsel *evsel = evlist__last(evlist); struct perf_cpu_map *cpus; int err; @@ -140,7 +140,7 @@ static int attach__cpu_disabled(struct evlist *evlist) static int attach__cpu_enabled(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__last(evlist); + struct evsel *evsel = evlist__last(evlist); struct perf_cpu_map *cpus; int err; @@ -180,7 +180,7 @@ static int test_times(int (attach)(struct evlist *), goto out_err; } - evsel = perf_evlist__last(evlist); + evsel = evlist__last(evlist); evsel->core.attr.read_format |= PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING; diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index cf4f90170f90..cd6cae8e5137 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -92,7 +92,7 @@ int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unu evlist = perf_evlist__new_default(); TEST_ASSERT_VAL("failed to get evlist", evlist); - evsel = perf_evlist__first(evlist); + evsel = evlist__first(evlist); TEST_ASSERT_VAL("failed to allocate ids", !perf_evsel__alloc_id(&evsel->core, 1, 1)); diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c index 5330f106a6ee..956205bf9326 100644 --- a/tools/perf/tests/evsel-roundtrip-name.c +++ b/tools/perf/tests/evsel-roundtrip-name.c @@ -34,7 +34,7 @@ static int perf_evsel__roundtrip_cache_name_test(void) } idx = 0; - evsel = perf_evlist__first(evlist); + evsel = evlist__first(evlist); for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index fa55b7bad3af..6367c8f6ca22 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -721,7 +721,7 @@ int test__hists_cumulate(struct test *test __maybe_unused, int subtest __maybe_u if (verbose > 1) machine__fprintf(machine, stderr); - evsel = perf_evlist__first(evlist); + evsel = evlist__first(evlist); for (i = 0; i < ARRAY_SIZE(testcases); i++) { err = testcases[i](evsel, machine); diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index 1a3bdc0a2d14..a024d3f3a412 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -311,8 +311,8 @@ int test__hists_link(struct test *test __maybe_unused, int subtest __maybe_unuse print_hists_in(hists); } - first = perf_evlist__first(evlist); - evsel = perf_evlist__last(evlist); + first = evlist__first(evlist); + evsel = evlist__last(evlist); first_hists = evsel__hists(first); hists = evsel__hists(evsel); diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index 3f6dfa212260..38f804ff6452 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -608,7 +608,7 @@ int test__hists_output(struct test *test __maybe_unused, int subtest __maybe_unu if (verbose > 1) machine__fprintf(machine, stderr); - evsel = perf_evlist__first(evlist); + evsel = evlist__first(evlist); for (i = 0; i < ARRAY_SIZE(testcases); i++) { err = testcases[i](evsel, machine); diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index bd4ae8e5cd5d..92c7d591bcac 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -93,7 +93,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un perf_evlist__config(evlist, &opts, NULL); - evsel = perf_evlist__first(evlist); + evsel = evlist__first(evlist); evsel->core.attr.comm = 1; evsel->core.attr.disabled = 1; @@ -132,7 +132,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un evlist__enable(evlist); - evsel = perf_evlist__last(evlist); + evsel = evlist__last(evlist); CHECK__(evsel__disable(evsel)); diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index c25c8e7b41e5..25e0ed2eedfc 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -46,7 +46,7 @@ static bool kvm_s390_create_vm_valid(void) static int test__checkevent_tracepoint(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong number of groups", 0 == evlist->nr_groups); @@ -77,7 +77,7 @@ static int test__checkevent_tracepoint_multi(struct evlist *evlist) static int test__checkevent_raw(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type); @@ -87,7 +87,7 @@ static int test__checkevent_raw(struct evlist *evlist) static int test__checkevent_numeric(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", 1 == evsel->core.attr.type); @@ -97,7 +97,7 @@ static int test__checkevent_numeric(struct evlist *evlist) static int test__checkevent_symbolic_name(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); @@ -108,7 +108,7 @@ static int test__checkevent_symbolic_name(struct evlist *evlist) static int test__checkevent_symbolic_name_config(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); @@ -129,7 +129,7 @@ static int test__checkevent_symbolic_name_config(struct evlist *evlist) static int test__checkevent_symbolic_alias(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->core.attr.type); @@ -140,7 +140,7 @@ static int test__checkevent_symbolic_alias(struct evlist *evlist) static int test__checkevent_genhw(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->core.attr.type); @@ -150,7 +150,7 @@ static int test__checkevent_genhw(struct evlist *evlist) static int test__checkevent_breakpoint(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->core.attr.type); @@ -164,7 +164,7 @@ static int test__checkevent_breakpoint(struct evlist *evlist) static int test__checkevent_breakpoint_x(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->core.attr.type); @@ -177,7 +177,7 @@ static int test__checkevent_breakpoint_x(struct evlist *evlist) static int test__checkevent_breakpoint_r(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", @@ -192,7 +192,7 @@ static int test__checkevent_breakpoint_r(struct evlist *evlist) static int test__checkevent_breakpoint_w(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", @@ -207,7 +207,7 @@ static int test__checkevent_breakpoint_w(struct evlist *evlist) static int test__checkevent_breakpoint_rw(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", @@ -222,7 +222,7 @@ static int test__checkevent_breakpoint_rw(struct evlist *evlist) static int test__checkevent_tracepoint_modifier(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); @@ -253,7 +253,7 @@ test__checkevent_tracepoint_multi_modifier(struct evlist *evlist) static int test__checkevent_raw_modifier(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); @@ -265,7 +265,7 @@ static int test__checkevent_raw_modifier(struct evlist *evlist) static int test__checkevent_numeric_modifier(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); @@ -277,7 +277,7 @@ static int test__checkevent_numeric_modifier(struct evlist *evlist) static int test__checkevent_symbolic_name_modifier(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); @@ -289,7 +289,7 @@ static int test__checkevent_symbolic_name_modifier(struct evlist *evlist) static int test__checkevent_exclude_host_modifier(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host); @@ -299,7 +299,7 @@ static int test__checkevent_exclude_host_modifier(struct evlist *evlist) static int test__checkevent_exclude_guest_modifier(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest); TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host); @@ -309,7 +309,7 @@ static int test__checkevent_exclude_guest_modifier(struct evlist *evlist) static int test__checkevent_symbolic_alias_modifier(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); @@ -321,7 +321,7 @@ static int test__checkevent_symbolic_alias_modifier(struct evlist *evlist) static int test__checkevent_genhw_modifier(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); @@ -333,7 +333,7 @@ static int test__checkevent_genhw_modifier(struct evlist *evlist) static int test__checkevent_exclude_idle_modifier(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude idle", evsel->core.attr.exclude_idle); TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); @@ -348,7 +348,7 @@ static int test__checkevent_exclude_idle_modifier(struct evlist *evlist) static int test__checkevent_exclude_idle_modifier_1(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude idle", evsel->core.attr.exclude_idle); TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest); @@ -363,7 +363,7 @@ static int test__checkevent_exclude_idle_modifier_1(struct evlist *evlist) static int test__checkevent_breakpoint_modifier(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); @@ -378,7 +378,7 @@ static int test__checkevent_breakpoint_modifier(struct evlist *evlist) static int test__checkevent_breakpoint_x_modifier(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); @@ -392,7 +392,7 @@ static int test__checkevent_breakpoint_x_modifier(struct evlist *evlist) static int test__checkevent_breakpoint_r_modifier(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); @@ -406,7 +406,7 @@ static int test__checkevent_breakpoint_r_modifier(struct evlist *evlist) static int test__checkevent_breakpoint_w_modifier(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); @@ -420,7 +420,7 @@ static int test__checkevent_breakpoint_w_modifier(struct evlist *evlist) static int test__checkevent_breakpoint_rw_modifier(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel); @@ -435,7 +435,7 @@ static int test__checkevent_breakpoint_rw_modifier(struct evlist *evlist) static int test__checkevent_pmu(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type); @@ -453,7 +453,7 @@ static int test__checkevent_pmu(struct evlist *evlist) static int test__checkevent_list(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->core.nr_entries); @@ -492,7 +492,7 @@ static int test__checkevent_list(struct evlist *evlist) static int test__checkevent_pmu_name(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); /* cpu/config=1,name=krava/u */ TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); @@ -513,7 +513,7 @@ static int test__checkevent_pmu_name(struct evlist *evlist) static int test__checkevent_pmu_partial_time_callgraph(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); /* cpu/config=1,call-graph=fp,time,period=100000/ */ TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); @@ -546,7 +546,7 @@ static int test__checkevent_pmu_partial_time_callgraph(struct evlist *evlist) static int test__checkevent_pmu_events(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type); @@ -564,7 +564,7 @@ static int test__checkevent_pmu_events(struct evlist *evlist) static int test__checkevent_pmu_events_mix(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); /* pmu-event:u */ TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); @@ -642,7 +642,7 @@ static int test__group1(struct evlist *evlist) TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); /* instructions:k */ - evsel = leader = perf_evlist__first(evlist); + evsel = leader = evlist__first(evlist); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", PERF_COUNT_HW_INSTRUCTIONS == evsel->core.attr.config); @@ -684,7 +684,7 @@ static int test__group2(struct evlist *evlist) TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); /* faults + :ku modifier */ - evsel = leader = perf_evlist__first(evlist); + evsel = leader = evlist__first(evlist); TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", PERF_COUNT_SW_PAGE_FAULTS == evsel->core.attr.config); @@ -739,7 +739,7 @@ static int test__group3(struct evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong number of groups", 2 == evlist->nr_groups); /* group1 syscalls:sys_enter_openat:H */ - evsel = leader = perf_evlist__first(evlist); + evsel = leader = evlist__first(evlist); TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->core.attr.type); TEST_ASSERT_VAL("wrong sample_type", PERF_TP_SAMPLE_TYPE == evsel->core.attr.sample_type); @@ -831,7 +831,7 @@ static int test__group4(struct evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); /* cycles:u + p */ - evsel = leader = perf_evlist__first(evlist); + evsel = leader = evlist__first(evlist); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); @@ -875,7 +875,7 @@ static int test__group5(struct evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong number of groups", 2 == evlist->nr_groups); /* cycles + G */ - evsel = leader = perf_evlist__first(evlist); + evsel = leader = evlist__first(evlist); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); @@ -961,7 +961,7 @@ static int test__group_gh1(struct evlist *evlist) TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); /* cycles + :H group modifier */ - evsel = leader = perf_evlist__first(evlist); + evsel = leader = evlist__first(evlist); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); @@ -1001,7 +1001,7 @@ static int test__group_gh2(struct evlist *evlist) TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); /* cycles + :G group modifier */ - evsel = leader = perf_evlist__first(evlist); + evsel = leader = evlist__first(evlist); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); @@ -1041,7 +1041,7 @@ static int test__group_gh3(struct evlist *evlist) TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); /* cycles:G + :u group modifier */ - evsel = leader = perf_evlist__first(evlist); + evsel = leader = evlist__first(evlist); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); @@ -1081,7 +1081,7 @@ static int test__group_gh4(struct evlist *evlist) TEST_ASSERT_VAL("wrong number of groups", 1 == evlist->nr_groups); /* cycles:G + :uG group modifier */ - evsel = leader = perf_evlist__first(evlist); + evsel = leader = evlist__first(evlist); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); @@ -1120,7 +1120,7 @@ static int test__leader_sample1(struct evlist *evlist) TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->core.nr_entries); /* cycles - sampling group leader */ - evsel = leader = perf_evlist__first(evlist); + evsel = leader = evlist__first(evlist); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); @@ -1173,7 +1173,7 @@ static int test__leader_sample2(struct evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); /* instructions - sampling group leader */ - evsel = leader = perf_evlist__first(evlist); + evsel = leader = evlist__first(evlist); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", PERF_COUNT_HW_INSTRUCTIONS == evsel->core.attr.config); @@ -1207,7 +1207,7 @@ static int test__leader_sample2(struct evlist *evlist __maybe_unused) static int test__checkevent_pinned_modifier(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); @@ -1225,7 +1225,7 @@ static int test__pinned_group(struct evlist *evlist) TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->core.nr_entries); /* cycles - group leader */ - evsel = leader = perf_evlist__first(evlist); + evsel = leader = evlist__first(evlist); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config); @@ -1251,7 +1251,7 @@ static int test__pinned_group(struct evlist *evlist) static int test__checkevent_breakpoint_len(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->core.attr.type); @@ -1266,7 +1266,7 @@ static int test__checkevent_breakpoint_len(struct evlist *evlist) static int test__checkevent_breakpoint_len_w(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->core.attr.type); @@ -1282,7 +1282,7 @@ static int test__checkevent_breakpoint_len_w(struct evlist *evlist) static int test__checkevent_breakpoint_len_rw_modifier(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel); @@ -1294,7 +1294,7 @@ test__checkevent_breakpoint_len_rw_modifier(struct evlist *evlist) static int test__checkevent_precise_max_modifier(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->core.attr.type); @@ -1305,7 +1305,7 @@ static int test__checkevent_precise_max_modifier(struct evlist *evlist) static int test__checkevent_config_symbol(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong name setting", strcmp(evsel->name, "insn") == 0); return 0; @@ -1313,7 +1313,7 @@ static int test__checkevent_config_symbol(struct evlist *evlist) static int test__checkevent_config_raw(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong name setting", strcmp(evsel->name, "rawpmu") == 0); return 0; @@ -1321,7 +1321,7 @@ static int test__checkevent_config_raw(struct evlist *evlist) static int test__checkevent_config_num(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong name setting", strcmp(evsel->name, "numpmu") == 0); return 0; @@ -1329,7 +1329,7 @@ static int test__checkevent_config_num(struct evlist *evlist) static int test__checkevent_config_cache(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong name setting", strcmp(evsel->name, "cachepmu") == 0); return 0; @@ -1342,7 +1342,7 @@ static bool test__intel_pt_valid(void) static int test__intel_pt(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong name setting", strcmp(evsel->name, "intel_pt//u") == 0); return 0; @@ -1350,7 +1350,7 @@ static int test__intel_pt(struct evlist *evlist) static int test__checkevent_complex_name(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong complex name parsing", strcmp(evsel->name, "COMPLEX_CYCLES_NAME:orig=cycles,desc=chip-clock-ticks") == 0); return 0; @@ -1358,7 +1358,7 @@ static int test__checkevent_complex_name(struct evlist *evlist) static int test__sym_event_slash(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong type", evsel->core.attr.type == PERF_TYPE_HARDWARE); TEST_ASSERT_VAL("wrong config", evsel->core.attr.config == PERF_COUNT_HW_CPU_CYCLES); @@ -1368,7 +1368,7 @@ static int test__sym_event_slash(struct evlist *evlist) static int test__sym_event_dc(struct evlist *evlist) { - struct evsel *evsel = perf_evlist__first(evlist); + struct evsel *evsel = evlist__first(evlist); TEST_ASSERT_VAL("wrong type", evsel->core.attr.type == PERF_TYPE_HARDWARE); TEST_ASSERT_VAL("wrong config", evsel->core.attr.config == PERF_COUNT_HW_CPU_CYCLES); diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 199a66444e60..401e8d11427b 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -104,7 +104,7 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus /* * Config the evsels, setting attr->comm on the first one, etc. */ - evsel = perf_evlist__first(evlist); + evsel = evlist__first(evlist); perf_evsel__set_sample_bit(evsel, CPU); perf_evsel__set_sample_bit(evsel, TID); perf_evsel__set_sample_bit(evsel, TIME); diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 30a70db6473d..ffa592e0020e 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -367,7 +367,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ goto out_err; } - cpu_clocks_evsel = perf_evlist__last(evlist); + cpu_clocks_evsel = evlist__last(evlist); /* Second event */ err = parse_events(evlist, "cycles:u", NULL); @@ -376,7 +376,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ goto out_err; } - cycles_evsel = perf_evlist__last(evlist); + cycles_evsel = evlist__last(evlist); /* Third event */ if (!perf_evlist__can_select_event(evlist, sched_switch)) { @@ -391,7 +391,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ goto out_err; } - switch_evsel = perf_evlist__last(evlist); + switch_evsel = evlist__last(evlist); perf_evsel__set_sample_bit(switch_evsel, CPU); perf_evsel__set_sample_bit(switch_evsel, TIME); @@ -401,12 +401,12 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ switch_evsel->immediate = true; /* Test moving an event to the front */ - if (cycles_evsel == perf_evlist__first(evlist)) { + if (cycles_evsel == evlist__first(evlist)) { pr_debug("cycles event already at front"); goto out_err; } perf_evlist__to_front(evlist, cycles_evsel); - if (cycles_evsel != perf_evlist__first(evlist)) { + if (cycles_evsel != evlist__first(evlist)) { pr_debug("Failed to move cycles event to front"); goto out_err; } @@ -421,7 +421,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ goto out_err; } - tracking_evsel = perf_evlist__last(evlist); + tracking_evsel = evlist__last(evlist); perf_evlist__set_tracking_event(evlist, tracking_evsel); @@ -434,7 +434,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_ perf_evlist__config(evlist, &opts, NULL); /* Check moved event is still at the front */ - if (cycles_evsel != perf_evlist__first(evlist)) { + if (cycles_evsel != evlist__first(evlist)) { pr_debug("Front event no longer at front"); goto out_err; } diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 7fc39af48a76..24565f83e07d 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -88,7 +88,7 @@ int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused goto out_delete_evlist; } - evsel = perf_evlist__first(evlist); + evsel = evlist__first(evlist); evsel->core.attr.task = 1; #ifdef __s390x__ evsel->core.attr.sample_freq = 1000000; diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 589168ca9f62..7a7187e069b4 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -3319,13 +3319,13 @@ browse_hists: switch (key) { case K_TAB: if (pos->core.node.next == &evlist->core.entries) - pos = perf_evlist__first(evlist); + pos = evlist__first(evlist); else pos = perf_evsel__next(pos); goto browse_hists; case K_UNTAB: if (pos->core.node.prev == &evlist->core.entries) - pos = perf_evlist__last(evlist); + pos = evlist__last(evlist); else pos = perf_evsel__prev(pos); goto browse_hists; @@ -3417,7 +3417,7 @@ int perf_evlist__tui_browse_hists(struct evlist *evlist, const char *help, single_entry: if (nr_entries == 1) { - struct evsel *first = perf_evlist__first(evlist); + struct evsel *first = evlist__first(evlist); return perf_evsel__hists_browse(first, nr_entries, help, false, hbt, min_pcnt, diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index 37283e865352..10c187b8b8ea 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -1568,7 +1568,7 @@ struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name) return ERR_PTR(-err); } - evsel = perf_evlist__last(evlist); + evsel = evlist__last(evlist); } bpf__for_each_map_named(map, obj, tmp, name) { diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 559db38594a8..e8f0357b1532 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -105,7 +105,7 @@ struct evlist *perf_evlist__new_dummy(void) */ void perf_evlist__set_id_pos(struct evlist *evlist) { - struct evsel *first = perf_evlist__first(evlist); + struct evsel *first = evlist__first(evlist); evlist->id_pos = first->id_pos; evlist->is_pos = first->is_pos; @@ -559,14 +559,14 @@ struct evsel *perf_evlist__id2evsel(struct evlist *evlist, u64 id) struct perf_sample_id *sid; if (evlist->core.nr_entries == 1 || !id) - return perf_evlist__first(evlist); + return evlist__first(evlist); sid = perf_evlist__id2sid(evlist, id); if (sid) return container_of(sid->evsel, struct evsel, core); if (!perf_evlist__sample_id_all(evlist)) - return perf_evlist__first(evlist); + return evlist__first(evlist); return NULL; } @@ -610,7 +610,7 @@ static int perf_evlist__event2id(struct evlist *evlist, struct evsel *perf_evlist__event2evsel(struct evlist *evlist, union perf_event *event) { - struct evsel *first = perf_evlist__first(evlist); + struct evsel *first = evlist__first(evlist); struct hlist_head *head; struct perf_sample_id *sid; int hash; @@ -1222,7 +1222,7 @@ u64 perf_evlist__combined_branch_type(struct evlist *evlist) bool perf_evlist__valid_read_format(struct evlist *evlist) { - struct evsel *first = perf_evlist__first(evlist), *pos = first; + struct evsel *first = evlist__first(evlist), *pos = first; u64 read_format = first->core.attr.read_format; u64 sample_type = first->core.attr.sample_type; @@ -1242,13 +1242,13 @@ bool perf_evlist__valid_read_format(struct evlist *evlist) u64 perf_evlist__read_format(struct evlist *evlist) { - struct evsel *first = perf_evlist__first(evlist); + struct evsel *first = evlist__first(evlist); return first->core.attr.read_format; } u16 perf_evlist__id_hdr_size(struct evlist *evlist) { - struct evsel *first = perf_evlist__first(evlist); + struct evsel *first = evlist__first(evlist); struct perf_sample *data; u64 sample_type; u16 size = 0; @@ -1281,7 +1281,7 @@ out: bool perf_evlist__valid_sample_id_all(struct evlist *evlist) { - struct evsel *first = perf_evlist__first(evlist), *pos = first; + struct evsel *first = evlist__first(evlist), *pos = first; evlist__for_each_entry_continue(evlist, pos) { if (first->core.attr.sample_id_all != pos->core.attr.sample_id_all) @@ -1293,7 +1293,7 @@ bool perf_evlist__valid_sample_id_all(struct evlist *evlist) bool perf_evlist__sample_id_all(struct evlist *evlist) { - struct evsel *first = perf_evlist__first(evlist); + struct evsel *first = evlist__first(evlist); return first->core.attr.sample_id_all; } @@ -1568,7 +1568,7 @@ int perf_evlist__strerror_open(struct evlist *evlist, "Hint:\tThe current value is %d.", value); break; case EINVAL: { - struct evsel *first = perf_evlist__first(evlist); + struct evsel *first = evlist__first(evlist); int max_freq; if (sysctl__read_int("kernel/perf_event_max_sample_rate", &max_freq) < 0) @@ -1630,7 +1630,7 @@ void perf_evlist__to_front(struct evlist *evlist, struct evsel *evsel, *n; LIST_HEAD(move); - if (move_evsel == perf_evlist__first(evlist)) + if (move_evsel == evlist__first(evlist)) return; evlist__for_each_entry_safe(evlist, n, evsel) { @@ -1751,7 +1751,7 @@ bool perf_evlist__exclude_kernel(struct evlist *evlist) void perf_evlist__force_leader(struct evlist *evlist) { if (!evlist->nr_groups) { - struct evsel *leader = perf_evlist__first(evlist); + struct evsel *leader = evlist__first(evlist); perf_evlist__set_leader(evlist); leader->forced_leader = true; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index ad9c0ba57a91..6529ad2a9d97 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "events_stats.h" #include "evsel.h" #include @@ -242,14 +243,18 @@ static inline bool perf_evlist__empty(struct evlist *evlist) return list_empty(&evlist->core.entries); } -static inline struct evsel *perf_evlist__first(struct evlist *evlist) +static inline struct evsel *evlist__first(struct evlist *evlist) { - return list_entry(evlist->core.entries.next, struct evsel, core.node); + struct perf_evsel *evsel = perf_evlist__first(&evlist->core); + + return container_of(evsel, struct evsel, core); } -static inline struct evsel *perf_evlist__last(struct evlist *evlist) +static inline struct evsel *evlist__last(struct evlist *evlist) { - return list_entry(evlist->core.entries.prev, struct evsel, core.node); + struct perf_evsel *evsel = perf_evlist__last(&evlist->core); + + return container_of(evsel, struct evsel, core); } size_t perf_evlist__fprintf(struct evlist *evlist, FILE *fp); diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c index 9f9c6c6a2fd3..1bdf4c6ea3e5 100644 --- a/tools/perf/util/jitdump.c +++ b/tools/perf/util/jitdump.c @@ -777,7 +777,7 @@ jit_process(struct perf_session *session, * track sample_type to compute id_all layout * perf sets the same sample type to all events as of now */ - first = perf_evlist__first(session->evlist); + first = evlist__first(session->evlist); jd.sample_type = first->core.attr.sample_type; *nbytes = 0; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index d7aebe9b005d..d69ff746cda5 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1936,7 +1936,7 @@ int parse_events(struct evlist *evlist, const char *str, perf_evlist__splice_list_tail(evlist, &parse_state.list); evlist->nr_groups += parse_state.nr_groups; - last = perf_evlist__last(evlist); + last = evlist__last(evlist); last->cmdline_group_boundary = true; return 0; @@ -2050,7 +2050,7 @@ foreach_evsel_in_last_glob(struct evlist *evlist, * So no need to WARN here, let *func do this. */ if (evlist->core.nr_entries > 0) - last = perf_evlist__last(evlist); + last = evlist__last(evlist); do { err = (*func)(last, arg); diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 8a015fc0aba0..8579505c29a4 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -30,7 +30,7 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str) if (parse_events(evlist, str, NULL)) goto out_delete; - evsel = perf_evlist__first(evlist); + evsel = evlist__first(evlist); while (1) { fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, flags); @@ -171,7 +171,7 @@ void perf_evlist__config(struct evlist *evlist, struct record_opts *opts, use_sample_identifier = perf_can_sample_identifier(); sample_id = true; } else if (evlist->core.nr_entries > 1) { - struct evsel *first = perf_evlist__first(evlist); + struct evsel *first = evlist__first(evlist); evlist__for_each_entry(evlist, evsel) { if (evsel->core.attr.sample_type == first->core.attr.sample_type) @@ -276,7 +276,7 @@ bool perf_evlist__can_select_event(struct evlist *evlist, const char *str) if (err) goto out_delete; - evsel = perf_evlist__last(temp_evlist); + evsel = evlist__last(temp_evlist); if (!evlist || perf_cpu_map__empty(evlist->core.cpus)) { struct perf_cpu_map *cpus = perf_cpu_map__new(NULL); diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index a2308eb77681..43d1d410854a 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -2329,7 +2329,7 @@ static struct evsel *find_evsel(struct evlist *evlist, char *event_name) if (nr > evlist->core.nr_entries) return NULL; - evsel = perf_evlist__first(evlist); + evsel = evlist__first(evlist); while (--nr > 0) evsel = perf_evsel__next(evsel); diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c index ef96e3dd6902..3dce2de9d005 100644 --- a/tools/perf/util/top.c +++ b/tools/perf/util/top.c @@ -71,7 +71,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) } if (top->evlist->core.nr_entries == 1) { - struct evsel *first = perf_evlist__first(top->evlist); + struct evsel *first = evlist__first(top->evlist); ret += SNPRINTF(bf + ret, size - ret, "%" PRIu64 "%s ", (uint64_t)first->core.attr.sample_period, opts->freq ? "Hz" : ""); -- cgit v1.2.3-59-g8ed1b From ff47d86a0d9bf618b185b49cb4bb9c6f957bb445 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 3 Sep 2019 10:54:48 +0200 Subject: libperf: Add perf_evlist__read_format() function Add the perf_evlist__read_format() function to libperf as internal function. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-30-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evlist.c | 7 +++++++ tools/perf/lib/include/internal/evlist.h | 2 ++ tools/perf/util/evlist.c | 8 +------- tools/perf/util/evlist.h | 1 - 4 files changed, 10 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c index 2bdd9d2c79d9..ae861bf38976 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/perf/lib/evlist.c @@ -161,3 +161,10 @@ void perf_evlist__disable(struct perf_evlist *evlist) perf_evlist__for_each_entry(evlist, evsel) perf_evsel__disable(evsel); } + +u64 perf_evlist__read_format(struct perf_evlist *evlist) +{ + struct perf_evsel *first = perf_evlist__first(evlist); + + return first->attr.read_format; +} diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h index 16ae6d6cfb39..63516fe14f4c 100644 --- a/tools/perf/lib/include/internal/evlist.h +++ b/tools/perf/lib/include/internal/evlist.h @@ -66,4 +66,6 @@ static inline struct perf_evsel *perf_evlist__last(struct perf_evlist *evlist) return list_entry(evlist->entries.prev, struct perf_evsel, node); } +u64 perf_evlist__read_format(struct perf_evlist *evlist); + #endif /* __LIBPERF_INTERNAL_EVLIST_H */ diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index e8f0357b1532..bc788192493f 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -503,7 +503,7 @@ int perf_evlist__id_add_fd(struct evlist *evlist, * This way does not work with group format read, so bail * out in that case. */ - if (perf_evlist__read_format(evlist) & PERF_FORMAT_GROUP) + if (perf_evlist__read_format(&evlist->core) & PERF_FORMAT_GROUP) return -1; if (!(evsel->core.attr.read_format & PERF_FORMAT_ID) || @@ -1240,12 +1240,6 @@ bool perf_evlist__valid_read_format(struct evlist *evlist) return true; } -u64 perf_evlist__read_format(struct evlist *evlist) -{ - struct evsel *first = evlist__first(evlist); - return first->core.attr.read_format; -} - u16 perf_evlist__id_hdr_size(struct evlist *evlist) { struct evsel *first = evlist__first(evlist); diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 6529ad2a9d97..3f89d9913a30 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -217,7 +217,6 @@ int perf_evlist__apply_filters(struct evlist *evlist, struct evsel **err_evsel); void __perf_evlist__set_leader(struct list_head *list); void perf_evlist__set_leader(struct evlist *evlist); -u64 perf_evlist__read_format(struct evlist *evlist); u64 __perf_evlist__combined_sample_type(struct evlist *evlist); u64 perf_evlist__combined_sample_type(struct evlist *evlist); u64 perf_evlist__combined_branch_type(struct evlist *evlist); -- cgit v1.2.3-59-g8ed1b From b0031c22819ab606a0cb648c0f0a7d80db3c3a89 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 3 Sep 2019 11:01:04 +0200 Subject: libperf: Add perf_evlist__id_add() function Add the perf_evlist__id_add() function to libperf as an internal function. We already have the 'heads' member in 'struct perf_evlist'. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-31-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evlist.c | 26 ++++++++++++++++++++++++++ tools/perf/lib/include/internal/evlist.h | 4 ++++ tools/perf/tests/event_update.c | 2 +- tools/perf/util/evlist.c | 22 +--------------------- tools/perf/util/evlist.h | 2 -- tools/perf/util/header.c | 4 ++-- 6 files changed, 34 insertions(+), 26 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c index ae861bf38976..a29ee8a746d9 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/perf/lib/evlist.c @@ -1,9 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include +#include #include #include +#include #include #include #include @@ -168,3 +171,26 @@ u64 perf_evlist__read_format(struct perf_evlist *evlist) return first->attr.read_format; } + +#define SID(e, x, y) xyarray__entry(e->sample_id, x, y) + +static void perf_evlist__id_hash(struct perf_evlist *evlist, + struct perf_evsel *evsel, + int cpu, int thread, u64 id) +{ + int hash; + struct perf_sample_id *sid = SID(evsel, cpu, thread); + + sid->id = id; + sid->evsel = evsel; + hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS); + hlist_add_head(&sid->node, &evlist->heads[hash]); +} + +void perf_evlist__id_add(struct perf_evlist *evlist, + struct perf_evsel *evsel, + int cpu, int thread, u64 id) +{ + perf_evlist__id_hash(evlist, evsel, cpu, thread, id); + evsel->id[evsel->ids++] = id; +} diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h index 63516fe14f4c..649406f717bc 100644 --- a/tools/perf/lib/include/internal/evlist.h +++ b/tools/perf/lib/include/internal/evlist.h @@ -68,4 +68,8 @@ static inline struct perf_evsel *perf_evlist__last(struct perf_evlist *evlist) u64 perf_evlist__read_format(struct perf_evlist *evlist); +void perf_evlist__id_add(struct perf_evlist *evlist, + struct perf_evsel *evsel, + int cpu, int thread, u64 id); + #endif /* __LIBPERF_INTERNAL_EVLIST_H */ diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index cd6cae8e5137..c727379cf20e 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -97,7 +97,7 @@ int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unu TEST_ASSERT_VAL("failed to allocate ids", !perf_evsel__alloc_id(&evsel->core, 1, 1)); - perf_evlist__id_add(evlist, evsel, 0, 0, 123); + perf_evlist__id_add(&evlist->core, &evsel->core, 0, 0, 123); evsel->unit = strdup("KRAVA"); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index bc788192493f..f2863b4c61d7 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -461,26 +461,6 @@ int perf_evlist__poll(struct evlist *evlist, int timeout) return fdarray__poll(&evlist->core.pollfd, timeout); } -static void perf_evlist__id_hash(struct evlist *evlist, - struct evsel *evsel, - int cpu, int thread, u64 id) -{ - int hash; - struct perf_sample_id *sid = SID(evsel, cpu, thread); - - sid->id = id; - sid->evsel = &evsel->core; - hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS); - hlist_add_head(&sid->node, &evlist->core.heads[hash]); -} - -void perf_evlist__id_add(struct evlist *evlist, struct evsel *evsel, - int cpu, int thread, u64 id) -{ - perf_evlist__id_hash(evlist, evsel, cpu, thread, id); - evsel->core.id[evsel->core.ids++] = id; -} - int perf_evlist__id_add_fd(struct evlist *evlist, struct evsel *evsel, int cpu, int thread, int fd) @@ -518,7 +498,7 @@ int perf_evlist__id_add_fd(struct evlist *evlist, id = read_data[id_idx]; add: - perf_evlist__id_add(evlist, evsel, cpu, thread, id); + perf_evlist__id_add(&evlist->core, &evsel->core, cpu, thread, id); return 0; } diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 3f89d9913a30..eb35b4b1d86f 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -141,8 +141,6 @@ struct evsel * perf_evlist__find_tracepoint_by_name(struct evlist *evlist, const char *name); -void perf_evlist__id_add(struct evlist *evlist, struct evsel *evsel, - int cpu, int thread, u64 id); int perf_evlist__id_add_fd(struct evlist *evlist, struct evsel *evsel, int cpu, int thread, int fd); diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index fc5eac41e102..02602bc8cabf 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -3618,7 +3618,7 @@ int perf_session__read_header(struct perf_session *session) if (perf_header__getbuffer64(header, fd, &f_id, sizeof(f_id))) goto out_errno; - perf_evlist__id_add(session->evlist, evsel, 0, j, f_id); + perf_evlist__id_add(&session->evlist->core, &evsel->core, 0, j, f_id); } lseek(fd, tmp, SEEK_SET); @@ -3754,7 +3754,7 @@ int perf_event__process_attr(struct perf_tool *tool __maybe_unused, return -ENOMEM; for (i = 0; i < n_ids; i++) { - perf_evlist__id_add(evlist, evsel, 0, i, event->attr.id[i]); + perf_evlist__id_add(&evlist->core, &evsel->core, 0, i, event->attr.id[i]); } return 0; -- cgit v1.2.3-59-g8ed1b From d5a99483dece17dbde01968a7ffc03b7f575dc11 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 3 Sep 2019 11:19:56 +0200 Subject: libperf: Add perf_evlist__id_add_fd() function Add the perf_evlist__id_add_fd() function to libperf as an internal function. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-32-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evlist.c | 44 ++++++++++++++++++++++++++++++++ tools/perf/lib/include/internal/evlist.h | 4 +++ tools/perf/util/evlist.c | 43 +------------------------------ tools/perf/util/evlist.h | 4 --- tools/perf/util/evsel.c | 2 +- 5 files changed, 50 insertions(+), 47 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c index a29ee8a746d9..3a16dd0c044f 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/perf/lib/evlist.c @@ -4,11 +4,14 @@ #include #include #include +#include #include #include #include #include #include +#include +#include #include #include @@ -194,3 +197,44 @@ void perf_evlist__id_add(struct perf_evlist *evlist, perf_evlist__id_hash(evlist, evsel, cpu, thread, id); evsel->id[evsel->ids++] = id; } + +int perf_evlist__id_add_fd(struct perf_evlist *evlist, + struct perf_evsel *evsel, + int cpu, int thread, int fd) +{ + u64 read_data[4] = { 0, }; + int id_idx = 1; /* The first entry is the counter value */ + u64 id; + int ret; + + ret = ioctl(fd, PERF_EVENT_IOC_ID, &id); + if (!ret) + goto add; + + if (errno != ENOTTY) + return -1; + + /* Legacy way to get event id.. All hail to old kernels! */ + + /* + * This way does not work with group format read, so bail + * out in that case. + */ + if (perf_evlist__read_format(evlist) & PERF_FORMAT_GROUP) + return -1; + + if (!(evsel->attr.read_format & PERF_FORMAT_ID) || + read(fd, &read_data, sizeof(read_data)) == -1) + return -1; + + if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) + ++id_idx; + if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) + ++id_idx; + + id = read_data[id_idx]; + +add: + perf_evlist__id_add(evlist, evsel, cpu, thread, id); + return 0; +} diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h index 649406f717bc..7d64185cfabd 100644 --- a/tools/perf/lib/include/internal/evlist.h +++ b/tools/perf/lib/include/internal/evlist.h @@ -72,4 +72,8 @@ void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel, int cpu, int thread, u64 id); +int perf_evlist__id_add_fd(struct perf_evlist *evlist, + struct perf_evsel *evsel, + int cpu, int thread, int fd); + #endif /* __LIBPERF_INTERNAL_EVLIST_H */ diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index f2863b4c61d7..a37eccf65eae 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -461,47 +461,6 @@ int perf_evlist__poll(struct evlist *evlist, int timeout) return fdarray__poll(&evlist->core.pollfd, timeout); } -int perf_evlist__id_add_fd(struct evlist *evlist, - struct evsel *evsel, - int cpu, int thread, int fd) -{ - u64 read_data[4] = { 0, }; - int id_idx = 1; /* The first entry is the counter value */ - u64 id; - int ret; - - ret = ioctl(fd, PERF_EVENT_IOC_ID, &id); - if (!ret) - goto add; - - if (errno != ENOTTY) - return -1; - - /* Legacy way to get event id.. All hail to old kernels! */ - - /* - * This way does not work with group format read, so bail - * out in that case. - */ - if (perf_evlist__read_format(&evlist->core) & PERF_FORMAT_GROUP) - return -1; - - if (!(evsel->core.attr.read_format & PERF_FORMAT_ID) || - read(fd, &read_data, sizeof(read_data)) == -1) - return -1; - - if (evsel->core.attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) - ++id_idx; - if (evsel->core.attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) - ++id_idx; - - id = read_data[id_idx]; - - add: - perf_evlist__id_add(&evlist->core, &evsel->core, cpu, thread, id); - return 0; -} - static void perf_evlist__set_sid_idx(struct evlist *evlist, struct evsel *evsel, int idx, int cpu, int thread) @@ -776,7 +735,7 @@ static int evlist__mmap_per_evsel(struct evlist *evlist, int idx, } if (evsel->core.attr.read_format & PERF_FORMAT_ID) { - if (perf_evlist__id_add_fd(evlist, evsel, cpu, thread, + if (perf_evlist__id_add_fd(&evlist->core, &evsel->core, cpu, thread, fd) < 0) return -1; perf_evlist__set_sid_idx(evlist, evsel, idx, cpu, diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index eb35b4b1d86f..80b3361613e5 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -141,10 +141,6 @@ struct evsel * perf_evlist__find_tracepoint_by_name(struct evlist *evlist, const char *name); -int perf_evlist__id_add_fd(struct evlist *evlist, - struct evsel *evsel, - int cpu, int thread, int fd); - int perf_evlist__add_pollfd(struct evlist *evlist, int fd); int perf_evlist__alloc_pollfd(struct evlist *evlist); int perf_evlist__filter_pollfd(struct evlist *evlist, short revents_and_mask); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index a4a492f11849..9c284d2adcea 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2662,7 +2662,7 @@ static int store_evsel_ids(struct evsel *evsel, struct evlist *evlist) thread++) { int fd = FD(evsel, cpu, thread); - if (perf_evlist__id_add_fd(evlist, evsel, + if (perf_evlist__id_add_fd(&evlist->core, &evsel->core, cpu, thread, fd) < 0) return -1; } -- cgit v1.2.3-59-g8ed1b From 20f2be1d48ec293b5a935595bd0c2e2915ffa77c Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 6 Aug 2019 15:25:25 +0200 Subject: libperf: Move 'page_size' global variable to libperf We need the 'page_size' variable in libperf, so move it there. Add a libperf_init() as a global libperf init function to obtain this value via sysconf() at tool start. Committer notes: Add internal/lib.h to tools/perf/ files using 'page_size', sometimes replacing util.h with it if that was the only reason for having util.h included. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-33-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 2 +- tools/perf/arch/arm64/util/arm-spe.c | 2 +- tools/perf/arch/s390/util/machine.c | 2 +- tools/perf/arch/x86/tests/intel-cqm.c | 1 + tools/perf/arch/x86/tests/rdpmc.c | 2 +- tools/perf/arch/x86/util/intel-bts.c | 2 +- tools/perf/arch/x86/util/intel-pt.c | 2 +- tools/perf/arch/x86/util/machine.c | 2 +- tools/perf/lib/core.c | 7 +++++++ tools/perf/lib/include/internal/lib.h | 2 ++ tools/perf/lib/include/perf/core.h | 1 + tools/perf/lib/lib.c | 2 ++ tools/perf/lib/libperf.map | 1 + tools/perf/perf.c | 7 ++++--- tools/perf/tests/mmap-thread-lookup.c | 2 +- tools/perf/tests/vmlinux-kallsyms.c | 2 +- tools/perf/util/auxtrace.c | 1 - tools/perf/util/evlist.c | 2 +- tools/perf/util/header.c | 2 +- tools/perf/util/machine.c | 1 + tools/perf/util/mmap.c | 2 +- tools/perf/util/python.c | 2 +- tools/perf/util/session.c | 1 - tools/perf/util/srccode.c | 2 +- tools/perf/util/synthetic-events.c | 2 +- tools/perf/util/trace-event-info.c | 2 +- tools/perf/util/util.c | 3 +-- tools/perf/util/util.h | 2 -- 28 files changed, 36 insertions(+), 25 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 6654bcfc1224..2e4de211d881 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -25,7 +25,7 @@ #include "../../util/evsel.h" #include "../../util/pmu.h" #include "../../util/cs-etm.h" -#include "../../util/util.h" // page_size +#include // page_size #include "../../util/session.h" #include diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index 745f2d50ee82..eba6541ec0f1 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -16,7 +16,7 @@ #include "../../util/evsel.h" #include "../../util/evlist.h" #include "../../util/session.h" -#include "../../util/util.h" // page_size +#include // page_size #include "../../util/pmu.h" #include "../../util/debug.h" #include "../../util/auxtrace.h" diff --git a/tools/perf/arch/s390/util/machine.c b/tools/perf/arch/s390/util/machine.c index df099d6cc3f5..724efb2d842d 100644 --- a/tools/perf/arch/s390/util/machine.c +++ b/tools/perf/arch/s390/util/machine.c @@ -2,7 +2,7 @@ #include #include #include -#include "util.h" // page_size +#include // page_size #include "machine.h" #include "api/fs/fs.h" #include "debug.h" diff --git a/tools/perf/arch/x86/tests/intel-cqm.c b/tools/perf/arch/x86/tests/intel-cqm.c index 0329b9168fae..3ec562a2aaba 100644 --- a/tools/perf/arch/x86/tests/intel-cqm.c +++ b/tools/perf/arch/x86/tests/intel-cqm.c @@ -5,6 +5,7 @@ #include "evlist.h" #include "evsel.h" #include "arch-tests.h" +#include // page_size #include #include diff --git a/tools/perf/arch/x86/tests/rdpmc.c b/tools/perf/arch/x86/tests/rdpmc.c index e7640fb047de..1ea916656a2d 100644 --- a/tools/perf/arch/x86/tests/rdpmc.c +++ b/tools/perf/arch/x86/tests/rdpmc.c @@ -13,7 +13,7 @@ #include "tests/tests.h" #include "cloexec.h" #include "event.h" -#include "util.h" // page_size +#include // page_size #include "arch-tests.h" static u64 rdpmc(unsigned int counter) diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index e2c7095327db..f7f68a50a5cd 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -23,7 +23,7 @@ #include "../../util/tsc.h" #include "../../util/auxtrace.h" #include "../../util/intel-bts.h" -#include "../../util/util.h" // page_size +#include // page_size #define KiB(x) ((x) * 1024) #define MiB(x) ((x) * 1024 * 1024) diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 84a65524c418..d6d26256915f 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -27,7 +27,7 @@ #include "../../util/record.h" #include "../../util/target.h" #include "../../util/tsc.h" -#include "../../util/util.h" // page_size +#include // page_size #include "../../util/intel-pt.h" #define KiB(x) ((x) * 1024) diff --git a/tools/perf/arch/x86/util/machine.c b/tools/perf/arch/x86/util/machine.c index f0c289862f9f..e17e080e76f4 100644 --- a/tools/perf/arch/x86/util/machine.c +++ b/tools/perf/arch/x86/util/machine.c @@ -4,7 +4,7 @@ #include #include -#include "../../util/util.h" // page_size +#include // page_size #include "../../util/machine.h" #include "../../util/map.h" #include "../../util/symbol.h" diff --git a/tools/perf/lib/core.c b/tools/perf/lib/core.c index 29d5e3348718..6689d593c2d1 100644 --- a/tools/perf/lib/core.c +++ b/tools/perf/lib/core.c @@ -4,7 +4,9 @@ #include #include +#include #include +#include #include "internal.h" static int __base_pr(enum libperf_print_level level, const char *format, @@ -32,3 +34,8 @@ void libperf_print(enum libperf_print_level level, const char *format, ...) __libperf_pr(level, format, args); va_end(args); } + +void libperf_init(void) +{ + page_size = sysconf(_SC_PAGE_SIZE); +} diff --git a/tools/perf/lib/include/internal/lib.h b/tools/perf/lib/include/internal/lib.h index 0b56f1201dc9..9168b7d2a7e1 100644 --- a/tools/perf/lib/include/internal/lib.h +++ b/tools/perf/lib/include/internal/lib.h @@ -4,6 +4,8 @@ #include +extern unsigned int page_size; + ssize_t readn(int fd, void *buf, size_t n); ssize_t writen(int fd, const void *buf, size_t n); diff --git a/tools/perf/lib/include/perf/core.h b/tools/perf/lib/include/perf/core.h index c341a7b2c874..ba2f4e76a3e2 100644 --- a/tools/perf/lib/include/perf/core.h +++ b/tools/perf/lib/include/perf/core.h @@ -18,5 +18,6 @@ typedef int (*libperf_print_fn_t)(enum libperf_print_level level, const char *, va_list ap); LIBPERF_API void libperf_set_print(libperf_print_fn_t fn); +LIBPERF_API void libperf_init(void); #endif /* __LIBPERF_CORE_H */ diff --git a/tools/perf/lib/lib.c b/tools/perf/lib/lib.c index 2a81819c3b8c..18658931fc71 100644 --- a/tools/perf/lib/lib.c +++ b/tools/perf/lib/lib.c @@ -5,6 +5,8 @@ #include #include +unsigned int page_size; + static ssize_t ion(bool is_read, int fd, void *buf, size_t n) { void *buf_start = buf; diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index cd0d17b996c8..724da66776ef 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -1,5 +1,6 @@ LIBPERF_0.0.1 { global: + libperf_init; libperf_set_print; perf_cpu_map__dummy_new; perf_cpu_map__get; diff --git a/tools/perf/perf.c b/tools/perf/perf.c index bb40a108b8f7..c012ceb64ff9 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -12,6 +12,7 @@ #include "util/build-id.h" #include "util/cache.h" #include "util/env.h" +#include // page_size #include #include "util/config.h" #include @@ -20,11 +21,12 @@ #include "util/bpf-loader.h" #include "util/debug.h" #include "util/event.h" -#include "util/util.h" // page_size, usage() +#include "util/util.h" // usage() #include "ui/ui.h" #include "perf-sys.h" #include #include +#include #include #include #include @@ -438,8 +440,7 @@ int main(int argc, const char **argv) exec_cmd_init("perf", PREFIX, PERF_EXEC_PATH, EXEC_PATH_ENVIRONMENT); pager_init(PERF_PAGER_ENVIRONMENT); - /* The page_size is placed in util object. */ - page_size = sysconf(_SC_PAGE_SIZE); + libperf_init(); cmd = extract_argv0_path(argv[0]); if (!cmd) diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c index 33b496d194f4..8d9d4cbff76d 100644 --- a/tools/perf/tests/mmap-thread-lookup.c +++ b/tools/perf/tests/mmap-thread-lookup.c @@ -16,7 +16,7 @@ #include "symbol.h" #include "util/synthetic-events.h" #include "thread.h" -#include "util.h" // page_size +#include // page_size #define THREADS 4 diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index 7f28775875c2..aa296ffea6d1 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -7,7 +7,7 @@ #include "dso.h" #include "map.h" #include "symbol.h" -#include "util.h" // page_size +#include // page_size #include "tests.h" #include "debug.h" #include "machine.h" diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 4bd92f5bfb5f..8470dfe9fe97 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -50,7 +50,6 @@ #include "intel-bts.h" #include "arm-spe.h" #include "s390-cpumsf.h" -#include "util.h" // page_size #include "util/mmap.h" #include diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index a37eccf65eae..6069fb52661f 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -17,7 +17,7 @@ #include "evsel.h" #include "debug.h" #include "units.h" -#include "util.h" // page_size +#include // page_size #include "../perf.h" #include "asm/bug.h" #include "bpf-event.h" diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 02602bc8cabf..3b24b4974c5f 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -42,7 +42,7 @@ #include "tool.h" #include "time-utils.h" #include "units.h" -#include "util.h" // page_size, perf_exe() +#include "util/util.h" // perf_exe() #include "cputopo.h" #include "bpf-event.h" diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 0535338f2d7a..70a9f8716a4b 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -32,6 +32,7 @@ #include "linux/hash.h" #include "asm/bug.h" #include "bpf-event.h" +#include // page_size #include #include diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 4cc3b54b2f73..12671d089748 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -20,7 +20,7 @@ #include "event.h" #include "mmap.h" #include "../perf.h" -#include "util.h" /* page_size */ +#include /* page_size */ size_t perf_mmap__mmap_len(struct mmap *map) { diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index fcbafb1e8d9d..6c46d7dbd263 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -14,7 +14,7 @@ #include "thread_map.h" #include "trace-event.h" #include "mmap.h" -#include "util.h" +#include #include "../perf-sys.h" #if PY_MAJOR_VERSION < 3 diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 84a30ff3968a..061bb4d6a3f5 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -29,7 +29,6 @@ #include "thread-stack.h" #include "sample-raw.h" #include "stat.h" -#include "util.h" #include "ui/progress.h" #include "../perf.h" #include "arch/common.h" diff --git a/tools/perf/util/srccode.c b/tools/perf/util/srccode.c index b402f9ca89ab..d84ed8b6caaa 100644 --- a/tools/perf/util/srccode.c +++ b/tools/perf/util/srccode.c @@ -15,7 +15,7 @@ #include #include "srccode.h" #include "debug.h" -#include "util.h" // page_size +#include // page_size #define MAXSRCCACHE (32*1024*1024) #define MAXSRCFILES 64 diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index 96ed008c2775..807cbca403a7 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -16,7 +16,6 @@ #include "util/synthetic-events.h" #include "util/target.h" #include "util/time-utils.h" -#include "util/util.h" #include #include #include @@ -26,6 +25,7 @@ #include #include #include +#include // page_size #include #include #include diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index fe07e7550930..086e98ff42a3 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c @@ -2,7 +2,6 @@ /* * Copyright (C) 2008,2009, Steven Rostedt */ -#include "util.h" // page_size #include #include #include @@ -19,6 +18,7 @@ #include #include #include +#include // page_size #include "trace-event.h" #include diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 32322a20a68b..cb6fa4c98470 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -3,6 +3,7 @@ #include "debug.h" #include "event.h" #include "namespaces.h" +#include #include #include #include @@ -41,8 +42,6 @@ void perf_set_multithreaded(void) perf_singlethreaded = false; } -unsigned int page_size; - int sysctl_perf_event_max_stack = PERF_MAX_STACK_DEPTH; int sysctl_perf_event_max_contexts_per_stack = PERF_MAX_CONTEXTS_PER_STACK; diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 45a5c6f20197..d6ae394e67c4 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -33,8 +33,6 @@ int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size); size_t hex_width(u64 v); -extern unsigned int page_size; - int sysctl__max_stack(void); int fetch_kernel_version(unsigned int *puint, -- cgit v1.2.3-59-g8ed1b From 26049111c333fda4194e895f4cb719766b602256 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 23 Sep 2019 16:22:22 -0300 Subject: perf tools: No need to include internal/lib.h from util/util.h That was done just to have users of writen() and readn(), that before had their prototypes in util/util.h to get it without having to add an include for internal/lib.h, but the right way is to add it and by now all places already do it. Fix a fallout were readlink() was used but unistd.h was being obtained by luck thru util.h -> internal/lib.h, now to check why unistd.h is being included there... Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-lcnytgrtafey3kwlfog2rzzj@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/sdt.c | 1 + tools/perf/util/util.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c index cf1bd57d3023..60f0e9ee04fb 100644 --- a/tools/perf/tests/sdt.c +++ b/tools/perf/tests/sdt.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index d6ae394e67c4..b78b73e5bb32 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -11,7 +11,6 @@ #include #include #include -#include /* General helper functions */ void usage(const char *err) __noreturn; -- cgit v1.2.3-59-g8ed1b From 7634d5336a6e66cba5befd8190b3994916424e08 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 23 Sep 2019 18:06:52 -0300 Subject: libperf: Use sys/types.h to get ssize_t, not unistd.h The sys/types.h header looks more sensible, from its name we can gather it should be there because of some needed typedef, and it is much smaller than unistd.h, so use it and fix up the fallout in places where it was being used for something else entirely but being obtained by sheer luck, indirectly. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-49bn251httu22ymwgipeavmy@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/include/internal/lib.h | 2 +- tools/perf/util/mmap.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/lib/include/internal/lib.h b/tools/perf/lib/include/internal/lib.h index 9168b7d2a7e1..5175d491b2d4 100644 --- a/tools/perf/lib/include/internal/lib.h +++ b/tools/perf/lib/include/internal/lib.h @@ -2,7 +2,7 @@ #ifndef __LIBPERF_INTERNAL_LIB_H #define __LIBPERF_INTERNAL_LIB_H -#include +#include extern unsigned int page_size; diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 12671d089748..a35dc57d5995 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -12,6 +12,7 @@ #include #include #include +#include // sysconf() #ifdef HAVE_LIBNUMA_SUPPORT #include #endif -- cgit v1.2.3-59-g8ed1b From fb4bf51fcc153f74c86e08ce1d17e9f1a1a71ba0 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 2 Sep 2019 10:35:47 +0200 Subject: libperf: Add libperf dependency for tests targets Add libperf dependency for tests targets. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-36-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/lib/Makefile b/tools/perf/lib/Makefile index 54466cc84544..85ccb8c439a4 100644 --- a/tools/perf/lib/Makefile +++ b/tools/perf/lib/Makefile @@ -138,7 +138,7 @@ clean: $(LIBAPI)-clean *.o *~ *.a *.so *.so.$(VERSION) *.so.$(LIBPERF_VERSION) .*.d .*.cmd LIBPERF-CFLAGS $(LIBPERF_PC) $(Q)$(MAKE) -C tests clean -tests: +tests: libs $(Q)$(MAKE) -C tests $(Q)$(MAKE) -C tests run -- cgit v1.2.3-59-g8ed1b From 428dab813a56ce9402f359dc35a3ccdfcaea9429 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 31 Aug 2019 20:44:13 +0200 Subject: libperf: Merge libperf_set_print() into libperf_init() The libperf_set_print() function needs to be called in any case so let's merge it with libperf_init(), so we have just one init function. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-34-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/core.c | 8 ++------ tools/perf/lib/include/perf/core.h | 3 +-- tools/perf/lib/libperf.map | 1 - tools/perf/perf.c | 8 +++++++- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/core.c b/tools/perf/lib/core.c index 6689d593c2d1..d0b9ae422b9f 100644 --- a/tools/perf/lib/core.c +++ b/tools/perf/lib/core.c @@ -17,11 +17,6 @@ static int __base_pr(enum libperf_print_level level, const char *format, static libperf_print_fn_t __libperf_pr = __base_pr; -void libperf_set_print(libperf_print_fn_t fn) -{ - __libperf_pr = fn; -} - __printf(2, 3) void libperf_print(enum libperf_print_level level, const char *format, ...) { @@ -35,7 +30,8 @@ void libperf_print(enum libperf_print_level level, const char *format, ...) va_end(args); } -void libperf_init(void) +void libperf_init(libperf_print_fn_t fn) { page_size = sysconf(_SC_PAGE_SIZE); + __libperf_pr = fn; } diff --git a/tools/perf/lib/include/perf/core.h b/tools/perf/lib/include/perf/core.h index ba2f4e76a3e2..cfd70e720c1c 100644 --- a/tools/perf/lib/include/perf/core.h +++ b/tools/perf/lib/include/perf/core.h @@ -17,7 +17,6 @@ enum libperf_print_level { typedef int (*libperf_print_fn_t)(enum libperf_print_level level, const char *, va_list ap); -LIBPERF_API void libperf_set_print(libperf_print_fn_t fn); -LIBPERF_API void libperf_init(void); +LIBPERF_API void libperf_init(libperf_print_fn_t fn); #endif /* __LIBPERF_CORE_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 724da66776ef..5eb0150ccdc6 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -1,7 +1,6 @@ LIBPERF_0.0.1 { global: libperf_init; - libperf_set_print; perf_cpu_map__dummy_new; perf_cpu_map__get; perf_cpu_map__put; diff --git a/tools/perf/perf.c b/tools/perf/perf.c index c012ceb64ff9..27f94b0bb874 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -430,6 +430,12 @@ void pthread__unblock_sigwinch(void) pthread_sigmask(SIG_UNBLOCK, &set, NULL); } +static int libperf_print(enum libperf_print_level level, + const char *fmt, va_list ap) +{ + return eprintf(level, verbose, fmt, ap); +} + int main(int argc, const char **argv) { int err; @@ -440,7 +446,7 @@ int main(int argc, const char **argv) exec_cmd_init("perf", PREFIX, PERF_EXEC_PATH, EXEC_PATH_ENVIRONMENT); pager_init(PERF_PAGER_ENVIRONMENT); - libperf_init(); + libperf_init(libperf_print); cmd = extract_argv0_path(argv[0]); if (!cmd) -- cgit v1.2.3-59-g8ed1b From 379dd98c3d77de920f09f1933592982d200e076a Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 2 Sep 2019 10:33:09 +0200 Subject: libperf: Add libperf_init() call to the tests Add libperf_init() call to the automated tests. Committer notes: Added missing stdarg.h and/or stdio.h to places using vfprintf. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-34-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/tests/test-cpumap.c | 10 ++++++++++ tools/perf/lib/tests/test-evlist.c | 10 ++++++++++ tools/perf/lib/tests/test-evsel.c | 10 ++++++++++ tools/perf/lib/tests/test-threadmap.c | 10 ++++++++++ 4 files changed, 40 insertions(+) (limited to 'tools') diff --git a/tools/perf/lib/tests/test-cpumap.c b/tools/perf/lib/tests/test-cpumap.c index 76a43cfb83a1..aa34c20df07e 100644 --- a/tools/perf/lib/tests/test-cpumap.c +++ b/tools/perf/lib/tests/test-cpumap.c @@ -1,13 +1,23 @@ // SPDX-License-Identifier: GPL-2.0 +#include +#include #include #include +static int libperf_print(enum libperf_print_level level, + const char *fmt, va_list ap) +{ + return vfprintf(stderr, fmt, ap); +} + int main(int argc, char **argv) { struct perf_cpu_map *cpus; __T_START; + libperf_init(libperf_print); + cpus = perf_cpu_map__dummy_new(); if (!cpus) return -1; diff --git a/tools/perf/lib/tests/test-evlist.c b/tools/perf/lib/tests/test-evlist.c index 4e1407f20ffd..e6b2ab2e2bde 100644 --- a/tools/perf/lib/tests/test-evlist.c +++ b/tools/perf/lib/tests/test-evlist.c @@ -1,4 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 +#include +#include #include #include #include @@ -6,6 +8,12 @@ #include #include +static int libperf_print(enum libperf_print_level level, + const char *fmt, va_list ap) +{ + return vfprintf(stderr, fmt, ap); +} + static int test_stat_cpu(void) { struct perf_cpu_map *cpus; @@ -177,6 +185,8 @@ int main(int argc, char **argv) { __T_START; + libperf_init(libperf_print); + test_stat_cpu(); test_stat_thread(); test_stat_thread_enable(); diff --git a/tools/perf/lib/tests/test-evsel.c b/tools/perf/lib/tests/test-evsel.c index 2c648fe5617e..1b6c4285ac2b 100644 --- a/tools/perf/lib/tests/test-evsel.c +++ b/tools/perf/lib/tests/test-evsel.c @@ -1,10 +1,18 @@ // SPDX-License-Identifier: GPL-2.0 +#include +#include #include #include #include #include #include +static int libperf_print(enum libperf_print_level level, + const char *fmt, va_list ap) +{ + return vfprintf(stderr, fmt, ap); +} + static int test_stat_cpu(void) { struct perf_cpu_map *cpus; @@ -116,6 +124,8 @@ int main(int argc, char **argv) { __T_START; + libperf_init(libperf_print); + test_stat_cpu(); test_stat_thread(); test_stat_thread_enable(); diff --git a/tools/perf/lib/tests/test-threadmap.c b/tools/perf/lib/tests/test-threadmap.c index 10a4f4cbbdd5..8c5f47247d9e 100644 --- a/tools/perf/lib/tests/test-threadmap.c +++ b/tools/perf/lib/tests/test-threadmap.c @@ -1,13 +1,23 @@ // SPDX-License-Identifier: GPL-2.0 +#include +#include #include #include +static int libperf_print(enum libperf_print_level level, + const char *fmt, va_list ap) +{ + return vfprintf(stderr, fmt, ap); +} + int main(int argc, char **argv) { struct perf_thread_map *threads; __T_START; + libperf_init(libperf_print); + threads = perf_thread_map__new_dummy(); if (!threads) return -1; -- cgit v1.2.3-59-g8ed1b From 31f67fc462a9e5df3b900924c2bf649c7bc63af8 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 6 Aug 2019 13:21:53 +0200 Subject: libperf: Add perf_evlist__alloc_pollfd() function Move perf_evlist__alloc_pollfd() from tools/perf to libperf, it will be used in the following patches. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-37-jolsa@kernel.org [ Added api/fd/array.h include to the lib/evlist.c file ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/lib/evlist.c | 22 ++++++++++++++++++++++ tools/perf/lib/include/internal/evlist.h | 2 ++ tools/perf/util/evlist.c | 23 +---------------------- tools/perf/util/evlist.h | 1 - 4 files changed, 25 insertions(+), 23 deletions(-) (limited to 'tools') diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c index 3a16dd0c044f..3c3b97f40be0 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/perf/lib/evlist.c @@ -14,6 +14,7 @@ #include #include #include +#include void perf_evlist__init(struct perf_evlist *evlist) { @@ -238,3 +239,24 @@ add: perf_evlist__id_add(evlist, evsel, cpu, thread, id); return 0; } + +int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) +{ + int nr_cpus = perf_cpu_map__nr(evlist->cpus); + int nr_threads = perf_thread_map__nr(evlist->threads); + int nfds = 0; + struct perf_evsel *evsel; + + perf_evlist__for_each_entry(evlist, evsel) { + if (evsel->system_wide) + nfds += nr_cpus; + else + nfds += nr_cpus * nr_threads; + } + + if (fdarray__available_entries(&evlist->pollfd) < nfds && + fdarray__grow(&evlist->pollfd, nfds) < 0) + return -ENOMEM; + + return 0; +} diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h index 7d64185cfabd..88c0dfaf0ddc 100644 --- a/tools/perf/lib/include/internal/evlist.h +++ b/tools/perf/lib/include/internal/evlist.h @@ -24,6 +24,8 @@ struct perf_evlist { struct hlist_head heads[PERF_EVLIST__HLIST_SIZE]; }; +int perf_evlist__alloc_pollfd(struct perf_evlist *evlist); + /** * __perf_evlist__for_each_entry - iterate thru all the evsels * @list: list_head instance to iterate diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 6069fb52661f..c47f23e7f3c8 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -398,27 +398,6 @@ int perf_evlist__enable_event_idx(struct evlist *evlist, return perf_evlist__enable_event_thread(evlist, evsel, idx); } -int perf_evlist__alloc_pollfd(struct evlist *evlist) -{ - int nr_cpus = perf_cpu_map__nr(evlist->core.cpus); - int nr_threads = perf_thread_map__nr(evlist->core.threads); - int nfds = 0; - struct evsel *evsel; - - evlist__for_each_entry(evlist, evsel) { - if (evsel->core.system_wide) - nfds += nr_cpus; - else - nfds += nr_cpus * nr_threads; - } - - if (fdarray__available_entries(&evlist->core.pollfd) < nfds && - fdarray__grow(&evlist->core.pollfd, nfds) < 0) - return -ENOMEM; - - return 0; -} - static int __perf_evlist__add_pollfd(struct evlist *evlist, int fd, struct mmap *map, short revent) { @@ -944,7 +923,7 @@ int evlist__mmap_ex(struct evlist *evlist, unsigned int pages, if (!evlist->mmap) return -ENOMEM; - if (evlist->core.pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) + if (evlist->core.pollfd.entries == NULL && perf_evlist__alloc_pollfd(&evlist->core) < 0) return -ENOMEM; evlist->core.mmap_len = evlist__mmap_size(pages); diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 80b3361613e5..bebbaa9b6325 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -142,7 +142,6 @@ perf_evlist__find_tracepoint_by_name(struct evlist *evlist, const char *name); int perf_evlist__add_pollfd(struct evlist *evlist, int fd); -int perf_evlist__alloc_pollfd(struct evlist *evlist); int perf_evlist__filter_pollfd(struct evlist *evlist, short revents_and_mask); int perf_evlist__poll(struct evlist *evlist, int timeout); -- cgit v1.2.3-59-g8ed1b From f4009e7bf7ba3375cb00e33ca901d61a5acd6c2b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 16 Aug 2019 16:00:45 +0200 Subject: libperf: Add perf_evlist__add_pollfd() function Move perf_evlist__add_pollfd() from tools/perf to libperf, it will be used in the following patches. Also rename perf's perf_evlist__add_pollfd()/perf_evlist__filter_pollfd() to evlist__add_pollfd()/evlist__filter_pollfd(). Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-38-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kvm.c | 4 ++-- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/lib/evlist.c | 16 ++++++++++++++++ tools/perf/lib/include/internal/evlist.h | 2 ++ tools/perf/util/evlist.c | 25 ++++--------------------- tools/perf/util/evlist.h | 4 ++-- 7 files changed, 28 insertions(+), 27 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 710a2898ed6c..2227e2f42c09 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -967,10 +967,10 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm) goto out; } - if (perf_evlist__add_pollfd(kvm->evlist, kvm->timerfd) < 0) + if (evlist__add_pollfd(kvm->evlist, kvm->timerfd) < 0) goto out; - nr_stdin = perf_evlist__add_pollfd(kvm->evlist, fileno(stdin)); + nr_stdin = evlist__add_pollfd(kvm->evlist, fileno(stdin)); if (nr_stdin < 0) goto out; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 48600c90cc7e..d6daaad348b5 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1624,7 +1624,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) err = 0; waking++; - if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0) + if (evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0) draining = true; } diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 97667287f573..8d9784b5d028 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3475,7 +3475,7 @@ again: int timeout = done ? 100 : -1; if (!draining && perf_evlist__poll(evlist, timeout) > 0) { - if (perf_evlist__filter_pollfd(evlist, POLLERR | POLLHUP | POLLNVAL) == 0) + if (evlist__filter_pollfd(evlist, POLLERR | POLLHUP | POLLNVAL) == 0) draining = true; goto again; diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c index 3c3b97f40be0..e4d8b3b7b8fc 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/perf/lib/evlist.c @@ -12,6 +12,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -260,3 +263,16 @@ int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) return 0; } + +int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, + void *ptr, short revent) +{ + int pos = fdarray__add(&evlist->pollfd, fd, revent | POLLERR | POLLHUP); + + if (pos >= 0) { + evlist->pollfd.priv[pos].ptr = ptr; + fcntl(fd, F_SETFL, O_NONBLOCK); + } + + return pos; +} diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h index 88c0dfaf0ddc..9f440ab12b76 100644 --- a/tools/perf/lib/include/internal/evlist.h +++ b/tools/perf/lib/include/internal/evlist.h @@ -25,6 +25,8 @@ struct perf_evlist { }; int perf_evlist__alloc_pollfd(struct perf_evlist *evlist); +int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, + void *ptr, short revent); /** * __perf_evlist__for_each_entry - iterate thru all the evsels diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index c47f23e7f3c8..051be9a31db9 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -398,26 +398,9 @@ int perf_evlist__enable_event_idx(struct evlist *evlist, return perf_evlist__enable_event_thread(evlist, evsel, idx); } -static int __perf_evlist__add_pollfd(struct evlist *evlist, int fd, - struct mmap *map, short revent) +int evlist__add_pollfd(struct evlist *evlist, int fd) { - int pos = fdarray__add(&evlist->core.pollfd, fd, revent | POLLERR | POLLHUP); - /* - * Save the idx so that when we filter out fds POLLHUP'ed we can - * close the associated evlist->mmap[] entry. - */ - if (pos >= 0) { - evlist->core.pollfd.priv[pos].ptr = map; - - fcntl(fd, F_SETFL, O_NONBLOCK); - } - - return pos; -} - -int perf_evlist__add_pollfd(struct evlist *evlist, int fd) -{ - return __perf_evlist__add_pollfd(evlist, fd, NULL, POLLIN); + return perf_evlist__add_pollfd(&evlist->core, fd, NULL, POLLIN); } static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd, @@ -429,7 +412,7 @@ static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd, perf_mmap__put(map); } -int perf_evlist__filter_pollfd(struct evlist *evlist, short revents_and_mask) +int evlist__filter_pollfd(struct evlist *evlist, short revents_and_mask) { return fdarray__filter(&evlist->core.pollfd, revents_and_mask, perf_evlist__munmap_filtered, NULL); @@ -708,7 +691,7 @@ static int evlist__mmap_per_evsel(struct evlist *evlist, int idx, * Therefore don't add it for polling. */ if (!evsel->core.system_wide && - __perf_evlist__add_pollfd(evlist, fd, &maps[idx], revent) < 0) { + perf_evlist__add_pollfd(&evlist->core, fd, &maps[idx], revent) < 0) { perf_mmap__put(&maps[idx]); return -1; } diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index bebbaa9b6325..2eac8aab24a3 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -141,8 +141,8 @@ struct evsel * perf_evlist__find_tracepoint_by_name(struct evlist *evlist, const char *name); -int perf_evlist__add_pollfd(struct evlist *evlist, int fd); -int perf_evlist__filter_pollfd(struct evlist *evlist, short revents_and_mask); +int evlist__add_pollfd(struct evlist *evlist, int fd); +int evlist__filter_pollfd(struct evlist *evlist, short revents_and_mask); int perf_evlist__poll(struct evlist *evlist, int timeout); -- cgit v1.2.3-59-g8ed1b From 80ab2987a016f774201d4f3509118047f9d58175 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 31 Aug 2019 22:48:33 +0200 Subject: libperf: Add perf_evlist__poll() function Move perf_evlist__poll() from tools/perf to libperf, it will be used in the following patches. And rename the existing perf's function to evlist__poll(). Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190913132355.21634-39-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-top.c | 4 ++-- tools/perf/builtin-trace.c | 2 +- tools/perf/lib/evlist.c | 5 +++++ tools/perf/lib/include/perf/evlist.h | 1 + tools/perf/lib/libperf.map | 1 + tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/util/evlist.c | 6 +++--- tools/perf/util/evlist.h | 2 +- tools/perf/util/python.c | 2 +- 12 files changed, 19 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index d6daaad348b5..23332861de6e 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1615,7 +1615,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) if (hits == rec->samples) { if (done || draining) break; - err = perf_evlist__poll(rec->evlist, -1); + err = evlist__poll(rec->evlist, -1); /* * Propagate error, only if there's any. Ignore positive * number of returned events and interrupt error. diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 73bf79053ae3..30d8eb614377 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1307,7 +1307,7 @@ static int __cmd_top(struct perf_top *top) } /* Wait for a minimal set of events before starting the snapshot */ - perf_evlist__poll(top->evlist, 100); + evlist__poll(top->evlist, 100); perf_top__mmap_read(top); @@ -1317,7 +1317,7 @@ static int __cmd_top(struct perf_top *top) perf_top__mmap_read(top); if (opts->overwrite || (hits == top->samples)) - ret = perf_evlist__poll(top->evlist, 100); + ret = evlist__poll(top->evlist, 100); if (resize) { perf_top__resize(top); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 8d9784b5d028..c52c3120a811 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3474,7 +3474,7 @@ again: if (trace->nr_events == before) { int timeout = done ? 100 : -1; - if (!draining && perf_evlist__poll(evlist, timeout) > 0) { + if (!draining && evlist__poll(evlist, timeout) > 0) { if (evlist__filter_pollfd(evlist, POLLERR | POLLHUP | POLLNVAL) == 0) draining = true; diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c index e4d8b3b7b8fc..d1496fee810c 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/perf/lib/evlist.c @@ -276,3 +276,8 @@ int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, return pos; } + +int perf_evlist__poll(struct perf_evlist *evlist, int timeout) +{ + return fdarray__poll(&evlist->pollfd, timeout); +} diff --git a/tools/perf/lib/include/perf/evlist.h b/tools/perf/lib/include/perf/evlist.h index 38365f8f3fba..8a2ce0757ab2 100644 --- a/tools/perf/lib/include/perf/evlist.h +++ b/tools/perf/lib/include/perf/evlist.h @@ -31,5 +31,6 @@ LIBPERF_API void perf_evlist__disable(struct perf_evlist *evlist); LIBPERF_API void perf_evlist__set_maps(struct perf_evlist *evlist, struct perf_cpu_map *cpus, struct perf_thread_map *threads); +LIBPERF_API int perf_evlist__poll(struct perf_evlist *evlist, int timeout); #endif /* __LIBPERF_EVLIST_H */ diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map index 5eb0150ccdc6..ab8dbde1136c 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/perf/lib/libperf.map @@ -39,6 +39,7 @@ LIBPERF_0.0.1 { perf_evlist__remove; perf_evlist__next; perf_evlist__set_maps; + perf_evlist__poll; local: *; }; diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index 4629fa33c8ad..2b5c46813053 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -127,7 +127,7 @@ int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest } if (nr_events == before) - perf_evlist__poll(evlist, 10); + evlist__poll(evlist, 10); if (++nr_polls > 5) { pr_debug("%s: no events!\n", __func__); diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 401e8d11427b..437426be29e9 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -287,7 +287,7 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus * perf_event_attr.wakeup_events, just PERF_EVENT_SAMPLE does. */ if (total_events == before && false) - perf_evlist__poll(evlist, -1); + evlist__poll(evlist, -1); sleep(1); if (++wakeups > 5) { diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 24565f83e07d..bce3a4cb4c89 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -130,7 +130,7 @@ retry: out_init: if (!exited || !nr_exit) { - perf_evlist__poll(evlist, -1); + evlist__poll(evlist, -1); goto retry; } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 051be9a31db9..d4c7fd125ce9 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -418,9 +418,9 @@ int evlist__filter_pollfd(struct evlist *evlist, short revents_and_mask) perf_evlist__munmap_filtered, NULL); } -int perf_evlist__poll(struct evlist *evlist, int timeout) +int evlist__poll(struct evlist *evlist, int timeout) { - return fdarray__poll(&evlist->core.pollfd, timeout); + return perf_evlist__poll(&evlist->core, timeout); } static void perf_evlist__set_sid_idx(struct evlist *evlist, @@ -1736,7 +1736,7 @@ static void *perf_evlist__poll_thread(void *arg) draining = true; if (!draining) - perf_evlist__poll(evlist, 1000); + evlist__poll(evlist, 1000); for (i = 0; i < evlist->core.nr_mmaps; i++) { struct mmap *map = &evlist->mmap[i]; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 2eac8aab24a3..130d44d691b8 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -144,7 +144,7 @@ perf_evlist__find_tracepoint_by_name(struct evlist *evlist, int evlist__add_pollfd(struct evlist *evlist, int fd); int evlist__filter_pollfd(struct evlist *evlist, short revents_and_mask); -int perf_evlist__poll(struct evlist *evlist, int timeout); +int evlist__poll(struct evlist *evlist, int timeout); struct evsel *perf_evlist__id2evsel(struct evlist *evlist, u64 id); struct evsel *perf_evlist__id2evsel_strict(struct evlist *evlist, diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 6c46d7dbd263..53f31053a27a 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -918,7 +918,7 @@ static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist, if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout)) return NULL; - n = perf_evlist__poll(evlist, timeout); + n = evlist__poll(evlist, timeout); if (n < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; -- cgit v1.2.3-59-g8ed1b From 32ff3fec07b6d8e6c5cc2342f6cbbdcb224d484c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 24 Sep 2019 15:14:12 -0300 Subject: perf copyfile: Move copyfile routines to separate files Further reducing the util.c hodgepodge files. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-0i62zh7ok25znibyebgq0qs4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/Build | 1 + tools/perf/util/build-id.c | 3 +- tools/perf/util/copyfile.c | 144 +++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/copyfile.h | 16 +++++ tools/perf/util/symbol-elf.c | 2 +- tools/perf/util/util.c | 135 ---------------------------------------- tools/perf/util/util.h | 5 -- 7 files changed, 164 insertions(+), 142 deletions(-) create mode 100644 tools/perf/util/copyfile.c create mode 100644 tools/perf/util/copyfile.h (limited to 'tools') diff --git a/tools/perf/util/Build b/tools/perf/util/Build index fd89d6a8cd65..4d1894e38a81 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -3,6 +3,7 @@ perf-y += block-range.o perf-y += build-id.o perf-y += cacheline.o perf-y += config.o +perf-y += copyfile.o perf-y += ctype.o perf-y += db-export.o perf-y += env.o diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 7928c398a063..c076fc7fe025 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -7,12 +7,13 @@ * Copyright (C) 2009, 2010 Red Hat Inc. * Copyright (C) 2009, 2010 Arnaldo Carvalho de Melo */ -#include "util.h" // copyfile_ns(), lsdir(), mkdir_p(), rm_rf() +#include "util.h" // lsdir(), mkdir_p(), rm_rf() #include #include #include #include #include +#include "util/copyfile.h" #include "dso.h" #include "build-id.h" #include "event.h" diff --git a/tools/perf/util/copyfile.c b/tools/perf/util/copyfile.c new file mode 100644 index 000000000000..3fa0db136667 --- /dev/null +++ b/tools/perf/util/copyfile.c @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "util/copyfile.h" +#include "util/namespaces.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int slow_copyfile(const char *from, const char *to, struct nsinfo *nsi) +{ + int err = -1; + char *line = NULL; + size_t n; + FILE *from_fp, *to_fp; + struct nscookie nsc; + + nsinfo__mountns_enter(nsi, &nsc); + from_fp = fopen(from, "r"); + nsinfo__mountns_exit(&nsc); + if (from_fp == NULL) + goto out; + + to_fp = fopen(to, "w"); + if (to_fp == NULL) + goto out_fclose_from; + + while (getline(&line, &n, from_fp) > 0) + if (fputs(line, to_fp) == EOF) + goto out_fclose_to; + err = 0; +out_fclose_to: + fclose(to_fp); + free(line); +out_fclose_from: + fclose(from_fp); +out: + return err; +} + +int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size) +{ + void *ptr; + loff_t pgoff; + + pgoff = off_in & ~(page_size - 1); + off_in -= pgoff; + + ptr = mmap(NULL, off_in + size, PROT_READ, MAP_PRIVATE, ifd, pgoff); + if (ptr == MAP_FAILED) + return -1; + + while (size) { + ssize_t ret = pwrite(ofd, ptr + off_in, size, off_out); + if (ret < 0 && errno == EINTR) + continue; + if (ret <= 0) + break; + + size -= ret; + off_in += ret; + off_out += ret; + } + munmap(ptr, off_in + size); + + return size ? -1 : 0; +} + +static int copyfile_mode_ns(const char *from, const char *to, mode_t mode, + struct nsinfo *nsi) +{ + int fromfd, tofd; + struct stat st; + int err; + char *tmp = NULL, *ptr = NULL; + struct nscookie nsc; + + nsinfo__mountns_enter(nsi, &nsc); + err = stat(from, &st); + nsinfo__mountns_exit(&nsc); + if (err) + goto out; + err = -1; + + /* extra 'x' at the end is to reserve space for '.' */ + if (asprintf(&tmp, "%s.XXXXXXx", to) < 0) { + tmp = NULL; + goto out; + } + ptr = strrchr(tmp, '/'); + if (!ptr) + goto out; + ptr = memmove(ptr + 1, ptr, strlen(ptr) - 1); + *ptr = '.'; + + tofd = mkstemp(tmp); + if (tofd < 0) + goto out; + + if (fchmod(tofd, mode)) + goto out_close_to; + + if (st.st_size == 0) { /* /proc? do it slowly... */ + err = slow_copyfile(from, tmp, nsi); + goto out_close_to; + } + + nsinfo__mountns_enter(nsi, &nsc); + fromfd = open(from, O_RDONLY); + nsinfo__mountns_exit(&nsc); + if (fromfd < 0) + goto out_close_to; + + err = copyfile_offset(fromfd, 0, tofd, 0, st.st_size); + + close(fromfd); +out_close_to: + close(tofd); + if (!err) + err = link(tmp, to); + unlink(tmp); +out: + free(tmp); + return err; +} + +int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi) +{ + return copyfile_mode_ns(from, to, 0755, nsi); +} + +int copyfile_mode(const char *from, const char *to, mode_t mode) +{ + return copyfile_mode_ns(from, to, mode, NULL); +} + +int copyfile(const char *from, const char *to) +{ + return copyfile_mode(from, to, 0755); +} diff --git a/tools/perf/util/copyfile.h b/tools/perf/util/copyfile.h new file mode 100644 index 000000000000..e85d2f22f3cc --- /dev/null +++ b/tools/perf/util/copyfile.h @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef PERF_COPYFILE_H_ +#define PERF_COPYFILE_H_ + +#include +#include +#include + +struct nsinfo; + +int copyfile(const char *from, const char *to); +int copyfile_mode(const char *from, const char *to, mode_t mode); +int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi); +int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size); + +#endif // PERF_COPYFILE_H_ diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 6fbfdf8bf61f..66f4be1df573 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -17,7 +17,7 @@ #include "machine.h" #include "vdso.h" #include "debug.h" -#include "util.h" +#include "util/copyfile.h" #include #include #include diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index cb6fa4c98470..5eda6e19c947 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -2,10 +2,7 @@ #include "util.h" #include "debug.h" #include "event.h" -#include "namespaces.h" -#include #include -#include #include #include #include @@ -233,138 +230,6 @@ out: return list; } -static int slow_copyfile(const char *from, const char *to, struct nsinfo *nsi) -{ - int err = -1; - char *line = NULL; - size_t n; - FILE *from_fp, *to_fp; - struct nscookie nsc; - - nsinfo__mountns_enter(nsi, &nsc); - from_fp = fopen(from, "r"); - nsinfo__mountns_exit(&nsc); - if (from_fp == NULL) - goto out; - - to_fp = fopen(to, "w"); - if (to_fp == NULL) - goto out_fclose_from; - - while (getline(&line, &n, from_fp) > 0) - if (fputs(line, to_fp) == EOF) - goto out_fclose_to; - err = 0; -out_fclose_to: - fclose(to_fp); - free(line); -out_fclose_from: - fclose(from_fp); -out: - return err; -} - -int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size) -{ - void *ptr; - loff_t pgoff; - - pgoff = off_in & ~(page_size - 1); - off_in -= pgoff; - - ptr = mmap(NULL, off_in + size, PROT_READ, MAP_PRIVATE, ifd, pgoff); - if (ptr == MAP_FAILED) - return -1; - - while (size) { - ssize_t ret = pwrite(ofd, ptr + off_in, size, off_out); - if (ret < 0 && errno == EINTR) - continue; - if (ret <= 0) - break; - - size -= ret; - off_in += ret; - off_out += ret; - } - munmap(ptr, off_in + size); - - return size ? -1 : 0; -} - -static int copyfile_mode_ns(const char *from, const char *to, mode_t mode, - struct nsinfo *nsi) -{ - int fromfd, tofd; - struct stat st; - int err; - char *tmp = NULL, *ptr = NULL; - struct nscookie nsc; - - nsinfo__mountns_enter(nsi, &nsc); - err = stat(from, &st); - nsinfo__mountns_exit(&nsc); - if (err) - goto out; - err = -1; - - /* extra 'x' at the end is to reserve space for '.' */ - if (asprintf(&tmp, "%s.XXXXXXx", to) < 0) { - tmp = NULL; - goto out; - } - ptr = strrchr(tmp, '/'); - if (!ptr) - goto out; - ptr = memmove(ptr + 1, ptr, strlen(ptr) - 1); - *ptr = '.'; - - tofd = mkstemp(tmp); - if (tofd < 0) - goto out; - - if (fchmod(tofd, mode)) - goto out_close_to; - - if (st.st_size == 0) { /* /proc? do it slowly... */ - err = slow_copyfile(from, tmp, nsi); - goto out_close_to; - } - - nsinfo__mountns_enter(nsi, &nsc); - fromfd = open(from, O_RDONLY); - nsinfo__mountns_exit(&nsc); - if (fromfd < 0) - goto out_close_to; - - err = copyfile_offset(fromfd, 0, tofd, 0, st.st_size); - - close(fromfd); -out_close_to: - close(tofd); - if (!err) - err = link(tmp, to); - unlink(tmp); -out: - free(tmp); - return err; -} - -int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi) -{ - return copyfile_mode_ns(from, to, 0755, nsi); -} - -int copyfile_mode(const char *from, const char *to, mode_t mode) -{ - return copyfile_mode_ns(from, to, mode, NULL); -} - -int copyfile(const char *from, const char *to) -{ - return copyfile_mode(from, to, 0755); -} - size_t hex_width(u64 v) { size_t n = 1; diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index b78b73e5bb32..9969b8b46f7c 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -17,7 +17,6 @@ void usage(const char *err) __noreturn; void die(const char *err, ...) __noreturn __printf(1, 2); struct dirent; -struct nsinfo; struct strlist; int mkdir_p(char *path, mode_t mode); @@ -25,10 +24,6 @@ int rm_rf(const char *path); int rm_rf_perf_data(const char *path); struct strlist *lsdir(const char *name, bool (*filter)(const char *, struct dirent *)); bool lsdir_no_dot_filter(const char *name, struct dirent *d); -int copyfile(const char *from, const char *to); -int copyfile_mode(const char *from, const char *to, mode_t mode); -int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi); -int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size); size_t hex_width(u64 v); -- cgit v1.2.3-59-g8ed1b From 90a48843a18663a25aa70c6d717d38a4443e5e29 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Wed, 25 Sep 2019 15:12:42 +0200 Subject: KVM: selftests: fix ucall on x86 After commit e8bb4755eea2("KVM: selftests: Split ucall.c into architecture specific files") selftests which use ucall on x86 started segfaulting and apparently it's gcc to blame: it "optimizes" ucall() function throwing away va_start/va_end part because it thinks the structure is not being used. Previously, it couldn't do that because the there was also MMIO version and the decision which particular implementation to use was done at runtime. With older gccs it's possible to solve the problem by adding 'volatile' to 'struct ucall' but at least with gcc-8.3 this trick doesn't work. 'memory' clobber seems to do the job. Signed-off-by: Vitaly Kuznetsov Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/lib/x86_64/ucall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/lib/x86_64/ucall.c b/tools/testing/selftests/kvm/lib/x86_64/ucall.c index 4bfc9a90b1de..da4d89ad5419 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/ucall.c +++ b/tools/testing/selftests/kvm/lib/x86_64/ucall.c @@ -32,7 +32,7 @@ void ucall(uint64_t cmd, int nargs, ...) va_end(va); asm volatile("in %[port], %%al" - : : [port] "d" (UCALL_PIO_PORT), "D" (&uc) : "rax"); + : : [port] "d" (UCALL_PIO_PORT), "D" (&uc) : "rax", "memory"); } uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc) -- cgit v1.2.3-59-g8ed1b From 4b526de50e39b38cd828396267379183c7c21354 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 19 Jul 2019 13:41:06 -0700 Subject: KVM: x86: Check kvm_rebooting in kvm_spurious_fault() Explicitly check kvm_rebooting in kvm_spurious_fault() prior to invoking BUG(), as opposed to assuming the caller has already done so. Letting kvm_spurious_fault() be called "directly" will allow VMX to better optimize its low level assembly flows. As a happy side effect, kvm_spurious_fault() no longer needs to be marked as a dead end since it doesn't unconditionally BUG(). Acked-by: Paolo Bonzini Cc: Josh Poimboeuf Signed-off-by: Sean Christopherson Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/x86.c | 3 ++- tools/objtool/check.c | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index c5ed92482e2c..de0c9d8097c2 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1534,7 +1534,7 @@ enum { #define kvm_arch_vcpu_memslots_id(vcpu) ((vcpu)->arch.hflags & HF_SMM_MASK ? 1 : 0) #define kvm_memslots_for_spte_role(kvm, role) __kvm_memslots(kvm, (role).smm) -asmlinkage void __noreturn kvm_spurious_fault(void); +asmlinkage void kvm_spurious_fault(void); /* * Hardware virtualization extension instructions may fault if a diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c9a3d8efe1c2..0ed07d8d2caa 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -360,7 +360,8 @@ EXPORT_SYMBOL_GPL(kvm_set_apic_base); asmlinkage __visible void kvm_spurious_fault(void) { /* Fault while not rebooting. We want the trace. */ - BUG(); + if (!kvm_rebooting) + BUG(); } EXPORT_SYMBOL_GPL(kvm_spurious_fault); diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 176f2f084060..044c9a3cb247 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -138,7 +138,6 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func, "do_task_dead", "__module_put_and_exit", "complete_and_exit", - "kvm_spurious_fault", "__reiserfs_panic", "lbug_with_loc", "fortify_panic", -- cgit v1.2.3-59-g8ed1b From 19a4ff534bb09686f53800564cb977bad2177c00 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 19 Sep 2019 13:37:03 -0400 Subject: selftests, sched/membarrier: Add multi-threaded test membarrier commands cover very different code paths if they are in a single-threaded vs multi-threaded process. Therefore, exercise both scenarios in the kernel selftests to increase coverage of this selftest. Signed-off-by: Mathieu Desnoyers Signed-off-by: Peter Zijlstra (Intel) Cc: Chris Metcalf Cc: Christoph Lameter Cc: Eric W. Biederman Cc: Kirill Tkhai Cc: Linus Torvalds Cc: Mike Galbraith Cc: Oleg Nesterov Cc: Paul E. McKenney Cc: Peter Zijlstra Cc: Russell King - ARM Linux admin Cc: Shuah Khan Cc: Thomas Gleixner Link: https://lkml.kernel.org/r/20190919173705.2181-6-mathieu.desnoyers@efficios.com Signed-off-by: Ingo Molnar --- tools/testing/selftests/membarrier/.gitignore | 3 +- tools/testing/selftests/membarrier/Makefile | 5 +- .../testing/selftests/membarrier/membarrier_test.c | 313 -------------------- .../selftests/membarrier/membarrier_test_impl.h | 317 +++++++++++++++++++++ .../membarrier/membarrier_test_multi_thread.c | 73 +++++ .../membarrier/membarrier_test_single_thread.c | 24 ++ 6 files changed, 419 insertions(+), 316 deletions(-) delete mode 100644 tools/testing/selftests/membarrier/membarrier_test.c create mode 100644 tools/testing/selftests/membarrier/membarrier_test_impl.h create mode 100644 tools/testing/selftests/membarrier/membarrier_test_multi_thread.c create mode 100644 tools/testing/selftests/membarrier/membarrier_test_single_thread.c (limited to 'tools') diff --git a/tools/testing/selftests/membarrier/.gitignore b/tools/testing/selftests/membarrier/.gitignore index 020c44f49a9e..f2f7ec0a99b4 100644 --- a/tools/testing/selftests/membarrier/.gitignore +++ b/tools/testing/selftests/membarrier/.gitignore @@ -1 +1,2 @@ -membarrier_test +membarrier_test_multi_thread +membarrier_test_single_thread diff --git a/tools/testing/selftests/membarrier/Makefile b/tools/testing/selftests/membarrier/Makefile index 97e3bdf3d1e9..34d1c81a2324 100644 --- a/tools/testing/selftests/membarrier/Makefile +++ b/tools/testing/selftests/membarrier/Makefile @@ -1,7 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-only CFLAGS += -g -I../../../../usr/include/ +LDLIBS += -lpthread -TEST_GEN_PROGS := membarrier_test +TEST_GEN_PROGS := membarrier_test_single_thread \ + membarrier_test_multi_thread include ../lib.mk - diff --git a/tools/testing/selftests/membarrier/membarrier_test.c b/tools/testing/selftests/membarrier/membarrier_test.c deleted file mode 100644 index 70b4ddbf126b..000000000000 --- a/tools/testing/selftests/membarrier/membarrier_test.c +++ /dev/null @@ -1,313 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#define _GNU_SOURCE -#include -#include -#include -#include -#include - -#include "../kselftest.h" - -static int sys_membarrier(int cmd, int flags) -{ - return syscall(__NR_membarrier, cmd, flags); -} - -static int test_membarrier_cmd_fail(void) -{ - int cmd = -1, flags = 0; - const char *test_name = "sys membarrier invalid command"; - - if (sys_membarrier(cmd, flags) != -1) { - ksft_exit_fail_msg( - "%s test: command = %d, flags = %d. Should fail, but passed\n", - test_name, cmd, flags); - } - if (errno != EINVAL) { - ksft_exit_fail_msg( - "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n", - test_name, flags, EINVAL, strerror(EINVAL), - errno, strerror(errno)); - } - - ksft_test_result_pass( - "%s test: command = %d, flags = %d, errno = %d. Failed as expected\n", - test_name, cmd, flags, errno); - return 0; -} - -static int test_membarrier_flags_fail(void) -{ - int cmd = MEMBARRIER_CMD_QUERY, flags = 1; - const char *test_name = "sys membarrier MEMBARRIER_CMD_QUERY invalid flags"; - - if (sys_membarrier(cmd, flags) != -1) { - ksft_exit_fail_msg( - "%s test: flags = %d. Should fail, but passed\n", - test_name, flags); - } - if (errno != EINVAL) { - ksft_exit_fail_msg( - "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n", - test_name, flags, EINVAL, strerror(EINVAL), - errno, strerror(errno)); - } - - ksft_test_result_pass( - "%s test: flags = %d, errno = %d. Failed as expected\n", - test_name, flags, errno); - return 0; -} - -static int test_membarrier_global_success(void) -{ - int cmd = MEMBARRIER_CMD_GLOBAL, flags = 0; - const char *test_name = "sys membarrier MEMBARRIER_CMD_GLOBAL"; - - if (sys_membarrier(cmd, flags) != 0) { - ksft_exit_fail_msg( - "%s test: flags = %d, errno = %d\n", - test_name, flags, errno); - } - - ksft_test_result_pass( - "%s test: flags = %d\n", test_name, flags); - return 0; -} - -static int test_membarrier_private_expedited_fail(void) -{ - int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0; - const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED not registered failure"; - - if (sys_membarrier(cmd, flags) != -1) { - ksft_exit_fail_msg( - "%s test: flags = %d. Should fail, but passed\n", - test_name, flags); - } - if (errno != EPERM) { - ksft_exit_fail_msg( - "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n", - test_name, flags, EPERM, strerror(EPERM), - errno, strerror(errno)); - } - - ksft_test_result_pass( - "%s test: flags = %d, errno = %d\n", - test_name, flags, errno); - return 0; -} - -static int test_membarrier_register_private_expedited_success(void) -{ - int cmd = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, flags = 0; - const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED"; - - if (sys_membarrier(cmd, flags) != 0) { - ksft_exit_fail_msg( - "%s test: flags = %d, errno = %d\n", - test_name, flags, errno); - } - - ksft_test_result_pass( - "%s test: flags = %d\n", - test_name, flags); - return 0; -} - -static int test_membarrier_private_expedited_success(void) -{ - int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0; - const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED"; - - if (sys_membarrier(cmd, flags) != 0) { - ksft_exit_fail_msg( - "%s test: flags = %d, errno = %d\n", - test_name, flags, errno); - } - - ksft_test_result_pass( - "%s test: flags = %d\n", - test_name, flags); - return 0; -} - -static int test_membarrier_private_expedited_sync_core_fail(void) -{ - int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE, flags = 0; - const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE not registered failure"; - - if (sys_membarrier(cmd, flags) != -1) { - ksft_exit_fail_msg( - "%s test: flags = %d. Should fail, but passed\n", - test_name, flags); - } - if (errno != EPERM) { - ksft_exit_fail_msg( - "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n", - test_name, flags, EPERM, strerror(EPERM), - errno, strerror(errno)); - } - - ksft_test_result_pass( - "%s test: flags = %d, errno = %d\n", - test_name, flags, errno); - return 0; -} - -static int test_membarrier_register_private_expedited_sync_core_success(void) -{ - int cmd = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE, flags = 0; - const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE"; - - if (sys_membarrier(cmd, flags) != 0) { - ksft_exit_fail_msg( - "%s test: flags = %d, errno = %d\n", - test_name, flags, errno); - } - - ksft_test_result_pass( - "%s test: flags = %d\n", - test_name, flags); - return 0; -} - -static int test_membarrier_private_expedited_sync_core_success(void) -{ - int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0; - const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE"; - - if (sys_membarrier(cmd, flags) != 0) { - ksft_exit_fail_msg( - "%s test: flags = %d, errno = %d\n", - test_name, flags, errno); - } - - ksft_test_result_pass( - "%s test: flags = %d\n", - test_name, flags); - return 0; -} - -static int test_membarrier_register_global_expedited_success(void) -{ - int cmd = MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED, flags = 0; - const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED"; - - if (sys_membarrier(cmd, flags) != 0) { - ksft_exit_fail_msg( - "%s test: flags = %d, errno = %d\n", - test_name, flags, errno); - } - - ksft_test_result_pass( - "%s test: flags = %d\n", - test_name, flags); - return 0; -} - -static int test_membarrier_global_expedited_success(void) -{ - int cmd = MEMBARRIER_CMD_GLOBAL_EXPEDITED, flags = 0; - const char *test_name = "sys membarrier MEMBARRIER_CMD_GLOBAL_EXPEDITED"; - - if (sys_membarrier(cmd, flags) != 0) { - ksft_exit_fail_msg( - "%s test: flags = %d, errno = %d\n", - test_name, flags, errno); - } - - ksft_test_result_pass( - "%s test: flags = %d\n", - test_name, flags); - return 0; -} - -static int test_membarrier(void) -{ - int status; - - status = test_membarrier_cmd_fail(); - if (status) - return status; - status = test_membarrier_flags_fail(); - if (status) - return status; - status = test_membarrier_global_success(); - if (status) - return status; - status = test_membarrier_private_expedited_fail(); - if (status) - return status; - status = test_membarrier_register_private_expedited_success(); - if (status) - return status; - status = test_membarrier_private_expedited_success(); - if (status) - return status; - status = sys_membarrier(MEMBARRIER_CMD_QUERY, 0); - if (status < 0) { - ksft_test_result_fail("sys_membarrier() failed\n"); - return status; - } - if (status & MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE) { - status = test_membarrier_private_expedited_sync_core_fail(); - if (status) - return status; - status = test_membarrier_register_private_expedited_sync_core_success(); - if (status) - return status; - status = test_membarrier_private_expedited_sync_core_success(); - if (status) - return status; - } - /* - * It is valid to send a global membarrier from a non-registered - * process. - */ - status = test_membarrier_global_expedited_success(); - if (status) - return status; - status = test_membarrier_register_global_expedited_success(); - if (status) - return status; - status = test_membarrier_global_expedited_success(); - if (status) - return status; - return 0; -} - -static int test_membarrier_query(void) -{ - int flags = 0, ret; - - ret = sys_membarrier(MEMBARRIER_CMD_QUERY, flags); - if (ret < 0) { - if (errno == ENOSYS) { - /* - * It is valid to build a kernel with - * CONFIG_MEMBARRIER=n. However, this skips the tests. - */ - ksft_exit_skip( - "sys membarrier (CONFIG_MEMBARRIER) is disabled.\n"); - } - ksft_exit_fail_msg("sys_membarrier() failed\n"); - } - if (!(ret & MEMBARRIER_CMD_GLOBAL)) - ksft_exit_skip( - "sys_membarrier unsupported: CMD_GLOBAL not found.\n"); - - ksft_test_result_pass("sys_membarrier available\n"); - return 0; -} - -int main(int argc, char **argv) -{ - ksft_print_header(); - ksft_set_plan(13); - - test_membarrier_query(); - test_membarrier(); - - return ksft_exit_pass(); -} diff --git a/tools/testing/selftests/membarrier/membarrier_test_impl.h b/tools/testing/selftests/membarrier/membarrier_test_impl.h new file mode 100644 index 000000000000..186be69f0a59 --- /dev/null +++ b/tools/testing/selftests/membarrier/membarrier_test_impl.h @@ -0,0 +1,317 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +#include "../kselftest.h" + +static int sys_membarrier(int cmd, int flags) +{ + return syscall(__NR_membarrier, cmd, flags); +} + +static int test_membarrier_cmd_fail(void) +{ + int cmd = -1, flags = 0; + const char *test_name = "sys membarrier invalid command"; + + if (sys_membarrier(cmd, flags) != -1) { + ksft_exit_fail_msg( + "%s test: command = %d, flags = %d. Should fail, but passed\n", + test_name, cmd, flags); + } + if (errno != EINVAL) { + ksft_exit_fail_msg( + "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n", + test_name, flags, EINVAL, strerror(EINVAL), + errno, strerror(errno)); + } + + ksft_test_result_pass( + "%s test: command = %d, flags = %d, errno = %d. Failed as expected\n", + test_name, cmd, flags, errno); + return 0; +} + +static int test_membarrier_flags_fail(void) +{ + int cmd = MEMBARRIER_CMD_QUERY, flags = 1; + const char *test_name = "sys membarrier MEMBARRIER_CMD_QUERY invalid flags"; + + if (sys_membarrier(cmd, flags) != -1) { + ksft_exit_fail_msg( + "%s test: flags = %d. Should fail, but passed\n", + test_name, flags); + } + if (errno != EINVAL) { + ksft_exit_fail_msg( + "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n", + test_name, flags, EINVAL, strerror(EINVAL), + errno, strerror(errno)); + } + + ksft_test_result_pass( + "%s test: flags = %d, errno = %d. Failed as expected\n", + test_name, flags, errno); + return 0; +} + +static int test_membarrier_global_success(void) +{ + int cmd = MEMBARRIER_CMD_GLOBAL, flags = 0; + const char *test_name = "sys membarrier MEMBARRIER_CMD_GLOBAL"; + + if (sys_membarrier(cmd, flags) != 0) { + ksft_exit_fail_msg( + "%s test: flags = %d, errno = %d\n", + test_name, flags, errno); + } + + ksft_test_result_pass( + "%s test: flags = %d\n", test_name, flags); + return 0; +} + +static int test_membarrier_private_expedited_fail(void) +{ + int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0; + const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED not registered failure"; + + if (sys_membarrier(cmd, flags) != -1) { + ksft_exit_fail_msg( + "%s test: flags = %d. Should fail, but passed\n", + test_name, flags); + } + if (errno != EPERM) { + ksft_exit_fail_msg( + "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n", + test_name, flags, EPERM, strerror(EPERM), + errno, strerror(errno)); + } + + ksft_test_result_pass( + "%s test: flags = %d, errno = %d\n", + test_name, flags, errno); + return 0; +} + +static int test_membarrier_register_private_expedited_success(void) +{ + int cmd = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, flags = 0; + const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED"; + + if (sys_membarrier(cmd, flags) != 0) { + ksft_exit_fail_msg( + "%s test: flags = %d, errno = %d\n", + test_name, flags, errno); + } + + ksft_test_result_pass( + "%s test: flags = %d\n", + test_name, flags); + return 0; +} + +static int test_membarrier_private_expedited_success(void) +{ + int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0; + const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED"; + + if (sys_membarrier(cmd, flags) != 0) { + ksft_exit_fail_msg( + "%s test: flags = %d, errno = %d\n", + test_name, flags, errno); + } + + ksft_test_result_pass( + "%s test: flags = %d\n", + test_name, flags); + return 0; +} + +static int test_membarrier_private_expedited_sync_core_fail(void) +{ + int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE, flags = 0; + const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE not registered failure"; + + if (sys_membarrier(cmd, flags) != -1) { + ksft_exit_fail_msg( + "%s test: flags = %d. Should fail, but passed\n", + test_name, flags); + } + if (errno != EPERM) { + ksft_exit_fail_msg( + "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n", + test_name, flags, EPERM, strerror(EPERM), + errno, strerror(errno)); + } + + ksft_test_result_pass( + "%s test: flags = %d, errno = %d\n", + test_name, flags, errno); + return 0; +} + +static int test_membarrier_register_private_expedited_sync_core_success(void) +{ + int cmd = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE, flags = 0; + const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE"; + + if (sys_membarrier(cmd, flags) != 0) { + ksft_exit_fail_msg( + "%s test: flags = %d, errno = %d\n", + test_name, flags, errno); + } + + ksft_test_result_pass( + "%s test: flags = %d\n", + test_name, flags); + return 0; +} + +static int test_membarrier_private_expedited_sync_core_success(void) +{ + int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0; + const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE"; + + if (sys_membarrier(cmd, flags) != 0) { + ksft_exit_fail_msg( + "%s test: flags = %d, errno = %d\n", + test_name, flags, errno); + } + + ksft_test_result_pass( + "%s test: flags = %d\n", + test_name, flags); + return 0; +} + +static int test_membarrier_register_global_expedited_success(void) +{ + int cmd = MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED, flags = 0; + const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED"; + + if (sys_membarrier(cmd, flags) != 0) { + ksft_exit_fail_msg( + "%s test: flags = %d, errno = %d\n", + test_name, flags, errno); + } + + ksft_test_result_pass( + "%s test: flags = %d\n", + test_name, flags); + return 0; +} + +static int test_membarrier_global_expedited_success(void) +{ + int cmd = MEMBARRIER_CMD_GLOBAL_EXPEDITED, flags = 0; + const char *test_name = "sys membarrier MEMBARRIER_CMD_GLOBAL_EXPEDITED"; + + if (sys_membarrier(cmd, flags) != 0) { + ksft_exit_fail_msg( + "%s test: flags = %d, errno = %d\n", + test_name, flags, errno); + } + + ksft_test_result_pass( + "%s test: flags = %d\n", + test_name, flags); + return 0; +} + +static int test_membarrier_fail(void) +{ + int status; + + status = test_membarrier_cmd_fail(); + if (status) + return status; + status = test_membarrier_flags_fail(); + if (status) + return status; + status = test_membarrier_private_expedited_fail(); + if (status) + return status; + status = sys_membarrier(MEMBARRIER_CMD_QUERY, 0); + if (status < 0) { + ksft_test_result_fail("sys_membarrier() failed\n"); + return status; + } + if (status & MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE) { + status = test_membarrier_private_expedited_sync_core_fail(); + if (status) + return status; + } + return 0; +} + +static int test_membarrier_success(void) +{ + int status; + + status = test_membarrier_global_success(); + if (status) + return status; + status = test_membarrier_register_private_expedited_success(); + if (status) + return status; + status = test_membarrier_private_expedited_success(); + if (status) + return status; + status = sys_membarrier(MEMBARRIER_CMD_QUERY, 0); + if (status < 0) { + ksft_test_result_fail("sys_membarrier() failed\n"); + return status; + } + if (status & MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE) { + status = test_membarrier_register_private_expedited_sync_core_success(); + if (status) + return status; + status = test_membarrier_private_expedited_sync_core_success(); + if (status) + return status; + } + /* + * It is valid to send a global membarrier from a non-registered + * process. + */ + status = test_membarrier_global_expedited_success(); + if (status) + return status; + status = test_membarrier_register_global_expedited_success(); + if (status) + return status; + status = test_membarrier_global_expedited_success(); + if (status) + return status; + return 0; +} + +static int test_membarrier_query(void) +{ + int flags = 0, ret; + + ret = sys_membarrier(MEMBARRIER_CMD_QUERY, flags); + if (ret < 0) { + if (errno == ENOSYS) { + /* + * It is valid to build a kernel with + * CONFIG_MEMBARRIER=n. However, this skips the tests. + */ + ksft_exit_skip( + "sys membarrier (CONFIG_MEMBARRIER) is disabled.\n"); + } + ksft_exit_fail_msg("sys_membarrier() failed\n"); + } + if (!(ret & MEMBARRIER_CMD_GLOBAL)) + ksft_exit_skip( + "sys_membarrier unsupported: CMD_GLOBAL not found.\n"); + + ksft_test_result_pass("sys_membarrier available\n"); + return 0; +} diff --git a/tools/testing/selftests/membarrier/membarrier_test_multi_thread.c b/tools/testing/selftests/membarrier/membarrier_test_multi_thread.c new file mode 100644 index 000000000000..ac5613e5b0eb --- /dev/null +++ b/tools/testing/selftests/membarrier/membarrier_test_multi_thread.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0 +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +#include "membarrier_test_impl.h" + +static int thread_ready, thread_quit; +static pthread_mutex_t test_membarrier_thread_mutex = + PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t test_membarrier_thread_cond = + PTHREAD_COND_INITIALIZER; + +void *test_membarrier_thread(void *arg) +{ + pthread_mutex_lock(&test_membarrier_thread_mutex); + thread_ready = 1; + pthread_cond_broadcast(&test_membarrier_thread_cond); + pthread_mutex_unlock(&test_membarrier_thread_mutex); + + pthread_mutex_lock(&test_membarrier_thread_mutex); + while (!thread_quit) + pthread_cond_wait(&test_membarrier_thread_cond, + &test_membarrier_thread_mutex); + pthread_mutex_unlock(&test_membarrier_thread_mutex); + + return NULL; +} + +static int test_mt_membarrier(void) +{ + int i; + pthread_t test_thread; + + pthread_create(&test_thread, NULL, + test_membarrier_thread, NULL); + + pthread_mutex_lock(&test_membarrier_thread_mutex); + while (!thread_ready) + pthread_cond_wait(&test_membarrier_thread_cond, + &test_membarrier_thread_mutex); + pthread_mutex_unlock(&test_membarrier_thread_mutex); + + test_membarrier_fail(); + + test_membarrier_success(); + + pthread_mutex_lock(&test_membarrier_thread_mutex); + thread_quit = 1; + pthread_cond_broadcast(&test_membarrier_thread_cond); + pthread_mutex_unlock(&test_membarrier_thread_mutex); + + pthread_join(test_thread, NULL); + + return 0; +} + +int main(int argc, char **argv) +{ + ksft_print_header(); + ksft_set_plan(13); + + test_membarrier_query(); + + /* Multi-threaded */ + test_mt_membarrier(); + + return ksft_exit_pass(); +} diff --git a/tools/testing/selftests/membarrier/membarrier_test_single_thread.c b/tools/testing/selftests/membarrier/membarrier_test_single_thread.c new file mode 100644 index 000000000000..c1c963902854 --- /dev/null +++ b/tools/testing/selftests/membarrier/membarrier_test_single_thread.c @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0 +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +#include "membarrier_test_impl.h" + +int main(int argc, char **argv) +{ + ksft_print_header(); + ksft_set_plan(13); + + test_membarrier_query(); + + test_membarrier_fail(); + + test_membarrier_success(); + + return ksft_exit_pass(); +} -- cgit v1.2.3-59-g8ed1b From 9620bc361ac6e292ad2d6997b2f59f41f4e17862 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 25 Sep 2019 15:06:59 -0300 Subject: perf evsel: Remove need for symbol_conf in evsel_fprintf.c So that we an later link it to the python binding without having to drag the symbol object files. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-8823tveyasocnuoelq4qopwf@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-sched.c | 2 +- tools/perf/builtin-script.c | 6 ++++-- tools/perf/builtin-trace.c | 2 +- tools/perf/util/evsel.h | 7 ++++--- tools/perf/util/evsel_fprintf.c | 14 ++++++-------- 5 files changed, 16 insertions(+), 15 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 079e67a36904..f9706306fea0 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -2055,7 +2055,7 @@ static void timehist_print_sample(struct perf_sched *sched, EVSEL__PRINT_SYM | EVSEL__PRINT_ONELINE | EVSEL__PRINT_CALLCHAIN_ARROW | EVSEL__PRINT_SKIP_IGNORED, - &callchain_cursor, stdout); + &callchain_cursor, symbol_conf.bt_stop_list, stdout); out: printf("\n"); diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 22c1d114014c..0d43e2e5afff 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1325,7 +1325,8 @@ static int perf_sample__fprintf_bts(struct perf_sample *sample, } else printed += fprintf(fp, "\n"); - printed += sample__fprintf_sym(sample, al, 0, print_opts, cursor, fp); + printed += sample__fprintf_sym(sample, al, 0, print_opts, cursor, + symbol_conf.bt_stop_list, fp); } /* print branch_to information */ @@ -1867,7 +1868,8 @@ static void process_event(struct perf_script *script, cursor = &callchain_cursor; fputc(cursor ? '\n' : ' ', fp); - sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor, fp); + sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor, + symbol_conf.bt_stop_list, fp); } if (PRINT_FIELD(IREGS)) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index c52c3120a811..318225c8d7a7 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2076,7 +2076,7 @@ static int trace__fprintf_callchain(struct trace *trace, struct perf_sample *sam EVSEL__PRINT_DSO | EVSEL__PRINT_UNKNOWN_AS_ADDR; - return sample__fprintf_callchain(sample, 38, print_opts, &callchain_cursor, trace->output); + return sample__fprintf_callchain(sample, 38, print_opts, &callchain_cursor, symbol_conf.bt_stop_list, trace->output); } static const char *errno_to_name(struct evsel *evsel, int err) diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index a5b29ac10da0..4a4c64833893 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -428,12 +428,13 @@ int perf_evsel__fprintf(struct evsel *evsel, struct callchain_cursor; int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment, - unsigned int print_opts, - struct callchain_cursor *cursor, FILE *fp); + unsigned int print_opts, struct callchain_cursor *cursor, + struct strlist *bt_stop_list, FILE *fp); int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al, int left_alignment, unsigned int print_opts, - struct callchain_cursor *cursor, FILE *fp); + struct callchain_cursor *cursor, + struct strlist *bt_stop_list, FILE *fp); bool perf_evsel__fallback(struct evsel *evsel, int err, char *msg, size_t msgsize); diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c index a8cbdf4c2753..756b1e852db7 100644 --- a/tools/perf/util/evsel_fprintf.c +++ b/tools/perf/util/evsel_fprintf.c @@ -102,7 +102,7 @@ out: int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment, unsigned int print_opts, struct callchain_cursor *cursor, - FILE *fp) + struct strlist *bt_stop_list, FILE *fp) { int printed = 0; struct callchain_cursor_node *node; @@ -175,10 +175,8 @@ int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment, printed += fprintf(fp, "\n"); /* Add srccode here too? */ - if (symbol_conf.bt_stop_list && - node->sym && - strlist__has_entry(symbol_conf.bt_stop_list, - node->sym->name)) { + if (bt_stop_list && node->sym && + strlist__has_entry(bt_stop_list, node->sym->name)) { break; } @@ -193,7 +191,7 @@ next: int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al, int left_alignment, unsigned int print_opts, - struct callchain_cursor *cursor, FILE *fp) + struct callchain_cursor *cursor, struct strlist *bt_stop_list, FILE *fp) { int printed = 0; int print_ip = print_opts & EVSEL__PRINT_IP; @@ -204,8 +202,8 @@ int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al, int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR; if (cursor != NULL) { - printed += sample__fprintf_callchain(sample, left_alignment, - print_opts, cursor, fp); + printed += sample__fprintf_callchain(sample, left_alignment, print_opts, + cursor, bt_stop_list, fp); } else { printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " "); -- cgit v1.2.3-59-g8ed1b From ca1252779f48ece225c6003e01c675abb91cf1b4 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 24 Sep 2019 15:41:51 -0300 Subject: perf evsel: Introduce evsel_fprintf.h We already had evsel_fprintf.c, add its counterpart, so that we can reduce evsel.h a bit more. We needed a new perf_event_attr_fprintf.c file so as to have a separate object to link with the python binding in tools/perf/util/python-ext-sources and not drag symbol_conf, etc into the python binding. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-06bdmt1062d9unzgqmxwlv88@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-evlist.c | 1 + tools/perf/builtin-sched.c | 1 + tools/perf/builtin-script.c | 1 + tools/perf/builtin-trace.c | 2 + tools/perf/util/Build | 1 + tools/perf/util/evsel.c | 153 ++---------------------------- tools/perf/util/evsel.h | 51 +--------- tools/perf/util/evsel_fprintf.c | 1 + tools/perf/util/evsel_fprintf.h | 50 ++++++++++ tools/perf/util/header.c | 1 + tools/perf/util/perf_event_attr_fprintf.c | 148 +++++++++++++++++++++++++++++ tools/perf/util/python-ext-sources | 1 + 12 files changed, 218 insertions(+), 193 deletions(-) create mode 100644 tools/perf/util/evsel_fprintf.h create mode 100644 tools/perf/util/perf_event_attr_fprintf.c (limited to 'tools') diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c index 60509ce4dd28..440501994931 100644 --- a/tools/perf/builtin-evlist.c +++ b/tools/perf/builtin-evlist.c @@ -10,6 +10,7 @@ #include "perf.h" #include "util/evlist.h" #include "util/evsel.h" +#include "util/evsel_fprintf.h" #include "util/parse-events.h" #include #include "util/session.h" diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index f9706306fea0..5cacc4f84c8d 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -6,6 +6,7 @@ #include "util/cpumap.h" #include "util/evlist.h" #include "util/evsel.h" +#include "util/evsel_fprintf.h" #include "util/symbol.h" #include "util/thread.h" #include "util/header.h" diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 0d43e2e5afff..286fc70d7402 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -17,6 +17,7 @@ #include "util/trace-event.h" #include "util/evlist.h" #include "util/evsel.h" +#include "util/evsel_fprintf.h" #include "util/evswitch.h" #include "util/sort.h" #include "util/data.h" diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 318225c8d7a7..bb5130d02155 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -28,6 +28,8 @@ #include "util/dso.h" #include "util/env.h" #include "util/event.h" +#include "util/evsel.h" +#include "util/evsel_fprintf.h" #include "util/synthetic-events.h" #include "util/evlist.h" #include "util/evswitch.h" diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 4d1894e38a81..8dcfca1a882f 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -11,6 +11,7 @@ perf-y += event.o perf-y += evlist.o perf-y += evsel.o perf-y += evsel_fprintf.o +perf-y += perf_event_attr_fprintf.o perf-y += evswitch.o perf-y += find_bit.o perf-y += get_current_dir_name.o diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 9c284d2adcea..6323b0c60f6c 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -30,6 +30,7 @@ #include "counts.h" #include "event.h" #include "evsel.h" +#include "util/evsel_fprintf.h" #include "evlist.h" #include #include "thread_map.h" @@ -1443,152 +1444,6 @@ static int get_group_fd(struct evsel *evsel, int cpu, int thread) return fd; } -struct bit_names { - int bit; - const char *name; -}; - -static void __p_bits(char *buf, size_t size, u64 value, struct bit_names *bits) -{ - bool first_bit = true; - int i = 0; - - do { - if (value & bits[i].bit) { - buf += scnprintf(buf, size, "%s%s", first_bit ? "" : "|", bits[i].name); - first_bit = false; - } - } while (bits[++i].name != NULL); -} - -static void __p_sample_type(char *buf, size_t size, u64 value) -{ -#define bit_name(n) { PERF_SAMPLE_##n, #n } - struct bit_names bits[] = { - bit_name(IP), bit_name(TID), bit_name(TIME), bit_name(ADDR), - bit_name(READ), bit_name(CALLCHAIN), bit_name(ID), bit_name(CPU), - bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW), - bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER), - bit_name(IDENTIFIER), bit_name(REGS_INTR), bit_name(DATA_SRC), - bit_name(WEIGHT), bit_name(PHYS_ADDR), - { .name = NULL, } - }; -#undef bit_name - __p_bits(buf, size, value, bits); -} - -static void __p_branch_sample_type(char *buf, size_t size, u64 value) -{ -#define bit_name(n) { PERF_SAMPLE_BRANCH_##n, #n } - struct bit_names bits[] = { - bit_name(USER), bit_name(KERNEL), bit_name(HV), bit_name(ANY), - bit_name(ANY_CALL), bit_name(ANY_RETURN), bit_name(IND_CALL), - bit_name(ABORT_TX), bit_name(IN_TX), bit_name(NO_TX), - bit_name(COND), bit_name(CALL_STACK), bit_name(IND_JUMP), - bit_name(CALL), bit_name(NO_FLAGS), bit_name(NO_CYCLES), - { .name = NULL, } - }; -#undef bit_name - __p_bits(buf, size, value, bits); -} - -static void __p_read_format(char *buf, size_t size, u64 value) -{ -#define bit_name(n) { PERF_FORMAT_##n, #n } - struct bit_names bits[] = { - bit_name(TOTAL_TIME_ENABLED), bit_name(TOTAL_TIME_RUNNING), - bit_name(ID), bit_name(GROUP), - { .name = NULL, } - }; -#undef bit_name - __p_bits(buf, size, value, bits); -} - -#define BUF_SIZE 1024 - -#define p_hex(val) snprintf(buf, BUF_SIZE, "%#"PRIx64, (uint64_t)(val)) -#define p_unsigned(val) snprintf(buf, BUF_SIZE, "%"PRIu64, (uint64_t)(val)) -#define p_signed(val) snprintf(buf, BUF_SIZE, "%"PRId64, (int64_t)(val)) -#define p_sample_type(val) __p_sample_type(buf, BUF_SIZE, val) -#define p_branch_sample_type(val) __p_branch_sample_type(buf, BUF_SIZE, val) -#define p_read_format(val) __p_read_format(buf, BUF_SIZE, val) - -#define PRINT_ATTRn(_n, _f, _p) \ -do { \ - if (attr->_f) { \ - _p(attr->_f); \ - ret += attr__fprintf(fp, _n, buf, priv);\ - } \ -} while (0) - -#define PRINT_ATTRf(_f, _p) PRINT_ATTRn(#_f, _f, _p) - -int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr, - attr__fprintf_f attr__fprintf, void *priv) -{ - char buf[BUF_SIZE]; - int ret = 0; - - PRINT_ATTRf(type, p_unsigned); - PRINT_ATTRf(size, p_unsigned); - PRINT_ATTRf(config, p_hex); - PRINT_ATTRn("{ sample_period, sample_freq }", sample_period, p_unsigned); - PRINT_ATTRf(sample_type, p_sample_type); - PRINT_ATTRf(read_format, p_read_format); - - PRINT_ATTRf(disabled, p_unsigned); - PRINT_ATTRf(inherit, p_unsigned); - PRINT_ATTRf(pinned, p_unsigned); - PRINT_ATTRf(exclusive, p_unsigned); - PRINT_ATTRf(exclude_user, p_unsigned); - PRINT_ATTRf(exclude_kernel, p_unsigned); - PRINT_ATTRf(exclude_hv, p_unsigned); - PRINT_ATTRf(exclude_idle, p_unsigned); - PRINT_ATTRf(mmap, p_unsigned); - PRINT_ATTRf(comm, p_unsigned); - PRINT_ATTRf(freq, p_unsigned); - PRINT_ATTRf(inherit_stat, p_unsigned); - PRINT_ATTRf(enable_on_exec, p_unsigned); - PRINT_ATTRf(task, p_unsigned); - PRINT_ATTRf(watermark, p_unsigned); - PRINT_ATTRf(precise_ip, p_unsigned); - PRINT_ATTRf(mmap_data, p_unsigned); - PRINT_ATTRf(sample_id_all, p_unsigned); - PRINT_ATTRf(exclude_host, p_unsigned); - PRINT_ATTRf(exclude_guest, p_unsigned); - PRINT_ATTRf(exclude_callchain_kernel, p_unsigned); - PRINT_ATTRf(exclude_callchain_user, p_unsigned); - PRINT_ATTRf(mmap2, p_unsigned); - PRINT_ATTRf(comm_exec, p_unsigned); - PRINT_ATTRf(use_clockid, p_unsigned); - PRINT_ATTRf(context_switch, p_unsigned); - PRINT_ATTRf(write_backward, p_unsigned); - PRINT_ATTRf(namespaces, p_unsigned); - PRINT_ATTRf(ksymbol, p_unsigned); - PRINT_ATTRf(bpf_event, p_unsigned); - PRINT_ATTRf(aux_output, p_unsigned); - - PRINT_ATTRn("{ wakeup_events, wakeup_watermark }", wakeup_events, p_unsigned); - PRINT_ATTRf(bp_type, p_unsigned); - PRINT_ATTRn("{ bp_addr, config1 }", bp_addr, p_hex); - PRINT_ATTRn("{ bp_len, config2 }", bp_len, p_hex); - PRINT_ATTRf(branch_sample_type, p_branch_sample_type); - PRINT_ATTRf(sample_regs_user, p_hex); - PRINT_ATTRf(sample_stack_user, p_unsigned); - PRINT_ATTRf(clockid, p_signed); - PRINT_ATTRf(sample_regs_intr, p_hex); - PRINT_ATTRf(aux_watermark, p_unsigned); - PRINT_ATTRf(sample_max_stack, p_unsigned); - - return ret; -} - -static int __open_attr__fprintf(FILE *fp, const char *name, const char *val, - void *priv __maybe_unused) -{ - return fprintf(fp, " %-32s %s\n", name, val); -} - static void perf_evsel__remove_fd(struct evsel *pos, int nr_cpus, int nr_threads, int thread_idx) @@ -1659,6 +1514,12 @@ static bool ignore_missing_thread(struct evsel *evsel, return true; } +static int __open_attr__fprintf(FILE *fp, const char *name, const char *val, + void *priv __maybe_unused) +{ + return fprintf(fp, " %-32s %s\n", name, val); +} + static void display_attr(struct perf_event_attr *attr) { if (verbose >= 2) { diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 4a4c64833893..48183b5f5f83 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -13,12 +12,6 @@ #include "symbol_conf.h" #include -struct addr_location; -struct evsel; -union perf_event; - -struct cgroup; - /* * The 'struct perf_evsel_config_term' is used to pass event * specific configuration data to perf_evsel__config routine. @@ -62,7 +55,11 @@ struct perf_evsel_config_term { bool weak; }; +struct bpf_object; +struct cgroup; +struct perf_counts; struct perf_stat_evsel; +union perf_event; typedef int (perf_evsel__sb_cb_t)(union perf_event *event, void *data); @@ -71,9 +68,6 @@ enum perf_tool_event { PERF_TOOL_DURATION_TIME = 1, }; -struct bpf_object; -struct perf_counts; - /** struct evsel - event selector * * @evlist - evlist this evsel is in, if it is in one. @@ -404,38 +398,6 @@ static inline bool perf_evsel__is_clock(struct evsel *evsel) perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK); } -struct perf_attr_details { - bool freq; - bool verbose; - bool event_group; - bool force; - bool trace_fields; -}; - -int perf_evsel__fprintf(struct evsel *evsel, - struct perf_attr_details *details, FILE *fp); - -#define EVSEL__PRINT_IP (1<<0) -#define EVSEL__PRINT_SYM (1<<1) -#define EVSEL__PRINT_DSO (1<<2) -#define EVSEL__PRINT_SYMOFFSET (1<<3) -#define EVSEL__PRINT_ONELINE (1<<4) -#define EVSEL__PRINT_SRCLINE (1<<5) -#define EVSEL__PRINT_UNKNOWN_AS_ADDR (1<<6) -#define EVSEL__PRINT_CALLCHAIN_ARROW (1<<7) -#define EVSEL__PRINT_SKIP_IGNORED (1<<8) - -struct callchain_cursor; - -int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment, - unsigned int print_opts, struct callchain_cursor *cursor, - struct strlist *bt_stop_list, FILE *fp); - -int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al, - int left_alignment, unsigned int print_opts, - struct callchain_cursor *cursor, - struct strlist *bt_stop_list, FILE *fp); - bool perf_evsel__fallback(struct evsel *evsel, int err, char *msg, size_t msgsize); int perf_evsel__open_strerror(struct evsel *evsel, struct target *target, @@ -468,11 +430,6 @@ static inline bool evsel__has_callchain(const struct evsel *evsel) return (evsel->core.attr.sample_type & PERF_SAMPLE_CALLCHAIN) != 0; } -typedef int (*attr__fprintf_f)(FILE *, const char *, const char *, void *); - -int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr, - attr__fprintf_f attr__fprintf, void *priv); - struct perf_env *perf_evsel__env(struct evsel *evsel); int perf_evsel__store_ids(struct evsel *evsel, struct evlist *evlist); diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c index 756b1e852db7..028df7afb0dc 100644 --- a/tools/perf/util/evsel_fprintf.c +++ b/tools/perf/util/evsel_fprintf.c @@ -4,6 +4,7 @@ #include #include #include "evsel.h" +#include "util/evsel_fprintf.h" #include "util/event.h" #include "callchain.h" #include "map.h" diff --git a/tools/perf/util/evsel_fprintf.h b/tools/perf/util/evsel_fprintf.h new file mode 100644 index 000000000000..47e6c8456bb1 --- /dev/null +++ b/tools/perf/util/evsel_fprintf.h @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef __PERF_EVSEL_FPRINTF_H +#define __PERF_EVSEL_FPRINTF_H 1 + +#include +#include + +struct evsel; + +struct perf_attr_details { + bool freq; + bool verbose; + bool event_group; + bool force; + bool trace_fields; +}; + +int perf_evsel__fprintf(struct evsel *evsel, + struct perf_attr_details *details, FILE *fp); + +#define EVSEL__PRINT_IP (1<<0) +#define EVSEL__PRINT_SYM (1<<1) +#define EVSEL__PRINT_DSO (1<<2) +#define EVSEL__PRINT_SYMOFFSET (1<<3) +#define EVSEL__PRINT_ONELINE (1<<4) +#define EVSEL__PRINT_SRCLINE (1<<5) +#define EVSEL__PRINT_UNKNOWN_AS_ADDR (1<<6) +#define EVSEL__PRINT_CALLCHAIN_ARROW (1<<7) +#define EVSEL__PRINT_SKIP_IGNORED (1<<8) + +struct addr_location; +struct perf_event_attr; +struct perf_sample; +struct callchain_cursor; +struct strlist; + +int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment, + unsigned int print_opts, struct callchain_cursor *cursor, + struct strlist *bt_stop_list, FILE *fp); + +int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al, + int left_alignment, unsigned int print_opts, + struct callchain_cursor *cursor, + struct strlist *bt_stop_list, FILE *fp); + +typedef int (*attr__fprintf_f)(FILE *, const char *, const char *, void *); + +int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr, + attr__fprintf_f attr__fprintf, void *priv); +#endif // __PERF_EVSEL_H diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 3b24b4974c5f..86d9396cb131 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -25,6 +25,7 @@ #include "dso.h" #include "evlist.h" #include "evsel.h" +#include "util/evsel_fprintf.h" #include "header.h" #include "memswap.h" #include "trace-event.h" diff --git a/tools/perf/util/perf_event_attr_fprintf.c b/tools/perf/util/perf_event_attr_fprintf.c new file mode 100644 index 000000000000..d4ad3f04923a --- /dev/null +++ b/tools/perf/util/perf_event_attr_fprintf.c @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include +#include "util/evsel_fprintf.h" + +struct bit_names { + int bit; + const char *name; +}; + +static void __p_bits(char *buf, size_t size, u64 value, struct bit_names *bits) +{ + bool first_bit = true; + int i = 0; + + do { + if (value & bits[i].bit) { + buf += scnprintf(buf, size, "%s%s", first_bit ? "" : "|", bits[i].name); + first_bit = false; + } + } while (bits[++i].name != NULL); +} + +static void __p_sample_type(char *buf, size_t size, u64 value) +{ +#define bit_name(n) { PERF_SAMPLE_##n, #n } + struct bit_names bits[] = { + bit_name(IP), bit_name(TID), bit_name(TIME), bit_name(ADDR), + bit_name(READ), bit_name(CALLCHAIN), bit_name(ID), bit_name(CPU), + bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW), + bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER), + bit_name(IDENTIFIER), bit_name(REGS_INTR), bit_name(DATA_SRC), + bit_name(WEIGHT), bit_name(PHYS_ADDR), + { .name = NULL, } + }; +#undef bit_name + __p_bits(buf, size, value, bits); +} + +static void __p_branch_sample_type(char *buf, size_t size, u64 value) +{ +#define bit_name(n) { PERF_SAMPLE_BRANCH_##n, #n } + struct bit_names bits[] = { + bit_name(USER), bit_name(KERNEL), bit_name(HV), bit_name(ANY), + bit_name(ANY_CALL), bit_name(ANY_RETURN), bit_name(IND_CALL), + bit_name(ABORT_TX), bit_name(IN_TX), bit_name(NO_TX), + bit_name(COND), bit_name(CALL_STACK), bit_name(IND_JUMP), + bit_name(CALL), bit_name(NO_FLAGS), bit_name(NO_CYCLES), + { .name = NULL, } + }; +#undef bit_name + __p_bits(buf, size, value, bits); +} + +static void __p_read_format(char *buf, size_t size, u64 value) +{ +#define bit_name(n) { PERF_FORMAT_##n, #n } + struct bit_names bits[] = { + bit_name(TOTAL_TIME_ENABLED), bit_name(TOTAL_TIME_RUNNING), + bit_name(ID), bit_name(GROUP), + { .name = NULL, } + }; +#undef bit_name + __p_bits(buf, size, value, bits); +} + +#define BUF_SIZE 1024 + +#define p_hex(val) snprintf(buf, BUF_SIZE, "%#"PRIx64, (uint64_t)(val)) +#define p_unsigned(val) snprintf(buf, BUF_SIZE, "%"PRIu64, (uint64_t)(val)) +#define p_signed(val) snprintf(buf, BUF_SIZE, "%"PRId64, (int64_t)(val)) +#define p_sample_type(val) __p_sample_type(buf, BUF_SIZE, val) +#define p_branch_sample_type(val) __p_branch_sample_type(buf, BUF_SIZE, val) +#define p_read_format(val) __p_read_format(buf, BUF_SIZE, val) + +#define PRINT_ATTRn(_n, _f, _p) \ +do { \ + if (attr->_f) { \ + _p(attr->_f); \ + ret += attr__fprintf(fp, _n, buf, priv);\ + } \ +} while (0) + +#define PRINT_ATTRf(_f, _p) PRINT_ATTRn(#_f, _f, _p) + +int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr, + attr__fprintf_f attr__fprintf, void *priv) +{ + char buf[BUF_SIZE]; + int ret = 0; + + PRINT_ATTRf(type, p_unsigned); + PRINT_ATTRf(size, p_unsigned); + PRINT_ATTRf(config, p_hex); + PRINT_ATTRn("{ sample_period, sample_freq }", sample_period, p_unsigned); + PRINT_ATTRf(sample_type, p_sample_type); + PRINT_ATTRf(read_format, p_read_format); + + PRINT_ATTRf(disabled, p_unsigned); + PRINT_ATTRf(inherit, p_unsigned); + PRINT_ATTRf(pinned, p_unsigned); + PRINT_ATTRf(exclusive, p_unsigned); + PRINT_ATTRf(exclude_user, p_unsigned); + PRINT_ATTRf(exclude_kernel, p_unsigned); + PRINT_ATTRf(exclude_hv, p_unsigned); + PRINT_ATTRf(exclude_idle, p_unsigned); + PRINT_ATTRf(mmap, p_unsigned); + PRINT_ATTRf(comm, p_unsigned); + PRINT_ATTRf(freq, p_unsigned); + PRINT_ATTRf(inherit_stat, p_unsigned); + PRINT_ATTRf(enable_on_exec, p_unsigned); + PRINT_ATTRf(task, p_unsigned); + PRINT_ATTRf(watermark, p_unsigned); + PRINT_ATTRf(precise_ip, p_unsigned); + PRINT_ATTRf(mmap_data, p_unsigned); + PRINT_ATTRf(sample_id_all, p_unsigned); + PRINT_ATTRf(exclude_host, p_unsigned); + PRINT_ATTRf(exclude_guest, p_unsigned); + PRINT_ATTRf(exclude_callchain_kernel, p_unsigned); + PRINT_ATTRf(exclude_callchain_user, p_unsigned); + PRINT_ATTRf(mmap2, p_unsigned); + PRINT_ATTRf(comm_exec, p_unsigned); + PRINT_ATTRf(use_clockid, p_unsigned); + PRINT_ATTRf(context_switch, p_unsigned); + PRINT_ATTRf(write_backward, p_unsigned); + PRINT_ATTRf(namespaces, p_unsigned); + PRINT_ATTRf(ksymbol, p_unsigned); + PRINT_ATTRf(bpf_event, p_unsigned); + PRINT_ATTRf(aux_output, p_unsigned); + + PRINT_ATTRn("{ wakeup_events, wakeup_watermark }", wakeup_events, p_unsigned); + PRINT_ATTRf(bp_type, p_unsigned); + PRINT_ATTRn("{ bp_addr, config1 }", bp_addr, p_hex); + PRINT_ATTRn("{ bp_len, config2 }", bp_len, p_hex); + PRINT_ATTRf(branch_sample_type, p_branch_sample_type); + PRINT_ATTRf(sample_regs_user, p_hex); + PRINT_ATTRf(sample_stack_user, p_unsigned); + PRINT_ATTRf(clockid, p_signed); + PRINT_ATTRf(sample_regs_intr, p_hex); + PRINT_ATTRf(aux_watermark, p_unsigned); + PRINT_ATTRf(sample_max_stack, p_unsigned); + + return ret; +} diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index c6dd478956f1..9af183860fbd 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources @@ -10,6 +10,7 @@ util/python.c util/cap.c util/evlist.c util/evsel.c +util/perf_event_attr_fprintf.c util/cpumap.c util/memswap.c util/mmap.c -- cgit v1.2.3-59-g8ed1b From bd70462062f36bec9d93d3900addfca4f8ec718f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 24 Sep 2019 15:45:21 -0300 Subject: perf evlist: Remove unused perf_evlist__fprintf() method Ditch it, noone is using it, one more stdio.h include in a hot header. Fix the fallout in parse-events.y, where we end up using a FILE pointer, I think due to YYDEBUG being set and in some places, like Amazon Linux 1 we don't get stdio.h included by luck, like in most other places, add a explicit stdio.h include directive. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-37k5q0lhdbo2hvvfbnnzn7og@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 13 ------------- tools/perf/util/evlist.h | 3 --- tools/perf/util/parse-events.y | 1 + 3 files changed, 1 insertion(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index d4c7fd125ce9..84c42790dab3 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1421,19 +1421,6 @@ int perf_evlist__parse_sample_timestamp(struct evlist *evlist, return perf_evsel__parse_sample_timestamp(evsel, event, timestamp); } -size_t perf_evlist__fprintf(struct evlist *evlist, FILE *fp) -{ - struct evsel *evsel; - size_t printed = 0; - - evlist__for_each_entry(evlist, evsel) { - printed += fprintf(fp, "%s%s", evsel->idx ? ", " : "", - perf_evsel__name(evsel)); - } - - return printed + fprintf(fp, "\n"); -} - int perf_evlist__strerror_open(struct evlist *evlist, int err, char *buf, size_t size) { diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 130d44d691b8..7cfe75522ba5 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include "events_stats.h" @@ -249,8 +248,6 @@ static inline struct evsel *evlist__last(struct evlist *evlist) return container_of(evsel, struct evsel, core); } -size_t perf_evlist__fprintf(struct evlist *evlist, FILE *fp); - int perf_evlist__strerror_open(struct evlist *evlist, int err, char *buf, size_t size); int perf_evlist__strerror_mmap(struct evlist *evlist, int err, char *buf, size_t size); diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index f1c36ed1cf36..65809ad67808 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -9,6 +9,7 @@ #define YYDEBUG 1 #include +#include #include #include #include -- cgit v1.2.3-59-g8ed1b From 95be9d197da6f9006f6a70a0d141498ea2488858 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 24 Sep 2019 15:56:14 -0300 Subject: perf evsel: Move config terms to a separate header Further reducing the size of util/evsel.h. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-20zr7di9eynm0272mtjfdhfc@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/util/cs-etm.c | 1 + tools/perf/builtin-top.c | 1 + tools/perf/util/evsel.c | 1 + tools/perf/util/evsel.h | 43 --------------------------------- tools/perf/util/evsel_config.h | 50 +++++++++++++++++++++++++++++++++++++++ tools/perf/util/parse-events.c | 1 + 6 files changed, 54 insertions(+), 43 deletions(-) create mode 100644 tools/perf/util/evsel_config.h (limited to 'tools') diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 2e4de211d881..ede040cf82ad 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -23,6 +23,7 @@ #include "../../util/event.h" #include "../../util/evlist.h" #include "../../util/evsel.h" +#include "../../util/evsel_config.h" #include "../../util/pmu.h" #include "../../util/cs-etm.h" #include // page_size diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 30d8eb614377..1f60124eb19b 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -27,6 +27,7 @@ #include "util/dso.h" #include "util/evlist.h" #include "util/evsel.h" +#include "util/evsel_config.h" #include "util/event.h" #include "util/machine.h" #include "util/map.h" diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 6323b0c60f6c..5591af81a070 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -30,6 +30,7 @@ #include "counts.h" #include "event.h" #include "evsel.h" +#include "util/evsel_config.h" #include "util/evsel_fprintf.h" #include "evlist.h" #include diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 48183b5f5f83..ddc5ee6f6592 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -12,49 +12,6 @@ #include "symbol_conf.h" #include -/* - * The 'struct perf_evsel_config_term' is used to pass event - * specific configuration data to perf_evsel__config routine. - * It is allocated within event parsing and attached to - * perf_evsel::config_terms list head. -*/ -enum term_type { - PERF_EVSEL__CONFIG_TERM_PERIOD, - PERF_EVSEL__CONFIG_TERM_FREQ, - PERF_EVSEL__CONFIG_TERM_TIME, - PERF_EVSEL__CONFIG_TERM_CALLGRAPH, - PERF_EVSEL__CONFIG_TERM_STACK_USER, - PERF_EVSEL__CONFIG_TERM_INHERIT, - PERF_EVSEL__CONFIG_TERM_MAX_STACK, - PERF_EVSEL__CONFIG_TERM_MAX_EVENTS, - PERF_EVSEL__CONFIG_TERM_OVERWRITE, - PERF_EVSEL__CONFIG_TERM_DRV_CFG, - PERF_EVSEL__CONFIG_TERM_BRANCH, - PERF_EVSEL__CONFIG_TERM_PERCORE, - PERF_EVSEL__CONFIG_TERM_AUX_OUTPUT, -}; - -struct perf_evsel_config_term { - struct list_head list; - enum term_type type; - union { - u64 period; - u64 freq; - bool time; - char *callgraph; - char *drv_cfg; - u64 stack_user; - int max_stack; - bool inherit; - bool overwrite; - char *branch; - unsigned long max_events; - bool percore; - bool aux_output; - } val; - bool weak; -}; - struct bpf_object; struct cgroup; struct perf_counts; diff --git a/tools/perf/util/evsel_config.h b/tools/perf/util/evsel_config.h new file mode 100644 index 000000000000..8a7648037c18 --- /dev/null +++ b/tools/perf/util/evsel_config.h @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef __PERF_EVSEL_CONFIG_H +#define __PERF_EVSEL_CONFIG_H 1 + +#include +#include + +/* + * The 'struct perf_evsel_config_term' is used to pass event + * specific configuration data to perf_evsel__config routine. + * It is allocated within event parsing and attached to + * perf_evsel::config_terms list head. +*/ +enum evsel_term_type { + PERF_EVSEL__CONFIG_TERM_PERIOD, + PERF_EVSEL__CONFIG_TERM_FREQ, + PERF_EVSEL__CONFIG_TERM_TIME, + PERF_EVSEL__CONFIG_TERM_CALLGRAPH, + PERF_EVSEL__CONFIG_TERM_STACK_USER, + PERF_EVSEL__CONFIG_TERM_INHERIT, + PERF_EVSEL__CONFIG_TERM_MAX_STACK, + PERF_EVSEL__CONFIG_TERM_MAX_EVENTS, + PERF_EVSEL__CONFIG_TERM_OVERWRITE, + PERF_EVSEL__CONFIG_TERM_DRV_CFG, + PERF_EVSEL__CONFIG_TERM_BRANCH, + PERF_EVSEL__CONFIG_TERM_PERCORE, + PERF_EVSEL__CONFIG_TERM_AUX_OUTPUT, +}; + +struct perf_evsel_config_term { + struct list_head list; + enum evsel_term_type type; + union { + u64 period; + u64 freq; + bool time; + char *callgraph; + char *drv_cfg; + u64 stack_user; + int max_stack; + bool inherit; + bool overwrite; + char *branch; + unsigned long max_events; + bool percore; + bool aux_output; + } val; + bool weak; +}; +#endif // __PERF_EVSEL_CONFIG_H diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index d69ff746cda5..50737046fa63 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -34,6 +34,7 @@ #include "asm/bug.h" #include "util/parse-branch-options.h" #include "metricgroup.h" +#include "util/evsel_config.h" #include "util/mmap.h" #define MAX_NAME_LEN 100 -- cgit v1.2.3-59-g8ed1b From 252a2fdc742bc34b94da203282773952d3b54279 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 24 Sep 2019 16:07:59 -0300 Subject: perf tools: Replace needless mmap.h with what is needed, event.h The perf_sample struct definition and the event_attr_init() are in util/event.h, but some places were getting it thru an otherwise needless util/mmap.h header, fix it by including util/event.h directly. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-p1anwyjdbbvghrkl9dlxv7h5@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 2 +- tools/perf/util/parse-events.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 69d0a1991b29..e830eadfca2a 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -34,7 +34,7 @@ #include "bpf-event.h" #include "block-range.h" #include "string2.h" -#include "util/mmap.h" +#include "util/event.h" #include "arch/common.h" #include #include diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 50737046fa63..b5e2adef49de 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -35,7 +35,7 @@ #include "util/parse-branch-options.h" #include "metricgroup.h" #include "util/evsel_config.h" -#include "util/mmap.h" +#include "util/event.h" #define MAX_NAME_LEN 100 -- cgit v1.2.3-59-g8ed1b From 6f6473c37d34b00676a152ec7e60770c78ed7c2f Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 23 Sep 2019 16:33:39 -0700 Subject: perf stat: Fix free memory access / memory leaks in metrics Make sure to not free the name passed in by the caller, but free all the allocated ids when parsing expressions. The loop at the end knows that the first entry shouldn't be freed, so make sure the caller name is the first entry. Fixes % perf stat -M IpB,IpCall,IpTB,IPC,Retiring_SMT,Frontend_Bound_SMT,Kernel_Utilization,CPU_Utilization --metric-only -a -I 1000 sleep 2 valgrind: 1.009943231 ==21527== Invalid read of size 1 ==21527== at 0x483CB74: strcmp (vg_replace_strmem.c:849) ==21527== by 0x582CF8: collect_all_aliases (stat-display.c:554) ==21527== by 0x582EB3: collect_data (stat-display.c:577) ==21527== by 0x583A32: print_counter_aggr (stat-display.c:806) ==21527== by 0x584FAD: perf_evlist__print_counters (stat-display.c:1200) ==21527== by 0x45133A: print_counters (builtin-stat.c:655) ==21527== by 0x450629: process_interval (builtin-stat.c:353) ==21527== by 0x450FBD: __run_perf_stat (builtin-stat.c:564) ==21527== by 0x451285: run_perf_stat (builtin-stat.c:636) ==21527== by 0x454619: cmd_stat (builtin-stat.c:1966) ==21527== by 0x4D557D: run_builtin (perf.c:310) ==21527== by 0x4D57EA: handle_internal_command (perf.c:362) ==21527== Address 0x12826cd0 is 0 bytes inside a block of size 25 free'd ==21527== at 0x4839A0C: free (vg_replace_malloc.c:540) ==21527== by 0x627041: __zfree (zalloc.c:13) ==21527== by 0x57F66A: generic_metric (stat-shadow.c:814) ==21527== by 0x580B21: perf_stat__print_shadow_stats (stat-shadow.c:1057) ==21527== by 0x58418E: print_metric_headers (stat-display.c:943) ==21527== by 0x5844BC: print_interval (stat-display.c:1004) ==21527== by 0x584DEB: perf_evlist__print_counters (stat-display.c:1172) ==21527== by 0x45133A: print_counters (builtin-stat.c:655) ==21527== by 0x450629: process_interval (builtin-stat.c:353) ==21527== by 0x450FBD: __run_perf_stat (builtin-stat.c:564) ==21527== by 0x451285: run_perf_stat (builtin-stat.c:636) ==21527== by 0x454619: cmd_stat (builtin-stat.c:1966) ==21527== Block was alloc'd at ==21527== at 0x483880B: malloc (vg_replace_malloc.c:309) ==21527== by 0x51677DE: strdup (in /usr/lib64/libc-2.29.so) ==21527== by 0x506457: parse_events_name (parse-events.c:1754) ==21527== by 0x5550BB: parse_events_parse (parse-events.y:214) ==21527== by 0x50694D: parse_events__scanner (parse-events.c:1887) ==21527== by 0x506AEF: parse_events (parse-events.c:1927) ==21527== by 0x521D8B: metricgroup__parse_groups (metricgroup.c:527) ==21527== by 0x45156F: parse_metric_groups (builtin-stat.c:721) ==21527== by 0x6228A9: get_value (parse-options.c:243) ==21527== by 0x62363F: parse_short_opt (parse-options.c:348) ==21527== by 0x62363F: parse_options_step (parse-options.c:536) ==21527== by 0x62363F: parse_options_subcommand (parse-options.c:651) ==21527== by 0x453C1D: cmd_stat (builtin-stat.c:1718) ==21527== by 0x4D557D: run_builtin (perf.c:310) and also a leak report. Committer testing: Before: # perf stat -M IpB,IpCall,IpTB,IPC,Retiring_SMT,Frontend_Bound_SMT,Kernel_Utilization,CPU_Utilization --metric-only -a -I 1000 sleep 2 # time CPU_Utilization 1.000470810 free(): double free detected in tcache 2 Aborted (core dumped) # After: # perf stat -M IpB,IpCall,IpTB,IPC,Retiring_SMT,Frontend_Bound_SMT,Kernel_Utilization,CPU_Utilization --metric-only -a -I 1000 sleep 2 # time CPU_Utilization 1.000494752 0.1 2.001105112 0.1 # Signed-off-by: Andi Kleen Acked-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Link: http://lore.kernel.org/lkml/20190923233339.25326-3-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/stat-shadow.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index 70c87fdb2a43..2c41d47f6f83 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -738,6 +738,8 @@ static void generic_metric(struct perf_stat_config *config, char *n, *pn; expr__ctx_init(&pctx); + /* Must be first id entry */ + expr__add_id(&pctx, name, avg); for (i = 0; metric_events[i]; i++) { struct saved_value *v; struct stats *stats; @@ -776,8 +778,6 @@ static void generic_metric(struct perf_stat_config *config, expr__add_id(&pctx, n, avg_stats(stats)*scale); } - expr__add_id(&pctx, name, avg); - if (!metric_events[i]) { const char *p = metric_expr; -- cgit v1.2.3-59-g8ed1b From 7834fa948bebe648e8ce03393fb6b213c33f0a3a Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 23 Sep 2019 16:33:37 -0700 Subject: perf evlist: Fix access of freed id arrays I'm not fully sure if this is the correct fix, but without this I get crashes on more complex perf stat metric usages. The problem is that part of the state gets freed when a weak group fails, but then is later still used. Just don't free the ids, we're going to reuse them anyways on the weak group retry. For example: % perf stat -M IpB,IpCall,IpTB,IPC,Retiring_SMT,Frontend_Bound_SMT,Kernel_Utilization,CPU_Utilization --metric-only -a -I 1000 sleep 2 crashes and gives in valgrind: =21527== Invalid write of size 8 ==21527== at 0x4EE582: hlist_add_head (list.h:644) ==21527== by 0x4EFD3C: perf_evlist__id_hash (evlist.c:477) ==21527== by 0x4EFD99: perf_evlist__id_add (evlist.c:483) ==21527== by 0x4EFF15: perf_evlist__id_add_fd (evlist.c:524) ==21527== by 0x4FC693: store_evsel_ids (evsel.c:2969) ==21527== by 0x4FC76C: perf_evsel__store_ids (evsel.c:2986) ==21527== by 0x450DA7: __run_perf_stat (builtin-stat.c:519) ==21527== by 0x451285: run_perf_stat (builtin-stat.c:636) ==21527== by 0x454619: cmd_stat (builtin-stat.c:1966) ==21527== by 0x4D557D: run_builtin (perf.c:310) ==21527== by 0x4D57EA: handle_internal_command (perf.c:362) ==21527== by 0x4D5931: run_argv (perf.c:406) ==21527== Address 0x12e3f008 is 104 bytes inside a block of size 2,056 free'd ==21527== at 0x4839A0C: free (vg_replace_malloc.c:540) ==21527== by 0x627139: xyarray__delete (xyarray.c:32) ==21527== by 0x4F6BE4: perf_evsel__free_id (evsel.c:1253) ==21527== by 0x4FA11F: evsel__close (evsel.c:1994) ==21527== by 0x4F30A3: perf_evlist__reset_weak_group (evlist.c:1783) ==21527== by 0x450B47: __run_perf_stat (builtin-stat.c:466) ==21527== by 0x451285: run_perf_stat (builtin-stat.c:636) ==21527== by 0x454619: cmd_stat (builtin-stat.c:1966) ==21527== by 0x4D557D: run_builtin (perf.c:310) ==21527== by 0x4D57EA: handle_internal_command (perf.c:362) ==21527== by 0x4D5931: run_argv (perf.c:406) ==21527== by 0x4D5CAE: main (perf.c:531) ==21527== Block was alloc'd at ==21527== at 0x483AB1A: calloc (vg_replace_malloc.c:762) ==21527== by 0x627024: zalloc (zalloc.c:8) ==21527== by 0x627088: xyarray__new (xyarray.c:10) ==21527== by 0x4F6B20: perf_evsel__alloc_id (evsel.c:1237) ==21527== by 0x4FC74E: perf_evsel__store_ids (evsel.c:2983) ==21527== by 0x450DA7: __run_perf_stat (builtin-stat.c:519) ==21527== by 0x451285: run_perf_stat (builtin-stat.c:636) ==21527== by 0x454619: cmd_stat (builtin-stat.c:1966) ==21527== by 0x4D557D: run_builtin (perf.c:310) ==21527== by 0x4D57EA: handle_internal_command (perf.c:362) ==21527== by 0x4D5931: run_argv (perf.c:406) ==21527== by 0x4D5CAE: main (perf.c:531) Signed-off-by: Andi Kleen Acked-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Link: http://lore.kernel.org/lkml/20190923233339.25326-1-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 84c42790dab3..d277a98e62df 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1659,7 +1659,7 @@ struct evsel *perf_evlist__reset_weak_group(struct evlist *evsel_list, is_open = false; if (c2->leader == leader) { if (is_open) - evsel__close(c2); + perf_evsel__close(&evsel->core); c2->leader = c2; c2->core.nr_members = 0; } -- cgit v1.2.3-59-g8ed1b From 28b951760cebdf1de0d32f38f325b667c2494564 Mon Sep 17 00:00:00 2001 From: Mamatha Inamdar Date: Mon, 9 Sep 2019 12:33:33 +0530 Subject: perf vendor events: Remove P8 HW events which are not supported This patch is to remove following hardware events from JSON file which are not supported on POWER8. pm_l3_p0_grp_pump pm_l3_p0_lco_data pm_l3_p0_lco_no_data pm_l3_p0_lco_rty Note: Unfortunately power8 event list is not publicly available. Fixes: c3b4d5c4afb0 ("perf vendor events: Remove P8 HW events which are not supported") Signed-off-by: Mamatha Inamdar Acked-by: Ravi Bangoria Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20190909065624.11956.3992.stgit@localhost.localdomain Signed-off-by: Arnaldo Carvalho de Melo --- .../perf/pmu-events/arch/powerpc/power8/other.json | 24 ---------------------- 1 file changed, 24 deletions(-) (limited to 'tools') diff --git a/tools/perf/pmu-events/arch/powerpc/power8/other.json b/tools/perf/pmu-events/arch/powerpc/power8/other.json index 9dc2f6b70354..b2a3df07fbc4 100644 --- a/tools/perf/pmu-events/arch/powerpc/power8/other.json +++ b/tools/perf/pmu-events/arch/powerpc/power8/other.json @@ -1775,30 +1775,6 @@ "BriefDescription": "L3 Load Prefetches", "PublicDescription": "" }, - {, - "EventCode": "0xa29084", - "EventName": "PM_L3_P0_GRP_PUMP", - "BriefDescription": "L3 pf sent with grp scope port 0", - "PublicDescription": "" - }, - {, - "EventCode": "0x528084", - "EventName": "PM_L3_P0_LCO_DATA", - "BriefDescription": "lco sent with data port 0", - "PublicDescription": "" - }, - {, - "EventCode": "0x518080", - "EventName": "PM_L3_P0_LCO_NO_DATA", - "BriefDescription": "dataless l3 lco sent port 0", - "PublicDescription": "" - }, - {, - "EventCode": "0xa4908c", - "EventName": "PM_L3_P0_LCO_RTY", - "BriefDescription": "L3 LCO received retry port 0", - "PublicDescription": "" - }, {, "EventCode": "0x84908d", "EventName": "PM_L3_PF0_ALLOC", -- cgit v1.2.3-59-g8ed1b From 61bf4ee29d5a44399bacec9cda9ef314acdbecda Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Mon, 9 Sep 2019 13:41:15 +0200 Subject: perf jvmti: Include JVMTI support for s390 Enable JVMTI support for s390 perf tool chain. Signed-off-by: Thomas Richter Cc: Heiko Carstens Cc: Hendrik Brueckner Cc: Vasily Gorbik Link: http://lore.kernel.org/lkml/20190909114116.50469-3-tmricht@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/s390/Makefile | 1 + tools/perf/util/genelf.h | 3 +++ 2 files changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/perf/arch/s390/Makefile b/tools/perf/arch/s390/Makefile index cb198787570a..6ac8887be7c9 100644 --- a/tools/perf/arch/s390/Makefile +++ b/tools/perf/arch/s390/Makefile @@ -4,6 +4,7 @@ PERF_HAVE_DWARF_REGS := 1 endif HAVE_KVM_STAT_SUPPORT := 1 PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1 +PERF_HAVE_JITDUMP := 1 # # Syscall table generation for perf diff --git a/tools/perf/util/genelf.h b/tools/perf/util/genelf.h index b72440bf9a79..d4137559be05 100644 --- a/tools/perf/util/genelf.h +++ b/tools/perf/util/genelf.h @@ -35,6 +35,9 @@ int jit_add_debug_info(Elf *e, uint64_t code_addr, void *debug, int nr_debug_ent #elif defined(__sparc__) #define GEN_ELF_ARCH EM_SPARC #define GEN_ELF_CLASS ELFCLASS32 +#elif defined(__s390x__) +#define GEN_ELF_ARCH EM_S390 +#define GEN_ELF_CLASS ELFCLASS64 #else #error "unsupported architecture" #endif -- cgit v1.2.3-59-g8ed1b From 815c1560bf8fd522b8d93a1d727868b910c1cc24 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Mon, 9 Sep 2019 13:41:16 +0200 Subject: perf build: Add detection of java-11-openjdk-devel package With Java 11 there is no seperate JRE anymore. Details: https://coderanch.com/t/701603/java/JRE-JDK Therefore the detection of the JRE needs to be adapted. This change works for s390 and x86. I have not tested other platforms. Committer testing: Continues to work with the OpenJDK 8: $ rm -f ~acme/lib64/libperf-jvmti.so $ rpm -qa | grep jdk-devel java-1.8.0-openjdk-devel-1.8.0.222.b10-0.fc30.x86_64 $ git log --oneline -1 a51937170f33 (HEAD -> perf/core) perf build: Add detection of java-11-openjdk-devel package $ rm -rf /tmp/build/perf ; mkdir -p /tmp/build/perf ; make -C tools/perf O=/tmp/build/perf install > /dev/null 2>1 $ ls -la ~acme/lib64/libperf-jvmti.so -rwxr-xr-x. 1 acme acme 230744 Sep 24 16:46 /home/acme/lib64/libperf-jvmti.so $ Suggested-by: Andreas Krebbel Signed-off-by: Thomas Richter Tested-by: Arnaldo Carvalho de Melo Cc: Heiko Carstens Cc: Hendrik Brueckner Cc: Vasily Gorbik Link: http://lore.kernel.org/lkml/20190909114116.50469-4-tmricht@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index a269d78456b6..46f7fba2306c 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -924,7 +924,7 @@ ifndef NO_JVMTI JDIR=$(shell /usr/sbin/update-java-alternatives -l | head -1 | awk '{print $$3}') else ifneq (,$(wildcard /usr/sbin/alternatives)) - JDIR=$(shell /usr/sbin/alternatives --display java | tail -1 | cut -d' ' -f 5 | sed 's%/jre/bin/java.%%g') + JDIR=$(shell /usr/sbin/alternatives --display java | tail -1 | cut -d' ' -f 5 | sed -e 's%/jre/bin/java.%%g' -e 's%/bin/java.%%g') endif endif ifndef JDIR -- cgit v1.2.3-59-g8ed1b From d6840d87b2d148e19e244ad2b44d28ba07f437a0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 25 Sep 2019 09:27:05 -0300 Subject: perf parser: Remove needless include directives They go on accumulating there like the debug.h one, that was introduced here: f23610245c1a ("perf list: Add debug support for outputing alias string") But then, when that need is removed via: 2073ad3326b7 ("perf tools: Factor out PMU matching in parser") The thing stays there, so continue the house cleaning spree... list.h not needed, no macros from there are used, and 'struct list_head' is in linux/types.h, ditto for util.h, no need for that as well. Cc: Adrian Hunter Cc: Andi Kleen Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-zkxr3mf6inun8m5mbnil4u0d@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/parse-events.y | 3 --- 1 file changed, 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 65809ad67808..48126ae4cd13 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -11,12 +11,9 @@ #include #include #include -#include #include -#include "util.h" #include "pmu.h" #include "evsel.h" -#include "debug.h" #include "parse-events.h" #include "parse-events-bison.h" -- cgit v1.2.3-59-g8ed1b From 8a03222f508bf09e03cf38f6bd77b34b450c1d60 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Mon, 23 Sep 2019 11:41:12 -0700 Subject: selftests/bpf: test_progs: fix client/server race in tcp_rtt This is the same problem I found earlier in test_sockopt_inherit: there is a race between server thread doing accept() and client thread doing connect(). Let's explicitly synchronize them via pthread conditional variable. v2: * don't exit from server_thread without signaling condvar, fixes possible issue where main() would wait forever (Andrii Nakryiko) Fixes: b55873984dab ("selftests/bpf: test BPF_SOCK_OPS_RTT_CB") Signed-off-by: Stanislav Fomichev Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/prog_tests/tcp_rtt.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c b/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c index fdc0b3614a9e..a82da555b1b0 100644 --- a/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c +++ b/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c @@ -203,14 +203,24 @@ static int start_server(void) return fd; } +static pthread_mutex_t server_started_mtx = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t server_started = PTHREAD_COND_INITIALIZER; + static void *server_thread(void *arg) { struct sockaddr_storage addr; socklen_t len = sizeof(addr); int fd = *(int *)arg; int client_fd; + int err; + + err = listen(fd, 1); + + pthread_mutex_lock(&server_started_mtx); + pthread_cond_signal(&server_started); + pthread_mutex_unlock(&server_started_mtx); - if (CHECK_FAIL(listen(fd, 1)) < 0) { + if (CHECK_FAIL(err < 0)) { perror("Failed to listed on socket"); return NULL; } @@ -248,7 +258,14 @@ void test_tcp_rtt(void) if (CHECK_FAIL(server_fd < 0)) goto close_cgroup_fd; - pthread_create(&tid, NULL, server_thread, (void *)&server_fd); + if (CHECK_FAIL(pthread_create(&tid, NULL, server_thread, + (void *)&server_fd))) + goto close_cgroup_fd; + + pthread_mutex_lock(&server_started_mtx); + pthread_cond_wait(&server_started, &server_started_mtx); + pthread_mutex_unlock(&server_started_mtx); + CHECK_FAIL(run_test(cgroup_fd, server_fd)); close(server_fd); close_cgroup_fd: -- cgit v1.2.3-59-g8ed1b From aef70a1f44c0b570e6345c02c2d240471859f0a4 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 25 Sep 2019 11:30:38 -0700 Subject: libbpf: fix false uninitialized variable warning Some compilers emit warning for potential uninitialized next_id usage. The code is correct, but control flow is too complicated for some compilers to figure this out. Re-initialize next_id to satisfy compiler. Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann --- tools/lib/bpf/btf_dump.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c index 715967762312..84b0661db7f3 100644 --- a/tools/lib/bpf/btf_dump.c +++ b/tools/lib/bpf/btf_dump.c @@ -1167,6 +1167,7 @@ static void btf_dump_emit_type_chain(struct btf_dump *d, return; } + next_id = decls->ids[decls->cnt - 1]; next_t = btf__type_by_id(d->btf, next_id); multidim = btf_is_array(next_t); /* we need space if we have named non-pointer */ -- cgit v1.2.3-59-g8ed1b From d778c30a056ac352d1c0c58b5850e0fcc5655a58 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 25 Sep 2019 11:36:14 -0700 Subject: selftests/bpf: delete unused variables in test_sysctl Remove no longer used variables and avoid compiler warnings. Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/test_sysctl.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_sysctl.c b/tools/testing/selftests/bpf/test_sysctl.c index 4f8ec1f10a80..a320e3844b17 100644 --- a/tools/testing/selftests/bpf/test_sysctl.c +++ b/tools/testing/selftests/bpf/test_sysctl.c @@ -1385,7 +1385,6 @@ static int fixup_sysctl_value(const char *buf, size_t buf_len, uint8_t raw[sizeof(uint64_t)]; uint64_t num; } value = {}; - uint8_t c, i; if (buf_len > sizeof(value)) { log_err("Value is too big (%zd) to use in fixup", buf_len); -- cgit v1.2.3-59-g8ed1b From 4670d68b9254710fdeaf794cad54d8b2c9929e0a Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 25 Sep 2019 11:52:05 -0700 Subject: selftests/bpf: adjust strobemeta loop to satisfy latest clang Some recent changes in latest Clang started causing the following warning when unrolling strobemeta test case main loop: progs/strobemeta.h:416:2: warning: loop not unrolled: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering [-Wpass-failed=transform-warning] This patch simplifies loop's exit condition to depend only on constant max iteration number (STROBE_MAX_MAP_ENTRIES), while moving early termination logic inside the loop body. The changes are equivalent from program logic standpoint, but fixes the warning. It also appears to improve generated BPF code, as it fixes previously failing non-unrolled strobemeta test cases. Cc: Alexei Starovoitov Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/progs/strobemeta.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/progs/strobemeta.h b/tools/testing/selftests/bpf/progs/strobemeta.h index 8a399bdfd920..067eb625d01c 100644 --- a/tools/testing/selftests/bpf/progs/strobemeta.h +++ b/tools/testing/selftests/bpf/progs/strobemeta.h @@ -413,7 +413,10 @@ static __always_inline void *read_map_var(struct strobemeta_cfg *cfg, #else #pragma unroll #endif - for (int i = 0; i < STROBE_MAX_MAP_ENTRIES && i < map.cnt; ++i) { + for (int i = 0; i < STROBE_MAX_MAP_ENTRIES; ++i) { + if (i >= map.cnt) + break; + descr->key_lens[i] = 0; len = bpf_probe_read_str(payload, STROBE_MAX_STR_LEN, map.entries[i].key); -- cgit v1.2.3-59-g8ed1b From c7d4f7eeb6da9408e9ba7475fe2624bdb4d837d0 Mon Sep 17 00:00:00 2001 From: Michel Lespinasse Date: Wed, 25 Sep 2019 16:46:02 -0700 Subject: rbtree: avoid generating code twice for the cached versions (tools copy) As was already noted in rbtree.h, the logic to cache rb_first (or rb_last) can easily be implemented externally to the core rbtree api. This commit takes the changes applied to the include/linux/ and lib/ rbtree files in 9f973cb38088 ("lib/rbtree: avoid generating code twice for the cached versions"), and applies these to the tools/include/linux/ and tools/lib/ files as well to keep them synchronized. Link: http://lkml.kernel.org/r/20190703034812.53002-1-walken@google.com Signed-off-by: Michel Lespinasse Cc: David Howells Cc: Davidlohr Bueso Cc: Peter Zijlstra (Intel) Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- tools/include/linux/rbtree.h | 71 ++++++++++++++++++++++------------ tools/include/linux/rbtree_augmented.h | 31 ++++++--------- tools/lib/rbtree.c | 37 ++---------------- 3 files changed, 62 insertions(+), 77 deletions(-) (limited to 'tools') diff --git a/tools/include/linux/rbtree.h b/tools/include/linux/rbtree.h index d83763a5327c..e03b1ea23e0e 100644 --- a/tools/include/linux/rbtree.h +++ b/tools/include/linux/rbtree.h @@ -31,25 +31,9 @@ struct rb_root { struct rb_node *rb_node; }; -/* - * Leftmost-cached rbtrees. - * - * We do not cache the rightmost node based on footprint - * size vs number of potential users that could benefit - * from O(1) rb_last(). Just not worth it, users that want - * this feature can always implement the logic explicitly. - * Furthermore, users that want to cache both pointers may - * find it a bit asymmetric, but that's ok. - */ -struct rb_root_cached { - struct rb_root rb_root; - struct rb_node *rb_leftmost; -}; - #define rb_parent(r) ((struct rb_node *)((r)->__rb_parent_color & ~3)) #define RB_ROOT (struct rb_root) { NULL, } -#define RB_ROOT_CACHED (struct rb_root_cached) { {NULL, }, NULL } #define rb_entry(ptr, type, member) container_of(ptr, type, member) #define RB_EMPTY_ROOT(root) (READ_ONCE((root)->rb_node) == NULL) @@ -71,12 +55,6 @@ extern struct rb_node *rb_prev(const struct rb_node *); extern struct rb_node *rb_first(const struct rb_root *); extern struct rb_node *rb_last(const struct rb_root *); -extern void rb_insert_color_cached(struct rb_node *, - struct rb_root_cached *, bool); -extern void rb_erase_cached(struct rb_node *node, struct rb_root_cached *); -/* Same as rb_first(), but O(1) */ -#define rb_first_cached(root) (root)->rb_leftmost - /* Postorder iteration - always visit the parent after its children */ extern struct rb_node *rb_first_postorder(const struct rb_root *); extern struct rb_node *rb_next_postorder(const struct rb_node *); @@ -84,8 +62,6 @@ extern struct rb_node *rb_next_postorder(const struct rb_node *); /* Fast replacement of a single node without remove/rebalance/add/rebalance */ extern void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root); -extern void rb_replace_node_cached(struct rb_node *victim, struct rb_node *new, - struct rb_root_cached *root); static inline void rb_link_node(struct rb_node *node, struct rb_node *parent, struct rb_node **rb_link) @@ -129,4 +105,51 @@ static inline void rb_erase_init(struct rb_node *n, struct rb_root *root) rb_erase(n, root); RB_CLEAR_NODE(n); } + +/* + * Leftmost-cached rbtrees. + * + * We do not cache the rightmost node based on footprint + * size vs number of potential users that could benefit + * from O(1) rb_last(). Just not worth it, users that want + * this feature can always implement the logic explicitly. + * Furthermore, users that want to cache both pointers may + * find it a bit asymmetric, but that's ok. + */ +struct rb_root_cached { + struct rb_root rb_root; + struct rb_node *rb_leftmost; +}; + +#define RB_ROOT_CACHED (struct rb_root_cached) { {NULL, }, NULL } + +/* Same as rb_first(), but O(1) */ +#define rb_first_cached(root) (root)->rb_leftmost + +static inline void rb_insert_color_cached(struct rb_node *node, + struct rb_root_cached *root, + bool leftmost) +{ + if (leftmost) + root->rb_leftmost = node; + rb_insert_color(node, &root->rb_root); +} + +static inline void rb_erase_cached(struct rb_node *node, + struct rb_root_cached *root) +{ + if (root->rb_leftmost == node) + root->rb_leftmost = rb_next(node); + rb_erase(node, &root->rb_root); +} + +static inline void rb_replace_node_cached(struct rb_node *victim, + struct rb_node *new, + struct rb_root_cached *root) +{ + if (root->rb_leftmost == victim) + root->rb_leftmost = new; + rb_replace_node(victim, new, &root->rb_root); +} + #endif /* __TOOLS_LINUX_PERF_RBTREE_H */ diff --git a/tools/include/linux/rbtree_augmented.h b/tools/include/linux/rbtree_augmented.h index ddd01006ece5..467a3eefe1d2 100644 --- a/tools/include/linux/rbtree_augmented.h +++ b/tools/include/linux/rbtree_augmented.h @@ -32,17 +32,16 @@ struct rb_augment_callbacks { void (*rotate)(struct rb_node *old, struct rb_node *new); }; -extern void __rb_insert_augmented(struct rb_node *node, - struct rb_root *root, - bool newleft, struct rb_node **leftmost, +extern void __rb_insert_augmented(struct rb_node *node, struct rb_root *root, void (*augment_rotate)(struct rb_node *old, struct rb_node *new)); + /* * Fixup the rbtree and update the augmented information when rebalancing. * * On insertion, the user must update the augmented information on the path * leading to the inserted node, then call rb_link_node() as usual and - * rb_augment_inserted() instead of the usual rb_insert_color() call. - * If rb_augment_inserted() rebalances the rbtree, it will callback into + * rb_insert_augmented() instead of the usual rb_insert_color() call. + * If rb_insert_augmented() rebalances the rbtree, it will callback into * a user provided function to update the augmented information on the * affected subtrees. */ @@ -50,7 +49,7 @@ static inline void rb_insert_augmented(struct rb_node *node, struct rb_root *root, const struct rb_augment_callbacks *augment) { - __rb_insert_augmented(node, root, false, NULL, augment->rotate); + __rb_insert_augmented(node, root, augment->rotate); } static inline void @@ -58,8 +57,9 @@ rb_insert_augmented_cached(struct rb_node *node, struct rb_root_cached *root, bool newleft, const struct rb_augment_callbacks *augment) { - __rb_insert_augmented(node, &root->rb_root, - newleft, &root->rb_leftmost, augment->rotate); + if (newleft) + root->rb_leftmost = node; + rb_insert_augmented(node, &root->rb_root, augment); } #define RB_DECLARE_CALLBACKS(rbstatic, rbname, rbstruct, rbfield, \ @@ -139,7 +139,6 @@ extern void __rb_erase_color(struct rb_node *parent, struct rb_root *root, static __always_inline struct rb_node * __rb_erase_augmented(struct rb_node *node, struct rb_root *root, - struct rb_node **leftmost, const struct rb_augment_callbacks *augment) { struct rb_node *child = node->rb_right; @@ -147,9 +146,6 @@ __rb_erase_augmented(struct rb_node *node, struct rb_root *root, struct rb_node *parent, *rebalance; unsigned long pc; - if (leftmost && node == *leftmost) - *leftmost = rb_next(node); - if (!tmp) { /* * Case 1: node to erase has no more than 1 child (easy!) @@ -249,8 +245,7 @@ static __always_inline void rb_erase_augmented(struct rb_node *node, struct rb_root *root, const struct rb_augment_callbacks *augment) { - struct rb_node *rebalance = __rb_erase_augmented(node, root, - NULL, augment); + struct rb_node *rebalance = __rb_erase_augmented(node, root, augment); if (rebalance) __rb_erase_color(rebalance, root, augment->rotate); } @@ -259,11 +254,9 @@ static __always_inline void rb_erase_augmented_cached(struct rb_node *node, struct rb_root_cached *root, const struct rb_augment_callbacks *augment) { - struct rb_node *rebalance = __rb_erase_augmented(node, &root->rb_root, - &root->rb_leftmost, - augment); - if (rebalance) - __rb_erase_color(rebalance, &root->rb_root, augment->rotate); + if (root->rb_leftmost == node) + root->rb_leftmost = rb_next(node); + rb_erase_augmented(node, &root->rb_root, augment); } #endif /* _TOOLS_LINUX_RBTREE_AUGMENTED_H */ diff --git a/tools/lib/rbtree.c b/tools/lib/rbtree.c index 804f145e3113..2548ff8c4d9c 100644 --- a/tools/lib/rbtree.c +++ b/tools/lib/rbtree.c @@ -83,14 +83,10 @@ __rb_rotate_set_parents(struct rb_node *old, struct rb_node *new, static __always_inline void __rb_insert(struct rb_node *node, struct rb_root *root, - bool newleft, struct rb_node **leftmost, void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) { struct rb_node *parent = rb_red_parent(node), *gparent, *tmp; - if (newleft) - *leftmost = node; - while (true) { /* * Loop invariant: node is red. @@ -436,34 +432,17 @@ static const struct rb_augment_callbacks dummy_callbacks = { void rb_insert_color(struct rb_node *node, struct rb_root *root) { - __rb_insert(node, root, false, NULL, dummy_rotate); + __rb_insert(node, root, dummy_rotate); } void rb_erase(struct rb_node *node, struct rb_root *root) { struct rb_node *rebalance; - rebalance = __rb_erase_augmented(node, root, - NULL, &dummy_callbacks); + rebalance = __rb_erase_augmented(node, root, &dummy_callbacks); if (rebalance) ____rb_erase_color(rebalance, root, dummy_rotate); } -void rb_insert_color_cached(struct rb_node *node, - struct rb_root_cached *root, bool leftmost) -{ - __rb_insert(node, &root->rb_root, leftmost, - &root->rb_leftmost, dummy_rotate); -} - -void rb_erase_cached(struct rb_node *node, struct rb_root_cached *root) -{ - struct rb_node *rebalance; - rebalance = __rb_erase_augmented(node, &root->rb_root, - &root->rb_leftmost, &dummy_callbacks); - if (rebalance) - ____rb_erase_color(rebalance, &root->rb_root, dummy_rotate); -} - /* * Augmented rbtree manipulation functions. * @@ -472,10 +451,9 @@ void rb_erase_cached(struct rb_node *node, struct rb_root_cached *root) */ void __rb_insert_augmented(struct rb_node *node, struct rb_root *root, - bool newleft, struct rb_node **leftmost, void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) { - __rb_insert(node, root, newleft, leftmost, augment_rotate); + __rb_insert(node, root, augment_rotate); } /* @@ -580,15 +558,6 @@ void rb_replace_node(struct rb_node *victim, struct rb_node *new, __rb_change_child(victim, new, parent, root); } -void rb_replace_node_cached(struct rb_node *victim, struct rb_node *new, - struct rb_root_cached *root) -{ - rb_replace_node(victim, new, &root->rb_root); - - if (root->rb_leftmost == victim) - root->rb_leftmost = new; -} - static struct rb_node *rb_left_deepest_node(const struct rb_node *node) { for (;;) { -- cgit v1.2.3-59-g8ed1b From 444b8a83f1e01584ff2d53f5951d8e836c0070b5 Mon Sep 17 00:00:00 2001 From: Michel Lespinasse Date: Wed, 25 Sep 2019 16:46:04 -0700 Subject: augmented rbtree: add comments for RB_DECLARE_CALLBACKS macro Patch series "make RB_DECLARE_CALLBACKS more generic", v3. These changes are intended to make the RB_DECLARE_CALLBACKS macro more generic (allowing the aubmented subtree information to be a struct instead of a scalar). I have verified the compiled lib/interval_tree.o and mm/mmap.o files to check that they didn't change. This held as expected for interval_tree.o; mmap.o did have some changes which could be reverted by marking __vma_link_rb as noinline. I did not add such a change to the patchset; I felt it was reasonable enough to leave the inlining decision up to the compiler. This patch (of 3): Add a short comment summarizing the arguments to RB_DECLARE_CALLBACKS. The arguments are also now capitalized. This copies the style of the INTERVAL_TREE_DEFINE macro. No functional changes in this commit, only comments and capitalization. Link: http://lkml.kernel.org/r/20190703040156.56953-2-walken@google.com Signed-off-by: Michel Lespinasse Acked-by: Davidlohr Bueso Acked-by: Peter Zijlstra (Intel) Cc: David Howells Cc: Uladzislau Rezki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rbtree_augmented.h | 54 +++++++++++++++++++++------------- tools/include/linux/rbtree_augmented.h | 54 +++++++++++++++++++++------------- 2 files changed, 66 insertions(+), 42 deletions(-) (limited to 'tools') diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h index 179faab29f52..979941600082 100644 --- a/include/linux/rbtree_augmented.h +++ b/include/linux/rbtree_augmented.h @@ -60,39 +60,51 @@ rb_insert_augmented_cached(struct rb_node *node, rb_insert_augmented(node, &root->rb_root, augment); } -#define RB_DECLARE_CALLBACKS(rbstatic, rbname, rbstruct, rbfield, \ - rbtype, rbaugmented, rbcompute) \ +/* + * Template for declaring augmented rbtree callbacks + * + * RBSTATIC: 'static' or empty + * RBNAME: name of the rb_augment_callbacks structure + * RBSTRUCT: struct type of the tree nodes + * RBFIELD: name of struct rb_node field within RBSTRUCT + * RBTYPE: type of the RBAUGMENTED field + * RBAUGMENTED: name of RBTYPE field within RBSTRUCT holding data for subtree + * RBCOMPUTE: name of function that recomputes the RBAUGMENTED data + */ + +#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ + RBTYPE, RBAUGMENTED, RBCOMPUTE) \ static inline void \ -rbname ## _propagate(struct rb_node *rb, struct rb_node *stop) \ +RBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop) \ { \ while (rb != stop) { \ - rbstruct *node = rb_entry(rb, rbstruct, rbfield); \ - rbtype augmented = rbcompute(node); \ - if (node->rbaugmented == augmented) \ + RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \ + RBTYPE augmented = RBCOMPUTE(node); \ + if (node->RBAUGMENTED == augmented) \ break; \ - node->rbaugmented = augmented; \ - rb = rb_parent(&node->rbfield); \ + node->RBAUGMENTED = augmented; \ + rb = rb_parent(&node->RBFIELD); \ } \ } \ static inline void \ -rbname ## _copy(struct rb_node *rb_old, struct rb_node *rb_new) \ +RBNAME ## _copy(struct rb_node *rb_old, struct rb_node *rb_new) \ { \ - rbstruct *old = rb_entry(rb_old, rbstruct, rbfield); \ - rbstruct *new = rb_entry(rb_new, rbstruct, rbfield); \ - new->rbaugmented = old->rbaugmented; \ + RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \ + RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \ + new->RBAUGMENTED = old->RBAUGMENTED; \ } \ static void \ -rbname ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \ +RBNAME ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \ { \ - rbstruct *old = rb_entry(rb_old, rbstruct, rbfield); \ - rbstruct *new = rb_entry(rb_new, rbstruct, rbfield); \ - new->rbaugmented = old->rbaugmented; \ - old->rbaugmented = rbcompute(old); \ + RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \ + RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \ + new->RBAUGMENTED = old->RBAUGMENTED; \ + old->RBAUGMENTED = RBCOMPUTE(old); \ } \ -rbstatic const struct rb_augment_callbacks rbname = { \ - .propagate = rbname ## _propagate, \ - .copy = rbname ## _copy, \ - .rotate = rbname ## _rotate \ +RBSTATIC const struct rb_augment_callbacks RBNAME = { \ + .propagate = RBNAME ## _propagate, \ + .copy = RBNAME ## _copy, \ + .rotate = RBNAME ## _rotate \ }; diff --git a/tools/include/linux/rbtree_augmented.h b/tools/include/linux/rbtree_augmented.h index 467a3eefe1d2..de3a480204ba 100644 --- a/tools/include/linux/rbtree_augmented.h +++ b/tools/include/linux/rbtree_augmented.h @@ -62,39 +62,51 @@ rb_insert_augmented_cached(struct rb_node *node, rb_insert_augmented(node, &root->rb_root, augment); } -#define RB_DECLARE_CALLBACKS(rbstatic, rbname, rbstruct, rbfield, \ - rbtype, rbaugmented, rbcompute) \ +/* + * Template for declaring augmented rbtree callbacks + * + * RBSTATIC: 'static' or empty + * RBNAME: name of the rb_augment_callbacks structure + * RBSTRUCT: struct type of the tree nodes + * RBFIELD: name of struct rb_node field within RBSTRUCT + * RBTYPE: type of the RBAUGMENTED field + * RBAUGMENTED: name of RBTYPE field within RBSTRUCT holding data for subtree + * RBCOMPUTE: name of function that recomputes the RBAUGMENTED data + */ + +#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ + RBTYPE, RBAUGMENTED, RBCOMPUTE) \ static inline void \ -rbname ## _propagate(struct rb_node *rb, struct rb_node *stop) \ +RBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop) \ { \ while (rb != stop) { \ - rbstruct *node = rb_entry(rb, rbstruct, rbfield); \ - rbtype augmented = rbcompute(node); \ - if (node->rbaugmented == augmented) \ + RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \ + RBTYPE augmented = RBCOMPUTE(node); \ + if (node->RBAUGMENTED == augmented) \ break; \ - node->rbaugmented = augmented; \ - rb = rb_parent(&node->rbfield); \ + node->RBAUGMENTED = augmented; \ + rb = rb_parent(&node->RBFIELD); \ } \ } \ static inline void \ -rbname ## _copy(struct rb_node *rb_old, struct rb_node *rb_new) \ +RBNAME ## _copy(struct rb_node *rb_old, struct rb_node *rb_new) \ { \ - rbstruct *old = rb_entry(rb_old, rbstruct, rbfield); \ - rbstruct *new = rb_entry(rb_new, rbstruct, rbfield); \ - new->rbaugmented = old->rbaugmented; \ + RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \ + RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \ + new->RBAUGMENTED = old->RBAUGMENTED; \ } \ static void \ -rbname ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \ +RBNAME ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \ { \ - rbstruct *old = rb_entry(rb_old, rbstruct, rbfield); \ - rbstruct *new = rb_entry(rb_new, rbstruct, rbfield); \ - new->rbaugmented = old->rbaugmented; \ - old->rbaugmented = rbcompute(old); \ + RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \ + RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \ + new->RBAUGMENTED = old->RBAUGMENTED; \ + old->RBAUGMENTED = RBCOMPUTE(old); \ } \ -rbstatic const struct rb_augment_callbacks rbname = { \ - .propagate = rbname ## _propagate, \ - .copy = rbname ## _copy, \ - .rotate = rbname ## _rotate \ +RBSTATIC const struct rb_augment_callbacks RBNAME = { \ + .propagate = RBNAME ## _propagate, \ + .copy = RBNAME ## _copy, \ + .rotate = RBNAME ## _rotate \ }; -- cgit v1.2.3-59-g8ed1b From 315cc066b8ae8349a27887ad7a34e1916e9797fe Mon Sep 17 00:00:00 2001 From: Michel Lespinasse Date: Wed, 25 Sep 2019 16:46:07 -0700 Subject: augmented rbtree: add new RB_DECLARE_CALLBACKS_MAX macro Add RB_DECLARE_CALLBACKS_MAX, which generates augmented rbtree callbacks for the case where the augmented value is a scalar whose definition follows a max(f(node)) pattern. This actually covers all present uses of RB_DECLARE_CALLBACKS, and saves some (source) code duplication in the various RBCOMPUTE function definitions. [walken@google.com: fix mm/vmalloc.c] Link: http://lkml.kernel.org/r/CANN689FXgK13wDYNh1zKxdipeTuALG4eKvKpsdZqKFJ-rvtGiQ@mail.gmail.com [walken@google.com: re-add check to check_augmented()] Link: http://lkml.kernel.org/r/20190727022027.GA86863@google.com Link: http://lkml.kernel.org/r/20190703040156.56953-3-walken@google.com Signed-off-by: Michel Lespinasse Acked-by: Peter Zijlstra (Intel) Cc: David Howells Cc: Davidlohr Bueso Cc: Uladzislau Rezki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/mm/pat_rbtree.c | 19 +++-------------- drivers/block/drbd/drbd_interval.c | 29 +++----------------------- include/linux/interval_tree_generic.h | 22 ++------------------ include/linux/rbtree_augmented.h | 36 ++++++++++++++++++++++++++++++++- lib/rbtree_test.c | 37 ++++++++++++++++------------------ mm/mmap.c | 29 ++++++++++++++++---------- mm/vmalloc.c | 5 ++--- tools/include/linux/rbtree_augmented.h | 36 ++++++++++++++++++++++++++++++++- 8 files changed, 115 insertions(+), 98 deletions(-) (limited to 'tools') diff --git a/arch/x86/mm/pat_rbtree.c b/arch/x86/mm/pat_rbtree.c index fa16036fa592..65ebe4b88f7c 100644 --- a/arch/x86/mm/pat_rbtree.c +++ b/arch/x86/mm/pat_rbtree.c @@ -54,23 +54,10 @@ static u64 get_subtree_max_end(struct rb_node *node) return ret; } -static u64 compute_subtree_max_end(struct memtype *data) -{ - u64 max_end = data->end, child_max_end; - - child_max_end = get_subtree_max_end(data->rb.rb_right); - if (child_max_end > max_end) - max_end = child_max_end; - - child_max_end = get_subtree_max_end(data->rb.rb_left); - if (child_max_end > max_end) - max_end = child_max_end; - - return max_end; -} +#define NODE_END(node) ((node)->end) -RB_DECLARE_CALLBACKS(static, memtype_rb_augment_cb, struct memtype, rb, - u64, subtree_max_end, compute_subtree_max_end) +RB_DECLARE_CALLBACKS_MAX(static, memtype_rb_augment_cb, + struct memtype, rb, u64, subtree_max_end, NODE_END) /* Find the first (lowest start addr) overlapping range from rb tree */ static struct memtype *memtype_rb_lowest_match(struct rb_root *root, diff --git a/drivers/block/drbd/drbd_interval.c b/drivers/block/drbd/drbd_interval.c index c58986556161..651bd0236a99 100644 --- a/drivers/block/drbd/drbd_interval.c +++ b/drivers/block/drbd/drbd_interval.c @@ -13,33 +13,10 @@ sector_t interval_end(struct rb_node *node) return this->end; } -/** - * compute_subtree_last - compute end of @node - * - * The end of an interval is the highest (start + (size >> 9)) value of this - * node and of its children. Called for @node and its parents whenever the end - * may have changed. - */ -static inline sector_t -compute_subtree_last(struct drbd_interval *node) -{ - sector_t max = node->sector + (node->size >> 9); - - if (node->rb.rb_left) { - sector_t left = interval_end(node->rb.rb_left); - if (left > max) - max = left; - } - if (node->rb.rb_right) { - sector_t right = interval_end(node->rb.rb_right); - if (right > max) - max = right; - } - return max; -} +#define NODE_END(node) ((node)->sector + ((node)->size >> 9)) -RB_DECLARE_CALLBACKS(static, augment_callbacks, struct drbd_interval, rb, - sector_t, end, compute_subtree_last); +RB_DECLARE_CALLBACKS_MAX(static, augment_callbacks, + struct drbd_interval, rb, sector_t, end, NODE_END); /** * drbd_insert_interval - insert a new interval into a tree diff --git a/include/linux/interval_tree_generic.h b/include/linux/interval_tree_generic.h index 855476145fe1..aaa8a0767aa3 100644 --- a/include/linux/interval_tree_generic.h +++ b/include/linux/interval_tree_generic.h @@ -30,26 +30,8 @@ \ /* Callbacks for augmented rbtree insert and remove */ \ \ -static inline ITTYPE ITPREFIX ## _compute_subtree_last(ITSTRUCT *node) \ -{ \ - ITTYPE max = ITLAST(node), subtree_last; \ - if (node->ITRB.rb_left) { \ - subtree_last = rb_entry(node->ITRB.rb_left, \ - ITSTRUCT, ITRB)->ITSUBTREE; \ - if (max < subtree_last) \ - max = subtree_last; \ - } \ - if (node->ITRB.rb_right) { \ - subtree_last = rb_entry(node->ITRB.rb_right, \ - ITSTRUCT, ITRB)->ITSUBTREE; \ - if (max < subtree_last) \ - max = subtree_last; \ - } \ - return max; \ -} \ - \ -RB_DECLARE_CALLBACKS(static, ITPREFIX ## _augment, ITSTRUCT, ITRB, \ - ITTYPE, ITSUBTREE, ITPREFIX ## _compute_subtree_last) \ +RB_DECLARE_CALLBACKS_MAX(static, ITPREFIX ## _augment, \ + ITSTRUCT, ITRB, ITTYPE, ITSUBTREE, ITLAST) \ \ /* Insert / remove interval nodes from the tree */ \ \ diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h index 979941600082..e5937e387e02 100644 --- a/include/linux/rbtree_augmented.h +++ b/include/linux/rbtree_augmented.h @@ -61,7 +61,7 @@ rb_insert_augmented_cached(struct rb_node *node, } /* - * Template for declaring augmented rbtree callbacks + * Template for declaring augmented rbtree callbacks (generic case) * * RBSTATIC: 'static' or empty * RBNAME: name of the rb_augment_callbacks structure @@ -107,6 +107,40 @@ RBSTATIC const struct rb_augment_callbacks RBNAME = { \ .rotate = RBNAME ## _rotate \ }; +/* + * Template for declaring augmented rbtree callbacks, + * computing RBAUGMENTED scalar as max(RBCOMPUTE(node)) for all subtree nodes. + * + * RBSTATIC: 'static' or empty + * RBNAME: name of the rb_augment_callbacks structure + * RBSTRUCT: struct type of the tree nodes + * RBFIELD: name of struct rb_node field within RBSTRUCT + * RBTYPE: type of the RBAUGMENTED field + * RBAUGMENTED: name of RBTYPE field within RBSTRUCT holding data for subtree + * RBCOMPUTE: name of function that returns the per-node RBTYPE scalar + */ + +#define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ + RBTYPE, RBAUGMENTED, RBCOMPUTE) \ +static inline RBTYPE RBNAME ## _compute_max(RBSTRUCT *node) \ +{ \ + RBSTRUCT *child; \ + RBTYPE max = RBCOMPUTE(node); \ + if (node->RBFIELD.rb_left) { \ + child = rb_entry(node->RBFIELD.rb_left, RBSTRUCT, RBFIELD); \ + if (child->RBAUGMENTED > max) \ + max = child->RBAUGMENTED; \ + } \ + if (node->RBFIELD.rb_right) { \ + child = rb_entry(node->RBFIELD.rb_right, RBSTRUCT, RBFIELD); \ + if (child->RBAUGMENTED > max) \ + max = child->RBAUGMENTED; \ + } \ + return max; \ +} \ +RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ + RBTYPE, RBAUGMENTED, RBNAME ## _compute_max) + #define RB_RED 0 #define RB_BLACK 1 diff --git a/lib/rbtree_test.c b/lib/rbtree_test.c index 62b8ee92643d..41ae3c7570d3 100644 --- a/lib/rbtree_test.c +++ b/lib/rbtree_test.c @@ -77,26 +77,10 @@ static inline void erase_cached(struct test_node *node, struct rb_root_cached *r } -static inline u32 augment_recompute(struct test_node *node) -{ - u32 max = node->val, child_augmented; - if (node->rb.rb_left) { - child_augmented = rb_entry(node->rb.rb_left, struct test_node, - rb)->augmented; - if (max < child_augmented) - max = child_augmented; - } - if (node->rb.rb_right) { - child_augmented = rb_entry(node->rb.rb_right, struct test_node, - rb)->augmented; - if (max < child_augmented) - max = child_augmented; - } - return max; -} +#define NODE_VAL(node) ((node)->val) -RB_DECLARE_CALLBACKS(static, augment_callbacks, struct test_node, rb, - u32, augmented, augment_recompute) +RB_DECLARE_CALLBACKS_MAX(static, augment_callbacks, + struct test_node, rb, u32, augmented, NODE_VAL) static void insert_augmented(struct test_node *node, struct rb_root_cached *root) @@ -238,7 +222,20 @@ static void check_augmented(int nr_nodes) check(nr_nodes); for (rb = rb_first(&root.rb_root); rb; rb = rb_next(rb)) { struct test_node *node = rb_entry(rb, struct test_node, rb); - WARN_ON_ONCE(node->augmented != augment_recompute(node)); + u32 subtree, max = node->val; + if (node->rb.rb_left) { + subtree = rb_entry(node->rb.rb_left, struct test_node, + rb)->augmented; + if (max < subtree) + max = subtree; + } + if (node->rb.rb_right) { + subtree = rb_entry(node->rb.rb_right, struct test_node, + rb)->augmented; + if (max < subtree) + max = subtree; + } + WARN_ON_ONCE(node->augmented != max); } } diff --git a/mm/mmap.c b/mm/mmap.c index f1e8c7f93e04..14b7da317ec0 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -289,9 +289,9 @@ out: return retval; } -static long vma_compute_subtree_gap(struct vm_area_struct *vma) +static inline unsigned long vma_compute_gap(struct vm_area_struct *vma) { - unsigned long max, prev_end, subtree_gap; + unsigned long gap, prev_end; /* * Note: in the rare case of a VM_GROWSDOWN above a VM_GROWSUP, we @@ -299,14 +299,21 @@ static long vma_compute_subtree_gap(struct vm_area_struct *vma) * an unmapped area; whereas when expanding we only require one. * That's a little inconsistent, but keeps the code here simpler. */ - max = vm_start_gap(vma); + gap = vm_start_gap(vma); if (vma->vm_prev) { prev_end = vm_end_gap(vma->vm_prev); - if (max > prev_end) - max -= prev_end; + if (gap > prev_end) + gap -= prev_end; else - max = 0; + gap = 0; } + return gap; +} + +#ifdef CONFIG_DEBUG_VM_RB +static unsigned long vma_compute_subtree_gap(struct vm_area_struct *vma) +{ + unsigned long max = vma_compute_gap(vma), subtree_gap; if (vma->vm_rb.rb_left) { subtree_gap = rb_entry(vma->vm_rb.rb_left, struct vm_area_struct, vm_rb)->rb_subtree_gap; @@ -322,7 +329,6 @@ static long vma_compute_subtree_gap(struct vm_area_struct *vma) return max; } -#ifdef CONFIG_DEBUG_VM_RB static int browse_rb(struct mm_struct *mm) { struct rb_root *root = &mm->mm_rb; @@ -428,8 +434,9 @@ static void validate_mm(struct mm_struct *mm) #define validate_mm(mm) do { } while (0) #endif -RB_DECLARE_CALLBACKS(static, vma_gap_callbacks, struct vm_area_struct, vm_rb, - unsigned long, rb_subtree_gap, vma_compute_subtree_gap) +RB_DECLARE_CALLBACKS_MAX(static, vma_gap_callbacks, + struct vm_area_struct, vm_rb, + unsigned long, rb_subtree_gap, vma_compute_gap) /* * Update augmented rbtree rb_subtree_gap values after vma->vm_start or @@ -439,8 +446,8 @@ RB_DECLARE_CALLBACKS(static, vma_gap_callbacks, struct vm_area_struct, vm_rb, static void vma_gap_update(struct vm_area_struct *vma) { /* - * As it turns out, RB_DECLARE_CALLBACKS() already created a callback - * function that does exactly what we want. + * As it turns out, RB_DECLARE_CALLBACKS_MAX() already created + * a callback function that does exactly what we want. */ vma_gap_callbacks_propagate(&vma->vm_rb, NULL); } diff --git a/mm/vmalloc.c b/mm/vmalloc.c index fcadd3e25c0c..a3c70e275f4e 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -396,9 +396,8 @@ compute_subtree_max_size(struct vmap_area *va) get_subtree_max_size(va->rb_node.rb_right)); } -RB_DECLARE_CALLBACKS(static, free_vmap_area_rb_augment_cb, - struct vmap_area, rb_node, unsigned long, subtree_max_size, - compute_subtree_max_size) +RB_DECLARE_CALLBACKS_MAX(static, free_vmap_area_rb_augment_cb, + struct vmap_area, rb_node, unsigned long, subtree_max_size, va_size) static void purge_vmap_area_lazy(void); static BLOCKING_NOTIFIER_HEAD(vmap_notify_list); diff --git a/tools/include/linux/rbtree_augmented.h b/tools/include/linux/rbtree_augmented.h index de3a480204ba..4e8c4c76e9a2 100644 --- a/tools/include/linux/rbtree_augmented.h +++ b/tools/include/linux/rbtree_augmented.h @@ -63,7 +63,7 @@ rb_insert_augmented_cached(struct rb_node *node, } /* - * Template for declaring augmented rbtree callbacks + * Template for declaring augmented rbtree callbacks (generic case) * * RBSTATIC: 'static' or empty * RBNAME: name of the rb_augment_callbacks structure @@ -109,6 +109,40 @@ RBSTATIC const struct rb_augment_callbacks RBNAME = { \ .rotate = RBNAME ## _rotate \ }; +/* + * Template for declaring augmented rbtree callbacks, + * computing RBAUGMENTED scalar as max(RBCOMPUTE(node)) for all subtree nodes. + * + * RBSTATIC: 'static' or empty + * RBNAME: name of the rb_augment_callbacks structure + * RBSTRUCT: struct type of the tree nodes + * RBFIELD: name of struct rb_node field within RBSTRUCT + * RBTYPE: type of the RBAUGMENTED field + * RBAUGMENTED: name of RBTYPE field within RBSTRUCT holding data for subtree + * RBCOMPUTE: name of function that returns the per-node RBTYPE scalar + */ + +#define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ + RBTYPE, RBAUGMENTED, RBCOMPUTE) \ +static inline RBTYPE RBNAME ## _compute_max(RBSTRUCT *node) \ +{ \ + RBSTRUCT *child; \ + RBTYPE max = RBCOMPUTE(node); \ + if (node->RBFIELD.rb_left) { \ + child = rb_entry(node->RBFIELD.rb_left, RBSTRUCT, RBFIELD); \ + if (child->RBAUGMENTED > max) \ + max = child->RBAUGMENTED; \ + } \ + if (node->RBFIELD.rb_right) { \ + child = rb_entry(node->RBFIELD.rb_right, RBSTRUCT, RBFIELD); \ + if (child->RBAUGMENTED > max) \ + max = child->RBAUGMENTED; \ + } \ + return max; \ +} \ +RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ + RBTYPE, RBAUGMENTED, RBNAME ## _compute_max) + #define RB_RED 0 #define RB_BLACK 1 -- cgit v1.2.3-59-g8ed1b From 6d2052d188d962ffb7ad3d413e6ffd5f276aec94 Mon Sep 17 00:00:00 2001 From: Michel Lespinasse Date: Wed, 25 Sep 2019 16:46:10 -0700 Subject: augmented rbtree: rework the RB_DECLARE_CALLBACKS macro definition Change the definition of the RBCOMPUTE function. The propagate callback repeatedly calls RBCOMPUTE as it moves from leaf to root. it wants to stop recomputing once the augmented subtree information doesn't change. This was previously checked using the == operator, but that only works when the augmented subtree information is a scalar field. This commit modifies the RBCOMPUTE function so that it now sets the augmented subtree information instead of returning it, and returns a boolean value indicating if the propagate callback should stop. The motivation for this change is that I want to introduce augmented rbtree uses where the augmented data for the subtree is a struct instead of a scalar. Link: http://lkml.kernel.org/r/20190703040156.56953-4-walken@google.com Signed-off-by: Michel Lespinasse Acked-by: Peter Zijlstra (Intel) Cc: David Howells Cc: Davidlohr Bueso Cc: Uladzislau Rezki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rbtree_augmented.h | 24 ++++++++++++------------ tools/include/linux/rbtree_augmented.h | 24 ++++++++++++------------ 2 files changed, 24 insertions(+), 24 deletions(-) (limited to 'tools') diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h index e5937e387e02..fdd421b8d9ae 100644 --- a/include/linux/rbtree_augmented.h +++ b/include/linux/rbtree_augmented.h @@ -67,22 +67,19 @@ rb_insert_augmented_cached(struct rb_node *node, * RBNAME: name of the rb_augment_callbacks structure * RBSTRUCT: struct type of the tree nodes * RBFIELD: name of struct rb_node field within RBSTRUCT - * RBTYPE: type of the RBAUGMENTED field - * RBAUGMENTED: name of RBTYPE field within RBSTRUCT holding data for subtree + * RBAUGMENTED: name of field within RBSTRUCT holding data for subtree * RBCOMPUTE: name of function that recomputes the RBAUGMENTED data */ -#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ - RBTYPE, RBAUGMENTED, RBCOMPUTE) \ +#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \ + RBSTRUCT, RBFIELD, RBAUGMENTED, RBCOMPUTE) \ static inline void \ RBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop) \ { \ while (rb != stop) { \ RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \ - RBTYPE augmented = RBCOMPUTE(node); \ - if (node->RBAUGMENTED == augmented) \ + if (RBCOMPUTE(node, true)) \ break; \ - node->RBAUGMENTED = augmented; \ rb = rb_parent(&node->RBFIELD); \ } \ } \ @@ -99,7 +96,7 @@ RBNAME ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \ RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \ RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \ new->RBAUGMENTED = old->RBAUGMENTED; \ - old->RBAUGMENTED = RBCOMPUTE(old); \ + RBCOMPUTE(old, false); \ } \ RBSTATIC const struct rb_augment_callbacks RBNAME = { \ .propagate = RBNAME ## _propagate, \ @@ -122,7 +119,7 @@ RBSTATIC const struct rb_augment_callbacks RBNAME = { \ #define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ RBTYPE, RBAUGMENTED, RBCOMPUTE) \ -static inline RBTYPE RBNAME ## _compute_max(RBSTRUCT *node) \ +static inline bool RBNAME ## _compute_max(RBSTRUCT *node, bool exit) \ { \ RBSTRUCT *child; \ RBTYPE max = RBCOMPUTE(node); \ @@ -136,10 +133,13 @@ static inline RBTYPE RBNAME ## _compute_max(RBSTRUCT *node) \ if (child->RBAUGMENTED > max) \ max = child->RBAUGMENTED; \ } \ - return max; \ + if (exit && node->RBAUGMENTED == max) \ + return true; \ + node->RBAUGMENTED = max; \ + return false; \ } \ -RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ - RBTYPE, RBAUGMENTED, RBNAME ## _compute_max) +RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \ + RBSTRUCT, RBFIELD, RBAUGMENTED, RBNAME ## _compute_max) #define RB_RED 0 diff --git a/tools/include/linux/rbtree_augmented.h b/tools/include/linux/rbtree_augmented.h index 4e8c4c76e9a2..381aa948610d 100644 --- a/tools/include/linux/rbtree_augmented.h +++ b/tools/include/linux/rbtree_augmented.h @@ -69,22 +69,19 @@ rb_insert_augmented_cached(struct rb_node *node, * RBNAME: name of the rb_augment_callbacks structure * RBSTRUCT: struct type of the tree nodes * RBFIELD: name of struct rb_node field within RBSTRUCT - * RBTYPE: type of the RBAUGMENTED field - * RBAUGMENTED: name of RBTYPE field within RBSTRUCT holding data for subtree + * RBAUGMENTED: name of field within RBSTRUCT holding data for subtree * RBCOMPUTE: name of function that recomputes the RBAUGMENTED data */ -#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ - RBTYPE, RBAUGMENTED, RBCOMPUTE) \ +#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \ + RBSTRUCT, RBFIELD, RBAUGMENTED, RBCOMPUTE) \ static inline void \ RBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop) \ { \ while (rb != stop) { \ RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \ - RBTYPE augmented = RBCOMPUTE(node); \ - if (node->RBAUGMENTED == augmented) \ + if (RBCOMPUTE(node, true)) \ break; \ - node->RBAUGMENTED = augmented; \ rb = rb_parent(&node->RBFIELD); \ } \ } \ @@ -101,7 +98,7 @@ RBNAME ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \ RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \ RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \ new->RBAUGMENTED = old->RBAUGMENTED; \ - old->RBAUGMENTED = RBCOMPUTE(old); \ + RBCOMPUTE(old, false); \ } \ RBSTATIC const struct rb_augment_callbacks RBNAME = { \ .propagate = RBNAME ## _propagate, \ @@ -124,7 +121,7 @@ RBSTATIC const struct rb_augment_callbacks RBNAME = { \ #define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ RBTYPE, RBAUGMENTED, RBCOMPUTE) \ -static inline RBTYPE RBNAME ## _compute_max(RBSTRUCT *node) \ +static inline bool RBNAME ## _compute_max(RBSTRUCT *node, bool exit) \ { \ RBSTRUCT *child; \ RBTYPE max = RBCOMPUTE(node); \ @@ -138,10 +135,13 @@ static inline RBTYPE RBNAME ## _compute_max(RBSTRUCT *node) \ if (child->RBAUGMENTED > max) \ max = child->RBAUGMENTED; \ } \ - return max; \ + if (exit && node->RBAUGMENTED == max) \ + return true; \ + node->RBAUGMENTED = max; \ + return false; \ } \ -RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ - RBTYPE, RBAUGMENTED, RBNAME ## _compute_max) +RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \ + RBSTRUCT, RBFIELD, RBAUGMENTED, RBNAME ## _compute_max) #define RB_RED 0 -- cgit v1.2.3-59-g8ed1b From ca7a03c4175366a92cee0ccc4fec0038c3266e26 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 24 Sep 2019 16:01:28 +0200 Subject: ipv6: do not free rt if FIB_LOOKUP_NOREF is set on suppress rule Commit 7d9e5f422150 removed references from certain dsts, but accounting for this never translated down into the fib6 suppression code. This bug was triggered by WireGuard users who use wg-quick(8), which uses the "suppress-prefix" directive to ip-rule(8) for routing all of their internet traffic without routing loops. The test case added here causes the reference underflow by causing packets to evaluate a suppress rule. Fixes: 7d9e5f422150 ("ipv6: convert major tx path to use RT6_LOOKUP_F_DST_NOREF") Signed-off-by: Jason A. Donenfeld Acked-by: Wei Wang Signed-off-by: David S. Miller --- net/ipv6/fib6_rules.c | 3 ++- tools/testing/selftests/net/fib_tests.sh | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index d22b6c140f23..f9e8fe3ff0c5 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -287,7 +287,8 @@ static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg return false; suppress_route: - ip6_rt_put(rt); + if (!(arg->flags & FIB_LOOKUP_NOREF)) + ip6_rt_put(rt); return true; } diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh index cba83a12da82..c4ba0ff4a53f 100755 --- a/tools/testing/selftests/net/fib_tests.sh +++ b/tools/testing/selftests/net/fib_tests.sh @@ -9,7 +9,7 @@ ret=0 ksft_skip=4 # all tests in this script. Can be overridden with -t option -TESTS="unregister down carrier nexthop ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics ipv4_route_metrics ipv4_route_v6_gw rp_filter" +TESTS="unregister down carrier nexthop suppress ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics ipv4_route_metrics ipv4_route_v6_gw rp_filter" VERBOSE=0 PAUSE_ON_FAIL=no @@ -616,6 +616,20 @@ fib_nexthop_test() cleanup } +fib_suppress_test() +{ + $IP link add dummy1 type dummy + $IP link set dummy1 up + $IP -6 route add default dev dummy1 + $IP -6 rule add table main suppress_prefixlength 0 + ping -f -c 1000 -W 1 1234::1 || true + $IP -6 rule del table main suppress_prefixlength 0 + $IP link del dummy1 + + # If we got here without crashing, we're good. + return 0 +} + ################################################################################ # Tests on route add and replace @@ -1593,6 +1607,7 @@ do fib_carrier_test|carrier) fib_carrier_test;; fib_rp_filter_test|rp_filter) fib_rp_filter_test;; fib_nexthop_test|nexthop) fib_nexthop_test;; + fib_suppress_test|suppress) fib_suppress_test;; ipv6_route_test|ipv6_rt) ipv6_route_test;; ipv4_route_test|ipv4_rt) ipv4_route_test;; ipv6_addr_metric) ipv6_addr_metric_test;; -- cgit v1.2.3-59-g8ed1b From 39529a9948d8f67f39cb72bec914c1adab38562d Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 25 Sep 2019 13:37:45 -0700 Subject: libbpf: Teach btf_dumper to emit stand-alone anonymous enum definitions BTF-to-C converter previously skipped anonymous enums in an assumption that those are embedded in struct's field definitions. This is not always the case and a lot of kernel constants are defined as part of anonymous enums. This change fixes the logic by eagerly marking all types as either referenced by any other type or not. This is enough to distinguish two classes of anonymous enums and emit previously omitted enum definitions. Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20190925203745.3173184-1-andriin@fb.com --- tools/lib/bpf/btf_dump.c | 93 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c index 84b0661db7f3..ede55fec3618 100644 --- a/tools/lib/bpf/btf_dump.c +++ b/tools/lib/bpf/btf_dump.c @@ -48,6 +48,8 @@ struct btf_dump_type_aux_state { __u8 fwd_emitted: 1; /* whether unique non-duplicate name was already assigned */ __u8 name_resolved: 1; + /* whether type is referenced from any other type */ + __u8 referenced: 1; }; struct btf_dump { @@ -173,6 +175,7 @@ void btf_dump__free(struct btf_dump *d) free(d); } +static int btf_dump_mark_referenced(struct btf_dump *d); static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr); static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id); @@ -213,6 +216,11 @@ int btf_dump__dump_type(struct btf_dump *d, __u32 id) /* VOID is special */ d->type_states[0].order_state = ORDERED; d->type_states[0].emit_state = EMITTED; + + /* eagerly determine referenced types for anon enums */ + err = btf_dump_mark_referenced(d); + if (err) + return err; } d->emit_queue_cnt = 0; @@ -226,6 +234,79 @@ int btf_dump__dump_type(struct btf_dump *d, __u32 id) return 0; } +/* + * Mark all types that are referenced from any other type. This is used to + * determine top-level anonymous enums that need to be emitted as an + * independent type declarations. + * Anonymous enums come in two flavors: either embedded in a struct's field + * definition, in which case they have to be declared inline as part of field + * type declaration; or as a top-level anonymous enum, typically used for + * declaring global constants. It's impossible to distinguish between two + * without knowning whether given enum type was referenced from other type: + * top-level anonymous enum won't be referenced by anything, while embedded + * one will. + */ +static int btf_dump_mark_referenced(struct btf_dump *d) +{ + int i, j, n = btf__get_nr_types(d->btf); + const struct btf_type *t; + __u16 vlen; + + for (i = 1; i <= n; i++) { + t = btf__type_by_id(d->btf, i); + vlen = btf_vlen(t); + + switch (btf_kind(t)) { + case BTF_KIND_INT: + case BTF_KIND_ENUM: + case BTF_KIND_FWD: + break; + + case BTF_KIND_VOLATILE: + case BTF_KIND_CONST: + case BTF_KIND_RESTRICT: + case BTF_KIND_PTR: + case BTF_KIND_TYPEDEF: + case BTF_KIND_FUNC: + case BTF_KIND_VAR: + d->type_states[t->type].referenced = 1; + break; + + case BTF_KIND_ARRAY: { + const struct btf_array *a = btf_array(t); + + d->type_states[a->index_type].referenced = 1; + d->type_states[a->type].referenced = 1; + break; + } + case BTF_KIND_STRUCT: + case BTF_KIND_UNION: { + const struct btf_member *m = btf_members(t); + + for (j = 0; j < vlen; j++, m++) + d->type_states[m->type].referenced = 1; + break; + } + case BTF_KIND_FUNC_PROTO: { + const struct btf_param *p = btf_params(t); + + for (j = 0; j < vlen; j++, p++) + d->type_states[p->type].referenced = 1; + break; + } + case BTF_KIND_DATASEC: { + const struct btf_var_secinfo *v = btf_var_secinfos(t); + + for (j = 0; j < vlen; j++, v++) + d->type_states[v->type].referenced = 1; + break; + } + default: + return -EINVAL; + } + } + return 0; +} static int btf_dump_add_emit_queue_id(struct btf_dump *d, __u32 id) { __u32 *new_queue; @@ -395,7 +476,12 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr) } case BTF_KIND_ENUM: case BTF_KIND_FWD: - if (t->name_off != 0) { + /* + * non-anonymous or non-referenced enums are top-level + * declarations and should be emitted. Same logic can be + * applied to FWDs, it won't hurt anyways. + */ + if (t->name_off != 0 || !tstate->referenced) { err = btf_dump_add_emit_queue_id(d, id); if (err) return err; @@ -536,11 +622,6 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id) t = btf__type_by_id(d->btf, id); kind = btf_kind(t); - if (top_level_def && t->name_off == 0) { - pr_warning("unexpected nameless definition, id:[%u]\n", id); - return; - } - if (tstate->emit_state == EMITTING) { if (tstate->fwd_emitted) return; -- cgit v1.2.3-59-g8ed1b From 26acf400d2dcc72c7e713e1f55db47ad92010cc2 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 26 Sep 2019 14:36:48 -0300 Subject: perf unwind: Fix libunwind build failure on i386 systems Naresh Kamboju reported, that on the i386 build pr_err() doesn't get defined properly due to header ordering: perf-in.o: In function `libunwind__x86_reg_id': tools/perf/util/libunwind/../../arch/x86/util/unwind-libunwind.c:109: undefined reference to `pr_err' Reported-by: Naresh Kamboju Signed-off-by: Arnaldo Carvalho de Melo Cc: David Ahern Cc: Jiri Olsa Cc: Linus Torvalds Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar --- tools/perf/arch/x86/util/unwind-libunwind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/arch/x86/util/unwind-libunwind.c b/tools/perf/arch/x86/util/unwind-libunwind.c index 05920e3edf7a..47357973b55b 100644 --- a/tools/perf/arch/x86/util/unwind-libunwind.c +++ b/tools/perf/arch/x86/util/unwind-libunwind.c @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include "../../util/debug.h" #ifndef REMOTE_UNWIND_LIBUNWIND #include #include "perf_regs.h" #include "../../util/unwind.h" -#include "../../util/debug.h" #endif #ifdef HAVE_ARCH_X86_64_SUPPORT -- cgit v1.2.3-59-g8ed1b From 094444204570a5420d9e6ce3d4558877c3487856 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 26 Sep 2019 15:01:15 +0200 Subject: selftests: kvm: add test for dirty logging inside nested guests Check that accesses by nested guests are logged according to the L1 physical addresses rather than L2. Most of the patch is really adding EPT support to the testing framework. Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/Makefile | 1 + .../selftests/kvm/include/x86_64/processor.h | 3 + tools/testing/selftests/kvm/include/x86_64/vmx.h | 14 ++ tools/testing/selftests/kvm/lib/kvm_util.c | 2 +- .../testing/selftests/kvm/lib/kvm_util_internal.h | 3 + tools/testing/selftests/kvm/lib/x86_64/vmx.c | 201 ++++++++++++++++++++- .../selftests/kvm/x86_64/vmx_dirty_log_test.c | 156 ++++++++++++++++ 7 files changed, 377 insertions(+), 3 deletions(-) create mode 100644 tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c (limited to 'tools') diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 62c591f87dab..fd84b7a78dcf 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -22,6 +22,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/smm_test TEST_GEN_PROGS_x86_64 += x86_64/state_test TEST_GEN_PROGS_x86_64 += x86_64/sync_regs_test TEST_GEN_PROGS_x86_64 += x86_64/vmx_close_while_nested_test +TEST_GEN_PROGS_x86_64 += x86_64/vmx_dirty_log_test TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test TEST_GEN_PROGS_x86_64 += x86_64/vmx_tsc_adjust_test TEST_GEN_PROGS_x86_64 += clear_dirty_log_test diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h index 0c17f2ee685e..ff234018219c 100644 --- a/tools/testing/selftests/kvm/include/x86_64/processor.h +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h @@ -1083,6 +1083,9 @@ void kvm_get_cpu_address_width(unsigned int *pa_bits, unsigned int *va_bits); #define VMX_BASIC_MEM_TYPE_WB 6LLU #define VMX_BASIC_INOUT 0x0040000000000000LLU +/* VMX_EPT_VPID_CAP bits */ +#define VMX_EPT_VPID_CAP_AD_BITS (1ULL << 21) + /* MSR_IA32_VMX_MISC bits */ #define MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS (1ULL << 29) #define MSR_IA32_VMX_MISC_PREEMPTION_TIMER_SCALE 0x1F diff --git a/tools/testing/selftests/kvm/include/x86_64/vmx.h b/tools/testing/selftests/kvm/include/x86_64/vmx.h index 69b17055f63d..6ae5a47fe067 100644 --- a/tools/testing/selftests/kvm/include/x86_64/vmx.h +++ b/tools/testing/selftests/kvm/include/x86_64/vmx.h @@ -569,6 +569,10 @@ struct vmx_pages { void *enlightened_vmcs_hva; uint64_t enlightened_vmcs_gpa; void *enlightened_vmcs; + + void *eptp_hva; + uint64_t eptp_gpa; + void *eptp; }; struct vmx_pages *vcpu_alloc_vmx(struct kvm_vm *vm, vm_vaddr_t *p_vmx_gva); @@ -576,4 +580,14 @@ bool prepare_for_vmx_operation(struct vmx_pages *vmx); void prepare_vmcs(struct vmx_pages *vmx, void *guest_rip, void *guest_rsp); bool load_vmcs(struct vmx_pages *vmx); +void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm, + uint64_t nested_paddr, uint64_t paddr, uint32_t eptp_memslot); +void nested_map(struct vmx_pages *vmx, struct kvm_vm *vm, + uint64_t nested_paddr, uint64_t paddr, uint64_t size, + uint32_t eptp_memslot); +void nested_map_memslot(struct vmx_pages *vmx, struct kvm_vm *vm, + uint32_t memslot, uint32_t eptp_memslot); +void prepare_eptp(struct vmx_pages *vmx, struct kvm_vm *vm, + uint32_t eptp_memslot); + #endif /* SELFTEST_KVM_VMX_H */ diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 80a338b5403c..41cf45416060 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -705,7 +705,7 @@ void vm_userspace_mem_region_add(struct kvm_vm *vm, * on error (e.g. currently no memory region using memslot as a KVM * memory slot ID). */ -static struct userspace_mem_region * +struct userspace_mem_region * memslot2region(struct kvm_vm *vm, uint32_t memslot) { struct userspace_mem_region *region; diff --git a/tools/testing/selftests/kvm/lib/kvm_util_internal.h b/tools/testing/selftests/kvm/lib/kvm_util_internal.h index f36262e0f655..ac50c42750cf 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util_internal.h +++ b/tools/testing/selftests/kvm/lib/kvm_util_internal.h @@ -68,4 +68,7 @@ void virt_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent); void regs_dump(FILE *stream, struct kvm_regs *regs, uint8_t indent); void sregs_dump(FILE *stream, struct kvm_sregs *sregs, uint8_t indent); +struct userspace_mem_region * +memslot2region(struct kvm_vm *vm, uint32_t memslot); + #endif /* SELFTEST_KVM_UTIL_INTERNAL_H */ diff --git a/tools/testing/selftests/kvm/lib/x86_64/vmx.c b/tools/testing/selftests/kvm/lib/x86_64/vmx.c index 9cef0455b819..fab8f6b0bf52 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/vmx.c +++ b/tools/testing/selftests/kvm/lib/x86_64/vmx.c @@ -7,11 +7,39 @@ #include "test_util.h" #include "kvm_util.h" +#include "../kvm_util_internal.h" #include "processor.h" #include "vmx.h" +#define PAGE_SHIFT_4K 12 + +#define KVM_EPT_PAGE_TABLE_MIN_PADDR 0x1c0000 + bool enable_evmcs; +struct eptPageTableEntry { + uint64_t readable:1; + uint64_t writable:1; + uint64_t executable:1; + uint64_t memory_type:3; + uint64_t ignore_pat:1; + uint64_t page_size:1; + uint64_t accessed:1; + uint64_t dirty:1; + uint64_t ignored_11_10:2; + uint64_t address:40; + uint64_t ignored_62_52:11; + uint64_t suppress_ve:1; +}; + +struct eptPageTablePointer { + uint64_t memory_type:3; + uint64_t page_walk_length:3; + uint64_t ad_enabled:1; + uint64_t reserved_11_07:5; + uint64_t address:40; + uint64_t reserved_63_52:12; +}; int vcpu_enable_evmcs(struct kvm_vm *vm, int vcpu_id) { uint16_t evmcs_ver; @@ -174,15 +202,35 @@ bool load_vmcs(struct vmx_pages *vmx) */ static inline void init_vmcs_control_fields(struct vmx_pages *vmx) { + uint32_t sec_exec_ctl = 0; + vmwrite(VIRTUAL_PROCESSOR_ID, 0); vmwrite(POSTED_INTR_NV, 0); vmwrite(PIN_BASED_VM_EXEC_CONTROL, rdmsr(MSR_IA32_VMX_TRUE_PINBASED_CTLS)); - if (!vmwrite(SECONDARY_VM_EXEC_CONTROL, 0)) + + if (vmx->eptp_gpa) { + uint64_t ept_paddr; + struct eptPageTablePointer eptp = { + .memory_type = VMX_BASIC_MEM_TYPE_WB, + .page_walk_length = 3, /* + 1 */ + .ad_enabled = !!(rdmsr(MSR_IA32_VMX_EPT_VPID_CAP) & VMX_EPT_VPID_CAP_AD_BITS), + .address = vmx->eptp_gpa >> PAGE_SHIFT_4K, + }; + + memcpy(&ept_paddr, &eptp, sizeof(ept_paddr)); + vmwrite(EPT_POINTER, ept_paddr); + sec_exec_ctl |= SECONDARY_EXEC_ENABLE_EPT; + } + + if (!vmwrite(SECONDARY_VM_EXEC_CONTROL, sec_exec_ctl)) vmwrite(CPU_BASED_VM_EXEC_CONTROL, rdmsr(MSR_IA32_VMX_TRUE_PROCBASED_CTLS) | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS); - else + else { vmwrite(CPU_BASED_VM_EXEC_CONTROL, rdmsr(MSR_IA32_VMX_TRUE_PROCBASED_CTLS)); + GUEST_ASSERT(!sec_exec_ctl); + } + vmwrite(EXCEPTION_BITMAP, 0); vmwrite(PAGE_FAULT_ERROR_CODE_MASK, 0); vmwrite(PAGE_FAULT_ERROR_CODE_MATCH, -1); /* Never match */ @@ -327,3 +375,152 @@ void prepare_vmcs(struct vmx_pages *vmx, void *guest_rip, void *guest_rsp) init_vmcs_host_state(); init_vmcs_guest_state(guest_rip, guest_rsp); } + +void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm, + uint64_t nested_paddr, uint64_t paddr, uint32_t eptp_memslot) +{ + uint16_t index[4]; + struct eptPageTableEntry *pml4e; + + TEST_ASSERT(vm->mode == VM_MODE_PXXV48_4K, "Attempt to use " + "unknown or unsupported guest mode, mode: 0x%x", vm->mode); + + TEST_ASSERT((nested_paddr % vm->page_size) == 0, + "Nested physical address not on page boundary,\n" + " nested_paddr: 0x%lx vm->page_size: 0x%x", + nested_paddr, vm->page_size); + TEST_ASSERT((nested_paddr >> vm->page_shift) <= vm->max_gfn, + "Physical address beyond beyond maximum supported,\n" + " nested_paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x", + paddr, vm->max_gfn, vm->page_size); + TEST_ASSERT((paddr % vm->page_size) == 0, + "Physical address not on page boundary,\n" + " paddr: 0x%lx vm->page_size: 0x%x", + paddr, vm->page_size); + TEST_ASSERT((paddr >> vm->page_shift) <= vm->max_gfn, + "Physical address beyond beyond maximum supported,\n" + " paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x", + paddr, vm->max_gfn, vm->page_size); + + index[0] = (nested_paddr >> 12) & 0x1ffu; + index[1] = (nested_paddr >> 21) & 0x1ffu; + index[2] = (nested_paddr >> 30) & 0x1ffu; + index[3] = (nested_paddr >> 39) & 0x1ffu; + + /* Allocate page directory pointer table if not present. */ + pml4e = vmx->eptp_hva; + if (!pml4e[index[3]].readable) { + pml4e[index[3]].address = vm_phy_page_alloc(vm, + KVM_EPT_PAGE_TABLE_MIN_PADDR, eptp_memslot) + >> vm->page_shift; + pml4e[index[3]].writable = true; + pml4e[index[3]].readable = true; + pml4e[index[3]].executable = true; + } + + /* Allocate page directory table if not present. */ + struct eptPageTableEntry *pdpe; + pdpe = addr_gpa2hva(vm, pml4e[index[3]].address * vm->page_size); + if (!pdpe[index[2]].readable) { + pdpe[index[2]].address = vm_phy_page_alloc(vm, + KVM_EPT_PAGE_TABLE_MIN_PADDR, eptp_memslot) + >> vm->page_shift; + pdpe[index[2]].writable = true; + pdpe[index[2]].readable = true; + pdpe[index[2]].executable = true; + } + + /* Allocate page table if not present. */ + struct eptPageTableEntry *pde; + pde = addr_gpa2hva(vm, pdpe[index[2]].address * vm->page_size); + if (!pde[index[1]].readable) { + pde[index[1]].address = vm_phy_page_alloc(vm, + KVM_EPT_PAGE_TABLE_MIN_PADDR, eptp_memslot) + >> vm->page_shift; + pde[index[1]].writable = true; + pde[index[1]].readable = true; + pde[index[1]].executable = true; + } + + /* Fill in page table entry. */ + struct eptPageTableEntry *pte; + pte = addr_gpa2hva(vm, pde[index[1]].address * vm->page_size); + pte[index[0]].address = paddr >> vm->page_shift; + pte[index[0]].writable = true; + pte[index[0]].readable = true; + pte[index[0]].executable = true; + + /* + * For now mark these as accessed and dirty because the only + * testcase we have needs that. Can be reconsidered later. + */ + pte[index[0]].accessed = true; + pte[index[0]].dirty = true; +} + +/* + * Map a range of EPT guest physical addresses to the VM's physical address + * + * Input Args: + * vm - Virtual Machine + * nested_paddr - Nested guest physical address to map + * paddr - VM Physical Address + * size - The size of the range to map + * eptp_memslot - Memory region slot for new virtual translation tables + * + * Output Args: None + * + * Return: None + * + * Within the VM given by vm, creates a nested guest translation for the + * page range starting at nested_paddr to the page range starting at paddr. + */ +void nested_map(struct vmx_pages *vmx, struct kvm_vm *vm, + uint64_t nested_paddr, uint64_t paddr, uint64_t size, + uint32_t eptp_memslot) +{ + size_t page_size = vm->page_size; + size_t npages = size / page_size; + + TEST_ASSERT(nested_paddr + size > nested_paddr, "Vaddr overflow"); + TEST_ASSERT(paddr + size > paddr, "Paddr overflow"); + + while (npages--) { + nested_pg_map(vmx, vm, nested_paddr, paddr, eptp_memslot); + nested_paddr += page_size; + paddr += page_size; + } +} + +/* Prepare an identity extended page table that maps all the + * physical pages in VM. + */ +void nested_map_memslot(struct vmx_pages *vmx, struct kvm_vm *vm, + uint32_t memslot, uint32_t eptp_memslot) +{ + sparsebit_idx_t i, last; + struct userspace_mem_region *region = + memslot2region(vm, memslot); + + i = (region->region.guest_phys_addr >> vm->page_shift) - 1; + last = i + (region->region.memory_size >> vm->page_shift); + for (;;) { + i = sparsebit_next_clear(region->unused_phy_pages, i); + if (i > last) + break; + + nested_map(vmx, vm, + (uint64_t)i << vm->page_shift, + (uint64_t)i << vm->page_shift, + 1 << vm->page_shift, + eptp_memslot); + } +} + +void prepare_eptp(struct vmx_pages *vmx, struct kvm_vm *vm, + uint32_t eptp_memslot) +{ + vmx->eptp = (void *)vm_vaddr_alloc(vm, getpagesize(), 0x10000, 0, 0); + vmx->eptp_hva = addr_gva2hva(vm, (uintptr_t)vmx->eptp); + vmx->eptp_gpa = addr_gva2gpa(vm, (uintptr_t)vmx->eptp); +} diff --git a/tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c b/tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c new file mode 100644 index 000000000000..0bca1cfe2c1e --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KVM dirty page logging test + * + * Copyright (C) 2018, Red Hat, Inc. + */ + +#define _GNU_SOURCE /* for program_invocation_name */ + +#include +#include +#include +#include + +#include "test_util.h" +#include "kvm_util.h" +#include "processor.h" +#include "vmx.h" + +#define VCPU_ID 1 + +/* The memory slot index to track dirty pages */ +#define TEST_MEM_SLOT_INDEX 1 +#define TEST_MEM_SIZE 3 + +/* L1 guest test virtual memory offset */ +#define GUEST_TEST_MEM 0xc0000000 + +/* L2 guest test virtual memory offset */ +#define NESTED_TEST_MEM1 0xc0001000 +#define NESTED_TEST_MEM2 0xc0002000 + +static void l2_guest_code(void) +{ + *(volatile uint64_t *)NESTED_TEST_MEM1; + *(volatile uint64_t *)NESTED_TEST_MEM1 = 1; + GUEST_SYNC(true); + GUEST_SYNC(false); + + *(volatile uint64_t *)NESTED_TEST_MEM2 = 1; + GUEST_SYNC(true); + *(volatile uint64_t *)NESTED_TEST_MEM2 = 1; + GUEST_SYNC(true); + GUEST_SYNC(false); + + /* Exit to L1 and never come back. */ + vmcall(); +} + +void l1_guest_code(struct vmx_pages *vmx) +{ +#define L2_GUEST_STACK_SIZE 64 + unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; + + GUEST_ASSERT(vmx->vmcs_gpa); + GUEST_ASSERT(prepare_for_vmx_operation(vmx)); + GUEST_ASSERT(load_vmcs(vmx)); + + prepare_vmcs(vmx, l2_guest_code, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + GUEST_SYNC(false); + GUEST_ASSERT(!vmlaunch()); + GUEST_SYNC(false); + GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL); + GUEST_DONE(); +} + +int main(int argc, char *argv[]) +{ + vm_vaddr_t vmx_pages_gva = 0; + struct vmx_pages *vmx; + unsigned long *bmap; + uint64_t *host_test_mem; + + struct kvm_vm *vm; + struct kvm_run *run; + struct ucall uc; + bool done = false; + + /* Create VM */ + vm = vm_create_default(VCPU_ID, 0, l1_guest_code); + vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid()); + vmx = vcpu_alloc_vmx(vm, &vmx_pages_gva); + vcpu_args_set(vm, VCPU_ID, 1, vmx_pages_gva); + run = vcpu_state(vm, VCPU_ID); + + /* Add an extra memory slot for testing dirty logging */ + vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, + GUEST_TEST_MEM, + TEST_MEM_SLOT_INDEX, + TEST_MEM_SIZE, + KVM_MEM_LOG_DIRTY_PAGES); + + /* + * Add an identity map for GVA range [0xc0000000, 0xc0002000). This + * affects both L1 and L2. However... + */ + virt_map(vm, GUEST_TEST_MEM, GUEST_TEST_MEM, + TEST_MEM_SIZE * 4096, 0); + + /* + * ... pages in the L2 GPA range [0xc0001000, 0xc0003000) will map to + * 0xc0000000. + * + * Note that prepare_eptp should be called only L1's GPA map is done, + * meaning after the last call to virt_map. + */ + prepare_eptp(vmx, vm, 0); + nested_map_memslot(vmx, vm, 0, 0); + nested_map(vmx, vm, NESTED_TEST_MEM1, GUEST_TEST_MEM, 4096, 0); + nested_map(vmx, vm, NESTED_TEST_MEM2, GUEST_TEST_MEM, 4096, 0); + + bmap = bitmap_alloc(TEST_MEM_SIZE); + host_test_mem = addr_gpa2hva(vm, GUEST_TEST_MEM); + + while (!done) { + memset(host_test_mem, 0xaa, TEST_MEM_SIZE * 4096); + _vcpu_run(vm, VCPU_ID); + TEST_ASSERT(run->exit_reason == KVM_EXIT_IO, + "Unexpected exit reason: %u (%s),\n", + run->exit_reason, + exit_reason_str(run->exit_reason)); + + switch (get_ucall(vm, VCPU_ID, &uc)) { + case UCALL_ABORT: + TEST_ASSERT(false, "%s at %s:%d", (const char *)uc.args[0], + __FILE__, uc.args[1]); + /* NOT REACHED */ + case UCALL_SYNC: + /* + * The nested guest wrote at offset 0x1000 in the memslot, but the + * dirty bitmap must be filled in according to L1 GPA, not L2. + */ + kvm_vm_get_dirty_log(vm, TEST_MEM_SLOT_INDEX, bmap); + if (uc.args[1]) { + TEST_ASSERT(test_bit(0, bmap), "Page 0 incorrectly reported clean\n"); + TEST_ASSERT(host_test_mem[0] == 1, "Page 0 not written by guest\n"); + } else { + TEST_ASSERT(!test_bit(0, bmap), "Page 0 incorrectly reported dirty\n"); + TEST_ASSERT(host_test_mem[0] == 0xaaaaaaaaaaaaaaaaULL, "Page 0 written by guest\n"); + } + + TEST_ASSERT(!test_bit(1, bmap), "Page 1 incorrectly reported dirty\n"); + TEST_ASSERT(host_test_mem[4096 / 8] == 0xaaaaaaaaaaaaaaaaULL, "Page 1 written by guest\n"); + TEST_ASSERT(!test_bit(2, bmap), "Page 2 incorrectly reported dirty\n"); + TEST_ASSERT(host_test_mem[8192 / 8] == 0xaaaaaaaaaaaaaaaaULL, "Page 2 written by guest\n"); + break; + case UCALL_DONE: + done = true; + break; + default: + TEST_ASSERT(false, "Unknown ucall 0x%x.", uc.cmd); + } + } +} -- cgit v1.2.3-59-g8ed1b From 4b0b2b096da9d296e0e5668cdfba8613bd6f5bc8 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 25 Sep 2019 12:59:23 -0700 Subject: libsubcmd: Make _FORTIFY_SOURCE defines dependent on the feature Unconditionally defining _FORTIFY_SOURCE can break tools that don't work with it, such as memory sanitizers: https://github.com/google/sanitizers/wiki/AddressSanitizer#faq Fixes: 4b6ab94eabe4 ("perf subcmd: Create subcmd library") Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Andi Kleen Cc: Jiri Olsa Cc: Josh Poimboeuf Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lore.kernel.org/lkml/20190925195924.152834-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/subcmd/Makefile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lib/subcmd/Makefile b/tools/lib/subcmd/Makefile index ed61fb3a46c0..5b2cd5e58df0 100644 --- a/tools/lib/subcmd/Makefile +++ b/tools/lib/subcmd/Makefile @@ -20,7 +20,13 @@ MAKEFLAGS += --no-print-directory LIBFILE = $(OUTPUT)libsubcmd.a CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC +CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -fPIC + +ifeq ($(DEBUG),0) + ifeq ($(feature-fortify-source), 1) + CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 + endif +endif ifeq ($(CC_NO_CLANG), 0) CFLAGS += -O3 -- cgit v1.2.3-59-g8ed1b From e3e2cf3d5b1fe800b032e14c0fdcd9a6fb20cf3b Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 25 Sep 2019 12:59:24 -0700 Subject: perf tests: Avoid raising SEGV using an obvious NULL dereference An optimized build such as: make -C tools/perf CLANG=1 CC=clang EXTRA_CFLAGS="-O3 will turn the dereference operation into a ud2 instruction, raising a SIGILL rather than a SIGSEGV. Use raise(..) for correctness and clarity. Similar issues were addressed in Numfor Mbiziwo-Tiapo's patch: https://lkml.org/lkml/2019/7/8/1234 Committer testing: Before: [root@quaco ~]# perf test hooks 55: perf hooks : Ok [root@quaco ~]# perf test -v hooks 55: perf hooks : --- start --- test child forked, pid 17092 SIGSEGV is observed as expected, try to recover. Fatal error (SEGFAULT) in perf hook 'test' test child finished with 0 ---- end ---- perf hooks: Ok [root@quaco ~]# After: [root@quaco ~]# perf test hooks 55: perf hooks : Ok [root@quaco ~]# perf test -v hooks 55: perf hooks : --- start --- test child forked, pid 17909 SIGSEGV is observed as expected, try to recover. Fatal error (SEGFAULT) in perf hook 'test' test child finished with 0 ---- end ---- perf hooks: Ok [root@quaco ~]# Fixes: a074865e60ed ("perf tools: Introduce perf hooks") Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Andi Kleen Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Wang Nan Link: http://lore.kernel.org/lkml/20190925195924.152834-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/perf-hooks.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/tests/perf-hooks.c b/tools/perf/tests/perf-hooks.c index dbc27199c65e..dd865e0bea12 100644 --- a/tools/perf/tests/perf-hooks.c +++ b/tools/perf/tests/perf-hooks.c @@ -19,12 +19,11 @@ static void sigsegv_handler(int sig __maybe_unused) static void the_hook(void *_hook_flags) { int *hook_flags = _hook_flags; - int *p = NULL; *hook_flags = 1234; /* Generate a segfault, test perf_hooks__recover */ - *p = 0; + raise(SIGSEGV); } int test__perf_hooks(struct test *test __maybe_unused, int subtest __maybe_unused) -- cgit v1.2.3-59-g8ed1b From d586ac10ce56b2381b8e1d8ed74660c1b2b8ab0d Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Fri, 20 Sep 2019 21:13:27 -0700 Subject: perf docs: Allow man page date to be specified With this change if a perf_date parameter is provided to asciidoc then it will override the default date written to the man page metadata. Without this change, or if the perf_date isn't specified, then the current date is written to the metadata. Having this parameter allows the metadata to be constant if builds happen on different dates. The name of the parameter is intended to be consistent with the existing perf_version parameter. Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Andi Kleen Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lore.kernel.org/lkml/20190921041327.155054-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/asciidoc.conf | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/perf/Documentation/asciidoc.conf b/tools/perf/Documentation/asciidoc.conf index 356b23a40339..2b62ba1e72b7 100644 --- a/tools/perf/Documentation/asciidoc.conf +++ b/tools/perf/Documentation/asciidoc.conf @@ -71,6 +71,9 @@ ifdef::backend-docbook[] [header] template::[header-declarations] +ifdef::perf_date[] +{perf_date} +endif::perf_date[] {mantitle} {manvolnum} -- cgit v1.2.3-59-g8ed1b From 08a96a31474a732fd654575ced843b94bc3212e1 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 27 Sep 2019 09:28:11 -0300 Subject: tools headers uapi: Sync drm/i915_drm.h with the kernel sources To pick the change in: bf73fc0fa9cf ("drm/i915: Show support for accurate sw PMU busyness tracking") That don't result in any changes in tooling, just silences this perf build warning: Warning: Kernel ABI header at 'tools/include/uapi/drm/i915_drm.h' differs from latest version at 'include/uapi/drm/i915_drm.h' diff -u tools/include/uapi/drm/i915_drm.h include/uapi/drm/i915_drm.h Cc: Adrian Hunter Cc: Chris Wilson Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-o651nt7vpz93tu3nmx4f3xql@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/drm/i915_drm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/include/uapi/drm/i915_drm.h b/tools/include/uapi/drm/i915_drm.h index 328d05e77d9f..469dc512cca3 100644 --- a/tools/include/uapi/drm/i915_drm.h +++ b/tools/include/uapi/drm/i915_drm.h @@ -521,6 +521,7 @@ typedef struct drm_i915_irq_wait { #define I915_SCHEDULER_CAP_PRIORITY (1ul << 1) #define I915_SCHEDULER_CAP_PREEMPTION (1ul << 2) #define I915_SCHEDULER_CAP_SEMAPHORES (1ul << 3) +#define I915_SCHEDULER_CAP_ENGINE_BUSY_STATS (1ul << 4) #define I915_PARAM_HUC_STATUS 42 -- cgit v1.2.3-59-g8ed1b From 2e4a75976dfb88ee6ce019b1d4fa507aabd02c14 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Fri, 27 Sep 2019 17:54:13 +0200 Subject: KVM: selftests: x86: clarify what is reported on KVM_GET_MSRS failure When KVM_GET_MSRS fail the report looks like ==== Test Assertion Failure ==== lib/x86_64/processor.c:1089: r == nmsrs pid=28775 tid=28775 - Argument list too long 1 0x000000000040a55f: vcpu_save_state at processor.c:1088 (discriminator 3) 2 0x00000000004010e3: main at state_test.c:171 (discriminator 4) 3 0x00007fb8e69223d4: ?? ??:0 4 0x0000000000401287: _start at ??:? Unexpected result from KVM_GET_MSRS, r: 36 (failed at 194) and it's not obvious that '194' here is the failed MSR index and that it's printed in hex. Change that. Suggested-by: Sean Christopherson Signed-off-by: Vitaly Kuznetsov Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/lib/x86_64/processor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c index c53dbc6bc568..6698cb741e10 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c @@ -1085,7 +1085,7 @@ struct kvm_x86_state *vcpu_save_state(struct kvm_vm *vm, uint32_t vcpuid) for (i = 0; i < nmsrs; i++) state->msrs.entries[i].index = list->indices[i]; r = ioctl(vcpu->fd, KVM_GET_MSRS, &state->msrs); - TEST_ASSERT(r == nmsrs, "Unexpected result from KVM_GET_MSRS, r: %i (failed at %x)", + TEST_ASSERT(r == nmsrs, "Unexpected result from KVM_GET_MSRS, r: %i (failed MSR was 0x%x)", r, r == nmsrs ? -1 : list->indices[r]); r = ioctl(vcpu->fd, KVM_GET_DEBUGREGS, &state->debugregs); -- cgit v1.2.3-59-g8ed1b From 979b9b251ae06e3408153bd7b9342a290d65e826 Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Thu, 26 Sep 2019 14:43:38 +0300 Subject: mlxsw: spectrum: Clear VLAN filters during port initialization When a port is created, its VLAN filters are not cleared by the firmware. This causes tagged packets to be later dropped by the ingress STP filters, which default to DISCARD state. The above did not matter much until commit b5ce611fd96e ("mlxsw: spectrum: Add devlink-trap support") where we exposed the drop reason to users. Without this patch, the drop reason users will see is not consistent. If a port is enslaved to a VLAN-aware bridge and a packet with an invalid VLAN tries to ingress the bridge, it will be dropped due to ingress STP filter. If the VLAN is later enabled and then disabled, the packet will be dropped by the ingress VLAN filter despite the above being a seemingly NOP operation. Fix this by clearing all the VLAN filters during port initialization. Adjust the test accordingly. Fixes: b5ce611fd96e ("mlxsw: spectrum: Add devlink-trap support") Reported-by: Alex Kushnarov Tested-by: Alex Kushnarov Acked-by: Jiri Pirko Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 9 +++++++++ .../testing/selftests/drivers/net/mlxsw/devlink_trap_l2_drops.sh | 7 ------- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index dd234cf7b39d..dcf9562bce8a 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -3771,6 +3771,14 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port, goto err_port_qdiscs_init; } + err = mlxsw_sp_port_vlan_set(mlxsw_sp_port, 0, VLAN_N_VID - 1, false, + false); + if (err) { + dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to clear VLAN filter\n", + mlxsw_sp_port->local_port); + goto err_port_vlan_clear; + } + err = mlxsw_sp_port_nve_init(mlxsw_sp_port); if (err) { dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize NVE\n", @@ -3818,6 +3826,7 @@ err_port_vlan_create: err_port_pvid_set: mlxsw_sp_port_nve_fini(mlxsw_sp_port); err_port_nve_init: +err_port_vlan_clear: mlxsw_sp_tc_qdisc_fini(mlxsw_sp_port); err_port_qdiscs_init: mlxsw_sp_port_fids_fini(mlxsw_sp_port); diff --git a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l2_drops.sh b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l2_drops.sh index 5dcdfa20fc6c..126caf28b529 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l2_drops.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l2_drops.sh @@ -224,13 +224,6 @@ ingress_vlan_filter_test() local vid=10 bridge vlan add vid $vid dev $swp2 master - # During initialization the firmware enables all the VLAN filters and - # the driver does not turn them off since the traffic will be discarded - # by the STP filter whose default is DISCARD state. Add the VID on the - # ingress bridge port and then remove it to make sure it is not member - # in the VLAN. - bridge vlan add vid $vid dev $swp1 master - bridge vlan del vid $vid dev $swp1 master RET=0 -- cgit v1.2.3-59-g8ed1b From 8ed4889eb83179dbc9a105cfed65cc42ecb61097 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Fri, 27 Sep 2019 11:10:22 -0400 Subject: selftests/ftrace: Fix same probe error test The "same probe" selftest that tests that adding the same probe fails doesn't add the same probe and passes, which fails the test. Fixes: b78b94b82122 ("selftests/ftrace: Update kprobe event error testcase") Signed-off-by: Steven Rostedt (VMware) --- tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc index 8a4025e912cb..ef1e9bafb098 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc @@ -95,7 +95,7 @@ echo 'p:kprobes/testevent _do_fork abcd=\1' > kprobe_events check_error 'p:kprobes/testevent _do_fork ^bcd=\1' # DIFF_ARG_TYPE check_error 'p:kprobes/testevent _do_fork ^abcd=\1:u8' # DIFF_ARG_TYPE check_error 'p:kprobes/testevent _do_fork ^abcd=\"foo"' # DIFF_ARG_TYPE -check_error '^p:kprobes/testevent _do_fork' # SAME_PROBE +check_error '^p:kprobes/testevent _do_fork abcd=\1' # SAME_PROBE fi exit 0 -- cgit v1.2.3-59-g8ed1b From 55d554f5d14071f7c2c5dbd88d0a2eb695c97d16 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Thu, 26 Sep 2019 19:13:44 -0600 Subject: tools: bpf: Use !building_out_of_srctree to determine srctree make TARGETS=bpf kselftest fails with: Makefile:127: tools/build/Makefile.include: No such file or directory When the bpf tool make is invoked from tools Makefile, srctree is cleared and the current logic check for srctree equals to empty string to determine srctree location from CURDIR. When the build in invoked from selftests/bpf Makefile, the srctree is set to "." and the same logic used for srctree equals to empty is needed to determine srctree. Check building_out_of_srctree undefined as the condition for both cases to fix "make TARGETS=bpf kselftest" build failure. Signed-off-by: Shuah Khan Signed-off-by: Daniel Borkmann Acked-by: Song Liu Link: https://lore.kernel.org/bpf/20190927011344.4695-1-skhan@linuxfoundation.org --- tools/bpf/Makefile | 6 +++++- tools/lib/bpf/Makefile | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/bpf/Makefile b/tools/bpf/Makefile index fbf5e4a0cb9c..5d1995fd369c 100644 --- a/tools/bpf/Makefile +++ b/tools/bpf/Makefile @@ -12,7 +12,11 @@ INSTALL ?= install CFLAGS += -Wall -O2 CFLAGS += -D__EXPORTED_HEADERS__ -I$(srctree)/include/uapi -I$(srctree)/include -ifeq ($(srctree),) +# This will work when bpf is built in tools env. where srctree +# isn't set and when invoked from selftests build, where srctree +# is set to ".". building_out_of_srctree is undefined for in srctree +# builds +ifndef building_out_of_srctree srctree := $(patsubst %/,%,$(dir $(CURDIR))) srctree := $(patsubst %/,%,$(dir $(srctree))) endif diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index c6f94cffe06e..20772663d3e1 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile @@ -8,7 +8,11 @@ LIBBPF_MAJOR_VERSION := $(firstword $(subst ., ,$(LIBBPF_VERSION))) MAKEFLAGS += --no-print-directory -ifeq ($(srctree),) +# This will work when bpf is built in tools env. where srctree +# isn't set and when invoked from selftests build, where srctree +# is a ".". building_out_of_srctree is undefined for in srctree +# builds +ifndef building_out_of_srctree srctree := $(patsubst %/,%,$(dir $(CURDIR))) srctree := $(patsubst %/,%,$(dir $(srctree))) srctree := $(patsubst %/,%,$(dir $(srctree))) -- cgit v1.2.3-59-g8ed1b From b1ba55cf1cfb9f3e0e00d743534684a25bf66d28 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 27 Sep 2019 11:30:30 -0300 Subject: tools headers uapi: Sync asm-generic/mman-common.h with the kernel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To pick the changes from: 1a4e58cce84e ("mm: introduce MADV_PAGEOUT") 9c276cc65a58 ("mm: introduce MADV_COLD") That result in these changes in the tools: $ tools/perf/trace/beauty/madvise_behavior.sh > before $ cp include/uapi/asm-generic/mman-common.h tools/include/uapi/asm-generic/mman-common.h $ git diff diff --git a/tools/include/uapi/asm-generic/mman-common.h b/tools/include/uapi/asm-generic/mman-common.h index 63b1f506ea67..c160a5354eb6 100644 --- a/tools/include/uapi/asm-generic/mman-common.h +++ b/tools/include/uapi/asm-generic/mman-common.h @@ -67,6 +67,9 @@ #define MADV_WIPEONFORK 18 /* Zero memory on fork, child only */ #define MADV_KEEPONFORK 19 /* Undo MADV_WIPEONFORK */ +#define MADV_COLD 20 /* deactivate these pages */ +#define MADV_PAGEOUT 21 /* reclaim these pages */ + /* compatibility flags */ #define MAP_FILE 0 $ tools/perf/trace/beauty/madvise_behavior.sh > after $ diff -u before after --- before 2019-09-27 11:29:43.346320100 -0300 +++ after 2019-09-27 11:30:03.838570439 -0300 @@ -16,6 +16,8 @@ [17] = "DODUMP", [18] = "WIPEONFORK", [19] = "KEEPONFORK", + [20] = "COLD", + [21] = "PAGEOUT", [100] = "HWPOISON", [101] = "SOFT_OFFLINE", }; $ I.e. now when madvise gets those behaviours as args, it will be able to translate from the number to a human readable string. This addresses the following perf build warning: Warning: Kernel ABI header at 'tools/include/uapi/asm-generic/mman-common.h' differs from latest version at 'include/uapi/asm-generic/mman-common.h' diff -u tools/include/uapi/asm-generic/mman-common.h include/uapi/asm-generic/mman-common.h Cc: Adrian Hunter Cc: Brendan Gregg Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Minchan Kim Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-n40y6c4sa49p29q6sl8w3ufx@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/asm-generic/mman-common.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/include/uapi/asm-generic/mman-common.h b/tools/include/uapi/asm-generic/mman-common.h index 63b1f506ea67..c160a5354eb6 100644 --- a/tools/include/uapi/asm-generic/mman-common.h +++ b/tools/include/uapi/asm-generic/mman-common.h @@ -67,6 +67,9 @@ #define MADV_WIPEONFORK 18 /* Zero memory on fork, child only */ #define MADV_KEEPONFORK 19 /* Undo MADV_WIPEONFORK */ +#define MADV_COLD 20 /* deactivate these pages */ +#define MADV_PAGEOUT 21 /* reclaim these pages */ + /* compatibility flags */ #define MAP_FILE 0 -- cgit v1.2.3-59-g8ed1b From 05f371f8c55d69e4c04db4473085303291e4e734 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 27 Sep 2019 11:42:26 -0300 Subject: tools headers uapi: Sync linux/usbdevice_fs.h with the kernel sources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To pick up the changes from: 4ed3350539aa ("USB: usbfs: Add a capability flag for runtime suspend") 7794f486ed0b ("usbfs: Add ioctls for runtime power management") This triggers these changes in the kernel sources, automagically supporting these new ioctls in the 'perf trace' beautifiers. Soon this will be used in things like filter expressions for tracepoints in 'perf record', 'perf trace', 'perf top', i.e. filter expressions will do a lookup to turn things like USBDEVFS_WAIT_FOR_RESUME into _IO('U', 35) before associating the tracepoint expression to tracepoint perf event. $ tools/perf/trace/beauty/usbdevfs_ioctl.sh > before $ cp include/uapi/linux/usbdevice_fs.h tools/include/uapi/linux/usbdevice_fs.h $ git diff diff --git a/tools/include/uapi/linux/usbdevice_fs.h b/tools/include/uapi/linux/usbdevice_fs.h index 78efe870c2b7..cf525cddeb94 100644 --- a/tools/include/uapi/linux/usbdevice_fs.h +++ b/tools/include/uapi/linux/usbdevice_fs.h @@ -158,6 +158,7 @@ struct usbdevfs_hub_portinfo { #define USBDEVFS_CAP_MMAP 0x20 #define USBDEVFS_CAP_DROP_PRIVILEGES 0x40 #define USBDEVFS_CAP_CONNINFO_EX 0x80 +#define USBDEVFS_CAP_SUSPEND 0x100 /* USBDEVFS_DISCONNECT_CLAIM flags & struct */ @@ -223,5 +224,8 @@ struct usbdevfs_streams { * extending size of the data returned. */ #define USBDEVFS_CONNINFO_EX(len) _IOC(_IOC_READ, 'U', 32, len) +#define USBDEVFS_FORBID_SUSPEND _IO('U', 33) +#define USBDEVFS_ALLOW_SUSPEND _IO('U', 34) +#define USBDEVFS_WAIT_FOR_RESUME _IO('U', 35) #endif /* _UAPI_LINUX_USBDEVICE_FS_H */ $ tools/perf/trace/beauty/usbdevfs_ioctl.sh > after $ diff -u before after --- before 2019-09-27 11:41:50.634867620 -0300 +++ after 2019-09-27 11:42:07.453102978 -0300 @@ -24,6 +24,9 @@ [30] = "DROP_PRIVILEGES", [31] = "GET_SPEED", [32] = "CONNINFO_EX", + [33] = "FORBID_SUSPEND", + [34] = "ALLOW_SUSPEND", + [35] = "WAIT_FOR_RESUME", [3] = "RESETEP", [4] = "SETINTERFACE", [5] = "SETCONFIGURATION", $ This addresses the following perf build warning: Warning: Kernel ABI header at 'tools/include/uapi/linux/usbdevice_fs.h' differs from latest version at 'include/uapi/linux/usbdevice_fs.h' diff -u tools/include/uapi/linux/usbdevice_fs.h include/uapi/linux/usbdevice_fs.h Cc: Alan Stern Cc: Adrian Hunter Cc: Brendan Gregg Cc: Greg Kroah-Hartman Cc: Jiri Olsa Cc: Luis Cláudio Gonçalves Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-x1rb109b9nfi7pukota82xhj@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/linux/usbdevice_fs.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/include/uapi/linux/usbdevice_fs.h b/tools/include/uapi/linux/usbdevice_fs.h index 78efe870c2b7..cf525cddeb94 100644 --- a/tools/include/uapi/linux/usbdevice_fs.h +++ b/tools/include/uapi/linux/usbdevice_fs.h @@ -158,6 +158,7 @@ struct usbdevfs_hub_portinfo { #define USBDEVFS_CAP_MMAP 0x20 #define USBDEVFS_CAP_DROP_PRIVILEGES 0x40 #define USBDEVFS_CAP_CONNINFO_EX 0x80 +#define USBDEVFS_CAP_SUSPEND 0x100 /* USBDEVFS_DISCONNECT_CLAIM flags & struct */ @@ -223,5 +224,8 @@ struct usbdevfs_streams { * extending size of the data returned. */ #define USBDEVFS_CONNINFO_EX(len) _IOC(_IOC_READ, 'U', 32, len) +#define USBDEVFS_FORBID_SUSPEND _IO('U', 33) +#define USBDEVFS_ALLOW_SUSPEND _IO('U', 34) +#define USBDEVFS_WAIT_FOR_RESUME _IO('U', 35) #endif /* _UAPI_LINUX_USBDEVICE_FS_H */ -- cgit v1.2.3-59-g8ed1b From 0ae4061223a3d097222cbec6599370e54db17731 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 27 Sep 2019 12:01:26 -0300 Subject: tools headers uapi: Sync linux/fs.h with the kernel sources To pick the changes from: 78a1b96bcf7a ("fscrypt: add FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS ioctl") 23c688b54016 ("fscrypt: allow unprivileged users to add/remove keys for v2 policies") 5dae460c2292 ("fscrypt: v2 encryption policy support") 5a7e29924dac ("fscrypt: add FS_IOC_GET_ENCRYPTION_KEY_STATUS ioctl") b1c0ec3599f4 ("fscrypt: add FS_IOC_REMOVE_ENCRYPTION_KEY ioctl") 22d94f493bfb ("fscrypt: add FS_IOC_ADD_ENCRYPTION_KEY ioctl") 3b6df59bc4d2 ("fscrypt: use FSCRYPT_* definitions, not FS_*") 2336d0deb2d4 ("fscrypt: use FSCRYPT_ prefix for uapi constants") 7af0ab0d3aab ("fs, fscrypt: move uapi definitions to new header ") That don't trigger any changes in tooling, as it so far is used only for: $ grep -l 'fs\.h' tools/perf/trace/beauty/*.sh | xargs grep regex= tools/perf/trace/beauty/rename_flags.sh:regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+RENAME_([[:alnum:]_]+)[[:space:]]+\(1[[:space:]]*<<[[:space:]]*([[:xdigit:]]+)[[:space:]]*\)[[:space:]]*.*' tools/perf/trace/beauty/sync_file_range.sh:regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+SYNC_FILE_RANGE_([[:alnum:]_]+)[[:space:]]+([[:xdigit:]]+)[[:space:]]*.*' tools/perf/trace/beauty/usbdevfs_ioctl.sh:regex="^#[[:space:]]*define[[:space:]]+USBDEVFS_(\w+)(\(\w+\))?[[:space:]]+_IO[CWR]{0,2}\([[:space:]]*(_IOC_\w+,[[:space:]]*)?'U'[[:space:]]*,[[:space:]]*([[:digit:]]+).*" tools/perf/trace/beauty/usbdevfs_ioctl.sh:regex="^#[[:space:]]*define[[:space:]]+USBDEVFS_(\w+)[[:space:]]+_IO[WR]{0,2}\([[:space:]]*'U'[[:space:]]*,[[:space:]]*([[:digit:]]+).*" $ This silences this perf build warning: Warning: Kernel ABI header at 'tools/include/uapi/linux/fs.h' differs from latest version at 'include/uapi/linux/fs.h' diff -u tools/include/uapi/linux/fs.h include/uapi/linux/fs.h Cc: Adrian Hunter Cc: Eric Biggers Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-44g48exl9br9ba0t64chqb4i@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/linux/fs.h | 55 +---------- tools/include/uapi/linux/fscrypt.h | 181 +++++++++++++++++++++++++++++++++++++ tools/perf/check-headers.sh | 1 + 3 files changed, 186 insertions(+), 51 deletions(-) create mode 100644 tools/include/uapi/linux/fscrypt.h (limited to 'tools') diff --git a/tools/include/uapi/linux/fs.h b/tools/include/uapi/linux/fs.h index 2a616aa3f686..379a612f8f1d 100644 --- a/tools/include/uapi/linux/fs.h +++ b/tools/include/uapi/linux/fs.h @@ -13,6 +13,9 @@ #include #include #include +#ifndef __KERNEL__ +#include +#endif /* Use of MS_* flags within the kernel is restricted to core mount(2) code. */ #if !defined(__KERNEL__) @@ -212,57 +215,6 @@ struct fsxattr { #define FS_IOC_GETFSLABEL _IOR(0x94, 49, char[FSLABEL_MAX]) #define FS_IOC_SETFSLABEL _IOW(0x94, 50, char[FSLABEL_MAX]) -/* - * File system encryption support - */ -/* Policy provided via an ioctl on the topmost directory */ -#define FS_KEY_DESCRIPTOR_SIZE 8 - -#define FS_POLICY_FLAGS_PAD_4 0x00 -#define FS_POLICY_FLAGS_PAD_8 0x01 -#define FS_POLICY_FLAGS_PAD_16 0x02 -#define FS_POLICY_FLAGS_PAD_32 0x03 -#define FS_POLICY_FLAGS_PAD_MASK 0x03 -#define FS_POLICY_FLAG_DIRECT_KEY 0x04 /* use master key directly */ -#define FS_POLICY_FLAGS_VALID 0x07 - -/* Encryption algorithms */ -#define FS_ENCRYPTION_MODE_INVALID 0 -#define FS_ENCRYPTION_MODE_AES_256_XTS 1 -#define FS_ENCRYPTION_MODE_AES_256_GCM 2 -#define FS_ENCRYPTION_MODE_AES_256_CBC 3 -#define FS_ENCRYPTION_MODE_AES_256_CTS 4 -#define FS_ENCRYPTION_MODE_AES_128_CBC 5 -#define FS_ENCRYPTION_MODE_AES_128_CTS 6 -#define FS_ENCRYPTION_MODE_SPECK128_256_XTS 7 /* Removed, do not use. */ -#define FS_ENCRYPTION_MODE_SPECK128_256_CTS 8 /* Removed, do not use. */ -#define FS_ENCRYPTION_MODE_ADIANTUM 9 - -struct fscrypt_policy { - __u8 version; - __u8 contents_encryption_mode; - __u8 filenames_encryption_mode; - __u8 flags; - __u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE]; -}; - -#define FS_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct fscrypt_policy) -#define FS_IOC_GET_ENCRYPTION_PWSALT _IOW('f', 20, __u8[16]) -#define FS_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct fscrypt_policy) - -/* Parameters for passing an encryption key into the kernel keyring */ -#define FS_KEY_DESC_PREFIX "fscrypt:" -#define FS_KEY_DESC_PREFIX_SIZE 8 - -/* Structure that userspace passes to the kernel keyring */ -#define FS_MAX_KEY_SIZE 64 - -struct fscrypt_key { - __u32 mode; - __u8 raw[FS_MAX_KEY_SIZE]; - __u32 size; -}; - /* * Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS) * @@ -306,6 +258,7 @@ struct fscrypt_key { #define FS_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ #define FS_HUGE_FILE_FL 0x00040000 /* Reserved for ext4 */ #define FS_EXTENT_FL 0x00080000 /* Extents */ +#define FS_VERITY_FL 0x00100000 /* Verity protected inode */ #define FS_EA_INODE_FL 0x00200000 /* Inode used for large EA */ #define FS_EOFBLOCKS_FL 0x00400000 /* Reserved for ext4 */ #define FS_NOCOW_FL 0x00800000 /* Do not cow file */ diff --git a/tools/include/uapi/linux/fscrypt.h b/tools/include/uapi/linux/fscrypt.h new file mode 100644 index 000000000000..39ccfe9311c3 --- /dev/null +++ b/tools/include/uapi/linux/fscrypt.h @@ -0,0 +1,181 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * fscrypt user API + * + * These ioctls can be used on filesystems that support fscrypt. See the + * "User API" section of Documentation/filesystems/fscrypt.rst. + */ +#ifndef _UAPI_LINUX_FSCRYPT_H +#define _UAPI_LINUX_FSCRYPT_H + +#include + +/* Encryption policy flags */ +#define FSCRYPT_POLICY_FLAGS_PAD_4 0x00 +#define FSCRYPT_POLICY_FLAGS_PAD_8 0x01 +#define FSCRYPT_POLICY_FLAGS_PAD_16 0x02 +#define FSCRYPT_POLICY_FLAGS_PAD_32 0x03 +#define FSCRYPT_POLICY_FLAGS_PAD_MASK 0x03 +#define FSCRYPT_POLICY_FLAG_DIRECT_KEY 0x04 +#define FSCRYPT_POLICY_FLAGS_VALID 0x07 + +/* Encryption algorithms */ +#define FSCRYPT_MODE_AES_256_XTS 1 +#define FSCRYPT_MODE_AES_256_CTS 4 +#define FSCRYPT_MODE_AES_128_CBC 5 +#define FSCRYPT_MODE_AES_128_CTS 6 +#define FSCRYPT_MODE_ADIANTUM 9 +#define __FSCRYPT_MODE_MAX 9 + +/* + * Legacy policy version; ad-hoc KDF and no key verification. + * For new encrypted directories, use fscrypt_policy_v2 instead. + * + * Careful: the .version field for this is actually 0, not 1. + */ +#define FSCRYPT_POLICY_V1 0 +#define FSCRYPT_KEY_DESCRIPTOR_SIZE 8 +struct fscrypt_policy_v1 { + __u8 version; + __u8 contents_encryption_mode; + __u8 filenames_encryption_mode; + __u8 flags; + __u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]; +}; +#define fscrypt_policy fscrypt_policy_v1 + +/* + * Process-subscribed "logon" key description prefix and payload format. + * Deprecated; prefer FS_IOC_ADD_ENCRYPTION_KEY instead. + */ +#define FSCRYPT_KEY_DESC_PREFIX "fscrypt:" +#define FSCRYPT_KEY_DESC_PREFIX_SIZE 8 +#define FSCRYPT_MAX_KEY_SIZE 64 +struct fscrypt_key { + __u32 mode; + __u8 raw[FSCRYPT_MAX_KEY_SIZE]; + __u32 size; +}; + +/* + * New policy version with HKDF and key verification (recommended). + */ +#define FSCRYPT_POLICY_V2 2 +#define FSCRYPT_KEY_IDENTIFIER_SIZE 16 +struct fscrypt_policy_v2 { + __u8 version; + __u8 contents_encryption_mode; + __u8 filenames_encryption_mode; + __u8 flags; + __u8 __reserved[4]; + __u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]; +}; + +/* Struct passed to FS_IOC_GET_ENCRYPTION_POLICY_EX */ +struct fscrypt_get_policy_ex_arg { + __u64 policy_size; /* input/output */ + union { + __u8 version; + struct fscrypt_policy_v1 v1; + struct fscrypt_policy_v2 v2; + } policy; /* output */ +}; + +/* + * v1 policy keys are specified by an arbitrary 8-byte key "descriptor", + * matching fscrypt_policy_v1::master_key_descriptor. + */ +#define FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR 1 + +/* + * v2 policy keys are specified by a 16-byte key "identifier" which the kernel + * calculates as a cryptographic hash of the key itself, + * matching fscrypt_policy_v2::master_key_identifier. + */ +#define FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER 2 + +/* + * Specifies a key, either for v1 or v2 policies. This doesn't contain the + * actual key itself; this is just the "name" of the key. + */ +struct fscrypt_key_specifier { + __u32 type; /* one of FSCRYPT_KEY_SPEC_TYPE_* */ + __u32 __reserved; + union { + __u8 __reserved[32]; /* reserve some extra space */ + __u8 descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]; + __u8 identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]; + } u; +}; + +/* Struct passed to FS_IOC_ADD_ENCRYPTION_KEY */ +struct fscrypt_add_key_arg { + struct fscrypt_key_specifier key_spec; + __u32 raw_size; + __u32 __reserved[9]; + __u8 raw[]; +}; + +/* Struct passed to FS_IOC_REMOVE_ENCRYPTION_KEY */ +struct fscrypt_remove_key_arg { + struct fscrypt_key_specifier key_spec; +#define FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY 0x00000001 +#define FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS 0x00000002 + __u32 removal_status_flags; /* output */ + __u32 __reserved[5]; +}; + +/* Struct passed to FS_IOC_GET_ENCRYPTION_KEY_STATUS */ +struct fscrypt_get_key_status_arg { + /* input */ + struct fscrypt_key_specifier key_spec; + __u32 __reserved[6]; + + /* output */ +#define FSCRYPT_KEY_STATUS_ABSENT 1 +#define FSCRYPT_KEY_STATUS_PRESENT 2 +#define FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED 3 + __u32 status; +#define FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF 0x00000001 + __u32 status_flags; + __u32 user_count; + __u32 __out_reserved[13]; +}; + +#define FS_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct fscrypt_policy) +#define FS_IOC_GET_ENCRYPTION_PWSALT _IOW('f', 20, __u8[16]) +#define FS_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct fscrypt_policy) +#define FS_IOC_GET_ENCRYPTION_POLICY_EX _IOWR('f', 22, __u8[9]) /* size + version */ +#define FS_IOC_ADD_ENCRYPTION_KEY _IOWR('f', 23, struct fscrypt_add_key_arg) +#define FS_IOC_REMOVE_ENCRYPTION_KEY _IOWR('f', 24, struct fscrypt_remove_key_arg) +#define FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS _IOWR('f', 25, struct fscrypt_remove_key_arg) +#define FS_IOC_GET_ENCRYPTION_KEY_STATUS _IOWR('f', 26, struct fscrypt_get_key_status_arg) + +/**********************************************************************/ + +/* old names; don't add anything new here! */ +#ifndef __KERNEL__ +#define FS_KEY_DESCRIPTOR_SIZE FSCRYPT_KEY_DESCRIPTOR_SIZE +#define FS_POLICY_FLAGS_PAD_4 FSCRYPT_POLICY_FLAGS_PAD_4 +#define FS_POLICY_FLAGS_PAD_8 FSCRYPT_POLICY_FLAGS_PAD_8 +#define FS_POLICY_FLAGS_PAD_16 FSCRYPT_POLICY_FLAGS_PAD_16 +#define FS_POLICY_FLAGS_PAD_32 FSCRYPT_POLICY_FLAGS_PAD_32 +#define FS_POLICY_FLAGS_PAD_MASK FSCRYPT_POLICY_FLAGS_PAD_MASK +#define FS_POLICY_FLAG_DIRECT_KEY FSCRYPT_POLICY_FLAG_DIRECT_KEY +#define FS_POLICY_FLAGS_VALID FSCRYPT_POLICY_FLAGS_VALID +#define FS_ENCRYPTION_MODE_INVALID 0 /* never used */ +#define FS_ENCRYPTION_MODE_AES_256_XTS FSCRYPT_MODE_AES_256_XTS +#define FS_ENCRYPTION_MODE_AES_256_GCM 2 /* never used */ +#define FS_ENCRYPTION_MODE_AES_256_CBC 3 /* never used */ +#define FS_ENCRYPTION_MODE_AES_256_CTS FSCRYPT_MODE_AES_256_CTS +#define FS_ENCRYPTION_MODE_AES_128_CBC FSCRYPT_MODE_AES_128_CBC +#define FS_ENCRYPTION_MODE_AES_128_CTS FSCRYPT_MODE_AES_128_CTS +#define FS_ENCRYPTION_MODE_SPECK128_256_XTS 7 /* removed */ +#define FS_ENCRYPTION_MODE_SPECK128_256_CTS 8 /* removed */ +#define FS_ENCRYPTION_MODE_ADIANTUM FSCRYPT_MODE_ADIANTUM +#define FS_KEY_DESC_PREFIX FSCRYPT_KEY_DESC_PREFIX +#define FS_KEY_DESC_PREFIX_SIZE FSCRYPT_KEY_DESC_PREFIX_SIZE +#define FS_MAX_KEY_SIZE FSCRYPT_MAX_KEY_SIZE +#endif /* !__KERNEL__ */ + +#endif /* _UAPI_LINUX_FSCRYPT_H */ diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh index e2e0f06c97d0..cea13cb987d0 100755 --- a/tools/perf/check-headers.sh +++ b/tools/perf/check-headers.sh @@ -8,6 +8,7 @@ include/uapi/drm/i915_drm.h include/uapi/linux/fadvise.h include/uapi/linux/fcntl.h include/uapi/linux/fs.h +include/uapi/linux/fscrypt.h include/uapi/linux/kcmp.h include/uapi/linux/kvm.h include/uapi/linux/in.h -- cgit v1.2.3-59-g8ed1b From b7ad6108484221f431372b94763b74e550d16c93 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 27 Sep 2019 12:18:21 -0300 Subject: tools headers kvm: Sync kvm headers with the kernel sources To pick the changes in: 200824f55eef ("KVM: s390: Disallow invalid bits in kvm_valid_regs and kvm_dirty_regs") 4a53d99dd0c2 ("KVM: VMX: Introduce exit reason for receiving INIT signal on guest-mode") 7396d337cfad ("KVM: x86: Return to userspace with internal error on unexpected exit reason") 92f35b751c71 ("KVM: arm/arm64: vgic: Allow more than 256 vcpus for KVM_IRQ_LINE") None of them trigger any changes in tooling, this time this is just to silence these perf build warnings: Warning: Kernel ABI header at 'tools/include/uapi/linux/kvm.h' differs from latest version at 'include/uapi/linux/kvm.h' diff -u tools/include/uapi/linux/kvm.h include/uapi/linux/kvm.h Warning: Kernel ABI header at 'tools/arch/x86/include/uapi/asm/vmx.h' differs from latest version at 'arch/x86/include/uapi/asm/vmx.h' diff -u tools/arch/x86/include/uapi/asm/vmx.h arch/x86/include/uapi/asm/vmx.h Warning: Kernel ABI header at 'tools/arch/s390/include/uapi/asm/kvm.h' differs from latest version at 'arch/s390/include/uapi/asm/kvm.h' diff -u tools/arch/s390/include/uapi/asm/kvm.h arch/s390/include/uapi/asm/kvm.h Warning: Kernel ABI header at 'tools/arch/arm/include/uapi/asm/kvm.h' differs from latest version at 'arch/arm/include/uapi/asm/kvm.h' diff -u tools/arch/arm/include/uapi/asm/kvm.h arch/arm/include/uapi/asm/kvm.h Warning: Kernel ABI header at 'tools/arch/arm64/include/uapi/asm/kvm.h' differs from latest version at 'arch/arm64/include/uapi/asm/kvm.h' diff -u tools/arch/arm64/include/uapi/asm/kvm.h arch/arm64/include/uapi/asm/kvm.h Cc: Adrian Hunter Cc: Janosch Frank Cc: Jiri Olsa Cc: Liran Alon Cc: Marc Zyngier Cc: Namhyung Kim Cc: Paolo Bonzini Cc: Thomas Huth Link: https://lkml.kernel.org/n/tip-akuugvvjxte26kzv23zp5d2z@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/arm/include/uapi/asm/kvm.h | 4 +++- tools/arch/arm64/include/uapi/asm/kvm.h | 4 +++- tools/arch/s390/include/uapi/asm/kvm.h | 6 ++++++ tools/arch/x86/include/uapi/asm/vmx.h | 2 ++ tools/include/uapi/linux/kvm.h | 3 +++ 5 files changed, 17 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/arch/arm/include/uapi/asm/kvm.h b/tools/arch/arm/include/uapi/asm/kvm.h index a4217c1a5d01..2769360f195c 100644 --- a/tools/arch/arm/include/uapi/asm/kvm.h +++ b/tools/arch/arm/include/uapi/asm/kvm.h @@ -266,8 +266,10 @@ struct kvm_vcpu_events { #define KVM_DEV_ARM_ITS_CTRL_RESET 4 /* KVM_IRQ_LINE irq field index values */ +#define KVM_ARM_IRQ_VCPU2_SHIFT 28 +#define KVM_ARM_IRQ_VCPU2_MASK 0xf #define KVM_ARM_IRQ_TYPE_SHIFT 24 -#define KVM_ARM_IRQ_TYPE_MASK 0xff +#define KVM_ARM_IRQ_TYPE_MASK 0xf #define KVM_ARM_IRQ_VCPU_SHIFT 16 #define KVM_ARM_IRQ_VCPU_MASK 0xff #define KVM_ARM_IRQ_NUM_SHIFT 0 diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h index 9a507716ae2f..67c21f9bdbad 100644 --- a/tools/arch/arm64/include/uapi/asm/kvm.h +++ b/tools/arch/arm64/include/uapi/asm/kvm.h @@ -325,8 +325,10 @@ struct kvm_vcpu_events { #define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1 /* KVM_IRQ_LINE irq field index values */ +#define KVM_ARM_IRQ_VCPU2_SHIFT 28 +#define KVM_ARM_IRQ_VCPU2_MASK 0xf #define KVM_ARM_IRQ_TYPE_SHIFT 24 -#define KVM_ARM_IRQ_TYPE_MASK 0xff +#define KVM_ARM_IRQ_TYPE_MASK 0xf #define KVM_ARM_IRQ_VCPU_SHIFT 16 #define KVM_ARM_IRQ_VCPU_MASK 0xff #define KVM_ARM_IRQ_NUM_SHIFT 0 diff --git a/tools/arch/s390/include/uapi/asm/kvm.h b/tools/arch/s390/include/uapi/asm/kvm.h index 47104e5b47fd..436ec7636927 100644 --- a/tools/arch/s390/include/uapi/asm/kvm.h +++ b/tools/arch/s390/include/uapi/asm/kvm.h @@ -231,6 +231,12 @@ struct kvm_guest_debug_arch { #define KVM_SYNC_GSCB (1UL << 9) #define KVM_SYNC_BPBC (1UL << 10) #define KVM_SYNC_ETOKEN (1UL << 11) + +#define KVM_SYNC_S390_VALID_FIELDS \ + (KVM_SYNC_PREFIX | KVM_SYNC_GPRS | KVM_SYNC_ACRS | KVM_SYNC_CRS | \ + KVM_SYNC_ARCH0 | KVM_SYNC_PFAULT | KVM_SYNC_VRS | KVM_SYNC_RICCB | \ + KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN) + /* length and alignment of the sdnx as a power of two */ #define SDNXC 8 #define SDNXL (1UL << SDNXC) diff --git a/tools/arch/x86/include/uapi/asm/vmx.h b/tools/arch/x86/include/uapi/asm/vmx.h index f0b0c90dd398..f01950aa7fae 100644 --- a/tools/arch/x86/include/uapi/asm/vmx.h +++ b/tools/arch/x86/include/uapi/asm/vmx.h @@ -31,6 +31,7 @@ #define EXIT_REASON_EXCEPTION_NMI 0 #define EXIT_REASON_EXTERNAL_INTERRUPT 1 #define EXIT_REASON_TRIPLE_FAULT 2 +#define EXIT_REASON_INIT_SIGNAL 3 #define EXIT_REASON_PENDING_INTERRUPT 7 #define EXIT_REASON_NMI_WINDOW 8 @@ -90,6 +91,7 @@ { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, \ { EXIT_REASON_EXTERNAL_INTERRUPT, "EXTERNAL_INTERRUPT" }, \ { EXIT_REASON_TRIPLE_FAULT, "TRIPLE_FAULT" }, \ + { EXIT_REASON_INIT_SIGNAL, "INIT_SIGNAL" }, \ { EXIT_REASON_PENDING_INTERRUPT, "PENDING_INTERRUPT" }, \ { EXIT_REASON_NMI_WINDOW, "NMI_WINDOW" }, \ { EXIT_REASON_TASK_SWITCH, "TASK_SWITCH" }, \ diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h index 5e3f12d5359e..233efbb1c81c 100644 --- a/tools/include/uapi/linux/kvm.h +++ b/tools/include/uapi/linux/kvm.h @@ -243,6 +243,8 @@ struct kvm_hyperv_exit { #define KVM_INTERNAL_ERROR_SIMUL_EX 2 /* Encounter unexpected vm-exit due to delivery event. */ #define KVM_INTERNAL_ERROR_DELIVERY_EV 3 +/* Encounter unexpected vm-exit reason */ +#define KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON 4 /* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */ struct kvm_run { @@ -996,6 +998,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_ARM_PTRAUTH_ADDRESS 171 #define KVM_CAP_ARM_PTRAUTH_GENERIC 172 #define KVM_CAP_PMU_EVENT_FILTER 173 +#define KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 174 #ifdef KVM_CAP_IRQ_ROUTING -- cgit v1.2.3-59-g8ed1b From 7d4c85b7035eb2f9ab217ce649dcd1bfaf0cacd3 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 26 Sep 2019 15:00:18 -0700 Subject: perf llvm: Don't access out-of-scope array The 'test_dir' variable is assigned to the 'release' array which is out-of-scope 3 lines later. Extend the scope of the 'release' array so that an out-of-scope array isn't accessed. Bug detected by clang's address sanitizer. Fixes: 07bc5c699a3d ("perf tools: Make fetch_kernel_version() publicly available") Cc: stable@vger.kernel.org # v4.4+ Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Andi Kleen Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Wang Nan Link: http://lore.kernel.org/lkml/20190926220018.25402-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/llvm-utils.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c index 8d04e3d070b1..8b14e4a7f1dc 100644 --- a/tools/perf/util/llvm-utils.c +++ b/tools/perf/util/llvm-utils.c @@ -233,14 +233,14 @@ static int detect_kbuild_dir(char **kbuild_dir) const char *prefix_dir = ""; const char *suffix_dir = ""; + /* _UTSNAME_LENGTH is 65 */ + char release[128]; + char *autoconf_path; int err; if (!test_dir) { - /* _UTSNAME_LENGTH is 65 */ - char release[128]; - err = fetch_kernel_version(NULL, release, sizeof(release)); if (err) -- cgit v1.2.3-59-g8ed1b From 02d084792273e8a5f1813dcad988229a45be96ea Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Fri, 27 Sep 2019 10:11:46 +0200 Subject: perf vendor events s390: Add JSON transaction for machine type 8561 Add s390 transaction counter definition for machine 8561. This is the same file as for the predecessor machine. Fixes: 6e67d77d673d ("perf vendor events s390: Add JSON files for machine type 8561") Signed-off-by: Thomas Richter Cc: Heiko Carstens Cc: Vasily Gorbik Link: http://lore.kernel.org/lkml/20190927081147.18345-1-tmricht@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/pmu-events/arch/s390/cf_m8561/transaction.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tools/perf/pmu-events/arch/s390/cf_m8561/transaction.json (limited to 'tools') diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/transaction.json b/tools/perf/pmu-events/arch/s390/cf_m8561/transaction.json new file mode 100644 index 000000000000..1a0034f79f73 --- /dev/null +++ b/tools/perf/pmu-events/arch/s390/cf_m8561/transaction.json @@ -0,0 +1,7 @@ +[ + { + "BriefDescription": "Transaction count", + "MetricName": "transaction", + "MetricExpr": "TX_C_TEND + TX_NC_TEND + TX_NC_TABORT + TX_C_TABORT_SPECIAL + TX_C_TABORT_NO_SPECIAL" + } +] -- cgit v1.2.3-59-g8ed1b From 0d0e5ecec6116db6031829299e74cc71240c9ff3 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Fri, 27 Sep 2019 10:11:47 +0200 Subject: perf vendor events s390: Use s390 machine name instead of type 8561 In the pmu-events directory for JSON file definitions use the official machine name IBM z15 instead of machine type number 8561. This is consistent with previous machines. Signed-off-by: Thomas Richter Cc: Heiko Carstens Cc: Vasily Gorbik Link: http://lore.kernel.org/lkml/20190927081147.18345-2-tmricht@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- .../perf/pmu-events/arch/s390/cf_m8561/basic.json | 58 ---- .../perf/pmu-events/arch/s390/cf_m8561/crypto.json | 114 ------- .../pmu-events/arch/s390/cf_m8561/crypto6.json | 30 -- .../pmu-events/arch/s390/cf_m8561/extended.json | 373 --------------------- .../pmu-events/arch/s390/cf_m8561/transaction.json | 7 - tools/perf/pmu-events/arch/s390/cf_z15/basic.json | 58 ++++ tools/perf/pmu-events/arch/s390/cf_z15/crypto.json | 114 +++++++ .../perf/pmu-events/arch/s390/cf_z15/crypto6.json | 30 ++ .../perf/pmu-events/arch/s390/cf_z15/extended.json | 373 +++++++++++++++++++++ .../pmu-events/arch/s390/cf_z15/transaction.json | 7 + tools/perf/pmu-events/arch/s390/mapfile.csv | 2 +- 11 files changed, 583 insertions(+), 583 deletions(-) delete mode 100644 tools/perf/pmu-events/arch/s390/cf_m8561/basic.json delete mode 100644 tools/perf/pmu-events/arch/s390/cf_m8561/crypto.json delete mode 100644 tools/perf/pmu-events/arch/s390/cf_m8561/crypto6.json delete mode 100644 tools/perf/pmu-events/arch/s390/cf_m8561/extended.json delete mode 100644 tools/perf/pmu-events/arch/s390/cf_m8561/transaction.json create mode 100644 tools/perf/pmu-events/arch/s390/cf_z15/basic.json create mode 100644 tools/perf/pmu-events/arch/s390/cf_z15/crypto.json create mode 100644 tools/perf/pmu-events/arch/s390/cf_z15/crypto6.json create mode 100644 tools/perf/pmu-events/arch/s390/cf_z15/extended.json create mode 100644 tools/perf/pmu-events/arch/s390/cf_z15/transaction.json (limited to 'tools') diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/basic.json b/tools/perf/pmu-events/arch/s390/cf_m8561/basic.json deleted file mode 100644 index 17fb5241928b..000000000000 --- a/tools/perf/pmu-events/arch/s390/cf_m8561/basic.json +++ /dev/null @@ -1,58 +0,0 @@ -[ - { - "Unit": "CPU-M-CF", - "EventCode": "0", - "EventName": "CPU_CYCLES", - "BriefDescription": "CPU Cycles", - "PublicDescription": "Cycle Count" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "1", - "EventName": "INSTRUCTIONS", - "BriefDescription": "Instructions", - "PublicDescription": "Instruction Count" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "2", - "EventName": "L1I_DIR_WRITES", - "BriefDescription": "L1I Directory Writes", - "PublicDescription": "Level-1 I-Cache Directory Write Count" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "3", - "EventName": "L1I_PENALTY_CYCLES", - "BriefDescription": "L1I Penalty Cycles", - "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "4", - "EventName": "L1D_DIR_WRITES", - "BriefDescription": "L1D Directory Writes", - "PublicDescription": "Level-1 D-Cache Directory Write Count" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "5", - "EventName": "L1D_PENALTY_CYCLES", - "BriefDescription": "L1D Penalty Cycles", - "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "32", - "EventName": "PROBLEM_STATE_CPU_CYCLES", - "BriefDescription": "Problem-State CPU Cycles", - "PublicDescription": "Problem-State Cycle Count" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "33", - "EventName": "PROBLEM_STATE_INSTRUCTIONS", - "BriefDescription": "Problem-State Instructions", - "PublicDescription": "Problem-State Instruction Count" - }, -] diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/crypto.json b/tools/perf/pmu-events/arch/s390/cf_m8561/crypto.json deleted file mode 100644 index db286f19e7b6..000000000000 --- a/tools/perf/pmu-events/arch/s390/cf_m8561/crypto.json +++ /dev/null @@ -1,114 +0,0 @@ -[ - { - "Unit": "CPU-M-CF", - "EventCode": "64", - "EventName": "PRNG_FUNCTIONS", - "BriefDescription": "PRNG Functions", - "PublicDescription": "Total number of the PRNG functions issued by the CPU" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "65", - "EventName": "PRNG_CYCLES", - "BriefDescription": "PRNG Cycles", - "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "66", - "EventName": "PRNG_BLOCKED_FUNCTIONS", - "BriefDescription": "PRNG Blocked Functions", - "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "67", - "EventName": "PRNG_BLOCKED_CYCLES", - "BriefDescription": "PRNG Blocked Cycles", - "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "68", - "EventName": "SHA_FUNCTIONS", - "BriefDescription": "SHA Functions", - "PublicDescription": "Total number of SHA functions issued by the CPU" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "69", - "EventName": "SHA_CYCLES", - "BriefDescription": "SHA Cycles", - "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "70", - "EventName": "SHA_BLOCKED_FUNCTIONS", - "BriefDescription": "SHA Blocked Functions", - "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "71", - "EventName": "SHA_BLOCKED_CYCLES", - "BriefDescription": "SHA Bloced Cycles", - "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "72", - "EventName": "DEA_FUNCTIONS", - "BriefDescription": "DEA Functions", - "PublicDescription": "Total number of the DEA functions issued by the CPU" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "73", - "EventName": "DEA_CYCLES", - "BriefDescription": "DEA Cycles", - "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "74", - "EventName": "DEA_BLOCKED_FUNCTIONS", - "BriefDescription": "DEA Blocked Functions", - "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "75", - "EventName": "DEA_BLOCKED_CYCLES", - "BriefDescription": "DEA Blocked Cycles", - "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "76", - "EventName": "AES_FUNCTIONS", - "BriefDescription": "AES Functions", - "PublicDescription": "Total number of AES functions issued by the CPU" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "77", - "EventName": "AES_CYCLES", - "BriefDescription": "AES Cycles", - "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "78", - "EventName": "AES_BLOCKED_FUNCTIONS", - "BriefDescription": "AES Blocked Functions", - "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "79", - "EventName": "AES_BLOCKED_CYCLES", - "BriefDescription": "AES Blocked Cycles", - "PublicDescription": "Total number of CPU cycles blocked for the AES functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" - }, -] diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/crypto6.json b/tools/perf/pmu-events/arch/s390/cf_m8561/crypto6.json deleted file mode 100644 index 5e36bc2468d0..000000000000 --- a/tools/perf/pmu-events/arch/s390/cf_m8561/crypto6.json +++ /dev/null @@ -1,30 +0,0 @@ -[ - { - "Unit": "CPU-M-CF", - "EventCode": "80", - "EventName": "ECC_FUNCTION_COUNT", - "BriefDescription": "ECC Function Count", - "PublicDescription": "Long ECC function Count" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "81", - "EventName": "ECC_CYCLES_COUNT", - "BriefDescription": "ECC Cycles Count", - "PublicDescription": "Long ECC Function cycles count" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "82", - "EventName": "ECC_BLOCKED_FUNCTION_COUNT", - "BriefDescription": "Ecc Blocked Function Count", - "PublicDescription": "Long ECC blocked function count" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "83", - "EventName": "ECC_BLOCKED_CYCLES_COUNT", - "BriefDescription": "ECC Blocked Cycles Count", - "PublicDescription": "Long ECC blocked cycles count" - }, -] diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/extended.json b/tools/perf/pmu-events/arch/s390/cf_m8561/extended.json deleted file mode 100644 index 89e070727e1b..000000000000 --- a/tools/perf/pmu-events/arch/s390/cf_m8561/extended.json +++ /dev/null @@ -1,373 +0,0 @@ -[ - { - "Unit": "CPU-M-CF", - "EventCode": "128", - "EventName": "L1D_RO_EXCL_WRITES", - "BriefDescription": "L1D Read-only Exclusive Writes", - "PublicDescription": "A directory write to the Level-1 Data cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "129", - "EventName": "DTLB2_WRITES", - "BriefDescription": "DTLB2 Writes", - "PublicDescription": "A translation has been written into The Translation Lookaside Buffer 2 (TLB2) and the request was made by the data cache" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "130", - "EventName": "DTLB2_MISSES", - "BriefDescription": "DTLB2 Misses", - "PublicDescription": "A TLB2 miss is in progress for a request made by the data cache. Incremented by one for every TLB2 miss in progress for the Level-1 Data cache on this cycle" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "131", - "EventName": "DTLB2_HPAGE_WRITES", - "BriefDescription": "DTLB2 One-Megabyte Page Writes", - "PublicDescription": "A translation entry was written into the Combined Region and Segment Table Entry array in the Level-2 TLB for a one-megabyte page or a Last Host Translation was done" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "132", - "EventName": "DTLB2_GPAGE_WRITES", - "BriefDescription": "DTLB2 Two-Gigabyte Page Writes", - "PublicDescription": "A translation entry for a two-gigabyte page was written into the Level-2 TLB" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "133", - "EventName": "L1D_L2D_SOURCED_WRITES", - "BriefDescription": "L1D L2D Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "134", - "EventName": "ITLB2_WRITES", - "BriefDescription": "ITLB2 Writes", - "PublicDescription": "A translation entry has been written into the Translation Lookaside Buffer 2 (TLB2) and the request was made by the instruction cache" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "135", - "EventName": "ITLB2_MISSES", - "BriefDescription": "ITLB2 Misses", - "PublicDescription": "A TLB2 miss is in progress for a request made by the instruction cache. Incremented by one for every TLB2 miss in progress for the Level-1 Instruction cache in a cycle" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "136", - "EventName": "L1I_L2I_SOURCED_WRITES", - "BriefDescription": "L1I L2I Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "137", - "EventName": "TLB2_PTE_WRITES", - "BriefDescription": "TLB2 PTE Writes", - "PublicDescription": "A translation entry was written into the Page Table Entry array in the Level-2 TLB" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "138", - "EventName": "TLB2_CRSTE_WRITES", - "BriefDescription": "TLB2 CRSTE Writes", - "PublicDescription": "Translation entries were written into the Combined Region and Segment Table Entry array and the Page Table Entry array in the Level-2 TLB" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "139", - "EventName": "TLB2_ENGINES_BUSY", - "BriefDescription": "TLB2 Engines Busy", - "PublicDescription": "The number of Level-2 TLB translation engines busy in a cycle" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "140", - "EventName": "TX_C_TEND", - "BriefDescription": "Completed TEND instructions in constrained TX mode", - "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "141", - "EventName": "TX_NC_TEND", - "BriefDescription": "Completed TEND instructions in non-constrained TX mode", - "PublicDescription": "A TEND instruction has completed in a non-constrained transactional-execution mode" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "143", - "EventName": "L1C_TLB2_MISSES", - "BriefDescription": "L1C TLB2 Misses", - "PublicDescription": "Increments by one for any cycle where a level-1 cache or level-2 TLB miss is in progress" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "144", - "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES", - "BriefDescription": "L1D On-Chip L3 Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "145", - "EventName": "L1D_ONCHIP_MEMORY_SOURCED_WRITES", - "BriefDescription": "L1D On-Chip Memory Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip memory" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "146", - "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV", - "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention", - "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache with intervention" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "147", - "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES", - "BriefDescription": "L1D On-Cluster L3 Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Cluster Level-3 cache withountervention" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "148", - "EventName": "L1D_ONCLUSTER_MEMORY_SOURCED_WRITES", - "BriefDescription": "L1D On-Cluster Memory Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster memory" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "149", - "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES_IV", - "BriefDescription": "L1D On-Cluster L3 Sourced Writes with Intervention", - "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache with intervention" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "150", - "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES", - "BriefDescription": "L1D Off-Cluster L3 Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "151", - "EventName": "L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES", - "BriefDescription": "L1D Off-Cluster Memory Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Cluster memory" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "152", - "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV", - "BriefDescription": "L1D Off-Cluster L3 Sourced Writes with Intervention", - "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "153", - "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES", - "BriefDescription": "L1D Off-Drawer L3 Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "154", - "EventName": "L1D_OFFDRAWER_MEMORY_SOURCED_WRITES", - "BriefDescription": "L1D Off-Drawer Memory Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer memory" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "155", - "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES_IV", - "BriefDescription": "L1D Off-Drawer L3 Sourced Writes with Intervention", - "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "156", - "EventName": "L1D_ONDRAWER_L4_SOURCED_WRITES", - "BriefDescription": "L1D On-Drawer L4 Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer Level-4 cache" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "157", - "EventName": "L1D_OFFDRAWER_L4_SOURCED_WRITES", - "BriefDescription": "L1D Off-Drawer L4 Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "158", - "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_RO", - "BriefDescription": "L1D On-Chip L3 Sourced Writes read-only", - "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip L3 but a read-only invalidate was done to remove other copies of the cache line" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "162", - "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES", - "BriefDescription": "L1I On-Chip L3 Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache without intervention" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "163", - "EventName": "L1I_ONCHIP_MEMORY_SOURCED_WRITES", - "BriefDescription": "L1I On-Chip Memory Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from On-Chip memory" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "164", - "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV", - "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention", - "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache with intervention" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "165", - "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES", - "BriefDescription": "L1I On-Cluster L3 Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache without intervention" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "166", - "EventName": "L1I_ONCLUSTER_MEMORY_SOURCED_WRITES", - "BriefDescription": "L1I On-Cluster Memory Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster memory" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "167", - "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES_IV", - "BriefDescription": "L1I On-Cluster L3 Sourced Writes with Intervention", - "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Cluster Level-3 cache with intervention" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "168", - "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES", - "BriefDescription": "L1I Off-Cluster L3 Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "169", - "EventName": "L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES", - "BriefDescription": "L1I Off-Cluster Memory Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Cluster memory" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "170", - "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV", - "BriefDescription": "L1I Off-Cluster L3 Sourced Writes with Intervention", - "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "171", - "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES", - "BriefDescription": "L1I Off-Drawer L3 Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "172", - "EventName": "L1I_OFFDRAWER_MEMORY_SOURCED_WRITES", - "BriefDescription": "L1I Off-Drawer Memory Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer memory" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "173", - "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES_IV", - "BriefDescription": "L1I Off-Drawer L3 Sourced Writes with Intervention", - "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "174", - "EventName": "L1I_ONDRAWER_L4_SOURCED_WRITES", - "BriefDescription": "L1I On-Drawer L4 Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer Level-4 cache" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "175", - "EventName": "L1I_OFFDRAWER_L4_SOURCED_WRITES", - "BriefDescription": "L1I Off-Drawer L4 Sourced Writes", - "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "224", - "EventName": "BCD_DFP_EXECUTION_SLOTS", - "BriefDescription": "BCD DFP Execution Slots", - "PublicDescription": "Count of floating point execution slots used for finished Binary Coded Decimal to Decimal Floating Point conversions. Instructions: CDZT, CXZT, CZDT, CZXT" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "225", - "EventName": "VX_BCD_EXECUTION_SLOTS", - "BriefDescription": "VX BCD Execution Slots", - "PublicDescription": "Count of floating point execution slots used for finished vector arithmetic Binary Coded Decimal instructions. Instructions: VAP, VSP, VMPVMSP, VDP, VSDP, VRP, VLIP, VSRP, VPSOPVCP, VTP, VPKZ, VUPKZ, VCVB, VCVBG, VCVDVCVDG" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "226", - "EventName": "DECIMAL_INSTRUCTIONS", - "BriefDescription": "Decimal Instructions", - "PublicDescription": "Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED, EDMK, MP, SRP, SP, ZAP" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "232", - "EventName": "LAST_HOST_TRANSLATIONS", - "BriefDescription": "Last host translation done", - "PublicDescription": "Last Host Translation done" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "243", - "EventName": "TX_NC_TABORT", - "BriefDescription": "Aborted transactions in non-constrained TX mode", - "PublicDescription": "A transaction abort has occurred in a non-constrained transactional-execution mode" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "244", - "EventName": "TX_C_TABORT_NO_SPECIAL", - "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic", - "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "245", - "EventName": "TX_C_TABORT_SPECIAL", - "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic", - "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is using special logic to allow the transaction to complete" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "448", - "EventName": "MT_DIAG_CYCLES_ONE_THR_ACTIVE", - "BriefDescription": "Cycle count with one thread active", - "PublicDescription": "Cycle count with one thread active" - }, - { - "Unit": "CPU-M-CF", - "EventCode": "449", - "EventName": "MT_DIAG_CYCLES_TWO_THR_ACTIVE", - "BriefDescription": "Cycle count with two threads active", - "PublicDescription": "Cycle count with two threads active" - }, -] diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/transaction.json b/tools/perf/pmu-events/arch/s390/cf_m8561/transaction.json deleted file mode 100644 index 1a0034f79f73..000000000000 --- a/tools/perf/pmu-events/arch/s390/cf_m8561/transaction.json +++ /dev/null @@ -1,7 +0,0 @@ -[ - { - "BriefDescription": "Transaction count", - "MetricName": "transaction", - "MetricExpr": "TX_C_TEND + TX_NC_TEND + TX_NC_TABORT + TX_C_TABORT_SPECIAL + TX_C_TABORT_NO_SPECIAL" - } -] diff --git a/tools/perf/pmu-events/arch/s390/cf_z15/basic.json b/tools/perf/pmu-events/arch/s390/cf_z15/basic.json new file mode 100644 index 000000000000..17fb5241928b --- /dev/null +++ b/tools/perf/pmu-events/arch/s390/cf_z15/basic.json @@ -0,0 +1,58 @@ +[ + { + "Unit": "CPU-M-CF", + "EventCode": "0", + "EventName": "CPU_CYCLES", + "BriefDescription": "CPU Cycles", + "PublicDescription": "Cycle Count" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "1", + "EventName": "INSTRUCTIONS", + "BriefDescription": "Instructions", + "PublicDescription": "Instruction Count" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "2", + "EventName": "L1I_DIR_WRITES", + "BriefDescription": "L1I Directory Writes", + "PublicDescription": "Level-1 I-Cache Directory Write Count" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "3", + "EventName": "L1I_PENALTY_CYCLES", + "BriefDescription": "L1I Penalty Cycles", + "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "4", + "EventName": "L1D_DIR_WRITES", + "BriefDescription": "L1D Directory Writes", + "PublicDescription": "Level-1 D-Cache Directory Write Count" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "5", + "EventName": "L1D_PENALTY_CYCLES", + "BriefDescription": "L1D Penalty Cycles", + "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "32", + "EventName": "PROBLEM_STATE_CPU_CYCLES", + "BriefDescription": "Problem-State CPU Cycles", + "PublicDescription": "Problem-State Cycle Count" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "33", + "EventName": "PROBLEM_STATE_INSTRUCTIONS", + "BriefDescription": "Problem-State Instructions", + "PublicDescription": "Problem-State Instruction Count" + }, +] diff --git a/tools/perf/pmu-events/arch/s390/cf_z15/crypto.json b/tools/perf/pmu-events/arch/s390/cf_z15/crypto.json new file mode 100644 index 000000000000..db286f19e7b6 --- /dev/null +++ b/tools/perf/pmu-events/arch/s390/cf_z15/crypto.json @@ -0,0 +1,114 @@ +[ + { + "Unit": "CPU-M-CF", + "EventCode": "64", + "EventName": "PRNG_FUNCTIONS", + "BriefDescription": "PRNG Functions", + "PublicDescription": "Total number of the PRNG functions issued by the CPU" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "65", + "EventName": "PRNG_CYCLES", + "BriefDescription": "PRNG Cycles", + "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "66", + "EventName": "PRNG_BLOCKED_FUNCTIONS", + "BriefDescription": "PRNG Blocked Functions", + "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "67", + "EventName": "PRNG_BLOCKED_CYCLES", + "BriefDescription": "PRNG Blocked Cycles", + "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "68", + "EventName": "SHA_FUNCTIONS", + "BriefDescription": "SHA Functions", + "PublicDescription": "Total number of SHA functions issued by the CPU" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "69", + "EventName": "SHA_CYCLES", + "BriefDescription": "SHA Cycles", + "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "70", + "EventName": "SHA_BLOCKED_FUNCTIONS", + "BriefDescription": "SHA Blocked Functions", + "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "71", + "EventName": "SHA_BLOCKED_CYCLES", + "BriefDescription": "SHA Bloced Cycles", + "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "72", + "EventName": "DEA_FUNCTIONS", + "BriefDescription": "DEA Functions", + "PublicDescription": "Total number of the DEA functions issued by the CPU" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "73", + "EventName": "DEA_CYCLES", + "BriefDescription": "DEA Cycles", + "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "74", + "EventName": "DEA_BLOCKED_FUNCTIONS", + "BriefDescription": "DEA Blocked Functions", + "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "75", + "EventName": "DEA_BLOCKED_CYCLES", + "BriefDescription": "DEA Blocked Cycles", + "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "76", + "EventName": "AES_FUNCTIONS", + "BriefDescription": "AES Functions", + "PublicDescription": "Total number of AES functions issued by the CPU" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "77", + "EventName": "AES_CYCLES", + "BriefDescription": "AES Cycles", + "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "78", + "EventName": "AES_BLOCKED_FUNCTIONS", + "BriefDescription": "AES Blocked Functions", + "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "79", + "EventName": "AES_BLOCKED_CYCLES", + "BriefDescription": "AES Blocked Cycles", + "PublicDescription": "Total number of CPU cycles blocked for the AES functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" + }, +] diff --git a/tools/perf/pmu-events/arch/s390/cf_z15/crypto6.json b/tools/perf/pmu-events/arch/s390/cf_z15/crypto6.json new file mode 100644 index 000000000000..5e36bc2468d0 --- /dev/null +++ b/tools/perf/pmu-events/arch/s390/cf_z15/crypto6.json @@ -0,0 +1,30 @@ +[ + { + "Unit": "CPU-M-CF", + "EventCode": "80", + "EventName": "ECC_FUNCTION_COUNT", + "BriefDescription": "ECC Function Count", + "PublicDescription": "Long ECC function Count" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "81", + "EventName": "ECC_CYCLES_COUNT", + "BriefDescription": "ECC Cycles Count", + "PublicDescription": "Long ECC Function cycles count" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "82", + "EventName": "ECC_BLOCKED_FUNCTION_COUNT", + "BriefDescription": "Ecc Blocked Function Count", + "PublicDescription": "Long ECC blocked function count" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "83", + "EventName": "ECC_BLOCKED_CYCLES_COUNT", + "BriefDescription": "ECC Blocked Cycles Count", + "PublicDescription": "Long ECC blocked cycles count" + }, +] diff --git a/tools/perf/pmu-events/arch/s390/cf_z15/extended.json b/tools/perf/pmu-events/arch/s390/cf_z15/extended.json new file mode 100644 index 000000000000..89e070727e1b --- /dev/null +++ b/tools/perf/pmu-events/arch/s390/cf_z15/extended.json @@ -0,0 +1,373 @@ +[ + { + "Unit": "CPU-M-CF", + "EventCode": "128", + "EventName": "L1D_RO_EXCL_WRITES", + "BriefDescription": "L1D Read-only Exclusive Writes", + "PublicDescription": "A directory write to the Level-1 Data cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "129", + "EventName": "DTLB2_WRITES", + "BriefDescription": "DTLB2 Writes", + "PublicDescription": "A translation has been written into The Translation Lookaside Buffer 2 (TLB2) and the request was made by the data cache" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "130", + "EventName": "DTLB2_MISSES", + "BriefDescription": "DTLB2 Misses", + "PublicDescription": "A TLB2 miss is in progress for a request made by the data cache. Incremented by one for every TLB2 miss in progress for the Level-1 Data cache on this cycle" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "131", + "EventName": "DTLB2_HPAGE_WRITES", + "BriefDescription": "DTLB2 One-Megabyte Page Writes", + "PublicDescription": "A translation entry was written into the Combined Region and Segment Table Entry array in the Level-2 TLB for a one-megabyte page or a Last Host Translation was done" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "132", + "EventName": "DTLB2_GPAGE_WRITES", + "BriefDescription": "DTLB2 Two-Gigabyte Page Writes", + "PublicDescription": "A translation entry for a two-gigabyte page was written into the Level-2 TLB" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "133", + "EventName": "L1D_L2D_SOURCED_WRITES", + "BriefDescription": "L1D L2D Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "134", + "EventName": "ITLB2_WRITES", + "BriefDescription": "ITLB2 Writes", + "PublicDescription": "A translation entry has been written into the Translation Lookaside Buffer 2 (TLB2) and the request was made by the instruction cache" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "135", + "EventName": "ITLB2_MISSES", + "BriefDescription": "ITLB2 Misses", + "PublicDescription": "A TLB2 miss is in progress for a request made by the instruction cache. Incremented by one for every TLB2 miss in progress for the Level-1 Instruction cache in a cycle" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "136", + "EventName": "L1I_L2I_SOURCED_WRITES", + "BriefDescription": "L1I L2I Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "137", + "EventName": "TLB2_PTE_WRITES", + "BriefDescription": "TLB2 PTE Writes", + "PublicDescription": "A translation entry was written into the Page Table Entry array in the Level-2 TLB" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "138", + "EventName": "TLB2_CRSTE_WRITES", + "BriefDescription": "TLB2 CRSTE Writes", + "PublicDescription": "Translation entries were written into the Combined Region and Segment Table Entry array and the Page Table Entry array in the Level-2 TLB" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "139", + "EventName": "TLB2_ENGINES_BUSY", + "BriefDescription": "TLB2 Engines Busy", + "PublicDescription": "The number of Level-2 TLB translation engines busy in a cycle" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "140", + "EventName": "TX_C_TEND", + "BriefDescription": "Completed TEND instructions in constrained TX mode", + "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "141", + "EventName": "TX_NC_TEND", + "BriefDescription": "Completed TEND instructions in non-constrained TX mode", + "PublicDescription": "A TEND instruction has completed in a non-constrained transactional-execution mode" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "143", + "EventName": "L1C_TLB2_MISSES", + "BriefDescription": "L1C TLB2 Misses", + "PublicDescription": "Increments by one for any cycle where a level-1 cache or level-2 TLB miss is in progress" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "144", + "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES", + "BriefDescription": "L1D On-Chip L3 Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "145", + "EventName": "L1D_ONCHIP_MEMORY_SOURCED_WRITES", + "BriefDescription": "L1D On-Chip Memory Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip memory" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "146", + "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV", + "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention", + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache with intervention" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "147", + "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES", + "BriefDescription": "L1D On-Cluster L3 Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Cluster Level-3 cache withountervention" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "148", + "EventName": "L1D_ONCLUSTER_MEMORY_SOURCED_WRITES", + "BriefDescription": "L1D On-Cluster Memory Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster memory" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "149", + "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES_IV", + "BriefDescription": "L1D On-Cluster L3 Sourced Writes with Intervention", + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache with intervention" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "150", + "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES", + "BriefDescription": "L1D Off-Cluster L3 Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "151", + "EventName": "L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES", + "BriefDescription": "L1D Off-Cluster Memory Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Cluster memory" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "152", + "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV", + "BriefDescription": "L1D Off-Cluster L3 Sourced Writes with Intervention", + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "153", + "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES", + "BriefDescription": "L1D Off-Drawer L3 Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "154", + "EventName": "L1D_OFFDRAWER_MEMORY_SOURCED_WRITES", + "BriefDescription": "L1D Off-Drawer Memory Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer memory" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "155", + "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES_IV", + "BriefDescription": "L1D Off-Drawer L3 Sourced Writes with Intervention", + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "156", + "EventName": "L1D_ONDRAWER_L4_SOURCED_WRITES", + "BriefDescription": "L1D On-Drawer L4 Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer Level-4 cache" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "157", + "EventName": "L1D_OFFDRAWER_L4_SOURCED_WRITES", + "BriefDescription": "L1D Off-Drawer L4 Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "158", + "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_RO", + "BriefDescription": "L1D On-Chip L3 Sourced Writes read-only", + "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip L3 but a read-only invalidate was done to remove other copies of the cache line" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "162", + "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES", + "BriefDescription": "L1I On-Chip L3 Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache without intervention" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "163", + "EventName": "L1I_ONCHIP_MEMORY_SOURCED_WRITES", + "BriefDescription": "L1I On-Chip Memory Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from On-Chip memory" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "164", + "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV", + "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention", + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache with intervention" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "165", + "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES", + "BriefDescription": "L1I On-Cluster L3 Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache without intervention" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "166", + "EventName": "L1I_ONCLUSTER_MEMORY_SOURCED_WRITES", + "BriefDescription": "L1I On-Cluster Memory Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster memory" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "167", + "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES_IV", + "BriefDescription": "L1I On-Cluster L3 Sourced Writes with Intervention", + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Cluster Level-3 cache with intervention" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "168", + "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES", + "BriefDescription": "L1I Off-Cluster L3 Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "169", + "EventName": "L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES", + "BriefDescription": "L1I Off-Cluster Memory Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Cluster memory" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "170", + "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV", + "BriefDescription": "L1I Off-Cluster L3 Sourced Writes with Intervention", + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "171", + "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES", + "BriefDescription": "L1I Off-Drawer L3 Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "172", + "EventName": "L1I_OFFDRAWER_MEMORY_SOURCED_WRITES", + "BriefDescription": "L1I Off-Drawer Memory Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer memory" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "173", + "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES_IV", + "BriefDescription": "L1I Off-Drawer L3 Sourced Writes with Intervention", + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "174", + "EventName": "L1I_ONDRAWER_L4_SOURCED_WRITES", + "BriefDescription": "L1I On-Drawer L4 Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer Level-4 cache" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "175", + "EventName": "L1I_OFFDRAWER_L4_SOURCED_WRITES", + "BriefDescription": "L1I Off-Drawer L4 Sourced Writes", + "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "224", + "EventName": "BCD_DFP_EXECUTION_SLOTS", + "BriefDescription": "BCD DFP Execution Slots", + "PublicDescription": "Count of floating point execution slots used for finished Binary Coded Decimal to Decimal Floating Point conversions. Instructions: CDZT, CXZT, CZDT, CZXT" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "225", + "EventName": "VX_BCD_EXECUTION_SLOTS", + "BriefDescription": "VX BCD Execution Slots", + "PublicDescription": "Count of floating point execution slots used for finished vector arithmetic Binary Coded Decimal instructions. Instructions: VAP, VSP, VMPVMSP, VDP, VSDP, VRP, VLIP, VSRP, VPSOPVCP, VTP, VPKZ, VUPKZ, VCVB, VCVBG, VCVDVCVDG" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "226", + "EventName": "DECIMAL_INSTRUCTIONS", + "BriefDescription": "Decimal Instructions", + "PublicDescription": "Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED, EDMK, MP, SRP, SP, ZAP" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "232", + "EventName": "LAST_HOST_TRANSLATIONS", + "BriefDescription": "Last host translation done", + "PublicDescription": "Last Host Translation done" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "243", + "EventName": "TX_NC_TABORT", + "BriefDescription": "Aborted transactions in non-constrained TX mode", + "PublicDescription": "A transaction abort has occurred in a non-constrained transactional-execution mode" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "244", + "EventName": "TX_C_TABORT_NO_SPECIAL", + "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic", + "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "245", + "EventName": "TX_C_TABORT_SPECIAL", + "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic", + "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is using special logic to allow the transaction to complete" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "448", + "EventName": "MT_DIAG_CYCLES_ONE_THR_ACTIVE", + "BriefDescription": "Cycle count with one thread active", + "PublicDescription": "Cycle count with one thread active" + }, + { + "Unit": "CPU-M-CF", + "EventCode": "449", + "EventName": "MT_DIAG_CYCLES_TWO_THR_ACTIVE", + "BriefDescription": "Cycle count with two threads active", + "PublicDescription": "Cycle count with two threads active" + }, +] diff --git a/tools/perf/pmu-events/arch/s390/cf_z15/transaction.json b/tools/perf/pmu-events/arch/s390/cf_z15/transaction.json new file mode 100644 index 000000000000..1a0034f79f73 --- /dev/null +++ b/tools/perf/pmu-events/arch/s390/cf_z15/transaction.json @@ -0,0 +1,7 @@ +[ + { + "BriefDescription": "Transaction count", + "MetricName": "transaction", + "MetricExpr": "TX_C_TEND + TX_NC_TEND + TX_NC_TABORT + TX_C_TABORT_SPECIAL + TX_C_TABORT_NO_SPECIAL" + } +] diff --git a/tools/perf/pmu-events/arch/s390/mapfile.csv b/tools/perf/pmu-events/arch/s390/mapfile.csv index bd3fc577139c..61641a3480e0 100644 --- a/tools/perf/pmu-events/arch/s390/mapfile.csv +++ b/tools/perf/pmu-events/arch/s390/mapfile.csv @@ -4,4 +4,4 @@ Family-model,Version,Filename,EventType ^IBM.282[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_zec12,core ^IBM.296[45].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z13,core ^IBM.390[67].*[13]\.[1-5].[[:xdigit:]]+$,3,cf_z14,core -^IBM.856[12].*3\.6.[[:xdigit:]]+$,3,cf_m8561,core +^IBM.856[12].*3\.6.[[:xdigit:]]+$,3,cf_z15,core -- cgit v1.2.3-59-g8ed1b From ee212d6ea20887c0ef352be8563ca13dbf965906 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Sat, 28 Sep 2019 01:39:00 +0000 Subject: perf map: Fix overlapped map handling Whenever an mmap/mmap2 event occurs, the map tree must be updated to add a new entry. If a new map overlaps a previous map, the overlapped section of the previous map is effectively unmapped, but the non-overlapping sections are still valid. maps__fixup_overlappings() is responsible for creating any new map entries from the previously overlapped map. It optionally creates a before and an after map. When creating the after map the existing code failed to adjust the map.pgoff. This meant the new after map would incorrectly calculate the file offset for the ip. This results in incorrect symbol name resolution for any ip in the after region. Make maps__fixup_overlappings() correctly populate map.pgoff. Add an assert that new mapping matches old mapping at the beginning of the after map. Committer-testing: Validated correct parsing of libcoreclr.so symbols from .NET Core 3.0 preview9 (which didn't strip symbols). Preparation: ~/dotnet3.0-preview9/dotnet new webapi -o perfSymbol cd perfSymbol ~/dotnet3.0-preview9/dotnet publish perf record ~/dotnet3.0-preview9/dotnet \ bin/Debug/netcoreapp3.0/publish/perfSymbol.dll ^C Before: perf script --show-mmap-events 2>&1 | grep -e MMAP -e unknown |\ grep libcoreclr.so | head -n 4 dotnet 1907 373352.698780: PERF_RECORD_MMAP2 1907/1907: \ [0x7fe615726000(0x768000) @ 0 08:02 5510620 765057155]: \ r-xp .../3.0.0-preview9-19423-09/libcoreclr.so dotnet 1907 373352.701091: PERF_RECORD_MMAP2 1907/1907: \ [0x7fe615974000(0x1000) @ 0x24e000 08:02 5510620 765057155]: \ rwxp .../3.0.0-preview9-19423-09/libcoreclr.so dotnet 1907 373352.701241: PERF_RECORD_MMAP2 1907/1907: \ [0x7fe615c42000(0x1000) @ 0x51c000 08:02 5510620 765057155]: \ rwxp .../3.0.0-preview9-19423-09/libcoreclr.so dotnet 1907 373352.705249: 250000 cpu-clock: \ 7fe6159a1f99 [unknown] \ (.../3.0.0-preview9-19423-09/libcoreclr.so) After: perf script --show-mmap-events 2>&1 | grep -e MMAP -e unknown |\ grep libcoreclr.so | head -n 4 dotnet 1907 373352.698780: PERF_RECORD_MMAP2 1907/1907: \ [0x7fe615726000(0x768000) @ 0 08:02 5510620 765057155]: \ r-xp .../3.0.0-preview9-19423-09/libcoreclr.so dotnet 1907 373352.701091: PERF_RECORD_MMAP2 1907/1907: \ [0x7fe615974000(0x1000) @ 0x24e000 08:02 5510620 765057155]: \ rwxp .../3.0.0-preview9-19423-09/libcoreclr.so dotnet 1907 373352.701241: PERF_RECORD_MMAP2 1907/1907: \ [0x7fe615c42000(0x1000) @ 0x51c000 08:02 5510620 765057155]: \ rwxp .../3.0.0-preview9-19423-09/libcoreclr.so All the [unknown] symbols were resolved. Signed-off-by: Steve MacLean Tested-by: Brian Robbins Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Davidlohr Bueso Cc: Eric Saint-Etienne Cc: John Keeping Cc: John Salem Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Song Liu Cc: Stephane Eranian Cc: Tom McDonald Link: http://lore.kernel.org/lkml/BN8PR21MB136270949F22A6A02335C238F7800@BN8PR21MB1362.namprd21.prod.outlook.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/map.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 5b83ed1ebbd6..eec9b282c047 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "symbol.h" +#include #include #include #include @@ -850,6 +851,8 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp } after->start = map->end; + after->pgoff += map->end - pos->start; + assert(pos->map_ip(pos, map->end) == after->map_ip(after, map->end)); __map_groups__insert(pos->groups, after); if (verbose >= 2 && !use_browser) map__fprintf(after, fp); -- cgit v1.2.3-59-g8ed1b From b59711e9b0d22fd47abfa00602fd8c365cdd3ab7 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Sat, 28 Sep 2019 01:41:18 +0000 Subject: perf inject jit: Fix JIT_CODE_MOVE filename During perf inject --jit, JIT_CODE_MOVE records were injecting MMAP records with an incorrect filename. Specifically it was missing the ".so" suffix. Further the JIT_CODE_LOAD record were silently truncating the jr->load.code_index field to 32 bits before generating the filename. Make both records emit the same filename based on the full 64 bit code_index field. Fixes: 9b07e27f88b9 ("perf inject: Add jitdump mmap injection support") Cc: stable@vger.kernel.org # v4.6+ Signed-off-by: Steve MacLean Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Brian Robbins Cc: Davidlohr Bueso Cc: Eric Saint-Etienne Cc: John Keeping Cc: John Salem Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Song Liu Cc: Stephane Eranian Cc: Tom McDonald Link: http://lore.kernel.org/lkml/BN8PR21MB1362FF8F127B31DBF4121528F7800@BN8PR21MB1362.namprd21.prod.outlook.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/jitdump.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c index 1bdf4c6ea3e5..e3ccb0ce1938 100644 --- a/tools/perf/util/jitdump.c +++ b/tools/perf/util/jitdump.c @@ -395,7 +395,7 @@ static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr) size_t size; u16 idr_size; const char *sym; - uint32_t count; + uint64_t count; int ret, csize, usize; pid_t pid, tid; struct { @@ -418,7 +418,7 @@ static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr) return -1; filename = event->mmap2.filename; - size = snprintf(filename, PATH_MAX, "%s/jitted-%d-%u.so", + size = snprintf(filename, PATH_MAX, "%s/jitted-%d-%" PRIu64 ".so", jd->dir, pid, count); @@ -529,7 +529,7 @@ static int jit_repipe_code_move(struct jit_buf_desc *jd, union jr_entry *jr) return -1; filename = event->mmap2.filename; - size = snprintf(filename, PATH_MAX, "%s/jitted-%d-%"PRIu64, + size = snprintf(filename, PATH_MAX, "%s/jitted-%d-%" PRIu64 ".so", jd->dir, pid, jr->move.code_index); -- cgit v1.2.3-59-g8ed1b From 2657983b4c0d81632c6a73bae469951b0d341251 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Sat, 28 Sep 2019 01:53:08 +0000 Subject: perf docs: Correct and clarify jitdump spec Specification claims latest version of jitdump file format is 2. Current jit dump reading code treats 1 as the latest version. Correct spec to match code. The original language made it unclear the value to be written in the magic field. Revise language that the writer always writes the same value. Specify that the reader uses the value to detect endian mismatches. Signed-off-by: Steve MacLean Acked-by: Stephane Eranian Cc: Alexander Shishkin Cc: Andi Kleen Cc: Brian Robbins Cc: Davidlohr Bueso Cc: Eric Saint-Etienne Cc: Jiri Olsa Cc: John Keeping Cc: John Salem Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Song Liu Cc: Tom McDonald Link: http://lore.kernel.org/lkml/BN8PR21MB1362F63CDE7AC69736FC7F9EF7800@BN8PR21MB1362.namprd21.prod.outlook.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/jitdump-specification.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/Documentation/jitdump-specification.txt b/tools/perf/Documentation/jitdump-specification.txt index 4c62b0713651..52152d156ad9 100644 --- a/tools/perf/Documentation/jitdump-specification.txt +++ b/tools/perf/Documentation/jitdump-specification.txt @@ -36,8 +36,8 @@ III/ Jitdump file header format Each jitdump file starts with a fixed size header containing the following fields in order: -* uint32_t magic : a magic number tagging the file type. The value is 4-byte long and represents the string "JiTD" in ASCII form. It is 0x4A695444 or 0x4454694a depending on the endianness. The field can be used to detect the endianness of the file -* uint32_t version : a 4-byte value representing the format version. It is currently set to 2 +* uint32_t magic : a magic number tagging the file type. The value is 4-byte long and represents the string "JiTD" in ASCII form. It written is as 0x4A695444. The reader will detect an endian mismatch when it reads 0x4454694a. +* uint32_t version : a 4-byte value representing the format version. It is currently set to 1 * uint32_t total_size: size in bytes of file header * uint32_t elf_mach : ELF architecture encoding (ELF e_machine value as specified in /usr/include/elf.h) * uint32_t pad1 : padding. Reserved for future use -- cgit v1.2.3-59-g8ed1b From e98df280bc2a499fd41d7f9e2d6733884de69902 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 27 Sep 2019 16:35:44 -0700 Subject: perf script brstackinsn: Fix recovery from LBR/binary mismatch When the LBR data and the instructions in a binary do not match the loop printing instructions could get confused and print a long stream of bogus instructions. The problem was that if the instruction decoder cannot decode an instruction it ilen wasn't initialized, so the loop going through the basic block would continue with the previous value. Harden the code to avoid such problems: - Make sure ilen is always freshly initialized and is 0 for bad instructions. - Do not overrun the code buffer while printing instructions - Print a warning message if the final jump is not on an instruction boundary. Signed-off-by: Andi Kleen Cc: Jiri Olsa Link: http://lore.kernel.org/lkml/20190927233546.11533-1-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 286fc70d7402..67be8d31afab 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1063,7 +1063,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, continue; insn = 0; - for (off = 0;; off += ilen) { + for (off = 0; off < (unsigned)len; off += ilen) { uint64_t ip = start + off; printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, attr, fp); @@ -1074,6 +1074,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, printed += print_srccode(thread, x.cpumode, ip); break; } else { + ilen = 0; printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", ip, dump_insn(&x, ip, buffer + off, len - off, &ilen)); if (ilen == 0) @@ -1083,6 +1084,8 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, insn++; } } + if (off != (unsigned)len) + printed += fprintf(fp, "\tmismatch of LBR data and executable\n"); } /* @@ -1123,6 +1126,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, goto out; } for (off = 0; off <= end - start; off += ilen) { + ilen = 0; printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", start + off, dump_insn(&x, start + off, buffer + off, len - off, &ilen)); if (ilen == 0) -- cgit v1.2.3-59-g8ed1b From 6bdfd9f118bd59cf0f85d3bf4b72b586adea17c1 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 27 Sep 2019 16:35:45 -0700 Subject: perf jevents: Fix period for Intel fixed counters The Intel fixed counters use a special table to override the JSON information. During this override the period information from the JSON file got dropped, which results in inst_retired.any and similar running with frequency mode instead of a period. Just specify the expected period in the table. Signed-off-by: Andi Kleen Cc: Jiri Olsa Link: http://lore.kernel.org/lkml/20190927233546.11533-2-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/pmu-events/jevents.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index 9e37287da924..e2837260ca4d 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -450,12 +450,12 @@ static struct fixed { const char *name; const char *event; } fixed[] = { - { "inst_retired.any", "event=0xc0" }, - { "inst_retired.any_p", "event=0xc0" }, - { "cpu_clk_unhalted.ref", "event=0x0,umask=0x03" }, - { "cpu_clk_unhalted.thread", "event=0x3c" }, - { "cpu_clk_unhalted.core", "event=0x3c" }, - { "cpu_clk_unhalted.thread_any", "event=0x3c,any=1" }, + { "inst_retired.any", "event=0xc0,period=2000003" }, + { "inst_retired.any_p", "event=0xc0,period=2000003" }, + { "cpu_clk_unhalted.ref", "event=0x0,umask=0x03,period=2000003" }, + { "cpu_clk_unhalted.thread", "event=0x3c,period=2000003" }, + { "cpu_clk_unhalted.core", "event=0x3c,period=2000003" }, + { "cpu_clk_unhalted.thread_any", "event=0x3c,any=1,period=2000003" }, { NULL, NULL}, }; -- cgit v1.2.3-59-g8ed1b From f67001a4a08eb124197ed4376941e1da9cf94b42 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 30 Sep 2019 10:55:34 -0300 Subject: perf tools: Propagate get_cpuid() error For consistency, propagate the exact cause for get_cpuid() to have failed. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-9ig269f7ktnhh99g4l15vpu2@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/powerpc/util/header.c | 3 ++- tools/perf/arch/s390/util/header.c | 9 +++++---- tools/perf/arch/x86/util/header.c | 3 ++- tools/perf/builtin-kvm.c | 7 ++++--- 4 files changed, 13 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index b6b7bc7e31a1..3b4cdfc5efd6 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include #include @@ -30,7 +31,7 @@ get_cpuid(char *buffer, size_t sz) buffer[nb-1] = '\0'; return 0; } - return -1; + return ENOBUFS; } char * diff --git a/tools/perf/arch/s390/util/header.c b/tools/perf/arch/s390/util/header.c index 8b0b018d896a..7933f6871c81 100644 --- a/tools/perf/arch/s390/util/header.c +++ b/tools/perf/arch/s390/util/header.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -54,7 +55,7 @@ int get_cpuid(char *buffer, size_t sz) sysinfo = fopen(SYSINFO, "r"); if (sysinfo == NULL) - return -1; + return errno; while ((read = getline(&line, &line_sz, sysinfo)) != -1) { if (!strncmp(line, SYSINFO_MANU, strlen(SYSINFO_MANU))) { @@ -89,7 +90,7 @@ int get_cpuid(char *buffer, size_t sz) /* Missing manufacturer, type or model information should not happen */ if (!manufacturer[0] || !type[0] || !model[0]) - return -1; + return EINVAL; /* * Scan /proc/service_levels and return the CPU-MF counter facility @@ -133,14 +134,14 @@ skip_sysinfo: else nbytes = snprintf(buffer, sz, "%s,%s,%s", manufacturer, type, model); - return (nbytes >= sz) ? -1 : 0; + return (nbytes >= sz) ? ENOBUFS : 0; } char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused) { char *buf = malloc(128); - if (buf && get_cpuid(buf, 128) < 0) + if (buf && get_cpuid(buf, 128)) zfree(&buf); return buf; } diff --git a/tools/perf/arch/x86/util/header.c b/tools/perf/arch/x86/util/header.c index 662ecf84a421..aa6deb463bf3 100644 --- a/tools/perf/arch/x86/util/header.c +++ b/tools/perf/arch/x86/util/header.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include #include @@ -58,7 +59,7 @@ __get_cpuid(char *buffer, size_t sz, const char *fmt) buffer[nb-1] = '\0'; return 0; } - return -1; + return ENOBUFS; } int diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 2227e2f42c09..58a9e0989491 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -705,14 +705,15 @@ static int process_sample_event(struct perf_tool *tool, static int cpu_isa_config(struct perf_kvm_stat *kvm) { - char buf[64], *cpuid; + char buf[128], *cpuid; int err; if (kvm->live) { err = get_cpuid(buf, sizeof(buf)); if (err != 0) { - pr_err("Failed to look up CPU type\n"); - return err; + pr_err("Failed to look up CPU type: %s\n", + str_error_r(err, buf, sizeof(buf))); + return -err; } cpuid = buf; } else -- cgit v1.2.3-59-g8ed1b From 9db0e3635fb35b6695275774ab909c51221b66ad Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 30 Sep 2019 11:48:32 -0300 Subject: perf evsel: Fall back to global 'perf_env' in perf_evsel__env() I.e. if evsel->evlist or evsel->evlist->env isn't set, return the environment for the running machine, as that would be set if reading from a perf.data file. Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-uqq4grmhbi12rwb0lfpo6lfu@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 3 ++- tools/perf/util/python.c | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 5591af81a070..abc7fda4a0fe 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -30,6 +30,7 @@ #include "counts.h" #include "event.h" #include "evsel.h" +#include "util/env.h" #include "util/evsel_config.h" #include "util/evsel_fprintf.h" #include "evlist.h" @@ -2512,7 +2513,7 @@ struct perf_env *perf_evsel__env(struct evsel *evsel) { if (evsel && evsel->evlist) return evsel->evlist->env; - return NULL; + return &perf_env; } static int store_evsel_ids(struct evsel *evsel, struct evlist *evlist) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 53f31053a27a..02460362256d 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -14,6 +14,7 @@ #include "thread_map.h" #include "trace-event.h" #include "mmap.h" +#include "util/env.h" #include #include "../perf-sys.h" @@ -53,6 +54,11 @@ int parse_callchain_record(const char *arg __maybe_unused, return 0; } +/* + * Add this one here not to drag util/env.c + */ +struct perf_env perf_env; + /* * Support debug printing even though util/debug.c is not linked. That means * implementing 'verbose' and 'eprintf'. -- cgit v1.2.3-59-g8ed1b From a66fa0619a0ae3585ef09e9c33ecfb5c7c6cb72b Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 30 Sep 2019 15:06:01 -0300 Subject: perf annotate: Propagate perf_env__arch() error The callers of symbol__annotate2() use symbol__strerror_disassemble() to convert its failure returns into a human readable string, so propagate error values from functions it calls, starting with perf_env__arch() that when fails the right thing to do is to look at 'errno' to see why its possible call to uname() failed. Reported-by: Russell King - ARM Linux admin Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra , Cc: Will Deacon Link: https://lkml.kernel.org/n/tip-it5d83kyusfhb1q1b0l4pxzs@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index e830eadfca2a..9b7b9176e713 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -2071,7 +2071,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, int err; if (!arch_name) - return -1; + return errno; args.arch = arch = arch__find(arch_name); if (arch == NULL) -- cgit v1.2.3-59-g8ed1b From 28f4417c3333940b242af03d90214f713bbef232 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 30 Sep 2019 15:11:47 -0300 Subject: perf annotate: Fix the signedness of failure returns Callers of symbol__annotate() expect a errno value or some other extended error value range in symbol__strerror_disassemble() to convert to a proper error string, fix it when propagating a failure to find the arch specific annotation routines via arch__find(arch_name). Reported-by: Russell King - ARM Linux admin Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra , Cc: Will Deacon Link: https://lkml.kernel.org/n/tip-o0k6dw7cas0vvmjjvgsyvu1i@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 9b7b9176e713..95109acf4808 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -2075,7 +2075,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, args.arch = arch = arch__find(arch_name); if (arch == NULL) - return -ENOTSUP; + return ENOTSUP; if (parch) *parch = arch; -- cgit v1.2.3-59-g8ed1b From 211f493b611eef012841f795166c38ec7528738d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 30 Sep 2019 15:44:13 -0300 Subject: perf annotate: Propagate the symbol__annotate() error return We were just returning -1 in symbol__annotate() when symbol__annotate() failed, propagate its error as it is used later to pass to symbol__strerror_disassemble() to present a error message to the user, that in some cases were getting: "Invalid -1 error code" Fix it to propagate the error. Reported-by: Russell King - ARM Linux admin Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra , Cc: Will Deacon Link: https://lkml.kernel.org/n/tip-0tj89rs9g7nbcyd5skadlvuu@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 95109acf4808..1de1a7091c48 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -2997,7 +2997,7 @@ int symbol__annotate2(struct symbol *sym, struct map *map, struct evsel *evsel, out_free_offsets: zfree(¬es->offsets); - return -1; + return err; } #define ANNOTATION__CFG(n) \ -- cgit v1.2.3-59-g8ed1b From 42d7a9107d83223a5fcecc6732d626a6c074cbc2 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 30 Sep 2019 15:48:12 -0300 Subject: perf annotate: Fix arch specific ->init() failure errors They are called from symbol__annotate() and to propagate errors that can help understand the problem make them return what symbol__strerror_disassemble() known, i.e. errno codes and other annotation specific errors in a special, out of errnos, range. Reported-by: Russell King - ARM Linux admin Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra , Cc: Will Deacon Link: https://lkml.kernel.org/n/tip-pqx7srcv7tixgid251aeboj6@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/annotate/instructions.c | 4 ++-- tools/perf/arch/arm64/annotate/instructions.c | 4 ++-- tools/perf/arch/s390/annotate/instructions.c | 6 ++++-- tools/perf/arch/x86/annotate/instructions.c | 6 ++++-- tools/perf/util/annotate.c | 6 ++++++ tools/perf/util/annotate.h | 2 ++ 6 files changed, 20 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/arm/annotate/instructions.c b/tools/perf/arch/arm/annotate/instructions.c index e1d4b484cc4b..2ff6cedeb9c5 100644 --- a/tools/perf/arch/arm/annotate/instructions.c +++ b/tools/perf/arch/arm/annotate/instructions.c @@ -37,7 +37,7 @@ static int arm__annotate_init(struct arch *arch, char *cpuid __maybe_unused) arm = zalloc(sizeof(*arm)); if (!arm) - return -1; + return ENOMEM; #define ARM_CONDS "(cc|cs|eq|ge|gt|hi|le|ls|lt|mi|ne|pl|vc|vs)" err = regcomp(&arm->call_insn, "^blx?" ARM_CONDS "?$", REG_EXTENDED); @@ -59,5 +59,5 @@ out_free_call: regfree(&arm->call_insn); out_free_arm: free(arm); - return -1; + return SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP; } diff --git a/tools/perf/arch/arm64/annotate/instructions.c b/tools/perf/arch/arm64/annotate/instructions.c index 43aa93ed8414..037e292ecd8e 100644 --- a/tools/perf/arch/arm64/annotate/instructions.c +++ b/tools/perf/arch/arm64/annotate/instructions.c @@ -95,7 +95,7 @@ static int arm64__annotate_init(struct arch *arch, char *cpuid __maybe_unused) arm = zalloc(sizeof(*arm)); if (!arm) - return -1; + return ENOMEM; /* bl, blr */ err = regcomp(&arm->call_insn, "^blr?$", REG_EXTENDED); @@ -118,5 +118,5 @@ out_free_call: regfree(&arm->call_insn); out_free_arm: free(arm); - return -1; + return SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP; } diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch/s390/annotate/instructions.c index 89bb8f2c54ce..a50e70baf918 100644 --- a/tools/perf/arch/s390/annotate/instructions.c +++ b/tools/perf/arch/s390/annotate/instructions.c @@ -164,8 +164,10 @@ static int s390__annotate_init(struct arch *arch, char *cpuid __maybe_unused) if (!arch->initialized) { arch->initialized = true; arch->associate_instruction_ops = s390__associate_ins_ops; - if (cpuid) - err = s390__cpuid_parse(arch, cpuid); + if (cpuid) { + if (s390__cpuid_parse(arch, cpuid)) + err = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING; + } } return err; diff --git a/tools/perf/arch/x86/annotate/instructions.c b/tools/perf/arch/x86/annotate/instructions.c index 44f5aba78210..7eb5621c021d 100644 --- a/tools/perf/arch/x86/annotate/instructions.c +++ b/tools/perf/arch/x86/annotate/instructions.c @@ -196,8 +196,10 @@ static int x86__annotate_init(struct arch *arch, char *cpuid) if (arch->initialized) return 0; - if (cpuid) - err = x86__cpuid_parse(arch, cpuid); + if (cpuid) { + if (x86__cpuid_parse(arch, cpuid)) + err = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING; + } arch->initialized = true; return err; diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 1de1a7091c48..dc15352924f9 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1631,6 +1631,12 @@ int symbol__strerror_disassemble(struct symbol *sym __maybe_unused, struct map * case SYMBOL_ANNOTATE_ERRNO__NO_LIBOPCODES_FOR_BPF: scnprintf(buf, buflen, "Please link with binutils's libopcode to enable BPF annotation"); break; + case SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP: + scnprintf(buf, buflen, "Problems with arch specific instruction name regular expressions."); + break; + case SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING: + scnprintf(buf, buflen, "Problems while parsing the CPUID in the arch specific initialization."); + break; default: scnprintf(buf, buflen, "Internal error: Invalid %d error code\n", errnum); break; diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index d94be9140e31..116e21f49da6 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -370,6 +370,8 @@ enum symbol_disassemble_errno { SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX = __SYMBOL_ANNOTATE_ERRNO__START, SYMBOL_ANNOTATE_ERRNO__NO_LIBOPCODES_FOR_BPF, + SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING, + SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP, __SYMBOL_ANNOTATE_ERRNO__END, }; -- cgit v1.2.3-59-g8ed1b From 16ed3c1e91159e28b02f11f71ff4ce4cbc6f99e4 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 30 Sep 2019 15:53:33 -0300 Subject: perf annotate: Return appropriate error code for allocation failures We should return errno or the annotation extra range understood by symbol__strerror_disassemble() instead of -1, fix it, returning ENOMEM instead. Reported-by: Russell King - ARM Linux admin Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra , Cc: Will Deacon Link: https://lkml.kernel.org/n/tip-8of1cmj3rz0mppfcshc9bbqq@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index dc15352924f9..b49ecdd51188 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1668,7 +1668,7 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil build_id_path = strdup(filename); if (!build_id_path) - return -1; + return ENOMEM; /* * old style build-id cache has name of XX/XXXXXXX.. while @@ -2977,7 +2977,7 @@ int symbol__annotate2(struct symbol *sym, struct map *map, struct evsel *evsel, notes->offsets = zalloc(size * sizeof(struct annotation_line *)); if (notes->offsets == NULL) - return -1; + return ENOMEM; if (perf_evsel__is_group_event(evsel)) nr_pcnt = evsel->core.nr_members; -- cgit v1.2.3-59-g8ed1b From 11aad897f6d1a28eae3b7e5b293647c522d65819 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 30 Sep 2019 16:04:21 -0300 Subject: perf annotate: Don't return -1 for error when doing BPF disassembly Return errno when open_memstream() fails and add two new speciall error codes for when an invalid, non BPF file or one without BTF is passed to symbol__disassemble_bpf(), so that its callers can rely on symbol__strerror_disassemble() to convert that to a human readable error message that can help figure out what is wrong, with hints even. Cc: Russell King - ARM Linux admin Cc: Song Liu Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra , Cc: Will Deacon Link: https://lkml.kernel.org/n/tip-usevw9r2gcipfcrbpaueurw0@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 19 +++++++++++++++---- tools/perf/util/annotate.h | 2 ++ 2 files changed, 17 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index b49ecdd51188..4036c7f7b0fb 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1637,6 +1637,13 @@ int symbol__strerror_disassemble(struct symbol *sym __maybe_unused, struct map * case SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING: scnprintf(buf, buflen, "Problems while parsing the CPUID in the arch specific initialization."); break; + case SYMBOL_ANNOTATE_ERRNO__BPF_INVALID_FILE: + scnprintf(buf, buflen, "Invalid BPF file: %s.", dso->long_name); + break; + case SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF: + scnprintf(buf, buflen, "The %s BPF file has no BTF section, compile with -g or use pahole -J.", + dso->long_name); + break; default: scnprintf(buf, buflen, "Internal error: Invalid %d error code\n", errnum); break; @@ -1719,13 +1726,13 @@ static int symbol__disassemble_bpf(struct symbol *sym, char tpath[PATH_MAX]; size_t buf_size; int nr_skip = 0; - int ret = -1; char *buf; bfd *bfdf; + int ret; FILE *s; if (dso->binary_type != DSO_BINARY_TYPE__BPF_PROG_INFO) - return -1; + return SYMBOL_ANNOTATE_ERRNO__BPF_INVALID_FILE; pr_debug("%s: handling sym %s addr %" PRIx64 " len %" PRIx64 "\n", __func__, sym->name, sym->start, sym->end - sym->start); @@ -1738,8 +1745,10 @@ static int symbol__disassemble_bpf(struct symbol *sym, assert(bfd_check_format(bfdf, bfd_object)); s = open_memstream(&buf, &buf_size); - if (!s) + if (!s) { + ret = errno; goto out; + } init_disassemble_info(&info, s, (fprintf_ftype) fprintf); @@ -1748,8 +1757,10 @@ static int symbol__disassemble_bpf(struct symbol *sym, info_node = perf_env__find_bpf_prog_info(dso->bpf_prog.env, dso->bpf_prog.id); - if (!info_node) + if (!info_node) { + return SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF; goto out; + } info_linear = info_node->info_linear; sub_id = dso->bpf_prog.sub_id; diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 116e21f49da6..d76fd0e81f46 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -372,6 +372,8 @@ enum symbol_disassemble_errno { SYMBOL_ANNOTATE_ERRNO__NO_LIBOPCODES_FOR_BPF, SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING, SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP, + SYMBOL_ANNOTATE_ERRNO__BPF_INVALID_FILE, + SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF, __SYMBOL_ANNOTATE_ERRNO__END, }; -- cgit v1.2.3-59-g8ed1b From 3969e76909d3aa06715997896184ee684f68d164 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Tue, 24 Sep 2019 13:52:37 -0600 Subject: selftests: pidfd: Fix undefined reference to pthread_create() Fix build failure: undefined reference to `pthread_create' collect2: error: ld returned 1 exit status Fix CFLAGS to include pthread correctly. Fixes: 740378dc7834 ("pidfd: add polling selftests") Signed-off-by: Shuah Khan Reviewed-by: Christian Brauner Cc: Link: https://lore.kernel.org/r/20190924195237.30519-1-skhan@linuxfoundation.org Signed-off-by: Christian Brauner --- tools/testing/selftests/pidfd/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/pidfd/Makefile b/tools/testing/selftests/pidfd/Makefile index 464c9b76148f..7550f08822a3 100644 --- a/tools/testing/selftests/pidfd/Makefile +++ b/tools/testing/selftests/pidfd/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -CFLAGS += -g -I../../../../usr/include/ -lpthread +CFLAGS += -g -I../../../../usr/include/ -pthread TEST_GEN_PROGS := pidfd_test pidfd_open_test pidfd_poll_test pidfd_wait -- cgit v1.2.3-59-g8ed1b From 1bd63524593b964934a33afd442df16b8f90e2b5 Mon Sep 17 00:00:00 2001 From: Yonghong Song Date: Mon, 30 Sep 2019 14:02:03 -0700 Subject: libbpf: handle symbol versioning properly for libbpf.a bcc uses libbpf repo as a submodule. It brings in libbpf source code and builds everything together to produce shared libraries. With latest libbpf, I got the following errors: /bin/ld: libbcc_bpf.so.0.10.0: version node not found for symbol xsk_umem__create@LIBBPF_0.0.2 /bin/ld: failed to set dynamic section sizes: Bad value collect2: error: ld returned 1 exit status make[2]: *** [src/cc/libbcc_bpf.so.0.10.0] Error 1 In xsk.c, we have asm(".symver xsk_umem__create_v0_0_2, xsk_umem__create@LIBBPF_0.0.2"); asm(".symver xsk_umem__create_v0_0_4, xsk_umem__create@@LIBBPF_0.0.4"); The linker thinks the built is for LIBBPF but cannot find proper version LIBBPF_0.0.2/4, so emit errors. I also confirmed that using libbpf.a to produce a shared library also has issues: -bash-4.4$ cat t.c extern void *xsk_umem__create; void * test() { return xsk_umem__create; } -bash-4.4$ gcc -c -fPIC t.c -bash-4.4$ gcc -shared t.o libbpf.a -o t.so /bin/ld: t.so: version node not found for symbol xsk_umem__create@LIBBPF_0.0.2 /bin/ld: failed to set dynamic section sizes: Bad value collect2: error: ld returned 1 exit status -bash-4.4$ Symbol versioning does happens in commonly used libraries, e.g., elfutils and glibc. For static libraries, for a versioned symbol, the old definitions will be ignored, and the symbol will be an alias to the latest definition. For example, glibc sched_setaffinity is versioned. -bash-4.4$ readelf -s /usr/lib64/libc.so.6 | grep sched_setaffinity 756: 000000000013d3d0 13 FUNC GLOBAL DEFAULT 13 sched_setaffinity@GLIBC_2.3.3 757: 00000000000e2e70 455 FUNC GLOBAL DEFAULT 13 sched_setaffinity@@GLIBC_2.3.4 1800: 0000000000000000 0 FILE LOCAL DEFAULT ABS sched_setaffinity.c 4228: 00000000000e2e70 455 FUNC LOCAL DEFAULT 13 __sched_setaffinity_new 4648: 000000000013d3d0 13 FUNC LOCAL DEFAULT 13 __sched_setaffinity_old 7338: 000000000013d3d0 13 FUNC GLOBAL DEFAULT 13 sched_setaffinity@GLIBC_2 7380: 00000000000e2e70 455 FUNC GLOBAL DEFAULT 13 sched_setaffinity@@GLIBC_ -bash-4.4$ For static library, the definition of sched_setaffinity aliases to the new definition. -bash-4.4$ readelf -s /usr/lib64/libc.a | grep sched_setaffinity File: /usr/lib64/libc.a(sched_setaffinity.o) 8: 0000000000000000 455 FUNC GLOBAL DEFAULT 1 __sched_setaffinity_new 12: 0000000000000000 455 FUNC WEAK DEFAULT 1 sched_setaffinity For both elfutils and glibc, additional macros are used to control different handling of symbol versioning w.r.t static and shared libraries. For elfutils, the macro is SYMBOL_VERSIONING (https://sourceware.org/git/?p=elfutils.git;a=blob;f=lib/eu-config.h). For glibc, the macro is SHARED (https://sourceware.org/git/?p=glibc.git;a=blob;f=include/shlib-compat.h;hb=refs/heads/master) This patch used SHARED as the macro name. After this patch, the libbpf.a has -bash-4.4$ readelf -s libbpf.a | grep xsk_umem__create 372: 0000000000017145 1190 FUNC GLOBAL DEFAULT 1 xsk_umem__create_v0_0_4 405: 0000000000017145 1190 FUNC GLOBAL DEFAULT 1 xsk_umem__create 499: 00000000000175eb 103 FUNC GLOBAL DEFAULT 1 xsk_umem__create_v0_0_2 -bash-4.4$ No versioned symbols for xsk_umem__create. The libbpf.a can be used to build a shared library succesfully. -bash-4.4$ cat t.c extern void *xsk_umem__create; void * test() { return xsk_umem__create; } -bash-4.4$ gcc -c -fPIC t.c -bash-4.4$ gcc -shared t.o libbpf.a -o t.so -bash-4.4$ Fixes: 10d30e301732 ("libbpf: add flags to umem config") Cc: Kevin Laatz Cc: Arnaldo Carvalho de Melo Cc: Andrii Nakryiko Acked-by: Andrii Nakryiko Signed-off-by: Yonghong Song Signed-off-by: Alexei Starovoitov --- tools/lib/bpf/Makefile | 27 ++++++++++++++++++--------- tools/lib/bpf/libbpf_internal.h | 16 ++++++++++++++++ tools/lib/bpf/xsk.c | 4 ++-- 3 files changed, 36 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index 20772663d3e1..56ce6292071b 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile @@ -114,6 +114,9 @@ override CFLAGS += $(INCLUDES) override CFLAGS += -fvisibility=hidden override CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 +# flags specific for shared library +SHLIB_FLAGS := -DSHARED + ifeq ($(VERBOSE),1) Q = else @@ -130,14 +133,17 @@ all: export srctree OUTPUT CC LD CFLAGS V include $(srctree)/tools/build/Makefile.include -BPF_IN := $(OUTPUT)libbpf-in.o +SHARED_OBJDIR := $(OUTPUT)sharedobjs/ +STATIC_OBJDIR := $(OUTPUT)staticobjs/ +BPF_IN_SHARED := $(SHARED_OBJDIR)libbpf-in.o +BPF_IN_STATIC := $(STATIC_OBJDIR)libbpf-in.o VERSION_SCRIPT := libbpf.map LIB_TARGET := $(addprefix $(OUTPUT),$(LIB_TARGET)) LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE)) PC_FILE := $(addprefix $(OUTPUT),$(PC_FILE)) -GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN) | \ +GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN_SHARED) | \ cut -d "@" -f1 | sed 's/_v[0-9]_[0-9]_[0-9].*//' | \ awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$8}' | \ sort -u | wc -l) @@ -159,7 +165,7 @@ all: fixdep all_cmd: $(CMD_TARGETS) check -$(BPF_IN): force elfdep bpfdep +$(BPF_IN_SHARED): force elfdep bpfdep @(test -f ../../include/uapi/linux/bpf.h -a -f ../../../include/uapi/linux/bpf.h && ( \ (diff -B ../../include/uapi/linux/bpf.h ../../../include/uapi/linux/bpf.h >/dev/null) || \ echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf.h' differs from latest version at 'include/uapi/linux/bpf.h'" >&2 )) || true @@ -175,17 +181,20 @@ $(BPF_IN): force elfdep bpfdep @(test -f ../../include/uapi/linux/if_xdp.h -a -f ../../../include/uapi/linux/if_xdp.h && ( \ (diff -B ../../include/uapi/linux/if_xdp.h ../../../include/uapi/linux/if_xdp.h >/dev/null) || \ echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/if_xdp.h' differs from latest version at 'include/uapi/linux/if_xdp.h'" >&2 )) || true - $(Q)$(MAKE) $(build)=libbpf + $(Q)$(MAKE) $(build)=libbpf OUTPUT=$(SHARED_OBJDIR) CFLAGS="$(CFLAGS) $(SHLIB_FLAGS)" + +$(BPF_IN_STATIC): force elfdep bpfdep + $(Q)$(MAKE) $(build)=libbpf OUTPUT=$(STATIC_OBJDIR) $(OUTPUT)libbpf.so: $(OUTPUT)libbpf.so.$(LIBBPF_VERSION) -$(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $(BPF_IN) +$(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $(BPF_IN_SHARED) $(QUIET_LINK)$(CC) --shared -Wl,-soname,libbpf.so.$(LIBBPF_MAJOR_VERSION) \ -Wl,--version-script=$(VERSION_SCRIPT) $^ -lelf -o $@ @ln -sf $(@F) $(OUTPUT)libbpf.so @ln -sf $(@F) $(OUTPUT)libbpf.so.$(LIBBPF_MAJOR_VERSION) -$(OUTPUT)libbpf.a: $(BPF_IN) +$(OUTPUT)libbpf.a: $(BPF_IN_STATIC) $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ $(OUTPUT)test_libbpf: test_libbpf.cpp $(OUTPUT)libbpf.a @@ -201,7 +210,7 @@ check: check_abi check_abi: $(OUTPUT)libbpf.so @if [ "$(GLOBAL_SYM_COUNT)" != "$(VERSIONED_SYM_COUNT)" ]; then \ - echo "Warning: Num of global symbols in $(BPF_IN)" \ + echo "Warning: Num of global symbols in $(BPF_IN_SHARED)" \ "($(GLOBAL_SYM_COUNT)) does NOT match with num of" \ "versioned symbols in $^ ($(VERSIONED_SYM_COUNT))." \ "Please make sure all LIBBPF_API symbols are" \ @@ -259,9 +268,9 @@ config-clean: $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null clean: - $(call QUIET_CLEAN, libbpf) $(RM) $(TARGETS) $(CXX_TEST_TARGET) \ + $(call QUIET_CLEAN, libbpf) $(RM) -rf $(TARGETS) $(CXX_TEST_TARGET) \ *.o *~ *.a *.so *.so.$(LIBBPF_MAJOR_VERSION) .*.d .*.cmd \ - *.pc LIBBPF-CFLAGS + *.pc LIBBPF-CFLAGS $(SHARED_OBJDIR) $(STATIC_OBJDIR) $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h index 2e83a34f8c79..98216a69c32f 100644 --- a/tools/lib/bpf/libbpf_internal.h +++ b/tools/lib/bpf/libbpf_internal.h @@ -34,6 +34,22 @@ (offsetof(TYPE, FIELD) + sizeof(((TYPE *)0)->FIELD)) #endif +/* Symbol versioning is different between static and shared library. + * Properly versioned symbols are needed for shared library, but + * only the symbol of the new version is needed for static library. + */ +#ifdef SHARED +# define COMPAT_VERSION(internal_name, api_name, version) \ + asm(".symver " #internal_name "," #api_name "@" #version); +# define DEFAULT_VERSION(internal_name, api_name, version) \ + asm(".symver " #internal_name "," #api_name "@@" #version); +#else +# define COMPAT_VERSION(internal_name, api_name, version) +# define DEFAULT_VERSION(internal_name, api_name, version) \ + extern typeof(internal_name) api_name \ + __attribute__((alias(#internal_name))); +#endif + extern void libbpf_print(enum libbpf_print_level level, const char *format, ...) __attribute__((format(printf, 2, 3))); diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c index 24fa313524fb..a902838f9fcc 100644 --- a/tools/lib/bpf/xsk.c +++ b/tools/lib/bpf/xsk.c @@ -261,8 +261,8 @@ int xsk_umem__create_v0_0_2(struct xsk_umem **umem_ptr, void *umem_area, return xsk_umem__create_v0_0_4(umem_ptr, umem_area, size, fill, comp, &config); } -asm(".symver xsk_umem__create_v0_0_2, xsk_umem__create@LIBBPF_0.0.2"); -asm(".symver xsk_umem__create_v0_0_4, xsk_umem__create@@LIBBPF_0.0.4"); +COMPAT_VERSION(xsk_umem__create_v0_0_2, xsk_umem__create, LIBBPF_0.0.2) +DEFAULT_VERSION(xsk_umem__create_v0_0_4, xsk_umem__create, LIBBPF_0.0.4) static int xsk_load_xdp_prog(struct xsk_socket *xsk) { -- cgit v1.2.3-59-g8ed1b From 17eac6c2db8b2cdfe33d40229bdda2acd86b304a Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Thu, 26 Sep 2019 16:40:14 -0600 Subject: selftests: Add kselftest-all and kselftest-install targets Add kselftest-all target to build tests from the top level Makefile. This is to simplify kselftest use-cases for CI and distributions where build and test systems are different. Current kselftest target builds and runs tests on a development system which is a developer use-case. Add kselftest-install target to install tests from the top level Makefile. This is to simplify kselftest use-cases for CI and distributions where build and test systems are different. This change addresses requests from developers and testers to add support for installing kselftest from the main Makefile. In addition, make the install directory the same when install is run using "make kselftest-install" or by running kselftest_install.sh. Also fix the INSTALL_PATH variable conflict between main Makefile and selftests Makefile. Signed-off-by: Shuah Khan Acked-by: Masahiro Yamada Signed-off-by: Shuah Khan --- Makefile | 5 ++--- tools/testing/selftests/Makefile | 8 ++++++-- tools/testing/selftests/kselftest_install.sh | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/Makefile b/Makefile index 6f54f2f95743..02f7ede2f344 100644 --- a/Makefile +++ b/Makefile @@ -1237,9 +1237,8 @@ PHONY += kselftest kselftest: $(Q)$(MAKE) -C $(srctree)/tools/testing/selftests run_tests -PHONY += kselftest-clean -kselftest-clean: - $(Q)$(MAKE) -C $(srctree)/tools/testing/selftests clean +kselftest-%: FORCE + $(Q)$(MAKE) -C $(srctree)/tools/testing/selftests $* PHONY += kselftest-merge kselftest-merge: diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index c3feccb99ff5..bad18145ed1a 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -171,9 +171,12 @@ run_pstore_crash: # 1. output_dir=kernel_src # 2. a separate output directory is specified using O= KBUILD_OUTPUT # 3. a separate output directory is specified using KBUILD_OUTPUT +# Avoid conflict with INSTALL_PATH set by the main Makefile # -INSTALL_PATH ?= $(BUILD)/install -INSTALL_PATH := $(abspath $(INSTALL_PATH)) +KSFT_INSTALL_PATH ?= $(BUILD)/kselftest_install +KSFT_INSTALL_PATH := $(abspath $(KSFT_INSTALL_PATH)) +# Avoid changing the rest of the logic here and lib.mk. +INSTALL_PATH := $(KSFT_INSTALL_PATH) ALL_SCRIPT := $(INSTALL_PATH)/run_kselftest.sh install: all @@ -203,6 +206,7 @@ ifdef INSTALL_PATH echo "[ -w /dev/kmsg ] && echo \"kselftest: Running tests in $$TARGET\" >> /dev/kmsg" >> $(ALL_SCRIPT); \ echo "cd $$TARGET" >> $(ALL_SCRIPT); \ echo -n "run_many" >> $(ALL_SCRIPT); \ + echo -n "Emit Tests for $$TARGET\n"; \ $(MAKE) -s --no-print-directory OUTPUT=$$BUILD_TARGET -C $$TARGET emit_tests >> $(ALL_SCRIPT); \ echo "" >> $(ALL_SCRIPT); \ echo "cd \$$ROOT" >> $(ALL_SCRIPT); \ diff --git a/tools/testing/selftests/kselftest_install.sh b/tools/testing/selftests/kselftest_install.sh index ec304463883c..e2e1911d62d5 100755 --- a/tools/testing/selftests/kselftest_install.sh +++ b/tools/testing/selftests/kselftest_install.sh @@ -24,12 +24,12 @@ main() echo "$0: Installing in specified location - $install_loc ..." fi - install_dir=$install_loc/kselftest + install_dir=$install_loc/kselftest_install # Create install directory mkdir -p $install_dir # Build tests - INSTALL_PATH=$install_dir make install + KSFT_INSTALL_PATH=$install_dir make install } main "$@" -- cgit v1.2.3-59-g8ed1b From 3a24f7f6b610910ee328df11392e21925cefdecb Mon Sep 17 00:00:00 2001 From: Cristian Marussi Date: Thu, 26 Sep 2019 18:52:18 +0100 Subject: kselftest: add capability to skip chosen TARGETS Let the user specify an optional TARGETS skiplist through the new optional SKIP_TARGETS Makefile variable. It is easier to skip at will using a reduced and well defined list of possibly problematic targets with SKIP_TARGETS than to provide a partially stripped down list of good targets using the usual TARGETS variable. Signed-off-by: Cristian Marussi Signed-off-by: Shuah Khan --- Documentation/dev-tools/kselftest.rst | 16 ++++++++++++++++ tools/testing/selftests/Makefile | 7 +++++++ 2 files changed, 23 insertions(+) (limited to 'tools') diff --git a/Documentation/dev-tools/kselftest.rst b/Documentation/dev-tools/kselftest.rst index 25604904fa6e..ecdfdc9d4b03 100644 --- a/Documentation/dev-tools/kselftest.rst +++ b/Documentation/dev-tools/kselftest.rst @@ -89,6 +89,22 @@ To build, save output files in a separate directory with KBUILD_OUTPUT :: $ export KBUILD_OUTPUT=/tmp/kselftest; make TARGETS="size timers" kselftest +Additionally you can use the "SKIP_TARGETS" variable on the make command +line to specify one or more targets to exclude from the TARGETS list. + +To run all tests but a single subsystem:: + + $ make -C tools/testing/selftests SKIP_TARGETS=ptrace run_tests + +You can specify multiple tests to skip:: + + $ make SKIP_TARGETS="size timers" kselftest + +You can also specify a restricted list of tests to run together with a +dedicated skiplist:: + + $ make TARGETS="bpf breakpoints size timers" SKIP_TARGETS=bpf kselftest + See the top-level tools/testing/selftests/Makefile for the list of all possible targets. diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index bad18145ed1a..e08f26ca4071 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -63,6 +63,13 @@ TARGETS += zram TARGETS_HOTPLUG = cpu-hotplug TARGETS_HOTPLUG += memory-hotplug +# User can optionally provide a TARGETS skiplist. +SKIP_TARGETS ?= +ifneq ($(SKIP_TARGETS),) + TMP := $(filter-out $(SKIP_TARGETS), $(TARGETS)) + override TARGETS := $(TMP) +endif + # Clear LDFLAGS and MAKEFLAGS if called from main # Makefile to avoid test build failures when test # Makefile doesn't have explicit build rules. -- cgit v1.2.3-59-g8ed1b From 131b30c94fbc0adb15f911609884dd39dada8f00 Mon Sep 17 00:00:00 2001 From: Cristian Marussi Date: Thu, 26 Sep 2019 18:52:19 +0100 Subject: kselftest: exclude failed TARGETS from runlist A TARGET which failed to be built/installed should not be included in the runlist generated inside the run_kselftest.sh script. Signed-off-by: Cristian Marussi Signed-off-by: Shuah Khan --- tools/testing/selftests/Makefile | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index e08f26ca4071..4cdbae6f4e61 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -208,8 +208,12 @@ ifdef INSTALL_PATH echo " cat /dev/null > \$$logfile" >> $(ALL_SCRIPT) echo "fi" >> $(ALL_SCRIPT) + @# While building run_kselftest.sh skip also non-existent TARGET dirs: + @# they could be the result of a build failure and should NOT be + @# included in the generated runlist. for TARGET in $(TARGETS); do \ BUILD_TARGET=$$BUILD/$$TARGET; \ + [ ! -d $$INSTALL_PATH/$$TARGET ] && echo "Skipping non-existent dir: $$TARGET" && continue; \ echo "[ -w /dev/kmsg ] && echo \"kselftest: Running tests in $$TARGET\" >> /dev/kmsg" >> $(ALL_SCRIPT); \ echo "cd $$TARGET" >> $(ALL_SCRIPT); \ echo -n "run_many" >> $(ALL_SCRIPT); \ -- cgit v1.2.3-59-g8ed1b From 852c8cbf34d3b3130a05c38064dd98614f97d3a8 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 19 Sep 2019 11:06:44 -0700 Subject: selftests/kselftest/runner.sh: Add 45 second timeout per test Commit a745f7af3cbd ("selftests/harness: Add 30 second timeout per test") solves the problem of kselftest_harness.h-using binary tests possibly hanging forever. However, scripts and other binaries can still hang forever. This adds a global timeout to each test script run. To make this configurable (e.g. as needed in the "rtc" test case), include a new per-test-directory "settings" file (similar to "config") that can contain kselftest-specific settings. The first recognized field is "timeout". Additionally, this splits the reporting for timeouts into a specific "TIMEOUT" not-ok (and adds exit code reporting in the remaining case). Signed-off-by: Kees Cook Signed-off-by: Shuah Khan --- tools/testing/selftests/kselftest/runner.sh | 36 ++++++++++++++++++++++++++--- tools/testing/selftests/rtc/settings | 1 + 2 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 tools/testing/selftests/rtc/settings (limited to 'tools') diff --git a/tools/testing/selftests/kselftest/runner.sh b/tools/testing/selftests/kselftest/runner.sh index 00c9020bdda8..84de7bc74f2c 100644 --- a/tools/testing/selftests/kselftest/runner.sh +++ b/tools/testing/selftests/kselftest/runner.sh @@ -3,9 +3,14 @@ # # Runs a set of tests in a given subdirectory. export skip_rc=4 +export timeout_rc=124 export logfile=/dev/stdout export per_test_logging= +# Defaults for "settings" file fields: +# "timeout" how many seconds to let each test run before failing. +export kselftest_default_timeout=45 + # There isn't a shell-agnostic way to find the path of a sourced file, # so we must rely on BASE_DIR being set to find other tools. if [ -z "$BASE_DIR" ]; then @@ -24,6 +29,16 @@ tap_prefix() fi } +tap_timeout() +{ + # Make sure tests will time out if utility is available. + if [ -x /usr/bin/timeout ] ; then + /usr/bin/timeout "$kselftest_timeout" "$1" + else + "$1" + fi +} + run_one() { DIR="$1" @@ -32,6 +47,18 @@ run_one() BASENAME_TEST=$(basename $TEST) + # Reset any "settings"-file variables. + export kselftest_timeout="$kselftest_default_timeout" + # Load per-test-directory kselftest "settings" file. + settings="$BASE_DIR/$DIR/settings" + if [ -r "$settings" ] ; then + while read line ; do + field=$(echo "$line" | cut -d= -f1) + value=$(echo "$line" | cut -d= -f2-) + eval "kselftest_$field"="$value" + done < "$settings" + fi + TEST_HDR_MSG="selftests: $DIR: $BASENAME_TEST" echo "# $TEST_HDR_MSG" if [ ! -x "$TEST" ]; then @@ -44,14 +71,17 @@ run_one() echo "not ok $test_num $TEST_HDR_MSG" else cd `dirname $TEST` > /dev/null - (((((./$BASENAME_TEST 2>&1; echo $? >&3) | + ((((( tap_timeout ./$BASENAME_TEST 2>&1; echo $? >&3) | tap_prefix >&4) 3>&1) | (read xs; exit $xs)) 4>>"$logfile" && echo "ok $test_num $TEST_HDR_MSG") || - (if [ $? -eq $skip_rc ]; then \ + (rc=$?; \ + if [ $rc -eq $skip_rc ]; then \ echo "not ok $test_num $TEST_HDR_MSG # SKIP" + elif [ $rc -eq $timeout_rc ]; then \ + echo "not ok $test_num $TEST_HDR_MSG # TIMEOUT" else - echo "not ok $test_num $TEST_HDR_MSG" + echo "not ok $test_num $TEST_HDR_MSG # exit=$rc" fi) cd - >/dev/null fi diff --git a/tools/testing/selftests/rtc/settings b/tools/testing/selftests/rtc/settings new file mode 100644 index 000000000000..ba4d85f74cd6 --- /dev/null +++ b/tools/testing/selftests/rtc/settings @@ -0,0 +1 @@ +timeout=90 -- cgit v1.2.3-59-g8ed1b From 86c1aea84b97120a6d428ce17a2ebd55be677f56 Mon Sep 17 00:00:00 2001 From: Brian Vazquez Date: Tue, 1 Oct 2019 10:37:27 -0700 Subject: selftests/bpf: test_progs: Don't leak server_fd in tcp_rtt server_fd needs to be closed if pthread can't be created. Fixes: 8a03222f508b ("selftests/bpf: test_progs: fix client/server race in tcp_rtt") Signed-off-by: Brian Vazquez Signed-off-by: Daniel Borkmann Reviewed-by: Stanislav Fomichev Link: https://lore.kernel.org/bpf/20191001173728.149786-2-brianvv@google.com --- tools/testing/selftests/bpf/prog_tests/tcp_rtt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c b/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c index a82da555b1b0..f4cd60d6fba2 100644 --- a/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c +++ b/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c @@ -260,13 +260,14 @@ void test_tcp_rtt(void) if (CHECK_FAIL(pthread_create(&tid, NULL, server_thread, (void *)&server_fd))) - goto close_cgroup_fd; + goto close_server_fd; pthread_mutex_lock(&server_started_mtx); pthread_cond_wait(&server_started, &server_started_mtx); pthread_mutex_unlock(&server_started_mtx); CHECK_FAIL(run_test(cgroup_fd, server_fd)); +close_server_fd: close(server_fd); close_cgroup_fd: close(cgroup_fd); -- cgit v1.2.3-59-g8ed1b From a2d074e4c6e81ec9ab359d54f0b88273c738de37 Mon Sep 17 00:00:00 2001 From: Brian Vazquez Date: Tue, 1 Oct 2019 10:37:28 -0700 Subject: selftests/bpf: test_progs: Don't leak server_fd in test_sockopt_inherit server_fd needs to be closed if pthread can't be created. Fixes: e3e02e1d9c24 ("selftests/bpf: test_progs: convert test_sockopt_inherit") Signed-off-by: Brian Vazquez Signed-off-by: Daniel Borkmann Reviewed-by: Stanislav Fomichev Link: https://lore.kernel.org/bpf/20191001173728.149786-3-brianvv@google.com --- tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c b/tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c index 6cbeea7b4bf1..8547ecbdc61f 100644 --- a/tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c +++ b/tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c @@ -195,7 +195,7 @@ static void run_test(int cgroup_fd) if (CHECK_FAIL(pthread_create(&tid, NULL, server_thread, (void *)&server_fd))) - goto close_bpf_object; + goto close_server_fd; pthread_mutex_lock(&server_started_mtx); pthread_cond_wait(&server_started, &server_started_mtx); -- cgit v1.2.3-59-g8ed1b From 8f9577eda5b74de4bd8b186c67f20736bdea6e07 Mon Sep 17 00:00:00 2001 From: "George G. Davis" Date: Tue, 17 Sep 2019 20:40:22 +0200 Subject: selftests: watchdog: Validate optional file argument The newly added optional file argument does not validate if the file is indeed a watchdog, e.g.: ./watchdog-test -f /dev/zero Watchdog Ticking Away! Fix it by confirming that the WDIOC_GETSUPPORT ioctl succeeds. Fixes: a4864a33f56caa ("selftests: watchdog: Add optional file argument") Reported-by: Eugeniu Rosca Signed-off-by: George G. Davis Signed-off-by: Eugeniu Rosca Signed-off-by: Shuah Khan --- tools/testing/selftests/watchdog/watchdog-test.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/watchdog/watchdog-test.c b/tools/testing/selftests/watchdog/watchdog-test.c index afff120c7be6..6ed822dc2222 100644 --- a/tools/testing/selftests/watchdog/watchdog-test.c +++ b/tools/testing/selftests/watchdog/watchdog-test.c @@ -97,6 +97,7 @@ int main(int argc, char *argv[]) int c; int oneshot = 0; char *file = "/dev/watchdog"; + struct watchdog_info info; setbuf(stdout, NULL); @@ -118,6 +119,16 @@ int main(int argc, char *argv[]) exit(-1); } + /* + * Validate that `file` is a watchdog device + */ + ret = ioctl(fd, WDIOC_GETSUPPORT, &info); + if (ret) { + printf("WDIOC_GETSUPPORT error '%s'\n", strerror(errno)); + close(fd); + exit(ret); + } + optind = 0; while ((c = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) { -- cgit v1.2.3-59-g8ed1b From ce3a677802121e038d2f062e90f96f84e7351da0 Mon Sep 17 00:00:00 2001 From: "George G. Davis" Date: Tue, 17 Sep 2019 20:40:23 +0200 Subject: selftests: watchdog: Add command line option to show watchdog_info With the new ioctl(WDIOC_GETSUPPORT) call in place, add a command line option to show the watchdog_info. Suggested-by: Eugeniu Rosca Signed-off-by: George G. Davis Signed-off-by: Eugeniu Rosca Signed-off-by: Shuah Khan --- tools/testing/selftests/watchdog/watchdog-test.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/watchdog/watchdog-test.c b/tools/testing/selftests/watchdog/watchdog-test.c index 6ed822dc2222..f45e510500c0 100644 --- a/tools/testing/selftests/watchdog/watchdog-test.c +++ b/tools/testing/selftests/watchdog/watchdog-test.c @@ -19,7 +19,7 @@ int fd; const char v = 'V'; -static const char sopts[] = "bdehp:t:Tn:NLf:"; +static const char sopts[] = "bdehp:t:Tn:NLf:i"; static const struct option lopts[] = { {"bootstatus", no_argument, NULL, 'b'}, {"disable", no_argument, NULL, 'd'}, @@ -32,6 +32,7 @@ static const struct option lopts[] = { {"getpretimeout", no_argument, NULL, 'N'}, {"gettimeleft", no_argument, NULL, 'L'}, {"file", required_argument, NULL, 'f'}, + {"info", no_argument, NULL, 'i'}, {NULL, no_argument, NULL, 0x0} }; @@ -72,6 +73,7 @@ static void usage(char *progname) printf("Usage: %s [options]\n", progname); printf(" -f, --file\t\tOpen watchdog device file\n"); printf("\t\t\tDefault is /dev/watchdog\n"); + printf(" -i, --info\t\tShow watchdog_info\n"); printf(" -b, --bootstatus\tGet last boot status (Watchdog/POR)\n"); printf(" -d, --disable\t\tTurn off the watchdog timer\n"); printf(" -e, --enable\t\tTurn on the watchdog timer\n"); @@ -216,6 +218,18 @@ int main(int argc, char *argv[]) case 'f': /* Handled above */ break; + case 'i': + /* + * watchdog_info was obtained as part of file open + * validation. So we just show it here. + */ + oneshot = 1; + printf("watchdog_info:\n"); + printf(" identity:\t\t%s\n", info.identity); + printf(" firmware_version:\t%u\n", + info.firmware_version); + printf(" options:\t\t%08x\n", info.options); + break; default: usage(argv[0]); -- cgit v1.2.3-59-g8ed1b From 6e06983dde969c15eb4fdab77f0eda8b18ea28e6 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Wed, 2 Oct 2019 17:14:30 -0600 Subject: selftests: kvm: Fix libkvm build error Fix the following build error from "make TARGETS=kvm kselftest": libkvm.a(assert.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a PIE object; recompile with -fPIC This error is seen when build is done from the main Makefile using kselftest target. In this case KBUILD_CPPFLAGS and CC_OPTION_CFLAGS are defined. When build is invoked using: "make -C tools/testing/selftests/kvm" KBUILD_CPPFLAGS and CC_OPTION_CFLAGS aren't defined. There is no need to pass in KBUILD_CPPFLAGS and CC_OPTION_CFLAGS for the check to determine if --no-pie is necessary, which is the case when these two aren't defined when "make -C tools/testing/selftests/kvm" runs. Fix it by simplifying the no-pie-option logic. With this change, both build variations work. "make TARGETS=kvm kselftest" "make -C tools/testing/selftests/kvm" Signed-off-by: Shuah Khan Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index fd84b7a78dcf..c5ec868fa1e5 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -49,7 +49,7 @@ CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \ -I$(LINUX_HDR_PATH) -Iinclude -I$( Date: Wed, 2 Oct 2019 13:29:23 -0400 Subject: udp: only do GSO if # of segs > 1 Prior to this change an application sending <= 1MSS worth of data and enabling UDP GSO would fail if the system had SW GSO enabled, but the same send would succeed if HW GSO offload is enabled. In addition to this inconsistency the error in the SW GSO case does not get back to the application if sending out of a real device so the user is unaware of this failure. With this change we only perform GSO if the # of segments is > 1 even if the application has enabled segmentation. I've also updated the relevant udpgso selftests. Fixes: bec1f6f69736 ("udp: generate gso with UDP_SEGMENT") Signed-off-by: Josh Hunt Reviewed-by: Willem de Bruijn Reviewed-by: Alexander Duyck Signed-off-by: David S. Miller --- net/ipv4/udp.c | 11 +++++++---- net/ipv6/udp.c | 11 +++++++---- tools/testing/selftests/net/udpgso.c | 16 ++++------------ 3 files changed, 18 insertions(+), 20 deletions(-) (limited to 'tools') diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 3e2b90181879..14bc654b6842 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -821,6 +821,7 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4, int is_udplite = IS_UDPLITE(sk); int offset = skb_transport_offset(skb); int len = skb->len - offset; + int datalen = len - sizeof(*uh); __wsum csum = 0; /* @@ -854,10 +855,12 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4, return -EIO; } - skb_shinfo(skb)->gso_size = cork->gso_size; - skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4; - skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(len - sizeof(*uh), - cork->gso_size); + if (datalen > cork->gso_size) { + skb_shinfo(skb)->gso_size = cork->gso_size; + skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4; + skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(datalen, + cork->gso_size); + } goto csum_partial; } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index eb9a9934ac05..6324d3a8cb53 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1109,6 +1109,7 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6, __wsum csum = 0; int offset = skb_transport_offset(skb); int len = skb->len - offset; + int datalen = len - sizeof(*uh); /* * Create a UDP header @@ -1141,10 +1142,12 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6, return -EIO; } - skb_shinfo(skb)->gso_size = cork->gso_size; - skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4; - skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(len - sizeof(*uh), - cork->gso_size); + if (datalen > cork->gso_size) { + skb_shinfo(skb)->gso_size = cork->gso_size; + skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4; + skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(datalen, + cork->gso_size); + } goto csum_partial; } diff --git a/tools/testing/selftests/net/udpgso.c b/tools/testing/selftests/net/udpgso.c index b8265ee9923f..614b31aad168 100644 --- a/tools/testing/selftests/net/udpgso.c +++ b/tools/testing/selftests/net/udpgso.c @@ -89,12 +89,9 @@ struct testcase testcases_v4[] = { .tfail = true, }, { - /* send a single MSS: will fail with GSO, because the segment - * logic in udp4_ufo_fragment demands a gso skb to be > MTU - */ + /* send a single MSS: will fall back to no GSO */ .tlen = CONST_MSS_V4, .gso_len = CONST_MSS_V4, - .tfail = true, .r_num_mss = 1, }, { @@ -139,10 +136,9 @@ struct testcase testcases_v4[] = { .tfail = true, }, { - /* send a single 1B MSS: will fail, see single MSS above */ + /* send a single 1B MSS: will fall back to no GSO */ .tlen = 1, .gso_len = 1, - .tfail = true, .r_num_mss = 1, }, { @@ -196,12 +192,9 @@ struct testcase testcases_v6[] = { .tfail = true, }, { - /* send a single MSS: will fail with GSO, because the segment - * logic in udp4_ufo_fragment demands a gso skb to be > MTU - */ + /* send a single MSS: will fall back to no GSO */ .tlen = CONST_MSS_V6, .gso_len = CONST_MSS_V6, - .tfail = true, .r_num_mss = 1, }, { @@ -246,10 +239,9 @@ struct testcase testcases_v6[] = { .tfail = true, }, { - /* send a single 1B MSS: will fail, see single MSS above */ + /* send a single 1B MSS: will fall back to no GSO */ .tlen = 1, .gso_len = 1, - .tfail = true, .r_num_mss = 1, }, { -- cgit v1.2.3-59-g8ed1b From ef129d34149ea23d0d442844fc25ae26a85589fc Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 4 Oct 2019 17:36:50 -0700 Subject: selftests/net: add nettest to .gitignore nettest is missing from gitignore. Fixes: acda655fefae ("selftests: Add nettest") Signed-off-by: Jakub Kicinski Signed-off-by: David S. Miller --- tools/testing/selftests/net/.gitignore | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/testing/selftests/net/.gitignore b/tools/testing/selftests/net/.gitignore index c7cced739c34..8aefd81fbc86 100644 --- a/tools/testing/selftests/net/.gitignore +++ b/tools/testing/selftests/net/.gitignore @@ -21,3 +21,4 @@ ipv6_flowlabel ipv6_flowlabel_mgr so_txtime tcp_fastopen_backup_key +nettest -- cgit v1.2.3-59-g8ed1b From fd418b01fe26c2430b1091675cceb3ab2b52e1e0 Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Tue, 8 Oct 2019 15:10:44 +0200 Subject: selftests/bpf: Set rp_filter in test_flow_dissector Many distributions enable rp_filter. However, the flow dissector test generates packets that have 1.1.1.1 set as (inner) source address without this address being reachable. This causes the selftest to fail. The selftests should not assume a particular initial configuration. Switch off rp_filter. Fixes: 50b3ed57dee9 ("selftests/bpf: test bpf flow dissection") Signed-off-by: Jiri Benc Signed-off-by: Daniel Borkmann Acked-by: Petar Penkov Link: https://lore.kernel.org/bpf/513a298f53e99561d2f70b2e60e2858ea6cda754.1570539863.git.jbenc@redhat.com --- tools/testing/selftests/bpf/test_flow_dissector.sh | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_flow_dissector.sh b/tools/testing/selftests/bpf/test_flow_dissector.sh index d23d4da66b83..e2d06191bd35 100755 --- a/tools/testing/selftests/bpf/test_flow_dissector.sh +++ b/tools/testing/selftests/bpf/test_flow_dissector.sh @@ -63,6 +63,9 @@ fi # Setup tc qdisc add dev lo ingress +echo 0 > /proc/sys/net/ipv4/conf/default/rp_filter +echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter +echo 0 > /proc/sys/net/ipv4/conf/lo/rp_filter echo "Testing IPv4..." # Drops all IP/UDP packets coming from port 9 -- cgit v1.2.3-59-g8ed1b From 106c35dda32f8b63f88cad7433f1b8bb0056958a Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Tue, 8 Oct 2019 15:10:45 +0200 Subject: selftests/bpf: More compatible nc options in test_lwt_ip_encap Out of the three nc implementations widely in use, at least two (BSD netcat and nmap-ncat) do not support -l combined with -s. Modify the nc invocation to be accepted by all of them. Fixes: 17a90a788473 ("selftests/bpf: test that GSO works in lwt_ip_encap") Signed-off-by: Jiri Benc Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/9f177682c387f3f943bb64d849e6c6774df3c5b4.1570539863.git.jbenc@redhat.com --- tools/testing/selftests/bpf/test_lwt_ip_encap.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_lwt_ip_encap.sh b/tools/testing/selftests/bpf/test_lwt_ip_encap.sh index acf7a74f97cd..59ea56945e6c 100755 --- a/tools/testing/selftests/bpf/test_lwt_ip_encap.sh +++ b/tools/testing/selftests/bpf/test_lwt_ip_encap.sh @@ -314,15 +314,15 @@ test_gso() command -v nc >/dev/null 2>&1 || \ { echo >&2 "nc is not available: skipping TSO tests"; return; } - # listen on IPv*_DST, capture TCP into $TMPFILE + # listen on port 9000, capture TCP into $TMPFILE if [ "${PROTO}" == "IPv4" ] ; then IP_DST=${IPv4_DST} ip netns exec ${NS3} bash -c \ - "nc -4 -l -s ${IPv4_DST} -p 9000 > ${TMPFILE} &" + "nc -4 -l -p 9000 > ${TMPFILE} &" elif [ "${PROTO}" == "IPv6" ] ; then IP_DST=${IPv6_DST} ip netns exec ${NS3} bash -c \ - "nc -6 -l -s ${IPv6_DST} -p 9000 > ${TMPFILE} &" + "nc -6 -l -p 9000 > ${TMPFILE} &" RET=$? else echo " test_gso: unknown PROTO: ${PROTO}" -- cgit v1.2.3-59-g8ed1b From 5b216ea1c40cf06eead15054c70e238c9bd4729e Mon Sep 17 00:00:00 2001 From: "Desnes A. Nunes do Rosario" Date: Thu, 3 Oct 2019 18:10:10 -0300 Subject: selftests/powerpc: Fix compile error on tlbie_test due to newer gcc Newer versions of GCC (>= 9) demand that the size of the string to be copied must be explicitly smaller than the size of the destination. Thus, the NULL char has to be taken into account on strncpy. This will avoid the following compiling error: tlbie_test.c: In function 'main': tlbie_test.c:639:4: error: 'strncpy' specified bound 100 equals destination size strncpy(logdir, optarg, LOGDIR_NAME_SIZE); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors Signed-off-by: Desnes A. Nunes do Rosario Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20191003211010.9711-1-desnesn@linux.ibm.com --- tools/testing/selftests/powerpc/mm/tlbie_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/mm/tlbie_test.c b/tools/testing/selftests/powerpc/mm/tlbie_test.c index 9868a5ddd847..f85a0938ab25 100644 --- a/tools/testing/selftests/powerpc/mm/tlbie_test.c +++ b/tools/testing/selftests/powerpc/mm/tlbie_test.c @@ -636,7 +636,7 @@ int main(int argc, char *argv[]) nrthreads = strtoul(optarg, NULL, 10); break; case 'l': - strncpy(logdir, optarg, LOGDIR_NAME_SIZE); + strncpy(logdir, optarg, LOGDIR_NAME_SIZE - 1); break; case 't': run_time = strtoul(optarg, NULL, 10); -- cgit v1.2.3-59-g8ed1b From c461e8df0c9bc46b3696dfb5d1df2f09d755af53 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 26 Sep 2019 13:43:10 -0400 Subject: tools/virtio: more stubs fix test module build. Signed-off-by: Michael S. Tsirkin --- tools/virtio/crypto/hash.h | 0 tools/virtio/linux/dma-mapping.h | 2 ++ 2 files changed, 2 insertions(+) create mode 100644 tools/virtio/crypto/hash.h (limited to 'tools') diff --git a/tools/virtio/crypto/hash.h b/tools/virtio/crypto/hash.h new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tools/virtio/linux/dma-mapping.h b/tools/virtio/linux/dma-mapping.h index f91aeb5fe571..8f41cd6bd5c0 100644 --- a/tools/virtio/linux/dma-mapping.h +++ b/tools/virtio/linux/dma-mapping.h @@ -29,4 +29,6 @@ enum dma_data_direction { #define dma_unmap_single(...) do { } while (0) #define dma_unmap_page(...) do { } while (0) +#define dma_max_mapping_size(...) SIZE_MAX + #endif -- cgit v1.2.3-59-g8ed1b From edc5774c097f6463e9fb2373832e7db726247809 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 13 Oct 2019 09:37:16 -0400 Subject: tools/virtio: xen stub Fixes test module build. Reported-by: Jan Kiszka Signed-off-by: Michael S. Tsirkin --- tools/virtio/xen/xen.h | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 tools/virtio/xen/xen.h (limited to 'tools') diff --git a/tools/virtio/xen/xen.h b/tools/virtio/xen/xen.h new file mode 100644 index 000000000000..f569387d1403 --- /dev/null +++ b/tools/virtio/xen/xen.h @@ -0,0 +1,6 @@ +#ifndef XEN_XEN_STUB_H +#define XEN_XEN_STUB_H + +#define xen_domain() 0 + +#endif -- cgit v1.2.3-59-g8ed1b From 6a6fac11b11299aa5bd8532ea863fc2f652af2b6 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Tue, 8 Oct 2019 11:38:41 +0200 Subject: perf jvmti: Link against tools/lib/ctype.h to have weak strlcpy() The build of file libperf-jvmti.so succeeds but the resulting object fails to load: # ~/linux/tools/perf/perf record -k mono -- java \ -XX:+PreserveFramePointer \ -agentpath:/root/linux/tools/perf/libperf-jvmti.so \ hog 100000 123450 Error occurred during initialization of VM Could not find agent library /root/linux/tools/perf/libperf-jvmti.so in absolute path, with error: /root/linux/tools/perf/libperf-jvmti.so: undefined symbol: _ctype Add the missing _ctype symbol into the build script. Fixes: 79743bc927f6 ("perf jvmti: Link against tools/lib/string.o to have weak strlcpy()") Signed-off-by: Thomas Richter Cc: Heiko Carstens Cc: Vasily Gorbik Link: http://lore.kernel.org/lkml/20191008093841.59387-1-tmricht@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/jvmti/Build | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/jvmti/Build b/tools/perf/jvmti/Build index 1e148bbdf820..202cadaaf097 100644 --- a/tools/perf/jvmti/Build +++ b/tools/perf/jvmti/Build @@ -2,7 +2,7 @@ jvmti-y += libjvmti.o jvmti-y += jvmti_agent.o # For strlcpy -jvmti-y += libstring.o +jvmti-y += libstring.o libctype.o CFLAGS_jvmti = -fPIC -DPIC -I$(JDIR)/include -I$(JDIR)/include/linux CFLAGS_REMOVE_jvmti = -Wmissing-declarations @@ -15,3 +15,7 @@ CFLAGS_libstring.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PE $(OUTPUT)jvmti/libstring.o: ../lib/string.c FORCE $(call rule_mkdir) $(call if_changed_dep,cc_o_c) + +$(OUTPUT)jvmti/libctype.o: ../lib/ctype.c FORCE + $(call rule_mkdir) + $(call if_changed_dep,cc_o_c) -- cgit v1.2.3-59-g8ed1b From 98a8b2e60c69927b1f405c3b001a1de3f4e53901 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 11 Oct 2019 11:21:40 -0700 Subject: perf evlist: Fix fix for freed id arrays In the earlier fix for the memory overrun of id arrays I managed to typo the wrong event in the fix. Of course we need to close the current event in the loop, not the original failing event. The same test case as in the original patch still passes. Fixes: 7834fa948beb ("perf evlist: Fix access of freed id arrays") Signed-off-by: Andi Kleen Cc: Jiri Olsa Link: http://lore.kernel.org/lkml/20191011182140.8353-2-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index d277a98e62df..de79c735e441 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1659,7 +1659,7 @@ struct evsel *perf_evlist__reset_weak_group(struct evlist *evsel_list, is_open = false; if (c2->leader == leader) { if (is_open) - perf_evsel__close(&evsel->core); + perf_evsel__close(&c2->core); c2->leader = c2; c2->core.nr_members = 0; } -- cgit v1.2.3-59-g8ed1b From 6080728ff8e9c9116e52e6f840152356ac2fea56 Mon Sep 17 00:00:00 2001 From: Yunfeng Ye Date: Tue, 15 Oct 2019 16:30:08 +0800 Subject: perf tools: Fix resource leak of closedir() on the error paths Both build_mem_topology() and rm_rf_depth_pat() have resource leaks of closedir() on the error paths. Fix this by calling closedir() before function returns. Fixes: e2091cedd51b ("perf tools: Add MEM_TOPOLOGY feature to perf data file") Fixes: cdb6b0235f17 ("perf tools: Add pattern name checking to rm_rf") Signed-off-by: Yunfeng Ye Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Alexey Budankov Cc: Andi Kleen Cc: Daniel Borkmann Cc: Feilong Lin Cc: Hu Shiyuan Cc: Igor Lubashev Cc: Kan Liang Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Song Liu Cc: Yonghong Song Link: http://lore.kernel.org/lkml/cd5f7cd2-b80d-6add-20a1-32f4f43e0744@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/header.c | 4 +++- tools/perf/util/util.c | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 86d9396cb131..becc2d109423 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1296,8 +1296,10 @@ static int build_mem_topology(struct memory_node *nodes, u64 size, u64 *cntp) continue; if (WARN_ONCE(cnt >= size, - "failed to write MEM_TOPOLOGY, way too many nodes\n")) + "failed to write MEM_TOPOLOGY, way too many nodes\n")) { + closedir(dir); return -1; + } ret = memory_node__read(&nodes[cnt++], idx); } diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 5eda6e19c947..ae56c766eda1 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -154,8 +154,10 @@ static int rm_rf_depth_pat(const char *path, int depth, const char **pat) if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) continue; - if (!match_pat(d->d_name, pat)) - return -2; + if (!match_pat(d->d_name, pat)) { + ret = -2; + break; + } scnprintf(namebuf, sizeof(namebuf), "%s/%s", path, d->d_name); -- cgit v1.2.3-59-g8ed1b From f948eb45e3af9fb18a0487d0797a773897ef6929 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Mon, 14 Oct 2019 12:10:47 -0500 Subject: perf annotate: Fix multiple memory and file descriptor leaks Store SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF in variable *ret*, instead of returning in the middle of the function and leaking multiple resources: prog_linfo, btf, s and bfdf. Addresses-Coverity-ID: 1454832 ("Structurally dead code") Fixes: 11aad897f6d1 ("perf annotate: Don't return -1 for error when doing BPF disassembly") Signed-off-by: Gustavo A. R. Silva Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20191014171047.GA30850@embeddedor Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 4036c7f7b0fb..e42bf572358c 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1758,7 +1758,7 @@ static int symbol__disassemble_bpf(struct symbol *sym, info_node = perf_env__find_bpf_prog_info(dso->bpf_prog.env, dso->bpf_prog.id); if (!info_node) { - return SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF; + ret = SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF; goto out; } info_linear = info_node->info_linear; -- cgit v1.2.3-59-g8ed1b From 5a0baf5123236362fda4e9772cc63b7faa16a0df Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 7 Oct 2019 10:02:21 +0300 Subject: perf tools: Fix mode setting in copyfile_mode_ns() slow_copyfile() opens the file by name, so "write" permissions must not be removed in copyfile_mode_ns() before calling slow_copyfile(). Example: Before: $ sudo chmod +r /proc/kcore $ sudo setcap "cap_sys_admin,cap_sys_ptrace,cap_syslog,cap_sys_rawio=ep" tools/perf/perf $ tools/perf/perf buildid-cache -k /proc/kcore Couldn't add /proc/kcore After: $ sudo chmod +r /proc/kcore $ sudo setcap "cap_sys_admin,cap_sys_ptrace,cap_syslog,cap_sys_rawio=ep" tools/perf/perf $ tools/perf/perf buildid-cache -v -k /proc/kcore kcore added to build-id cache directory /home/ahunter/.debug/[kernel.kcore]/37e340b1b5a7cf4f57ba8de2bc777359588a957f/2019100709562289 Signed-off-by: Adrian Hunter Acked-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Link: http://lore.kernel.org/lkml/20191007070221.11158-1-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/copyfile.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/copyfile.c b/tools/perf/util/copyfile.c index 3fa0db136667..47e03de7c235 100644 --- a/tools/perf/util/copyfile.c +++ b/tools/perf/util/copyfile.c @@ -101,14 +101,16 @@ static int copyfile_mode_ns(const char *from, const char *to, mode_t mode, if (tofd < 0) goto out; - if (fchmod(tofd, mode)) - goto out_close_to; - if (st.st_size == 0) { /* /proc? do it slowly... */ err = slow_copyfile(from, tmp, nsi); + if (!err && fchmod(tofd, mode)) + err = -1; goto out_close_to; } + if (fchmod(tofd, mode)) + goto out_close_to; + nsinfo__mountns_enter(nsi, &nsc); fromfd = open(from, O_RDONLY); nsinfo__mountns_exit(&nsc); -- cgit v1.2.3-59-g8ed1b From ae199c580da1754a2b051321eeb76d6dacd8707b Mon Sep 17 00:00:00 2001 From: Yunfeng Ye Date: Tue, 15 Oct 2019 10:54:14 +0800 Subject: perf c2c: Fix memory leak in build_cl_output() There is a memory leak problem in the failure paths of build_cl_output(), so fix it. Signed-off-by: Yunfeng Ye Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Feilong Lin Cc: Hu Shiyuan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/4d3c0178-5482-c313-98e1-f82090d2d456@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-c2c.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index 3542b6ab9813..e69f44941aad 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -2635,6 +2635,7 @@ static int build_cl_output(char *cl_sort, bool no_source) bool add_sym = false; bool add_dso = false; bool add_src = false; + int ret = 0; if (!buf) return -ENOMEM; @@ -2653,7 +2654,8 @@ static int build_cl_output(char *cl_sort, bool no_source) add_dso = true; } else if (strcmp(tok, "offset")) { pr_err("unrecognized sort token: %s\n", tok); - return -EINVAL; + ret = -EINVAL; + goto err; } } @@ -2676,13 +2678,15 @@ static int build_cl_output(char *cl_sort, bool no_source) add_sym ? "symbol," : "", add_dso ? "dso," : "", add_src ? "cl_srcline," : "", - "node") < 0) - return -ENOMEM; + "node") < 0) { + ret = -ENOMEM; + goto err; + } c2c.show_src = add_src; - +err: free(buf); - return 0; + return ret; } static int setup_coalesce(const char *coalesce, bool no_source) -- cgit v1.2.3-59-g8ed1b From 7a12f514c408cc499e61211f234858d3d4b7f4ea Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 15 Oct 2019 12:22:37 -0300 Subject: tools headers kvm: Sync kvm headers with the kernel sources To pick the changes in: bf653b78f960 ("KVM: vmx: Introduce handle_unexpected_vmexit and handle WAITPKG vmexit") That trigger these changes in tooling: CC /tmp/build/perf/arch/x86/util/kvm-stat.o INSTALL GTK UI DESCEND plugins make[3]: Nothing to be done for '/tmp/build/perf/plugins/libtraceevent-dynamic-list'. INSTALL trace_plugins LD /tmp/build/perf/arch/x86/util/perf-in.o LD /tmp/build/perf/arch/x86/perf-in.o LD /tmp/build/perf/arch/perf-in.o LD /tmp/build/perf/perf-in.o LINK /tmp/build/perf/perf And this is not just because that header is included, kvm-stat.c uses the VMX_EXIT_REASONS define and it got changed by the above cset. And addresses this perf build warnings: Warning: Kernel ABI header at 'tools/arch/x86/include/uapi/asm/vmx.h' differs from latest version at 'arch/x86/include/uapi/asm/vmx.h' diff -u tools/arch/x86/include/uapi/asm/vmx.h arch/x86/include/uapi/asm/vmx.h Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paolo Bonzini Cc: Tao Xu Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-gr1eel0hckmi5l3p2ewdpfxh@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/x86/include/uapi/asm/vmx.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/arch/x86/include/uapi/asm/vmx.h b/tools/arch/x86/include/uapi/asm/vmx.h index f01950aa7fae..3eb8411ab60e 100644 --- a/tools/arch/x86/include/uapi/asm/vmx.h +++ b/tools/arch/x86/include/uapi/asm/vmx.h @@ -86,6 +86,8 @@ #define EXIT_REASON_PML_FULL 62 #define EXIT_REASON_XSAVES 63 #define EXIT_REASON_XRSTORS 64 +#define EXIT_REASON_UMWAIT 67 +#define EXIT_REASON_TPAUSE 68 #define VMX_EXIT_REASONS \ { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, \ @@ -144,7 +146,9 @@ { EXIT_REASON_RDSEED, "RDSEED" }, \ { EXIT_REASON_PML_FULL, "PML_FULL" }, \ { EXIT_REASON_XSAVES, "XSAVES" }, \ - { EXIT_REASON_XRSTORS, "XRSTORS" } + { EXIT_REASON_XRSTORS, "XRSTORS" }, \ + { EXIT_REASON_UMWAIT, "UMWAIT" }, \ + { EXIT_REASON_TPAUSE, "TPAUSE" } #define VMX_ABORT_SAVE_GUEST_MSR_FAIL 1 #define VMX_ABORT_LOAD_HOST_PDPTE_FAIL 2 -- cgit v1.2.3-59-g8ed1b From 7cb3a2445705e45af9b58dd241d26598a35b1fdd Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 15 Oct 2019 12:30:08 -0300 Subject: tools headers kvm: Sync kvm headers with the kernel sources To pick the changes in: 0cb8410b90e7 ("kvm: svm: Intercept RDPRU") That trigger a rebuild in too in tooling: CC /tmp/build/perf/arch/x86/util/kvm-stat.o But this time around no changes in tooling results, as SVM_EXIT_RDPRU wasn't added to SVM_EXIT_REASONS, that is used in kvm-stat.c. And addresses this perf build warnings: Warning: Kernel ABI header at 'tools/arch/x86/include/uapi/asm/svm.h' differs from latest version at 'arch/x86/include/uapi/asm/svm.h' diff -u tools/arch/x86/include/uapi/asm/svm.h arch/x86/include/uapi/asm/svm.h Cc: Adrian Hunter Cc: Jim Mattson Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paolo Bonzini Link: https://lkml.kernel.org/n/tip-pqzkt1hmfpqph3ts8i6zzmim@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/x86/include/uapi/asm/svm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/arch/x86/include/uapi/asm/svm.h b/tools/arch/x86/include/uapi/asm/svm.h index a9731f8a480f..2e8a30f06c74 100644 --- a/tools/arch/x86/include/uapi/asm/svm.h +++ b/tools/arch/x86/include/uapi/asm/svm.h @@ -75,6 +75,7 @@ #define SVM_EXIT_MWAIT 0x08b #define SVM_EXIT_MWAIT_COND 0x08c #define SVM_EXIT_XSETBV 0x08d +#define SVM_EXIT_RDPRU 0x08e #define SVM_EXIT_NPF 0x400 #define SVM_EXIT_AVIC_INCOMPLETE_IPI 0x401 #define SVM_EXIT_AVIC_UNACCELERATED_ACCESS 0x402 -- cgit v1.2.3-59-g8ed1b From 8daf1fb73295b43fb2f624f709449b484532ba64 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 15 Oct 2019 12:35:02 -0300 Subject: tools headers kvm: Sync kvm.h headers with the kernel sources To pick the changes in: 344c6c804703 ("KVM/Hyper-V: Add new KVM capability KVM_CAP_HYPERV_DIRECT_TLBFLUSH") dee04eee9182 ("KVM: RISC-V: Add KVM_REG_RISCV for ONE_REG interface") These trigger the rebuild of this object: CC /tmp/build/perf/trace/beauty/ioctl.o But do not result in any change in tooling, as the additions are not being used in any table generatator. This silences this perf build warning: Warning: Kernel ABI header at 'tools/include/uapi/linux/kvm.h' differs from latest version at 'include/uapi/linux/kvm.h' diff -u tools/include/uapi/linux/kvm.h include/uapi/linux/kvm.h Cc: Adrian Hunter Cc: Anup Patel Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paolo Bonzini Cc: Paul Walmsley Cc: Tianyu Lan Link: https://lkml.kernel.org/n/tip-d1v48a0qfoe98u5v9tn3mu5u@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/linux/kvm.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h index 233efbb1c81c..52641d8ca9e8 100644 --- a/tools/include/uapi/linux/kvm.h +++ b/tools/include/uapi/linux/kvm.h @@ -999,6 +999,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_ARM_PTRAUTH_GENERIC 172 #define KVM_CAP_PMU_EVENT_FILTER 173 #define KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 174 +#define KVM_CAP_HYPERV_DIRECT_TLBFLUSH 175 #ifdef KVM_CAP_IRQ_ROUTING @@ -1145,6 +1146,7 @@ struct kvm_dirty_tlb { #define KVM_REG_S390 0x5000000000000000ULL #define KVM_REG_ARM64 0x6000000000000000ULL #define KVM_REG_MIPS 0x7000000000000000ULL +#define KVM_REG_RISCV 0x8000000000000000ULL #define KVM_REG_SIZE_SHIFT 52 #define KVM_REG_SIZE_MASK 0x00f0000000000000ULL -- cgit v1.2.3-59-g8ed1b From 5eca1379c0eb06e3908179665230a86d19bd2df7 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 15 Oct 2019 12:44:00 -0300 Subject: tools headers UAPI: Sync sched.h with the kernel To get the changes in: 78f6face5af3 ("sched: add kernel-doc for struct clone_args") f14c234b4bc5 ("clone3: switch to copy_struct_from_user()") This file gets rebuilt, but no changes ensues: CC /tmp/build/perf/trace/beauty/clone.o This addresses this perf build warning: Warning: Kernel ABI header at 'tools/include/uapi/linux/sched.h' differs from latest version at 'include/uapi/linux/sched.h' diff -u tools/include/uapi/linux/sched.h include/uapi/linux/sched.h Cc: Adrian Hunter Cc: Aleksa Sarai Cc: Christian Brauner Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-xqruu8wohwlbc57udg1g0xzx@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/linux/sched.h | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/include/uapi/linux/sched.h b/tools/include/uapi/linux/sched.h index b3105ac1381a..99335e1f4a27 100644 --- a/tools/include/uapi/linux/sched.h +++ b/tools/include/uapi/linux/sched.h @@ -33,8 +33,31 @@ #define CLONE_NEWNET 0x40000000 /* New network namespace */ #define CLONE_IO 0x80000000 /* Clone io context */ -/* - * Arguments for the clone3 syscall +#ifndef __ASSEMBLY__ +/** + * struct clone_args - arguments for the clone3 syscall + * @flags: Flags for the new process as listed above. + * All flags are valid except for CSIGNAL and + * CLONE_DETACHED. + * @pidfd: If CLONE_PIDFD is set, a pidfd will be + * returned in this argument. + * @child_tid: If CLONE_CHILD_SETTID is set, the TID of the + * child process will be returned in the child's + * memory. + * @parent_tid: If CLONE_PARENT_SETTID is set, the TID of + * the child process will be returned in the + * parent's memory. + * @exit_signal: The exit_signal the parent process will be + * sent when the child exits. + * @stack: Specify the location of the stack for the + * child process. + * @stack_size: The size of the stack for the child process. + * @tls: If CLONE_SETTLS is set, the tls descriptor + * is set to tls. + * + * The structure is versioned by size and thus extensible. + * New struct members must go at the end of the struct and + * must be properly 64bit aligned. */ struct clone_args { __aligned_u64 flags; @@ -46,6 +69,9 @@ struct clone_args { __aligned_u64 stack_size; __aligned_u64 tls; }; +#endif + +#define CLONE_ARGS_SIZE_VER0 64 /* sizeof first published struct */ /* * Scheduling policies -- cgit v1.2.3-59-g8ed1b From 1abecfcaa7bba21c9985e0136fa49836164dd8fd Mon Sep 17 00:00:00 2001 From: Yunfeng Ye Date: Wed, 16 Oct 2019 16:38:45 +0800 Subject: perf kmem: Fix memory leak in compact_gfp_flags() The memory @orig_flags is allocated by strdup(), it is freed on the normal path, but leak to free on the error path. Fix this by adding free(orig_flags) on the error path. Fixes: 0e11115644b3 ("perf kmem: Print gfp flags in human readable string") Signed-off-by: Yunfeng Ye Cc: Alexander Shishkin Cc: Feilong Lin Cc: Hu Shiyuan Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/f9e9f458-96f3-4a97-a1d5-9feec2420e07@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kmem.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 1e61e353f579..9661671cc26e 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -691,6 +691,7 @@ static char *compact_gfp_flags(char *gfp_flags) new = realloc(new_flags, len + strlen(cpt) + 2); if (new == NULL) { free(new_flags); + free(orig_flags); return NULL; } -- cgit v1.2.3-59-g8ed1b From 6f24c8d30d08f270b54f4c2cb9b08dfccbe59c57 Mon Sep 17 00:00:00 2001 From: John Hubbard Date: Fri, 18 Oct 2019 20:19:50 -0700 Subject: mm/gup_benchmark: add a missing "w" to getopt string Even though gup_benchmark.c has code to handle the -w command-line option, the "w" is not part of the getopt string. It looks as if it has been missing the whole time. On my machine, this leads naturally to the following predictable result: $ sudo ./gup_benchmark -w ./gup_benchmark: invalid option -- 'w' ...which is fixed with this commit. Link: http://lkml.kernel.org/r/20191014184639.1512873-2-jhubbard@nvidia.com Signed-off-by: John Hubbard Acked-by: Kirill A. Shutemov Cc: Keith Busch Cc: Shuah Khan Cc: Christoph Hellwig Cc: "Aneesh Kumar K . V" Cc: Ira Weiny Cc: Christoph Hellwig Cc: kbuild test robot Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- tools/testing/selftests/vm/gup_benchmark.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/vm/gup_benchmark.c b/tools/testing/selftests/vm/gup_benchmark.c index c0534e298b51..cb3fc09645c4 100644 --- a/tools/testing/selftests/vm/gup_benchmark.c +++ b/tools/testing/selftests/vm/gup_benchmark.c @@ -37,7 +37,7 @@ int main(int argc, char **argv) char *file = "/dev/zero"; char *p; - while ((opt = getopt(argc, argv, "m:r:n:f:tTLUSH")) != -1) { + while ((opt = getopt(argc, argv, "m:r:n:f:tTLUwSH")) != -1) { switch (opt) { case 'm': size = atoi(optarg) * MB; -- cgit v1.2.3-59-g8ed1b From 9de25d182b806d63412f6827e3066c031d4be500 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 7 Oct 2019 15:26:56 +0200 Subject: selftests: kvm: synchronize .gitignore to Makefile Because "Untracked files:" are annoying. Signed-off-by: Vitaly Kuznetsov Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/.gitignore | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore index b35da375530a..409c1fa75e03 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -1,4 +1,5 @@ /s390x/sync_regs_test +/s390x/memop /x86_64/cr4_cpuid_sync_test /x86_64/evmcs_test /x86_64/hyperv_cpuid @@ -9,6 +10,7 @@ /x86_64/state_test /x86_64/sync_regs_test /x86_64/vmx_close_while_nested_test +/x86_64/vmx_dirty_log_test /x86_64/vmx_set_nested_state_test /x86_64/vmx_tsc_adjust_test /clear_dirty_log_test -- cgit v1.2.3-59-g8ed1b From 700c17d9cec8712f4091692488fb63e2680f7a5d Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Tue, 8 Oct 2019 21:43:36 +0200 Subject: selftests: kvm: vmx_set_nested_state_test: don't check for VMX support twice vmx_set_nested_state_test() checks if VMX is supported twice: in the very beginning (and skips the whole test if it's not) and before doing test_vmx_nested_state(). One should be enough. Signed-off-by: Vitaly Kuznetsov Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c index 853e370e8a39..a6d85614ae4d 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c @@ -271,12 +271,7 @@ int main(int argc, char *argv[]) state.flags = KVM_STATE_NESTED_RUN_PENDING; test_nested_state_expect_einval(vm, &state); - /* - * TODO: When SVM support is added for KVM_SET_NESTED_STATE - * add tests here to support it like VMX. - */ - if (entry->ecx & CPUID_VMX) - test_vmx_nested_state(vm); + test_vmx_nested_state(vm); kvm_vm_free(vm); return 0; -- cgit v1.2.3-59-g8ed1b From 9143613ef0ba9f88d2fef9038930637a0909d35a Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Tue, 8 Oct 2019 21:43:37 +0200 Subject: selftests: kvm: consolidate VMX support checks vmx_* tests require VMX and three of them implement the same check. Move it to vmx library. Signed-off-by: Vitaly Kuznetsov Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/include/x86_64/vmx.h | 2 ++ tools/testing/selftests/kvm/lib/x86_64/vmx.c | 10 ++++++++++ .../testing/selftests/kvm/x86_64/vmx_close_while_nested_test.c | 6 +----- tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c | 6 +----- tools/testing/selftests/kvm/x86_64/vmx_tsc_adjust_test.c | 6 +----- 5 files changed, 15 insertions(+), 15 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/include/x86_64/vmx.h b/tools/testing/selftests/kvm/include/x86_64/vmx.h index 6ae5a47fe067..f52e0ba84fed 100644 --- a/tools/testing/selftests/kvm/include/x86_64/vmx.h +++ b/tools/testing/selftests/kvm/include/x86_64/vmx.h @@ -580,6 +580,8 @@ bool prepare_for_vmx_operation(struct vmx_pages *vmx); void prepare_vmcs(struct vmx_pages *vmx, void *guest_rip, void *guest_rsp); bool load_vmcs(struct vmx_pages *vmx); +void nested_vmx_check_supported(void); + void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm, uint64_t nested_paddr, uint64_t paddr, uint32_t eptp_memslot); void nested_map(struct vmx_pages *vmx, struct kvm_vm *vm, diff --git a/tools/testing/selftests/kvm/lib/x86_64/vmx.c b/tools/testing/selftests/kvm/lib/x86_64/vmx.c index fab8f6b0bf52..f6ec97b7eaef 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/vmx.c +++ b/tools/testing/selftests/kvm/lib/x86_64/vmx.c @@ -376,6 +376,16 @@ void prepare_vmcs(struct vmx_pages *vmx, void *guest_rip, void *guest_rsp) init_vmcs_guest_state(guest_rip, guest_rsp); } +void nested_vmx_check_supported(void) +{ + struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1); + + if (!(entry->ecx & CPUID_VMX)) { + fprintf(stderr, "nested VMX not enabled, skipping test\n"); + exit(KSFT_SKIP); + } +} + void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm, uint64_t nested_paddr, uint64_t paddr, uint32_t eptp_memslot) { diff --git a/tools/testing/selftests/kvm/x86_64/vmx_close_while_nested_test.c b/tools/testing/selftests/kvm/x86_64/vmx_close_while_nested_test.c index 3b0ffe01dacd..5dfb53546a26 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_close_while_nested_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_close_while_nested_test.c @@ -53,12 +53,8 @@ static void l1_guest_code(struct vmx_pages *vmx_pages) int main(int argc, char *argv[]) { vm_vaddr_t vmx_pages_gva; - struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1); - if (!(entry->ecx & CPUID_VMX)) { - fprintf(stderr, "nested VMX not enabled, skipping test\n"); - exit(KSFT_SKIP); - } + nested_vmx_check_supported(); vm = vm_create_default(VCPU_ID, 0, (void *) l1_guest_code); vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid()); diff --git a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c index a6d85614ae4d..9ef7fab39d48 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c @@ -224,7 +224,6 @@ int main(int argc, char *argv[]) { struct kvm_vm *vm; struct kvm_nested_state state; - struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1); have_evmcs = kvm_check_cap(KVM_CAP_HYPERV_ENLIGHTENED_VMCS); @@ -237,10 +236,7 @@ int main(int argc, char *argv[]) * AMD currently does not implement set_nested_state, so for now we * just early out. */ - if (!(entry->ecx & CPUID_VMX)) { - fprintf(stderr, "nested VMX not enabled, skipping test\n"); - exit(KSFT_SKIP); - } + nested_vmx_check_supported(); vm = vm_create_default(VCPU_ID, 0, 0); diff --git a/tools/testing/selftests/kvm/x86_64/vmx_tsc_adjust_test.c b/tools/testing/selftests/kvm/x86_64/vmx_tsc_adjust_test.c index f36c10eba71e..5590fd2bcf87 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_tsc_adjust_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_tsc_adjust_test.c @@ -128,12 +128,8 @@ static void report(int64_t val) int main(int argc, char *argv[]) { vm_vaddr_t vmx_pages_gva; - struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1); - if (!(entry->ecx & CPUID_VMX)) { - fprintf(stderr, "nested VMX not enabled, skipping test\n"); - exit(KSFT_SKIP); - } + nested_vmx_check_supported(); vm = vm_create_default(VCPU_ID, 0, (void *) l1_guest_code); vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid()); -- cgit v1.2.3-59-g8ed1b From 11eada4718a352a6a588de9908200c1e348530f1 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Tue, 8 Oct 2019 21:43:38 +0200 Subject: selftests: kvm: vmx_dirty_log_test: skip the test when VMX is not supported vmx_dirty_log_test fails on AMD and this is no surprise as it is VMX specific. Bail early when nested VMX is unsupported. Signed-off-by: Vitaly Kuznetsov Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c b/tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c index 0bca1cfe2c1e..a223a6401258 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c @@ -78,6 +78,8 @@ int main(int argc, char *argv[]) struct ucall uc; bool done = false; + nested_vmx_check_supported(); + /* Create VM */ vm = vm_create_default(VCPU_ID, 0, l1_guest_code); vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid()); -- cgit v1.2.3-59-g8ed1b From ef4059809890f732c69cc1726d3a9a108a832a2f Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Tue, 8 Oct 2019 20:08:08 +0200 Subject: selftests: kvm: fix sync_regs_test with newer gccs Commit 204c91eff798a ("KVM: selftests: do not blindly clobber registers in guest asm") was intended to make test more gcc-proof, however, the result is exactly the opposite: on newer gccs (e.g. 8.2.1) the test breaks with ==== Test Assertion Failure ==== x86_64/sync_regs_test.c:168: run->s.regs.regs.rbx == 0xBAD1DEA + 1 pid=14170 tid=14170 - Invalid argument 1 0x00000000004015b3: main at sync_regs_test.c:166 (discriminator 6) 2 0x00007f413fb66412: ?? ??:0 3 0x000000000040191d: _start at ??:? rbx sync regs value incorrect 0x1. Apparently, compile is still free to play games with registers even when they have variables attached. Re-write guest code with 'asm volatile' by embedding ucall there and making sure rbx is preserved. Fixes: 204c91eff798a ("KVM: selftests: do not blindly clobber registers in guest asm") Signed-off-by: Vitaly Kuznetsov Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/x86_64/sync_regs_test.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/kvm/x86_64/sync_regs_test.c b/tools/testing/selftests/kvm/x86_64/sync_regs_test.c index 11c2a70a7b87..5c8224256294 100644 --- a/tools/testing/selftests/kvm/x86_64/sync_regs_test.c +++ b/tools/testing/selftests/kvm/x86_64/sync_regs_test.c @@ -22,18 +22,19 @@ #define VCPU_ID 5 +#define UCALL_PIO_PORT ((uint16_t)0x1000) + +/* + * ucall is embedded here to protect against compiler reshuffling registers + * before calling a function. In this test we only need to get KVM_EXIT_IO + * vmexit and preserve RBX, no additional information is needed. + */ void guest_code(void) { - /* - * use a callee-save register, otherwise the compiler - * saves it around the call to GUEST_SYNC. - */ - register u32 stage asm("rbx"); - for (;;) { - GUEST_SYNC(0); - stage++; - asm volatile ("" : : "r" (stage)); - } + asm volatile("1: in %[port], %%al\n" + "add $0x1, %%rbx\n" + "jmp 1b" + : : [port] "d" (UCALL_PIO_PORT) : "rax", "rbx"); } static void compare_regs(struct kvm_regs *left, struct kvm_regs *right) -- cgit v1.2.3-59-g8ed1b