aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2009-01-09 00:26:43 -0500
committerPaul Mackerras <paulus@samba.org>2009-01-09 00:26:43 -0500
commit9abf8a08bc8f18a3b125f834f00e2e71b49c15d2 (patch)
tree45d09a1251d6974575a89773aa53ece1f3966021 /kernel
parentff6f05416ece2caec1a7a1f8180d6598e0ab9272 (diff)
perf_counter: Fix the cpu_clock software counter
Impact: bug fix Currently if you do (e.g.) timec -e -1 ls, it will report 0 for the value of the cpu_clock counter. The reason is that the core assumes that a counter's count field is up-to-date when the counter is inactive, and doesn't call the counter's read function. However, the cpu_clock counter code only updates the count in the read function. This fixes it by making both the read and disable functions update the count. It also makes the counter ignore time passing while the counter is disabled, by making the enable function update the hw.prev_count field. Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/perf_counter.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index 4be1a8d872b4..b7a027a2ef02 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -928,18 +928,32 @@ static const struct file_operations perf_fops = {
928 928
929static int cpu_clock_perf_counter_enable(struct perf_counter *counter) 929static int cpu_clock_perf_counter_enable(struct perf_counter *counter)
930{ 930{
931 int cpu = raw_smp_processor_id();
932
933 atomic64_set(&counter->hw.prev_count, cpu_clock(cpu));
931 return 0; 934 return 0;
932} 935}
933 936
937static void cpu_clock_perf_counter_update(struct perf_counter *counter)
938{
939 int cpu = raw_smp_processor_id();
940 s64 prev;
941 u64 now;
942
943 now = cpu_clock(cpu);
944 prev = atomic64_read(&counter->hw.prev_count);
945 atomic64_set(&counter->hw.prev_count, now);
946 atomic64_add(now - prev, &counter->count);
947}
948
934static void cpu_clock_perf_counter_disable(struct perf_counter *counter) 949static void cpu_clock_perf_counter_disable(struct perf_counter *counter)
935{ 950{
951 cpu_clock_perf_counter_update(counter);
936} 952}
937 953
938static void cpu_clock_perf_counter_read(struct perf_counter *counter) 954static void cpu_clock_perf_counter_read(struct perf_counter *counter)
939{ 955{
940 int cpu = raw_smp_processor_id(); 956 cpu_clock_perf_counter_update(counter);
941
942 atomic64_set(&counter->count, cpu_clock(cpu));
943} 957}
944 958
945static const struct hw_perf_counter_ops perf_ops_cpu_clock = { 959static const struct hw_perf_counter_ops perf_ops_cpu_clock = {