All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <20141002155348.GI2342@redhat.com>

diff --git a/a/1.txt b/N1/1.txt
index e8d6cdb..9767192 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -43,328 +43,3 @@ about to disappear.
 
 Thanks,
 Andrea
-
->From 2f6079396a59e64a380ff06e6107276dfa67b3ba Mon Sep 17 00:00:00 2001
-From: Andrea Arcangeli <aarcange@redhat.com>
-Date: Thu, 2 Oct 2014 16:58:00 +0200
-Subject: [PATCH] mm: gup: make get_user_pages_fast and __get_user_pages_fast
- latency conscious
-
-This teaches gup_fast and __gup_fast to re-enable irqs and
-cond_resched() if possible every BATCH_PAGES.
-
-Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
----
- arch/x86/mm/gup.c | 239 +++++++++++++++++++++++++++++++++++-------------------
- 1 file changed, 154 insertions(+), 85 deletions(-)
-
-diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c
-index 2ab183b..e05d7b0 100644
---- a/arch/x86/mm/gup.c
-+++ b/arch/x86/mm/gup.c
-@@ -12,6 +12,12 @@
- 
- #include <asm/pgtable.h>
- 
-+/*
-+ * Keep irq disabled for no more than BATCH_PAGES pages.
-+ * Matches PTRS_PER_PTE (or half in non-PAE kernels).
-+ */
-+#define BATCH_PAGES	512
-+
- static inline pte_t gup_get_pte(pte_t *ptep)
- {
- #ifndef CONFIG_X86_PAE
-@@ -250,6 +256,40 @@ static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end,
- 	return 1;
- }
- 
-+static inline int __get_user_pages_fast_batch(unsigned long start,
-+					      unsigned long end,
-+					      int write, struct page **pages)
-+{
-+	struct mm_struct *mm = current->mm;
-+	unsigned long next;
-+	unsigned long flags;
-+	pgd_t *pgdp;
-+	int nr = 0;
-+
-+	/*
-+	 * This doesn't prevent pagetable teardown, but does prevent
-+	 * the pagetables and pages from being freed on x86.
-+	 *
-+	 * So long as we atomically load page table pointers versus teardown
-+	 * (which we do on x86, with the above PAE exception), we can follow the
-+	 * address down to the the page and take a ref on it.
-+	 */
-+	local_irq_save(flags);
-+	pgdp = pgd_offset(mm, start);
-+	do {
-+		pgd_t pgd = *pgdp;
-+
-+		next = pgd_addr_end(start, end);
-+		if (pgd_none(pgd))
-+			break;
-+		if (!gup_pud_range(pgd, start, next, write, pages, &nr))
-+			break;
-+	} while (pgdp++, start = next, start != end);
-+	local_irq_restore(flags);
-+
-+	return nr;
-+}
-+
- /*
-  * Like get_user_pages_fast() except its IRQ-safe in that it won't fall
-  * back to the regular GUP.
-@@ -257,31 +297,57 @@ static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end,
- int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
- 			  struct page **pages)
- {
--	struct mm_struct *mm = current->mm;
--	unsigned long addr, len, end;
--	unsigned long next;
--	unsigned long flags;
--	pgd_t *pgdp;
--	int nr = 0;
-+	unsigned long len, end, batch_pages;
-+	int nr, ret;
- 
- 	start &= PAGE_MASK;
--	addr = start;
- 	len = (unsigned long) nr_pages << PAGE_SHIFT;
- 	end = start + len;
-+	/*
-+	 * get_user_pages() handles nr_pages == 0 gracefully, but
-+	 * gup_fast starts walking the first pagetable in a do {}
-+	 * while() fashion so it's not robust to handle nr_pages ==
-+	 * 0. There's no point in being permissive about end < start
-+	 * either. So this check verifies both nr_pages being non
-+	 * zero, and that "end" didn't overflow.
-+	 */
-+	VM_BUG_ON(end <= start);
- 	if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
- 					(void __user *)start, len)))
- 		return 0;
- 
--	/*
--	 * XXX: batch / limit 'nr', to avoid large irq off latency
--	 * needs some instrumenting to determine the common sizes used by
--	 * important workloads (eg. DB2), and whether limiting the batch size
--	 * will decrease performance.
--	 *
--	 * It seems like we're in the clear for the moment. Direct-IO is
--	 * the main guy that batches up lots of get_user_pages, and even
--	 * they are limited to 64-at-a-time which is not so many.
--	 */
-+	ret = 0;
-+	for (;;) {
-+		batch_pages = nr_pages;
-+		if (batch_pages > BATCH_PAGES && !irqs_disabled())
-+			batch_pages = BATCH_PAGES;
-+		len = (unsigned long) batch_pages << PAGE_SHIFT;
-+		end = start + len;
-+		nr = __get_user_pages_fast_batch(start, end, write, pages);
-+		VM_BUG_ON(nr > batch_pages);
-+		nr_pages -= nr;
-+		ret += nr;
-+		if (!nr_pages || nr != batch_pages)
-+			break;
-+		start += len;
-+		pages += batch_pages;
-+	}
-+
-+	return ret;
-+}
-+
-+static inline int get_user_pages_fast_batch(unsigned long start,
-+					    unsigned long end,
-+					    int write, struct page **pages)
-+{
-+	struct mm_struct *mm = current->mm;
-+	unsigned long next;
-+	pgd_t *pgdp;
-+	int nr = 0;
-+#ifdef CONFIG_DEBUG_VM
-+	unsigned long orig_start = start;
-+#endif
-+
- 	/*
- 	 * This doesn't prevent pagetable teardown, but does prevent
- 	 * the pagetables and pages from being freed on x86.
-@@ -290,18 +356,22 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
- 	 * (which we do on x86, with the above PAE exception), we can follow the
- 	 * address down to the the page and take a ref on it.
- 	 */
--	local_irq_save(flags);
--	pgdp = pgd_offset(mm, addr);
-+	local_irq_disable();
-+	pgdp = pgd_offset(mm, start);
- 	do {
- 		pgd_t pgd = *pgdp;
- 
--		next = pgd_addr_end(addr, end);
--		if (pgd_none(pgd))
-+		next = pgd_addr_end(start, end);
-+		if (pgd_none(pgd)) {
-+			VM_BUG_ON(nr >= (end-orig_start) >> PAGE_SHIFT);
- 			break;
--		if (!gup_pud_range(pgd, addr, next, write, pages, &nr))
-+		}
-+		if (!gup_pud_range(pgd, start, next, write, pages, &nr)) {
-+			VM_BUG_ON(nr >= (end-orig_start) >> PAGE_SHIFT);
- 			break;
--	} while (pgdp++, addr = next, addr != end);
--	local_irq_restore(flags);
-+		}
-+	} while (pgdp++, start = next, start != end);
-+	local_irq_enable();
- 
- 	return nr;
- }
-@@ -326,80 +396,79 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
- 			struct page **pages)
- {
- 	struct mm_struct *mm = current->mm;
--	unsigned long addr, len, end;
--	unsigned long next;
--	pgd_t *pgdp;
--	int nr = 0;
-+	unsigned long len, end, batch_pages;
-+	int nr, ret;
-+#ifdef CONFIG_DEBUG_VM
-+	unsigned long orig_start = start;
-+#endif
- 
- 	start &= PAGE_MASK;
--	addr = start;
-+#ifdef CONFIG_DEBUG_VM
-+	orig_start = start;
-+#endif
- 	len = (unsigned long) nr_pages << PAGE_SHIFT;
- 
- 	end = start + len;
--	if (end < start)
--		goto slow_irqon;
-+	/*
-+	 * get_user_pages() handles nr_pages == 0 gracefully, but
-+	 * gup_fast starts walking the first pagetable in a do {}
-+	 * while() fashion so it's not robust to handle nr_pages ==
-+	 * 0. There's no point in being permissive about end < start
-+	 * either. So this check verifies both nr_pages being non
-+	 * zero, and that "end" didn't overflow.
-+	 */
-+	VM_BUG_ON(end <= start);
- 
-+	nr = ret = 0;
- #ifdef CONFIG_X86_64
- 	if (end >> __VIRTUAL_MASK_SHIFT)
- 		goto slow_irqon;
- #endif
-+	for (;;) {
-+		cond_resched();
-+		batch_pages = min(nr_pages, BATCH_PAGES);
-+		len = (unsigned long) batch_pages << PAGE_SHIFT;
-+		end = start + len;
-+		nr = get_user_pages_fast_batch(start, end, write, pages);
-+		VM_BUG_ON(nr > batch_pages);
-+		nr_pages -= nr;
-+		ret += nr;
-+		if (!nr_pages)
-+			break;
-+		if (nr < batch_pages)
-+			goto slow_irqon;
-+		start += len;
-+		pages += batch_pages;
-+	}
- 
--	/*
--	 * XXX: batch / limit 'nr', to avoid large irq off latency
--	 * needs some instrumenting to determine the common sizes used by
--	 * important workloads (eg. DB2), and whether limiting the batch size
--	 * will decrease performance.
--	 *
--	 * It seems like we're in the clear for the moment. Direct-IO is
--	 * the main guy that batches up lots of get_user_pages, and even
--	 * they are limited to 64-at-a-time which is not so many.
--	 */
--	/*
--	 * This doesn't prevent pagetable teardown, but does prevent
--	 * the pagetables and pages from being freed on x86.
--	 *
--	 * So long as we atomically load page table pointers versus teardown
--	 * (which we do on x86, with the above PAE exception), we can follow the
--	 * address down to the the page and take a ref on it.
--	 */
--	local_irq_disable();
--	pgdp = pgd_offset(mm, addr);
--	do {
--		pgd_t pgd = *pgdp;
--
--		next = pgd_addr_end(addr, end);
--		if (pgd_none(pgd))
--			goto slow;
--		if (!gup_pud_range(pgd, addr, next, write, pages, &nr))
--			goto slow;
--	} while (pgdp++, addr = next, addr != end);
--	local_irq_enable();
--
--	VM_BUG_ON(nr != (end - start) >> PAGE_SHIFT);
--	return nr;
--
--	{
--		int ret;
-+	VM_BUG_ON(ret != (end - orig_start) >> PAGE_SHIFT);
-+	return ret;
- 
--slow:
--		local_irq_enable();
- slow_irqon:
--		/* Try to get the remaining pages with get_user_pages */
--		start += nr << PAGE_SHIFT;
--		pages += nr;
--
--		ret = get_user_pages_unlocked(current, mm, start,
--					      (end - start) >> PAGE_SHIFT,
--					      write, 0, pages);
--
--		/* Have to be a bit careful with return values */
--		if (nr > 0) {
--			if (ret < 0)
--				ret = nr;
--			else
--				ret += nr;
--		}
-+	/* Try to get the remaining pages with get_user_pages */
-+	start += nr << PAGE_SHIFT;
-+	pages += nr;
- 
--		return ret;
-+	/*
-+	 * "nr" was the get_user_pages_fast_batch last retval, "ret"
-+	 * was the sum of all get_user_pages_fast_batch retvals, now
-+	 * "nr" becomes the sum of all get_user_pages_fast_batch
-+	 * retvals and "ret" will become the get_user_pages_unlocked
-+	 * retval.
-+	 */
-+	nr = ret;
-+
-+	ret = get_user_pages_unlocked(current, mm, start,
-+				      (end - start) >> PAGE_SHIFT,
-+				      write, 0, pages);
-+
-+	/* Have to be a bit careful with return values */
-+	if (nr > 0) {
-+		if (ret < 0)
-+			ret = nr;
-+		else
-+			ret += nr;
- 	}
-+
-+	return ret;
- }
-
---
-To unsubscribe, send a message with 'unsubscribe linux-mm' in
-the body to majordomo@kvack.org.  For more info on Linux MM,
-see: http://www.linux-mm.org/ .
-Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
diff --git a/a/content_digest b/N1/content_digest
index ed74b20..33a8bef 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -70,331 +70,6 @@
  "about to disappear.\n"
  "\n"
  "Thanks,\n"
- "Andrea\n"
- "\n"
- ">From 2f6079396a59e64a380ff06e6107276dfa67b3ba Mon Sep 17 00:00:00 2001\n"
- "From: Andrea Arcangeli <aarcange@redhat.com>\n"
- "Date: Thu, 2 Oct 2014 16:58:00 +0200\n"
- "Subject: [PATCH] mm: gup: make get_user_pages_fast and __get_user_pages_fast\n"
- " latency conscious\n"
- "\n"
- "This teaches gup_fast and __gup_fast to re-enable irqs and\n"
- "cond_resched() if possible every BATCH_PAGES.\n"
- "\n"
- "Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>\n"
- "---\n"
- " arch/x86/mm/gup.c | 239 +++++++++++++++++++++++++++++++++++-------------------\n"
- " 1 file changed, 154 insertions(+), 85 deletions(-)\n"
- "\n"
- "diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c\n"
- "index 2ab183b..e05d7b0 100644\n"
- "--- a/arch/x86/mm/gup.c\n"
- "+++ b/arch/x86/mm/gup.c\n"
- "@@ -12,6 +12,12 @@\n"
- " \n"
- " #include <asm/pgtable.h>\n"
- " \n"
- "+/*\n"
- "+ * Keep irq disabled for no more than BATCH_PAGES pages.\n"
- "+ * Matches PTRS_PER_PTE (or half in non-PAE kernels).\n"
- "+ */\n"
- "+#define BATCH_PAGES\t512\n"
- "+\n"
- " static inline pte_t gup_get_pte(pte_t *ptep)\n"
- " {\n"
- " #ifndef CONFIG_X86_PAE\n"
- "@@ -250,6 +256,40 @@ static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end,\n"
- " \treturn 1;\n"
- " }\n"
- " \n"
- "+static inline int __get_user_pages_fast_batch(unsigned long start,\n"
- "+\t\t\t\t\t      unsigned long end,\n"
- "+\t\t\t\t\t      int write, struct page **pages)\n"
- "+{\n"
- "+\tstruct mm_struct *mm = current->mm;\n"
- "+\tunsigned long next;\n"
- "+\tunsigned long flags;\n"
- "+\tpgd_t *pgdp;\n"
- "+\tint nr = 0;\n"
- "+\n"
- "+\t/*\n"
- "+\t * This doesn't prevent pagetable teardown, but does prevent\n"
- "+\t * the pagetables and pages from being freed on x86.\n"
- "+\t *\n"
- "+\t * So long as we atomically load page table pointers versus teardown\n"
- "+\t * (which we do on x86, with the above PAE exception), we can follow the\n"
- "+\t * address down to the the page and take a ref on it.\n"
- "+\t */\n"
- "+\tlocal_irq_save(flags);\n"
- "+\tpgdp = pgd_offset(mm, start);\n"
- "+\tdo {\n"
- "+\t\tpgd_t pgd = *pgdp;\n"
- "+\n"
- "+\t\tnext = pgd_addr_end(start, end);\n"
- "+\t\tif (pgd_none(pgd))\n"
- "+\t\t\tbreak;\n"
- "+\t\tif (!gup_pud_range(pgd, start, next, write, pages, &nr))\n"
- "+\t\t\tbreak;\n"
- "+\t} while (pgdp++, start = next, start != end);\n"
- "+\tlocal_irq_restore(flags);\n"
- "+\n"
- "+\treturn nr;\n"
- "+}\n"
- "+\n"
- " /*\n"
- "  * Like get_user_pages_fast() except its IRQ-safe in that it won't fall\n"
- "  * back to the regular GUP.\n"
- "@@ -257,31 +297,57 @@ static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end,\n"
- " int __get_user_pages_fast(unsigned long start, int nr_pages, int write,\n"
- " \t\t\t  struct page **pages)\n"
- " {\n"
- "-\tstruct mm_struct *mm = current->mm;\n"
- "-\tunsigned long addr, len, end;\n"
- "-\tunsigned long next;\n"
- "-\tunsigned long flags;\n"
- "-\tpgd_t *pgdp;\n"
- "-\tint nr = 0;\n"
- "+\tunsigned long len, end, batch_pages;\n"
- "+\tint nr, ret;\n"
- " \n"
- " \tstart &= PAGE_MASK;\n"
- "-\taddr = start;\n"
- " \tlen = (unsigned long) nr_pages << PAGE_SHIFT;\n"
- " \tend = start + len;\n"
- "+\t/*\n"
- "+\t * get_user_pages() handles nr_pages == 0 gracefully, but\n"
- "+\t * gup_fast starts walking the first pagetable in a do {}\n"
- "+\t * while() fashion so it's not robust to handle nr_pages ==\n"
- "+\t * 0. There's no point in being permissive about end < start\n"
- "+\t * either. So this check verifies both nr_pages being non\n"
- "+\t * zero, and that \"end\" didn't overflow.\n"
- "+\t */\n"
- "+\tVM_BUG_ON(end <= start);\n"
- " \tif (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,\n"
- " \t\t\t\t\t(void __user *)start, len)))\n"
- " \t\treturn 0;\n"
- " \n"
- "-\t/*\n"
- "-\t * XXX: batch / limit 'nr', to avoid large irq off latency\n"
- "-\t * needs some instrumenting to determine the common sizes used by\n"
- "-\t * important workloads (eg. DB2), and whether limiting the batch size\n"
- "-\t * will decrease performance.\n"
- "-\t *\n"
- "-\t * It seems like we're in the clear for the moment. Direct-IO is\n"
- "-\t * the main guy that batches up lots of get_user_pages, and even\n"
- "-\t * they are limited to 64-at-a-time which is not so many.\n"
- "-\t */\n"
- "+\tret = 0;\n"
- "+\tfor (;;) {\n"
- "+\t\tbatch_pages = nr_pages;\n"
- "+\t\tif (batch_pages > BATCH_PAGES && !irqs_disabled())\n"
- "+\t\t\tbatch_pages = BATCH_PAGES;\n"
- "+\t\tlen = (unsigned long) batch_pages << PAGE_SHIFT;\n"
- "+\t\tend = start + len;\n"
- "+\t\tnr = __get_user_pages_fast_batch(start, end, write, pages);\n"
- "+\t\tVM_BUG_ON(nr > batch_pages);\n"
- "+\t\tnr_pages -= nr;\n"
- "+\t\tret += nr;\n"
- "+\t\tif (!nr_pages || nr != batch_pages)\n"
- "+\t\t\tbreak;\n"
- "+\t\tstart += len;\n"
- "+\t\tpages += batch_pages;\n"
- "+\t}\n"
- "+\n"
- "+\treturn ret;\n"
- "+}\n"
- "+\n"
- "+static inline int get_user_pages_fast_batch(unsigned long start,\n"
- "+\t\t\t\t\t    unsigned long end,\n"
- "+\t\t\t\t\t    int write, struct page **pages)\n"
- "+{\n"
- "+\tstruct mm_struct *mm = current->mm;\n"
- "+\tunsigned long next;\n"
- "+\tpgd_t *pgdp;\n"
- "+\tint nr = 0;\n"
- "+#ifdef CONFIG_DEBUG_VM\n"
- "+\tunsigned long orig_start = start;\n"
- "+#endif\n"
- "+\n"
- " \t/*\n"
- " \t * This doesn't prevent pagetable teardown, but does prevent\n"
- " \t * the pagetables and pages from being freed on x86.\n"
- "@@ -290,18 +356,22 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,\n"
- " \t * (which we do on x86, with the above PAE exception), we can follow the\n"
- " \t * address down to the the page and take a ref on it.\n"
- " \t */\n"
- "-\tlocal_irq_save(flags);\n"
- "-\tpgdp = pgd_offset(mm, addr);\n"
- "+\tlocal_irq_disable();\n"
- "+\tpgdp = pgd_offset(mm, start);\n"
- " \tdo {\n"
- " \t\tpgd_t pgd = *pgdp;\n"
- " \n"
- "-\t\tnext = pgd_addr_end(addr, end);\n"
- "-\t\tif (pgd_none(pgd))\n"
- "+\t\tnext = pgd_addr_end(start, end);\n"
- "+\t\tif (pgd_none(pgd)) {\n"
- "+\t\t\tVM_BUG_ON(nr >= (end-orig_start) >> PAGE_SHIFT);\n"
- " \t\t\tbreak;\n"
- "-\t\tif (!gup_pud_range(pgd, addr, next, write, pages, &nr))\n"
- "+\t\t}\n"
- "+\t\tif (!gup_pud_range(pgd, start, next, write, pages, &nr)) {\n"
- "+\t\t\tVM_BUG_ON(nr >= (end-orig_start) >> PAGE_SHIFT);\n"
- " \t\t\tbreak;\n"
- "-\t} while (pgdp++, addr = next, addr != end);\n"
- "-\tlocal_irq_restore(flags);\n"
- "+\t\t}\n"
- "+\t} while (pgdp++, start = next, start != end);\n"
- "+\tlocal_irq_enable();\n"
- " \n"
- " \treturn nr;\n"
- " }\n"
- "@@ -326,80 +396,79 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,\n"
- " \t\t\tstruct page **pages)\n"
- " {\n"
- " \tstruct mm_struct *mm = current->mm;\n"
- "-\tunsigned long addr, len, end;\n"
- "-\tunsigned long next;\n"
- "-\tpgd_t *pgdp;\n"
- "-\tint nr = 0;\n"
- "+\tunsigned long len, end, batch_pages;\n"
- "+\tint nr, ret;\n"
- "+#ifdef CONFIG_DEBUG_VM\n"
- "+\tunsigned long orig_start = start;\n"
- "+#endif\n"
- " \n"
- " \tstart &= PAGE_MASK;\n"
- "-\taddr = start;\n"
- "+#ifdef CONFIG_DEBUG_VM\n"
- "+\torig_start = start;\n"
- "+#endif\n"
- " \tlen = (unsigned long) nr_pages << PAGE_SHIFT;\n"
- " \n"
- " \tend = start + len;\n"
- "-\tif (end < start)\n"
- "-\t\tgoto slow_irqon;\n"
- "+\t/*\n"
- "+\t * get_user_pages() handles nr_pages == 0 gracefully, but\n"
- "+\t * gup_fast starts walking the first pagetable in a do {}\n"
- "+\t * while() fashion so it's not robust to handle nr_pages ==\n"
- "+\t * 0. There's no point in being permissive about end < start\n"
- "+\t * either. So this check verifies both nr_pages being non\n"
- "+\t * zero, and that \"end\" didn't overflow.\n"
- "+\t */\n"
- "+\tVM_BUG_ON(end <= start);\n"
- " \n"
- "+\tnr = ret = 0;\n"
- " #ifdef CONFIG_X86_64\n"
- " \tif (end >> __VIRTUAL_MASK_SHIFT)\n"
- " \t\tgoto slow_irqon;\n"
- " #endif\n"
- "+\tfor (;;) {\n"
- "+\t\tcond_resched();\n"
- "+\t\tbatch_pages = min(nr_pages, BATCH_PAGES);\n"
- "+\t\tlen = (unsigned long) batch_pages << PAGE_SHIFT;\n"
- "+\t\tend = start + len;\n"
- "+\t\tnr = get_user_pages_fast_batch(start, end, write, pages);\n"
- "+\t\tVM_BUG_ON(nr > batch_pages);\n"
- "+\t\tnr_pages -= nr;\n"
- "+\t\tret += nr;\n"
- "+\t\tif (!nr_pages)\n"
- "+\t\t\tbreak;\n"
- "+\t\tif (nr < batch_pages)\n"
- "+\t\t\tgoto slow_irqon;\n"
- "+\t\tstart += len;\n"
- "+\t\tpages += batch_pages;\n"
- "+\t}\n"
- " \n"
- "-\t/*\n"
- "-\t * XXX: batch / limit 'nr', to avoid large irq off latency\n"
- "-\t * needs some instrumenting to determine the common sizes used by\n"
- "-\t * important workloads (eg. DB2), and whether limiting the batch size\n"
- "-\t * will decrease performance.\n"
- "-\t *\n"
- "-\t * It seems like we're in the clear for the moment. Direct-IO is\n"
- "-\t * the main guy that batches up lots of get_user_pages, and even\n"
- "-\t * they are limited to 64-at-a-time which is not so many.\n"
- "-\t */\n"
- "-\t/*\n"
- "-\t * This doesn't prevent pagetable teardown, but does prevent\n"
- "-\t * the pagetables and pages from being freed on x86.\n"
- "-\t *\n"
- "-\t * So long as we atomically load page table pointers versus teardown\n"
- "-\t * (which we do on x86, with the above PAE exception), we can follow the\n"
- "-\t * address down to the the page and take a ref on it.\n"
- "-\t */\n"
- "-\tlocal_irq_disable();\n"
- "-\tpgdp = pgd_offset(mm, addr);\n"
- "-\tdo {\n"
- "-\t\tpgd_t pgd = *pgdp;\n"
- "-\n"
- "-\t\tnext = pgd_addr_end(addr, end);\n"
- "-\t\tif (pgd_none(pgd))\n"
- "-\t\t\tgoto slow;\n"
- "-\t\tif (!gup_pud_range(pgd, addr, next, write, pages, &nr))\n"
- "-\t\t\tgoto slow;\n"
- "-\t} while (pgdp++, addr = next, addr != end);\n"
- "-\tlocal_irq_enable();\n"
- "-\n"
- "-\tVM_BUG_ON(nr != (end - start) >> PAGE_SHIFT);\n"
- "-\treturn nr;\n"
- "-\n"
- "-\t{\n"
- "-\t\tint ret;\n"
- "+\tVM_BUG_ON(ret != (end - orig_start) >> PAGE_SHIFT);\n"
- "+\treturn ret;\n"
- " \n"
- "-slow:\n"
- "-\t\tlocal_irq_enable();\n"
- " slow_irqon:\n"
- "-\t\t/* Try to get the remaining pages with get_user_pages */\n"
- "-\t\tstart += nr << PAGE_SHIFT;\n"
- "-\t\tpages += nr;\n"
- "-\n"
- "-\t\tret = get_user_pages_unlocked(current, mm, start,\n"
- "-\t\t\t\t\t      (end - start) >> PAGE_SHIFT,\n"
- "-\t\t\t\t\t      write, 0, pages);\n"
- "-\n"
- "-\t\t/* Have to be a bit careful with return values */\n"
- "-\t\tif (nr > 0) {\n"
- "-\t\t\tif (ret < 0)\n"
- "-\t\t\t\tret = nr;\n"
- "-\t\t\telse\n"
- "-\t\t\t\tret += nr;\n"
- "-\t\t}\n"
- "+\t/* Try to get the remaining pages with get_user_pages */\n"
- "+\tstart += nr << PAGE_SHIFT;\n"
- "+\tpages += nr;\n"
- " \n"
- "-\t\treturn ret;\n"
- "+\t/*\n"
- "+\t * \"nr\" was the get_user_pages_fast_batch last retval, \"ret\"\n"
- "+\t * was the sum of all get_user_pages_fast_batch retvals, now\n"
- "+\t * \"nr\" becomes the sum of all get_user_pages_fast_batch\n"
- "+\t * retvals and \"ret\" will become the get_user_pages_unlocked\n"
- "+\t * retval.\n"
- "+\t */\n"
- "+\tnr = ret;\n"
- "+\n"
- "+\tret = get_user_pages_unlocked(current, mm, start,\n"
- "+\t\t\t\t      (end - start) >> PAGE_SHIFT,\n"
- "+\t\t\t\t      write, 0, pages);\n"
- "+\n"
- "+\t/* Have to be a bit careful with return values */\n"
- "+\tif (nr > 0) {\n"
- "+\t\tif (ret < 0)\n"
- "+\t\t\tret = nr;\n"
- "+\t\telse\n"
- "+\t\t\tret += nr;\n"
- " \t}\n"
- "+\n"
- "+\treturn ret;\n"
- " }\n"
- "\n"
- "--\n"
- "To unsubscribe, send a message with 'unsubscribe linux-mm' in\n"
- "the body to majordomo@kvack.org.  For more info on Linux MM,\n"
- "see: http://www.linux-mm.org/ .\n"
- "Don't email: <a href=mailto:\"dont@kvack.org\"> email@kvack.org </a>"
+ Andrea
 
-9c8d38e97c659b193063ff363652d0ab020bd8ffb60d343e4dfe70e410977d47
+49f15ad52f3d0542bfdeee5dca9e4f43db285f80b1b50545c315a1a3ea1b5c9a

diff --git a/a/1.txt b/N2/1.txt
index e8d6cdb..488861a 100644
--- a/a/1.txt
+++ b/N2/1.txt
@@ -362,9 +362,3 @@ index 2ab183b..e05d7b0 100644
 +
 +	return ret;
  }
-
---
-To unsubscribe, send a message with 'unsubscribe linux-mm' in
-the body to majordomo@kvack.org.  For more info on Linux MM,
-see: http://www.linux-mm.org/ .
-Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
diff --git a/a/content_digest b/N2/content_digest
index ed74b20..8c6a778 100644
--- a/a/content_digest
+++ b/N2/content_digest
@@ -389,12 +389,6 @@
  " \t}\n"
  "+\n"
  "+\treturn ret;\n"
- " }\n"
- "\n"
- "--\n"
- "To unsubscribe, send a message with 'unsubscribe linux-mm' in\n"
- "the body to majordomo@kvack.org.  For more info on Linux MM,\n"
- "see: http://www.linux-mm.org/ .\n"
- "Don't email: <a href=mailto:\"dont@kvack.org\"> email@kvack.org </a>"
+  }
 
-9c8d38e97c659b193063ff363652d0ab020bd8ffb60d343e4dfe70e410977d47
+29e109afadb6afc3b4558315d4ed3889221b425a64b4ef342255bb7f21a46c5f

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.