Commit 06c654ca authored by Ingo Molnar's avatar Ingo Molnar

Merge tag 'perf-core-for-mingo' of...

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:

  * Add --repeat global option to 'perf bench' to be used in benchmarks
    such as the existing 'futex' one, that was modified to use it instead
    of a local option. (Davidlohr Bueso)

  * Fix fd -> pathname resolution in 'trace', be it using /proc or
    a vfs_getname probe point. (Arnaldo Carvalho de Melo)

  * Add suggestion of how to set perf_event_paranoid sysctl, to help
    non-root users trying tools like 'trace' to get a working environment.
    (Arnaldo Carvalho de Melo)

Fixes:

  * Fix memory leak in the 'sched-messaging' perf bench test. (Davidlohr Bueso)

  * The -o and -n 'perf bench mem' options are mutually exclusive, emit error
    when both are specified. (Davidlohr Bueso)

  * Fix scrollbar refresh row index in the ui browser, problem exposed now
    that headers will be added and will be allowed to be switched on/off.
    (Jiri Olsa)

Cleanups:

  * Remove needless reassignments in 'trace' (Arnaldo Carvalho de Melo)

  * Cache the is_exit syscall test in 'trace) (Arnaldo Carvalho de Melo)

  * No need to reimplement err() in 'perf bench sched-messaging', drop barf().
    (Davidlohr Bueso).

  * Remove ev_name argument from perf_evsel__hists_browse, can be obtained
    from the other parameters. (Jiri Olsa)
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 98d350cf ecdac968
...@@ -16,6 +16,10 @@ This 'perf bench' command is a general framework for benchmark suites. ...@@ -16,6 +16,10 @@ This 'perf bench' command is a general framework for benchmark suites.
COMMON OPTIONS COMMON OPTIONS
-------------- --------------
-r::
--repeat=::
Specify amount of times to repeat the run (default 10).
-f:: -f::
--format=:: --format=::
Specify format style. Specify format style.
......
...@@ -43,5 +43,6 @@ extern int bench_futex_requeue(int argc, const char **argv, const char *prefix); ...@@ -43,5 +43,6 @@ extern int bench_futex_requeue(int argc, const char **argv, const char *prefix);
#define BENCH_FORMAT_UNKNOWN -1 #define BENCH_FORMAT_UNKNOWN -1
extern int bench_format; extern int bench_format;
extern unsigned int bench_repeat;
#endif #endif
...@@ -29,13 +29,6 @@ static u_int32_t futex1 = 0, futex2 = 0; ...@@ -29,13 +29,6 @@ static u_int32_t futex1 = 0, futex2 = 0;
*/ */
static unsigned int nrequeue = 1; static unsigned int nrequeue = 1;
/*
* There can be significant variance from run to run,
* the more repeats, the more exact the overall avg and
* the better idea of the futex latency.
*/
static unsigned int repeat = 10;
static pthread_t *worker; static pthread_t *worker;
static bool done = 0, silent = 0; static bool done = 0, silent = 0;
static pthread_mutex_t thread_lock; static pthread_mutex_t thread_lock;
...@@ -46,7 +39,6 @@ static unsigned int ncpus, threads_starting, nthreads = 0; ...@@ -46,7 +39,6 @@ static unsigned int ncpus, threads_starting, nthreads = 0;
static const struct option options[] = { static const struct option options[] = {
OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"),
OPT_UINTEGER('q', "nrequeue", &nrequeue, "Specify amount of threads to requeue at once"), OPT_UINTEGER('q', "nrequeue", &nrequeue, "Specify amount of threads to requeue at once"),
OPT_UINTEGER('r', "repeat", &repeat, "Specify amount of times to repeat the run"),
OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"),
OPT_END() OPT_END()
}; };
...@@ -146,7 +138,7 @@ int bench_futex_requeue(int argc, const char **argv, ...@@ -146,7 +138,7 @@ int bench_futex_requeue(int argc, const char **argv,
pthread_cond_init(&thread_parent, NULL); pthread_cond_init(&thread_parent, NULL);
pthread_cond_init(&thread_worker, NULL); pthread_cond_init(&thread_worker, NULL);
for (j = 0; j < repeat && !done; j++) { for (j = 0; j < bench_repeat && !done; j++) {
unsigned int nrequeued = 0; unsigned int nrequeued = 0;
struct timeval start, end, runtime; struct timeval start, end, runtime;
......
...@@ -30,15 +30,8 @@ static u_int32_t futex1 = 0; ...@@ -30,15 +30,8 @@ static u_int32_t futex1 = 0;
*/ */
static unsigned int nwakes = 1; static unsigned int nwakes = 1;
/*
* There can be significant variance from run to run,
* the more repeats, the more exact the overall avg and
* the better idea of the futex latency.
*/
static unsigned int repeat = 10;
pthread_t *worker; pthread_t *worker;
static bool done = 0, silent = 0; static bool done = false, silent = false;
static pthread_mutex_t thread_lock; static pthread_mutex_t thread_lock;
static pthread_cond_t thread_parent, thread_worker; static pthread_cond_t thread_parent, thread_worker;
static struct stats waketime_stats, wakeup_stats; static struct stats waketime_stats, wakeup_stats;
...@@ -47,7 +40,6 @@ static unsigned int ncpus, threads_starting, nthreads = 0; ...@@ -47,7 +40,6 @@ static unsigned int ncpus, threads_starting, nthreads = 0;
static const struct option options[] = { static const struct option options[] = {
OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"),
OPT_UINTEGER('w', "nwakes", &nwakes, "Specify amount of threads to wake at once"), OPT_UINTEGER('w', "nwakes", &nwakes, "Specify amount of threads to wake at once"),
OPT_UINTEGER('r', "repeat", &repeat, "Specify amount of times to repeat the run"),
OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"),
OPT_END() OPT_END()
}; };
...@@ -149,7 +141,7 @@ int bench_futex_wake(int argc, const char **argv, ...@@ -149,7 +141,7 @@ int bench_futex_wake(int argc, const char **argv,
pthread_cond_init(&thread_parent, NULL); pthread_cond_init(&thread_parent, NULL);
pthread_cond_init(&thread_worker, NULL); pthread_cond_init(&thread_worker, NULL);
for (j = 0; j < repeat && !done; j++) { for (j = 0; j < bench_repeat && !done; j++) {
unsigned int nwoken = 0; unsigned int nwoken = 0;
struct timeval start, end, runtime; struct timeval start, end, runtime;
......
...@@ -189,6 +189,11 @@ int bench_mem_memcpy(int argc, const char **argv, ...@@ -189,6 +189,11 @@ int bench_mem_memcpy(int argc, const char **argv,
argc = parse_options(argc, argv, options, argc = parse_options(argc, argv, options,
bench_mem_memcpy_usage, 0); bench_mem_memcpy_usage, 0);
if (no_prefault && only_prefault) {
fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n");
return 1;
}
if (use_cycle) if (use_cycle)
init_cycle(); init_cycle();
......
...@@ -181,6 +181,11 @@ int bench_mem_memset(int argc, const char **argv, ...@@ -181,6 +181,11 @@ int bench_mem_memset(int argc, const char **argv,
argc = parse_options(argc, argv, options, argc = parse_options(argc, argv, options,
bench_mem_memset_usage, 0); bench_mem_memset_usage, 0);
if (no_prefault && only_prefault) {
fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n");
return 1;
}
if (use_cycle) if (use_cycle)
init_cycle(); init_cycle();
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/poll.h> #include <sys/poll.h>
#include <limits.h> #include <limits.h>
#include <err.h>
#define DATASIZE 100 #define DATASIZE 100
...@@ -50,12 +51,6 @@ struct receiver_context { ...@@ -50,12 +51,6 @@ struct receiver_context {
int wakefd; int wakefd;
}; };
static void barf(const char *msg)
{
fprintf(stderr, "%s (error: %s)\n", msg, strerror(errno));
exit(1);
}
static void fdpair(int fds[2]) static void fdpair(int fds[2])
{ {
if (use_pipes) { if (use_pipes) {
...@@ -66,7 +61,7 @@ static void fdpair(int fds[2]) ...@@ -66,7 +61,7 @@ static void fdpair(int fds[2])
return; return;
} }
barf(use_pipes ? "pipe()" : "socketpair()"); err(EXIT_FAILURE, use_pipes ? "pipe()" : "socketpair()");
} }
/* Block until we're ready to go */ /* Block until we're ready to go */
...@@ -77,11 +72,11 @@ static void ready(int ready_out, int wakefd) ...@@ -77,11 +72,11 @@ static void ready(int ready_out, int wakefd)
/* Tell them we're ready. */ /* Tell them we're ready. */
if (write(ready_out, &dummy, 1) != 1) if (write(ready_out, &dummy, 1) != 1)
barf("CLIENT: ready write"); err(EXIT_FAILURE, "CLIENT: ready write");
/* Wait for "GO" signal */ /* Wait for "GO" signal */
if (poll(&pollfd, 1, -1) != 1) if (poll(&pollfd, 1, -1) != 1)
barf("poll"); err(EXIT_FAILURE, "poll");
} }
/* Sender sprays loops messages down each file descriptor */ /* Sender sprays loops messages down each file descriptor */
...@@ -101,7 +96,7 @@ static void *sender(struct sender_context *ctx) ...@@ -101,7 +96,7 @@ static void *sender(struct sender_context *ctx)
ret = write(ctx->out_fds[j], data + done, ret = write(ctx->out_fds[j], data + done,
sizeof(data)-done); sizeof(data)-done);
if (ret < 0) if (ret < 0)
barf("SENDER: write"); err(EXIT_FAILURE, "SENDER: write");
done += ret; done += ret;
if (done < DATASIZE) if (done < DATASIZE)
goto again; goto again;
...@@ -131,7 +126,7 @@ static void *receiver(struct receiver_context* ctx) ...@@ -131,7 +126,7 @@ static void *receiver(struct receiver_context* ctx)
again: again:
ret = read(ctx->in_fds[0], data + done, DATASIZE - done); ret = read(ctx->in_fds[0], data + done, DATASIZE - done);
if (ret < 0) if (ret < 0)
barf("SERVER: read"); err(EXIT_FAILURE, "SERVER: read");
done += ret; done += ret;
if (done < DATASIZE) if (done < DATASIZE)
goto again; goto again;
...@@ -144,14 +139,14 @@ static pthread_t create_worker(void *ctx, void *(*func)(void *)) ...@@ -144,14 +139,14 @@ static pthread_t create_worker(void *ctx, void *(*func)(void *))
{ {
pthread_attr_t attr; pthread_attr_t attr;
pthread_t childid; pthread_t childid;
int err; int ret;
if (!thread_mode) { if (!thread_mode) {
/* process mode */ /* process mode */
/* Fork the receiver. */ /* Fork the receiver. */
switch (fork()) { switch (fork()) {
case -1: case -1:
barf("fork()"); err(EXIT_FAILURE, "fork()");
break; break;
case 0: case 0:
(*func) (ctx); (*func) (ctx);
...@@ -165,19 +160,17 @@ static pthread_t create_worker(void *ctx, void *(*func)(void *)) ...@@ -165,19 +160,17 @@ static pthread_t create_worker(void *ctx, void *(*func)(void *))
} }
if (pthread_attr_init(&attr) != 0) if (pthread_attr_init(&attr) != 0)
barf("pthread_attr_init:"); err(EXIT_FAILURE, "pthread_attr_init:");
#ifndef __ia64__ #ifndef __ia64__
if (pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN) != 0) if (pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN) != 0)
barf("pthread_attr_setstacksize"); err(EXIT_FAILURE, "pthread_attr_setstacksize");
#endif #endif
err = pthread_create(&childid, &attr, func, ctx); ret = pthread_create(&childid, &attr, func, ctx);
if (err != 0) { if (ret != 0)
fprintf(stderr, "pthread_create failed: %s (%d)\n", err(EXIT_FAILURE, "pthread_create failed");
strerror(err), err);
exit(-1);
}
return childid; return childid;
} }
...@@ -207,14 +200,14 @@ static unsigned int group(pthread_t *pth, ...@@ -207,14 +200,14 @@ static unsigned int group(pthread_t *pth,
+ num_fds * sizeof(int)); + num_fds * sizeof(int));
if (!snd_ctx) if (!snd_ctx)
barf("malloc()"); err(EXIT_FAILURE, "malloc()");
for (i = 0; i < num_fds; i++) { for (i = 0; i < num_fds; i++) {
int fds[2]; int fds[2];
struct receiver_context *ctx = malloc(sizeof(*ctx)); struct receiver_context *ctx = malloc(sizeof(*ctx));
if (!ctx) if (!ctx)
barf("malloc()"); err(EXIT_FAILURE, "malloc()");
/* Create the pipe between client and server */ /* Create the pipe between client and server */
...@@ -281,7 +274,7 @@ int bench_sched_messaging(int argc, const char **argv, ...@@ -281,7 +274,7 @@ int bench_sched_messaging(int argc, const char **argv,
pth_tab = malloc(num_fds * 2 * num_groups * sizeof(pthread_t)); pth_tab = malloc(num_fds * 2 * num_groups * sizeof(pthread_t));
if (!pth_tab) if (!pth_tab)
barf("main:malloc()"); err(EXIT_FAILURE, "main:malloc()");
fdpair(readyfds); fdpair(readyfds);
fdpair(wakefds); fdpair(wakefds);
...@@ -294,13 +287,13 @@ int bench_sched_messaging(int argc, const char **argv, ...@@ -294,13 +287,13 @@ int bench_sched_messaging(int argc, const char **argv,
/* Wait for everyone to be ready */ /* Wait for everyone to be ready */
for (i = 0; i < total_children; i++) for (i = 0; i < total_children; i++)
if (read(readyfds[0], &dummy, 1) != 1) if (read(readyfds[0], &dummy, 1) != 1)
barf("Reading for readyfds"); err(EXIT_FAILURE, "Reading for readyfds");
gettimeofday(&start, NULL); gettimeofday(&start, NULL);
/* Kick them off */ /* Kick them off */
if (write(wakefds[1], &dummy, 1) != 1) if (write(wakefds[1], &dummy, 1) != 1)
barf("Writing to start them"); err(EXIT_FAILURE, "Writing to start them");
/* Reap them all */ /* Reap them all */
for (i = 0; i < total_children; i++) for (i = 0; i < total_children; i++)
...@@ -332,5 +325,7 @@ int bench_sched_messaging(int argc, const char **argv, ...@@ -332,5 +325,7 @@ int bench_sched_messaging(int argc, const char **argv,
break; break;
} }
free(pth_tab);
return 0; return 0;
} }
...@@ -104,9 +104,11 @@ static const char *bench_format_str; ...@@ -104,9 +104,11 @@ static const char *bench_format_str;
/* Output/formatting style, exported to benchmark modules: */ /* Output/formatting style, exported to benchmark modules: */
int bench_format = BENCH_FORMAT_DEFAULT; int bench_format = BENCH_FORMAT_DEFAULT;
unsigned int bench_repeat = 10; /* default number of times to repeat the run */
static const struct option bench_options[] = { static const struct option bench_options[] = {
OPT_STRING('f', "format", &bench_format_str, "default", "Specify format style"), OPT_STRING('f', "format", &bench_format_str, "default", "Specify format style"),
OPT_UINTEGER('r', "repeat", &bench_repeat, "Specify amount of times to repeat the run"),
OPT_END() OPT_END()
}; };
...@@ -226,6 +228,11 @@ int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -226,6 +228,11 @@ int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused)
goto end; goto end;
} }
if (bench_repeat == 0) {
printf("Invalid repeat option: Must specify a positive value\n");
goto end;
}
if (argc < 1) { if (argc < 1) {
print_usage(); print_usage();
goto end; goto end;
......
...@@ -1108,6 +1108,7 @@ struct syscall { ...@@ -1108,6 +1108,7 @@ struct syscall {
struct event_format *tp_format; struct event_format *tp_format;
const char *name; const char *name;
bool filtered; bool filtered;
bool is_exit;
struct syscall_fmt *fmt; struct syscall_fmt *fmt;
size_t (**arg_scnprintf)(char *bf, size_t size, struct syscall_arg *arg); size_t (**arg_scnprintf)(char *bf, size_t size, struct syscall_arg *arg);
void **arg_parm; void **arg_parm;
...@@ -1276,11 +1277,11 @@ static const char *thread__fd_path(struct thread *thread, int fd, ...@@ -1276,11 +1277,11 @@ static const char *thread__fd_path(struct thread *thread, int fd,
if (fd < 0) if (fd < 0)
return NULL; return NULL;
if ((fd > ttrace->paths.max || ttrace->paths.table[fd] == NULL)) if ((fd > ttrace->paths.max || ttrace->paths.table[fd] == NULL)) {
if (!trace->live) if (!trace->live)
return NULL; return NULL;
++trace->stats.proc_getname; ++trace->stats.proc_getname;
if (thread__read_fd_path(thread, fd)) { if (thread__read_fd_path(thread, fd))
return NULL; return NULL;
} }
...@@ -1473,6 +1474,8 @@ static int trace__read_syscall_info(struct trace *trace, int id) ...@@ -1473,6 +1474,8 @@ static int trace__read_syscall_info(struct trace *trace, int id)
if (sc->tp_format == NULL) if (sc->tp_format == NULL)
return -1; return -1;
sc->is_exit = !strcmp(name, "exit_group") || !strcmp(name, "exit");
return syscall__set_arg_fmts(sc); return syscall__set_arg_fmts(sc);
} }
...@@ -1629,7 +1632,6 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, ...@@ -1629,7 +1632,6 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
return -1; return -1;
args = perf_evsel__sc_tp_ptr(evsel, args, sample); args = perf_evsel__sc_tp_ptr(evsel, args, sample);
ttrace = thread->priv;
if (ttrace->entry_str == NULL) { if (ttrace->entry_str == NULL) {
ttrace->entry_str = malloc(1024); ttrace->entry_str = malloc(1024);
...@@ -1644,7 +1646,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, ...@@ -1644,7 +1646,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
printed += syscall__scnprintf_args(sc, msg + printed, 1024 - printed, printed += syscall__scnprintf_args(sc, msg + printed, 1024 - printed,
args, trace, thread); args, trace, thread);
if (!strcmp(sc->name, "exit_group") || !strcmp(sc->name, "exit")) { if (sc->is_exit) {
if (!trace->duration_filter && !trace->summary_only) { if (!trace->duration_filter && !trace->summary_only) {
trace__fprintf_entry_head(trace, thread, 1, sample->time, trace->output); trace__fprintf_entry_head(trace, thread, 1, sample->time, trace->output);
fprintf(trace->output, "%-70s\n", ttrace->entry_str); fprintf(trace->output, "%-70s\n", ttrace->entry_str);
...@@ -1687,8 +1689,6 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, ...@@ -1687,8 +1689,6 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
++trace->stats.vfs_getname; ++trace->stats.vfs_getname;
} }
ttrace = thread->priv;
ttrace->exit_time = sample->time; ttrace->exit_time = sample->time;
if (ttrace->entry_time) { if (ttrace->entry_time) {
......
...@@ -279,7 +279,7 @@ static void ui_browser__scrollbar_set(struct ui_browser *browser) ...@@ -279,7 +279,7 @@ static void ui_browser__scrollbar_set(struct ui_browser *browser)
{ {
int height = browser->height, h = 0, pct = 0, int height = browser->height, h = 0, pct = 0,
col = browser->width, col = browser->width,
row = browser->y - 1; row = 0;
if (browser->nr_entries > 1) { if (browser->nr_entries > 1) {
pct = ((browser->index * (browser->height - 1)) / pct = ((browser->index * (browser->height - 1)) /
......
...@@ -33,8 +33,7 @@ struct hist_browser { ...@@ -33,8 +33,7 @@ struct hist_browser {
extern void hist_browser__init_hpp(void); extern void hist_browser__init_hpp(void);
static int hists__browser_title(struct hists *hists, char *bf, size_t size, static int hists__browser_title(struct hists *hists, char *bf, size_t size);
const char *ev_name);
static void hist_browser__update_nr_entries(struct hist_browser *hb); static void hist_browser__update_nr_entries(struct hist_browser *hb);
static struct rb_node *hists__filter_entries(struct rb_node *nd, static struct rb_node *hists__filter_entries(struct rb_node *nd,
...@@ -346,7 +345,7 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser) ...@@ -346,7 +345,7 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser)
"Or reduce the sampling frequency."); "Or reduce the sampling frequency.");
} }
static int hist_browser__run(struct hist_browser *browser, const char *ev_name, static int hist_browser__run(struct hist_browser *browser,
struct hist_browser_timer *hbt) struct hist_browser_timer *hbt)
{ {
int key; int key;
...@@ -357,7 +356,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name, ...@@ -357,7 +356,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
browser->b.nr_entries = hist_browser__nr_entries(browser); browser->b.nr_entries = hist_browser__nr_entries(browser);
hist_browser__refresh_dimensions(browser); hist_browser__refresh_dimensions(browser);
hists__browser_title(browser->hists, title, sizeof(title), ev_name); hists__browser_title(browser->hists, title, sizeof(title));
if (ui_browser__show(&browser->b, title, if (ui_browser__show(&browser->b, title,
"Press '?' for help on key bindings") < 0) "Press '?' for help on key bindings") < 0)
...@@ -384,7 +383,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name, ...@@ -384,7 +383,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
ui_browser__warn_lost_events(&browser->b); ui_browser__warn_lost_events(&browser->b);
} }
hists__browser_title(browser->hists, title, sizeof(title), ev_name); hists__browser_title(browser->hists, title, sizeof(title));
ui_browser__show_title(&browser->b, title); ui_browser__show_title(&browser->b, title);
continue; continue;
} }
...@@ -1213,8 +1212,7 @@ static struct thread *hist_browser__selected_thread(struct hist_browser *browser ...@@ -1213,8 +1212,7 @@ static struct thread *hist_browser__selected_thread(struct hist_browser *browser
return browser->he_selection->thread; return browser->he_selection->thread;
} }
static int hists__browser_title(struct hists *hists, char *bf, size_t size, static int hists__browser_title(struct hists *hists, char *bf, size_t size)
const char *ev_name)
{ {
char unit; char unit;
int printed; int printed;
...@@ -1223,6 +1221,7 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size, ...@@ -1223,6 +1221,7 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size,
unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE]; unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
u64 nr_events = hists->stats.total_period; u64 nr_events = hists->stats.total_period;
struct perf_evsel *evsel = hists_to_evsel(hists); struct perf_evsel *evsel = hists_to_evsel(hists);
const char *ev_name = perf_evsel__name(evsel);
char buf[512]; char buf[512];
size_t buflen = sizeof(buf); size_t buflen = sizeof(buf);
...@@ -1390,7 +1389,7 @@ static void hist_browser__update_nr_entries(struct hist_browser *hb) ...@@ -1390,7 +1389,7 @@ static void hist_browser__update_nr_entries(struct hist_browser *hb)
} }
static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
const char *helpline, const char *ev_name, const char *helpline,
bool left_exits, bool left_exits,
struct hist_browser_timer *hbt, struct hist_browser_timer *hbt,
float min_pcnt, float min_pcnt,
...@@ -1465,7 +1464,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, ...@@ -1465,7 +1464,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
nr_options = 0; nr_options = 0;
key = hist_browser__run(browser, ev_name, hbt); key = hist_browser__run(browser, hbt);
if (browser->he_selection != NULL) { if (browser->he_selection != NULL) {
thread = hist_browser__selected_thread(browser); thread = hist_browser__selected_thread(browser);
...@@ -1843,7 +1842,7 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu, ...@@ -1843,7 +1842,7 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
{ {
struct perf_evlist *evlist = menu->b.priv; struct perf_evlist *evlist = menu->b.priv;
struct perf_evsel *pos; struct perf_evsel *pos;
const char *ev_name, *title = "Available samples"; const char *title = "Available samples";
int delay_secs = hbt ? hbt->refresh : 0; int delay_secs = hbt ? hbt->refresh : 0;
int key; int key;
...@@ -1876,9 +1875,8 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu, ...@@ -1876,9 +1875,8 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
*/ */
if (hbt) if (hbt)
hbt->timer(hbt->arg); hbt->timer(hbt->arg);
ev_name = perf_evsel__name(pos);
key = perf_evsel__hists_browse(pos, nr_events, help, key = perf_evsel__hists_browse(pos, nr_events, help,
ev_name, true, hbt, true, hbt,
menu->min_pcnt, menu->min_pcnt,
menu->env); menu->env);
ui_browser__show_title(&menu->b, title); ui_browser__show_title(&menu->b, title);
...@@ -1982,10 +1980,9 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, ...@@ -1982,10 +1980,9 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
single_entry: single_entry:
if (nr_entries == 1) { if (nr_entries == 1) {
struct perf_evsel *first = perf_evlist__first(evlist); struct perf_evsel *first = perf_evlist__first(evlist);
const char *ev_name = perf_evsel__name(first);
return perf_evsel__hists_browse(first, nr_entries, help, return perf_evsel__hists_browse(first, nr_entries, help,
ev_name, false, hbt, min_pcnt, false, hbt, min_pcnt,
env); env);
} }
......
...@@ -1214,10 +1214,11 @@ int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused, ...@@ -1214,10 +1214,11 @@ int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused,
"For your workloads it needs to be <= 1\nHint:\t"); "For your workloads it needs to be <= 1\nHint:\t");
} }
printed += scnprintf(buf + printed, size - printed, printed += scnprintf(buf + printed, size - printed,
"For system wide tracing it needs to be set to -1"); "For system wide tracing it needs to be set to -1.\n");
printed += scnprintf(buf + printed, size - printed, printed += scnprintf(buf + printed, size - printed,
".\nHint:\tThe current value is %d.", value); "Hint:\tTry: 'sudo sh -c \"echo -1 > /proc/sys/kernel/perf_event_paranoid\"'\n"
"Hint:\tThe current value is %d.", value);
break; break;
default: default:
scnprintf(buf, size, "%s", emsg); scnprintf(buf, size, "%s", emsg);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment