diff options
author | Olof Johansson <olof@lixom.net> | 2012-09-16 18:50:30 -0700 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2012-09-16 18:50:30 -0700 |
commit | d192f93cfca6a0aedbf10fa548d8bc17b86275d6 (patch) | |
tree | 357a4106ec49747bd78550a79d68f7b6d1f642a3 /kernel/events/core.c | |
parent | adcb079f28ec08165897e2450a4a60b219274008 (diff) | |
parent | d5703bd35a4c76b0717ea51e2e8aabce341828a1 (diff) |
Merge tag 'tegra-for-3.7-maintainers' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra into next/maintainers
* tag 'tegra-for-3.7-maintainers' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra:
MAINTAINERS: tegra: remove Olof/Colin, add device tree files
MAINTAINERS: add defconfig file to TEGRA section
+ sync with 3.6-rc4
Diffstat (limited to 'kernel/events/core.c')
-rw-r--r-- | kernel/events/core.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index f1cf0edeb39..b7935fcec7d 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -4039,7 +4039,7 @@ void perf_prepare_sample(struct perf_event_header *header, if (sample_type & PERF_SAMPLE_CALLCHAIN) { int size = 1; - data->callchain = perf_callchain(regs); + data->callchain = perf_callchain(event, regs); if (data->callchain) size += data->callchain->nr; @@ -5209,7 +5209,8 @@ static int perf_tp_event_match(struct perf_event *event, } void perf_tp_event(u64 addr, u64 count, void *record, int entry_size, - struct pt_regs *regs, struct hlist_head *head, int rctx) + struct pt_regs *regs, struct hlist_head *head, int rctx, + struct task_struct *task) { struct perf_sample_data data; struct perf_event *event; @@ -5228,6 +5229,31 @@ void perf_tp_event(u64 addr, u64 count, void *record, int entry_size, perf_swevent_event(event, count, &data, regs); } + /* + * If we got specified a target task, also iterate its context and + * deliver this event there too. + */ + if (task && task != current) { + struct perf_event_context *ctx; + struct trace_entry *entry = record; + + rcu_read_lock(); + ctx = rcu_dereference(task->perf_event_ctxp[perf_sw_context]); + if (!ctx) + goto unlock; + + list_for_each_entry_rcu(event, &ctx->event_list, event_entry) { + if (event->attr.type != PERF_TYPE_TRACEPOINT) + continue; + if (event->attr.config != entry->type) + continue; + if (perf_tp_event_match(event, &data, regs)) + perf_swevent_event(event, count, &data, regs); + } +unlock: + rcu_read_unlock(); + } + perf_swevent_put_recursion_context(rctx); } EXPORT_SYMBOL_GPL(perf_tp_event); |