Implement vmalloc() backed storage for perf_mmap(). Alternatively we could put this code in kernel/perf_counter_vmalloc.c and conditionally compile that or something, since there really isn't anything Sparc specific about it. Suggested-by: David Miller Signed-off-by: Peter Zijlstra LKML-Reference: --- arch/sparc/kernel/perf_counter.c | 72 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) Index: linux-2.6/arch/sparc/kernel/perf_counter.c =================================================================== --- linux-2.6.orig/arch/sparc/kernel/perf_counter.c +++ linux-2.6/arch/sparc/kernel/perf_counter.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -554,3 +555,74 @@ void __init init_hw_perf_counters(void) register_die_notifier(&perf_counter_nmi_notifier); } + +struct page *perf_mmap_to_page(void *addr) +{ + return vmalloc_to_page(addr); +} + +static void perf_mmap_unmark_page(void *addr) +{ + struct page *page = vmalloc_to_page(addr); + + page->mapping = NULL; +} + +static void perf_mmap_data_free_work(struct work_struct *work) +{ + struct perf_mmap_data *data; + void *base; + int i; + + data = container_of(work, struct perf_mmap_data, work); + + base = data->user_page; + for (i = 0; i < data->nr_pages + 1; i++) + perf_mmap_unmark_page(base + (i * PAGE_SIZE)); + + vfree(base); +} + +void perf_mmap_data_free(struct perf_mmap_data *data) +{ + schedule_work(&data->work); +} + +struct perf_mmap_data * +perf_mmap_data_alloc(struct perf_counter *counter, int nr_pages) +{ + struct perf_mmap_data *data; + unsigned long size; + void *all_buf; + int i; + + WARN_ON(atomic_read(&counter->mmap_count)); + + size = sizeof(struct perf_mmap_data); + size += nr_pages * sizeof(void *); + + data = kzalloc(size, GFP_KERNEL); + if (!data) + goto fail; + + INIT_WORK(&data->work, perf_mmap_data_free_work); + + all_buf = vmalloc_user((nr_pages + 1) * PAGE_SIZE); + if (!all_buf) + goto fail_all_buf; + + data->user_page = all_buf; + + for (i = 0; i < nr_pages; i++) + data->data_pages[i] = all_buf + ((i + 1) * PAGE_SIZE); + + data->nr_pages = nr_pages; + + return data; + +fail_all_buf: + kfree(data); + +fail: + return NULL; +} -- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/