Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Ingo Molnar:
 "Assorted standalone fixes"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  perf/x86/intel: Add model number for Avoton Silvermont
  perf: Fix capabilities bitfield compatibility in 'struct perf_event_mmap_page'
  perf/x86/intel/uncore: Don't use smp_processor_id() in validate_group()
  perf: Update ABI comment
  tools lib lk: Uninclude linux/magic.h in debugfs.c
  perf tools: Fix old GCC build error in trace-event-parse.c:parse_proc_kallsyms()
  perf probe: Fix finder to find lines of given function
  perf session: Check for SIGINT in more loops
  perf tools: Fix compile with libelf without get_phdrnum
  perf tools: Fix buildid cache handling of kallsyms with kcore
  perf annotate: Fix objdump line parsing offset validation
  perf tools: Fill in new definitions for madvise()/mmap() flags
  perf tools: Sharpen the libaudit dependencies test
This commit is contained in:
Linus Torvalds 2013-09-25 13:28:08 -07:00
commit bdc5663fa1
23 changed files with 164 additions and 49 deletions

View file

@ -1883,9 +1883,9 @@ static struct pmu pmu = {
void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now) void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now)
{ {
userpg->cap_usr_time = 0; userpg->cap_user_time = 0;
userpg->cap_usr_time_zero = 0; userpg->cap_user_time_zero = 0;
userpg->cap_usr_rdpmc = x86_pmu.attr_rdpmc; userpg->cap_user_rdpmc = x86_pmu.attr_rdpmc;
userpg->pmc_width = x86_pmu.cntval_bits; userpg->pmc_width = x86_pmu.cntval_bits;
if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
@ -1894,13 +1894,13 @@ void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now)
if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
return; return;
userpg->cap_usr_time = 1; userpg->cap_user_time = 1;
userpg->time_mult = this_cpu_read(cyc2ns); userpg->time_mult = this_cpu_read(cyc2ns);
userpg->time_shift = CYC2NS_SCALE_FACTOR; userpg->time_shift = CYC2NS_SCALE_FACTOR;
userpg->time_offset = this_cpu_read(cyc2ns_offset) - now; userpg->time_offset = this_cpu_read(cyc2ns_offset) - now;
if (sched_clock_stable && !check_tsc_disabled()) { if (sched_clock_stable && !check_tsc_disabled()) {
userpg->cap_usr_time_zero = 1; userpg->cap_user_time_zero = 1;
userpg->time_zero = this_cpu_read(cyc2ns_offset); userpg->time_zero = this_cpu_read(cyc2ns_offset);
} }
} }

View file

@ -2325,6 +2325,7 @@ __init int intel_pmu_init(void)
break; break;
case 55: /* Atom 22nm "Silvermont" */ case 55: /* Atom 22nm "Silvermont" */
case 77: /* Avoton "Silvermont" */
memcpy(hw_cache_event_ids, slm_hw_cache_event_ids, memcpy(hw_cache_event_ids, slm_hw_cache_event_ids,
sizeof(hw_cache_event_ids)); sizeof(hw_cache_event_ids));
memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs, memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,

View file

