Skip to content

Commit

Permalink
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/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 <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
  • Loading branch information
Ingo Molnar committed Jul 16, 2014
2 parents fbe26ab + 4414a3c commit f4aa84f
Show file tree
Hide file tree
Showing 17 changed files with 249 additions and 91 deletions.
1 change: 1 addition & 0 deletions tools/perf/arch/s390/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ ifndef NO_DWARF
PERF_HAVE_DWARF_REGS := 1
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
endif
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o
28 changes: 28 additions & 0 deletions tools/perf/arch/s390/util/header.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Implementation of get_cpuid().
*
* Copyright 2014 IBM Corp.
* Author(s): Alexander Yarygin <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License (version 2 only)
* as published by the Free Software Foundation.
*/

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

#include "../../util/header.h"

int get_cpuid(char *buffer, size_t sz)
{
const char *cpuid = "IBM/S390";

if (strlen(cpuid) + 1 > sz)
return -1;

strcpy(buffer, cpuid);
return 0;
}
1 change: 1 addition & 0 deletions tools/perf/arch/x86/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ endif
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/tsc.o
LIB_H += arch/$(ARCH)/util/tsc.h
HAVE_KVM_STAT_SUPPORT := 1
72 changes: 38 additions & 34 deletions tools/perf/builtin-kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#include <pthread.h>
#include <math.h>

