diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2010-05-20 10:46:39 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-05-21 05:37:59 -0400 |
commit | 5d967a8be636a4f301a8daad642bd1007299d9ec (patch) | |
tree | a55fa9c068f4a25a0de62797994353a36e165ca5 /kernel/perf_event.c | |
parent | adb8e118f288dc4c569ac9a89010b81a4745fbf0 (diff) |
perf: Optimize perf_output_copy()
Reduce the clutter in perf_output_copy() by keeping
an interator in perf_output_handle.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <20100521090710.742809176@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/perf_event.c')
-rw-r--r-- | kernel/perf_event.c | 54 |
1 files changed, 26 insertions, 28 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 1531e0b409a5..b67549a08626 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
@@ -2961,39 +2961,30 @@ again: | |||
2961 | void perf_output_copy(struct perf_output_handle *handle, | 2961 | void perf_output_copy(struct perf_output_handle *handle, |
2962 | const void *buf, unsigned int len) | 2962 | const void *buf, unsigned int len) |
2963 | { | 2963 | { |
2964 | unsigned int pages_mask; | 2964 | handle->offset += len; |
2965 | unsigned long offset; | ||
2966 | unsigned int size; | ||
2967 | void **pages; | ||
2968 | |||
2969 | offset = handle->offset; | ||
2970 | pages_mask = handle->data->nr_pages - 1; | ||
2971 | pages = handle->data->data_pages; | ||
2972 | |||
2973 | do { | ||
2974 | unsigned long page_offset; | ||
2975 | unsigned long page_size; | ||
2976 | int nr; | ||
2977 | |||
2978 | nr = (offset >> PAGE_SHIFT) & pages_mask; | ||
2979 | page_size = 1UL << (handle->data->data_order + PAGE_SHIFT); | ||
2980 | page_offset = offset & (page_size - 1); | ||
2981 | size = min_t(unsigned int, page_size - page_offset, len); | ||
2982 | |||
2983 | memcpy(pages[nr] + page_offset, buf, size); | ||
2984 | |||
2985 | len -= size; | ||
2986 | buf += size; | ||
2987 | offset += size; | ||
2988 | } while (len); | ||
2989 | |||
2990 | handle->offset = offset; | ||
2991 | 2965 | ||
2992 | /* | 2966 | /* |
2993 | * Check we didn't copy past our reservation window, taking the | 2967 | * Check we didn't copy past our reservation window, taking the |
2994 | * possible unsigned int wrap into account. | 2968 | * possible unsigned int wrap into account. |
2995 | */ | 2969 | */ |
2996 | WARN_ON_ONCE(((long)(handle->head - handle->offset)) < 0); | 2970 | if (WARN_ON_ONCE(((long)(handle->head - handle->offset)) < 0)) |
2971 | return; | ||
2972 | |||
2973 | do { | ||
2974 | unsigned long size = min(handle->size, len); | ||
2975 | |||
2976 | memcpy(handle->addr, buf, size); | ||
2977 | |||
2978 | len -= size; | ||
2979 | handle->addr += size; | ||
2980 | handle->size -= size; | ||
2981 | if (!handle->size) { | ||
2982 | handle->page++; | ||
2983 | handle->page &= handle->data->nr_pages - 1; | ||
2984 | handle->addr = handle->data->data_pages[handle->page]; | ||
2985 | handle->size = PAGE_SIZE << handle->data->data_order; | ||
2986 | } | ||
2987 | } while (len); | ||
2997 | } | 2988 | } |
2998 | 2989 | ||
2999 | int perf_output_begin(struct perf_output_handle *handle, | 2990 | int perf_output_begin(struct perf_output_handle *handle, |
@@ -3059,6 +3050,13 @@ int perf_output_begin(struct perf_output_handle *handle, | |||
3059 | if (head - local_read(&data->wakeup) > data->watermark) | 3050 | if (head - local_read(&data->wakeup) > data->watermark) |
3060 | local_add(data->watermark, &data->wakeup); | 3051 | local_add(data->watermark, &data->wakeup); |
3061 | 3052 | ||
3053 | handle->page = handle->offset >> (PAGE_SHIFT + data->data_order); | ||
3054 | handle->page &= data->nr_pages - 1; | ||
3055 | handle->size = handle->offset & ((PAGE_SIZE << data->data_order) - 1); | ||
3056 | handle->addr = data->data_pages[handle->page]; | ||
3057 | handle->addr += handle->size; | ||
3058 | handle->size = (PAGE_SIZE << data->data_order) - handle->size; | ||
3059 | |||
3062 | if (have_lost) { | 3060 | if (have_lost) { |
3063 | lost_event.header.type = PERF_RECORD_LOST; | 3061 | lost_event.header.type = PERF_RECORD_LOST; |
3064 | lost_event.header.misc = 0; | 3062 | lost_event.header.misc = 0; |