提交 b9f616bb 编写于 作者: I Ingo Molnar

Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core

...@@ -21,6 +21,8 @@ EVENT MODIFIERS ...@@ -21,6 +21,8 @@ EVENT MODIFIERS
Events can optionally have a modifer by appending a colon and one or Events can optionally have a modifer by appending a colon and one or
more modifiers. Modifiers allow the user to restrict when events are more modifiers. Modifiers allow the user to restrict when events are
counted with 'u' for user-space, 'k' for kernel, 'h' for hypervisor. counted with 'u' for user-space, 'k' for kernel, 'h' for hypervisor.
Additional modifiers are 'G' for guest counting (in KVM guests) and 'H'
for host counting (not in KVM guests).
The 'p' modifier can be used for specifying how precise the instruction The 'p' modifier can be used for specifying how precise the instruction
address should be. The 'p' modifier is currently only implemented for address should be. The 'p' modifier is currently only implemented for
......
tools/perf tools/perf
include/linux/const.h
include/linux/perf_event.h include/linux/perf_event.h
include/linux/rbtree.h include/linux/rbtree.h
include/linux/list.h include/linux/list.h
......
...@@ -22,9 +22,6 @@ ...@@ -22,9 +22,6 @@
static const char *file_name; static const char *file_name;
static char name_buffer[256]; static char name_buffer[256];
bool perf_host = 1;
bool perf_guest;
static const char * const kvm_usage[] = { static const char * const kvm_usage[] = {
"perf kvm [<options>] {top|record|report|diff|buildid-list}", "perf kvm [<options>] {top|record|report|diff|buildid-list}",
NULL NULL
...@@ -107,7 +104,8 @@ static int __cmd_buildid_list(int argc, const char **argv) ...@@ -107,7 +104,8 @@ static int __cmd_buildid_list(int argc, const char **argv)
int cmd_kvm(int argc, const char **argv, const char *prefix __used) int cmd_kvm(int argc, const char **argv, const char *prefix __used)
{ {
perf_host = perf_guest = 0; perf_host = 0;
perf_guest = 1;
argc = parse_options(argc, argv, kvm_options, kvm_usage, argc = parse_options(argc, argv, kvm_options, kvm_usage,
PARSE_OPT_STOP_AT_NON_OPTION); PARSE_OPT_STOP_AT_NON_OPTION);
......
...@@ -235,7 +235,6 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel, ...@@ -235,7 +235,6 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel,
if (he == NULL) if (he == NULL)
return NULL; return NULL;
evsel->hists.stats.total_period += sample->period;
hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
return he; return he;
} }
......
...@@ -111,8 +111,11 @@ int perf_evlist__add_default(struct perf_evlist *evlist) ...@@ -111,8 +111,11 @@ int perf_evlist__add_default(struct perf_evlist *evlist)
.type = PERF_TYPE_HARDWARE, .type = PERF_TYPE_HARDWARE,
.config = PERF_COUNT_HW_CPU_CYCLES, .config = PERF_COUNT_HW_CPU_CYCLES,
}; };
struct perf_evsel *evsel = perf_evsel__new(&attr, 0); struct perf_evsel *evsel;
event_attr_init(&attr);
evsel = perf_evsel__new(&attr, 0);
if (evsel == NULL) if (evsel == NULL)
goto error; goto error;
......
...@@ -76,21 +76,21 @@ static void hists__calc_col_len(struct hists *hists, struct hist_entry *h) ...@@ -76,21 +76,21 @@ static void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
} }
} }
static void hist_entry__add_cpumode_period(struct hist_entry *self, static void hist_entry__add_cpumode_period(struct hist_entry *he,
unsigned int cpumode, u64 period) unsigned int cpumode, u64 period)
{ {
switch (cpumode) { switch (cpumode) {
case PERF_RECORD_MISC_KERNEL: case PERF_RECORD_MISC_KERNEL:
self->period_sys += period; he->period_sys += period;
break; break;
case PERF_RECORD_MISC_USER: case PERF_RECORD_MISC_USER:
self->period_us += period; he->period_us += period;
break; break;
case PERF_RECORD_MISC_GUEST_KERNEL: case PERF_RECORD_MISC_GUEST_KERNEL:
self->period_guest_sys += period; he->period_guest_sys += period;
break; break;
case PERF_RECORD_MISC_GUEST_USER: case PERF_RECORD_MISC_GUEST_USER:
self->period_guest_us += period; he->period_guest_us += period;
break; break;
default: default:
break; break;
...@@ -165,18 +165,18 @@ void hists__decay_entries_threaded(struct hists *hists, ...@@ -165,18 +165,18 @@ void hists__decay_entries_threaded(struct hists *hists,
static struct hist_entry *hist_entry__new(struct hist_entry *template) static struct hist_entry *hist_entry__new(struct hist_entry *template)
{ {
size_t callchain_size = symbol_conf.use_callchain ? sizeof(struct callchain_root) : 0; size_t callchain_size = symbol_conf.use_callchain ? sizeof(struct callchain_root) : 0;
struct hist_entry *self = malloc(sizeof(*self) + callchain_size); struct hist_entry *he = malloc(sizeof(*he) + callchain_size);
if (self != NULL) { if (he != NULL) {
*self = *template; *he = *template;
self->nr_events = 1; he->nr_events = 1;
if (self->ms.map) if (he->ms.map)
self->ms.map->referenced = true; he->ms.map->referenced = true;
if (symbol_conf.use_callchain) if (symbol_conf.use_callchain)
callchain_init(self->callchain); callchain_init(he->callchain);
} }
return self; return he;
} }
static void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h) static void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h)
...@@ -677,15 +677,16 @@ static size_t callchain__fprintf_flat(FILE *fp, struct callchain_node *self, ...@@ -677,15 +677,16 @@ static size_t callchain__fprintf_flat(FILE *fp, struct callchain_node *self,
return ret; return ret;
} }
static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, static size_t hist_entry_callchain__fprintf(struct hist_entry *he,
u64 total_samples, int left_margin) u64 total_samples, int left_margin,
FILE *fp)
{ {
struct rb_node *rb_node; struct rb_node *rb_node;
struct callchain_node *chain; struct callchain_node *chain;
size_t ret = 0; size_t ret = 0;
u32 entries_printed = 0; u32 entries_printed = 0;
rb_node = rb_first(&self->sorted_chain); rb_node = rb_first(&he->sorted_chain);
while (rb_node) { while (rb_node) {
double percent; double percent;
...@@ -730,35 +731,35 @@ void hists__output_recalc_col_len(struct hists *hists, int max_rows) ...@@ -730,35 +731,35 @@ void hists__output_recalc_col_len(struct hists *hists, int max_rows)
} }
} }
static int hist_entry__pcnt_snprintf(struct hist_entry *self, char *s, static int hist_entry__pcnt_snprintf(struct hist_entry *he, char *s,
size_t size, struct hists *pair_hists, size_t size, struct hists *pair_hists,
bool show_displacement, long displacement, bool show_displacement, long displacement,
bool color, u64 session_total) bool color, u64 total_period)
{ {
u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us; u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us;
u64 nr_events; u64 nr_events;
const char *sep = symbol_conf.field_sep; const char *sep = symbol_conf.field_sep;
int ret; int ret;
if (symbol_conf.exclude_other && !self->parent) if (symbol_conf.exclude_other && !he->parent)
return 0; return 0;
if (pair_hists) { if (pair_hists) {
period = self->pair ? self->pair->period : 0; period = he->pair ? he->pair->period : 0;
nr_events = self->pair ? self->pair->nr_events : 0; nr_events = he->pair ? he->pair->nr_events : 0;
total = pair_hists->stats.total_period; total = pair_hists->stats.total_period;
period_sys = self->pair ? self->pair->period_sys : 0; period_sys = he->pair ? he->pair->period_sys : 0;
period_us = self->pair ? self->pair->period_us : 0; period_us = he->pair ? he->pair->period_us : 0;
period_guest_sys = self->pair ? self->pair->period_guest_sys : 0; period_guest_sys = he->pair ? he->pair->period_guest_sys : 0;
period_guest_us = self->pair ? self->pair->period_guest_us : 0; period_guest_us = he->pair ? he->pair->period_guest_us : 0;
} else { } else {
period = self->period; period = he->period;
nr_events = self->nr_events; nr_events = he->nr_events;
total = session_total; total = total_period;
period_sys = self->period_sys; period_sys = he->period_sys;
period_us = self->period_us; period_us = he->period_us;
period_guest_sys = self->period_guest_sys; period_guest_sys = he->period_guest_sys;
period_guest_us = self->period_guest_us; period_guest_us = he->period_guest_us;
} }
if (total) { if (total) {
...@@ -812,8 +813,8 @@ static int hist_entry__pcnt_snprintf(struct hist_entry *self, char *s, ...@@ -812,8 +813,8 @@ static int hist_entry__pcnt_snprintf(struct hist_entry *self, char *s,
if (total > 0) if (total > 0)
old_percent = (period * 100.0) / total; old_percent = (period * 100.0) / total;
if (session_total > 0) if (total_period > 0)
new_percent = (self->period * 100.0) / session_total; new_percent = (he->period * 100.0) / total_period;
diff = new_percent - old_percent; diff = new_percent - old_percent;
...@@ -862,9 +863,10 @@ int hist_entry__snprintf(struct hist_entry *he, char *s, size_t size, ...@@ -862,9 +863,10 @@ int hist_entry__snprintf(struct hist_entry *he, char *s, size_t size,
return ret; return ret;
} }
int hist_entry__fprintf(struct hist_entry *he, size_t size, struct hists *hists, static int hist_entry__fprintf(struct hist_entry *he, size_t size,
struct hists *pair_hists, bool show_displacement, struct hists *hists, struct hists *pair_hists,
long displacement, FILE *fp, u64 session_total) bool show_displacement, long displacement,
u64 total_period, FILE *fp)
{ {
char bf[512]; char bf[512];
int ret; int ret;
...@@ -874,14 +876,14 @@ int hist_entry__fprintf(struct hist_entry *he, size_t size, struct hists *hists, ...@@ -874,14 +876,14 @@ int hist_entry__fprintf(struct hist_entry *he, size_t size, struct hists *hists,
ret = hist_entry__pcnt_snprintf(he, bf, size, pair_hists, ret = hist_entry__pcnt_snprintf(he, bf, size, pair_hists,
show_displacement, displacement, show_displacement, displacement,
true, session_total); true, total_period);
hist_entry__snprintf(he, bf + ret, size - ret, hists); hist_entry__snprintf(he, bf + ret, size - ret, hists);
return fprintf(fp, "%s\n", bf); return fprintf(fp, "%s\n", bf);
} }
static size_t hist_entry__fprintf_callchain(struct hist_entry *self, static size_t hist_entry__fprintf_callchain(struct hist_entry *he,
struct hists *hists, FILE *fp, struct hists *hists,
u64 session_total) u64 total_period, FILE *fp)
{ {
int left_margin = 0; int left_margin = 0;
...@@ -889,11 +891,10 @@ static size_t hist_entry__fprintf_callchain(struct hist_entry *self, ...@@ -889,11 +891,10 @@ static size_t hist_entry__fprintf_callchain(struct hist_entry *self,
struct sort_entry *se = list_first_entry(&hist_entry__sort_list, struct sort_entry *se = list_first_entry(&hist_entry__sort_list,
typeof(*se), list); typeof(*se), list);
left_margin = hists__col_len(hists, se->se_width_idx); left_margin = hists__col_len(hists, se->se_width_idx);
left_margin -= thread__comm_len(self->thread); left_margin -= thread__comm_len(he->thread);
} }
return hist_entry_callchain__fprintf(fp, self, session_total, return hist_entry_callchain__fprintf(he, total_period, left_margin, fp);
left_margin);
} }
size_t hists__fprintf(struct hists *hists, struct hists *pair, size_t hists__fprintf(struct hists *hists, struct hists *pair,
...@@ -903,6 +904,7 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair, ...@@ -903,6 +904,7 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair,
struct sort_entry *se; struct sort_entry *se;
struct rb_node *nd; struct rb_node *nd;
size_t ret = 0; size_t ret = 0;
u64 total_period;
unsigned long position = 1; unsigned long position = 1;
long displacement = 0; long displacement = 0;
unsigned int width; unsigned int width;
...@@ -1025,6 +1027,8 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair, ...@@ -1025,6 +1027,8 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair,
goto out; goto out;
print_entries: print_entries:
total_period = hists->stats.total_period;
for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
...@@ -1040,11 +1044,10 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair, ...@@ -1040,11 +1044,10 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair,
++position; ++position;
} }
ret += hist_entry__fprintf(h, max_cols, hists, pair, show_displacement, ret += hist_entry__fprintf(h, max_cols, hists, pair, show_displacement,
displacement, fp, hists->stats.total_period); displacement, total_period, fp);
if (symbol_conf.use_callchain) if (symbol_conf.use_callchain)
ret += hist_entry__fprintf_callchain(h, hists, fp, ret += hist_entry__fprintf_callchain(h, hists, total_period, fp);
hists->stats.total_period);
if (max_rows && ++nr_rows >= max_rows) if (max_rows && ++nr_rows >= max_rows)
goto out; goto out;
......
...@@ -66,11 +66,8 @@ struct hists { ...@@ -66,11 +66,8 @@ struct hists {
struct hist_entry *__hists__add_entry(struct hists *self, struct hist_entry *__hists__add_entry(struct hists *self,
struct addr_location *al, struct addr_location *al,
struct symbol *parent, u64 period); struct symbol *parent, u64 period);
extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right);
extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right);
int hist_entry__fprintf(struct hist_entry *he, size_t size, struct hists *hists,
struct hists *pair_hists, bool show_displacement,
long displacement, FILE *fp, u64 session_total);
int hist_entry__snprintf(struct hist_entry *self, char *bf, size_t size, int hist_entry__snprintf(struct hist_entry *self, char *bf, size_t size,
struct hists *hists); struct hists *hists);
void hist_entry__free(struct hist_entry *); void hist_entry__free(struct hist_entry *);
......
...@@ -735,8 +735,8 @@ static int ...@@ -735,8 +735,8 @@ static int
parse_event_modifier(const char **strp, struct perf_event_attr *attr) parse_event_modifier(const char **strp, struct perf_event_attr *attr)
{ {
const char *str = *strp; const char *str = *strp;
int exclude = 0; int exclude = 0, exclude_GH = 0;
int eu = 0, ek = 0, eh = 0, precise = 0; int eu = 0, ek = 0, eh = 0, eH = 0, eG = 0, precise = 0;
if (!*str) if (!*str)
return 0; return 0;
...@@ -760,6 +760,14 @@ parse_event_modifier(const char **strp, struct perf_event_attr *attr) ...@@ -760,6 +760,14 @@ parse_event_modifier(const char **strp, struct perf_event_attr *attr)
if (!exclude) if (!exclude)
exclude = eu = ek = eh = 1; exclude = eu = ek = eh = 1;
eh = 0; eh = 0;
} else if (*str == 'G') {
if (!exclude_GH)
exclude_GH = eG = eH = 1;
eG = 0;
} else if (*str == 'H') {
if (!exclude_GH)
exclude_GH = eG = eH = 1;
eH = 0;
} else if (*str == 'p') { } else if (*str == 'p') {
precise++; precise++;
} else } else
...@@ -776,6 +784,8 @@ parse_event_modifier(const char **strp, struct perf_event_attr *attr) ...@@ -776,6 +784,8 @@ parse_event_modifier(const char **strp, struct perf_event_attr *attr)
attr->exclude_kernel = ek; attr->exclude_kernel = ek;
attr->exclude_hv = eh; attr->exclude_hv = eh;
attr->precise_ip = precise; attr->precise_ip = precise;
attr->exclude_host = eH;
attr->exclude_guest = eG;
return 0; return 0;
} }
...@@ -838,6 +848,7 @@ int parse_events(struct perf_evlist *evlist , const char *str, int unset __used) ...@@ -838,6 +848,7 @@ int parse_events(struct perf_evlist *evlist , const char *str, int unset __used)
for (;;) { for (;;) {
ostr = str; ostr = str;
memset(&attr, 0, sizeof(attr)); memset(&attr, 0, sizeof(attr));
event_attr_init(&attr);
ret = parse_event_symbols(evlist, &str, &attr); ret = parse_event_symbols(evlist, &str, &attr);
if (ret == EVT_FAILED) if (ret == EVT_FAILED)
return -1; return -1;
......
#include "../perf.h"
#include "util.h" #include "util.h"
#include <sys/mman.h> #include <sys/mman.h>
/*
* XXX We need to find a better place for these things...
*/
bool perf_host = true;
bool perf_guest = true;
void event_attr_init(struct perf_event_attr *attr)
{
if (!perf_host)
attr->exclude_host = 1;
if (!perf_guest)
attr->exclude_guest = 1;
}
int mkdir_p(char *path, mode_t mode) int mkdir_p(char *path, mode_t mode)
{ {
struct stat st; struct stat st;
......
...@@ -242,6 +242,10 @@ int strtailcmp(const char *s1, const char *s2); ...@@ -242,6 +242,10 @@ int strtailcmp(const char *s1, const char *s2);
unsigned long convert_unit(unsigned long value, char *unit); unsigned long convert_unit(unsigned long value, char *unit);
int readn(int fd, void *buf, size_t size); int readn(int fd, void *buf, size_t size);
struct perf_event_attr;
void event_attr_init(struct perf_event_attr *attr);
#define _STR(x) #x #define _STR(x) #x
#define STR(x) _STR(x) #define STR(x) _STR(x)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册