Skip to content

Commit 059c6d6

Browse files
committed
Merge tag 'perf-core-for-mingo-5.8-20200506' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf updates from Arnaldo: perf/core improvements and fixes: perf record: - Introduce --switch-output-event to use arbitrary events to be setup and read from a side band thread and, when they take place a signal be sent to the main 'perf record' thread, reusing the --switch-output code to take perf.data snapshots from the --overwrite ring buffer, e.g.: # perf record --overwrite -e sched:* \ --switch-output-event syscalls:*connect* \ workload will take perf.data.YYYYMMDDHHMMSS snapshots up to around the connect syscalls. Stephane Eranian: - Add --num-synthesize-threads option to control degree of parallelism of the synthesize_mmap() code which is scanning /proc/PID/task/PID/maps and can be time consuming. This mimics pre-existing behaviour in 'perf top'. Intel PT: Adrian Hunter: - Add support for synthesizing branch stacks for regular events (cycles, instructions, etc) from Intel PT data. perf bench: Ian Rogers: - Add a multi-threaded synthesize benchmark. - Add kallsyms parsing benchmark. Tommi Rantala: - Fix div-by-zero if runtime is zero. perf synthetic events: - Remove use of sscanf from /proc reading when parsing pre-existing threads to generate synthetic PERF_RECORD_{FORK,MMAP,COMM,etc} events. tools api: - Add a lightweight buffered reading API. libsymbols: - Parse kallsyms using new lightweight buffered reading io API. perf parse-events: - Fix memory leaks found on parse_events. perf mem2node: - Avoid double free related to realloc(). perf stat: Jin Yao: - Zero all the 'ena' and 'run' array slot stats for interval mode. - Improve runtime stat for interval mode Kajol Jain: - Enable Hz/hz printing for --metric-only option - Enhance JSON/metric infrastructure to handle "?". perf tests: Kajol Jain: - Added test for runtime param in metric expression. Tommi Rantala: - Fix data path in the session topology test. perf vendor events power9: Kajol Jain: - Add hv_24x7 socket/chip level metric events Coresight: Leo Yan: - Move definition of 'traceid_list' global variable from header file. Mike Leach: - Update to build with latest opencsd version. perf pmu: Shaokun Zhang: - Fix function name in comment, its get_cpuid_str(), not get_cpustr() Stephane Eranian: - Add perf_pmu__find_by_type() helper perf script: Stephane Eranian: - Remove extraneous newline in perf_sample__fprintf_regs(). Ian Rogers: - Avoid NULL dereference on symbol. tools feature: Stephane Eranian: - Add support for detecting libpfm4. perf symbol: Thomas Richter: - Fix kernel symbol address display in TUI verbose mode. perf cgroup: Tommi Rantala: - Avoid needless closing of unopened fd libperf: He Zhe: - Add NULL pointer check for cpu_map iteration and NULL assignment for all_cpus. Ian Rogers: - Fix a refcount leak in evlist method. Arnaldo Carvalho de Melo: - Rename the code in tools/perf/util, i.e. perf tooling specific, that operates on 'struct evsel' to evsel__, leaving the perf_evsel__ namespace for the routines in tools/lib/perf/ that operate on 'struct perf_evsel__'. tools/perf specific libraries: Konstantin Khlebnikov: - Fix reading new topology attribute "core_cpus" - Simplify checking if SMT is active. perf flamegraph: Arnaldo Carvalho de Melo: - Use /bin/bash for report and record scripts, just like all other such scripts, fixing a package dependency bug in a Linaro OpenEmbedded build checker. perf evlist: Jagadeesh Pagadala: - Remove duplicate headers. Miscelaneous: Zou Wei: - Remove unneeded semicolon in libtraceevent, 'perf c2c' and others. - Fix warning assignment of 0/1 to bool variable in 'perf report' Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
2 parents 4bd3010 + 19ce232 commit 059c6d6

File tree

135 files changed

+2699
-1517
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

135 files changed

+2699
-1517
lines changed

tools/build/Makefile.feature

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ FEATURE_TESTS_EXTRA := \
9898
llvm \
9999
llvm-version \
100100
clang \
101-
libbpf
101+
libbpf \
102+
libpfm4
102103

103104
FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)
104105

tools/build/feature/Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ FILES= \
6969
test-libaio.bin \
7070
test-libzstd.bin \
7171
test-clang-bpf-global-var.bin \
72-
test-file-handle.bin
72+
test-file-handle.bin \
73+
test-libpfm4.bin
7374

7475
FILES := $(addprefix $(OUTPUT),$(FILES))
7576

@@ -331,6 +332,9 @@ $(OUTPUT)test-clang-bpf-global-var.bin:
331332
$(OUTPUT)test-file-handle.bin:
332333
$(BUILD)
333334

335+
$(OUTPUT)test-libpfm4.bin:
336+
$(BUILD) -lpfm
337+
334338
###############################
335339

336340
clean:

