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 fixes and improvements from Arnaldo Carvalho de Melo:

 * libtraceevent build fixes from Namhyung Kim

 * Prevent overflow when calculating annotation buckets size, from Cody Schafer

 * Set breakpoint events sample period to 1, just like trace events, from Jovi Zhang

 * Fix strerror_r usage, from Kirill Shutemov

 * Fix duplicate function declaration problems with bison 2.6, from Kirill Shutemov

 * Add DSO caching facility (and perf test entry) to speed up binary file
   reading, will be used by the DWARF unwind code, from Jiri Olsa

 * Fix trace event storms by setting PERF_SAMPLE_PERIOD, from Frederic Weisbecker

 * perf kvm fixes from David Ahern

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Ingo Molnar committed Jul 25, 2012
2 parents e2b34e3 + 8696329 commit 045e7e6
Show file tree
Hide file tree
Showing 18 changed files with 657 additions and 116 deletions.
1 change: 1 addition & 0 deletions tools/lib/traceevent/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TRACEEVENT-CFLAGS
14 changes: 12 additions & 2 deletions tools/lib/traceevent/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ libtraceevent.so: $(PEVENT_LIB_OBJS)
libtraceevent.a: $(PEVENT_LIB_OBJS)
$(Q)$(do_build_static_lib)

$(PEVENT_LIB_OBJS): %.o: $(src)/%.c
$(PEVENT_LIB_OBJS): %.o: $(src)/%.c TRACEEVENT-CFLAGS
$(Q)$(do_fpic_compile)

define make_version.h
Expand Down Expand Up @@ -272,6 +272,16 @@ ifneq ($(dep_includes),)
include $(dep_includes)
endif

### Detect environment changes
TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):$(ARCH):$(CROSS_COMPILE)

TRACEEVENT-CFLAGS: force
@FLAGS='$(TRACK_CFLAGS)'; \
if test x"$$FLAGS" != x"`cat TRACEEVENT-CFLAGS 2>/dev/null`" ; then \
echo 1>&2 " * new build flags or cross compiler"; \
echo "$$FLAGS" >TRACEEVENT-CFLAGS; \
fi

tags: force
$(RM) tags
find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \
Expand All @@ -297,7 +307,7 @@ install: install_lib

clean:
$(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d
$(RM) tags TAGS
$(RM) TRACEEVENT-CFLAGS tags TAGS

endif # skip-makefile

Expand Down
4 changes: 4 additions & 0 deletions tools/perf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ LIB_OBJS += $(OUTPUT)util/usage.o
LIB_OBJS += $(OUTPUT)util/wrapper.o
LIB_OBJS += $(OUTPUT)util/sigchain.o
LIB_OBJS += $(OUTPUT)util/symbol.o
LIB_OBJS += $(OUTPUT)util/dso-test-data.o
LIB_OBJS += $(OUTPUT)util/color.o
LIB_OBJS += $(OUTPUT)util/pager.o
LIB_OBJS += $(OUTPUT)util/header.o
Expand Down Expand Up @@ -803,6 +804,9 @@ $(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS
$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<

$(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Wno-redundant-decls $<

$(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<

Expand Down
4 changes: 4 additions & 0 deletions tools/perf/builtin-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,10 @@ static struct test {
.desc = "Test perf pmu format parsing",
.func = test__perf_pmu,
},
{
.desc = "Test dso data interface",
.func = dso__test_data,
},
{
.func = NULL,
},
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/builtin-top.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he)
/*
* We can't annotate with just /proc/kallsyms
*/
if (map->dso->symtab_type == SYMTAB__KALLSYMS) {
if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS) {
pr_err("Can't annotate %s: No vmlinux file was found in the "
"path\n", sym->name);
sleep(1);
Expand Down
4 changes: 2 additions & 2 deletions tools/perf/ui/browsers/hists.c
Original file line number Diff line number Diff line change
Expand Up @@ -978,8 +978,8 @@ static int hist_browser__dump(struct hist_browser *browser)
fp = fopen(filename, "w");
if (fp == NULL) {
char bf[64];
strerror_r(errno, bf, sizeof(bf));
ui_helpline__fpush("Couldn't write to %s: %s", filename, bf);
const char *err = strerror_r(errno, bf, sizeof(bf));
ui_helpline__fpush("Couldn't write to %s: %s", filename, err);
return -1;
}

Expand Down
15 changes: 13 additions & 2 deletions tools/perf/util/annotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,18 @@ int symbol__alloc_hist(struct symbol *sym)
{
struct annotation *notes = symbol__annotation(sym);
const size_t size = symbol__size(sym);
size_t sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(u64));
size_t sizeof_sym_hist;

/* Check for overflow when calculating sizeof_sym_hist */
if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(u64))
return -1;

sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(u64));

/* Check for overflow in zalloc argument */
if (sizeof_sym_hist > (SIZE_MAX - sizeof(*notes->src))
/ symbol_conf.nr_events)
return -1;

notes->src = zalloc(sizeof(*notes->src) + symbol_conf.nr_events * sizeof_sym_hist);
if (notes->src == NULL)
Expand Down Expand Up @@ -777,7 +788,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
free_filename = false;
}

if (dso->symtab_type == SYMTAB__KALLSYMS) {
if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS) {
char bf[BUILD_ID_SIZE * 2 + 16] = " with build id ";
char *build_id_msg = NULL;

Expand Down
153 changes: 153 additions & 0 deletions tools/perf/util/dso-test-data.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#include "util.h"

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

#include "symbol.h"

#define TEST_ASSERT_VAL(text, cond) \
do { \
if (!(cond)) { \
pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \
return -1; \
} \
} while (0)

static char *test_file(int size)
{
static char buf_templ[] = "/tmp/test-XXXXXX";
char *templ = buf_templ;
int fd, i;
unsigned char *buf;

fd = mkostemp(templ, O_CREAT|O_WRONLY|O_TRUNC);

buf = malloc(size);
if (!buf) {
close(fd);
return NULL;
}

for (i = 0; i < size; i++)
buf[i] = (unsigned char) ((int) i % 10);

if (size != write(fd, buf, size))
templ = NULL;

close(fd);
return templ;
}

#define TEST_FILE_SIZE (DSO__DATA_CACHE_SIZE * 20)

struct test_data_offset {
off_t offset;
u8 data[10];
int size;
};

struct test_data_offset offsets[] = {
/* Fill first cache page. */
{
.offset = 10,
.data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
.size = 10,
},
/* Read first cache page. */
{
.offset = 10,
.data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
.size = 10,
},
/* Fill cache boundary pages. */
{
.offset = DSO__DATA_CACHE_SIZE - DSO__DATA_CACHE_SIZE % 10,
.data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
.size = 10,
},
/* Read cache boundary pages. */
{
.offset = DSO__DATA_CACHE_SIZE - DSO__DATA_CACHE_SIZE % 10,
.data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
.size = 10,
},
/* Fill final cache page. */
{
.offset = TEST_FILE_SIZE - 10,
.data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
.size = 10,
},
/* Read final cache page. */
{
.offset = TEST_FILE_SIZE - 10,
.data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
.size = 10,
},
/* Read final cache page. */
{
.offset = TEST_FILE_SIZE - 3,
.data = { 7, 8, 9, 0, 0, 0, 0, 0, 0, 0 },
.size = 3,
},
};

int dso__test_data(void)
{
struct machine machine;
struct dso *dso;
char *file = test_file(TEST_FILE_SIZE);
size_t i;

TEST_ASSERT_VAL("No test file", file);

memset(&machine, 0, sizeof(machine));

dso = dso__new((const char *)file);

/* Basic 10 bytes tests. */
for (i = 0; i < ARRAY_SIZE(offsets); i++) {
struct test_data_offset *data = &offsets[i];
ssize_t size;
u8 buf[10];

memset(buf, 0, 10);
size = dso__data_read_offset(dso, &machine, data->offset,
buf, 10);

TEST_ASSERT_VAL("Wrong size", size == data->size);
TEST_ASSERT_VAL("Wrong data", !memcmp(buf, data->data, 10));
}

/* Read cross multiple cache pages. */
{
ssize_t size;
int c;
u8 *buf;

buf = malloc(TEST_FILE_SIZE);
TEST_ASSERT_VAL("ENOMEM\n", buf);

/* First iteration to fill caches, second one to read them. */
for (c = 0; c < 2; c++) {
memset(buf, 0, TEST_FILE_SIZE);
size = dso__data_read_offset(dso, &machine, 10,
buf, TEST_FILE_SIZE);

TEST_ASSERT_VAL("Wrong size",
size == (TEST_FILE_SIZE - 10));

for (i = 0; i < (size_t)size; i++)
TEST_ASSERT_VAL("Wrong data",
buf[i] == (i % 10));
}

free(buf);
}

dso__delete(dso);
unlink(file);
return 0;
}
2 changes: 1 addition & 1 deletion tools/perf/util/evlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ int perf_evlist__add_tracepoints(struct perf_evlist *evlist,
attrs[i].type = PERF_TYPE_TRACEPOINT;
attrs[i].config = err;
attrs[i].sample_type = (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME |
PERF_SAMPLE_CPU);
PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD);
attrs[i].sample_period = 1;
}

Expand Down
6 changes: 6 additions & 0 deletions tools/perf/util/header.c
Original file line number Diff line number Diff line change
Expand Up @@ -1212,6 +1212,12 @@ static void print_event_desc(struct perf_header *ph, int fd, FILE *fp)
attr.exclude_user,
attr.exclude_kernel);

