Skip to content

Commit fdca7c1

Browse files
author
Ingo Molnar
committed
Merge tag 'perf-core-for-mingo-5.7-20200310' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: perf stat: Jin Yao: - Show percore counts in per CPU output. perf report: Jin Yao: - Allow selecting which block info columns to report and its order. - Support color ops to print block percents in color. - Fix wrong block address comparison in block_info__cmp(). perf annotate: Ravi Bangoria: - Get rid of annotation->nr_jumps, unused. expr: Jiri Olsa: - Move expr lexer to flex. llvm: Arnaldo Carvalho de Melo: - Add debug hint message about missing kernel-devel package. core: Kan Liang: - Initial patches to support the recently added PERF_SAMPLE_BRANCH_HW_INDEX kernel feature. - Add check for unexpected use of reserved membrs in event attr, so that in the future older perf tools will complain instead of silently try to process unknown features. libapi: Namhyung Kim: - Adopt cgroupsfs_find_mountpoint() from tools/perf/util/. libperf: Michael Petlan: - Add counting example. libtraceevent: Steven Rostedt (VMware): - Remove extra '\n' in print_event_time(). Signed-off-by: Arnaldo Carvalho de Melo <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
2 parents e48667b + f787fef commit fdca7c1

Some content is hidden

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

41 files changed

+755
-382
lines changed

tools/include/uapi/linux/perf_event.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ enum perf_branch_sample_type_shift {
181181

182182
PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT = 16, /* save branch type */
183183

184+
PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT = 17, /* save low level index of raw branch records */
185+
184186
PERF_SAMPLE_BRANCH_MAX_SHIFT /* non-ABI */
185187
};
186188

@@ -208,6 +210,8 @@ enum perf_branch_sample_type {
208210
PERF_SAMPLE_BRANCH_TYPE_SAVE =
209211
1U << PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT,
210212

213+
PERF_SAMPLE_BRANCH_HW_INDEX = 1U << PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT,
214+
211215
PERF_SAMPLE_BRANCH_MAX = 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
212216
};
213217

