Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f696eb1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'perf-fixes-for-linus' of...

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

* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (57 commits)
  x86, perf events: Check if we have APIC enabled
  perf_event: Fix variable initialization in other codepaths
  perf kmem: Fix unused argument build warning
  perf symbols: perf_header__read_build_ids() offset'n'size should be u64
  perf symbols: dsos__read_build_ids() should read both user and kernel buildids
  perf tools: Align long options which have no short forms
  perf kmem: Show usage if no option is specified
  sched: Mark sched_clock() as notrace
  perf sched: Add max delay time snapshot
  perf tools: Correct size given to memset
  perf_event: Fix perf_swevent_hrtimer() variable initialization
  perf sched: Fix for getting task's execution time
  tracing/kprobes: Fix field creation's bad error handling
  perf_event: Cleanup for cpu_clock_perf_event_update()
  perf_event: Allocate children's perf_event_ctxp at the right time
  perf_event: Clean up __perf_event_init_context()
  hw-breakpoints: Modify breakpoints without unregistering them
  perf probe: Update perf-probe document
  perf probe: Support --del option
  trace-kprobe: Support delete probe syntax
  ...
parents c4e194e3 12558038
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -188,7 +188,7 @@ config HAVE_MMIOTRACE_SUPPORT

config X86_DECODER_SELFTEST
	bool "x86 instruction decoder selftest"
     depends on DEBUG_KERNEL
	depends on DEBUG_KERNEL && KPROBES
	---help---
	 Perform x86 instruction decoder selftests at build time.
	 This option is useful for checking the sanity of x86 instruction
+21 −10
Original line number Diff line number Diff line
@@ -1632,6 +1632,7 @@ static void intel_pmu_drain_bts_buffer(struct cpu_hw_events *cpuc)

	data.period	= event->hw.last_period;
	data.addr	= 0;
	data.raw	= NULL;
	regs.ip		= 0;

	/*
@@ -1749,6 +1750,7 @@ static int p6_pmu_handle_irq(struct pt_regs *regs)
	u64 val;

	data.addr = 0;
	data.raw = NULL;

	cpuc = &__get_cpu_var(cpu_hw_events);

@@ -1794,6 +1796,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
	u64 ack, status;

	data.addr = 0;
	data.raw = NULL;

	cpuc = &__get_cpu_var(cpu_hw_events);

@@ -1857,6 +1860,7 @@ static int amd_pmu_handle_irq(struct pt_regs *regs)
	u64 val;

	data.addr = 0;
	data.raw = NULL;

	cpuc = &__get_cpu_var(cpu_hw_events);

@@ -2062,12 +2066,6 @@ static __init int p6_pmu_init(void)

	x86_pmu = p6_pmu;

	if (!cpu_has_apic) {
		pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n");
		pr_info("no hardware sampling interrupt available.\n");
		x86_pmu.apic = 0;
	}

	return 0;
}

@@ -2159,6 +2157,16 @@ static __init int amd_pmu_init(void)
	return 0;
}

static void __init pmu_check_apic(void)
{
	if (cpu_has_apic)
		return;

	x86_pmu.apic = 0;
	pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n");
	pr_info("no hardware sampling interrupt available.\n");
}

void __init init_hw_perf_events(void)
{
	int err;
@@ -2180,6 +2188,8 @@ void __init init_hw_perf_events(void)
		return;
	}

	pmu_check_apic();

	pr_cont("%s PMU driver.\n", x86_pmu.name);

	if (x86_pmu.num_events > X86_PMC_MAX_GENERIC) {
@@ -2287,7 +2297,7 @@ void callchain_store(struct perf_callchain_entry *entry, u64 ip)

static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry);
static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_nmi_entry);
static DEFINE_PER_CPU(int, in_nmi_frame);
static DEFINE_PER_CPU(int, in_ignored_frame);


static void
@@ -2303,8 +2313,9 @@ static void backtrace_warning(void *data, char *msg)

static int backtrace_stack(void *data, char *name)
{
	per_cpu(in_nmi_frame, smp_processor_id()) =
			x86_is_stack_id(NMI_STACK, name);
	per_cpu(in_ignored_frame, smp_processor_id()) =
			x86_is_stack_id(NMI_STACK, name) ||
			x86_is_stack_id(DEBUG_STACK, name);

	return 0;
}
@@ -2313,7 +2324,7 @@ static void backtrace_address(void *data, unsigned long addr, int reliable)
{
	struct perf_callchain_entry *entry = data;

	if (per_cpu(in_nmi_frame, smp_processor_id()))
	if (per_cpu(in_ignored_frame, smp_processor_id()))
		return;

	if (reliable)
+32 −1
Original line number Diff line number Diff line
@@ -103,6 +103,35 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
	return NULL;
}

static inline int
in_irq_stack(unsigned long *stack, unsigned long *irq_stack,
	     unsigned long *irq_stack_end)
{
	return (stack >= irq_stack && stack < irq_stack_end);
}

/*
 * We are returning from the irq stack and go to the previous one.
 * If the previous stack is also in the irq stack, then bp in the first
 * frame of the irq stack points to the previous, interrupted one.
 * Otherwise we have another level of indirection: We first save
 * the bp of the previous stack, then we switch the stack to the irq one
 * and save a new bp that links to the previous one.
 * (See save_args())
 */
static inline unsigned long
fixup_bp_irq_link(unsigned long bp, unsigned long *stack,
		  unsigned long *irq_stack, unsigned long *irq_stack_end)
{
#ifdef CONFIG_FRAME_POINTER
	struct stack_frame *frame = (struct stack_frame *)bp;

	if (!in_irq_stack(stack, irq_stack, irq_stack_end))
		return (unsigned long)frame->next_frame;
#endif
	return bp;
}

/*
 * x86-64 can have up to three kernel stacks:
 * process stack
@@ -175,7 +204,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
			irq_stack = irq_stack_end -
				(IRQ_STACK_SIZE - 64) / sizeof(*irq_stack);

			if (stack >= irq_stack && stack < irq_stack_end) {
			if (in_irq_stack(stack, irq_stack, irq_stack_end)) {
				if (ops->stack(data, "IRQ") < 0)
					break;
				bp = print_context_stack(tinfo, stack, bp,
@@ -186,6 +215,8 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
				 * pointer (index -1 to end) in the IRQ stack:
				 */
				stack = (unsigned long *) (irq_stack_end[-1]);
				bp = fixup_bp_irq_link(bp, stack, irq_stack,
						       irq_stack_end);
				irq_stack_end = NULL;
				ops->stack(data, "EOI");
				continue;
+3 −3
Original line number Diff line number Diff line
@@ -1076,10 +1076,10 @@ ENTRY(\sym)
	TRACE_IRQS_OFF
	movq %rsp,%rdi		/* pt_regs pointer */
	xorl %esi,%esi		/* no error code */
	PER_CPU(init_tss, %rbp)
	subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
	PER_CPU(init_tss, %r12)
	subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%r12)
	call \do_sym
	addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
	addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%r12)
	jmp paranoid_exit	/* %ebx: no swapgs flag */
	CFI_ENDPROC
END(\sym)
+2 −3
Original line number Diff line number Diff line
@@ -362,7 +362,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp,
		return ret;
	}

	if (bp->callback)
	ret = arch_store_info(bp);

	if (ret < 0)
@@ -519,7 +518,7 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args)
			break;
		}

		(bp->callback)(bp, args->regs);
		perf_bp_event(bp, args->regs);

		rcu_read_unlock();
	}
Loading