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