Skip to content

Commit 54a0f91

Browse files
committed
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: perf top: Fix live annotation in the --stdio interface perf top tui: Don't recalc column widths considering just the first page perf report: Add progress bar when processing time ordered events perf hists browser: Warn about lost events perf tools: Fix a typo of command name as trace-cmd perf hists: Fix recalculation of total_period when sorting entries perf header: Fix build on old systems perf ui browser: Handle K_RESIZE in dialog windows perf ui browser: No need to switch char sets that often perf hists browser: Use K_TIMER perf ui: Rename ui__warning_paranoid to ui__error_paranoid perf ui: Reimplement the popup windows using libslang perf ui: Reimplement ui__popup_menu using ui__browser perf ui: Reimplement ui_helpline using libslang perf ui: Improve handling sigwinch a bit perf ui progress: Reimplement using slang perf evlist: Fix grouping of multiple events
2 parents 94956ee + f9e3d4b commit 54a0f91

31 files changed

+624
-288
lines changed

tools/perf/builtin-record.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,13 +262,16 @@ static bool perf_evlist__equal(struct perf_evlist *evlist,
262262

263263
static void open_counters(struct perf_evlist *evlist)
264264
{
265-
struct perf_evsel *pos;
265+
struct perf_evsel *pos, *first;
266266

267267
if (evlist->cpus->map[0] < 0)
268268
no_inherit = true;
269269

270+
first = list_entry(evlist->entries.next, struct perf_evsel, node);
271+
270272
list_for_each_entry(pos, &evlist->entries, node) {
271273
struct perf_event_attr *attr = &pos->attr;
274+
struct xyarray *group_fd = NULL;
272275
/*
273276
* Check if parse_single_tracepoint_event has already asked for
274277
* PERF_SAMPLE_TIME.
@@ -283,15 +286,19 @@ static void open_counters(struct perf_evlist *evlist)
283286
*/
284287
bool time_needed = attr->sample_type & PERF_SAMPLE_TIME;
285288

289+
if (group && pos != first)
290+
group_fd = first->fd;
291+
286292
config_attr(pos, evlist);
287293
retry_sample_id:
288294
attr->sample_id_all = sample_id_all_avail ? 1 : 0;
289295
try_again:
290-
if (perf_evsel__open(pos, evlist->cpus, evlist->threads, group) < 0) {
296+
if (perf_evsel__open(pos, evlist->cpus, evlist->threads, group,
297+
group_fd) < 0) {
291298
int err = errno;
292299

293300
if (err == EPERM || err == EACCES) {
294-
ui__warning_paranoid();
301+
ui__error_paranoid();
295302
exit(EXIT_FAILURE);
296303
} else if (err == ENODEV && cpu_list) {
297304
die("No such device - did you specify"

tools/perf/builtin-stat.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,14 @@ struct stats runtime_itlb_cache_stats[MAX_NR_CPUS];
278278
struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS];
279279
struct stats walltime_nsecs_stats;
280280

281-
static int create_perf_stat_counter(struct perf_evsel *evsel)
281+
static int create_perf_stat_counter(struct perf_evsel *evsel,
282+
struct perf_evsel *first)
282283
{
283284
struct perf_event_attr *attr = &evsel->attr;
285+
struct xyarray *group_fd = NULL;
286+
287+
if (group && evsel != first)
288+
group_fd = first->fd;
284289

285290
if (scale)
286291
attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
@@ -289,14 +294,15 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)
289294
attr->inherit = !no_inherit;
290295

291296
if (system_wide)
292-
return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, group);
293-
297+
return perf_evsel__open_per_cpu(evsel, evsel_list->cpus,
298+
group, group_fd);
294299
if (target_pid == -1 && target_tid == -1) {
295300
attr->disabled = 1;
296301
attr->enable_on_exec = 1;
297302
}
298303

299-
return perf_evsel__open_per_thread(evsel, evsel_list->threads, group);
304+
return perf_evsel__open_per_thread(evsel, evsel_list->threads,
305+
group, group_fd);
300306
}
301307

302308
/*
@@ -396,7 +402,7 @@ static int read_counter(struct perf_evsel *counter)
396402
static int run_perf_stat(int argc __used, const char **argv)
397403
{
398404
unsigned long long t0, t1;
399-
struct perf_evsel *counter;
405+
struct perf_evsel *counter, *first;
400406
int status = 0;
401407
int child_ready_pipe[2], go_pipe[2];
402408
const bool forks = (argc > 0);
@@ -453,8 +459,10 @@ static int run_perf_stat(int argc __used, const char **argv)
453459
close(child_ready_pipe[0]);
454460
}
455461

462+
first = list_entry(evsel_list->entries.next, struct perf_evsel, node);
463+
456464
list_for_each_entry(counter, &evsel_list->entries, node) {
457-
if (create_perf_stat_counter(counter) < 0) {
465+
if (create_perf_stat_counter(counter, first) < 0) {
458466
if (errno == EINVAL || errno == ENOSYS || errno == ENOENT) {
459467
if (verbose)
460468
ui__warning("%s event is not supported by the kernel.\n",

tools/perf/builtin-test.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ static int test__open_syscall_event(void)
291291
goto out_thread_map_delete;
292292
}
293293

294-
if (perf_evsel__open_per_thread(evsel, threads, false) < 0) {
294+
if (perf_evsel__open_per_thread(evsel, threads, false, NULL) < 0) {
295295
pr_debug("failed to open counter: %s, "
296296
"tweak /proc/sys/kernel/perf_event_paranoid?\n",
297297
strerror(errno));
@@ -366,7 +366,7 @@ static int test__open_syscall_event_on_all_cpus(void)
366366
goto out_thread_map_delete;
367367
}
368368

369-
if (perf_evsel__open(evsel, cpus, threads, false) < 0) {
369+
if (perf_evsel__open(evsel, cpus, threads, false, NULL) < 0) {
370370
pr_debug("failed to open counter: %s, "
371371
"tweak /proc/sys/kernel/perf_event_paranoid?\n",
372372
strerror(errno));
@@ -531,7 +531,7 @@ static int test__basic_mmap(void)
531531

532532
perf_evlist__add(evlist, evsels[i]);
533533

534-
if (perf_evsel__open(evsels[i], cpus, threads, false) < 0) {
534+
if (perf_evsel__open(evsels[i], cpus, threads, false, NULL) < 0) {
535535
pr_debug("failed to open counter: %s, "
536536
"tweak /proc/sys/kernel/perf_event_paranoid?\n",
537537
strerror(errno));

tools/perf/builtin-top.c

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ static bool vmlinux_warned;
8989
static bool inherit = false;
9090
static int realtime_prio = 0;
9191
static bool group = false;
92+
static bool sample_id_all_avail = true;
9293
static unsigned int mmap_pages = 128;
9394

9495
static bool dump_symtab = false;
@@ -199,7 +200,8 @@ static void record_precise_ip(struct hist_entry *he, int counter, u64 ip)
199200
struct symbol *sym;
200201

201202
if (he == NULL || he->ms.sym == NULL ||
202-
(he != top.sym_filter_entry && use_browser != 1))
203+
((top.sym_filter_entry == NULL ||
204+
top.sym_filter_entry->ms.sym != he->ms.sym) && use_browser != 1))
203205
return;
204206

205207
sym = he->ms.sym;
@@ -289,11 +291,13 @@ static void print_sym_table(void)
289291

290292
printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
291293

292-
if (top.total_lost_warned != top.session->hists.stats.total_lost) {
293-
top.total_lost_warned = top.session->hists.stats.total_lost;
294-
color_fprintf(stdout, PERF_COLOR_RED, "WARNING:");
295-
printf(" LOST %" PRIu64 " events, Check IO/CPU overload\n",
296-
top.total_lost_warned);
294+
if (top.sym_evsel->hists.stats.nr_lost_warned !=
295+
top.sym_evsel->hists.stats.nr_events[PERF_RECORD_LOST]) {
296+
top.sym_evsel->hists.stats.nr_lost_warned =
297+
top.sym_evsel->hists.stats.nr_events[PERF_RECORD_LOST];
298+
color_fprintf(stdout, PERF_COLOR_RED,
299+
"WARNING: LOST %d chunks, Check IO/CPU overload",
300+
top.sym_evsel->hists.stats.nr_lost_warned);
297301
++printed;
298302
}
299303

@@ -561,7 +565,6 @@ static void perf_top__sort_new_samples(void *arg)
561565
hists__decay_entries_threaded(&t->sym_evsel->hists,
562566
top.hide_user_symbols,
563567
top.hide_kernel_symbols);
564-
hists__output_recalc_col_len(&t->sym_evsel->hists, winsize.ws_row - 3);
565568
}
566569

567570
static void *display_thread_tui(void *arg __used)
@@ -671,6 +674,7 @@ static int symbol_filter(struct map *map __used, struct symbol *sym)
671674
}
672675

673676
static void perf_event__process_sample(const union perf_event *event,
677+
struct perf_evsel *evsel,
674678
struct perf_sample *sample,
675679
struct perf_session *session)
676680
{
@@ -770,12 +774,8 @@ static void perf_event__process_sample(const union perf_event *event,
770774
}
771775

772776
if (al.sym == NULL || !al.sym->ignore) {
773-
struct perf_evsel *evsel;
774777
struct hist_entry *he;
775778

776-
evsel = perf_evlist__id2evsel(top.evlist, sample->id);
777-
assert(evsel != NULL);
778-
779779
if ((sort__has_parent || symbol_conf.use_callchain) &&
780780
sample->callchain) {
781781
err = perf_session__resolve_callchain(session, al.thread,
@@ -807,6 +807,7 @@ static void perf_event__process_sample(const union perf_event *event,
807807
static void perf_session__mmap_read_idx(struct perf_session *self, int idx)
808808
{
809809
struct perf_sample sample;
810+
struct perf_evsel *evsel;
810811
union perf_event *event;
811812
int ret;
812813

@@ -817,10 +818,16 @@ static void perf_session__mmap_read_idx(struct perf_session *self, int idx)
817818
continue;
818819
}
819820

821+
evsel = perf_evlist__id2evsel(self->evlist, sample.id);
822+
assert(evsel != NULL);
823+
820824
if (event->header.type == PERF_RECORD_SAMPLE)
821-
perf_event__process_sample(event, &sample, self);
822-
else
825+
perf_event__process_sample(event, evsel, &sample, self);
826+
else if (event->header.type < PERF_RECORD_MAX) {
827+
hists__inc_nr_events(&evsel->hists, event->header.type);
823828
perf_event__process(event, &sample, self);
829+
} else
830+
++self->hists.stats.nr_unknown_events;
824831
}
825832
}
826833

@@ -834,10 +841,16 @@ static void perf_session__mmap_read(struct perf_session *self)
834841

835842
static void start_counters(struct perf_evlist *evlist)
836843
{
837-
struct perf_evsel *counter;
844+
struct perf_evsel *counter, *first;
845+
846+
first = list_entry(evlist->entries.next, struct perf_evsel, node);
838847

839848
list_for_each_entry(counter, &evlist->entries, node) {
840849
struct perf_event_attr *attr = &counter->attr;
850+
struct xyarray *group_fd = NULL;
851+
852+
if (group && counter != first)
853+
group_fd = first->fd;
841854

842855
attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID;
843856

@@ -858,14 +871,23 @@ static void start_counters(struct perf_evlist *evlist)
858871
attr->mmap = 1;
859872
attr->comm = 1;
860873
attr->inherit = inherit;
874+
retry_sample_id:
875+
attr->sample_id_all = sample_id_all_avail ? 1 : 0;
861876
try_again:
862877
if (perf_evsel__open(counter, top.evlist->cpus,
863-
top.evlist->threads, group) < 0) {
878+
top.evlist->threads, group,
879+
group_fd) < 0) {
864880
int err = errno;
865881

866882
if (err == EPERM || err == EACCES) {
867-
ui__warning_paranoid();
883+
ui__error_paranoid();
868884
goto out_err;
885+
} else if (err == EINVAL && sample_id_all_avail) {
886+
/*
887+
* Old kernel, no attr->sample_id_type_all field
888+
*/
889+
sample_id_all_avail = false;
890+
goto retry_sample_id;
869891
}
870892
/*
871893
* If it's cycles then fall back to hrtimer

tools/perf/util/annotate.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,12 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
310310
}
311311
err = -ENOENT;
312312
dso->annotate_warned = 1;
313-
pr_err("Can't annotate %s: No vmlinux file%s was found in the "
314-
"path.\nPlease use 'perf buildid-cache -av vmlinux' or "
315-
"--vmlinux vmlinux.\n",
313+
pr_err("Can't annotate %s:\n\n"
314+
"No vmlinux file%s\nwas found in the path.\n\n"
315+
"Please use:\n\n"
316+
" perf buildid-cache -av vmlinux\n\n"
317+
"or:\n\n"
318+
" --vmlinux vmlinux",
316319
sym->name, build_id_msg ?: "");
317320
goto out_free_filename;
318321
}

tools/perf/util/debug.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,20 @@ int dump_printf(const char *fmt, ...)
4747
}
4848

4949
#ifdef NO_NEWT_SUPPORT
50-
void ui__warning(const char *format, ...)
50+
int ui__warning(const char *format, ...)
5151
{
5252
va_list args;
5353

5454
va_start(args, format);
5555
vfprintf(stderr, format, args);
5656
va_end(args);
57+
return 0;
5758
}
5859
#endif
5960

60-
void ui__warning_paranoid(void)
61+
int ui__error_paranoid(void)
6162
{
62-
ui__warning("Permission error - are you root?\n"
63+
return ui__error("Permission error - are you root?\n"
6364
"Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n"
6465
" -1 - Not paranoid at all\n"
6566
" 0 - Disallow raw tracepoint access for unpriv\n"

tools/perf/util/debug.h

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,18 @@ static inline int ui_helpline__show_help(const char *format __used, va_list ap _
1919
return 0;
2020
}
2121

22-
static inline struct ui_progress *ui_progress__new(const char *title __used,
23-
u64 total __used)
24-
{
25-
return (struct ui_progress *)1;
26-
}
27-
28-
static inline void ui_progress__update(struct ui_progress *self __used,
29-
u64 curr __used) {}
22+
static inline void ui_progress__update(u64 curr __used, u64 total __used,
23+
const char *title __used) {}
3024

31-
static inline void ui_progress__delete(struct ui_progress *self __used) {}
25+
#define ui__error(format, arg...) ui__warning(format, ##arg)
3226
#else
3327
extern char ui_helpline__last_msg[];
3428
int ui_helpline__show_help(const char *format, va_list ap);
3529
#include "ui/progress.h"
30+
int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2)));
3631
#endif
3732

38-
void ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2)));
39-
void ui__warning_paranoid(void);
33+
int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2)));
34+
int ui__error_paranoid(void);
4035

4136
#endif /* __PERF_DEBUG_H */

tools/perf/util/evlist.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,3 +539,33 @@ void perf_evlist__set_selected(struct perf_evlist *evlist,
539539
{
540540
evlist->selected = evsel;
541541
}
542+
543+
int perf_evlist__open(struct perf_evlist *evlist, bool group)
544+
{
545+
struct perf_evsel *evsel, *first;
546+
int err, ncpus, nthreads;
547+
548+
first = list_entry(evlist->entries.next, struct perf_evsel, node);
549+
550+
list_for_each_entry(evsel, &evlist->entries, node) {
551+
struct xyarray *group_fd = NULL;
552+
553+
if (group && evsel != first)
554+
group_fd = first->fd;
555+
556+
err = perf_evsel__open(evsel, evlist->cpus, evlist->threads,
557+
group, group_fd);
558+
if (err < 0)
559+
goto out_err;
560+
}
561+
562+
return 0;
563+
out_err:
564+
ncpus = evlist->cpus ? evlist->cpus->nr : 1;
565+
nthreads = evlist->threads ? evlist->threads->nr : 1;
566+
567+
list_for_each_entry_reverse(evsel, &evlist->entries, node)
568+
perf_evsel__close(evsel, ncpus, nthreads);
569+
570+
return err;
571+
}

tools/perf/util/evlist.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id);
5050

5151
union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx);
5252

53+
int perf_evlist__open(struct perf_evlist *evlist, bool group);
54+
5355
int perf_evlist__alloc_mmap(struct perf_evlist *evlist);
5456
int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite);
5557
void perf_evlist__munmap(struct perf_evlist *evlist);

0 commit comments

Comments
 (0)