summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorRobert Richter <robert.richter@amd.com>2012-04-02 20:19:07 +0200
committerIngo Molnar <mingo@kernel.org>2012-05-09 15:23:11 +0200
commitc75841a398d667d9968245b9519d93cedbfb4780 (patch)
tree41d89325e579c8962cdac056c887db6eb5acce6c /arch
parentad8537cda68a8fe81776cceca6c22d54dd652ea5 (diff)
perf/x86-ibs: Fix update of period
The last sw period was not correctly updated on overflow and thus led to wrong distribution of events. We always need to properly initialize data.period in struct perf_sample_data. Signed-off-by: Robert Richter <robert.richter@amd.com> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1333390758-10893-2-git-send-email-robert.richter@amd.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/cpu/perf_event_amd_ibs.c27
1 files changed, 14 insertions, 13 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
index 8ff74d439041..c8f69bea6624 100644
--- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c
+++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
@@ -386,7 +386,21 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
if (!(*buf++ & perf_ibs->valid_mask))
return 0;
+ /*
+ * Emulate IbsOpCurCnt in MSRC001_1033 (IbsOpCtl), not
+ * supported in all cpus. As this triggered an interrupt, we
+ * set the current count to the max count.
+ */
+ config = ibs_data.regs[0];
+ if (perf_ibs == &perf_ibs_op && !(ibs_caps & IBS_CAPS_RDWROPCNT)) {
+ config &= ~IBS_OP_CUR_CNT;
+ config |= (config & IBS_OP_MAX_CNT) << 36;
+ }
+
+ perf_ibs_event_update(perf_ibs, event, config);
perf_sample_data_init(&data, 0);
+ data.period = event->hw.last_period;
+
if (event->attr.sample_type & PERF_SAMPLE_RAW) {
ibs_data.caps = ibs_caps;
size = 1;
@@ -405,19 +419,6 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
regs = *iregs; /* XXX: update ip from ibs sample */
- /*
- * Emulate IbsOpCurCnt in MSRC001_1033 (IbsOpCtl), not
- * supported in all cpus. As this triggered an interrupt, we
- * set the current count to the max count.
- */
- config = ibs_data.regs[0];
- if (perf_ibs == &perf_ibs_op && !(ibs_caps & IBS_CAPS_RDWROPCNT)) {
- config &= ~IBS_OP_CUR_CNT;
- config |= (config & IBS_OP_MAX_CNT) << 36;
- }
-
- perf_ibs_event_update(perf_ibs, event, config);
-
overflow = perf_ibs_set_period(perf_ibs, hwc, &config);
reenable = !(overflow && perf_event_overflow(event, &data, &regs));
config = (config >> 4) | (reenable ? perf_ibs->enable_mask : 0);