perf, x86: Make a second write to performance counter if needed
Subsystems (2)
PATCH 1/1 perf, x86: Make a second write to performance counter if needed
On Netburst PMU we need a second write to a performance counter due to cpu erratum.
A simple flag test instead of alternative instructions was choosen because wrmsrl is already a macro and if virtualization is turned on will need an additional wrapper call which is more expencise.
nb: we should propably switch to jump-labels as only this facility reach the mainline.
--- arch/x86/kernel/cpu/perf_event.c | 10 ++++++++++ arch/x86/kernel/cpu/perf_event_p4.c | 9 +++++++++ 2 files changed, 19 insertions(+)
arch/x86/kernel/cpu/perf_event.c +10 -0
@@ -220,6 +220,7 @@ struct x86_pmu { struct perf_event *event);struct event_constraint *event_constraints;void (*quirks)(void ); +int perfctr_second_write;int (*cpu_prepare)(int cpu);void (*cpu_starting)(int cpu);
@@ -926,6 +927,15 @@ x86_perf_event_set_period(struct perf_evatomic64_set (&hwc->prev_count, (u64)-left);wrmsrl (hwc->event_base + idx, + (u64)(-left) & x86_pmu.cntval_mask); + +/* +* Due to erratum on certan cpu we need +* a second write to be sure the register +* is updated properly +*/ +if (x86_pmu.perfctr_second_write) +wrmsrl (hwc->event_base + idx, (u64)(-left) & x86_pmu.cntval_mask);perf_event_update_userpage (event);
arch/x86/kernel/cpu/perf_event_p4.c +9 -0
@@ -829,6 +829,15 @@ static __initconst const struct x86_pmu .max_period = (1ULL << 39) - 1, .hw_config = p4_hw_config, .schedule_events = p4_pmu_schedule_events, +/* +* This handles erratum N15 in intel doc 249199-029, +* the counter may not be updated correctly on write +* so we need a second write operation to do the trick +* (the official workaround didn't work) +* +* the former idea is taken from OProfile code +*/ + .perfctr_second_write = 1, };static __init int p4_pmu_init (void )
Peter Zijlstra
maintainerQuoted 9 lines · Cyrill Gorcunov
On Netburst PMU we need a second write to a performance counter due to cpu erratum.
A simple flag test instead of alternative instructions was choosen because wrmsrl is already a macro and if virtualization is turned on will need an additional wrapper call which is more expencise.
nb: we should propably switch to jump-labels as only this facility reach the mainline.
OK. Thanks Cyrill.
Quoted 4 lines · Peter Zijlstra
Quoted 3 lines · Cyrill Gorcunov
On Netburst PMU we need a second write to a performance counter due to cpu erratum.
Quoted 8 lines
Quoted 6 lines
A simple flag test instead of alternative instructions was choosen because wrmsrl is already a macro and if virtualization is turned on will need an additional wrapper call which is more expencise.
nb: we should propably switch to jump-labels as only this facility reach the mainline.
OK. Thanks Cyrill.
I tested this patch and it works well for pre-defined events.
Lin Ming
Commit-ID: 68aa00ac0a82e9a876c799bf6be7622b8f1c8517 Gitweb: http://git.kernel.org/tip/68aa00ac0a82e9a876c799bf6be7622b8f1c8517 Author: Cyrill Gorcunov <[email protected]> AuthorDate: Thu, 3 Jun 2010 01:23:04 +0400 Committer: Ingo Molnar <[email protected]> CommitDate: Wed, 9 Jun 2010 11:12:35 +0200
perf, x86: Make a second write to performance counter if needed
On Netburst PMU we need a second write to a performance counter due to cpu erratum.
A simple flag test instead of alternative instructions was choosen because wrmsrl is already a macro and if virtualization is turned on will need an additional wrapper call which is more expencise.
nb: we should propably switch to jump-labels as only this facility reach the mainline.
LKML-Reference: <20100602212304.GC5264@lenovo>
--- arch/x86/kernel/cpu/perf_event.c | 12 +++++++++++- arch/x86/kernel/cpu/perf_event_p4.c | 9 +++++++++ 2 files changed, 20 insertions(+), 1 deletions(-)
arch/x86/kernel/cpu/perf_event.c +11 -1
@@ -220,6 +220,7 @@ struct x86_pmu { struct perf_event *event);struct event_constraint *event_constraints;void (*quirks)(void ); +int perfctr_second_write;int (*cpu_prepare)(int cpu);void (*cpu_starting)(int cpu);
@@ -925,8 +926,17 @@ x86_perf_event_set_period(struct perf_event *event)*/ atomic64_set (&hwc->prev_count, (u64)-left); -wrmsrl (hwc->event_base + idx, +wrmsrl (hwc->event_base + idx, (u64)(-left) & x86_pmu.cntval_mask); + +/* +* Due to erratum on certan cpu we need +* a second write to be sure the register +* is updated properly +*/ +if (x86_pmu.perfctr_second_write) { +wrmsrl (hwc->event_base + idx, (u64)(-left) & x86_pmu.cntval_mask); + }perf_event_update_userpage (event);
arch/x86/kernel/cpu/perf_event_p4.c +9 -0
@@ -829,6 +829,15 @@ static __initconst const struct x86_pmu p4_pmu = { .max_period = (1ULL << 39) - 1, .hw_config = p4_hw_config, .schedule_events = p4_pmu_schedule_events, +/* +* This handles erratum N15 in intel doc 249199-029, +* the counter may not be updated correctly on write +* so we need a second write operation to do the trick +* (the official workaround didn't work) +* +* the former idea is taken from OProfile code +*/ + .perfctr_second_write = 1, };static __init int p4_pmu_init (void )