linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
To: Christophe Leroy <christophe.leroy@c-s.fr>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Paul Mackerras <paulus@samba.org>,
	Michael Ellerman <mpe@ellerman.id.au>,
	aneesh.kumar@linux.vnet.ibm.com
Cc: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org
Subject: Re: [PATCH v5 14/22] powerpc/mm: Move pte_fragment_alloc() to a common location
Date: Wed, 26 Sep 2018 08:13:36 +0530	[thread overview]
Message-ID: <87tvmdgeqv.fsf@linux.ibm.com> (raw)
In-Reply-To: <de995657691084fe1b8a5c31393a82e52604def8.1537892499.git.christophe.leroy@c-s.fr>

Christophe Leroy <christophe.leroy@c-s.fr> writes:

> In preparation of next patch which generalises the use of
> pte_fragment_alloc() for all, this patch moves the related functions
> in a place that is common to all subarches.
>
> The 8xx will need that for supporting 16k pages, as in that mode
> page tables still have a size of 4k.
>
> Since pte_fragment with only once fragment is not different
> from what is done in the general case, we can easily migrate all
> subarchs to pte fragments.
>
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>

> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> ---
>  arch/powerpc/include/asm/book3s/64/pgalloc.h |   1 +
>  arch/powerpc/mm/Makefile                     |   4 +-
>  arch/powerpc/mm/mmu_context_book3s64.c       |  15 ----
>  arch/powerpc/mm/pgtable-book3s64.c           |  85 --------------------
>  arch/powerpc/mm/pgtable-frag.c               | 116 +++++++++++++++++++++++++++
>  5 files changed, 120 insertions(+), 101 deletions(-)
>  create mode 100644 arch/powerpc/mm/pgtable-frag.c
>
> diff --git a/arch/powerpc/include/asm/book3s/64/pgalloc.h b/arch/powerpc/include/asm/book3s/64/pgalloc.h
> index bfed4cf3b2f3..6c2808c0f052 100644
> --- a/arch/powerpc/include/asm/book3s/64/pgalloc.h
> +++ b/arch/powerpc/include/asm/book3s/64/pgalloc.h
> @@ -39,6 +39,7 @@ extern struct vmemmap_backing *vmemmap_list;
>  extern struct kmem_cache *pgtable_cache[];
>  #define PGT_CACHE(shift) pgtable_cache[shift]
>  
> +void pte_frag_destroy(void *pte_frag);
>  extern pte_t *pte_fragment_alloc(struct mm_struct *, unsigned long, int);
>  extern pmd_t *pmd_fragment_alloc(struct mm_struct *, unsigned long);
>  extern void pte_fragment_free(unsigned long *, int);
> diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
> index d0c1ce1297e3..db2f001183d1 100644
> --- a/arch/powerpc/mm/Makefile
> +++ b/arch/powerpc/mm/Makefile
> @@ -15,7 +15,9 @@ obj-$(CONFIG_PPC_MMU_NOHASH)	+= mmu_context_nohash.o tlb_nohash.o \
>  obj-$(CONFIG_PPC_BOOK3E)	+= tlb_low_$(BITS)e.o
>  hash64-$(CONFIG_PPC_NATIVE)	:= hash_native_64.o
>  obj-$(CONFIG_PPC_BOOK3E_64)   += pgtable-book3e.o
> -obj-$(CONFIG_PPC_BOOK3S_64)	+= pgtable-hash64.o hash_utils_64.o slb.o $(hash64-y) mmu_context_book3s64.o pgtable-book3s64.o
> +obj-$(CONFIG_PPC_BOOK3S_64)	+= pgtable-hash64.o hash_utils_64.o slb.o \
> +				   $(hash64-y) mmu_context_book3s64.o \
> +				   pgtable-book3s64.o pgtable-frag.o
>  obj-$(CONFIG_PPC_RADIX_MMU)	+= pgtable-radix.o tlb-radix.o
>  obj-$(CONFIG_PPC_STD_MMU_32)	+= ppc_mmu_32.o hash_low_32.o mmu_context_hash32.o
>  obj-$(CONFIG_PPC_STD_MMU)	+= tlb_hash$(BITS).o
> diff --git a/arch/powerpc/mm/mmu_context_book3s64.c b/arch/powerpc/mm/mmu_context_book3s64.c
> index 510f103d7813..f720c5cc0b5e 100644
> --- a/arch/powerpc/mm/mmu_context_book3s64.c
> +++ b/arch/powerpc/mm/mmu_context_book3s64.c
> @@ -164,21 +164,6 @@ static void destroy_contexts(mm_context_t *ctx)
>  	}
>  }
>  
> -static void pte_frag_destroy(void *pte_frag)
> -{
> -	int count;
> -	struct page *page;
> -
> -	page = virt_to_page(pte_frag);
> -	/* drop all the pending references */
> -	count = ((unsigned long)pte_frag & ~PAGE_MASK) >> PTE_FRAG_SIZE_SHIFT;
> -	/* We allow PTE_FRAG_NR fragments from a PTE page */
> -	if (atomic_sub_and_test(PTE_FRAG_NR - count, &page->pt_frag_refcount)) {
> -		pgtable_page_dtor(page);
> -		__free_page(page);
> -	}
> -}
> -
>  static void pmd_frag_destroy(void *pmd_frag)
>  {
>  	int count;
> diff --git a/arch/powerpc/mm/pgtable-book3s64.c b/arch/powerpc/mm/pgtable-book3s64.c
> index 01d7c0f7c4f0..723cd324fa34 100644
> --- a/arch/powerpc/mm/pgtable-book3s64.c
> +++ b/arch/powerpc/mm/pgtable-book3s64.c
> @@ -317,91 +317,6 @@ void pmd_fragment_free(unsigned long *pmd)
>  	}
>  }
>  
> -static pte_t *get_pte_from_cache(struct mm_struct *mm)
> -{
> -	void *pte_frag, *ret;
> -
> -	spin_lock(&mm->page_table_lock);
> -	ret = mm->context.pte_frag;
> -	if (ret) {
> -		pte_frag = ret + PTE_FRAG_SIZE;
> -		/*
> -		 * If we have taken up all the fragments mark PTE page NULL
> -		 */
> -		if (((unsigned long)pte_frag & ~PAGE_MASK) == 0)
> -			pte_frag = NULL;
> -		mm->context.pte_frag = pte_frag;
> -	}
> -	spin_unlock(&mm->page_table_lock);
> -	return (pte_t *)ret;
> -}
> -
> -static pte_t *__alloc_for_ptecache(struct mm_struct *mm, int kernel)
> -{
> -	void *ret = NULL;
> -	struct page *page;
> -
> -	if (!kernel) {
> -		page = alloc_page(PGALLOC_GFP | __GFP_ACCOUNT);
> -		if (!page)
> -			return NULL;
> -		if (!pgtable_page_ctor(page)) {
> -			__free_page(page);
> -			return NULL;
> -		}
> -	} else {
> -		page = alloc_page(PGALLOC_GFP);
> -		if (!page)
> -			return NULL;
> -	}
> -
> -	atomic_set(&page->pt_frag_refcount, 1);
> -
> -	ret = page_address(page);
> -	/*
> -	 * if we support only one fragment just return the
> -	 * allocated page.
> -	 */
> -	if (PTE_FRAG_NR == 1)
> -		return ret;
> -	spin_lock(&mm->page_table_lock);
> -	/*
> -	 * If we find pgtable_page set, we return
> -	 * the allocated page with single fragement
> -	 * count.
> -	 */
> -	if (likely(!mm->context.pte_frag)) {
> -		atomic_set(&page->pt_frag_refcount, PTE_FRAG_NR);
> -		mm->context.pte_frag = ret + PTE_FRAG_SIZE;
> -	}
> -	spin_unlock(&mm->page_table_lock);
> -
> -	return (pte_t *)ret;
> -}
> -
> -pte_t *pte_fragment_alloc(struct mm_struct *mm, unsigned long vmaddr, int kernel)
> -{
> -	pte_t *pte;
> -
> -	pte = get_pte_from_cache(mm);
> -	if (pte)
> -		return pte;
> -
> -	return __alloc_for_ptecache(mm, kernel);
> -}
> -
> -void pte_fragment_free(unsigned long *table, int kernel)
> -{
> -	struct page *page = virt_to_page(table);
> -
> -	BUG_ON(atomic_read(&page->pt_frag_refcount) <= 0);
> -	if (atomic_dec_and_test(&page->pt_frag_refcount)) {
> -		if (!kernel)
> -			pgtable_page_dtor(page);
> -		__free_page(page);
> -	}
> -}
> -
>  static inline void pgtable_free(void *table, int index)
>  {
>  	switch (index) {
> diff --git a/arch/powerpc/mm/pgtable-frag.c b/arch/powerpc/mm/pgtable-frag.c
> new file mode 100644
> index 000000000000..d61e7c2a9a79
> --- /dev/null
> +++ b/arch/powerpc/mm/pgtable-frag.c
> @@ -0,0 +1,116 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/*
> + *  Handling Page Tables through page fragments
> + *
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/gfp.h>
> +#include <linux/mm.h>
> +#include <linux/percpu.h>
> +#include <linux/hardirq.h>
> +#include <linux/hugetlb.h>
> +#include <asm/pgalloc.h>
> +#include <asm/tlbflush.h>
> +#include <asm/tlb.h>
> +
> +void pte_frag_destroy(void *pte_frag)
> +{
> +	int count;
> +	struct page *page;
> +
> +	page = virt_to_page(pte_frag);
> +	/* drop all the pending references */
> +	count = ((unsigned long)pte_frag & ~PAGE_MASK) >> PTE_FRAG_SIZE_SHIFT;
> +	/* We allow PTE_FRAG_NR fragments from a PTE page */
> +	if (atomic_sub_and_test(PTE_FRAG_NR - count, &page->pt_frag_refcount)) {
> +		pgtable_page_dtor(page);
> +		__free_page(page);
> +	}
> +}
> +
> +static pte_t *get_pte_from_cache(struct mm_struct *mm)
> +{
> +	void *pte_frag, *ret;
> +
> +	spin_lock(&mm->page_table_lock);
> +	ret = mm->context.pte_frag;
> +	if (ret) {
> +		pte_frag = ret + PTE_FRAG_SIZE;
> +		/*
> +		 * If we have taken up all the fragments mark PTE page NULL
> +		 */
> +		if (((unsigned long)pte_frag & ~PAGE_MASK) == 0)
> +			pte_frag = NULL;
> +		mm->context.pte_frag = pte_frag;
> +	}
> +	spin_unlock(&mm->page_table_lock);
> +	return (pte_t *)ret;
> +}
> +
> +static pte_t *__alloc_for_ptecache(struct mm_struct *mm, int kernel)
> +{
> +	void *ret = NULL;
> +	struct page *page;
> +
> +	if (!kernel) {
> +		page = alloc_page(PGALLOC_GFP | __GFP_ACCOUNT);
> +		if (!page)
> +			return NULL;
> +		if (!pgtable_page_ctor(page)) {
> +			__free_page(page);
> +			return NULL;
> +		}
> +	} else {
> +		page = alloc_page(PGALLOC_GFP);
> +		if (!page)
> +			return NULL;
> +	}
> +
> +	atomic_set(&page->pt_frag_refcount, 1);
> +
> +	ret = page_address(page);
> +	/*
> +	 * if we support only one fragment just return the
> +	 * allocated page.
> +	 */
> +	if (PTE_FRAG_NR == 1)
> +		return ret;
> +	spin_lock(&mm->page_table_lock);
> +	/*
> +	 * If we find pgtable_page set, we return
> +	 * the allocated page with single fragement
> +	 * count.
> +	 */
> +	if (likely(!mm->context.pte_frag)) {
> +		atomic_set(&page->pt_frag_refcount, PTE_FRAG_NR);
> +		mm->context.pte_frag = ret + PTE_FRAG_SIZE;
> +	}
> +	spin_unlock(&mm->page_table_lock);
> +
> +	return (pte_t *)ret;
> +}
> +
> +pte_t *pte_fragment_alloc(struct mm_struct *mm, unsigned long vmaddr, int kernel)
> +{
> +	pte_t *pte;
> +
> +	pte = get_pte_from_cache(mm);
> +	if (pte)
> +		return pte;
> +
> +	return __alloc_for_ptecache(mm, kernel);
> +}
> +
> +void pte_fragment_free(unsigned long *table, int kernel)
> +{
> +	struct page *page = virt_to_page(table);
> +
> +	BUG_ON(atomic_read(&page->pt_frag_refcount) <= 0);
> +	if (atomic_dec_and_test(&page->pt_frag_refcount)) {
> +		if (!kernel)
> +			pgtable_page_dtor(page);
> +		__free_page(page);
> +	}
> +}
> -- 
> 2.13.3

  reply	other threads:[~2018-09-26  2:43 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-25 16:50 [PATCH v5 00/22] Implement use of HW assistance on TLB table walk on 8xx Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 01/22] Revert "powerpc/8xx: Use L1 entry APG to handle _PAGE_ACCESSED for CONFIG_SWAP" Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 02/22] powerpc/code-patching: add a helper to get the address of a patch_site Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 03/22] powerpc/8xx: Use patch_site for memory setup patching Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 04/22] powerpc/8xx: Use patch_site for perf counters setup Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 05/22] powerpc/8xx: Move SW perf counters in first 32kb of memory Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 06/22] powerpc/8xx: Temporarily disable 16k pages and 512k hugepages Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 07/22] powerpc/mm: Use hardware assistance in TLB handlers on the 8xx Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 08/22] powerpc/mm: Enable 512k hugepage support with HW assistance " Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 09/22] powerpc/8xx: don't use r12/SPRN_SPRG_SCRATCH2 in TLB Miss handlers Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 10/22] powerpc/8xx: regroup TLB handler routines Christophe Leroy