@@ -853,7 +857,9 @@ enum perf_event_type {
853857
* char data[size];}&& PERF_SAMPLE_RAW
854858
*
855859
* { u64 nr;
856-
* { u64 from, to, flags } lbr[nr];} && PERF_SAMPLE_BRANCH_STACK
860+
* { u64 hw_idx; } && PERF_SAMPLE_BRANCH_HW_INDEX
861+
* { u64 from, to, flags } lbr[nr];
862+
* } && PERF_SAMPLE_BRANCH_STACK
857863
*
858864
* { u64 abi; # enum perf_sample_regs_abi
859865
* u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_USER

tools/lib/api/fs/Build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
libapi-y += fs.o
22
libapi-y += tracing_path.o
3+
libapi-y += cgroup.o

tools/lib/api/fs/cgroup.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#include <linux/stringify.h>
3+
#include <sys/types.h>
4+
#include <sys/stat.h>
5+
#include <fcntl.h>
6+
#include <stdio.h>
7+
#include <stdlib.h>
8+
#include <string.h>
9+
#include "fs.h"
10+
11+
int cgroupfs_find_mountpoint(char *buf, size_t maxlen, const char *subsys)
12+
{
13+
FILE *fp;
14+
char mountpoint[PATH_MAX + 1], tokens[PATH_MAX + 1], type[PATH_MAX + 1];
15+
char path_v1[PATH_MAX + 1], path_v2[PATH_MAX + 2], *path;
16+
char *token, *saved_ptr = NULL;
17+
18+
fp = fopen("/proc/mounts", "r");
19+
if (!fp)
20+
return -1;
21+
22+
/*
23+
* in order to handle split hierarchy, we need to scan /proc/mounts
24+
* and inspect every cgroupfs mount point to find one that has
25+
* perf_event subsystem
26+
*/
27+
path_v1[0] = '\0';
28+
path_v2[0] = '\0';
29+
30+
while (fscanf(fp, "%*s %"__stringify(PATH_MAX)"s %"__stringify(PATH_MAX)"s %"
31+
__stringify(PATH_MAX)"s %*d %*d\n",
32+
mountpoint, type, tokens) == 3) {
33+
34+
if (!path_v1[0] && !strcmp(type, "cgroup")) {
35+
36+
token = strtok_r(tokens, ",", &saved_ptr);
37+
38+
while (token != NULL) {
39+
if (subsys && !strcmp(token, subsys)) {
40+
strcpy(path_v1, mountpoint);
41+
break;
42+
}
43+
token = strtok_r(NULL, ",", &saved_ptr);
44+
}
45+
}
46+
47+
if (!path_v2[0] && !strcmp(type, "cgroup2"))
48+
strcpy(path_v2, mountpoint);
49+
50+
if (path_v1[0] && path_v2[0])
51+
break;
52+
}
53+
fclose(fp);
54+
55+
if (path_v1[0])
56+
path = path_v1;
57+
else if (path_v2[0])
58+
path = path_v2;
59+
else
60+
return -1;
61+
62+
if (strlen(path) < maxlen) {
63+
strcpy(buf, path);
64+
return 0;
65+
}
66+
return -1;
67+
}

tools/lib/api/fs/fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ FS(bpf_fs)
2828
#undef FS
2929

3030

31+
int cgroupfs_find_mountpoint(char *buf, size_t maxlen, const char *subsys);
32+
3133
int filename__read_int(const char *filename, int *value);
3234
int filename__read_ull(const char *filename, unsigned long long *value);
3335
int filename__read_xll(const char *filename, unsigned long long *value);
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#include <linux/perf_event.h>
2+
#include <perf/evlist.h>
3+
#include <perf/evsel.h>
4+
#include <perf/cpumap.h>
5+
#include <perf/threadmap.h>
6+
#include <perf/mmap.h>
7+
#include <perf/core.h>
8+
#include <perf/event.h>
9+
#include <stdio.h>
10+
#include <unistd.h>
11+
12+
static int libperf_print(enum libperf_print_level level,
13+
const char *fmt, va_list ap)
14+
{
15+
return vfprintf(stderr, fmt, ap);
16+
}
17+
18+
int main(int argc, char **argv)
19+
{
20+
int count = 100000, err = 0;
21+
struct perf_evlist *evlist;
22+
struct perf_evsel *evsel;
23+
struct perf_thread_map *threads;
24+
struct perf_counts_values counts;
25+
26+
struct perf_event_attr attr1 = {
27+
.type = PERF_TYPE_SOFTWARE,
28+
.config = PERF_COUNT_SW_CPU_CLOCK,
29+
.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING,
30+
.disabled = 1,
31+
};
32+
struct perf_event_attr attr2 = {
33+
.type = PERF_TYPE_SOFTWARE,
34+
.config = PERF_COUNT_SW_TASK_CLOCK,
35+
.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING,
36+
.disabled = 1,
37+
};
38+
39+
libperf_init(libperf_print);
40+
threads = perf_thread_map__new_dummy();
41+
if (!threads) {
42+
fprintf(stderr, "failed to create threads\n");
43+
return -1;
44+
}
45+
perf_thread_map__set_pid(threads, 0, 0);
46+
evlist = perf_evlist__new();
47+
if (!evlist) {
48+
fprintf(stderr, "failed to create evlist\n");
49+
goto out_threads;
50+
}
51+
evsel = perf_evsel__new(&attr1);
52+
if (!evsel) {
53+
fprintf(stderr, "failed to create evsel1\n");
54+
goto out_evlist;
55+
}
56+
perf_evlist__add(evlist, evsel);
57+
evsel = perf_evsel__new(&attr2);
58+
if (!evsel) {
59+
fprintf(stderr, "failed to create evsel2\n");
60+
goto out_evlist;
61+
}
62+
perf_evlist__add(evlist, evsel);
63+
perf_evlist__set_maps(evlist, NULL, threads);
64+
err = perf_evlist__open(evlist);
65+
if (err) {
66+
fprintf(stderr, "failed to open evsel\n");
67+
goto out_evlist;
68+
}
69+
perf_evlist__enable(evlist);
70+
while (count--);
71+
perf_evlist__disable(evlist);
72+
perf_evlist__for_each_evsel(evlist, evsel) {
73+
perf_evsel__read(evsel, 0, 0, &counts);
74+
fprintf(stdout, "count %llu, enabled %llu, run %llu\n",
75+
counts.val, counts.ena, counts.run);
76+
}
77+
perf_evlist__close(evlist);
78+
out_evlist:
79+
perf_evlist__delete(evlist);
80+
out_threads:
81+
perf_thread_map__put(threads);
82+
return err;
83+
}

tools/lib/traceevent/event-parse.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5541,7 +5541,7 @@ static void print_event_time(struct tep_handle *tep, struct trace_seq *s,
55415541
if (p10 > 1 && p10 < time)
55425542
trace_seq_printf(s, "%5llu.%0*llu", time / p10, prec, time % p10);
55435543
else
5544-
trace_seq_printf(s, "%12llu\n", time);
5544+
trace_seq_printf(s, "%12llu", time);
55455545
}
55465546

55475547
struct print_event_type {

tools/perf/Documentation/perf-stat.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,15 @@ Configure all used events to run in kernel space.
334334
--all-user::
335335
Configure all used events to run in user space.
336336

337+
--percore-show-thread::
338+
The event modifier "percore" has supported to sum up the event counts
339+
for all hardware threads in a core and show the counts per core.
340+
341+
This option with event modifier "percore" enabled also sums up the event
342+
counts for all hardware threads in a core but show the sum counts per
343+
hardware thread. This is essentially a replacement for the any bit and
344+
convenient for post processing.
345+
337346
EXAMPLES
338347
--------
339348

tools/perf/builtin-diff.c

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -572,37 +572,20 @@ static void init_block_hist(struct block_hist *bh)
572572
bh->valid = true;
573573
}
574574

575-
static int block_pair_cmp(struct hist_entry *a, struct hist_entry *b)
576-
{
577-
struct block_info *bi_a = a->block_info;
578-
struct block_info *bi_b = b->block_info;
579-
int cmp;
580-
581-
if (!bi_a->sym || !bi_b->sym)
582-
return -1;
583-
584-
cmp = strcmp(bi_a->sym->name, bi_b->sym->name);
585-
586-
if ((!cmp) && (bi_a->start == bi_b->start) && (bi_a->end == bi_b->end))
587-
return 0;
588-
589-
return -1;
590-
}
591-
592575
static struct hist_entry *get_block_pair(struct hist_entry *he,
593576
struct hists *hists_pair)
594577
{
595578
struct rb_root_cached *root = hists_pair->entries_in;
596579
struct rb_node *next = rb_first_cached(root);
597-
int cmp;
580+
int64_t cmp;
598581

599582
while (next != NULL) {
600583
struct hist_entry *he_pair = rb_entry(next, struct hist_entry,
601584
rb_node_in);
602585

603586
next = rb_next(&he_pair->rb_node_in);
604587

605-
cmp = block_pair_cmp(he_pair, he);
588+
cmp = __block_info__cmp(he_pair, he);
606589
if (!cmp)
607590
return he_pair;
608591
}
@@ -1312,7 +1295,8 @@ static int cycles_printf(struct hist_entry *he, struct hist_entry *pair,
13121295
end_line = map__srcline(he->ms.map, bi->sym->start + bi->end,
13131296
he->ms.sym);
13141297

1315-
if ((start_line != SRCLINE_UNKNOWN) && (end_line != SRCLINE_UNKNOWN)) {
1298+
if ((strncmp(start_line, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0) &&
1299+
(strncmp(end_line, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) != 0)) {
13161300
scnprintf(buf, sizeof(buf), "[%s -> %s] %4ld",
13171301
start_line, end_line, block_he->diff.cycles);
13181302
} else {

tools/perf/builtin-report.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ struct report {
104104
bool symbol_ipc;
105105
bool total_cycles_mode;
106106
struct block_report *block_reports;
107+
int nr_block_reports;
107108
};
108109

109110
static int report__config(const char *var, const char *value, void *cb)
@@ -966,8 +967,19 @@ static int __cmd_report(struct report *rep)
966967
report__output_resort(rep);
967968

968969
if (rep->total_cycles_mode) {
970+
int block_hpps[6] = {
971+
PERF_HPP_REPORT__BLOCK_TOTAL_CYCLES_PCT,
972+
PERF_HPP_REPORT__BLOCK_LBR_CYCLES,
973+
PERF_HPP_REPORT__BLOCK_CYCLES_PCT,
974+
PERF_HPP_REPORT__BLOCK_AVG_CYCLES,
975+
PERF_HPP_REPORT__BLOCK_RANGE,
976+
PERF_HPP_REPORT__BLOCK_DSO,
977+
};
978+
969979
rep->block_reports = block_info__create_report(session->evlist,
970-
rep->total_cycles);
980+
rep->total_cycles,
981+
block_hpps, 6,
982+
&rep->nr_block_reports);
971983
if (!rep->block_reports)
972984
return -1;
973985
}
@@ -1551,8 +1563,11 @@ int cmd_report(int argc, const char **argv)
15511563
zfree(&report.ptime_range);
15521564
}
15531565

1554-
if (report.block_reports)
1555-
zfree(&report.block_reports);
1566+
if (report.block_reports) {
1567+
block_info__free_report(report.block_reports,
1568+
report.nr_block_reports);
1569+
report.block_reports = NULL;
1570+
}
15561571

15571572
zstd_fini(&(session->zstd_data));
15581573
perf_session__delete(session);

0 commit comments

Comments
 (0)