#if defined(__i386__) || defined(__x86_64__)
#ifdef HAVE_KVM_STAT_SUPPORT
#include <asm/svm.h>
#include <asm/vmx.h>
#include <asm/kvm.h>
Expand Down Expand Up @@ -99,7 +99,6 @@ struct perf_kvm_stat {
int trace_vcpu;

struct exit_reasons_table *exit_reasons;
int exit_reasons_size;
const char *exit_reasons_isa;

struct kvm_events_ops *events_ops;
Expand Down Expand Up @@ -158,20 +157,19 @@ static bool exit_event_end(struct perf_evsel *evsel,
return kvm_entry_event(evsel);
}

static struct exit_reasons_table vmx_exit_reasons[] = {
VMX_EXIT_REASONS
};
#define define_exit_reasons_table(name, symbols) \
static struct exit_reasons_table name[] = { \
symbols, { -1, NULL } \
}

static struct exit_reasons_table svm_exit_reasons[] = {
SVM_EXIT_REASONS
};
define_exit_reasons_table(vmx_exit_reasons, VMX_EXIT_REASONS);
define_exit_reasons_table(svm_exit_reasons, SVM_EXIT_REASONS);

static const char *get_exit_reason(struct perf_kvm_stat *kvm, u64 exit_code)
static const char *get_exit_reason(struct perf_kvm_stat *kvm,
struct exit_reasons_table *tbl,
u64 exit_code)
{
int i = kvm->exit_reasons_size;
struct exit_reasons_table *tbl = kvm->exit_reasons;

while (i--) {
while (tbl->reason != NULL) {
if (tbl->exit_code == exit_code)
return tbl->reason;
tbl++;
Expand All @@ -186,7 +184,8 @@ static void exit_event_decode_key(struct perf_kvm_stat *kvm,
struct event_key *key,
char decode[20])
{
const char *exit_reason = get_exit_reason(kvm, key->key);
const char *exit_reason = get_exit_reason(kvm, kvm->exit_reasons,
key->key);

scnprintf(decode, 20, "%s", exit_reason);
}
Expand Down Expand Up @@ -836,37 +835,45 @@ static int process_sample_event(struct perf_tool *tool,
return 0;
}

static int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid)
{
if (strstr(cpuid, "Intel")) {
kvm->exit_reasons = vmx_exit_reasons;
kvm->exit_reasons_isa = "VMX";
} else if (strstr(cpuid, "AMD")) {
kvm->exit_reasons = svm_exit_reasons;
kvm->exit_reasons_isa = "SVM";
} else
return -ENOTSUP;

return 0;
}

static int cpu_isa_config(struct perf_kvm_stat *kvm)
{
char buf[64], *cpuid;
int err, isa;
int err;

if (kvm->live) {
err = get_cpuid(buf, sizeof(buf));
if (err != 0) {
pr_err("Failed to look up CPU type (Intel or AMD)\n");
pr_err("Failed to look up CPU type\n");
return err;
}
cpuid = buf;
} else
cpuid = kvm->session->header.env.cpuid;

if (strstr(cpuid, "Intel"))
isa = 1;
else if (strstr(cpuid, "AMD"))
isa = 0;
else {
pr_err("CPU %s is not supported.\n", cpuid);
return -ENOTSUP;
if (!cpuid) {
pr_err("Failed to look up CPU type\n");
return -EINVAL;
}

if (isa == 1) {
kvm->exit_reasons = vmx_exit_reasons;
kvm->exit_reasons_size = ARRAY_SIZE(vmx_exit_reasons);
kvm->exit_reasons_isa = "VMX";
}
err = cpu_isa_init(kvm, cpuid);
if (err == -ENOTSUP)
pr_err("CPU %s is not supported.\n", cpuid);

return 0;
return err;
}

static bool verify_vcpu(int vcpu)
Expand Down Expand Up @@ -1585,9 +1592,6 @@ static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
.report_event = "vmexit",
.sort_key = "sample",

.exit_reasons = svm_exit_reasons,
.exit_reasons_size = ARRAY_SIZE(svm_exit_reasons),
.exit_reasons_isa = "SVM",
};

if (argc == 1) {
Expand All @@ -1609,7 +1613,7 @@ static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
perf_stat:
return cmd_stat(argc, argv, NULL);
}
#endif
#endif /* HAVE_KVM_STAT_SUPPORT */

static int __cmd_record(const char *file_name, int argc, const char **argv)
{
Expand Down Expand Up @@ -1726,7 +1730,7 @@ int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused)
return cmd_top(argc, argv, NULL);
else if (!strncmp(argv[0], "buildid-list", 12))
return __cmd_buildid_list(file_name, argc, argv);
#if defined(__i386__) || defined(__x86_64__)
#ifdef HAVE_KVM_STAT_SUPPORT
else if (!strncmp(argv[0], "stat", 4))
return kvm_cmd_stat(file_name, argc, argv);
#endif
Expand Down
23 changes: 20 additions & 3 deletions tools/perf/builtin-trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,7 @@ struct thread_trace {
u64 exit_time;
bool entry_pending;
unsigned long nr_events;
unsigned long pfmaj, pfmin;
char *entry_str;
double runtime_ms;
struct {
Expand Down Expand Up @@ -1787,12 +1788,12 @@ static void print_location(FILE *f, struct perf_sample *sample,
fprintf(f, "%s@", al->map->dso->long_name);

if ((verbose || print_sym) && al->sym)
fprintf(f, "%s+0x%lx", al->sym->name,
fprintf(f, "%s+0x%" PRIx64, al->sym->name,
al->addr - al->sym->start);
else if (al->map)
fprintf(f, "0x%lx", al->addr);
fprintf(f, "0x%" PRIx64, al->addr);
else
fprintf(f, "0x%lx", sample->addr);
fprintf(f, "0x%" PRIx64, sample->addr);
}

static int trace__pgfault(struct trace *trace,
Expand All @@ -1804,8 +1805,20 @@ static int trace__pgfault(struct trace *trace,
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
struct addr_location al;
char map_type = 'd';
struct thread_trace *ttrace;

thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
ttrace = thread__trace(thread, trace->output);
if (ttrace == NULL)
return -1;

if (evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ)
ttrace->pfmaj++;
else
ttrace->pfmin++;

if (trace->summary_only)
return 0;

thread__find_addr_location(thread, trace->host, cpumode, MAP__FUNCTION,
sample->ip, &al);
Expand Down Expand Up @@ -2346,6 +2359,10 @@ static int trace__fprintf_one_thread(struct thread *thread, void *priv)
printed += fprintf(fp, " %s (%d), ", thread__comm_str(thread), thread->tid);
printed += fprintf(fp, "%lu events, ", ttrace->nr_events);
printed += fprintf(fp, "%.1f%%", ratio);
if (ttrace->pfmaj)
printed += fprintf(fp, ", %lu majfaults", ttrace->pfmaj);
if (ttrace->pfmin)
printed += fprintf(fp, ", %lu minfaults", ttrace->pfmin);
printed += fprintf(fp, ", %.3f msec\n", ttrace->runtime_ms);
printed += thread__dump_stats(ttrace, trace, fp);

Expand Down
4 changes: 4 additions & 0 deletions tools/perf/config/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,10 @@ ifndef NO_LIBNUMA
endif
endif

ifdef HAVE_KVM_STAT_SUPPORT
CFLAGS += -DHAVE_KVM_STAT_SUPPORT
endif

# Among the variables below, these:
# perfexecdir
# template_dir
Expand Down
1 change: 1 addition & 0 deletions tools/perf/perf-sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#define mb() asm volatile("bcr 15,0" ::: "memory")
#define wmb() asm volatile("bcr 15,0" ::: "memory")
#define rmb() asm volatile("bcr 15,0" ::: "memory")
#define CPUINFO_PROC "vendor_id"
#endif

#ifdef __sh__
Expand Down
37 changes: 20 additions & 17 deletions tools/perf/ui/browser.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ unsigned int ui_browser__rb_tree_refresh(struct ui_browser *browser)
while (nd != NULL) {
ui_browser__gotorc(browser, row, 0);
browser->write(browser, nd, row);
if (++row == browser->height)
if (++row == browser->rows)
break;
nd = rb_next(nd);
}
Expand All @@ -166,7 +166,7 @@ bool ui_browser__is_current_entry(struct ui_browser *browser, unsigned row)
void ui_browser__refresh_dimensions(struct ui_browser *browser)
{
browser->width = SLtt_Screen_Cols - 1;
browser->height = SLtt_Screen_Rows - 2;
browser->height = browser->rows = SLtt_Screen_Rows - 2;
browser->y = 1;
browser->x = 0;
}
Expand Down Expand Up @@ -250,7 +250,10 @@ int ui_browser__show(struct ui_browser *browser, const char *title,
int err;
va_list ap;

ui_browser__refresh_dimensions(browser);
if (browser->refresh_dimensions == NULL)
browser->refresh_dimensions = ui_browser__refresh_dimensions;

browser->refresh_dimensions(browser);

pthread_mutex_lock(&ui__lock);
__ui_browser__show_title(browser, title);
Expand Down Expand Up @@ -367,7 +370,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)

if (key == K_RESIZE) {
ui__refresh_dimensions(false);
ui_browser__refresh_dimensions(browser);
browser->refresh_dimensions(browser);
__ui_browser__show_title(browser, browser->title);
ui_helpline__puts(browser->helpline);
continue;
Expand All @@ -389,7 +392,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
if (browser->index == browser->nr_entries - 1)
break;
++browser->index;
if (browser->index == browser->top_idx + browser->height) {
if (browser->index == browser->top_idx + browser->rows) {
++browser->top_idx;
browser->seek(browser, +1, SEEK_CUR);
}
Expand All @@ -405,10 +408,10 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
break;
case K_PGDN:
case ' ':
if (browser->top_idx + browser->height > browser->nr_entries - 1)
if (browser->top_idx + browser->rows > browser->nr_entries - 1)
break;

offset = browser->height;
offset = browser->rows;
if (browser->index + offset > browser->nr_entries - 1)
offset = browser->nr_entries - 1 - browser->index;
browser->index += offset;
Expand All @@ -419,10 +422,10 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
if (browser->top_idx == 0)
break;

if (browser->top_idx < browser->height)
if (browser->top_idx < browser->rows)
offset = browser->top_idx;
else
offset = browser->height;
offset = browser->rows;

browser->index -= offset;
browser->top_idx -= offset;
Expand All @@ -432,7 +435,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
ui_browser__reset_index(browser);
break;
case K_END:
offset = browser->height - 1;
offset = browser->rows - 1;
if (offset >= browser->nr_entries)
offset = browser->nr_entries - 1;

Expand Down Expand Up @@ -462,7 +465,7 @@ unsigned int ui_browser__list_head_refresh(struct ui_browser *browser)
if (!browser->filter || !browser->filter(browser, pos)) {
ui_browser__gotorc(browser, row, 0);
browser->write(browser, pos, row);
if (++row == browser->height)
if (++row == browser->rows)
break;
}
}
Expand Down Expand Up @@ -587,7 +590,7 @@ unsigned int ui_browser__argv_refresh(struct ui_browser *browser)
if (!browser->filter || !browser->filter(browser, *pos)) {
ui_browser__gotorc(browser, row, 0);
browser->write(browser, pos, row);
if (++row == browser->height)
if (++row == browser->rows)
break;
}

Expand Down Expand Up @@ -623,7 +626,7 @@ static void __ui_browser__line_arrow_up(struct ui_browser *browser,

SLsmg_set_char_set(1);

if (start < browser->top_idx + browser->height) {
if (start < browser->top_idx + browser->rows) {
row = start - browser->top_idx;
ui_browser__gotorc(browser, row, column);
SLsmg_write_char(SLSMG_LLCORN_CHAR);
Expand All @@ -633,7 +636,7 @@ static void __ui_browser__line_arrow_up(struct ui_browser *browser,
if (row-- == 0)
goto out;
} else
row = browser->height - 1;
row = browser->rows - 1;

if (end > browser->top_idx)
end_row = end - browser->top_idx;
Expand Down Expand Up @@ -675,16 +678,16 @@ static void __ui_browser__line_arrow_down(struct ui_browser *browser,
} else
row = 0;

if (end >= browser->top_idx + browser->height)
end_row = browser->height - 1;
if (end >= browser->top_idx + browser->rows)
end_row = browser->rows - 1;
else
end_row = end - browser->top_idx;

ui_browser__gotorc(browser, row, column);
SLsmg_draw_vline(end_row - row + 1);

ui_browser__gotorc(browser, end_row, column);
if (end < browser->top_idx + browser->height) {
if (end < browser->top_idx + browser->rows) {
SLsmg_write_char(SLSMG_LLCORN_CHAR);
ui_browser__gotorc(browser, end_row, column + 1);
SLsmg_write_char(SLSMG_HLINE_CHAR);
Expand Down
Loading

0 comments on commit f4aa84f

Please sign in to comment.