fprintf(fp, ", excl_host = %d, excl_guest = %d",
attr.exclude_host,
attr.exclude_guest);

fprintf(fp, ", precise_ip = %d", attr.precise_ip);

if (nr)
fprintf(fp, ", id = {");

Expand Down
7 changes: 5 additions & 2 deletions tools/perf/util/hist.c
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root,
bool printed = false;
struct rb_node *node;
int i = 0;
int ret;
int ret = 0;

/*
* If have one single callchain root, don't bother printing
Expand Down Expand Up @@ -747,8 +747,11 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root,
root = &cnode->rb_root;
}

return __callchain__fprintf_graph(fp, root, total_samples,
ret += __callchain__fprintf_graph(fp, root, total_samples,
1, 1, left_margin);
ret += fprintf(fp, "\n");

return ret;
}

static size_t __callchain__fprintf_flat(FILE *fp,
Expand Down
41 changes: 39 additions & 2 deletions tools/perf/util/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include <stdio.h>
#include <unistd.h>
#include "map.h"
#include "thread.h"
#include "strlist.h"

const char *map_type__name[MAP__NR_TYPES] = {
[MAP__FUNCTION] = "Functions",
Expand Down Expand Up @@ -585,7 +587,21 @@ int machine__init(struct machine *self, const char *root_dir, pid_t pid)
self->kmaps.machine = self;
self->pid = pid;
self->root_dir = strdup(root_dir);
return self->root_dir == NULL ? -ENOMEM : 0;
if (self->root_dir == NULL)
return -ENOMEM;

if (pid != HOST_KERNEL_ID) {
struct thread *thread = machine__findnew_thread(self, pid);
char comm[64];

if (thread == NULL)
return -ENOMEM;

snprintf(comm, sizeof(comm), "[guest/%d]", pid);
thread__set_comm(thread, comm);
}

return 0;
}

static void dsos__delete(struct list_head *self)
Expand Down Expand Up @@ -680,7 +696,15 @@ struct machine *machines__findnew(struct rb_root *self, pid_t pid)
(symbol_conf.guestmount)) {
sprintf(path, "%s/%d", symbol_conf.guestmount, pid);
if (access(path, R_OK)) {
pr_err("Can't access file %s\n", path);
static struct strlist *seen;

if (!seen)
seen = strlist__new(true, NULL);

if (!strlist__has_entry(seen, path)) {
pr_err("Can't access file %s\n", path);
strlist__add(seen, path);
}
machine = NULL;
goto out;
}
Expand Down Expand Up @@ -714,3 +738,16 @@ char *machine__mmap_name(struct machine *self, char *bf, size_t size)

return bf;
}

void machines__set_id_hdr_size(struct rb_root *machines, u16 id_hdr_size)
{
struct rb_node *node;
struct machine *machine;

for (node = rb_first(machines); node; node = rb_next(node)) {
machine = rb_entry(node, struct machine, rb_node);
machine->id_hdr_size = id_hdr_size;
}

return;
}
1 change: 1 addition & 0 deletions tools/perf/util/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ struct machine *machines__add(struct rb_root *self, pid_t pid,
struct machine *machines__find_host(struct rb_root *self);
struct machine *machines__find(struct rb_root *self, pid_t pid);
struct machine *machines__findnew(struct rb_root *self, pid_t pid);
void machines__set_id_hdr_size(struct rb_root *self, u16 id_hdr_size);
char *machine__mmap_name(struct machine *self, char *bf, size_t size);
int machine__init(struct machine *self, const char *root_dir, pid_t pid);
void machine__exit(struct machine *self);
Expand Down
Loading

0 comments on commit 045e7e6

Please sign in to comment.