2018-09-25 16:51 ` [PATCH v5 11/22] powerpc/mm: don't use pte_alloc_one_kernel() before slab is available Christophe Leroy
2018-09-25 16:51 ` [PATCH v5 12/22] powerpc/mm: inline pte_alloc_one() and pte_alloc_one_kernel() in PPC32 Christophe Leroy
2018-09-25 16:51 ` [PATCH v5 13/22] powerpc/book3s32: Remove CONFIG_BOOKE dependent code Christophe Leroy
2018-09-25 16:51 ` [PATCH v5 14/22] powerpc/mm: Move pte_fragment_alloc() to a common location Christophe Leroy
2018-09-26  2:43   ` Aneesh Kumar K.V [this message]
2018-09-25 16:51 ` [PATCH v5 15/22] powerpc/mm: Avoid useless lock with single page fragments Christophe Leroy
2018-09-26  2:43   ` Aneesh Kumar K.V
2018-09-25 16:51 ` [PATCH v5 16/22] powerpc/mm: move platform specific mmu-xxx.h in platform directories Christophe Leroy
2018-09-26  2:44   ` Aneesh Kumar K.V
2018-09-25 16:51 ` [PATCH v5 17/22] powerpc/mm: Move pgtable_t into platform headers Christophe Leroy
2018-09-26  2:44   ` Aneesh Kumar K.V
2018-09-25 16:51 ` [PATCH v5 18/22] powerpc/mm: Extend pte_fragment functionality to nohash/32 Christophe Leroy
2018-09-26  2:48   ` Aneesh Kumar K.V
2018-09-26  8:10     ` Christophe LEROY
2018-09-26  9:01       ` Aneesh Kumar K.V
2018-09-25 16:51 ` [PATCH v5 19/22] powerpc/8xx: Remove PTE_ATOMIC_UPDATES Christophe Leroy
2018-09-25 16:51 ` [PATCH v5 20/22] powerpc/mm: reintroduce 16K pages with HW assistance on 8xx Christophe Leroy
2018-09-25 16:51 ` [PATCH v5 21/22] powerpc/nohash32: allow setting GUARDED attribute in the PMD directly Christophe Leroy
2018-10-17 11:51   ` Christophe LEROY
2018-09-25 16:51 ` [PATCH v5 22/22] powerpc/8xx: set " Christophe Leroy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87tvmdgeqv.fsf@linux.ibm.com \
    --to=aneesh.kumar@linux.ibm.com \
    --cc=aneesh.kumar@linux.vnet.ibm.com \
    --cc=benh@kernel.crashing.org \
    --cc=christophe.leroy@c-s.fr \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mpe@ellerman.id.au \
    --cc=paulus@samba.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).