Skip to content

Commit

Permalink
Merge tag 'perf-urgent-for-mingo' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/kernel/git/acme/linux into perf/urgent

Pull perf/urgent fixes from Arnaldo Carvalho de Melo:

 * Check for SIGINT in more loops, allowing tools such as 'perf report' to
   react faster to Ctrl+C, from Arnaldo Carvalho de Melo.

 * Fix objdump line parsing offset validation in the annotate code,
   from Adrian Hunter.

 * Fix buildid cache handling of kallsyms with kcore, from Adrian Hunter.

 * Fix compile with libelf without get_phdrnum, from Adrian Hunter.

 * Sharpen the libaudit dependencies test, refusing to build with older
   libraries that doesn't have all the functions used by 'perf trace", fix
   from Ingo Molnar.

 * Fill in new definitions for madvise()/mmap() flags to fix the build in
   older systems, from Ingo Molnar.

 * Fix old GCC build error in older systems in the kallsyms parsing code in
   trace-event-parse.c, from Ingo Molnar.

 * Ignore DWARF declaration tags, allowing, for instance, that the

     $ perf probe -L getname

   command succeeds in showing the source code for the 'getname' kernel
   function, telling in which lines probes can be inserted, fix from
   Masami Hiramatsu.

 * Fix linux/magic.h related build breakage in some systems, fix from
   Vinson Lee.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Ingo Molnar committed Sep 20, 2013
2 parents 186844b + ce7eebe commit 24e31f0
Show file tree
Hide file tree
Showing 17 changed files with 119 additions and 31 deletions.
1 change: 0 additions & 1 deletion tools/lib/lk/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include <stdbool.h>
#include <sys/vfs.h>
#include <sys/mount.h>
#include <linux/magic.h>
#include <linux/kernel.h>

#include "debugfs.h"
Expand Down
2 changes: 0 additions & 2 deletions tools/perf/builtin-inject.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,6 @@ static int perf_inject__sched_stat(struct perf_tool *tool,
return perf_event__repipe(tool, event_sw, &sample_sw, machine);
}

extern volatile int session_done;

static void sig_handler(int sig __maybe_unused)
{
session_done = 1;
Expand Down
5 changes: 3 additions & 2 deletions tools/perf/builtin-report.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,6 @@ static int perf_report__setup_sample_type(struct perf_report *rep)
return 0;
}

extern volatile int session_done;

static void sig_handler(int sig __maybe_unused)
{
session_done = 1;
Expand Down Expand Up @@ -568,6 +566,9 @@ static int __cmd_report(struct perf_report *rep)
}
}

if (session_done())
return 0;

if (nr_samples == 0) {
ui__error("The %s file has no samples!\n", session->filename);
return 0;
Expand Down
2 changes: 0 additions & 2 deletions tools/perf/builtin-script.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,8 +553,6 @@ static struct perf_tool perf_script = {
.ordering_requires_timestamps = true,
};

extern volatile int session_done;

static void sig_handler(int sig __maybe_unused)
{
session_done = 1;
Expand Down
17 changes: 17 additions & 0 deletions tools/perf/builtin-trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,23 @@
#include <sys/mman.h>
#include <linux/futex.h>

/* For older distros: */
#ifndef MAP_STACK
# define MAP_STACK 0x20000
#endif

#ifndef MADV_HWPOISON
# define MADV_HWPOISON 100
#endif

#ifndef MADV_MERGEABLE
# define MADV_MERGEABLE 12
#endif

#ifndef MADV_UNMERGEABLE
# define MADV_UNMERGEABLE 13
#endif

static size_t syscall_arg__scnprintf_hex(char *bf, size_t size,
unsigned long arg,
u8 arg_idx __maybe_unused,
Expand Down
3 changes: 3 additions & 0 deletions tools/perf/config/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
CFLAGS += -DLIBELF_MMAP
endif
ifeq ($(call try-cc,$(SOURCE_ELF_GETPHDRNUM),$(FLAGS_LIBELF),-DHAVE_ELF_GETPHDRNUM),y)
CFLAGS += -DHAVE_ELF_GETPHDRNUM
endif

# include ARCH specific config
-include $(src-perf)/arch/$(ARCH)/Makefile
Expand Down
10 changes: 10 additions & 0 deletions tools/perf/config/feature-tests.mak
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ int main(void)
}
endef

define SOURCE_ELF_GETPHDRNUM
#include <libelf.h>
int main(void)
{
size_t dst;
return elf_getphdrnum(0, &dst);
}
endef

ifndef NO_SLANG
define SOURCE_SLANG
#include <slang.h>
Expand Down Expand Up @@ -210,6 +219,7 @@ define SOURCE_LIBAUDIT

int main(void)
{
printf(\"error message: %s\n\", audit_errno_to_name(0));
return audit_open();
}
endef
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/util/annotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
end = map__rip_2objdump(map, sym->end);

offset = line_ip - start;
if (offset < 0 || (u64)line_ip > end)
if ((u64)line_ip < start || (u64)line_ip > end)
offset = -1;
else
parsed_line = tmp2 + 1;
Expand Down
19 changes: 19 additions & 0 deletions tools/perf/util/dwarf-aux.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,21 @@ bool die_is_signed_type(Dwarf_Die *tp_die)
ret == DW_ATE_signed_fixed);
}

/**
* die_is_func_def - Ensure that this DIE is a subprogram and definition
* @dw_die: a DIE
*
* Ensure that this DIE is a subprogram and NOT a declaration. This
* returns true if @dw_die is a function definition.
**/
bool die_is_func_def(Dwarf_Die *dw_die)
{
Dwarf_Attribute attr;

return (dwarf_tag(dw_die) == DW_TAG_subprogram &&
dwarf_attr(dw_die, DW_AT_declaration, &attr) == NULL);
}

/**
* die_get_data_member_location - Get the data-member offset
* @mb_die: a DIE of a member of a data structure
Expand Down Expand Up @@ -392,6 +407,10 @@ static int __die_search_func_cb(Dwarf_Die *fn_die, void *data)
{
struct __addr_die_search_param *ad = data;

/*
* Since a declaration entry doesn't has given pc, this always returns
* function definition entry.
*/
if (dwarf_tag(fn_die) == DW_TAG_subprogram &&
dwarf_haspc(fn_die, ad->addr)) {
memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die));
Expand Down
3 changes: 3 additions & 0 deletions tools/perf/util/dwarf-aux.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ extern int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr,
extern int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr,
int (*callback)(Dwarf_Die *, void *), void *data);

