[wrecked] perf-allocate-mmap-buffer-using-vmalloc_user.patch removed from -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled
     perf: allocate mmap buffer using vmalloc_user()
has been removed from the -mm tree.  Its filename was
     perf-allocate-mmap-buffer-using-vmalloc_user.patch

This patch was dropped because other changes were merged, which wrecked this patch

The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/

------------------------------------------------------
Subject: perf: allocate mmap buffer using vmalloc_user()
From: David Miller <davem@xxxxxxxxxxxxx>

This is necessary to make the mmap ring buffer work properly on platforms
where D-cache aliasing is an issue.

vmalloc_user() ensures that the kernel side mapping is SHMLBA aligned, and
on platforms with D-cache aliasing matters the presence of VM_SHARED will
similarly SHMLBA align the user side mapping.

Thus the kernel and the user will be writing to the same D-cache aliases
and we'll avoid inconsistencies and corruption.

The only trick with this change is that vfree() cannot be invoked from
interrupt context, and thus it's not allowed from RCU callbacks.

We deal with this by using schedule_work().

Since the ring buffer is now completely linear even on the kernel side,
several simplifications are probably now possible in the code where we add
entries to the ring.

With help from Peter Zijlstra.

Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
Cc: Peter Zijlstra <a.p.zijlstra@xxxxxxxxx>
Cc: Jens Axboe <jens.axboe@xxxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxx>
Cc: Nick Piggin <nickpiggin@xxxxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

 include/linux/perf_counter.h |    1 
 kernel/perf_counter.c        |   72 +++++++++++++++++----------------
 2 files changed, 40 insertions(+), 33 deletions(-)

diff -puN include/linux/perf_counter.h~perf-allocate-mmap-buffer-using-vmalloc_user include/linux/perf_counter.h
--- a/include/linux/perf_counter.h~perf-allocate-mmap-buffer-using-vmalloc_user
+++ a/include/linux/perf_counter.h
@@ -507,6 +507,7 @@ struct file;
 
 struct perf_mmap_data {
 	struct rcu_head			rcu_head;
+	struct work_struct		work;
 	int				nr_pages;	/* nr of data pages  */
 	int				writable;	/* are we writable   */
 	int				nr_locked;	/* nr pages mlocked  */
diff -puN kernel/perf_counter.c~perf-allocate-mmap-buffer-using-vmalloc_user kernel/perf_counter.c
--- a/kernel/perf_counter.c~perf-allocate-mmap-buffer-using-vmalloc_user
+++ a/kernel/perf_counter.c
@@ -23,6 +23,7 @@
 #include <linux/hardirq.h>
 #include <linux/rculist.h>
 #include <linux/uaccess.h>
+#include <linux/vmalloc.h>
 #include <linux/syscalls.h>
 #include <linux/anon_inodes.h>
 #include <linux/kernel_stat.h>
@@ -2118,7 +2119,7 @@ static int perf_mmap_fault(struct vm_are
 		goto unlock;
 
 	if (vmf->pgoff == 0) {
-		vmf->page = virt_to_page(data->user_page);
+		vmf->page = vmalloc_to_page(data->user_page);
 	} else {
 		int nr = vmf->pgoff - 1;
 
@@ -2128,7 +2129,7 @@ static int perf_mmap_fault(struct vm_are
 		if (vmf->flags & FAULT_FLAG_WRITE)
 			goto unlock;
 
-		vmf->page = virt_to_page(data->data_pages[nr]);
+		vmf->page = vmalloc_to_page(data->data_pages[nr]);
 	}
 
 	get_page(vmf->page);
@@ -2142,10 +2143,34 @@ unlock:
 	return ret;
 }
 
+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);
+	kfree(data);
+}
+
 static int 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));
@@ -2157,15 +2182,16 @@ static int perf_mmap_data_alloc(struct p
 	if (!data)
 		goto fail;
 
-	data->user_page = (void *)get_zeroed_page(GFP_KERNEL);
-	if (!data->user_page)
-		goto fail_user_page;
-
-	for (i = 0; i < nr_pages; i++) {
-		data->data_pages[i] = (void *)get_zeroed_page(GFP_KERNEL);
-		if (!data->data_pages[i])
-			goto fail_data_pages;
-	}
+	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;
 	atomic_set(&data->lock, -1);
@@ -2174,39 +2200,19 @@ static int perf_mmap_data_alloc(struct p
 
 	return 0;
 
-fail_data_pages:
-	for (i--; i >= 0; i--)
-		free_page((unsigned long)data->data_pages[i]);
-
-	free_page((unsigned long)data->user_page);
-
-fail_user_page:
+fail_all_buf:
 	kfree(data);
 
 fail:
 	return -ENOMEM;
 }
 
-static void perf_mmap_free_page(unsigned long addr)
-{
-	struct page *page = virt_to_page((void *)addr);
-
-	page->mapping = NULL;
-	__free_page(page);
-}
-
 static void __perf_mmap_data_free(struct rcu_head *rcu_head)
 {
 	struct perf_mmap_data *data;
-	int i;
 
 	data = container_of(rcu_head, struct perf_mmap_data, rcu_head);
-
-	perf_mmap_free_page((unsigned long)data->user_page);
-	for (i = 0; i < data->nr_pages; i++)
-		perf_mmap_free_page((unsigned long)data->data_pages[i]);
-
-	kfree(data);
+	schedule_work(&data->work);
 }
 
 static void perf_mmap_data_free(struct perf_counter *counter)
_

Patches currently in -mm which might be from davem@xxxxxxxxxxxxx are

origin.patch
linux-next.patch
md-dm-log-fix-cn_ulog_callback-declaration.patch
ide-use-printk_once.patch
net-fix-config_net=n-build-on-sparc64.patch
sunrpc-use-formatting-of-module-name-in-sunrpc.patch
sparc32-convert-to-asm-generic-hardirqh.patch
fs-remove-unneeded-dcache_unhashed-tricks.patch
drivers-net-wireless-ath-ar9170-phyc-fix-uninitialised-variable.patch
arches-drop-superfluous-casts-in-nr_free_pages-callers.patch
mm-replace-various-uses-of-num_physpages-by-totalram_pages.patch
perf-allocate-mmap-buffer-using-vmalloc_user.patch
move-magic-numbers-into-magich.patch
proc-connector-add-event-for-process-becoming-session-leader.patch
build_bug_on-fix-it-and-a-couple-of-bogus-uses-of-it.patch
build_bug_on-fix-it-and-a-couple-of-bogus-uses-of-it-fix.patch
maintainers-add-ipvs-include-files.patch
scripts-get_maintainerpl-add-pattern-depth.patch
kprobes-use-do_irq-in-lkdtm.patch
sysctl-remove-struct-file-argument-of-proc_handler.patch
sound-core-pcm_timerc-use-lib-gcdc.patch
net-netfilter-ipvs-ip_vs_wrrc-use-lib-gcdc.patch
net-netfilter-ipvs-ip_vs_wrrc-use-lib-gcdc-fix.patch

--
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux