Received: by 10.192.165.148 with SMTP id m20csp729350imm; Fri, 4 May 2018 05:37:17 -0700 (PDT) X-Google-Smtp-Source: AB8JxZqZVUIddDU9ZO6ZcpVm0CQL7LrW53QQx3qQdNBuJ7h1YsmfHkLo3BNDQzYrKD0Zx0YFS6Gh X-Received: by 10.98.137.219 with SMTP id n88mr26608831pfk.11.1525437437487; Fri, 04 May 2018 05:37:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525437437; cv=none; d=google.com; s=arc-20160816; b=wOM7rVpY9yVpeD9qYyZD4XCEDN9bCUlYZrrFCj4FUQFLd29M84gJOVQ44Z0ReZmjiN +UfSj1wNTtVmmzr+qCQhSGHNO/Pl3/EdeIk56QWDBz74ErVHLOx4ld0881mPOR1AGY5M Acn6OnQx3ZXmW73uJgZW5oMZzvDlw1sTX2ns8ppZDz1GyjVc8ddpcJVMp7Ct1ty8+YG9 6WwOpcqCR7RwRmUpNtVclhCPRgmutpjvtCsA49yFmmRnxX5OIdS0iURwUmMuyCrrg9x9 IbGIvdJbz62Q/mkuhxvRwCYBhHXy+Izfh2CNIsZWwlK1Bc0TlEEVXswG4nB+CHQZwtix dw+A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:date:cc:to:subject:from:references :in-reply-to:message-id:arc-authentication-results; bh=inXOgdI+mcvCoEZgXhqPkTT/aEuTo7RH7lZWUMluASY=; b=MVbamExM3bGgqenanWHitb8MUTuuW3Jcf2S2uEDgOnag1IIXG/xLHMu3C3JdKLELcI qm3+jtGaXghYrui4EYiKIeCLFg8qu/emGekNz7DWcBhVwTr+JJbEKgKDqjCkcA4wGCU8 X7fWILsbKZGW9H3ElifnZ7FaQW1rDnnIHacWxiXVmtJCMK6cWHguHsOQmso6Wsq25c38 JN4HXlCrtgEnesoLqVCaeti1YolpPujDO/KFiPx9Pku1KNP+dgA5eQ/HXda68kePG1lf sfcL4pU+lle5WfQWlWj/lezflm1VBSlSAN3S51GoAK3cXYrU78WAwAwDl/mKIPvHGYTF RAKA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 5si12842543pfi.285.2018.05.04.05.37.02; Fri, 04 May 2018 05:37:17 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751802AbeEDMe3 (ORCPT + 99 others); Fri, 4 May 2018 08:34:29 -0400 Received: from pegase1.c-s.fr ([93.17.236.30]:45327 "EHLO pegase1.c-s.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751684AbeEDMeY (ORCPT ); Fri, 4 May 2018 08:34:24 -0400 Received: from localhost (mailhub1-int [192.168.12.234]) by localhost (Postfix) with ESMTP id 40crzv4fZVz9tvTD; Fri, 4 May 2018 14:34:19 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [192.168.12.234]) (amavisd-new, port 10024) with ESMTP id zjjAMGX06bIc; Fri, 4 May 2018 14:34:19 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 40crzv436mz9ttC1; Fri, 4 May 2018 14:34:19 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 5957B8B976; Fri, 4 May 2018 14:34:23 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id G8R-rxxq6HIh; Fri, 4 May 2018 14:34:23 +0200 (CEST) Received: from po14934vm.idsi0.si.c-s.fr (po15451.idsi0.si.c-s.fr [172.25.231.2]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 2FDA58B972; Fri, 4 May 2018 14:34:23 +0200 (CEST) Received: by po14934vm.idsi0.si.c-s.fr (Postfix, from userid 0) id ECBF56CF2D; Fri, 4 May 2018 14:34:22 +0200 (CEST) Message-Id: <7806b2c341cb3acfedbada47ad0d828f8aca0758.1525435203.git.christophe.leroy@c-s.fr> In-Reply-To: References: From: Christophe Leroy Subject: [PATCH 16/17] powerpc/mm: Make pte_fragment_alloc() common to PPC32 and PPC64 To: Benjamin Herrenschmidt , Paul Mackerras , Michael Ellerman , aneesh.kumar@linux.vnet.ibm.com Cc: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Date: Fri, 4 May 2018 14:34:22 +0200 (CEST) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In order to allow the 8xx to handle pte_fragments, this patch makes in common to PPC32 and PPC64 Signed-off-by: Christophe Leroy --- arch/powerpc/include/asm/mmu_context.h | 28 ++++++++++++++ arch/powerpc/mm/mmu_context_book3s64.c | 28 -------------- arch/powerpc/mm/pgtable.c | 67 ++++++++++++++++++++++++++++++++++ arch/powerpc/mm/pgtable_64.c | 67 ---------------------------------- arch/powerpc/platforms/Kconfig.cputype | 5 +++ 5 files changed, 100 insertions(+), 95 deletions(-) diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 1835ca1505d6..252988f7e219 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -262,5 +262,33 @@ static inline u64 pte_to_hpte_pkey_bits(u64 pteflags) #endif /* CONFIG_PPC_MEM_KEYS */ +#ifdef CONFIG_NEED_PTE_FRAG +static inline void destroy_pagetable_page(struct mm_struct *mm) +{ + int count; + void *pte_frag; + struct page *page; + + pte_frag = mm->context.pte_frag; + if (!pte_frag) + return; + + 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 (page_ref_sub_and_test(page, PTE_FRAG_NR - count)) { + pgtable_page_dtor(page); + free_unref_page(page); + } +} + +#else +static inline void destroy_pagetable_page(struct mm_struct *mm) +{ + return; +} +#endif + #endif /* __KERNEL__ */ #endif /* __ASM_POWERPC_MMU_CONTEXT_H */ diff --git a/arch/powerpc/mm/mmu_context_book3s64.c b/arch/powerpc/mm/mmu_context_book3s64.c index b75194dff64c..2f55a4e3c09a 100644 --- a/arch/powerpc/mm/mmu_context_book3s64.c +++ b/arch/powerpc/mm/mmu_context_book3s64.c @@ -192,34 +192,6 @@ static void destroy_contexts(mm_context_t *ctx) spin_unlock(&mmu_context_lock); } -#ifdef CONFIG_PPC_64K_PAGES -static void destroy_pagetable_page(struct mm_struct *mm) -{ - int count; - void *pte_frag; - struct page *page; - - pte_frag = mm->context.pte_frag; - if (!pte_frag) - return; - - 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 (page_ref_sub_and_test(page, PTE_FRAG_NR - count)) { - pgtable_page_dtor(page); - free_unref_page(page); - } -} - -#else -static inline void destroy_pagetable_page(struct mm_struct *mm) -{ - return; -} -#endif - void destroy_context(struct mm_struct *mm) { #ifdef CONFIG_SPAPR_TCE_IOMMU diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c index 9f361ae571e9..2d34755ed727 100644 --- a/arch/powerpc/mm/pgtable.c +++ b/arch/powerpc/mm/pgtable.c @@ -264,3 +264,70 @@ unsigned long vmalloc_to_phys(void *va) return __pa(pfn_to_kaddr(pfn)) + offset_in_page(va); } EXPORT_SYMBOL_GPL(vmalloc_to_phys); + +#ifdef CONFIG_NEED_PTE_FRAG +static pte_t *get_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_cache(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; + } + + ret = page_address(page); + 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)) { + set_page_count(page, 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_from_cache(mm); + if (pte) + return pte; + + return __alloc_for_cache(mm, kernel); +} +#endif diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index dd1102a246e4..1d8dc37d98a7 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -139,73 +139,6 @@ struct page *pmd_page(pmd_t pmd) return virt_to_page(pmd_page_vaddr(pmd)); } -#ifdef CONFIG_PPC_64K_PAGES -static pte_t *get_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_cache(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; - } - - ret = page_address(page); - 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)) { - set_page_count(page, 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_from_cache(mm); - if (pte) - return pte; - - return __alloc_for_cache(mm, kernel); -} -#endif /* CONFIG_PPC_64K_PAGES */ - void pte_fragment_free(unsigned long *table, int kernel) { struct page *page = virt_to_page(table); diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index f860f0326c78..7172b04c91b5 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -337,6 +337,11 @@ config PPC_MM_SLICES default y if PPC_8xx && HUGETLB_PAGE default n +config NEED_PTE_FRAG + bool + default y if PPC_BOOK3S_64 && PPC_64K_PAGES + default n + config PPC_HAVE_PMU_SUPPORT bool -- 2.13.3