@ -2706,14 +2706,14 @@ static void uncore_pmu_init_hrtimer(struct intel_uncore_box *box)
box->hrtimer.function = uncore_pmu_hrtimer; box->hrtimer.function = uncore_pmu_hrtimer;
} }
struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, int cpu) static struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, int node)
{ {
struct intel_uncore_box *box; struct intel_uncore_box *box;
int i, size; int i, size;
size = sizeof(*box) + type->num_shared_regs * sizeof(struct intel_uncore_extra_reg); size = sizeof(*box) + type->num_shared_regs * sizeof(struct intel_uncore_extra_reg);
box = kzalloc_node(size, GFP_KERNEL, cpu_to_node(cpu)); box = kzalloc_node(size, GFP_KERNEL, node);
if (!box) if (!box)
return NULL; return NULL;
@ -3031,7 +3031,7 @@ static int uncore_validate_group(struct intel_uncore_pmu *pmu,
struct intel_uncore_box *fake_box; struct intel_uncore_box *fake_box;
int ret = -EINVAL, n; int ret = -EINVAL, n;
fake_box = uncore_alloc_box(pmu->type, smp_processor_id()); fake_box = uncore_alloc_box(pmu->type, NUMA_NO_NODE);
if (!fake_box) if (!fake_box)
return -ENOMEM; return -ENOMEM;
@ -3294,7 +3294,7 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
} }
type = pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)]; type = pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)];
box = uncore_alloc_box(type, 0); box = uncore_alloc_box(type, NUMA_NO_NODE);
if (!box) if (!box)
return -ENOMEM; return -ENOMEM;
@ -3499,7 +3499,7 @@ static int uncore_cpu_prepare(int cpu, int phys_id)
if (pmu->func_id < 0) if (pmu->func_id < 0)
pmu->func_id = j; pmu->func_id = j;
box = uncore_alloc_box(type, cpu); box = uncore_alloc_box(type, cpu_to_node(cpu));
if (!box) if (!box)
return -ENOMEM; return -ENOMEM;

View file

@ -380,10 +380,13 @@ struct perf_event_mmap_page {
union { union {
__u64 capabilities; __u64 capabilities;
struct { struct {
__u64 cap_usr_time : 1, __u64 cap_bit0 : 1, /* Always 0, deprecated, see commit 860f085b74e9 */
cap_usr_rdpmc : 1, cap_bit0_is_deprecated : 1, /* Always 1, signals that bit 0 is zero */
cap_usr_time_zero : 1,
cap_____res : 61; cap_user_rdpmc : 1, /* The RDPMC instruction can be used to read counts */
cap_user_time : 1, /* The time_* fields are used */
cap_user_time_zero : 1, /* The time_zero field is used */
cap_____res : 59;
}; };
}; };
@ -442,12 +445,13 @@ struct perf_event_mmap_page {
* ((rem * time_mult) >> time_shift); * ((rem * time_mult) >> time_shift);
*/ */
__u64 time_zero; __u64 time_zero;
__u32 size; /* Header size up to __reserved[] fields. */
/* /*
* Hole for extension of the self monitor capabilities * Hole for extension of the self monitor capabilities
*/ */
__u64 __reserved[119]; /* align to 1k */ __u8 __reserved[118*8+4]; /* align to 1k. */
/* /*
* Control data for the mmap() data buffer. * Control data for the mmap() data buffer.
@ -528,6 +532,7 @@ enum perf_event_type {
* u64 len; * u64 len;
* u64 pgoff; * u64 pgoff;
* char filename[]; * char filename[];
* struct sample_id sample_id;
* }; * };
*/ */
PERF_RECORD_MMAP = 1, PERF_RECORD_MMAP = 1,

View file

@ -3660,6 +3660,26 @@ static void calc_timer_values(struct perf_event *event,
*running = ctx_time - event->tstamp_running; *running = ctx_time - event->tstamp_running;
} }
static void perf_event_init_userpage(struct perf_event *event)
{
struct perf_event_mmap_page *userpg;
struct ring_buffer *rb;
rcu_read_lock();
rb = rcu_dereference(event->rb);
if (!rb)
goto unlock;
userpg = rb->user_page;
/* Allow new userspace to detect that bit 0 is deprecated */
userpg->cap_bit0_is_deprecated = 1;
userpg->size = offsetof(struct perf_event_mmap_page, __reserved);
unlock:
rcu_read_unlock();
}
void __weak arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now) void __weak arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now)
{ {
} }
@ -4044,6 +4064,7 @@ again:
ring_buffer_attach(event, rb); ring_buffer_attach(event, rb);
rcu_assign_pointer(event->rb, rb); rcu_assign_pointer(event->rb, rb);
perf_event_init_userpage(event);
perf_event_update_userpage(event); perf_event_update_userpage(event);
unlock: unlock:

View file

@ -5,7 +5,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <sys/vfs.h> #include <sys/vfs.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <linux/magic.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include "debugfs.h" #include "debugfs.h"

