Generic Linux architectural discussions
 help / color / mirror / Atom feed
diff for duplicates of <20180914122824.181d9778@mschwideX1>

diff --git a/a/1.txt b/N1/1.txt
index 1ed65f3..2343790 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -34,470 +34,3 @@ this is TLB flushing there probably is some subtle problem left..
 
 Here we go:
 --
-From f222a7e40427b625700f2ca0919c32f07931c19a Mon Sep 17 00:00:00 2001
-From: Martin Schwidefsky <schwidefsky@de.ibm.com>
-Date: Fri, 14 Sep 2018 10:50:58 +0200
-Subject: [PATCH] s390/tlb: convert s390 to generic mmu_gather
-
-Introduce HAVE_RCU_NO_GATHER_PAGES to allow the arch code to disable
-page gathering in the generic mmu_gather code, then enable the generic
-mmu_gather code for s390.
-
-Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
----
- arch/Kconfig                |   3 +
- arch/s390/Kconfig           |   3 +
- arch/s390/include/asm/tlb.h | 131 ++++++++++++++------------------------------
- arch/s390/mm/pgalloc.c      |  63 +--------------------
- include/asm-generic/tlb.h   |   7 +++
- mm/mmu_gather.c             |  18 +++++-
- 6 files changed, 72 insertions(+), 153 deletions(-)
-
-diff --git a/arch/Kconfig b/arch/Kconfig
-index 053c44703539..9b257929a7c1 100644
---- a/arch/Kconfig
-+++ b/arch/Kconfig
-@@ -359,6 +359,9 @@ config HAVE_PERF_USER_STACK_DUMP
- config HAVE_ARCH_JUMP_LABEL
- 	bool
- 
-+config HAVE_RCU_NO_GATHER_PAGES
-+	bool
-+
- config HAVE_RCU_TABLE_FREE
- 	bool
- 
-diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
-index 9a9c7a6fe925..521457e3c5e4 100644
---- a/arch/s390/Kconfig
-+++ b/arch/s390/Kconfig
-@@ -161,6 +161,9 @@ config S390
- 	select HAVE_NOP_MCOUNT
- 	select HAVE_OPROFILE
- 	select HAVE_PERF_EVENTS
-+	select HAVE_RCU_NO_GATHER_PAGES
-+	select HAVE_RCU_TABLE_FREE
-+	select HAVE_RCU_TABLE_INVALIDATE
- 	select HAVE_REGS_AND_STACK_ACCESS_API
- 	select HAVE_RSEQ
- 	select HAVE_SYSCALL_TRACEPOINTS
-diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h
-index cf3d64313740..8073ff272b2b 100644
---- a/arch/s390/include/asm/tlb.h
-+++ b/arch/s390/include/asm/tlb.h
-@@ -22,98 +22,40 @@
-  * Pages used for the page tables is a different story. FIXME: more
-  */
- 
--#include <linux/mm.h>
--#include <linux/pagemap.h>
--#include <linux/swap.h>
--#include <asm/processor.h>
--#include <asm/pgalloc.h>
--#include <asm/tlbflush.h>
--
--struct mmu_gather {
--	struct mm_struct *mm;
--	struct mmu_table_batch *batch;
--	unsigned int fullmm;
--	unsigned long start, end;
--};
--
--struct mmu_table_batch {
--	struct rcu_head		rcu;
--	unsigned int		nr;
--	void			*tables[0];
--};
--
--#define MAX_TABLE_BATCH		\
--	((PAGE_SIZE - sizeof(struct mmu_table_batch)) / sizeof(void *))
--
--extern void tlb_table_flush(struct mmu_gather *tlb);
--extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
--
--static inline void
--arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
--			unsigned long start, unsigned long end)
--{
--	tlb->mm = mm;
--	tlb->start = start;
--	tlb->end = end;
--	tlb->fullmm = !(start | (end+1));
--	tlb->batch = NULL;
--}
--
--static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb)
--{
--	__tlb_flush_mm_lazy(tlb->mm);
--}
--
--static inline void tlb_flush_mmu_free(struct mmu_gather *tlb)
--{
--	tlb_table_flush(tlb);
--}
--
-+void __tlb_remove_table(void *_table);
-+static inline void tlb_flush(struct mmu_gather *tlb);
-+static inline bool __tlb_remove_page_size(struct mmu_gather *tlb,
-+					  struct page *page, int page_size);
- 
--static inline void tlb_flush_mmu(struct mmu_gather *tlb)
--{
--	tlb_flush_mmu_tlbonly(tlb);
--	tlb_flush_mmu_free(tlb);
--}
-+#define tlb_start_vma(tlb, vma)			do { } while (0)
-+#define tlb_end_vma(tlb, vma)			do { } while (0)
-+#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
- 
--static inline void
--arch_tlb_finish_mmu(struct mmu_gather *tlb,
--		unsigned long start, unsigned long end, bool force)
--{
--	if (force) {
--		tlb->start = start;
--		tlb->end = end;
--	}
-+#define tlb_flush tlb_flush
-+#define pte_free_tlb pte_free_tlb
-+#define pmd_free_tlb pmd_free_tlb
-+#define p4d_free_tlb p4d_free_tlb
-+#define pud_free_tlb pud_free_tlb
- 
--	tlb_flush_mmu(tlb);
--}
-+#include <asm/pgalloc.h>
-+#include <asm/tlbflush.h>
-+#include <asm-generic/tlb.h>
- 
- /*
-  * Release the page cache reference for a pte removed by
-  * tlb_ptep_clear_flush. In both flush modes the tlb for a page cache page
-  * has already been freed, so just do free_page_and_swap_cache.
-  */
--static inline bool __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
--{
--	free_page_and_swap_cache(page);
--	return false; /* avoid calling tlb_flush_mmu */
--}
--
--static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
--{
--	free_page_and_swap_cache(page);
--}
--
- static inline bool __tlb_remove_page_size(struct mmu_gather *tlb,
- 					  struct page *page, int page_size)
- {
--	return __tlb_remove_page(tlb, page);
-+	free_page_and_swap_cache(page);
-+	return false;
- }
- 
--static inline void tlb_remove_page_size(struct mmu_gather *tlb,
--					struct page *page, int page_size)
-+static inline void tlb_flush(struct mmu_gather *tlb)
- {
--	return tlb_remove_page(tlb, page);
-+	__tlb_flush_mm_lazy(tlb->mm);
- }
- 
- /*
-@@ -121,9 +63,18 @@ static inline void tlb_remove_page_size(struct mmu_gather *tlb,
-  * page table from the tlb.
-  */
- static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
--				unsigned long address)
-+                                unsigned long address)
- {
--	page_table_free_rcu(tlb, (unsigned long *) pte, address);
-+	__tlb_adjust_range(tlb, address, PAGE_SIZE);
-+	tlb->mm->context.flush_mm = 1;
-+	tlb->freed_tables = 1;
-+	tlb->cleared_ptes = 1;
-+	/*
-+	 * page_table_free_rcu takes care of the allocation bit masks
-+	 * of the 2K table fragments in the 4K page table page,
-+	 * then calls tlb_remove_table.
-+	 */
-+        page_table_free_rcu(tlb, (unsigned long *) pte, address);
- }
- 
- /*
-@@ -139,6 +90,10 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
- 	if (tlb->mm->context.asce_limit <= _REGION3_SIZE)
- 		return;
- 	pgtable_pmd_page_dtor(virt_to_page(pmd));
-+	__tlb_adjust_range(tlb, address, PAGE_SIZE);
-+	tlb->mm->context.flush_mm = 1;
-+	tlb->freed_tables = 1;
-+	tlb->cleared_puds = 1;
- 	tlb_remove_table(tlb, pmd);
- }
- 
-@@ -154,6 +109,10 @@ static inline void p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d,
- {
- 	if (tlb->mm->context.asce_limit <= _REGION1_SIZE)
- 		return;
-+	__tlb_adjust_range(tlb, address, PAGE_SIZE);
-+	tlb->mm->context.flush_mm = 1;
-+	tlb->freed_tables = 1;
-+	tlb->cleared_p4ds = 1;
- 	tlb_remove_table(tlb, p4d);
- }
- 
-@@ -169,19 +128,11 @@ static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
- {
- 	if (tlb->mm->context.asce_limit <= _REGION2_SIZE)
- 		return;
-+	tlb->mm->context.flush_mm = 1;
-+	tlb->freed_tables = 1;
-+	tlb->cleared_puds = 1;
- 	tlb_remove_table(tlb, pud);
- }
- 
--#define tlb_start_vma(tlb, vma)			do { } while (0)
--#define tlb_end_vma(tlb, vma)			do { } while (0)
--#define tlb_remove_tlb_entry(tlb, ptep, addr)	do { } while (0)
--#define tlb_remove_pmd_tlb_entry(tlb, pmdp, addr)	do { } while (0)
--#define tlb_migrate_finish(mm)			do { } while (0)
--#define tlb_remove_huge_tlb_entry(h, tlb, ptep, address)	\
--	tlb_remove_tlb_entry(tlb, ptep, address)
--
--static inline void tlb_change_page_size(struct mmu_gather *tlb, unsigned int page_size)
--{
--}
- 
- #endif /* _S390_TLB_H */
-diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c
-index 76d89ee8b428..f7656a0b3a1a 100644
---- a/arch/s390/mm/pgalloc.c
-+++ b/arch/s390/mm/pgalloc.c
-@@ -288,7 +288,7 @@ void page_table_free_rcu(struct mmu_gather *tlb, unsigned long *table,
- 	tlb_remove_table(tlb, table);
- }
- 
--static void __tlb_remove_table(void *_table)
-+void __tlb_remove_table(void *_table)
- {
- 	unsigned int mask = (unsigned long) _table & 3;
- 	void *table = (void *)((unsigned long) _table ^ mask);
-@@ -314,67 +314,6 @@ static void __tlb_remove_table(void *_table)
- 	}
- }
- 
--static void tlb_remove_table_smp_sync(void *arg)
--{
--	/* Simply deliver the interrupt */
--}
--
--static void tlb_remove_table_one(void *table)
--{
--	/*
--	 * This isn't an RCU grace period and hence the page-tables cannot be
--	 * assumed to be actually RCU-freed.
--	 *
--	 * It is however sufficient for software page-table walkers that rely
--	 * on IRQ disabling. See the comment near struct mmu_table_batch.
--	 */
--	smp_call_function(tlb_remove_table_smp_sync, NULL, 1);
--	__tlb_remove_table(table);
--}
--
--static void tlb_remove_table_rcu(struct rcu_head *head)
--{
--	struct mmu_table_batch *batch;
--	int i;
--
--	batch = container_of(head, struct mmu_table_batch, rcu);
--
--	for (i = 0; i < batch->nr; i++)
--		__tlb_remove_table(batch->tables[i]);
--
--	free_page((unsigned long)batch);
--}
--
--void tlb_table_flush(struct mmu_gather *tlb)
--{
--	struct mmu_table_batch **batch = &tlb->batch;
--
--	if (*batch) {
--		call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu);
--		*batch = NULL;
--	}
--}
--
--void tlb_remove_table(struct mmu_gather *tlb, void *table)
--{
--	struct mmu_table_batch **batch = &tlb->batch;
--
--	tlb->mm->context.flush_mm = 1;
--	if (*batch == NULL) {
--		*batch = (struct mmu_table_batch *)
--			__get_free_page(GFP_NOWAIT | __GFP_NOWARN);
--		if (*batch == NULL) {
--			__tlb_flush_mm_lazy(tlb->mm);
--			tlb_remove_table_one(table);
--			return;
--		}
--		(*batch)->nr = 0;
--	}
--	(*batch)->tables[(*batch)->nr++] = table;
--	if ((*batch)->nr == MAX_TABLE_BATCH)
--		tlb_flush_mmu(tlb);
--}
--
- /*
-  * Base infrastructure required to generate basic asces, region, segment,
-  * and page tables that do not make use of enhanced features like EDAT1.
-diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
-index 21c751cd751e..930e25abf4de 100644
---- a/include/asm-generic/tlb.h
-+++ b/include/asm-generic/tlb.h
-@@ -179,6 +179,7 @@ extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
- 
- #endif
- 
-+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES
- /*
-  * If we can't allocate a page to make a big batch of page pointers
-  * to work on, then just handle a few from the on-stack structure.
-@@ -203,6 +204,8 @@ struct mmu_gather_batch {
-  */
- #define MAX_GATHER_BATCH_COUNT	(10000UL/MAX_GATHER_BATCH)
- 
-+#endif
-+
- /*
-  * struct mmu_gather is an opaque type used by the mm code for passing around
-  * any data needed by arch specific code for tlb_remove_page.
-@@ -249,6 +252,7 @@ struct mmu_gather {
- 
- 	unsigned int		batch_count;
- 
-+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES
- 	struct mmu_gather_batch *active;
- 	struct mmu_gather_batch	local;
- 	struct page		*__pages[MMU_GATHER_BUNDLE];
-@@ -256,6 +260,7 @@ struct mmu_gather {
- #ifdef CONFIG_HAVE_MMU_GATHER_PAGE_SIZE
- 	unsigned int page_size;
- #endif
-+#endif
- };
- 
- void arch_tlb_gather_mmu(struct mmu_gather *tlb,
-@@ -264,8 +269,10 @@ void tlb_flush_mmu(struct mmu_gather *tlb);
- void arch_tlb_finish_mmu(struct mmu_gather *tlb,
- 			 unsigned long start, unsigned long end, bool force);
- void tlb_flush_mmu_free(struct mmu_gather *tlb);
-+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES
- extern bool __tlb_remove_page_size(struct mmu_gather *tlb, struct page *page,
- 				   int page_size);
-+#endif
- 
- static inline void __tlb_adjust_range(struct mmu_gather *tlb,
- 				      unsigned long address,
-diff --git a/mm/mmu_gather.c b/mm/mmu_gather.c
-index 2d5e617131f6..d3d2763d91b2 100644
---- a/mm/mmu_gather.c
-+++ b/mm/mmu_gather.c
-@@ -13,6 +13,8 @@
- 
- #ifdef HAVE_GENERIC_MMU_GATHER
- 
-+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES
-+
- static bool tlb_next_batch(struct mmu_gather *tlb)
- {
- 	struct mmu_gather_batch *batch;
-@@ -41,6 +43,8 @@ static bool tlb_next_batch(struct mmu_gather *tlb)
- 	return true;
- }
- 
-+#endif
-+
- void arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
- 				unsigned long start, unsigned long end)
- {
-@@ -49,12 +53,14 @@ void arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
- 	/* Is it from 0 to ~0? */
- 	tlb->fullmm     = !(start | (end+1));
- 	tlb->need_flush_all = 0;
-+
-+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES
- 	tlb->local.next = NULL;
- 	tlb->local.nr   = 0;
- 	tlb->local.max  = ARRAY_SIZE(tlb->__pages);
- 	tlb->active     = &tlb->local;
- 	tlb->batch_count = 0;
--
-+#endif
- #ifdef CONFIG_HAVE_RCU_TABLE_FREE
- 	tlb->batch = NULL;
- #endif
-@@ -67,16 +73,20 @@ void arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
- 
- void tlb_flush_mmu_free(struct mmu_gather *tlb)
- {
-+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES
- 	struct mmu_gather_batch *batch;
-+#endif
- 
- #ifdef CONFIG_HAVE_RCU_TABLE_FREE
- 	tlb_table_flush(tlb);
- #endif
-+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES
- 	for (batch = &tlb->local; batch && batch->nr; batch = batch->next) {
- 		free_pages_and_swap_cache(batch->pages, batch->nr);
- 		batch->nr = 0;
- 	}
- 	tlb->active = &tlb->local;
-+#endif
- }
- 
- void tlb_flush_mmu(struct mmu_gather *tlb)
-@@ -92,7 +102,9 @@ void tlb_flush_mmu(struct mmu_gather *tlb)
- void arch_tlb_finish_mmu(struct mmu_gather *tlb,
- 		unsigned long start, unsigned long end, bool force)
- {
-+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES
- 	struct mmu_gather_batch *batch, *next;
-+#endif
- 
- 	if (force) {
- 		__tlb_reset_range(tlb);
-@@ -104,13 +116,16 @@ void arch_tlb_finish_mmu(struct mmu_gather *tlb,
- 	/* keep the page table cache within bounds */
- 	check_pgt_cache();
- 
-+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES
- 	for (batch = tlb->local.next; batch; batch = next) {
- 		next = batch->next;
- 		free_pages((unsigned long)batch, 0);
- 	}
- 	tlb->local.next = NULL;
-+#endif
- }
- 
-+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES
- /* __tlb_remove_page
-  *	Must perform the equivalent to __free_pte(pte_get_and_clear(ptep)), while
-  *	handling the additional races in SMP caused by other CPUs caching valid
-@@ -143,6 +158,7 @@ bool __tlb_remove_page_size(struct mmu_gather *tlb, struct page *page, int page_
- 
- 	return false;
- }
-+#endif
- 
- #endif /* HAVE_GENERIC_MMU_GATHER */
- 
--- 
-2.16.4
-
-
--- 
-blue skies,
-   Martin.
-
-"Reality continues to ruin my life." - Calvin.
diff --git a/a/content_digest b/N1/content_digest
index 9d30206..e41526d 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -54,473 +54,6 @@
  "this is TLB flushing there probably is some subtle problem left..\n"
  "\n"
  "Here we go:\n"
- "--\n"
- "From f222a7e40427b625700f2ca0919c32f07931c19a Mon Sep 17 00:00:00 2001\n"
- "From: Martin Schwidefsky <schwidefsky@de.ibm.com>\n"
- "Date: Fri, 14 Sep 2018 10:50:58 +0200\n"
- "Subject: [PATCH] s390/tlb: convert s390 to generic mmu_gather\n"
- "\n"
- "Introduce HAVE_RCU_NO_GATHER_PAGES to allow the arch code to disable\n"
- "page gathering in the generic mmu_gather code, then enable the generic\n"
- "mmu_gather code for s390.\n"
- "\n"
- "Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>\n"
- "---\n"
- " arch/Kconfig                |   3 +\n"
- " arch/s390/Kconfig           |   3 +\n"
- " arch/s390/include/asm/tlb.h | 131 ++++++++++++++------------------------------\n"
- " arch/s390/mm/pgalloc.c      |  63 +--------------------\n"
- " include/asm-generic/tlb.h   |   7 +++\n"
- " mm/mmu_gather.c             |  18 +++++-\n"
- " 6 files changed, 72 insertions(+), 153 deletions(-)\n"
- "\n"
- "diff --git a/arch/Kconfig b/arch/Kconfig\n"
- "index 053c44703539..9b257929a7c1 100644\n"
- "--- a/arch/Kconfig\n"
- "+++ b/arch/Kconfig\n"
- "@@ -359,6 +359,9 @@ config HAVE_PERF_USER_STACK_DUMP\n"
- " config HAVE_ARCH_JUMP_LABEL\n"
- " \tbool\n"
- " \n"
- "+config HAVE_RCU_NO_GATHER_PAGES\n"
- "+\tbool\n"
- "+\n"
- " config HAVE_RCU_TABLE_FREE\n"
- " \tbool\n"
- " \n"
- "diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig\n"
- "index 9a9c7a6fe925..521457e3c5e4 100644\n"
- "--- a/arch/s390/Kconfig\n"
- "+++ b/arch/s390/Kconfig\n"
- "@@ -161,6 +161,9 @@ config S390\n"
- " \tselect HAVE_NOP_MCOUNT\n"
- " \tselect HAVE_OPROFILE\n"
- " \tselect HAVE_PERF_EVENTS\n"
- "+\tselect HAVE_RCU_NO_GATHER_PAGES\n"
- "+\tselect HAVE_RCU_TABLE_FREE\n"
- "+\tselect HAVE_RCU_TABLE_INVALIDATE\n"
- " \tselect HAVE_REGS_AND_STACK_ACCESS_API\n"
- " \tselect HAVE_RSEQ\n"
- " \tselect HAVE_SYSCALL_TRACEPOINTS\n"
- "diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h\n"
- "index cf3d64313740..8073ff272b2b 100644\n"
- "--- a/arch/s390/include/asm/tlb.h\n"
- "+++ b/arch/s390/include/asm/tlb.h\n"
- "@@ -22,98 +22,40 @@\n"
- "  * Pages used for the page tables is a different story. FIXME: more\n"
- "  */\n"
- " \n"
- "-#include <linux/mm.h>\n"
- "-#include <linux/pagemap.h>\n"
- "-#include <linux/swap.h>\n"
- "-#include <asm/processor.h>\n"
- "-#include <asm/pgalloc.h>\n"
- "-#include <asm/tlbflush.h>\n"
- "-\n"
- "-struct mmu_gather {\n"
- "-\tstruct mm_struct *mm;\n"
- "-\tstruct mmu_table_batch *batch;\n"
- "-\tunsigned int fullmm;\n"
- "-\tunsigned long start, end;\n"
- "-};\n"
- "-\n"
- "-struct mmu_table_batch {\n"
- "-\tstruct rcu_head\t\trcu;\n"
- "-\tunsigned int\t\tnr;\n"
- "-\tvoid\t\t\t*tables[0];\n"
- "-};\n"
- "-\n"
- "-#define MAX_TABLE_BATCH\t\t\\\n"
- "-\t((PAGE_SIZE - sizeof(struct mmu_table_batch)) / sizeof(void *))\n"
- "-\n"
- "-extern void tlb_table_flush(struct mmu_gather *tlb);\n"
- "-extern void tlb_remove_table(struct mmu_gather *tlb, void *table);\n"
- "-\n"
- "-static inline void\n"
- "-arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,\n"
- "-\t\t\tunsigned long start, unsigned long end)\n"
- "-{\n"
- "-\ttlb->mm = mm;\n"
- "-\ttlb->start = start;\n"
- "-\ttlb->end = end;\n"
- "-\ttlb->fullmm = !(start | (end+1));\n"
- "-\ttlb->batch = NULL;\n"
- "-}\n"
- "-\n"
- "-static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb)\n"
- "-{\n"
- "-\t__tlb_flush_mm_lazy(tlb->mm);\n"
- "-}\n"
- "-\n"
- "-static inline void tlb_flush_mmu_free(struct mmu_gather *tlb)\n"
- "-{\n"
- "-\ttlb_table_flush(tlb);\n"
- "-}\n"
- "-\n"
- "+void __tlb_remove_table(void *_table);\n"
- "+static inline void tlb_flush(struct mmu_gather *tlb);\n"
- "+static inline bool __tlb_remove_page_size(struct mmu_gather *tlb,\n"
- "+\t\t\t\t\t  struct page *page, int page_size);\n"
- " \n"
- "-static inline void tlb_flush_mmu(struct mmu_gather *tlb)\n"
- "-{\n"
- "-\ttlb_flush_mmu_tlbonly(tlb);\n"
- "-\ttlb_flush_mmu_free(tlb);\n"
- "-}\n"
- "+#define tlb_start_vma(tlb, vma)\t\t\tdo { } while (0)\n"
- "+#define tlb_end_vma(tlb, vma)\t\t\tdo { } while (0)\n"
- "+#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)\n"
- " \n"
- "-static inline void\n"
- "-arch_tlb_finish_mmu(struct mmu_gather *tlb,\n"
- "-\t\tunsigned long start, unsigned long end, bool force)\n"
- "-{\n"
- "-\tif (force) {\n"
- "-\t\ttlb->start = start;\n"
- "-\t\ttlb->end = end;\n"
- "-\t}\n"
- "+#define tlb_flush tlb_flush\n"
- "+#define pte_free_tlb pte_free_tlb\n"
- "+#define pmd_free_tlb pmd_free_tlb\n"
- "+#define p4d_free_tlb p4d_free_tlb\n"
- "+#define pud_free_tlb pud_free_tlb\n"
- " \n"
- "-\ttlb_flush_mmu(tlb);\n"
- "-}\n"
- "+#include <asm/pgalloc.h>\n"
- "+#include <asm/tlbflush.h>\n"
- "+#include <asm-generic/tlb.h>\n"
- " \n"
- " /*\n"
- "  * Release the page cache reference for a pte removed by\n"
- "  * tlb_ptep_clear_flush. In both flush modes the tlb for a page cache page\n"
- "  * has already been freed, so just do free_page_and_swap_cache.\n"
- "  */\n"
- "-static inline bool __tlb_remove_page(struct mmu_gather *tlb, struct page *page)\n"
- "-{\n"
- "-\tfree_page_and_swap_cache(page);\n"
- "-\treturn false; /* avoid calling tlb_flush_mmu */\n"
- "-}\n"
- "-\n"
- "-static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)\n"
- "-{\n"
- "-\tfree_page_and_swap_cache(page);\n"
- "-}\n"
- "-\n"
- " static inline bool __tlb_remove_page_size(struct mmu_gather *tlb,\n"
- " \t\t\t\t\t  struct page *page, int page_size)\n"
- " {\n"
- "-\treturn __tlb_remove_page(tlb, page);\n"
- "+\tfree_page_and_swap_cache(page);\n"
- "+\treturn false;\n"
- " }\n"
- " \n"
- "-static inline void tlb_remove_page_size(struct mmu_gather *tlb,\n"
- "-\t\t\t\t\tstruct page *page, int page_size)\n"
- "+static inline void tlb_flush(struct mmu_gather *tlb)\n"
- " {\n"
- "-\treturn tlb_remove_page(tlb, page);\n"
- "+\t__tlb_flush_mm_lazy(tlb->mm);\n"
- " }\n"
- " \n"
- " /*\n"
- "@@ -121,9 +63,18 @@ static inline void tlb_remove_page_size(struct mmu_gather *tlb,\n"
- "  * page table from the tlb.\n"
- "  */\n"
- " static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,\n"
- "-\t\t\t\tunsigned long address)\n"
- "+                                unsigned long address)\n"
- " {\n"
- "-\tpage_table_free_rcu(tlb, (unsigned long *) pte, address);\n"
- "+\t__tlb_adjust_range(tlb, address, PAGE_SIZE);\n"
- "+\ttlb->mm->context.flush_mm = 1;\n"
- "+\ttlb->freed_tables = 1;\n"
- "+\ttlb->cleared_ptes = 1;\n"
- "+\t/*\n"
- "+\t * page_table_free_rcu takes care of the allocation bit masks\n"
- "+\t * of the 2K table fragments in the 4K page table page,\n"
- "+\t * then calls tlb_remove_table.\n"
- "+\t */\n"
- "+        page_table_free_rcu(tlb, (unsigned long *) pte, address);\n"
- " }\n"
- " \n"
- " /*\n"
- "@@ -139,6 +90,10 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,\n"
- " \tif (tlb->mm->context.asce_limit <= _REGION3_SIZE)\n"
- " \t\treturn;\n"
- " \tpgtable_pmd_page_dtor(virt_to_page(pmd));\n"
- "+\t__tlb_adjust_range(tlb, address, PAGE_SIZE);\n"
- "+\ttlb->mm->context.flush_mm = 1;\n"
- "+\ttlb->freed_tables = 1;\n"
- "+\ttlb->cleared_puds = 1;\n"
- " \ttlb_remove_table(tlb, pmd);\n"
- " }\n"
- " \n"
- "@@ -154,6 +109,10 @@ static inline void p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d,\n"
- " {\n"
- " \tif (tlb->mm->context.asce_limit <= _REGION1_SIZE)\n"
- " \t\treturn;\n"
- "+\t__tlb_adjust_range(tlb, address, PAGE_SIZE);\n"
- "+\ttlb->mm->context.flush_mm = 1;\n"
- "+\ttlb->freed_tables = 1;\n"
- "+\ttlb->cleared_p4ds = 1;\n"
- " \ttlb_remove_table(tlb, p4d);\n"
- " }\n"
- " \n"
- "@@ -169,19 +128,11 @@ static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,\n"
- " {\n"
- " \tif (tlb->mm->context.asce_limit <= _REGION2_SIZE)\n"
- " \t\treturn;\n"
- "+\ttlb->mm->context.flush_mm = 1;\n"
- "+\ttlb->freed_tables = 1;\n"
- "+\ttlb->cleared_puds = 1;\n"
- " \ttlb_remove_table(tlb, pud);\n"
- " }\n"
- " \n"
- "-#define tlb_start_vma(tlb, vma)\t\t\tdo { } while (0)\n"
- "-#define tlb_end_vma(tlb, vma)\t\t\tdo { } while (0)\n"
- "-#define tlb_remove_tlb_entry(tlb, ptep, addr)\tdo { } while (0)\n"
- "-#define tlb_remove_pmd_tlb_entry(tlb, pmdp, addr)\tdo { } while (0)\n"
- "-#define tlb_migrate_finish(mm)\t\t\tdo { } while (0)\n"
- "-#define tlb_remove_huge_tlb_entry(h, tlb, ptep, address)\t\\\n"
- "-\ttlb_remove_tlb_entry(tlb, ptep, address)\n"
- "-\n"
- "-static inline void tlb_change_page_size(struct mmu_gather *tlb, unsigned int page_size)\n"
- "-{\n"
- "-}\n"
- " \n"
- " #endif /* _S390_TLB_H */\n"
- "diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c\n"
- "index 76d89ee8b428..f7656a0b3a1a 100644\n"
- "--- a/arch/s390/mm/pgalloc.c\n"
- "+++ b/arch/s390/mm/pgalloc.c\n"
- "@@ -288,7 +288,7 @@ void page_table_free_rcu(struct mmu_gather *tlb, unsigned long *table,\n"
- " \ttlb_remove_table(tlb, table);\n"
- " }\n"
- " \n"
- "-static void __tlb_remove_table(void *_table)\n"
- "+void __tlb_remove_table(void *_table)\n"
- " {\n"
- " \tunsigned int mask = (unsigned long) _table & 3;\n"
- " \tvoid *table = (void *)((unsigned long) _table ^ mask);\n"
- "@@ -314,67 +314,6 @@ static void __tlb_remove_table(void *_table)\n"
- " \t}\n"
- " }\n"
- " \n"
- "-static void tlb_remove_table_smp_sync(void *arg)\n"
- "-{\n"
- "-\t/* Simply deliver the interrupt */\n"
- "-}\n"
- "-\n"
- "-static void tlb_remove_table_one(void *table)\n"
- "-{\n"
- "-\t/*\n"
- "-\t * This isn't an RCU grace period and hence the page-tables cannot be\n"
- "-\t * assumed to be actually RCU-freed.\n"
- "-\t *\n"
- "-\t * It is however sufficient for software page-table walkers that rely\n"
- "-\t * on IRQ disabling. See the comment near struct mmu_table_batch.\n"
- "-\t */\n"
- "-\tsmp_call_function(tlb_remove_table_smp_sync, NULL, 1);\n"
- "-\t__tlb_remove_table(table);\n"
- "-}\n"
- "-\n"
- "-static void tlb_remove_table_rcu(struct rcu_head *head)\n"
- "-{\n"
- "-\tstruct mmu_table_batch *batch;\n"
- "-\tint i;\n"
- "-\n"
- "-\tbatch = container_of(head, struct mmu_table_batch, rcu);\n"
- "-\n"
- "-\tfor (i = 0; i < batch->nr; i++)\n"
- "-\t\t__tlb_remove_table(batch->tables[i]);\n"
- "-\n"
- "-\tfree_page((unsigned long)batch);\n"
- "-}\n"
- "-\n"
- "-void tlb_table_flush(struct mmu_gather *tlb)\n"
- "-{\n"
- "-\tstruct mmu_table_batch **batch = &tlb->batch;\n"
- "-\n"
- "-\tif (*batch) {\n"
- "-\t\tcall_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu);\n"
- "-\t\t*batch = NULL;\n"
- "-\t}\n"
- "-}\n"
- "-\n"
- "-void tlb_remove_table(struct mmu_gather *tlb, void *table)\n"
- "-{\n"
- "-\tstruct mmu_table_batch **batch = &tlb->batch;\n"
- "-\n"
- "-\ttlb->mm->context.flush_mm = 1;\n"
- "-\tif (*batch == NULL) {\n"
- "-\t\t*batch = (struct mmu_table_batch *)\n"
- "-\t\t\t__get_free_page(GFP_NOWAIT | __GFP_NOWARN);\n"
- "-\t\tif (*batch == NULL) {\n"
- "-\t\t\t__tlb_flush_mm_lazy(tlb->mm);\n"
- "-\t\t\ttlb_remove_table_one(table);\n"
- "-\t\t\treturn;\n"
- "-\t\t}\n"
- "-\t\t(*batch)->nr = 0;\n"
- "-\t}\n"
- "-\t(*batch)->tables[(*batch)->nr++] = table;\n"
- "-\tif ((*batch)->nr == MAX_TABLE_BATCH)\n"
- "-\t\ttlb_flush_mmu(tlb);\n"
- "-}\n"
- "-\n"
- " /*\n"
- "  * Base infrastructure required to generate basic asces, region, segment,\n"
- "  * and page tables that do not make use of enhanced features like EDAT1.\n"
- "diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h\n"
- "index 21c751cd751e..930e25abf4de 100644\n"
- "--- a/include/asm-generic/tlb.h\n"
- "+++ b/include/asm-generic/tlb.h\n"
- "@@ -179,6 +179,7 @@ extern void tlb_remove_table(struct mmu_gather *tlb, void *table);\n"
- " \n"
- " #endif\n"
- " \n"
- "+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES\n"
- " /*\n"
- "  * If we can't allocate a page to make a big batch of page pointers\n"
- "  * to work on, then just handle a few from the on-stack structure.\n"
- "@@ -203,6 +204,8 @@ struct mmu_gather_batch {\n"
- "  */\n"
- " #define MAX_GATHER_BATCH_COUNT\t(10000UL/MAX_GATHER_BATCH)\n"
- " \n"
- "+#endif\n"
- "+\n"
- " /*\n"
- "  * struct mmu_gather is an opaque type used by the mm code for passing around\n"
- "  * any data needed by arch specific code for tlb_remove_page.\n"
- "@@ -249,6 +252,7 @@ struct mmu_gather {\n"
- " \n"
- " \tunsigned int\t\tbatch_count;\n"
- " \n"
- "+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES\n"
- " \tstruct mmu_gather_batch *active;\n"
- " \tstruct mmu_gather_batch\tlocal;\n"
- " \tstruct page\t\t*__pages[MMU_GATHER_BUNDLE];\n"
- "@@ -256,6 +260,7 @@ struct mmu_gather {\n"
- " #ifdef CONFIG_HAVE_MMU_GATHER_PAGE_SIZE\n"
- " \tunsigned int page_size;\n"
- " #endif\n"
- "+#endif\n"
- " };\n"
- " \n"
- " void arch_tlb_gather_mmu(struct mmu_gather *tlb,\n"
- "@@ -264,8 +269,10 @@ void tlb_flush_mmu(struct mmu_gather *tlb);\n"
- " void arch_tlb_finish_mmu(struct mmu_gather *tlb,\n"
- " \t\t\t unsigned long start, unsigned long end, bool force);\n"
- " void tlb_flush_mmu_free(struct mmu_gather *tlb);\n"
- "+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES\n"
- " extern bool __tlb_remove_page_size(struct mmu_gather *tlb, struct page *page,\n"
- " \t\t\t\t   int page_size);\n"
- "+#endif\n"
- " \n"
- " static inline void __tlb_adjust_range(struct mmu_gather *tlb,\n"
- " \t\t\t\t      unsigned long address,\n"
- "diff --git a/mm/mmu_gather.c b/mm/mmu_gather.c\n"
- "index 2d5e617131f6..d3d2763d91b2 100644\n"
- "--- a/mm/mmu_gather.c\n"
- "+++ b/mm/mmu_gather.c\n"
- "@@ -13,6 +13,8 @@\n"
- " \n"
- " #ifdef HAVE_GENERIC_MMU_GATHER\n"
- " \n"
- "+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES\n"
- "+\n"
- " static bool tlb_next_batch(struct mmu_gather *tlb)\n"
- " {\n"
- " \tstruct mmu_gather_batch *batch;\n"
- "@@ -41,6 +43,8 @@ static bool tlb_next_batch(struct mmu_gather *tlb)\n"
- " \treturn true;\n"
- " }\n"
- " \n"
- "+#endif\n"
- "+\n"
- " void arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,\n"
- " \t\t\t\tunsigned long start, unsigned long end)\n"
- " {\n"
- "@@ -49,12 +53,14 @@ void arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,\n"
- " \t/* Is it from 0 to ~0? */\n"
- " \ttlb->fullmm     = !(start | (end+1));\n"
- " \ttlb->need_flush_all = 0;\n"
- "+\n"
- "+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES\n"
- " \ttlb->local.next = NULL;\n"
- " \ttlb->local.nr   = 0;\n"
- " \ttlb->local.max  = ARRAY_SIZE(tlb->__pages);\n"
- " \ttlb->active     = &tlb->local;\n"
- " \ttlb->batch_count = 0;\n"
- "-\n"
- "+#endif\n"
- " #ifdef CONFIG_HAVE_RCU_TABLE_FREE\n"
- " \ttlb->batch = NULL;\n"
- " #endif\n"
- "@@ -67,16 +73,20 @@ void arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,\n"
- " \n"
- " void tlb_flush_mmu_free(struct mmu_gather *tlb)\n"
- " {\n"
- "+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES\n"
- " \tstruct mmu_gather_batch *batch;\n"
- "+#endif\n"
- " \n"
- " #ifdef CONFIG_HAVE_RCU_TABLE_FREE\n"
- " \ttlb_table_flush(tlb);\n"
- " #endif\n"
- "+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES\n"
- " \tfor (batch = &tlb->local; batch && batch->nr; batch = batch->next) {\n"
- " \t\tfree_pages_and_swap_cache(batch->pages, batch->nr);\n"
- " \t\tbatch->nr = 0;\n"
- " \t}\n"
- " \ttlb->active = &tlb->local;\n"
- "+#endif\n"
- " }\n"
- " \n"
- " void tlb_flush_mmu(struct mmu_gather *tlb)\n"
- "@@ -92,7 +102,9 @@ void tlb_flush_mmu(struct mmu_gather *tlb)\n"
- " void arch_tlb_finish_mmu(struct mmu_gather *tlb,\n"
- " \t\tunsigned long start, unsigned long end, bool force)\n"
- " {\n"
- "+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES\n"
- " \tstruct mmu_gather_batch *batch, *next;\n"
- "+#endif\n"
- " \n"
- " \tif (force) {\n"
- " \t\t__tlb_reset_range(tlb);\n"
- "@@ -104,13 +116,16 @@ void arch_tlb_finish_mmu(struct mmu_gather *tlb,\n"
- " \t/* keep the page table cache within bounds */\n"
- " \tcheck_pgt_cache();\n"
- " \n"
- "+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES\n"
- " \tfor (batch = tlb->local.next; batch; batch = next) {\n"
- " \t\tnext = batch->next;\n"
- " \t\tfree_pages((unsigned long)batch, 0);\n"
- " \t}\n"
- " \ttlb->local.next = NULL;\n"
- "+#endif\n"
- " }\n"
- " \n"
- "+#ifndef CONFIG_HAVE_RCU_NO_GATHER_PAGES\n"
- " /* __tlb_remove_page\n"
- "  *\tMust perform the equivalent to __free_pte(pte_get_and_clear(ptep)), while\n"
- "  *\thandling the additional races in SMP caused by other CPUs caching valid\n"
- "@@ -143,6 +158,7 @@ bool __tlb_remove_page_size(struct mmu_gather *tlb, struct page *page, int page_\n"
- " \n"
- " \treturn false;\n"
- " }\n"
- "+#endif\n"
- " \n"
- " #endif /* HAVE_GENERIC_MMU_GATHER */\n"
- " \n"
- "-- \n"
- "2.16.4\n"
- "\n"
- "\n"
- "-- \n"
- "blue skies,\n"
- "   Martin.\n"
- "\n"
- "\"Reality continues to ruin my life.\" - Calvin."
+ --
 
-0994e8769a918930547c38a07137cfc9eb0d70c445c56492decdbc4a79a30edd
+899655bd4a7583737cd86c6a9be59c130d6549a8c4183b8d36560cc98e670299

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox