perf_counter: add an mmap method to allow userspace to read hardware counters
Impact: new feature giving performance improvement This adds the ability for userspace to do an mmap on a hardware counter fd and get access to a read-only page that contains the information needed to translate a hardware counter value to the full 64-bit counter value that would be returned by a read on the fd. This is useful on architectures that allow user programs to read the hardware counters, such as PowerPC. The mmap will only succeed if the counter is a hardware counter monitoring the current process. On my quad 2.5GHz PowerPC 970MP machine, userspace can read a counter and translate it to the full 64-bit value in about 30ns using the mmapped page, compared to about 830ns for the read syscall on the counter, so this does give a significant performance improvement. Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Orig-LKML-Reference: <20090323172417.297057964@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
committed by
Ingo Molnar
parent
96f6d44443
commit
37d8182838
@@ -417,6 +417,8 @@ void hw_perf_restore(u64 disable)
|
||||
atomic64_set(&counter->hw.prev_count, val);
|
||||
counter->hw.idx = hwc_index[i] + 1;
|
||||
write_pmc(counter->hw.idx, val);
|
||||
if (counter->user_page)
|
||||
perf_counter_update_userpage(counter);
|
||||
}
|
||||
mb();
|
||||
cpuhw->mmcr[0] |= MMCR0_PMXE | MMCR0_FCECE;
|
||||
@@ -572,6 +574,8 @@ static void power_perf_disable(struct perf_counter *counter)
|
||||
ppmu->disable_pmc(counter->hw.idx - 1, cpuhw->mmcr);
|
||||
write_pmc(counter->hw.idx, 0);
|
||||
counter->hw.idx = 0;
|
||||
if (counter->user_page)
|
||||
perf_counter_update_userpage(counter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -698,6 +702,8 @@ static void record_and_restart(struct perf_counter *counter, long val,
|
||||
write_pmc(counter->hw.idx, val);
|
||||
atomic64_set(&counter->hw.prev_count, val);
|
||||
atomic64_set(&counter->hw.period_left, left);
|
||||
if (counter->user_page)
|
||||
perf_counter_update_userpage(counter);
|
||||
|
||||
/*
|
||||
* Finally record data if requested.
|
||||
|
Reference in New Issue
Block a user