Merge branch 'perf/urgent' into perf/core
Conflicts: tools/perf/builtin-record.c tools/perf/builtin-top.c tools/perf/util/hist.h
This commit is contained in:
@@ -146,6 +146,9 @@ static inline void callchain_cursor_advance(struct callchain_cursor *cursor)
|
||||
|
||||
struct option;
|
||||
|
||||
int record_parse_callchain(const char *arg, struct perf_record_opts *opts);
|
||||
int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
|
||||
int record_callchain_opt(const struct option *opt, const char *arg, int unset);
|
||||
|
||||
extern const char record_callchain_help[];
|
||||
#endif /* __PERF_CALLCHAIN_H */
|
||||
|
||||
@@ -187,7 +187,7 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
|
||||
return -1;
|
||||
}
|
||||
|
||||
event->header.type = PERF_RECORD_MMAP2;
|
||||
event->header.type = PERF_RECORD_MMAP;
|
||||
/*
|
||||
* Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
|
||||
*/
|
||||
@@ -198,7 +198,6 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
|
||||
char prot[5];
|
||||
char execname[PATH_MAX];
|
||||
char anonstr[] = "//anon";
|
||||
unsigned int ino;
|
||||
size_t size;
|
||||
ssize_t n;
|
||||
|
||||
@@ -209,15 +208,12 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
|
||||
strcpy(execname, "");
|
||||
|
||||
/* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */
|
||||
n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %x:%x %u %s\n",
|
||||
&event->mmap2.start, &event->mmap2.len, prot,
|
||||
&event->mmap2.pgoff, &event->mmap2.maj,
|
||||
&event->mmap2.min,
|
||||
&ino, execname);
|
||||
n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %*x:%*x %*u %s\n",
|
||||
&event->mmap.start, &event->mmap.len, prot,
|
||||
&event->mmap.pgoff,
|
||||
execname);
|
||||
|
||||
event->mmap2.ino = (u64)ino;
|
||||
|
||||
if (n != 8)
|
||||
if (n != 5)
|
||||
continue;
|
||||
|
||||
if (prot[2] != 'x')
|
||||
@@ -227,15 +223,15 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
|
||||
strcpy(execname, anonstr);
|
||||
|
||||
size = strlen(execname) + 1;
|
||||
memcpy(event->mmap2.filename, execname, size);
|
||||
memcpy(event->mmap.filename, execname, size);
|
||||
size = PERF_ALIGN(size, sizeof(u64));
|
||||
event->mmap2.len -= event->mmap.start;
|
||||
event->mmap2.header.size = (sizeof(event->mmap2) -
|
||||
(sizeof(event->mmap2.filename) - size));
|
||||
memset(event->mmap2.filename + size, 0, machine->id_hdr_size);
|
||||
event->mmap2.header.size += machine->id_hdr_size;
|
||||
event->mmap2.pid = tgid;
|
||||
event->mmap2.tid = pid;
|
||||
event->mmap.len -= event->mmap.start;
|
||||
event->mmap.header.size = (sizeof(event->mmap) -
|
||||
(sizeof(event->mmap.filename) - size));
|
||||
memset(event->mmap.filename + size, 0, machine->id_hdr_size);
|
||||
event->mmap.header.size += machine->id_hdr_size;
|
||||
event->mmap.pid = tgid;
|
||||
event->mmap.tid = pid;
|
||||
|
||||
if (process(tool, event, &synth_sample, machine) != 0) {
|
||||
rc = -1;
|
||||
|
||||
@@ -558,12 +558,19 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
|
||||
|
||||
md->prev = old;
|
||||
|
||||
if (!evlist->overwrite)
|
||||
perf_mmap__write_tail(md, old);
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx)
|
||||
{
|
||||
if (!evlist->overwrite) {
|
||||
struct perf_mmap *md = &evlist->mmap[idx];
|
||||
unsigned int old = md->prev;
|
||||
|
||||
perf_mmap__write_tail(md, old);
|
||||
}
|
||||
}
|
||||
|
||||
static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx)
|
||||
{
|
||||
if (evlist->mmap[idx].base != NULL) {
|
||||
|
||||
@@ -90,6 +90,8 @@ struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id);
|
||||
|
||||
union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx);
|
||||
|
||||
void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx);
|
||||
|
||||
int perf_evlist__open(struct perf_evlist *evlist);
|
||||
void perf_evlist__close(struct perf_evlist *evlist);
|
||||
|
||||
|
||||
@@ -678,7 +678,6 @@ void perf_evsel__config(struct perf_evsel *evsel,
|
||||
attr->sample_type |= PERF_SAMPLE_WEIGHT;
|
||||
|
||||
attr->mmap = track;
|
||||
attr->mmap2 = track && !perf_missing_features.mmap2;
|
||||
attr->comm = track;
|
||||
|
||||
if (opts->sample_transaction)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <pthread.h>
|
||||
#include "callchain.h"
|
||||
#include "header.h"
|
||||
#include "color.h"
|
||||
#include "ui/progress.h"
|
||||
|
||||
extern struct callchain_param callchain_param;
|
||||
@@ -180,6 +181,18 @@ void perf_hpp__init(void);
|
||||
void perf_hpp__column_register(struct perf_hpp_fmt *format);
|
||||
void perf_hpp__column_enable(unsigned col);
|
||||
|
||||
static inline size_t perf_hpp__use_color(void)
|
||||
{
|
||||
return !symbol_conf.field_sep;
|
||||
}
|
||||
|
||||
static inline size_t perf_hpp__color_overhead(void)
|
||||
{
|
||||
return perf_hpp__use_color() ?
|
||||
(COLOR_MAXLEN + sizeof(PERF_COLOR_RESET)) * PERF_HPP__MAX_INDEX
|
||||
: 0;
|
||||
}
|
||||
|
||||
struct perf_evlist;
|
||||
|
||||
struct hist_browser_timer {
|
||||
|
||||
@@ -1460,10 +1460,10 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
|
||||
goto post;
|
||||
}
|
||||
|
||||
fname = dwarf_decl_file(&spdie);
|
||||
if (addr == (unsigned long)baseaddr) {
|
||||
/* Function entry - Relative line number is 0 */
|
||||
lineno = baseline;
|
||||
fname = dwarf_decl_file(&spdie);
|
||||
goto post;
|
||||
}
|
||||
|
||||
|
||||
@@ -815,6 +815,8 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
|
||||
PyObject *pyevent = pyrf_event__new(event);
|
||||
struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
|
||||
|
||||
perf_evlist__mmap_consume(evlist, cpu);
|
||||
|
||||
if (pyevent == NULL)
|
||||
return PyErr_NoMemory();
|
||||
|
||||
|
||||
@@ -56,6 +56,17 @@ static void handler_call_die(const char *handler_name)
|
||||
Py_FatalError("problem in Python trace event handler");
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert val into into the dictionary and decrement the reference counter.
|
||||
* This is necessary for dictionaries since PyDict_SetItemString() does not
|
||||
* steal a reference, as opposed to PyTuple_SetItem().
|
||||
*/
|
||||
static void pydict_set_item_string_decref(PyObject *dict, const char *key, PyObject *val)
|
||||
{
|
||||
PyDict_SetItemString(dict, key, val);
|
||||
Py_DECREF(val);
|
||||
}
|
||||
|
||||
static void define_value(enum print_arg_type field_type,
|
||||
const char *ev_name,
|
||||
const char *field_name,
|
||||
@@ -279,11 +290,11 @@ static void python_process_tracepoint(union perf_event *perf_event
|
||||
PyTuple_SetItem(t, n++, PyInt_FromLong(pid));
|
||||
PyTuple_SetItem(t, n++, PyString_FromString(comm));
|
||||
} else {
|
||||
PyDict_SetItemString(dict, "common_cpu", PyInt_FromLong(cpu));
|
||||
PyDict_SetItemString(dict, "common_s", PyInt_FromLong(s));
|
||||
PyDict_SetItemString(dict, "common_ns", PyInt_FromLong(ns));
|
||||
PyDict_SetItemString(dict, "common_pid", PyInt_FromLong(pid));
|
||||
PyDict_SetItemString(dict, "common_comm", PyString_FromString(comm));
|
||||
pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu));
|
||||
pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s));
|
||||
pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns));
|
||||
pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid));
|
||||
pydict_set_item_string_decref(dict, "common_comm", PyString_FromString(comm));
|
||||
}
|
||||
for (field = event->format.fields; field; field = field->next) {
|
||||
if (field->flags & FIELD_IS_STRING) {
|
||||
@@ -313,7 +324,7 @@ static void python_process_tracepoint(union perf_event *perf_event
|
||||
if (handler)
|
||||
PyTuple_SetItem(t, n++, obj);
|
||||
else
|
||||
PyDict_SetItemString(dict, field->name, obj);
|
||||
pydict_set_item_string_decref(dict, field->name, obj);
|
||||
|
||||
}
|
||||
if (!handler)
|
||||
@@ -370,21 +381,21 @@ static void python_process_general_event(union perf_event *perf_event
|
||||
if (!handler || !PyCallable_Check(handler))
|
||||
goto exit;
|
||||
|
||||
PyDict_SetItemString(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
|
||||
PyDict_SetItemString(dict, "attr", PyString_FromStringAndSize(
|
||||
pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
|
||||
pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize(
|
||||
(const char *)&evsel->attr, sizeof(evsel->attr)));
|
||||
PyDict_SetItemString(dict, "sample", PyString_FromStringAndSize(
|
||||
pydict_set_item_string_decref(dict, "sample", PyString_FromStringAndSize(
|
||||
(const char *)sample, sizeof(*sample)));
|
||||
PyDict_SetItemString(dict, "raw_buf", PyString_FromStringAndSize(
|
||||
pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize(
|
||||
(const char *)sample->raw_data, sample->raw_size));
|
||||
PyDict_SetItemString(dict, "comm",
|
||||
pydict_set_item_string_decref(dict, "comm",
|
||||
PyString_FromString(thread->comm));
|
||||
if (al->map) {
|
||||
PyDict_SetItemString(dict, "dso",
|
||||
pydict_set_item_string_decref(dict, "dso",
|
||||
PyString_FromString(al->map->dso->name));
|
||||
}
|
||||
if (al->sym) {
|
||||
PyDict_SetItemString(dict, "symbol",
|
||||
pydict_set_item_string_decref(dict, "symbol",
|
||||
PyString_FromString(al->sym->name));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user