aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-07-16 07:46:34 -0400
committerIngo Molnar <mingo@kernel.org>2014-07-16 07:46:34 -0400
commitf4aa84fc2a1c3a1ae1b81e434e8cde1c5f98a6b4 (patch)
tree5cccbfb9ef7d5d848afe67740f5ca6fa1cf5fb04 /tools
parentfbe26abe118ee1262b4ab0d12fefd42647eaea35 (diff)
parent4414a3c51028aea2ae2fe06c0377490eaa6abbfd (diff)
Merge tag 'perf-core-for-mingo' 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: User visible changes: o Prep patches to support 'perf kvm stat' on s390 (Alexander Yarygin) o Add pagefault statistics in 'trace' (Stanislav Fomichev) o Add header for columns in 'top' and 'report' TUI browsers (Jiri Olsa) o Add pagefault statistics in 'trace' (Stanislav Fomichev) Build fixes: o Fix build on 32-bit systems (Arnaldo Carvalho de Melo) Cleanups: o Convert open coded equivalents to asprintf() (Andy Shevchenko) Plumbing changes: o Allow reserving a row for header purposes in the hists browser (Arnaldo Carvalho de Melo) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/arch/s390/Makefile1
-rw-r--r--tools/perf/arch/s390/util/header.c28
-rw-r--r--tools/perf/arch/x86/Makefile1
-rw-r--r--tools/perf/builtin-kvm.c72
-rw-r--r--tools/perf/builtin-trace.c23
-rw-r--r--tools/perf/config/Makefile4
-rw-r--r--tools/perf/perf-sys.h1
-rw-r--r--tools/perf/ui/browser.c37
-rw-r--r--tools/perf/ui/browser.h3
-rw-r--r--tools/perf/ui/browsers/hists.c128
-rw-r--r--tools/perf/util/config.c13
-rw-r--r--tools/perf/util/data.c2
-rw-r--r--tools/perf/util/sort.c2
-rw-r--r--tools/perf/util/symbol.c1
-rw-r--r--tools/perf/util/symbol.h3
-rw-r--r--tools/perf/util/trace-event-info.c12
-rw-r--r--tools/perf/util/util.c9
17 files changed, 249 insertions, 91 deletions
diff --git a/tools/perf/arch/s390/Makefile b/tools/perf/arch/s390/Makefile
index 15130b50dfe3..744e629797be 100644
--- a/tools/perf/arch/s390/Makefile
+++ b/tools/perf/arch/s390/Makefile
@@ -2,3 +2,4 @@ ifndef NO_DWARF
2PERF_HAVE_DWARF_REGS := 1 2PERF_HAVE_DWARF_REGS := 1
3LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o 3LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
4endif 4endif
5LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o
diff --git a/tools/perf/arch/s390/util/header.c b/tools/perf/arch/s390/util/header.c
new file mode 100644
index 000000000000..9fa6c3e5782c
--- /dev/null
+++ b/tools/perf/arch/s390/util/header.c
@@ -0,0 +1,28 @@
1/*
2 * Implementation of get_cpuid().
3 *
4 * Copyright 2014 IBM Corp.
5 * Author(s): Alexander Yarygin <yarygin@linux.vnet.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License (version 2 only)
9 * as published by the Free Software Foundation.
10 */
11
12#include <sys/types.h>
13#include <unistd.h>
14#include <stdio.h>
15#include <string.h>
16
17#include "../../util/header.h"
18
19int get_cpuid(char *buffer, size_t sz)
20{
21 const char *cpuid = "IBM/S390";
22
23 if (strlen(cpuid) + 1 > sz)
24 return -1;
25
26 strcpy(buffer, cpuid);
27 return 0;
28}
diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
index 1641542e3636..d3939014a877 100644
--- a/tools/perf/arch/x86/Makefile
+++ b/tools/perf/arch/x86/Makefile
@@ -15,3 +15,4 @@ endif
15LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o 15LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o
16LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/tsc.o 16LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/tsc.o
17LIB_H += arch/$(ARCH)/util/tsc.h 17LIB_H += arch/$(ARCH)/util/tsc.h
18HAVE_KVM_STAT_SUPPORT := 1
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 0f1e5a2f6ad7..41dbeaf8cc11 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -29,7 +29,7 @@
29#include <pthread.h> 29#include <pthread.h>
30#include <math.h> 30#include <math.h>
31 31
32#if defined(__i386__) || defined(__x86_64__) 32#ifdef HAVE_KVM_STAT_SUPPORT
33#include <asm/svm.h> 33#include <asm/svm.h>
34#include <asm/vmx.h> 34#include <asm/vmx.h>
35#include <asm/kvm.h> 35#include <asm/kvm.h>
@@ -99,7 +99,6 @@ struct perf_kvm_stat {
99 int trace_vcpu; 99 int trace_vcpu;
100 100
101 struct exit_reasons_table *exit_reasons; 101 struct exit_reasons_table *exit_reasons;
102 int exit_reasons_size;
103 const char *exit_reasons_isa; 102 const char *exit_reasons_isa;
104 103
105 struct kvm_events_ops *events_ops; 104 struct kvm_events_ops *events_ops;
@@ -158,20 +157,19 @@ static bool exit_event_end(struct perf_evsel *evsel,
158 return kvm_entry_event(evsel); 157 return kvm_entry_event(evsel);
159} 158}
160 159
161static struct exit_reasons_table vmx_exit_reasons[] = { 160#define define_exit_reasons_table(name, symbols) \
162 VMX_EXIT_REASONS 161 static struct exit_reasons_table name[] = { \
163}; 162 symbols, { -1, NULL } \
163 }
164 164
165static struct exit_reasons_table svm_exit_reasons[] = { 165define_exit_reasons_table(vmx_exit_reasons, VMX_EXIT_REASONS);
166 SVM_EXIT_REASONS 166define_exit_reasons_table(svm_exit_reasons, SVM_EXIT_REASONS);
167};
168 167
169static const char *get_exit_reason(struct perf_kvm_stat *kvm, u64 exit_code) 168static const char *get_exit_reason(struct perf_kvm_stat *kvm,
169 struct exit_reasons_table *tbl,
170 u64 exit_code)
170{ 171{
171 int i = kvm->exit_reasons_size; 172 while (tbl->reason != NULL) {
172 struct exit_reasons_table *tbl = kvm->exit_reasons;
173
174 while (i--) {
175 if (tbl->exit_code == exit_code) 173 if (tbl->exit_code == exit_code)
176 return tbl->reason; 174 return tbl->reason;
177 tbl++; 175 tbl++;
@@ -186,7 +184,8 @@ static void exit_event_decode_key(struct perf_kvm_stat *kvm,
186 struct event_key *key, 184 struct event_key *key,
187 char decode[20]) 185 char decode[20])
188{ 186{
189 const char *exit_reason = get_exit_reason(kvm, key->key); 187 const char *exit_reason = get_exit_reason(kvm, kvm->exit_reasons,
188 key->key);
190 189
191 scnprintf(decode, 20, "%s", exit_reason); 190 scnprintf(decode, 20, "%s", exit_reason);
192} 191}
@@ -836,37 +835,45 @@ static int process_sample_event(struct perf_tool *tool,
836 return 0; 835 return 0;
837} 836}
838 837
838static int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid)
839{
840 if (strstr(cpuid, "Intel")) {
841 kvm->exit_reasons = vmx_exit_reasons;
842 kvm->exit_reasons_isa = "VMX";
843 } else if (strstr(cpuid, "AMD")) {
844 kvm->exit_reasons = svm_exit_reasons;
845 kvm->exit_reasons_isa = "SVM";
846 } else
847 return -ENOTSUP;
848
849 return 0;
850}
851
839static int cpu_isa_config(struct perf_kvm_stat *kvm) 852static int cpu_isa_config(struct perf_kvm_stat *kvm)
840{ 853{
841 char buf[64], *cpuid; 854 char buf[64], *cpuid;
842 int err, isa; 855 int err;
843 856
844 if (kvm->live) { 857 if (kvm->live) {
845 err = get_cpuid(buf, sizeof(buf)); 858 err = get_cpuid(buf, sizeof(buf));
846 if (err != 0) { 859 if (err != 0) {
847 pr_err("Failed to look up CPU type (Intel or AMD)\n"); 860 pr_err("Failed to look up CPU type\n");
848 return err; 861 return err;
849 } 862 }
850 cpuid = buf; 863 cpuid = buf;
851 } else 864 } else
852 cpuid = kvm->session->header.env.cpuid; 865 cpuid = kvm->session->header.env.cpuid;
853 866
854 if (strstr(cpuid, "Intel")) 867 if (!cpuid) {
855 isa = 1; 868 pr_err("Failed to look up CPU type\n");
856 else if (strstr(cpuid, "AMD")) 869 return -EINVAL;
857 isa = 0;
858 else {
859 pr_err("CPU %s is not supported.\n", cpuid);
860 return -ENOTSUP;
861 } 870 }
862 871
863 if (isa == 1) { 872 err = cpu_isa_init(kvm, cpuid);
864 kvm->exit_reasons = vmx_exit_reasons; 873 if (err == -ENOTSUP)
865 kvm->exit_reasons_size = ARRAY_SIZE(vmx_exit_reasons); 874 pr_err("CPU %s is not supported.\n", cpuid);
866 kvm->exit_reasons_isa = "VMX";
867 }
868 875
869 return 0; 876 return err;
870} 877}
871 878
872static bool verify_vcpu(int vcpu) 879static bool verify_vcpu(int vcpu)
@@ -1585,9 +1592,6 @@ static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
1585 .report_event = "vmexit", 1592 .report_event = "vmexit",
1586 .sort_key = "sample", 1593 .sort_key = "sample",
1587 1594
1588 .exit_reasons = svm_exit_reasons,
1589 .exit_reasons_size = ARRAY_SIZE(svm_exit_reasons),
1590 .exit_reasons_isa = "SVM",
1591 }; 1595 };
1592 1596
1593 if (argc == 1) { 1597 if (argc == 1) {
@@ -1609,7 +1613,7 @@ static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
1609perf_stat: 1613perf_stat:
1610 return cmd_stat(argc, argv, NULL); 1614 return cmd_stat(argc, argv, NULL);
1611} 1615}
1612#endif 1616#endif /* HAVE_KVM_STAT_SUPPORT */
1613 1617
1614static int __cmd_record(const char *file_name, int argc, const char **argv) 1618static int __cmd_record(const char *file_name, int argc, const char **argv)
1615{ 1619{
@@ -1726,7 +1730,7 @@ int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused)
1726 return cmd_top(argc, argv, NULL); 1730 return cmd_top(argc, argv, NULL);
1727 else if (!strncmp(argv[0], "buildid-list", 12)) 1731 else if (!strncmp(argv[0], "buildid-list", 12))
1728 return __cmd_buildid_list(file_name, argc, argv); 1732 return __cmd_buildid_list(file_name, argc, argv);
1729#if defined(__i386__) || defined(__x86_64__) 1733#ifdef HAVE_KVM_STAT_SUPPORT
1730 else if (!strncmp(argv[0], "stat", 4)) 1734 else if (!strncmp(argv[0], "stat", 4))
1731 return kvm_cmd_stat(file_name, argc, argv); 1735 return kvm_cmd_stat(file_name, argc, argv);
1732#endif 1736#endif
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index dc7a694b61fe..c4a5a7d7b2cf 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1133,6 +1133,7 @@ struct thread_trace {
1133 u64 exit_time; 1133 u64 exit_time;
1134 bool entry_pending; 1134 bool entry_pending;
1135 unsigned long nr_events; 1135 unsigned long nr_events;
1136 unsigned long pfmaj, pfmin;
1136 char *entry_str; 1137 char *entry_str;
1137 double runtime_ms; 1138 double runtime_ms;
1138 struct { 1139 struct {
@@ -1787,12 +1788,12 @@ static void print_location(FILE *f, struct perf_sample *sample,
1787 fprintf(f, "%s@", al->map->dso->long_name); 1788 fprintf(f, "%s@", al->map->dso->long_name);
1788 1789
1789 if ((verbose || print_sym) && al->sym) 1790 if ((verbose || print_sym) && al->sym)
1790 fprintf(f, "%s+0x%lx", al->sym->name, 1791 fprintf(f, "%s+0x%" PRIx64, al->sym->name,
1791 al->addr - al->sym->start); 1792 al->addr - al->sym->start);
1792 else if (al->map) 1793 else if (al->map)
1793 fprintf(f, "0x%lx", al->addr); 1794 fprintf(f, "0x%" PRIx64, al->addr);
1794 else 1795 else
1795 fprintf(f, "0x%lx", sample->addr); 1796 fprintf(f, "0x%" PRIx64, sample->addr);
1796} 1797}
1797 1798
1798static int trace__pgfault(struct trace *trace, 1799static int trace__pgfault(struct trace *trace,
@@ -1804,8 +1805,20 @@ static int trace__pgfault(struct trace *trace,
1804 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 1805 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
1805 struct addr_location al; 1806 struct addr_location al;
1806 char map_type = 'd'; 1807 char map_type = 'd';
1808 struct thread_trace *ttrace;
1807 1809
1808 thread = machine__findnew_thread(trace->host, sample->pid, sample->tid); 1810 thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
1811 ttrace = thread__trace(thread, trace->output);
1812 if (ttrace == NULL)
1813 return -1;
1814
1815 if (evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ)
1816 ttrace->pfmaj++;
1817 else
1818 ttrace->pfmin++;
1819
1820 if (trace->summary_only)
1821 return 0;
1809 1822
1810 thread__find_addr_location(thread, trace->host, cpumode, MAP__FUNCTION, 1823 thread__find_addr_location(thread, trace->host, cpumode, MAP__FUNCTION,
1811 sample->ip, &al); 1824 sample->ip, &al);
@@ -2346,6 +2359,10 @@ static int trace__fprintf_one_thread(struct thread *thread, void *priv)
2346 printed += fprintf(fp, " %s (%d), ", thread__comm_str(thread), thread->tid); 2359 printed += fprintf(fp, " %s (%d), ", thread__comm_str(thread), thread->tid);
2347 printed += fprintf(fp, "%lu events, ", ttrace->nr_events); 2360 printed += fprintf(fp, "%lu events, ", ttrace->nr_events);
2348 printed += fprintf(fp, "%.1f%%", ratio); 2361 printed += fprintf(fp, "%.1f%%", ratio);
2362 if (ttrace->pfmaj)
2363 printed += fprintf(fp, ", %lu majfaults", ttrace->pfmaj);
2364 if (ttrace->pfmin)
2365 printed += fprintf(fp, ", %lu minfaults", ttrace->pfmin);
2349 printed += fprintf(fp, ", %.3f msec\n", ttrace->runtime_ms); 2366 printed += fprintf(fp, ", %.3f msec\n", ttrace->runtime_ms);
2350 printed += thread__dump_stats(ttrace, trace, fp); 2367 printed += thread__dump_stats(ttrace, trace, fp);
2351 2368
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 346bdb617544..b7f42d577c4e 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -594,6 +594,10 @@ ifndef NO_LIBNUMA
594 endif 594 endif
595endif 595endif
596 596
597ifdef HAVE_KVM_STAT_SUPPORT
598 CFLAGS += -DHAVE_KVM_STAT_SUPPORT
599endif
600
597# Among the variables below, these: 601# Among the variables below, these:
598# perfexecdir 602# perfexecdir
599# template_dir 603# template_dir
diff --git a/tools/perf/perf-sys.h b/tools/perf/perf-sys.h
index 5268a1481d23..937e4324ad94 100644
--- a/tools/perf/perf-sys.h
+++ b/tools/perf/perf-sys.h
@@ -54,6 +54,7 @@
54#define mb() asm volatile("bcr 15,0" ::: "memory") 54#define mb() asm volatile("bcr 15,0" ::: "memory")
55#define wmb() asm volatile("bcr 15,0" ::: "memory") 55#define wmb() asm volatile("bcr 15,0" ::: "memory")
56#define rmb() asm volatile("bcr 15,0" ::: "memory") 56#define rmb() asm volatile("bcr 15,0" ::: "memory")
57#define CPUINFO_PROC "vendor_id"
57#endif 58#endif
58 59
59#ifdef __sh__ 60#ifdef __sh__
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index 9d2294efc00c..6680fa5cb9dd 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -150,7 +150,7 @@ unsigned int ui_browser__rb_tree_refresh(struct ui_browser *browser)
150 while (nd != NULL) { 150 while (nd != NULL) {
151 ui_browser__gotorc(browser, row, 0); 151 ui_browser__gotorc(browser, row, 0);
152 browser->write(browser, nd, row); 152 browser->write(browser, nd, row);
153 if (++row == browser->height) 153 if (++row == browser->rows)
154 break; 154 break;
155 nd = rb_next(nd); 155 nd = rb_next(nd);
156 } 156 }
@@ -166,7 +166,7 @@ bool ui_browser__is_current_entry(struct ui_browser *browser, unsigned row)
166void ui_browser__refresh_dimensions(struct ui_browser *browser) 166void ui_browser__refresh_dimensions(struct ui_browser *browser)
167{ 167{
168 browser->width = SLtt_Screen_Cols - 1; 168 browser->width = SLtt_Screen_Cols - 1;
169 browser->height = SLtt_Screen_Rows - 2; 169 browser->height = browser->rows = SLtt_Screen_Rows - 2;
170 browser->y = 1; 170 browser->y = 1;
171 browser->x = 0; 171 browser->x = 0;
172} 172}
@@ -250,7 +250,10 @@ int ui_browser__show(struct ui_browser *browser, const char *title,
250 int err; 250 int err;
251 va_list ap; 251 va_list ap;
252 252
253 ui_browser__refresh_dimensions(browser); 253 if (browser->refresh_dimensions == NULL)
254 browser->refresh_dimensions = ui_browser__refresh_dimensions;
255
256 browser->refresh_dimensions(browser);
254 257
255 pthread_mutex_lock(&ui__lock); 258 pthread_mutex_lock(&ui__lock);
256 __ui_browser__show_title(browser, title); 259 __ui_browser__show_title(browser, title);
@@ -367,7 +370,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
367 370
368 if (key == K_RESIZE) { 371 if (key == K_RESIZE) {
369 ui__refresh_dimensions(false); 372 ui__refresh_dimensions(false);
370 ui_browser__refresh_dimensions(browser); 373 browser->refresh_dimensions(browser);
371 __ui_browser__show_title(browser, browser->title); 374 __ui_browser__show_title(browser, browser->title);
372 ui_helpline__puts(browser->helpline); 375 ui_helpline__puts(browser->helpline);
373 continue; 376 continue;
@@ -389,7 +392,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
389 if (browser->index == browser->nr_entries - 1) 392 if (browser->index == browser->nr_entries - 1)
390 break; 393 break;
391 ++browser->index; 394 ++browser->index;
392 if (browser->index == browser->top_idx + browser->height) { 395 if (browser->index == browser->top_idx + browser->rows) {
393 ++browser->top_idx; 396 ++browser->top_idx;
394 browser->seek(browser, +1, SEEK_CUR); 397 browser->seek(browser, +1, SEEK_CUR);
395 } 398 }
@@ -405,10 +408,10 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
405 break; 408 break;
406 case K_PGDN: 409 case K_PGDN:
407 case ' ': 410 case ' ':
408 if (browser->top_idx + browser->height > browser->nr_entries - 1) 411 if (browser->top_idx + browser->rows > browser->nr_entries - 1)
409 break; 412 break;
410 413
411 offset = browser->height; 414 offset = browser->rows;
412 if (browser->index + offset > browser->nr_entries - 1) 415 if (browser->index + offset > browser->nr_entries - 1)
413 offset = browser->nr_entries - 1 - browser->index; 416 offset = browser->nr_entries - 1 - browser->index;
414 browser->index += offset; 417 browser->index += offset;
@@ -419,10 +422,10 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
419 if (browser->top_idx == 0) 422 if (browser->top_idx == 0)
420 break; 423 break;
421 424
422 if (browser->top_idx < browser->height) 425 if (browser->top_idx < browser->rows)
423 offset = browser->top_idx; 426 offset = browser->top_idx;
424 else 427 else
425 offset = browser->height; 428 offset = browser->rows;
426 429
427 browser->index -= offset; 430 browser->index -= offset;
428 browser->top_idx -= offset; 431 browser->top_idx -= offset;
@@ -432,7 +435,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
432 ui_browser__reset_index(browser); 435 ui_browser__reset_index(browser);
433 break; 436 break;
434 case K_END: 437 case K_END:
435 offset = browser->height - 1; 438 offset = browser->rows - 1;
436 if (offset >= browser->nr_entries) 439 if (offset >= browser->nr_entries)
437 offset = browser->nr_entries - 1; 440 offset = browser->nr_entries - 1;
438 441
@@ -462,7 +465,7 @@ unsigned int ui_browser__list_head_refresh(struct ui_browser *browser)
462 if (!browser->filter || !browser->filter(browser, pos)) { 465 if (!browser->filter || !browser->filter(browser, pos)) {
463 ui_browser__gotorc(browser, row, 0); 466 ui_browser__gotorc(browser, row, 0);
464 browser->write(browser, pos, row); 467 browser->write(browser, pos, row);
465 if (++row == browser->height) 468 if (++row == browser->rows)
466 break; 469 break;
467 } 470 }
468 } 471 }
@@ -587,7 +590,7 @@ unsigned int ui_browser__argv_refresh(struct ui_browser *browser)
587 if (!browser->filter || !browser->filter(browser, *pos)) { 590 if (!browser->filter || !browser->filter(browser, *pos)) {
588 ui_browser__gotorc(browser, row, 0); 591 ui_browser__gotorc(browser, row, 0);
589 browser->write(browser, pos, row); 592 browser->write(browser, pos, row);
590 if (++row == browser->height) 593 if (++row == browser->rows)
591 break; 594 break;
592 } 595 }
593 596
@@ -623,7 +626,7 @@ static void __ui_browser__line_arrow_up(struct ui_browser *browser,
623 626
624 SLsmg_set_char_set(1); 627 SLsmg_set_char_set(1);
625 628
626 if (start < browser->top_idx + browser->height) { 629 if (start < browser->top_idx + browser->rows) {
627 row = start - browser->top_idx; 630 row = start - browser->top_idx;
628 ui_browser__gotorc(browser, row, column); 631 ui_browser__gotorc(browser, row, column);
629 SLsmg_write_char(SLSMG_LLCORN_CHAR); 632 SLsmg_write_char(SLSMG_LLCORN_CHAR);
@@ -633,7 +636,7 @@ static void __ui_browser__line_arrow_up(struct ui_browser *browser,
633 if (row-- == 0) 636 if (row-- == 0)
634 goto out; 637 goto out;
635 } else 638 } else
636 row = browser->height - 1; 639 row = browser->rows - 1;
637 640
638 if (end > browser->top_idx) 641 if (end > browser->top_idx)
639 end_row = end - browser->top_idx; 642 end_row = end - browser->top_idx;
@@ -675,8 +678,8 @@ static void __ui_browser__line_arrow_down(struct ui_browser *browser,
675 } else 678 } else
676 row = 0; 679 row = 0;
677 680
678 if (end >= browser->top_idx + browser->height) 681 if (end >= browser->top_idx + browser->rows)
679 end_row = browser->height - 1; 682 end_row = browser->rows - 1;
680 else 683 else
681 end_row = end - browser->top_idx; 684 end_row = end - browser->top_idx;
682 685
@@ -684,7 +687,7 @@ static void __ui_browser__line_arrow_down(struct ui_browser *browser,
684 SLsmg_draw_vline(end_row - row + 1); 687 SLsmg_draw_vline(end_row - row + 1);
685 688
686 ui_browser__gotorc(browser, end_row, column); 689 ui_browser__gotorc(browser, end_row, column);
687 if (end < browser->top_idx + browser->height) { 690 if (end < browser->top_idx + browser->rows) {
688 SLsmg_write_char(SLSMG_LLCORN_CHAR); 691 SLsmg_write_char(SLSMG_LLCORN_CHAR);
689 ui_browser__gotorc(browser, end_row, column + 1); 692 ui_browser__gotorc(browser, end_row, column + 1);
690 SLsmg_write_char(SLSMG_HLINE_CHAR); 693 SLsmg_write_char(SLSMG_HLINE_CHAR);
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h
index 03d4d6295f10..92ae72113965 100644
--- a/tools/perf/ui/browser.h
+++ b/tools/perf/ui/browser.h
@@ -14,11 +14,12 @@
14struct ui_browser { 14struct ui_browser {
15 u64 index, top_idx; 15 u64 index, top_idx;
16 void *top, *entries; 16 void *top, *entries;
17 u16 y, x, width, height; 17 u16 y, x, width, height, rows;
18 int current_color; 18 int current_color;
19 void *priv; 19 void *priv;
20 const char *title; 20 const char *title;
21 char *helpline; 21 char *helpline;
22 void (*refresh_dimensions)(struct ui_browser *browser);
22 unsigned int (*refresh)(struct ui_browser *browser); 23 unsigned int (*refresh)(struct ui_browser *browser);
23 void (*write)(struct ui_browser *browser, void *entry, int row); 24 void (*write)(struct ui_browser *browser, void *entry, int row);
24 void (*seek)(struct ui_browser *browser, off_t offset, int whence); 25 void (*seek)(struct ui_browser *browser, off_t offset, int whence);
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 2185091c5227..a94b11fc5e00 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -26,6 +26,7 @@ struct hist_browser {
26 struct map_symbol *selection; 26 struct map_symbol *selection;
27 int print_seq; 27 int print_seq;
28 bool show_dso; 28 bool show_dso;
29 bool show_headers;
29 float min_pcnt; 30 float min_pcnt;
30 u64 nr_non_filtered_entries; 31 u64 nr_non_filtered_entries;
31 u64 nr_callchain_rows; 32 u64 nr_callchain_rows;
@@ -56,11 +57,42 @@ static u32 hist_browser__nr_entries(struct hist_browser *hb)
56 return nr_entries + hb->nr_callchain_rows; 57 return nr_entries + hb->nr_callchain_rows;
57} 58}
58 59
59static void hist_browser__refresh_dimensions(struct hist_browser *browser) 60static void hist_browser__update_rows(struct hist_browser *hb)
60{ 61{
62 struct ui_browser *browser = &hb->b;
63 u16 header_offset = hb->show_headers ? 1 : 0, index_row;
64
65 browser->rows = browser->height - header_offset;
66 /*
67 * Verify if we were at the last line and that line isn't
68 * visibe because we now show the header line(s).
69 */
70 index_row = browser->index - browser->top_idx;
71 if (index_row >= browser->rows)
72 browser->index -= index_row - browser->rows + 1;
73}
74
75static void hist_browser__refresh_dimensions(struct ui_browser *browser)
76{
77 struct hist_browser *hb = container_of(browser, struct hist_browser, b);
78
61 /* 3 == +/- toggle symbol before actual hist_entry rendering */ 79 /* 3 == +/- toggle symbol before actual hist_entry rendering */
62 browser->b.width = 3 + (hists__sort_list_width(browser->hists) + 80 browser->width = 3 + (hists__sort_list_width(hb->hists) + sizeof("[k]"));
63 sizeof("[k]")); 81 /*
82 * FIXME: Just keeping existing behaviour, but this really should be
83 * before updating browser->width, as it will invalidate the
84 * calculation above. Fix this and the fallout in another
85 * changeset.
86 */
87 ui_browser__refresh_dimensions(browser);
88 hist_browser__update_rows(hb);
89}
90
91static void hist_browser__gotorc(struct hist_browser *browser, int row, int column)
92{
93 u16 header_offset = browser->show_headers ? 1 : 0;
94
95 ui_browser__gotorc(&browser->b, row + header_offset, column);
64} 96}
65 97
66static void hist_browser__reset(struct hist_browser *browser) 98static void hist_browser__reset(struct hist_browser *browser)
@@ -73,7 +105,7 @@ static void hist_browser__reset(struct hist_browser *browser)
73 105
74 hist_browser__update_nr_entries(browser); 106 hist_browser__update_nr_entries(browser);
75 browser->b.nr_entries = hist_browser__nr_entries(browser); 107 browser->b.nr_entries = hist_browser__nr_entries(browser);
76 hist_browser__refresh_dimensions(browser); 108 hist_browser__refresh_dimensions(&browser->b);
77 ui_browser__reset_index(&browser->b); 109 ui_browser__reset_index(&browser->b);
78} 110}
79 111
@@ -355,7 +387,6 @@ static int hist_browser__run(struct hist_browser *browser,
355 browser->b.entries = &browser->hists->entries; 387 browser->b.entries = &browser->hists->entries;
356 browser->b.nr_entries = hist_browser__nr_entries(browser); 388 browser->b.nr_entries = hist_browser__nr_entries(browser);
357 389
358 hist_browser__refresh_dimensions(browser);
359 hists__browser_title(browser->hists, title, sizeof(title)); 390 hists__browser_title(browser->hists, title, sizeof(title));
360 391
361 if (ui_browser__show(&browser->b, title, 392 if (ui_browser__show(&browser->b, title,
@@ -392,10 +423,10 @@ static int hist_browser__run(struct hist_browser *browser,
392 struct hist_entry *h = rb_entry(browser->b.top, 423 struct hist_entry *h = rb_entry(browser->b.top,
393 struct hist_entry, rb_node); 424 struct hist_entry, rb_node);
394 ui_helpline__pop(); 425 ui_helpline__pop();
395 ui_helpline__fpush("%d: nr_ent=(%d,%d), height=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d", 426 ui_helpline__fpush("%d: nr_ent=(%d,%d), rows=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d",
396 seq++, browser->b.nr_entries, 427 seq++, browser->b.nr_entries,
397 browser->hists->nr_entries, 428 browser->hists->nr_entries,
398 browser->b.height, 429 browser->b.rows,
399 browser->b.index, 430 browser->b.index,
400 browser->b.top_idx, 431 browser->b.top_idx,
401 h->row_offset, h->nr_rows); 432 h->row_offset, h->nr_rows);
@@ -409,6 +440,10 @@ static int hist_browser__run(struct hist_browser *browser,
409 /* Expand the whole world. */ 440 /* Expand the whole world. */
410 hist_browser__set_folding(browser, true); 441 hist_browser__set_folding(browser, true);
411 break; 442 break;
443 case 'H':
444 browser->show_headers = !browser->show_headers;
445 hist_browser__update_rows(browser);
446 break;
412 case K_ENTER: 447 case K_ENTER:
413 if (hist_browser__toggle_fold(browser)) 448 if (hist_browser__toggle_fold(browser))
414 break; 449 break;
@@ -508,13 +543,13 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browse
508 } 543 }
509 544
510 ui_browser__set_color(&browser->b, color); 545 ui_browser__set_color(&browser->b, color);
511 ui_browser__gotorc(&browser->b, row, 0); 546 hist_browser__gotorc(browser, row, 0);
512 slsmg_write_nstring(" ", offset + extra_offset); 547 slsmg_write_nstring(" ", offset + extra_offset);
513 slsmg_printf("%c ", folded_sign); 548 slsmg_printf("%c ", folded_sign);
514 slsmg_write_nstring(str, width); 549 slsmg_write_nstring(str, width);
515 free(alloc_str); 550 free(alloc_str);
516 551
517 if (++row == browser->b.height) 552 if (++row == browser->b.rows)
518 goto out; 553 goto out;
519do_next: 554do_next:
520 if (folded_sign == '+') 555 if (folded_sign == '+')
@@ -527,7 +562,7 @@ do_next:
527 new_level, row, row_offset, 562 new_level, row, row_offset,
528 is_current_entry); 563 is_current_entry);
529 } 564 }
530 if (row == browser->b.height) 565 if (row == browser->b.rows)
531 goto out; 566 goto out;
532 node = next; 567 node = next;
533 } 568 }
@@ -567,13 +602,13 @@ static int hist_browser__show_callchain_node(struct hist_browser *browser,
567 602
568 s = callchain_list__sym_name(chain, bf, sizeof(bf), 603 s = callchain_list__sym_name(chain, bf, sizeof(bf),
569 browser->show_dso); 604 browser->show_dso);
570 ui_browser__gotorc(&browser->b, row, 0); 605 hist_browser__gotorc(browser, row, 0);
571 ui_browser__set_color(&browser->b, color); 606 ui_browser__set_color(&browser->b, color);
572 slsmg_write_nstring(" ", offset); 607 slsmg_write_nstring(" ", offset);
573 slsmg_printf("%c ", folded_sign); 608 slsmg_printf("%c ", folded_sign);
574 slsmg_write_nstring(s, width - 2); 609 slsmg_write_nstring(s, width - 2);
575 610
576 if (++row == browser->b.height) 611 if (++row == browser->b.rows)
577 goto out; 612 goto out;
578 } 613 }
579 614
@@ -602,7 +637,7 @@ static int hist_browser__show_callchain(struct hist_browser *browser,
602 row += hist_browser__show_callchain_node(browser, node, level, 637 row += hist_browser__show_callchain_node(browser, node, level,
603 row, row_offset, 638 row, row_offset,
604 is_current_entry); 639 is_current_entry);
605 if (row == browser->b.height) 640 if (row == browser->b.rows)
606 break; 641 break;
607 } 642 }
608 643
@@ -732,7 +767,7 @@ static int hist_browser__show_entry(struct hist_browser *browser,
732 .ptr = &arg, 767 .ptr = &arg,
733 }; 768 };
734 769
735 ui_browser__gotorc(&browser->b, row, 0); 770 hist_browser__gotorc(browser, row, 0);
736 771
737 perf_hpp__for_each_format(fmt) { 772 perf_hpp__for_each_format(fmt) {
738 if (perf_hpp__should_skip(fmt)) 773 if (perf_hpp__should_skip(fmt))
@@ -776,7 +811,7 @@ static int hist_browser__show_entry(struct hist_browser *browser,
776 } else 811 } else
777 --row_offset; 812 --row_offset;
778 813
779 if (folded_sign == '-' && row != browser->b.height) { 814 if (folded_sign == '-' && row != browser->b.rows) {
780 printed += hist_browser__show_callchain(browser, &entry->sorted_chain, 815 printed += hist_browser__show_callchain(browser, &entry->sorted_chain,
781 1, row, &row_offset, 816 1, row, &row_offset,
782 &current_entry); 817 &current_entry);
@@ -787,6 +822,56 @@ static int hist_browser__show_entry(struct hist_browser *browser,
787 return printed; 822 return printed;
788} 823}
789 824
825static int advance_hpp_check(struct perf_hpp *hpp, int inc)
826{
827 advance_hpp(hpp, inc);
828 return hpp->size <= 0;
829}
830
831static int hists__scnprintf_headers(char *buf, size_t size, struct hists *hists)
832{
833 struct perf_hpp dummy_hpp = {
834 .buf = buf,
835 .size = size,
836 };
837 struct perf_hpp_fmt *fmt;
838 size_t ret = 0;
839
840 if (symbol_conf.use_callchain) {
841 ret = scnprintf(buf, size, " ");
842 if (advance_hpp_check(&dummy_hpp, ret))
843 return ret;
844 }
845
846 perf_hpp__for_each_format(fmt) {
847 if (perf_hpp__should_skip(fmt))
848 continue;
849
850 /* We need to add the length of the columns header. */
851 perf_hpp__reset_width(fmt, hists);
852
853 ret = fmt->header(fmt, &dummy_hpp, hists_to_evsel(hists));
854 if (advance_hpp_check(&dummy_hpp, ret))
855 break;
856
857 ret = scnprintf(dummy_hpp.buf, dummy_hpp.size, " ");
858 if (advance_hpp_check(&dummy_hpp, ret))
859 break;
860 }
861
862 return ret;
863}
864
865static void hist_browser__show_headers(struct hist_browser *browser)
866{
867 char headers[1024];
868
869 hists__scnprintf_headers(headers, sizeof(headers), browser->hists);
870 ui_browser__gotorc(&browser->b, 0, 0);
871 ui_browser__set_color(&browser->b, HE_COLORSET_ROOT);
872 slsmg_write_nstring(headers, browser->b.width + 1);
873}
874
790static void ui_browser__hists_init_top(struct ui_browser *browser) 875static void ui_browser__hists_init_top(struct ui_browser *browser)
791{ 876{
792 if (browser->top == NULL) { 877 if (browser->top == NULL) {
@@ -800,9 +885,15 @@ static void ui_browser__hists_init_top(struct ui_browser *browser)
800static unsigned int hist_browser__refresh(struct ui_browser *browser) 885static unsigned int hist_browser__refresh(struct ui_browser *browser)
801{ 886{
802 unsigned row = 0; 887 unsigned row = 0;
888 u16 header_offset = 0;
803 struct rb_node *nd; 889 struct rb_node *nd;
804 struct hist_browser *hb = container_of(browser, struct hist_browser, b); 890 struct hist_browser *hb = container_of(browser, struct hist_browser, b);
805 891
892 if (hb->show_headers) {
893 hist_browser__show_headers(hb);
894 header_offset = 1;
895 }
896
806 ui_browser__hists_init_top(browser); 897 ui_browser__hists_init_top(browser);
807 898
808 for (nd = browser->top; nd; nd = rb_next(nd)) { 899 for (nd = browser->top; nd; nd = rb_next(nd)) {
@@ -817,11 +908,11 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
817 continue; 908 continue;
818 909
819 row += hist_browser__show_entry(hb, h, row); 910 row += hist_browser__show_entry(hb, h, row);
820 if (row == browser->height) 911 if (row == browser->rows)
821 break; 912 break;
822 } 913 }
823 914
824 return row; 915 return row + header_offset;
825} 916}
826 917
827static struct rb_node *hists__filter_entries(struct rb_node *nd, 918static struct rb_node *hists__filter_entries(struct rb_node *nd,
@@ -1190,8 +1281,10 @@ static struct hist_browser *hist_browser__new(struct hists *hists)
1190 if (browser) { 1281 if (browser) {
1191 browser->hists = hists; 1282 browser->hists = hists;
1192 browser->b.refresh = hist_browser__refresh; 1283 browser->b.refresh = hist_browser__refresh;
1284 browser->b.refresh_dimensions = hist_browser__refresh_dimensions;
1193 browser->b.seek = ui_browser__hists_seek; 1285 browser->b.seek = ui_browser__hists_seek;
1194 browser->b.use_navkeypressed = true; 1286 browser->b.use_navkeypressed = true;
1287 browser->show_headers = symbol_conf.show_hist_headers;
1195 } 1288 }
1196 1289
1197 return browser; 1290 return browser;
@@ -1421,6 +1514,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1421 "d Zoom into current DSO\n" \ 1514 "d Zoom into current DSO\n" \
1422 "E Expand all callchains\n" \ 1515 "E Expand all callchains\n" \
1423 "F Toggle percentage of filtered entries\n" \ 1516 "F Toggle percentage of filtered entries\n" \
1517 "H Display column headers\n" \
1424 1518
1425 /* help messages are sorted by lexical order of the hotkey */ 1519 /* help messages are sorted by lexical order of the hotkey */
1426 const char report_help[] = HIST_BROWSER_HELP_COMMON 1520 const char report_help[] = HIST_BROWSER_HELP_COMMON
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 24519e14ac56..1e5e2e5af6b1 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -350,6 +350,16 @@ static int perf_default_core_config(const char *var __maybe_unused,
350 return 0; 350 return 0;
351} 351}
352 352
353static int perf_ui_config(const char *var, const char *value)
354{
355 /* Add other config variables here. */
356 if (!strcmp(var, "ui.show-headers")) {
357 symbol_conf.show_hist_headers = perf_config_bool(var, value);
358 return 0;
359 }
360 return 0;
361}
362
353int perf_default_config(const char *var, const char *value, 363int perf_default_config(const char *var, const char *value,
354 void *dummy __maybe_unused) 364 void *dummy __maybe_unused)
355{ 365{
@@ -359,6 +369,9 @@ int perf_default_config(const char *var, const char *value,
359 if (!prefixcmp(var, "hist.")) 369 if (!prefixcmp(var, "hist."))
360 return perf_hist_config(var, value); 370 return perf_hist_config(var, value);
361 371
372 if (!prefixcmp(var, "ui."))
373 return perf_ui_config(var, value);
374
362 /* Add other config variables here. */ 375 /* Add other config variables here. */
363 return 0; 376 return 0;
364} 377}
diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c
index 55de44ecebef..ee370a7f2444 100644
--- a/tools/perf/util/data.c
+++ b/tools/perf/util/data.c
@@ -65,7 +65,7 @@ static int open_file_read(struct perf_data_file *file)
65 goto out_close; 65 goto out_close;
66 66
67 if (!file->force && st.st_uid && (st.st_uid != geteuid())) { 67 if (!file->force && st.st_uid && (st.st_uid != geteuid())) {
68 pr_err("file %s not owned by current user or root\n", 68 pr_err("File %s not owned by current user or root (use -f to override)\n",
69 file->path); 69 file->path);
70 goto out_close; 70 goto out_close;
71 } 71 }
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 1ec57dd82284..14e5a039bc45 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -1215,7 +1215,7 @@ static int __sort__hpp_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
1215 hse = container_of(fmt, struct hpp_sort_entry, hpp); 1215 hse = container_of(fmt, struct hpp_sort_entry, hpp);
1216 len = hists__col_len(&evsel->hists, hse->se->se_width_idx); 1216 len = hists__col_len(&evsel->hists, hse->se->se_width_idx);
1217 1217
1218 return scnprintf(hpp->buf, hpp->size, "%*s", len, hse->se->se_header); 1218 return scnprintf(hpp->buf, hpp->size, "%-*s", len, hse->se->se_header);
1219} 1219}
1220 1220
1221static int __sort__hpp_width(struct perf_hpp_fmt *fmt, 1221static int __sort__hpp_width(struct perf_hpp_fmt *fmt,
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 7b9096f29cdb..2e6a2e219eb9 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -34,6 +34,7 @@ struct symbol_conf symbol_conf = {
34 .annotate_src = true, 34 .annotate_src = true,
35 .demangle = true, 35 .demangle = true,
36 .cumulate_callchain = true, 36 .cumulate_callchain = true,
37 .show_hist_headers = true,
37 .symfs = "", 38 .symfs = "",
38}; 39};
39 40
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 615c752dd767..a81877b1dee0 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -118,7 +118,8 @@ struct symbol_conf {
118 annotate_src, 118 annotate_src,
119 event_group, 119 event_group,
120 demangle, 120 demangle,
121 filter_relative; 121 filter_relative,
122 show_hist_headers;
122 const char *vmlinux_name, 123 const char *vmlinux_name,
123 *kallsyms_name, 124 *kallsyms_name,
124 *source_prefix, 125 *source_prefix,
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index 7e6fcfe8b438..c3bba883f5c3 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -191,12 +191,10 @@ static int copy_event_system(const char *sys, struct tracepoint_path *tps)
191 strcmp(dent->d_name, "..") == 0 || 191 strcmp(dent->d_name, "..") == 0 ||
192 !name_in_tp_list(dent->d_name, tps)) 192 !name_in_tp_list(dent->d_name, tps))
193 continue; 193 continue;
194 format = malloc(strlen(sys) + strlen(dent->d_name) + 10); 194 if (asprintf(&format, "%s/%s/format", sys, dent->d_name) < 0) {
195 if (!format) {
196 err = -ENOMEM; 195 err = -ENOMEM;
197 goto out; 196 goto out;
198 } 197 }
199 sprintf(format, "%s/%s/format", sys, dent->d_name);
200 ret = stat(format, &st); 198 ret = stat(format, &st);
201 free(format); 199 free(format);
202 if (ret < 0) 200 if (ret < 0)
@@ -217,12 +215,10 @@ static int copy_event_system(const char *sys, struct tracepoint_path *tps)
217 strcmp(dent->d_name, "..") == 0 || 215 strcmp(dent->d_name, "..") == 0 ||
218 !name_in_tp_list(dent->d_name, tps)) 216 !name_in_tp_list(dent->d_name, tps))
219 continue; 217 continue;
220 format = malloc(strlen(sys) + strlen(dent->d_name) + 10); 218 if (asprintf(&format, "%s/%s/format", sys, dent->d_name) < 0) {
221 if (!format) {
222 err = -ENOMEM; 219 err = -ENOMEM;
223 goto out; 220 goto out;
224 } 221 }
225 sprintf(format, "%s/%s/format", sys, dent->d_name);
226 ret = stat(format, &st); 222 ret = stat(format, &st);
227 223
228 if (ret >= 0) { 224 if (ret >= 0) {
@@ -317,12 +313,10 @@ static int record_event_files(struct tracepoint_path *tps)
317 strcmp(dent->d_name, "ftrace") == 0 || 313 strcmp(dent->d_name, "ftrace") == 0 ||
318 !system_in_tp_list(dent->d_name, tps)) 314 !system_in_tp_list(dent->d_name, tps))
319 continue; 315 continue;
320 sys = malloc(strlen(path) + strlen(dent->d_name) + 2); 316 if (asprintf(&sys, "%s/%s", path, dent->d_name) < 0) {
321 if (!sys) {
322 err = -ENOMEM; 317 err = -ENOMEM;
323 goto out; 318 goto out;
324 } 319 }
325 sprintf(sys, "%s/%s", path, dent->d_name);
326 ret = stat(sys, &st); 320 ret = stat(sys, &st);
327 if (ret >= 0) { 321 if (ret >= 0) {
328 ssize_t size = strlen(dent->d_name) + 1; 322 ssize_t size = strlen(dent->d_name) + 1;
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 95aefa78bb07..e4132aeeb780 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -333,12 +333,9 @@ const char *find_tracing_dir(void)
333 if (!debugfs) 333 if (!debugfs)
334 return NULL; 334 return NULL;
335 335
336 tracing = malloc(strlen(debugfs) + 9); 336 if (asprintf(&tracing, "%s/tracing", debugfs) < 0)
337 if (!tracing)
338 return NULL; 337 return NULL;
339 338
340 sprintf(tracing, "%s/tracing", debugfs);
341
342 tracing_found = 1; 339 tracing_found = 1;
343 return tracing; 340 return tracing;
344} 341}
@@ -352,11 +349,9 @@ char *get_tracing_file(const char *name)
352 if (!tracing) 349 if (!tracing)
353 return NULL; 350 return NULL;
354 351
355 file = malloc(strlen(tracing) + strlen(name) + 2); 352 if (asprintf(&file, "%s/%s", tracing, name) < 0)
356 if (!file)
357 return NULL; 353 return NULL;
358 354
359 sprintf(file, "%s/%s", tracing, name);
360 return file; 355 return file;
361} 356}
362 357