From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753766Ab0H1O2O (ORCPT ); Sat, 28 Aug 2010 10:28:14 -0400 Received: from bombadil.infradead.org ([18.85.46.34]:47758 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753523Ab0H1O1q (ORCPT ); Sat, 28 Aug 2010 10:27:46 -0400 Message-Id: <20100828142456.102992099@chello.nl> User-Agent: quilt/0.47-1 Date: Sat, 28 Aug 2010 16:16:47 +0200 From: Peter Zijlstra To: Andrea Arcangeli , Avi Kivity , Thomas Gleixner , Rik van Riel , Ingo Molnar , akpm@linux-foundation.org, Linus Torvalds Cc: linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, Benjamin Herrenschmidt , David Miller , Hugh Dickins , Mel Gorman , Nick Piggin , Peter Zijlstra , Paul McKenney , Yanmin Zhang , Stephen Rothwell , Martin Schwidefsky Subject: [PATCH 10/20] s390: preemptible mmu_gather References: <20100828141637.421594670@chello.nl> Content-Disposition: inline; filename=martin-mm-preempt-tlb-gather-s390.patch Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Martin Schwidefsky Adapt the stand-alone s390 mmu_gather implementation to the new preemptible mmu_gather interface. Signed-off-by: Martin Schwidefsky Signed-off-by: Peter Zijlstra LKML-Reference: <20100409105800.0d0f93ac@mschwide.boeblingen.de.ibm.com> --- arch/s390/include/asm/tlb.h | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) Index: linux-2.6/arch/s390/include/asm/tlb.h =================================================================== --- linux-2.6.orig/arch/s390/include/asm/tlb.h +++ linux-2.6/arch/s390/include/asm/tlb.h @@ -28,44 +28,50 @@ #include #include -#ifndef CONFIG_SMP -#define TLB_NR_PTRS 1 -#else -#define TLB_NR_PTRS 508 -#endif - struct mmu_gather { struct mm_struct *mm; unsigned int fullmm; unsigned int nr_ptes; unsigned int nr_pxds; - void *array[TLB_NR_PTRS]; + unsigned int max; + void **array; + void *local[8]; }; -DECLARE_PER_CPU(struct mmu_gather, mmu_gathers); - -static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, - unsigned int full_mm_flush) +static inline void __tlb_alloc_pages(struct mmu_gather *tlb) { - struct mmu_gather *tlb = &get_cpu_var(mmu_gathers); + unsigned long addr = __get_free_pages(GFP_ATOMIC, 0); + + if (addr) { + tlb->array = (void *) addr; + tlb->max = PAGE_SIZE / sizeof(void *); + } +} +static inline void tlb_gather_mmu(struct mmu_gather *tlb, + struct mm_struct *mm, + unsigned int full_mm_flush) +{ tlb->mm = mm; + tlb->max = ARRAY_SIZE(tlb->local); + tlb->array = tlb->local; tlb->fullmm = full_mm_flush; - tlb->nr_ptes = 0; - tlb->nr_pxds = TLB_NR_PTRS; if (tlb->fullmm) __tlb_flush_mm(mm); - return tlb; + else + __tlb_alloc_pages(tlb); + tlb->nr_ptes = 0; + tlb->nr_pxds = tlb->max; } static inline void tlb_flush_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) { - if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pxds < TLB_NR_PTRS)) + if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pxds < tlb->max)) __tlb_flush_mm(tlb->mm); while (tlb->nr_ptes > 0) pte_free(tlb->mm, tlb->array[--tlb->nr_ptes]); - while (tlb->nr_pxds < TLB_NR_PTRS) + while (tlb->nr_pxds < tlb->max) /* pgd_free frees the pointer as region or segment table */ pgd_free(tlb->mm, tlb->array[tlb->nr_pxds++]); } @@ -78,7 +84,8 @@ static inline void tlb_finish_mmu(struct /* keep the page table cache within bounds */ check_pgt_cache(); - put_cpu_var(mmu_gathers); + if (tlb->array != tlb->local) + free_pages((unsigned long) tlb->array, 0); } /* From mboxrd@z Thu Jan 1 00:00:00 1970 From: Peter Zijlstra Subject: [PATCH 10/20] s390: preemptible mmu_gather Date: Sat, 28 Aug 2010 16:16:47 +0200 Message-ID: <20100828142456.102992099@chello.nl> References: <20100828141637.421594670@chello.nl> Return-path: Received: from bombadil.infradead.org ([18.85.46.34]:47758 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753523Ab0H1O1q (ORCPT ); Sat, 28 Aug 2010 10:27:46 -0400 Content-Disposition: inline; filename=martin-mm-preempt-tlb-gather-s390.patch Sender: linux-arch-owner@vger.kernel.org List-ID: To: Andrea Arcangeli , Avi Kivity , Thomas Gleixner , Rik van Riel , Ingo Molnar , akpm@linux-fou Cc: linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, Benjamin Herrenschmidt , David Miller , Hugh Dickins , Mel Gorman , Nick Piggin , Peter Zijlstra , Paul McKenney , Yanmin Zhang , Stephen Rothwell , Martin Schwidefsky From: Martin Schwidefsky Adapt the stand-alone s390 mmu_gather implementation to the new preemptible mmu_gather interface. Signed-off-by: Martin Schwidefsky Signed-off-by: Peter Zijlstra LKML-Reference: <20100409105800.0d0f93ac@mschwide.boeblingen.de.ibm.com> --- arch/s390/include/asm/tlb.h | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) Index: linux-2.6/arch/s390/include/asm/tlb.h =================================================================== --- linux-2.6.orig/arch/s390/include/asm/tlb.h +++ linux-2.6/arch/s390/include/asm/tlb.h @@ -28,44 +28,50 @@ #include #include -#ifndef CONFIG_SMP -#define TLB_NR_PTRS 1 -#else -#define TLB_NR_PTRS 508 -#endif - struct mmu_gather { struct mm_struct *mm; unsigned int fullmm; unsigned int nr_ptes; unsigned int nr_pxds; - void *array[TLB_NR_PTRS]; + unsigned int max; + void **array; + void *local[8]; }; -DECLARE_PER_CPU(struct mmu_gather, mmu_gathers); - -static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, - unsigned int full_mm_flush) +static inline void __tlb_alloc_pages(struct mmu_gather *tlb) { - struct mmu_gather *tlb = &get_cpu_var(mmu_gathers); + unsigned long addr = __get_free_pages(GFP_ATOMIC, 0); + + if (addr) { + tlb->array = (void *) addr; + tlb->max = PAGE_SIZE / sizeof(void *); + } +} +static inline void tlb_gather_mmu(struct mmu_gather *tlb, + struct mm_struct *mm, + unsigned int full_mm_flush) +{ tlb->mm = mm; + tlb->max = ARRAY_SIZE(tlb->local); + tlb->array = tlb->local; tlb->fullmm = full_mm_flush; - tlb->nr_ptes = 0; - tlb->nr_pxds = TLB_NR_PTRS; if (tlb->fullmm) __tlb_flush_mm(mm); - return tlb; + else + __tlb_alloc_pages(tlb); + tlb->nr_ptes = 0; + tlb->nr_pxds = tlb->max; } static inline void tlb_flush_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) { - if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pxds < TLB_NR_PTRS)) + if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pxds < tlb->max)) __tlb_flush_mm(tlb->mm); while (tlb->nr_ptes > 0) pte_free(tlb->mm, tlb->array[--tlb->nr_ptes]); - while (tlb->nr_pxds < TLB_NR_PTRS) + while (tlb->nr_pxds < tlb->max) /* pgd_free frees the pointer as region or segment table */ pgd_free(tlb->mm, tlb->array[tlb->nr_pxds++]); } @@ -78,7 +84,8 @@ static inline void tlb_finish_mmu(struct /* keep the page table cache within bounds */ check_pgt_cache(); - put_cpu_var(mmu_gathers); + if (tlb->array != tlb->local) + free_pages((unsigned long) tlb->array, 0); } /*