diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-12-14 08:44:31 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-14 14:31:27 -0500 |
commit | e06c61a879910869aa5bf3f8f634abfee1a7bebc (patch) | |
tree | 30add308b26946b618bb0e2d711c2b1c27f58714 /kernel/perf_counter.c | |
parent | 6c594c21fcb02c662f11c97be4d7d2b73060a205 (diff) |
perfcounters: add nr-of-faults counter
Impact: add new feature, new sw counter
Add a counter that counts the number of pagefaults a task
is experiencing.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/perf_counter.c')
-rw-r--r-- | kernel/perf_counter.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index fb11e351e44e..59c52f9ee431 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c | |||
@@ -888,6 +888,54 @@ static const struct hw_perf_counter_ops perf_ops_task_clock = { | |||
888 | .hw_perf_counter_read = task_clock_perf_counter_read, | 888 | .hw_perf_counter_read = task_clock_perf_counter_read, |
889 | }; | 889 | }; |
890 | 890 | ||
891 | static u64 get_page_faults(void) | ||
892 | { | ||
893 | struct task_struct *curr = current; | ||
894 | |||
895 | return curr->maj_flt + curr->min_flt; | ||
896 | } | ||
897 | |||
898 | static void page_faults_perf_counter_update(struct perf_counter *counter) | ||
899 | { | ||
900 | u64 prev, now; | ||
901 | s64 delta; | ||
902 | |||
903 | prev = atomic64_read(&counter->hw.prev_count); | ||
904 | now = get_page_faults(); | ||
905 | |||
906 | atomic64_set(&counter->hw.prev_count, now); | ||
907 | |||
908 | delta = now - prev; | ||
909 | if (WARN_ON_ONCE(delta < 0)) | ||
910 | delta = 0; | ||
911 | |||
912 | atomic64_add(delta, &counter->count); | ||
913 | } | ||
914 | |||
915 | static void page_faults_perf_counter_read(struct perf_counter *counter) | ||
916 | { | ||
917 | page_faults_perf_counter_update(counter); | ||
918 | } | ||
919 | |||
920 | static void page_faults_perf_counter_enable(struct perf_counter *counter) | ||
921 | { | ||
922 | /* | ||
923 | * page-faults is a per-task value already, | ||
924 | * so we dont have to clear it on switch-in. | ||
925 | */ | ||
926 | } | ||
927 | |||
928 | static void page_faults_perf_counter_disable(struct perf_counter *counter) | ||
929 | { | ||
930 | page_faults_perf_counter_update(counter); | ||
931 | } | ||
932 | |||
933 | static const struct hw_perf_counter_ops perf_ops_page_faults = { | ||
934 | .hw_perf_counter_enable = page_faults_perf_counter_enable, | ||
935 | .hw_perf_counter_disable = page_faults_perf_counter_disable, | ||
936 | .hw_perf_counter_read = page_faults_perf_counter_read, | ||
937 | }; | ||
938 | |||
891 | static u64 get_context_switches(void) | 939 | static u64 get_context_switches(void) |
892 | { | 940 | { |
893 | struct task_struct *curr = current; | 941 | struct task_struct *curr = current; |
@@ -994,6 +1042,9 @@ sw_perf_counter_init(struct perf_counter *counter) | |||
994 | case PERF_COUNT_TASK_CLOCK: | 1042 | case PERF_COUNT_TASK_CLOCK: |
995 | hw_ops = &perf_ops_task_clock; | 1043 | hw_ops = &perf_ops_task_clock; |
996 | break; | 1044 | break; |
1045 | case PERF_COUNT_PAGE_FAULTS: | ||
1046 | hw_ops = &perf_ops_page_faults; | ||
1047 | break; | ||
997 | case PERF_COUNT_CONTEXT_SWITCHES: | 1048 | case PERF_COUNT_CONTEXT_SWITCHES: |
998 | hw_ops = &perf_ops_context_switches; | 1049 | hw_ops = &perf_ops_context_switches; |
999 | break; | 1050 | break; |