View file

@ -32,7 +32,7 @@ u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc)
int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc, int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
struct perf_tsc_conversion *tc) struct perf_tsc_conversion *tc)
{ {
bool cap_usr_time_zero; bool cap_user_time_zero;
u32 seq; u32 seq;
int i = 0; int i = 0;
@ -42,7 +42,7 @@ int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
tc->time_mult = pc->time_mult; tc->time_mult = pc->time_mult;
tc->time_shift = pc->time_shift; tc->time_shift = pc->time_shift;
tc->time_zero = pc->time_zero; tc->time_zero = pc->time_zero;
cap_usr_time_zero = pc->cap_usr_time_zero; cap_user_time_zero = pc->cap_user_time_zero;
rmb(); rmb();
if (pc->lock == seq && !(seq & 1)) if (pc->lock == seq && !(seq & 1))
break; break;
@ -52,7 +52,7 @@ int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
} }
} }
if (!cap_usr_time_zero) if (!cap_user_time_zero)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return 0; return 0;

View file

@ -321,8 +321,6 @@ found:
return perf_event__repipe(tool, event_sw, &sample_sw, machine); return perf_event__repipe(tool, event_sw, &sample_sw, machine);
} }
extern volatile int session_done;
static void sig_handler(int sig __maybe_unused) static void sig_handler(int sig __maybe_unused)
{ {
session_done = 1; session_done = 1;

View file

@ -401,8 +401,6 @@ static int perf_report__setup_sample_type(struct perf_report *rep)
return 0; return 0;
} }
extern volatile int session_done;
static void sig_handler(int sig __maybe_unused) static void sig_handler(int sig __maybe_unused)
{ {
session_done = 1; session_done = 1;
@ -568,6 +566,9 @@ static int __cmd_report(struct perf_report *rep)
} }
} }
if (session_done())
return 0;
if (nr_samples == 0) { if (nr_samples == 0) {
ui__error("The %s file has no samples!\n", session->filename); ui__error("The %s file has no samples!\n", session->filename);
return 0; return 0;

View file

@ -553,8 +553,6 @@ static struct perf_tool perf_script = {
.ordering_requires_timestamps = true, .ordering_requires_timestamps = true,
}; };
extern volatile int session_done;
static void sig_handler(int sig __maybe_unused) static void sig_handler(int sig __maybe_unused)
{ {
session_done = 1; session_done = 1;

View file

@ -16,6 +16,23 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <linux/futex.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, static size_t syscall_arg__scnprintf_hex(char *bf, size_t size,
unsigned long arg, unsigned long arg,
u8 arg_idx __maybe_unused, u8 arg_idx __maybe_unused,

View file

@ -180,6 +180,9 @@ FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y) ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
CFLAGS += -DLIBELF_MMAP CFLAGS += -DLIBELF_MMAP
endif endif
ifeq ($(call try-cc,$(SOURCE_ELF_GETPHDRNUM),$(FLAGS_LIBELF),-DHAVE_ELF_GETPHDRNUM),y)
CFLAGS += -DHAVE_ELF_GETPHDRNUM
endif
# include ARCH specific config # include ARCH specific config
-include $(src-perf)/arch/$(ARCH)/Makefile -include $(src-perf)/arch/$(ARCH)/Makefile

View file

@ -61,6 +61,15 @@ int main(void)
} }
endef endef
define SOURCE_ELF_GETPHDRNUM
#include <libelf.h>
int main(void)
{
size_t dst;
return elf_getphdrnum(0, &dst);
}
endef
ifndef NO_SLANG ifndef NO_SLANG
define SOURCE_SLANG define SOURCE_SLANG
#include <slang.h> #include <slang.h>
@ -210,6 +219,7 @@ define SOURCE_LIBAUDIT
int main(void) int main(void)
{ {
printf(\"error message: %s\n\", audit_errno_to_name(0));
return audit_open(); return audit_open();
} }
endef endef

View file

@ -809,7 +809,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
end = map__rip_2objdump(map, sym->end); end = map__rip_2objdump(map, sym->end);
offset = line_ip - start; offset = line_ip - start;
if (offset < 0 || (u64)line_ip > end) if ((u64)line_ip < start || (u64)line_ip > end)
offset = -1; offset = -1;
else else
parsed_line = tmp2 + 1; parsed_line = tmp2 + 1;

View file

@ -262,6 +262,21 @@ bool die_is_signed_type(Dwarf_Die *tp_die)
ret == DW_ATE_signed_fixed); 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 * die_get_data_member_location - Get the data-member offset
* @mb_die: a DIE of a member of a data structure * @mb_die: a DIE of a member of a data structure
@ -392,6 +407,10 @@ static int __die_search_func_cb(Dwarf_Die *fn_die, void *data)
{ {
struct __addr_die_search_param *ad = 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 && if (dwarf_tag(fn_die) == DW_TAG_subprogram &&
dwarf_haspc(fn_die, ad->addr)) { dwarf_haspc(fn_die, ad->addr)) {
memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die)); memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die));

