Skip to content

Commit

Permalink
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
torvalds committed Sep 25, 2013
2 parents 743a7ec + cf3b425 commit bdc5663
Show file tree
Hide file tree
Showing 23 changed files with 164 additions and 49 deletions.
10 changes: 5 additions & 5 deletions arch/x86/kernel/cpu/perf_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -1883,9 +1883,9 @@ static struct pmu pmu = {

void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now)
{
userpg->cap_usr_time = 0;
userpg->cap_usr_time_zero = 0;
userpg->cap_usr_rdpmc = x86_pmu.attr_rdpmc;
userpg->cap_user_time = 0;
userpg->cap_user_time_zero = 0;
userpg->cap_user_rdpmc = x86_pmu.attr_rdpmc;
userpg->pmc_width = x86_pmu.cntval_bits;

if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
Expand All @@ -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))
return;

userpg->cap_usr_time = 1;
userpg->cap_user_time = 1;
userpg->time_mult = this_cpu_read(cyc2ns);
userpg->time_shift = CYC2NS_SCALE_FACTOR;
userpg->time_offset = this_cpu_read(cyc2ns_offset) - now;

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);
}
}
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/cpu/perf_event_intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -2325,6 +2325,7 @@ __init int intel_pmu_init(void)
break;

case 55: /* Atom 22nm "Silvermont" */
case 77: /* Avoton "Silvermont" */
memcpy(hw_cache_event_ids, slm_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
Expand Down
10 changes: 5 additions & 5 deletions arch/x86/kernel/cpu/perf_event_intel_uncore.c
Original file line number Diff line number Diff line change
Expand Up @@ -2706,14 +2706,14 @@ static void uncore_pmu_init_hrtimer(struct intel_uncore_box *box)
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;
int i, size;

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)
return NULL;

Expand Down Expand Up @@ -3031,7 +3031,7 @@ static int uncore_validate_group(struct intel_uncore_pmu *pmu,
struct intel_uncore_box *fake_box;
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)
return -ENOMEM;

Expand Down Expand Up @@ -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)];
box = uncore_alloc_box(type, 0);
box = uncore_alloc_box(type, NUMA_NO_NODE);
if (!box)
return -ENOMEM;

Expand Down Expand Up @@ -3499,7 +3499,7 @@ static int uncore_cpu_prepare(int cpu, int phys_id)
if (pmu->func_id < 0)
pmu->func_id = j;

box = uncore_alloc_box(type, cpu);
box = uncore_alloc_box(type, cpu_to_node(cpu));
if (!box)
return -ENOMEM;

Expand Down
15 changes: 10 additions & 5 deletions include/uapi/linux/perf_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -380,10 +380,13 @@ struct perf_event_mmap_page {
union {
__u64 capabilities;
struct {
__u64 cap_usr_time : 1,
cap_usr_rdpmc : 1,
cap_usr_time_zero : 1,
cap_____res : 61;
__u64 cap_bit0 : 1, /* Always 0, deprecated, see commit 860f085b74e9 */
cap_bit0_is_deprecated : 1, /* Always 1, signals that bit 0 is zero */

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;
};
};

Expand Down Expand Up @@ -442,12 +445,13 @@ struct perf_event_mmap_page {
* ((rem * time_mult) >> time_shift);
*/
__u64 time_zero;
__u32 size; /* Header size up to __reserved[] fields. */

/*
* 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.
Expand Down Expand Up @@ -528,6 +532,7 @@ enum perf_event_type {
* u64 len;
* u64 pgoff;
* char filename[];
* struct sample_id sample_id;
* };
*/
PERF_RECORD_MMAP = 1,
Expand Down
21 changes: 21 additions & 0 deletions kernel/events/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3660,6 +3660,26 @@ static void calc_timer_values(struct perf_event *event,
*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)
{
}
Expand Down Expand Up @@ -4044,6 +4064,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
ring_buffer_attach(event, rb);
rcu_assign_pointer(event->rb, rb);

perf_event_init_userpage(event);
perf_event_update_userpage(event);

unlock:
Expand Down
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
6 changes: 3 additions & 3 deletions tools/perf/arch/x86/util/tsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
struct perf_tsc_conversion *tc)
{
bool cap_usr_time_zero;
bool cap_user_time_zero;
u32 seq;
int i = 0;

Expand All @@ -42,7 +42,7 @@ int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
tc->time_mult = pc->time_mult;
tc->time_shift = pc->time_shift;
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();
if (pc->lock == seq && !(seq & 1))
break;
Expand All @@ -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 0;
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
Loading

0 comments on commit bdc5663

Please sign in to comment.