tools/build/feature/test-libopencsd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
/*
55
* Check OpenCSD library version is sufficient to provide required features
66
*/
7-
#define OCSD_MIN_VER ((0 << 16) | (11 << 8) | (0))
7+
#define OCSD_MIN_VER ((0 << 16) | (14 << 8) | (0))
88
#if !defined(OCSD_VER_NUM) || (OCSD_VER_NUM < OCSD_MIN_VER)
9-
#error "OpenCSD >= 0.11.0 is required"
9+
#error "OpenCSD >= 0.14.0 is required"
1010
#endif
1111

1212
int main(void)

tools/build/feature/test-libpfm4.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#include <sys/types.h>
3+
#include <perfmon/pfmlib.h>
4+
5+
int main(void)
6+
{
7+
pfm_initialize();
8+
return 0;
9+
}

tools/lib/api/io.h

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* Lightweight buffered reading library.
4+
*
5+
* Copyright 2019 Google LLC.
6+
*/
7+
#ifndef __API_IO__
8+
#define __API_IO__
9+
10+
#include <stdlib.h>
11+
#include <unistd.h>
12+
13+
struct io {
14+
/* File descriptor being read/ */
15+
int fd;
16+
/* Size of the read buffer. */
17+
unsigned int buf_len;
18+
/* Pointer to storage for buffering read. */
19+
char *buf;
20+
/* End of the storage. */
21+
char *end;
22+
/* Currently accessed data pointer. */
23+
char *data;
24+
/* Set true on when the end of file on read error. */
25+
bool eof;
26+
};
27+
28+
static inline void io__init(struct io *io, int fd,
29+
char *buf, unsigned int buf_len)
30+
{
31+
io->fd = fd;
32+
io->buf_len = buf_len;
33+
io->buf = buf;
34+
io->end = buf;
35+
io->data = buf;
36+
io->eof = false;
37+
}
38+
39+
/* Reads one character from the "io" file with similar semantics to fgetc. */
40+
static inline int io__get_char(struct io *io)
41+
{
42+
char *ptr = io->data;
43+
44+
if (io->eof)
45+
return -1;
46+
47+
if (ptr == io->end) {
48+
ssize_t n = read(io->fd, io->buf, io->buf_len);
49+
50+
if (n <= 0) {
51+
io->eof = true;
52+
return -1;
53+
}
54+
ptr = &io->buf[0];
55+
io->end = &io->buf[n];
56+
}
57+
io->data = ptr + 1;
58+
return *ptr;
59+
}
60+
61+
/* Read a hexadecimal value with no 0x prefix into the out argument hex. If the
62+
* first character isn't hexadecimal returns -2, io->eof returns -1, otherwise
63+
* returns the character after the hexadecimal value which may be -1 for eof.
64+
* If the read value is larger than a u64 the high-order bits will be dropped.
65+
*/
66+
static inline int io__get_hex(struct io *io, __u64 *hex)
67+
{
68+
bool first_read = true;
69+
70+
*hex = 0;
71+
while (true) {
72+
int ch = io__get_char(io);
73+
74+
if (ch < 0)
75+
return ch;
76+
if (ch >= '0' && ch <= '9')
77+
*hex = (*hex << 4) | (ch - '0');
78+
else if (ch >= 'a' && ch <= 'f')
79+
*hex = (*hex << 4) | (ch - 'a' + 10);
80+
else if (ch >= 'A' && ch <= 'F')
81+
*hex = (*hex << 4) | (ch - 'A' + 10);
82+
else if (first_read)
83+
return -2;
84+
else
85+
return ch;
86+
first_read = false;
87+
}
88+
}
89+
90+
/* Read a positive decimal value with out argument dec. If the first character
91+
* isn't a decimal returns -2, io->eof returns -1, otherwise returns the
92+
* character after the decimal value which may be -1 for eof. If the read value
93+
* is larger than a u64 the high-order bits will be dropped.
94+
*/
95+
static inline int io__get_dec(struct io *io, __u64 *dec)
96+
{
97+
bool first_read = true;
98+
99+
*dec = 0;
100+
while (true) {
101+
int ch = io__get_char(io);
102+
103+
if (ch < 0)
104+
return ch;
105+
if (ch >= '0' && ch <= '9')
106+
*dec = (*dec * 10) + ch - '0';
107+
else if (first_read)
108+
return -2;
109+
else
110+
return ch;
111+
first_read = false;
112+
}
113+
}
114+
115+
#endif /* __API_IO__ */

tools/lib/perf/cpumap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list)
247247