View file

@ -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, extern int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr,
int (*callback)(Dwarf_Die *, void *), void *data); 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 */ /* Compare diename and tname */
extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname); extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname);

View file

@ -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); return write_padded(fd, name, name_len + 1, len);
} }
static int __dsos__write_buildid_table(struct list_head *head, pid_t pid, static int __dsos__write_buildid_table(struct list_head *head,
u16 misc, int fd) struct machine *machine,
pid_t pid, u16 misc, int fd)
{ {
char nm[PATH_MAX];
struct dso *pos; struct dso *pos;
dsos__for_each_with_build_id(pos, head) { dsos__for_each_with_build_id(pos, head) {
@ -215,6 +217,10 @@ static int __dsos__write_buildid_table(struct list_head *head, pid_t pid,
if (is_vdso_map(pos->short_name)) { if (is_vdso_map(pos->short_name)) {
name = (char *) VDSO__MAP_NAME; name = (char *) VDSO__MAP_NAME;
name_len = sizeof(VDSO__MAP_NAME) + 1; 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 { } else {
name = pos->long_name; name = pos->long_name;
name_len = pos->long_name_len + 1; name_len = pos->long_name_len + 1;
@ -240,10 +246,10 @@ static int machine__write_buildid_table(struct machine *machine, int fd)
umisc = PERF_RECORD_MISC_GUEST_USER; umisc = PERF_RECORD_MISC_GUEST_USER;
} }
err = __dsos__write_buildid_table(&machine->kernel_dsos, machine->pid, err = __dsos__write_buildid_table(&machine->kernel_dsos, machine,
kmisc, fd); machine->pid, kmisc, fd);
if (err == 0) if (err == 0)
err = __dsos__write_buildid_table(&machine->user_dsos, err = __dsos__write_buildid_table(&machine->user_dsos, machine,
machine->pid, umisc, fd); machine->pid, umisc, fd);
return err; return err;
} }
@ -375,23 +381,31 @@ out_free:
return err; 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_kallsyms = dso->kernel && dso->long_name[0] != '/';
bool is_vdso = is_vdso_map(dso->short_name); 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), if (dso__is_kcore(dso)) {
dso->long_name, debugdir, is_kallsyms = true;
is_kallsyms, is_vdso); 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; struct dso *pos;
int err = 0; int err = 0;
dsos__for_each_with_build_id(pos, head) 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; err = -1;
return err; return err;
@ -399,8 +413,9 @@ static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir)
static int machine__cache_build_ids(struct machine *machine, const char *debugdir) static int machine__cache_build_ids(struct machine *machine, const char *debugdir)
{ {
int ret = __dsos__cache_build_ids(&machine->kernel_dsos, debugdir); int ret = __dsos__cache_build_ids(&machine->kernel_dsos, machine,
ret |= __dsos__cache_build_ids(&machine->user_dsos, debugdir); debugdir);
ret |= __dsos__cache_build_ids(&machine->user_dsos, machine, debugdir);
return ret; return ret;
} }

View file

@ -611,6 +611,8 @@ void hists__collapse_resort(struct hists *hists)
next = rb_first(root); next = rb_first(root);
while (next) { while (next) {
if (session_done())
break;
n = rb_entry(next, struct hist_entry, rb_node_in); n = rb_entry(next, struct hist_entry, rb_node_in);
next = rb_next(&n->rb_node_in); next = rb_next(&n->rb_node_in);

View file

@ -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 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)) { if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) {
pr_warning("Failed to find probe point in any " pr_warning("Failed to find probe point in any "
"functions.\n"); "functions.\n");
@ -980,12 +980,10 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
struct dwarf_callback_param *param = data; struct dwarf_callback_param *param = data;
struct probe_finder *pf = param->data; struct probe_finder *pf = param->data;
struct perf_probe_point *pp = &pf->pev->point; struct perf_probe_point *pp = &pf->pev->point;
Dwarf_Attribute attr;
/* Check tag and diename */ /* Check tag and diename */
if (dwarf_tag(sp_die) != DW_TAG_subprogram || if (!die_is_func_def(sp_die) ||
!die_compare_name(sp_die, pp->function) || !die_compare_name(sp_die, pp->function))
dwarf_attr(sp_die, DW_AT_declaration, &attr))
return DWARF_CB_OK; return DWARF_CB_OK;
/* Check declared file */ /* Check declared file */
@ -1474,7 +1472,7 @@ static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
return 0; 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) static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
{ {
struct dwarf_callback_param *param = data; struct dwarf_callback_param *param = data;
@ -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))) if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die)))
return DWARF_CB_OK; 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)) { die_compare_name(sp_die, lr->function)) {
lf->fname = dwarf_decl_file(sp_die); lf->fname = dwarf_decl_file(sp_die);
dwarf_decl_line(sp_die, &lr->offset); dwarf_decl_line(sp_die, &lr->offset);

View file

@ -531,6 +531,9 @@ static int flush_sample_queue(struct perf_session *s,
return 0; return 0;
list_for_each_entry_safe(iter, tmp, head, list) { list_for_each_entry_safe(iter, tmp, head, list) {
if (session_done())
return 0;
if (iter->timestamp > limit) if (iter->timestamp > limit)
break; break;
@ -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; volatile int session_done;
static int __perf_session__process_pipe_events(struct perf_session *self, static int __perf_session__process_pipe_events(struct perf_session *self,
@ -1372,10 +1374,13 @@ more:
"Processing events..."); "Processing events...");
} }
err = 0;
if (session_done())
goto out_err;
if (file_pos < file_size) if (file_pos < file_size)
goto more; goto more;
err = 0;
/* do the final flush for ordered samples */ /* do the final flush for ordered samples */
session->ordered_samples.next_flush = ULLONG_MAX; session->ordered_samples.next_flush = ULLONG_MAX;
err = flush_sample_queue(session, tool); err = flush_sample_queue(session, tool);

View file

@ -124,4 +124,8 @@ int __perf_session__set_tracepoints_handlers(struct perf_session *session,
#define perf_session__set_tracepoints_handlers(session, array) \ #define perf_session__set_tracepoints_handlers(session, array) \
__perf_session__set_tracepoints_handlers(session, array, ARRAY_SIZE(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 */ #endif /* __PERF_SESSION_H */

View file

@ -8,6 +8,22 @@
#include "symbol.h" #include "symbol.h"
#include "debug.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 #ifndef NT_GNU_BUILD_ID
#define NT_GNU_BUILD_ID 3 #define NT_GNU_BUILD_ID 3
#endif #endif

View file

@ -186,7 +186,7 @@ void parse_proc_kallsyms(struct pevent *pevent,
char *next = NULL; char *next = NULL;
char *addr_str; char *addr_str;
char *mod; char *mod;
char *fmt; char *fmt = NULL;
line = strtok_r(file, "\n", &next); line = strtok_r(file, "\n", &next);
while (line) { while (line) {