/* Ensure that this DIE is a subprogram and definition (not declaration) */
extern bool die_is_func_def(Dwarf_Die *dw_die);

/* Compare diename and tname */
extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname);

Expand Down
41 changes: 28 additions & 13 deletions tools/perf/util/header.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,11 @@ static int write_buildid(char *name, size_t name_len, u8 *build_id,
return write_padded(fd, name, name_len + 1, len);
}

static int __dsos__write_buildid_table(struct list_head *head, pid_t pid,
u16 misc, int fd)
static int __dsos__write_buildid_table(struct list_head *head,
struct machine *machine,
pid_t pid, u16 misc, int fd)
{
char nm[PATH_MAX];
struct dso *pos;

dsos__for_each_with_build_id(pos, head) {
Expand All @@ -215,6 +217,10 @@ static int __dsos__write_buildid_table(struct list_head *head, pid_t pid,
if (is_vdso_map(pos->short_name)) {
name = (char *) VDSO__MAP_NAME;
name_len = sizeof(VDSO__MAP_NAME) + 1;
} else if (dso__is_kcore(pos)) {
machine__mmap_name(machine, nm, sizeof(nm));
name = nm;
name_len = strlen(nm) + 1;
} else {
name = pos->long_name;
name_len = pos->long_name_len + 1;
Expand All @@ -240,10 +246,10 @@ static int machine__write_buildid_table(struct machine *machine, int fd)
umisc = PERF_RECORD_MISC_GUEST_USER;
}

err = __dsos__write_buildid_table(&machine->kernel_dsos, machine->pid,
kmisc, fd);
err = __dsos__write_buildid_table(&machine->kernel_dsos, machine,
machine->pid, kmisc, fd);
if (err == 0)
err = __dsos__write_buildid_table(&machine->user_dsos,
err = __dsos__write_buildid_table(&machine->user_dsos, machine,
machine->pid, umisc, fd);
return err;
}
Expand Down Expand Up @@ -375,32 +381,41 @@ int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir)
return err;
}

static int dso__cache_build_id(struct dso *dso, const char *debugdir)
static int dso__cache_build_id(struct dso *dso, struct machine *machine,
const char *debugdir)
{
bool is_kallsyms = dso->kernel && dso->long_name[0] != '/';
bool is_vdso = is_vdso_map(dso->short_name);
char *name = dso->long_name;
char nm[PATH_MAX];

return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id),
dso->long_name, debugdir,
is_kallsyms, is_vdso);
if (dso__is_kcore(dso)) {
is_kallsyms = true;
machine__mmap_name(machine, nm, sizeof(nm));
name = nm;
}
return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id), name,
debugdir, is_kallsyms, is_vdso);
}

static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir)
static int __dsos__cache_build_ids(struct list_head *head,
struct machine *machine, const char *debugdir)
{
struct dso *pos;
int err = 0;

dsos__for_each_with_build_id(pos, head)
if (dso__cache_build_id(pos, debugdir))
if (dso__cache_build_id(pos, machine, debugdir))
err = -1;

return err;
}

