Commit 92bf309a authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar

perf_counter: Push perf_sample_data through the swcounter code

Push the perf_sample_data further outwards to the swcounter interface,
to abstract it away some more.
Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 9cffa8d5
...@@ -3171,20 +3171,15 @@ static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer) ...@@ -3171,20 +3171,15 @@ static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer)
} }
static void perf_swcounter_overflow(struct perf_counter *counter, static void perf_swcounter_overflow(struct perf_counter *counter,
int nmi, struct pt_regs *regs, u64 addr) int nmi, struct perf_sample_data *data)
{ {
struct perf_sample_data data = { data->period = counter->hw.last_period;
.regs = regs,
.addr = addr,
.period = counter->hw.last_period,
};
perf_swcounter_update(counter); perf_swcounter_update(counter);
perf_swcounter_set_period(counter); perf_swcounter_set_period(counter);
if (perf_counter_overflow(counter, nmi, &data)) if (perf_counter_overflow(counter, nmi, data))
/* soft-disable the counter */ /* soft-disable the counter */
; ;
} }
static int perf_swcounter_is_counting(struct perf_counter *counter) static int perf_swcounter_is_counting(struct perf_counter *counter)
...@@ -3249,18 +3244,18 @@ static int perf_swcounter_match(struct perf_counter *counter, ...@@ -3249,18 +3244,18 @@ static int perf_swcounter_match(struct perf_counter *counter,
} }
static void perf_swcounter_add(struct perf_counter *counter, u64 nr, static void perf_swcounter_add(struct perf_counter *counter, u64 nr,
int nmi, struct pt_regs *regs, u64 addr) int nmi, struct perf_sample_data *data)
{ {
int neg = atomic64_add_negative(nr, &counter->hw.count); int neg = atomic64_add_negative(nr, &counter->hw.count);
if (counter->hw.sample_period && !neg && regs) if (counter->hw.sample_period && !neg && data->regs)
perf_swcounter_overflow(counter, nmi, regs, addr); perf_swcounter_overflow(counter, nmi, data);
} }
static void perf_swcounter_ctx_event(struct perf_counter_context *ctx, static void perf_swcounter_ctx_event(struct perf_counter_context *ctx,
enum perf_type_id type, u32 event, enum perf_type_id type,
u64 nr, int nmi, struct pt_regs *regs, u32 event, u64 nr, int nmi,
u64 addr) struct perf_sample_data *data)
{ {
struct perf_counter *counter; struct perf_counter *counter;
...@@ -3269,8 +3264,8 @@ static void perf_swcounter_ctx_event(struct perf_counter_context *ctx, ...@@ -3269,8 +3264,8 @@ static void perf_swcounter_ctx_event(struct perf_counter_context *ctx,
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(counter, &ctx->event_list, event_entry) { list_for_each_entry_rcu(counter, &ctx->event_list, event_entry) {
if (perf_swcounter_match(counter, type, event, regs)) if (perf_swcounter_match(counter, type, event, data->regs))
perf_swcounter_add(counter, nr, nmi, regs, addr); perf_swcounter_add(counter, nr, nmi, data);
} }
rcu_read_unlock(); rcu_read_unlock();
} }
...@@ -3289,9 +3284,9 @@ static int *perf_swcounter_recursion_context(struct perf_cpu_context *cpuctx) ...@@ -3289,9 +3284,9 @@ static int *perf_swcounter_recursion_context(struct perf_cpu_context *cpuctx)
return &cpuctx->recursion[0]; return &cpuctx->recursion[0];
} }
static void __perf_swcounter_event(enum perf_type_id type, u32 event, static void do_perf_swcounter_event(enum perf_type_id type, u32 event,
u64 nr, int nmi, struct pt_regs *regs, u64 nr, int nmi,
u64 addr) struct perf_sample_data *data)
{ {
struct perf_cpu_context *cpuctx = &get_cpu_var(perf_cpu_context); struct perf_cpu_context *cpuctx = &get_cpu_var(perf_cpu_context);
int *recursion = perf_swcounter_recursion_context(cpuctx); int *recursion = perf_swcounter_recursion_context(cpuctx);
...@@ -3304,7 +3299,7 @@ static void __perf_swcounter_event(enum perf_type_id type, u32 event, ...@@ -3304,7 +3299,7 @@ static void __perf_swcounter_event(enum perf_type_id type, u32 event,
barrier(); barrier();
perf_swcounter_ctx_event(&cpuctx->ctx, type, event, perf_swcounter_ctx_event(&cpuctx->ctx, type, event,
nr, nmi, regs, addr); nr, nmi, data);
rcu_read_lock(); rcu_read_lock();
/* /*
* doesn't really matter which of the child contexts the * doesn't really matter which of the child contexts the
...@@ -3312,7 +3307,7 @@ static void __perf_swcounter_event(enum perf_type_id type, u32 event, ...@@ -3312,7 +3307,7 @@ static void __perf_swcounter_event(enum perf_type_id type, u32 event,
*/ */
ctx = rcu_dereference(current->perf_counter_ctxp); ctx = rcu_dereference(current->perf_counter_ctxp);
if (ctx) if (ctx)
perf_swcounter_ctx_event(ctx, type, event, nr, nmi, regs, addr); perf_swcounter_ctx_event(ctx, type, event, nr, nmi, data);
rcu_read_unlock(); rcu_read_unlock();
barrier(); barrier();
...@@ -3325,7 +3320,12 @@ static void __perf_swcounter_event(enum perf_type_id type, u32 event, ...@@ -3325,7 +3320,12 @@ static void __perf_swcounter_event(enum perf_type_id type, u32 event,
void void
perf_swcounter_event(u32 event, u64 nr, int nmi, struct pt_regs *regs, u64 addr) perf_swcounter_event(u32 event, u64 nr, int nmi, struct pt_regs *regs, u64 addr)
{ {
__perf_swcounter_event(PERF_TYPE_SOFTWARE, event, nr, nmi, regs, addr); struct perf_sample_data data = {
.regs = regs,
.addr = addr,
};
do_perf_swcounter_event(PERF_TYPE_SOFTWARE, event, nr, nmi, &data);
} }
static void perf_swcounter_read(struct perf_counter *counter) static void perf_swcounter_read(struct perf_counter *counter)
...@@ -3469,12 +3469,15 @@ static const struct pmu perf_ops_task_clock = { ...@@ -3469,12 +3469,15 @@ static const struct pmu perf_ops_task_clock = {
#ifdef CONFIG_EVENT_PROFILE #ifdef CONFIG_EVENT_PROFILE
void perf_tpcounter_event(int event_id) void perf_tpcounter_event(int event_id)
{ {
struct pt_regs *regs = get_irq_regs(); struct perf_sample_data data = {
.regs = get_irq_regs();
.addr = 0,
};
if (!regs) if (!data.regs)
regs = task_pt_regs(current); data.regs = task_pt_regs(current);
__perf_swcounter_event(PERF_TYPE_TRACEPOINT, event_id, 1, 1, regs, 0); do_perf_swcounter_event(PERF_TYPE_TRACEPOINT, event_id, 1, 1, &data);
} }
EXPORT_SYMBOL_GPL(perf_tpcounter_event); EXPORT_SYMBOL_GPL(perf_tpcounter_event);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment