Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Ingo Molnar: "Kernel side changes: - Improved kbprobes robustness - Intel PEBS support for PT hardware tracing - Other Intel PT improvements: high order pages memory footprint reduction and various related cleanups - Misc cleanups The perf tooling side has been very busy in this cycle, with over 300 commits. This is an incomplete high-level summary of the many improvements done by over 30 developers: - Lots of updates to the following tools: 'perf c2c' 'perf config' 'perf record' 'perf report' 'perf script' 'perf test' 'perf top' 'perf trace' - Updates to libperf and libtraceevent, and a consolidation of the proliferation of x86 instruction decoder libraries. - Vendor event updates for Intel and PowerPC CPUs, - Updates to hardware tracing tooling for ARM and Intel CPUs, - ... and lots of other changes and cleanups - see the shortlog and Git log for details" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (322 commits) kprobes: Prohibit probing on BUG() and WARN() address perf/x86: Make more stuff static x86, perf: Fix the dependency of the x86 insn decoder selftest objtool: Ignore intentional differences for the x86 insn decoder objtool: Update sync-check.sh from perf's check-headers.sh perf build: Ignore intentional differences for the x86 insn decoder perf intel-pt: Use shared x86 insn decoder perf intel-pt: Remove inat.c from build dependency list perf: Update .gitignore file objtool: Move x86 insn decoder to a common location perf metricgroup: Support multiple events for metricgroup perf metricgroup: Scale the metric result perf pmu: Change convert_scale from static to global perf symbols: Move mem_info and branch_info out of symbol.h perf auxtrace: Uninline functions that touch perf_session perf tools: Remove needless evlist.h include directives perf tools: Remove needless evlist.h include directives perf tools: Remove needless thread_map.h include directives perf tools: Remove needless thread.h include directives perf tools: Remove needless map.h include directives ...
This commit is contained in:
@@ -1887,6 +1887,89 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx)
|
||||
ctx->generation++;
|
||||
}
|
||||
|
||||
static int
|
||||
perf_aux_output_match(struct perf_event *event, struct perf_event *aux_event)
|
||||
{
|
||||
if (!has_aux(aux_event))
|
||||
return 0;
|
||||
|
||||
if (!event->pmu->aux_output_match)
|
||||
return 0;
|
||||
|
||||
return event->pmu->aux_output_match(aux_event);
|
||||
}
|
||||
|
||||
static void put_event(struct perf_event *event);
|
||||
static void event_sched_out(struct perf_event *event,
|
||||
struct perf_cpu_context *cpuctx,
|
||||
struct perf_event_context *ctx);
|
||||
|
||||
static void perf_put_aux_event(struct perf_event *event)
|
||||
{
|
||||
struct perf_event_context *ctx = event->ctx;
|
||||
struct perf_cpu_context *cpuctx = __get_cpu_context(ctx);
|
||||
struct perf_event *iter;
|
||||
|
||||
/*
|
||||
* If event uses aux_event tear down the link
|
||||
*/
|
||||
if (event->aux_event) {
|
||||
iter = event->aux_event;
|
||||
event->aux_event = NULL;
|
||||
put_event(iter);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the event is an aux_event, tear down all links to
|
||||
* it from other events.
|
||||
*/
|
||||
for_each_sibling_event(iter, event->group_leader) {
|
||||
if (iter->aux_event != event)
|
||||
continue;
|
||||
|
||||
iter->aux_event = NULL;
|
||||
put_event(event);
|
||||
|
||||
/*
|
||||
* If it's ACTIVE, schedule it out and put it into ERROR
|
||||
* state so that we don't try to schedule it again. Note
|
||||
* that perf_event_enable() will clear the ERROR status.
|
||||
*/
|
||||
event_sched_out(iter, cpuctx, ctx);
|
||||
perf_event_set_state(event, PERF_EVENT_STATE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
static int perf_get_aux_event(struct perf_event *event,
|
||||
struct perf_event *group_leader)
|
||||
{
|
||||
/*
|
||||
* Our group leader must be an aux event if we want to be
|
||||
* an aux_output. This way, the aux event will precede its
|
||||
* aux_output events in the group, and therefore will always
|
||||
* schedule first.
|
||||
*/
|
||||
if (!group_leader)
|
||||
return 0;
|
||||
|
||||
if (!perf_aux_output_match(event, group_leader))
|
||||
return 0;
|
||||
|
||||
if (!atomic_long_inc_not_zero(&group_leader->refcount))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Link aux_outputs to their aux event; this is undone in
|
||||
* perf_group_detach() by perf_put_aux_event(). When the
|
||||
* group in torn down, the aux_output events loose their
|
||||
* link to the aux_event and can't schedule any more.
|
||||
*/
|
||||
event->aux_event = group_leader;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void perf_group_detach(struct perf_event *event)
|
||||
{
|
||||
struct perf_event *sibling, *tmp;
|
||||
@@ -1902,6 +1985,8 @@ static void perf_group_detach(struct perf_event *event)
|
||||
|
||||
event->attach_state &= ~PERF_ATTACH_GROUP;
|
||||
|
||||
perf_put_aux_event(event);
|
||||
|
||||
/*
|
||||
* If this is a sibling, remove it from its group.
|
||||
*/
|
||||
@@ -10426,6 +10511,12 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
|
||||
goto err_ns;
|
||||
}
|
||||
|
||||
if (event->attr.aux_output &&
|
||||
!(pmu->capabilities & PERF_PMU_CAP_AUX_OUTPUT)) {
|
||||
err = -EOPNOTSUPP;
|
||||
goto err_pmu;
|
||||
}
|
||||
|
||||
err = exclusive_event_init(event);
|
||||
if (err)
|
||||
goto err_pmu;
|
||||
@@ -11082,6 +11173,8 @@ SYSCALL_DEFINE5(perf_event_open,
|
||||
}
|
||||
}
|
||||
|
||||
if (event->attr.aux_output && !perf_get_aux_event(event, group_leader))
|
||||
goto err_locked;
|
||||
|
||||
/*
|
||||
* Must be under the same ctx::mutex as perf_install_in_context(),
|
||||
|
Reference in New Issue
Block a user