static int machine__cache_build_ids(struct machine *machine, const char *debugdir)
{
int ret = __dsos__cache_build_ids(&machine->kernel_dsos, debugdir);
ret |= __dsos__cache_build_ids(&machine->user_dsos, debugdir);
int ret = __dsos__cache_build_ids(&machine->kernel_dsos, machine,
debugdir);
ret |= __dsos__cache_build_ids(&machine->user_dsos, machine, debugdir);
return ret;
}

Expand Down
2 changes: 2 additions & 0 deletions tools/perf/util/hist.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,8 @@ void hists__collapse_resort(struct hists *hists)
next = rb_first(root);

while (next) {
if (session_done())
break;
n = rb_entry(next, struct hist_entry, rb_node_in);
next = rb_next(&n->rb_node_in);

Expand Down
12 changes: 5 additions & 7 deletions tools/perf/util/probe-finder.c
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf)
}

/* If not a real subprogram, find a real one */
if (dwarf_tag(sc_die) != DW_TAG_subprogram) {
if (!die_is_func_def(sc_die)) {
if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) {
pr_warning("Failed to find probe point in any "
"functions.\n");
Expand Down Expand Up @@ -980,12 +980,10 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
struct dwarf_callback_param *param = data;
struct probe_finder *pf = param->data;
struct perf_probe_point *pp = &pf->pev->point;
Dwarf_Attribute attr;

/* Check tag and diename */
if (dwarf_tag(sp_die) != DW_TAG_subprogram ||
!die_compare_name(sp_die, pp->function) ||
dwarf_attr(sp_die, DW_AT_declaration, &attr))
if (!die_is_func_def(sp_die) ||
!die_compare_name(sp_die, pp->function))
return DWARF_CB_OK;

/* Check declared file */
Expand Down Expand Up @@ -1474,7 +1472,7 @@ static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
return 0;
}

/* Search function from function name */
/* Search function definition from function name */
static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
{
struct dwarf_callback_param *param = data;
Expand All @@ -1485,7 +1483,7 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die)))
return DWARF_CB_OK;

if (dwarf_tag(sp_die) == DW_TAG_subprogram &&
if (die_is_func_def(sp_die) &&
die_compare_name(sp_die, lr->function)) {
lf->fname = dwarf_decl_file(sp_die);
dwarf_decl_line(sp_die, &lr->offset);
Expand Down
9 changes: 7 additions & 2 deletions tools/perf/util/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,9 @@ static int flush_sample_queue(struct perf_session *s,
return 0;

list_for_each_entry_safe(iter, tmp, head, list) {
if (session_done())
return 0;

if (iter->timestamp > limit)
break;

Expand Down Expand Up @@ -1160,7 +1163,6 @@ static void perf_session__warn_about_errors(const struct perf_session *session,
}
}

#define session_done() (*(volatile int *)(&session_done))
volatile int session_done;

static int __perf_session__process_pipe_events(struct perf_session *self,
Expand Down Expand Up @@ -1372,10 +1374,13 @@ int __perf_session__process_events(struct perf_session *session,
"Processing events...");
}

err = 0;
if (session_done())
goto out_err;

if (file_pos < file_size)
goto more;

err = 0;
/* do the final flush for ordered samples */
session->ordered_samples.next_flush = ULLONG_MAX;
err = flush_sample_queue(session, tool);
Expand Down
4 changes: 4 additions & 0 deletions tools/perf/util/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,8 @@ int __perf_session__set_tracepoints_handlers(struct perf_session *session,

#define perf_session__set_tracepoints_handlers(session, array) \
__perf_session__set_tracepoints_handlers(session, array, ARRAY_SIZE(array))

extern volatile int session_done;

#define session_done() (*(volatile int *)(&session_done))
#endif /* __PERF_SESSION_H */
16 changes: 16 additions & 0 deletions tools/perf/util/symbol-elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,22 @@
#include "symbol.h"
#include "debug.h"

#ifndef HAVE_ELF_GETPHDRNUM
static int elf_getphdrnum(Elf *elf, size_t *dst)
{
GElf_Ehdr gehdr;
GElf_Ehdr *ehdr;

ehdr = gelf_getehdr(elf, &gehdr);
if (!ehdr)
return -1;

*dst = ehdr->e_phnum;

return 0;
}
#endif

#ifndef NT_GNU_BUILD_ID
#define NT_GNU_BUILD_ID 3
#endif
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/util/trace-event-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ void parse_proc_kallsyms(struct pevent *pevent,
char *next = NULL;
char *addr_str;
char *mod;
char *fmt;
char *fmt = NULL;

line = strtok_r(file, "\n", &next);
while (line) {
Expand Down

0 comments on commit 24e31f0

Please sign in to comment.