Skip to content

Commit

Permalink
Merge tag 'perf-tools-for-v5.13-2021-04-29' of git://git.kernel.org/p…
Browse files Browse the repository at this point in the history
…ub/scm/linux/kernel/git/acme/linux

Pull perf tool updates from Arnaldo Carvalho de Melo:
 "perf stat:

   - Add support for hybrid PMUs to support systems such as Intel
     Alderlake and its BIG/little core/atom cpus.

   - Introduce 'bperf' to share hardware PMCs with BPF.

   - New --iostat option to collect and present IO stats on Intel
     hardware.

     This functionality is based on recently introduced sysfs attributes
     for Intel® Xeon® Scalable processor family (code name Skylake-SP)
     in commit bb42b3d ("perf/x86/intel/uncore: Expose an Uncore
     unit to IIO PMON mapping")

     It is intended to provide four I/O performance metrics in MB per
     each PCIe root port:

       - Inbound Read: I/O devices below root port read from the host memory
       - Inbound Write: I/O devices below root port write to the host memory
       - Outbound Read: CPU reads from I/O devices below root port
       - Outbound Write: CPU writes to I/O devices below root port

   - Align CSV output for summary.

   - Clarify --null use cases: Assess raw overhead of 'perf stat' or
     measure just wall clock time.

   - Improve readability of shadow stats.

  perf record:

   - Change the COMM when starting tha workload so that --exclude-perf
     doesn't seem to be not honoured.

   - Improve 'Workload failed' message printing events + what was
     exec'ed.

   - Fix cross-arch support for TIME_CONV.

  perf report:

   - Add option to disable raw event ordering.

   - Dump the contents of PERF_RECORD_TIME_CONV in 'perf report -D'.

   - Improvements to --stat output, that shows information about
     PERF_RECORD_ events.

   - Preserve identifier id in OCaml demangler.

  perf annotate:

   - Show full source location with 'l' hotkey in the 'perf annotate'
     TUI.

   - Add line number like in TUI and source location at EOL to the 'perf
     annotate' --stdio mode.

   - Add --demangle and --demangle-kernel to 'perf annotate'.

   - Allow configuring annotate.demangle{,_kernel} in 'perf config'.

   - Fix sample events lost in stdio mode.

  perf data:

   - Allow converting a perf.data file to JSON.

  libperf:

   - Add support for user space counter access.

   - Update topdown documentation to permit rdpmc calls.

  perf test:

   - Add 'perf test' for 'perf stat' CSV output.

   - Add 'perf test' entries to test the hybrid PMU support.

   - Cleanup 'perf test daemon' if its 'perf test' is interrupted.

   - Handle metric reuse in pmu-events parsing 'perf test' entry.

   - Add test for PE executable support.

   - Add timeout for wait for daemon start in its 'perf test' entries.

  Build:

   - Enable libtraceevent dynamic linking.

   - Improve feature detection output.

   - Fix caching of feature checks caching.

   - First round of updates for tools copies of kernel headers.

   - Enable warnings when compiling BPF programs.

  Vendor specific events:

   - Intel:
      - Add missing skylake & icelake model numbers.

   - arm64:
      - Add Hisi hip08 L1, L2 and L3 metrics.
      - Add Fujitsu A64FX PMU events.

   - PowerPC:
      - Initial JSON/events list for power10 platform.
      - Remove unsupported power9 metrics.

   - AMD:
      - Add Zen3 events.
      - Fix broken L2 Cache Hits from L2 HWPF metric.
      - Use lowercases for all the eventcodes and umasks.

  Hardware tracing:

   - arm64:
      - Update CoreSight ETM metadata format.
      - Fix bitmap for CS-ETM option.
      - Support PID tracing in config.
      - Detect pid in VMID for kernel running at EL2.

  Arch specific updates:

   - MIPS:
      - Support MIPS unwinding and dwarf-regs.
      - Generate mips syscalls_n64.c syscall table.

   - PowerPC:
      - Add support for PERF_SAMPLE_WEIGH_STRUCT on PowerPC.
      - Support pipeline stage cycles for powerpc.

  libbeauty:

   - Fix fsconfig generator"

* tag 'perf-tools-for-v5.13-2021-04-29' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux: (132 commits)
  perf build: Defer printing detected features to the end of all feature checks
  tools build: Allow deferring printing the results of feature detection
  perf build: Regenerate the FEATURE_DUMP file after extra feature checks
  perf session: Dump PERF_RECORD_TIME_CONV event
  perf session: Add swap operation for event TIME_CONV
  perf jit: Let convert_timestamp() to be backwards-compatible
  perf tools: Change fields type in perf_record_time_conv
  perf tools: Enable libtraceevent dynamic linking
  perf Documentation: Document intel-hybrid support
  perf tests: Skip 'perf stat metrics (shadow stat) test' for hybrid
  perf tests: Support 'Convert perf time to TSC' test for hybrid
  perf tests: Support 'Session topology' test for hybrid
  perf tests: Support 'Parse and process metrics' test for hybrid
  perf tests: Support 'Track with sched_switch' test for hybrid
  perf tests: Skip 'Setup struct perf_event_attr' test for hybrid
  perf tests: Add hybrid cases for 'Roundtrip evsel->name' test
  perf tests: Add hybrid cases for 'Parse event definition strings' test
  perf record: Uniquify hybrid event name
  perf stat: Warn group events from different hybrid PMU
  perf stat: Filter out unmatched aggregation for hybrid event
  ...
  • Loading branch information
torvalds committed May 1, 2021
2 parents 22650f1 + c6e3bf4 commit 10a3efd
Show file tree
Hide file tree
Showing 244 changed files with 9,952 additions and 883 deletions.
2 changes: 2 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -14290,8 +14290,10 @@ R: Mark Rutland <[email protected]>
R: Alexander Shishkin <[email protected]>
R: Jiri Olsa <[email protected]>
R: Namhyung Kim <[email protected]>
L: [email protected]
L: [email protected]
S: Supported
W: https://perf.wiki.kernel.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
F: arch/*/events/*
F: arch/*/events/*/*
Expand Down
28 changes: 18 additions & 10 deletions tools/build/Makefile.feature
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ FEATURE_TESTS_BASIC := \
libpython-version \
libslang \
libslang-include-subdir \
libtraceevent \
libcrypto \
libunwind \
pthread-attr-setaffinity-np \
Expand Down Expand Up @@ -239,17 +240,24 @@ ifeq ($(VF),1)
feature_verbose := 1
endif

ifeq ($(feature_display),1)
$(info )
$(info Auto-detecting system features:)
$(foreach feat,$(FEATURE_DISPLAY),$(call feature_print_status,$(feat),))
ifneq ($(feature_verbose),1)
feature_display_entries = $(eval $(feature_display_entries_code))
define feature_display_entries_code
ifeq ($(feature_display),1)
$(info )
$(info Auto-detecting system features:)
$(foreach feat,$(FEATURE_DISPLAY),$(call feature_print_status,$(feat),))
ifneq ($(feature_verbose),1)
$(info )
endif
endif
endif

ifeq ($(feature_verbose),1)
TMP := $(filter-out $(FEATURE_DISPLAY),$(FEATURE_TESTS))
$(foreach feat,$(TMP),$(call feature_print_status,$(feat),))
$(info )
ifeq ($(feature_verbose),1)
TMP := $(filter-out $(FEATURE_DISPLAY),$(FEATURE_TESTS))
$(foreach feat,$(TMP),$(call feature_print_status,$(feat),))
$(info )
endif
endef

ifeq ($(FEATURE_DISPLAY_DEFERRED),)
$(call feature_display_entries)
endif
4 changes: 4 additions & 0 deletions tools/build/feature/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ FILES= \
test-libpython-version.bin \
test-libslang.bin \
test-libslang-include-subdir.bin \
test-libtraceevent.bin \
test-libcrypto.bin \
test-libunwind.bin \
test-libunwind-debug-frame.bin \
Expand Down Expand Up @@ -196,6 +197,9 @@ $(OUTPUT)test-libslang.bin:
$(OUTPUT)test-libslang-include-subdir.bin:
$(BUILD) -lslang

$(OUTPUT)test-libtraceevent.bin:
$(BUILD) -ltraceevent

$(OUTPUT)test-libcrypto.bin:
$(BUILD) -lcrypto

Expand Down
12 changes: 12 additions & 0 deletions tools/build/feature/test-libtraceevent.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: GPL-2.0
#include <traceevent/trace-seq.h>

int main(void)
{
int rv = 0;
struct trace_seq s;
trace_seq_init(&s);
rv += !(s.state == TRACE_SEQ__GOOD);
trace_seq_destroy(&s);
return rv;
}
75 changes: 75 additions & 0 deletions tools/include/linux/math64.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_MATH64_H
#define _LINUX_MATH64_H

#include <linux/types.h>

#ifdef __x86_64__
static inline u64 mul_u64_u64_div64(u64 a, u64 b, u64 c)
{
u64 q;

asm ("mulq %2; divq %3" : "=a" (q)
: "a" (a), "rm" (b), "rm" (c)
: "rdx");

return q;
}
#define mul_u64_u64_div64 mul_u64_u64_div64
#endif

#ifdef __SIZEOF_INT128__
static inline u64 mul_u64_u32_shr(u64 a, u32 b, unsigned int shift)
{
return (u64)(((unsigned __int128)a * b) >> shift);
}

#else

#ifdef __i386__
static inline u64 mul_u32_u32(u32 a, u32 b)
{
u32 high, low;

asm ("mull %[b]" : "=a" (low), "=d" (high)
: [a] "a" (a), [b] "rm" (b) );

return low | ((u64)high) << 32;
}
#else
static inline u64 mul_u32_u32(u32 a, u32 b)
{
return (u64)a * b;
}
#endif

static inline u64 mul_u64_u32_shr(u64 a, u32 b, unsigned int shift)
{
u32 ah, al;
u64 ret;

al = a;
ah = a >> 32;

ret = mul_u32_u32(al, b) >> shift;
if (ah)
ret += mul_u32_u32(ah, b) << (32 - shift);

return ret;
}

#endif /* __SIZEOF_INT128__ */

#ifndef mul_u64_u64_div64
static inline u64 mul_u64_u64_div64(u64 a, u64 b, u64 c)
{
u64 quot, rem;

quot = a / c;
rem = a % c;

return quot * b + (rem * b) / c;
}
#endif

#endif /* _LINUX_MATH64_H */
3 changes: 3 additions & 0 deletions tools/include/linux/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ typedef __u32 __bitwise __be32;
typedef __u64 __bitwise __le64;
typedef __u64 __bitwise __be64;

typedef __u16 __bitwise __sum16;
typedef __u32 __bitwise __wsum;

typedef struct {
int counter;
} atomic_t;
Expand Down
15 changes: 15 additions & 0 deletions tools/include/uapi/linux/perf_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,21 @@ enum perf_type_id {
PERF_TYPE_MAX, /* non-ABI */
};

/*
* attr.config layout for type PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE
* PERF_TYPE_HARDWARE: 0xEEEEEEEE000000AA
* AA: hardware event ID
* EEEEEEEE: PMU type ID
* PERF_TYPE_HW_CACHE: 0xEEEEEEEE00DDCCBB
* BB: hardware cache ID
* CC: hardware cache op ID
* DD: hardware cache op result ID
* EEEEEEEE: PMU type ID
* If the PMU type ID is 0, the PERF_TYPE_RAW will be applied.
*/
#define PERF_PMU_TYPE_SHIFT 32
#define PERF_HW_EVENT_MASK 0xffffffff

/*
* Generalized performance event event_id types, used by the
* attr.event_id parameter of the sys_perf_event_open()
Expand Down
3 changes: 3 additions & 0 deletions tools/lib/perf/Documentation/libperf.txt
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ SYNOPSIS
struct perf_thread_map *threads);
void perf_evsel__close(struct perf_evsel *evsel);
void perf_evsel__close_cpu(struct perf_evsel *evsel, int cpu);
int perf_evsel__mmap(struct perf_evsel *evsel, int pages);
void perf_evsel__munmap(struct perf_evsel *evsel);
void *perf_evsel__mmap_base(struct perf_evsel *evsel, int cpu, int thread);
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);
Expand Down
80 changes: 80 additions & 0 deletions tools/lib/perf/evsel.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
#include <stdlib.h>
#include <internal/xyarray.h>
#include <internal/cpumap.h>
#include <internal/mmap.h>
#include <internal/threadmap.h>
#include <internal/lib.h>
#include <linux/string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>

void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr)
{
Expand All @@ -38,6 +40,7 @@ void perf_evsel__delete(struct perf_evsel *evsel)
}

#define FD(e, x, y) (*(int *) xyarray__entry(e->fd, x, y))
#define MMAP(e, x, y) (e->mmap ? ((struct perf_mmap *) xyarray__entry(e->mmap, x, y)) : NULL)

int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
{
Expand All @@ -55,6 +58,13 @@ int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
return evsel->fd != NULL ? 0 : -ENOMEM;
}

static int perf_evsel__alloc_mmap(struct perf_evsel *evsel, int ncpus, int nthreads)
{
evsel->mmap = xyarray__new(ncpus, nthreads, sizeof(struct perf_mmap));

return evsel->mmap != NULL ? 0 : -ENOMEM;
}

static int
sys_perf_event_open(struct perf_event_attr *attr,
pid_t pid, int cpu, int group_fd,
Expand Down Expand Up @@ -156,6 +166,72 @@ void perf_evsel__close_cpu(struct perf_evsel *evsel, int cpu)
perf_evsel__close_fd_cpu(evsel, cpu);
}

void perf_evsel__munmap(struct perf_evsel *evsel)
{
int cpu, thread;

if (evsel->fd == NULL || evsel->mmap == NULL)
return;

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);
struct perf_mmap *map = MMAP(evsel, cpu, thread);

if (fd < 0)
continue;

perf_mmap__munmap(map);
}
}

xyarray__delete(evsel->mmap);
evsel->mmap = NULL;
}

int perf_evsel__mmap(struct perf_evsel *evsel, int pages)
{
int ret, cpu, thread;
struct perf_mmap_param mp = {
.prot = PROT_READ | PROT_WRITE,
.mask = (pages * page_size) - 1,
};

if (evsel->fd == NULL || evsel->mmap)
return -EINVAL;

if (perf_evsel__alloc_mmap(evsel, xyarray__max_x(evsel->fd), xyarray__max_y(evsel->fd)) < 0)
return -ENOMEM;

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);
struct perf_mmap *map = MMAP(evsel, cpu, thread);

if (fd < 0)
continue;

perf_mmap__init(map, NULL, false, NULL);

ret = perf_mmap__mmap(map, &mp, fd, cpu);
if (ret) {
perf_evsel__munmap(evsel);
return ret;
}
}
}

return 0;
}

void *perf_evsel__mmap_base(struct perf_evsel *evsel, int cpu, int thread)
{
if (FD(evsel, cpu, thread) < 0 || MMAP(evsel, cpu, thread) == NULL)
return NULL;

return MMAP(evsel, cpu, thread)->base;
}

int perf_evsel__read_size(struct perf_evsel *evsel)
{
u64 read_format = evsel->attr.read_format;
Expand Down Expand Up @@ -191,6 +267,10 @@ int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
if (FD(evsel, cpu, thread) < 0)
return -EINVAL;

if (MMAP(evsel, cpu, thread) &&
!perf_mmap__read_self(MMAP(evsel, cpu, thread), count))
return 0;

if (readn(FD(evsel, cpu, thread), count->values, size) <= 0)
return -errno;

Expand Down
1 change: 1 addition & 0 deletions tools/lib/perf/include/internal/evsel.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ struct perf_evsel {
struct perf_cpu_map *own_cpus;
struct perf_thread_map *threads;
struct xyarray *fd;
struct xyarray *mmap;
struct xyarray *sample_id;
u64 *id;
u32 ids;
Expand Down
3 changes: 3 additions & 0 deletions tools/lib/perf/include/internal/mmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#define PERF_SAMPLE_MAX_SIZE (1 << 16)

struct perf_mmap;
struct perf_counts_values;

typedef void (*libperf_unmap_cb_t)(struct perf_mmap *map);

Expand Down Expand Up @@ -52,4 +53,6 @@ void perf_mmap__put(struct perf_mmap *map);

u64 perf_mmap__read_head(struct perf_mmap *map);

int perf_mmap__read_self(struct perf_mmap *map, struct perf_counts_values *count);

#endif /* __LIBPERF_INTERNAL_MMAP_H */
32 changes: 32 additions & 0 deletions tools/lib/perf/include/internal/tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,32 @@
#define __LIBPERF_INTERNAL_TESTS_H

#include <stdio.h>
#include <unistd.h>

int tests_failed;
int tests_verbose;

static inline int get_verbose(char **argv, int argc)
{
int c;
int verbose = 0;

while ((c = getopt(argc, argv, "v")) != -1) {
switch (c)
{
case 'v':
verbose = 1;
break;
default:
break;
}
}
return verbose;
}

#define __T_START \
do { \
tests_verbose = get_verbose(argv, argc); \
fprintf(stdout, "- running %s...", __FILE__); \
fflush(NULL); \
tests_failed = 0; \
Expand All @@ -30,4 +51,15 @@ do {
} \
} while (0)

#define __T_VERBOSE(...) \
do { \
if (tests_verbose) { \
if (tests_verbose == 1) { \
fputc('\n', stderr); \
tests_verbose++; \
} \
fprintf(stderr, ##__VA_ARGS__); \
} \
} while (0)

#endif /* __LIBPERF_INTERNAL_TESTS_H */
Loading

0 comments on commit 10a3efd

Please sign in to comment.