248248
int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx)
249249
{
250-
if (idx < cpus->nr)
250+
if (cpus && idx < cpus->nr)
251251
return cpus->map[idx];
252252

253253
return -1;

tools/lib/perf/evlist.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,8 @@
1111
#include <internal/mmap.h>
1212
#include <internal/cpumap.h>
1313
#include <internal/threadmap.h>
14-
#include <internal/xyarray.h>
1514
#include <internal/lib.h>
1615
#include <linux/zalloc.h>
17-
#include <sys/ioctl.h>
1816
#include <stdlib.h>
1917
#include <errno.h>
2018
#include <unistd.h>
@@ -125,8 +123,10 @@ static void perf_evlist__purge(struct perf_evlist *evlist)
125123
void perf_evlist__exit(struct perf_evlist *evlist)
126124
{
127125
perf_cpu_map__put(evlist->cpus);
126+
perf_cpu_map__put(evlist->all_cpus);
128127
perf_thread_map__put(evlist->threads);
129128
evlist->cpus = NULL;
129+
evlist->all_cpus = NULL;
130130
evlist->threads = NULL;
131131
fdarray__exit(&evlist->pollfd);
132132
}

tools/lib/subcmd/parse-options.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ struct option {
151151
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = "time", .help = (h), .callback = parse_opt_approxidate_cb }
152152
#define OPT_CALLBACK(s, l, v, a, h, f) \
153153
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = (a), .help = (h), .callback = (f) }
154+
#define OPT_CALLBACK_SET(s, l, v, os, a, h, f) \
155+
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = (a), .help = (h), .callback = (f), .set = check_vtype(os, bool *)}
154156
#define OPT_CALLBACK_NOOPT(s, l, v, a, h, f) \
155157
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = (a), .help = (h), .callback = (f), .flags = PARSE_OPT_NOARG }
156158
#define OPT_CALLBACK_DEFAULT(s, l, v, a, h, f, d) \

tools/lib/symbol/kallsyms.c

Lines changed: 38 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// SPDX-License-Identifier: GPL-2.0
22
#include "symbol/kallsyms.h"
3+
#include "api/io.h"
34
#include <stdio.h>
4-
#include <stdlib.h>
5+
#include <sys/stat.h>
6+
#include <fcntl.h>
57

68
u8 kallsyms2elf_type(char type)
79
{
@@ -15,74 +17,62 @@ bool kallsyms__is_function(char symbol_type)
1517
return symbol_type == 'T' || symbol_type == 'W';
1618
}
1719

18-
/*
19-
* While we find nice hex chars, build a long_val.
20-
* Return number of chars processed.
21-
*/
22-
int hex2u64(const char *ptr, u64 *long_val)
20+
static void read_to_eol(struct io *io)
2321
{
24-
char *p;
22+
int ch;
2523

26-
*long_val = strtoull(ptr, &p, 16);
27-
28-
return p - ptr;
24+
for (;;) {
25+
ch = io__get_char(io);
26+
if (ch < 0 || ch == '\n')
27+
return;
28+
}
2929
}
3030

3131
int kallsyms__parse(const char *filename, void *arg,
3232
int (*process_symbol)(void *arg, const char *name,
3333
char type, u64 start))
3434
{
35-
char *line = NULL;
36-
size_t n;
37-
int err = -1;
38-
FILE *file = fopen(filename, "r");
39-
40-
if (file == NULL)
41-
goto out_failure;
42-
43-
err = 0;
35+
struct io io;
36+
char bf[BUFSIZ];
37+
int err;
4438

45-
while (!feof(file)) {
46-
u64 start;
47-
int line_len, len;
48-
char symbol_type;
49-
char *symbol_name;
39+
io.fd = open(filename, O_RDONLY, 0);
5040

51-
line_len = getline(&line, &n, file);
52-
if (line_len < 0 || !line)
53-
break;
41+
if (io.fd < 0)
42+
return -1;
5443

55-
line[--line_len] = '\0'; /* \n */
44+
io__init(&io, io.fd, bf, sizeof(bf));
5645

57-
len = hex2u64(line, &start);
46+
err = 0;
47+
while (!io.eof) {
48+
__u64 start;
49+
int ch;
50+
size_t i;
51+
char symbol_type;
52+
char symbol_name[KSYM_NAME_LEN + 1];
5853

59-
/* Skip the line if we failed to parse the address. */
60-
if (!len)
54+
if (io__get_hex(&io, &start) != ' ') {
55+
read_to_eol(&io);
6156
continue;
62-
63-
len++;
64-
if (len + 2 >= line_len)
57+
}
58+
symbol_type = io__get_char(&io);
59+
if (io__get_char(&io) != ' ') {
60+
read_to_eol(&io);
6561
continue;
66-
67-
symbol_type = line[len];
68-
len += 2;
69-
symbol_name = line + len;
70-
len = line_len - len;
71-
72-
if (len >= KSYM_NAME_LEN) {
73-
err = -1;
74-
break;
7562
}
63+
for (i = 0; i < sizeof(symbol_name); i++) {
64+
ch = io__get_char(&io);
65+
if (ch < 0 || ch == '\n')
66+
break;
67+
symbol_name[i] = ch;
68+
}
69+
symbol_name[i] = '\0';
7670

7771
err = process_symbol(arg, symbol_name, symbol_type, start);
7872
if (err)
7973
break;
8074
}
8175

82-
free(line);
83-
fclose(file);
76+
close(io.fd);
8477
return err;
85-
86-
out_failure:
87-
return -1;
8878
}

tools/lib/symbol/kallsyms.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ static inline u8 kallsyms2elf_binding(char type)
1818
return isupper(type) ? STB_GLOBAL : STB_LOCAL;
1919
}
2020

21-
int hex2u64(const char *ptr, u64 *long_val);
22-
2321
u8 kallsyms2elf_type(char type);
2422

2523
bool kallsyms__is_function(char symbol_type);

0 commit comments

Comments
 (0)