From: Peter Zijlstra <a.p.zijls...@chello.nl> Implements optional HAVE_RCU_TABLE_FREE support for x86.
This is useful for things like Xen and KVM where paravirt tlb flush means the software page table walkers like GUP-fast cannot rely on IRQs disabling like regular x86 can. Not for inclusion - is part of PeterZ's "Unify TLB gather implementations" http://mid.gmane.org/20120627211540.459910...@chello.nl Cc: Nikunj A Dadhania <nik...@linux.vnet.ibm.com> Cc: Jeremy Fitzhardinge <jer...@goop.org> Cc: Avi Kivity <a...@redhat.com> Signed-off-by: Peter Zijlstra <a.p.zijls...@chello.nl> Link: http://lkml.kernel.org/n/tip-r106wg6t7crxxhva55jna...@git.kernel.org --- arch/x86/include/asm/tlb.h | 1 + arch/x86/mm/pgtable.c | 6 +++--- include/asm-generic/tlb.h | 9 +++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/tlb.h b/arch/x86/include/asm/tlb.h index 4fef207..f5489f0 100644 --- a/arch/x86/include/asm/tlb.h +++ b/arch/x86/include/asm/tlb.h @@ -1,6 +1,7 @@ #ifndef _ASM_X86_TLB_H #define _ASM_X86_TLB_H +#define __tlb_remove_table(table) free_page_and_swap_cache(table) #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) diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index 8573b83..34fa168 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -51,21 +51,21 @@ void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte) { pgtable_page_dtor(pte); paravirt_release_pte(page_to_pfn(pte)); - tlb_remove_page(tlb, pte); + tlb_remove_table(tlb, pte); } #if PAGETABLE_LEVELS > 2 void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) { paravirt_release_pmd(__pa(pmd) >> PAGE_SHIFT); - tlb_remove_page(tlb, virt_to_page(pmd)); + tlb_remove_table(tlb, virt_to_page(pmd)); } #if PAGETABLE_LEVELS > 3 void ___pud_free_tlb(struct mmu_gather *tlb, pud_t *pud) { paravirt_release_pud(__pa(pud) >> PAGE_SHIFT); - tlb_remove_page(tlb, virt_to_page(pud)); + tlb_remove_table(tlb, virt_to_page(pud)); } #endif /* PAGETABLE_LEVELS > 3 */ #endif /* PAGETABLE_LEVELS > 2 */ diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h index ed6642a..d382b22 100644 --- a/include/asm-generic/tlb.h +++ b/include/asm-generic/tlb.h @@ -19,6 +19,8 @@ #include <asm/pgalloc.h> #include <asm/tlbflush.h> +static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page); + #ifdef CONFIG_HAVE_RCU_TABLE_FREE /* * Semi RCU freeing of the page directories. @@ -60,6 +62,13 @@ struct mmu_table_batch { extern void tlb_table_flush(struct mmu_gather *tlb); extern void tlb_remove_table(struct mmu_gather *tlb, void *table); +#else + +static inline void tlb_remove_table(struct mmu_gather *tlb, void *table) +{ + tlb_remove_page(tlb, table); +} + #endif /* -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html