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

Commit 4d7b4ac2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

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

* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (311 commits)
  perf tools: Add mode to build without newt support
  perf symbols: symbol inconsistency message should be done only at verbose=1
  perf tui: Add explicit -lslang option
  perf options: Type check all the remaining OPT_ variants
  perf options: Type check OPT_BOOLEAN and fix the offenders
  perf options: Check v type in OPT_U?INTEGER
  perf options: Introduce OPT_UINTEGER
  perf tui: Add workaround for slang < 2.1.4
  perf record: Fix bug mismatch with -c option definition
  perf options: Introduce OPT_U64
  perf tui: Add help window to show key associations
  perf tui: Make <- exit menus too
  perf newt: Add single key shortcuts for zoom into DSO and threads
  perf newt: Exit browser unconditionally when CTRL+C, q or Q is pressed
  perf newt: Fix the 'A'/'a' shortcut for annotate
  perf newt: Make <- exit the ui_browser
  x86, perf: P4 PMU - fix counters management logic
  perf newt: Make <- zoom out filters
  perf report: Report number of events, not samples
  perf hist: Clarify events_stats fields usage
  ...

Fix up trivial conflicts in kernel/fork.c and tools/perf/builtin-record.c
parents 3aaf51ac 94f3ca95
Loading
Loading
Loading
Loading
+2 −8
Original line number Diff line number Diff line
@@ -165,8 +165,8 @@ the user entry_handler invocation is also skipped.

1.4 How Does Jump Optimization Work?

If you configured your kernel with CONFIG_OPTPROBES=y (currently
this option is supported on x86/x86-64, non-preemptive kernel) and
If your kernel is built with CONFIG_OPTPROBES=y (currently this flag
is automatically set 'y' on x86/x86-64, non-preemptive kernel) and
the "debug.kprobes_optimization" kernel parameter is set to 1 (see
sysctl(8)), Kprobes tries to reduce probe-hit overhead by using a jump
instruction instead of a breakpoint instruction at each probepoint.
@@ -271,8 +271,6 @@ tweak the kernel's execution path, you need to suppress optimization,
using one of the following techniques:
- Specify an empty function for the kprobe's post_handler or break_handler.
 or
- Config CONFIG_OPTPROBES=n.
 or
- Execute 'sysctl -w debug.kprobes_optimization=n'

2. Architectures Supported
@@ -307,10 +305,6 @@ it useful to "Compile the kernel with debug info" (CONFIG_DEBUG_INFO),
so you can use "objdump -d -l vmlinux" to see the source-to-object
code mapping.

If you want to reduce probing overhead, set "Kprobes jump optimization
support" (CONFIG_OPTPROBES) to "y". You can find this option under the
"Kprobes" line.

4. API Reference

The Kprobes API includes a "register" function and an "unregister"
+3 −1
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@ Synopsis of kprobe_events
  $retval	: Fetch return value.(*)
  +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**)
  NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
  FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
		  (u8/u16/u32/u64/s8/s16/s32/s64) are supported.

  (*) only for return probe.
  (**) this is useful for fetching a field of data structures.
+5 −5
Original line number Diff line number Diff line
@@ -4354,13 +4354,13 @@ M: Paul Mackerras <paulus@samba.org>
M:	Ingo Molnar <mingo@elte.hu>
M:	Arnaldo Carvalho de Melo <acme@redhat.com>
S:	Supported
F:	kernel/perf_event.c
F:	kernel/perf_event*.c
F:	include/linux/perf_event.h
F:	arch/*/kernel/perf_event.c
F:	arch/*/kernel/*/perf_event.c
F:	arch/*/kernel/*/*/perf_event.c
F:	arch/*/kernel/perf_event*.c
F:	arch/*/kernel/*/perf_event*.c
F:	arch/*/kernel/*/*/perf_event*.c
F:	arch/*/include/asm/perf_event.h
F:	arch/*/lib/perf_event.c
F:	arch/*/lib/perf_event*.c
F:	arch/*/kernel/perf_callchain.c
F:	tools/perf/

+13 −7
Original line number Diff line number Diff line
@@ -42,15 +42,10 @@ config KPROBES
	  If in doubt, say "N".

config OPTPROBES
	bool "Kprobes jump optimization support (EXPERIMENTAL)"
	default y
	depends on KPROBES
	def_bool y
	depends on KPROBES && HAVE_OPTPROBES
	depends on !PREEMPT
	depends on HAVE_OPTPROBES
	select KALLSYMS_ALL
	help
	  This option will allow kprobes to optimize breakpoint to
	  a jump for reducing its overhead.

config HAVE_EFFICIENT_UNALIGNED_ACCESS
	bool
@@ -142,6 +137,17 @@ config HAVE_HW_BREAKPOINT
	bool
	depends on PERF_EVENTS

config HAVE_MIXED_BREAKPOINTS_REGS
	bool
	depends on HAVE_HW_BREAKPOINT
	help
	  Depending on the arch implementation of hardware breakpoints,
	  some of them have separate registers for data and instruction
	  breakpoints addresses, others have mixed registers to store
	  them but define the access type in a control register.
	  Select this option if your arch implements breakpoints under the
	  latter fashion.

config HAVE_USER_RETURN_NOTIFIER
	bool

