perf, x86: Fixup the PEBS handler for Core2 cpus
Pull the core handler in line with the nhm one, also make sure we always drain the buffer. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Arnaldo Carvalho de Melo <acme@infradead.org> Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
committed by
Ingo Molnar
parent
7645a24cbd
commit
d80c7502ff
@@ -472,20 +472,39 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
|
|||||||
struct pt_regs regs;
|
struct pt_regs regs;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (!event || !ds || !x86_pmu.pebs)
|
if (!ds || !x86_pmu.pebs)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
at = (struct pebs_record_core *)(unsigned long)ds->pebs_buffer_base;
|
at = (struct pebs_record_core *)(unsigned long)ds->pebs_buffer_base;
|
||||||
top = (struct pebs_record_core *)(unsigned long)ds->pebs_index;
|
top = (struct pebs_record_core *)(unsigned long)ds->pebs_index;
|
||||||
|
|
||||||
if (top <= at)
|
/*
|
||||||
|
* Whatever else happens, drain the thing
|
||||||
|
*/
|
||||||
|
ds->pebs_index = ds->pebs_buffer_base;
|
||||||
|
|
||||||
|
if (!test_bit(0, cpuc->active_mask))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ds->pebs_index = ds->pebs_buffer_base;
|
WARN_ON_ONCE(!event);
|
||||||
|
|
||||||
|
if (!event->attr.precise)
|
||||||
|
return;
|
||||||
|
|
||||||
|
n = top - at;
|
||||||
|
if (n <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!intel_pmu_save_and_restart(event))
|
if (!intel_pmu_save_and_restart(event))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Should not happen, we program the threshold at 1 and do not
|
||||||
|
* set a reset value.
|
||||||
|
*/
|
||||||
|
WARN_ON_ONCE(n > 1);
|
||||||
|
at += n - 1;
|
||||||
|
|
||||||
perf_sample_data_init(&data, 0);
|
perf_sample_data_init(&data, 0);
|
||||||
data.period = event->hw.last_period;
|
data.period = event->hw.last_period;
|
||||||
|
|
||||||
@@ -495,14 +514,6 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
|
|||||||
data.raw = &raw;
|
data.raw = &raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = top - at;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Should not happen, we program the threshold at 1 and do not
|
|
||||||
* set a reset value.
|
|
||||||
*/
|
|
||||||
WARN_ON_ONCE(n > 1);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We use the interrupt regs as a base because the PEBS record
|
* We use the interrupt regs as a base because the PEBS record
|
||||||
* does not contain a full regs set, specifically it seems to
|
* does not contain a full regs set, specifically it seems to
|
||||||
@@ -545,12 +556,11 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
|
|||||||
at = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
|
at = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
|
||||||
top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
|
top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
|
||||||
|
|
||||||
if (top <= at)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ds->pebs_index = ds->pebs_buffer_base;
|
ds->pebs_index = ds->pebs_buffer_base;
|
||||||
|
|
||||||
n = top - at;
|
n = top - at;
|
||||||
|
if (n <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Should not happen, we program the threshold at 1 and do not
|
* Should not happen, we program the threshold at 1 and do not
|
||||||
|
Reference in New Issue
Block a user