aboutsummaryrefslogtreecommitdiff
path: root/kernel/perf_counter.c
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2009-03-19 20:26:19 +0100
committerIngo Molnar <mingo@elte.hu>2009-04-06 09:30:17 +0200
commit0322cd6ec504b0bf08ca7b2c3d7f43bda37d79c9 (patch)
tree8e5487e1a6700eb865ec1f268d51e9d6d3d38a71 /kernel/perf_counter.c
parentb8e83514b64577b48bfb794fe85fcde40a9343ca (diff)
perf_counter: unify irq output code
Impact: cleanup Having 3 slightly different copies of the same code around does nobody any good. First step in revamping the output format. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> Cc: Steven Rostedt <rostedt@goodmis.org> Orig-LKML-Reference: <20090319194233.929962222@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/perf_counter.c')
-rw-r--r--kernel/perf_counter.c106
1 files changed, 56 insertions, 50 deletions
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index 68a56a68bc7..f054b8c9bf9 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -1354,6 +1354,60 @@ static const struct file_operations perf_fops = {
};
/*
+ * Output
+ */
+
+static void perf_counter_store_irq(struct perf_counter *counter, u64 data)
+{
+ struct perf_data *irqdata = counter->irqdata;
+
+ if (irqdata->len > PERF_DATA_BUFLEN - sizeof(u64)) {
+ irqdata->overrun++;
+ } else {
+ u64 *p = (u64 *) &irqdata->data[irqdata->len];
+
+ *p = data;
+ irqdata->len += sizeof(u64);
+ }
+}
+
+static void perf_counter_handle_group(struct perf_counter *counter)
+{
+ struct perf_counter *leader, *sub;
+
+ leader = counter->group_leader;
+ list_for_each_entry(sub, &leader->sibling_list, list_entry) {
+ if (sub != counter)
+ sub->hw_ops->read(sub);
+ perf_counter_store_irq(counter, sub->hw_event.event_config);
+ perf_counter_store_irq(counter, atomic64_read(&sub->count));
+ }
+}
+
+void perf_counter_output(struct perf_counter *counter,
+ int nmi, struct pt_regs *regs)
+{
+ switch (counter->hw_event.record_type) {
+ case PERF_RECORD_SIMPLE:
+ return;
+
+ case PERF_RECORD_IRQ:
+ perf_counter_store_irq(counter, instruction_pointer(regs));
+ break;
+
+ case PERF_RECORD_GROUP:
+ perf_counter_handle_group(counter);
+ break;
+ }
+
+ if (nmi) {
+ counter->wakeup_pending = 1;
+ set_perf_counter_pending();
+ } else
+ wake_up(&counter->waitq);
+}
+
+/*
* Generic software counter infrastructure
*/
@@ -1395,54 +1449,6 @@ static void perf_swcounter_set_period(struct perf_counter *counter)
atomic64_set(&hwc->count, -left);
}
-static void perf_swcounter_store_irq(struct perf_counter *counter, u64 data)
-{
- struct perf_data *irqdata = counter->irqdata;
-
- if (irqdata->len > PERF_DATA_BUFLEN - sizeof(u64)) {
- irqdata->overrun++;
- } else {
- u64 *p = (u64 *) &irqdata->data[irqdata->len];
-
- *p = data;
- irqdata->len += sizeof(u64);
- }
-}
-
-static void perf_swcounter_handle_group(struct perf_counter *sibling)
-{
- struct perf_counter *counter, *group_leader = sibling->group_leader;
-
- list_for_each_entry(counter, &group_leader->sibling_list, list_entry) {
- counter->hw_ops->read(counter);
- perf_swcounter_store_irq(sibling, counter->hw_event.event_config);
- perf_swcounter_store_irq(sibling, atomic64_read(&counter->count));
- }
-}
-
-static void perf_swcounter_interrupt(struct perf_counter *counter,
- int nmi, struct pt_regs *regs)
-{
- switch (counter->hw_event.record_type) {
- case PERF_RECORD_SIMPLE:
- break;
-
- case PERF_RECORD_IRQ:
- perf_swcounter_store_irq(counter, instruction_pointer(regs));
- break;
-
- case PERF_RECORD_GROUP:
- perf_swcounter_handle_group(counter);
- break;
- }
-
- if (nmi) {
- counter->wakeup_pending = 1;
- set_perf_counter_pending();
- } else
- wake_up(&counter->waitq);
-}
-
static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer)
{
struct perf_counter *counter;
@@ -1461,7 +1467,7 @@ static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer)
regs = task_pt_regs(current);
if (regs)
- perf_swcounter_interrupt(counter, 0, regs);
+ perf_counter_output(counter, 0, regs);
hrtimer_forward_now(hrtimer, ns_to_ktime(counter->hw.irq_period));
@@ -1473,7 +1479,7 @@ static void perf_swcounter_overflow(struct perf_counter *counter,
{
perf_swcounter_update(counter);
perf_swcounter_set_period(counter);
- perf_swcounter_interrupt(counter, nmi, regs);
+ perf_counter_output(counter, nmi, regs);
}
static int perf_swcounter_match(struct perf_counter *counter,