+68 −61
Original line number Diff line number Diff line
@@ -35,6 +35,9 @@ struct cpu_hw_events {
	u64 alternatives[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
	unsigned long amasks[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
	unsigned long avalues[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];

	unsigned int group_flag;
	int n_txn_start;
};
DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);

@@ -718,66 +721,6 @@ static int collect_events(struct perf_event *group, int max_count,
	return n;
}

static void event_sched_in(struct perf_event *event)
{
	event->state = PERF_EVENT_STATE_ACTIVE;
	event->oncpu = smp_processor_id();
	event->tstamp_running += event->ctx->time - event->tstamp_stopped;
	if (is_software_event(event))
		event->pmu->enable(event);
}

/*
 * Called to enable a whole group of events.
 * Returns 1 if the group was enabled, or -EAGAIN if it could not be.
 * Assumes the caller has disabled interrupts and has
 * frozen the PMU with hw_perf_save_disable.
 */
int hw_perf_group_sched_in(struct perf_event *group_leader,
	       struct perf_cpu_context *cpuctx,
	       struct perf_event_context *ctx)
{
	struct cpu_hw_events *cpuhw;
	long i, n, n0;
	struct perf_event *sub;

	if (!ppmu)
		return 0;
	cpuhw = &__get_cpu_var(cpu_hw_events);
	n0 = cpuhw->n_events;
	n = collect_events(group_leader, ppmu->n_counter - n0,
			   &cpuhw->event[n0], &cpuhw->events[n0],
			   &cpuhw->flags[n0]);
	if (n < 0)
		return -EAGAIN;
	if (check_excludes(cpuhw->event, cpuhw->flags, n0, n))
		return -EAGAIN;
	i = power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n + n0);
	if (i < 0)
		return -EAGAIN;
	cpuhw->n_events = n0 + n;
	cpuhw->n_added += n;

	/*
	 * OK, this group can go on; update event states etc.,
	 * and enable any software events
	 */
	for (i = n0; i < n0 + n; ++i)
		cpuhw->event[i]->hw.config = cpuhw->events[i];
	cpuctx->active_oncpu += n;
	n = 1;
	event_sched_in(group_leader);
	list_for_each_entry(sub, &group_leader->sibling_list, group_entry) {
		if (sub->state != PERF_EVENT_STATE_OFF) {
			event_sched_in(sub);
			++n;
		}
	}
	ctx->nr_active += n;

	return 1;
}

/*
 * Add a event to the PMU.
 * If all events are not already frozen, then we disable and
@@ -805,12 +748,22 @@ static int power_pmu_enable(struct perf_event *event)
	cpuhw->event[n0] = event;
	cpuhw->events[n0] = event->hw.config;
	cpuhw->flags[n0] = event->hw.event_base;

	/*
	 * If group events scheduling transaction was started,
	 * skip the schedulability test here, it will be peformed
	 * at commit time(->commit_txn) as a whole
	 */
	if (cpuhw->group_flag & PERF_EVENT_TXN_STARTED)
		goto nocheck;

	if (check_excludes(cpuhw->event, cpuhw->flags, n0, 1))
		goto out;
	if (power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n0 + 1))
		goto out;

	event->hw.config = cpuhw->events[n0];

nocheck:
	++cpuhw->n_events;
	++cpuhw->n_added;

@@ -896,11 +849,65 @@ static void power_pmu_unthrottle(struct perf_event *event)
	local_irq_restore(flags);
}

/*
 * Start group events scheduling transaction
 * Set the flag to make pmu::enable() not perform the
 * schedulability test, it will be performed at commit time
 */
void power_pmu_start_txn(const struct pmu *pmu)
{
	struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);

	cpuhw->group_flag |= PERF_EVENT_TXN_STARTED;
	cpuhw->n_txn_start = cpuhw->n_events;
}

/*
 * Stop group events scheduling transaction
 * Clear the flag and pmu::enable() will perform the
 * schedulability test.
 */
void power_pmu_cancel_txn(const struct pmu *pmu)
{
	struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);

	cpuhw->group_flag &= ~PERF_EVENT_TXN_STARTED;
}

/*
 * Commit group events scheduling transaction
 * Perform the group schedulability test as a whole
 * Return 0 if success
 */
int power_pmu_commit_txn(const struct pmu *pmu)
{
	struct cpu_hw_events *cpuhw;
	long i, n;

	if (!ppmu)
		return -EAGAIN;
	cpuhw = &__get_cpu_var(cpu_hw_events);
	n = cpuhw->n_events;
	if (check_excludes(cpuhw->event, cpuhw->flags, 0, n))
		return -EAGAIN;
	i = power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n);
	if (i < 0)
		return -EAGAIN;

	for (i = cpuhw->n_txn_start; i < n; ++i)
		cpuhw->event[i]->hw.config = cpuhw->events[i];

	return 0;
}

struct pmu power_pmu = {
	.enable		= power_pmu_enable,
	.disable	= power_pmu_disable,
	.read		= power_pmu_read,
	.unthrottle	= power_pmu_unthrottle,
	.start_txn	= power_pmu_start_txn,
	.cancel_txn	= power_pmu_cancel_txn,
	.commit_txn	= power_pmu_commit_txn,
};

/*
Loading