From 3cafa9fbb5c1d564b7b8e7224f493effbf04ffee Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 20 May 2010 19:07:56 +0200 Subject: [PATCH] perf: Optimize the !vmalloc backed buffer Reduce code and data by using the knowledge that for !PERF_USE_VMALLOC data_order is always 0. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Frederic Weisbecker Cc: Paul Mackerras Cc: Mike Galbraith Cc: Steven Rostedt LKML-Reference: <20100521090710.795019386@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_event.h | 2 +- kernel/perf_event.c | 41 ++++++++++++++++++++++++-------------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 7bd17f0488f8..09cd9c1abfda 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -588,8 +588,8 @@ struct perf_mmap_data { struct rcu_head rcu_head; #ifdef CONFIG_PERF_USE_VMALLOC struct work_struct work; + int page_order; /* allocation order */ #endif - int data_order; /* allocation order */ int nr_pages; /* nr of data pages */ int writable; /* are we writable */ int nr_locked; /* nr pages mlocked */ diff --git a/kernel/perf_event.c b/kernel/perf_event.c index b67549a08626..953ce46d7b2f 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -2297,11 +2297,6 @@ unlock: rcu_read_unlock(); } -static unsigned long perf_data_size(struct perf_mmap_data *data) -{ - return data->nr_pages << (PAGE_SHIFT + data->data_order); -} - #ifndef CONFIG_PERF_USE_VMALLOC /* @@ -2359,7 +2354,6 @@ perf_mmap_data_alloc(struct perf_event *event, int nr_pages) goto fail_data_pages; } - data->data_order = 0; data->nr_pages = nr_pages; return data; @@ -2395,6 +2389,11 @@ static void perf_mmap_data_free(struct perf_mmap_data *data) kfree(data); } +static inline int page_order(struct perf_mmap_data *data) +{ + return 0; +} + #else /* @@ -2403,10 +2402,15 @@ static void perf_mmap_data_free(struct perf_mmap_data *data) * Required for architectures that have d-cache aliasing issues. */ +static inline int page_order(struct perf_mmap_data *data) +{ + return data->page_order; +} + static struct page * perf_mmap_to_page(struct perf_mmap_data *data, unsigned long pgoff) { - if (pgoff > (1UL << data->data_order)) + if (pgoff > (1UL << page_order(data))) return NULL; return vmalloc_to_page((void *)data->user_page + pgoff * PAGE_SIZE); @@ -2426,7 +2430,7 @@ static void perf_mmap_data_free_work(struct work_struct *work) int i, nr; data = container_of(work, struct perf_mmap_data, work); - nr = 1 << data->data_order; + nr = 1 << page_order(data); base = data->user_page; for (i = 0; i < nr + 1; i++) @@ -2465,7 +2469,7 @@ perf_mmap_data_alloc(struct perf_event *event, int nr_pages) data->user_page = all_buf; data->data_pages[0] = all_buf + PAGE_SIZE; - data->data_order = ilog2(nr_pages); + data->page_order = ilog2(nr_pages); data->nr_pages = 1; return data; @@ -2479,6 +2483,11 @@ fail: #endif +static unsigned long perf_data_size(struct perf_mmap_data *data) +{ + return data->nr_pages << (PAGE_SHIFT + page_order(data)); +} + static int perf_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct perf_event *event = vma->vm_file->private_data; @@ -2979,10 +2988,12 @@ void perf_output_copy(struct perf_output_handle *handle, handle->addr += size; handle->size -= size; if (!handle->size) { + struct perf_mmap_data *data = handle->data; + handle->page++; - handle->page &= handle->data->nr_pages - 1; - handle->addr = handle->data->data_pages[handle->page]; - handle->size = PAGE_SIZE << handle->data->data_order; + handle->page &= data->nr_pages - 1; + handle->addr = data->data_pages[handle->page]; + handle->size = PAGE_SIZE << page_order(data); } } while (len); } @@ -3050,12 +3061,12 @@ int perf_output_begin(struct perf_output_handle *handle, if (head - local_read(&data->wakeup) > data->watermark) local_add(data->watermark, &data->wakeup); - handle->page = handle->offset >> (PAGE_SHIFT + data->data_order); + handle->page = handle->offset >> (PAGE_SHIFT + page_order(data)); handle->page &= data->nr_pages - 1; - handle->size = handle->offset & ((PAGE_SIZE << data->data_order) - 1); + handle->size = handle->offset & ((PAGE_SIZE << page_order(data)) - 1); handle->addr = data->data_pages[handle->page]; handle->addr += handle->size; - handle->size = (PAGE_SIZE << data->data_order) - handle->size; + handle->size = (PAGE_SIZE << page_order(data)) - handle->size; if (have_lost) { lost_event.header.type = PERF_RECORD_LOST; -- 2.39.5