From: Vineet Gupta <Vineet.Gupta1@synopsys.com>
To: Andrew Morton <akpm@linux-foundation.org>,
"Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>,
"Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>,
Mel Gorman <mgorman@suse.de>,
Matthew Wilcox <matthew.r.wilcox@intel.com>,
Minchan Kim <minchan@kernel.org>
Cc: linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-mm@kvack.org, Vineet Gupta <Vineet.Gupta1@synopsys.com>
Subject: [PATCH v2 05/12] ARCv2: mm: THP support
Date: Tue, 22 Sep 2015 16:04:49 +0530 [thread overview]
Message-ID: <1442918096-17454-6-git-send-email-vgupta@synopsys.com> (raw)
In-Reply-To: <1442918096-17454-1-git-send-email-vgupta@synopsys.com>
ARC Linux implements 2 level page walk: PGD:PTE
In THP regime, PTE is folded into PGD (and canonically referred to as PMD)
Thus thp PMD accessors are implemented in terms of PTE (just like sparc)
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
arch/arc/Kconfig | 4 +++
arch/arc/include/asm/hugepage.h | 78 +++++++++++++++++++++++++++++++++++++++++
arch/arc/include/asm/page.h | 1 +
arch/arc/include/asm/pgtable.h | 16 +++++++--
arch/arc/mm/tlb.c | 48 +++++++++++++++++++++++++
arch/arc/mm/tlbex.S | 19 +++++++---
6 files changed, 160 insertions(+), 6 deletions(-)
create mode 100644 arch/arc/include/asm/hugepage.h
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 78c0621d5819..5912006391ed 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -76,6 +76,10 @@ config STACKTRACE_SUPPORT
config HAVE_LATENCYTOP_SUPPORT
def_bool y
+config HAVE_ARCH_TRANSPARENT_HUGEPAGE
+ def_bool y
+ depends on ARC_MMU_V4
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
diff --git a/arch/arc/include/asm/hugepage.h b/arch/arc/include/asm/hugepage.h
new file mode 100644
index 000000000000..d7614d2af454
--- /dev/null
+++ b/arch/arc/include/asm/hugepage.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2013-15 Synopsys, Inc. (www.synopsys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#ifndef _ASM_ARC_HUGEPAGE_H
+#define _ASM_ARC_HUGEPAGE_H
+
+#include <linux/types.h>
+#include <asm-generic/pgtable-nopmd.h>
+
+/*
+ * ARC Linux implements 2 level page walk: PGD:PTE
+ * In THP regime, PTE is folded into PGD (and canonically referred to as PMD)
+ * Thus thp PMD accessors are implemented in terms of PTE (just like sparc)
+ */
+static inline pte_t pmd_pte(pmd_t pmd)
+{
+ return __pte(pmd_val(pmd));
+}
+
+static inline pmd_t pte_pmd(pte_t pte)
+{
+ return __pmd(pte_val(pte));
+}
+
+#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd)))
+#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd)))
+#define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd)))
+#define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd)))
+#define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd)))
+#define pmd_mkhuge(pmd) pte_pmd(pte_mkhuge(pmd_pte(pmd)))
+#define pmd_mknotpresent(pmd) pte_pmd(pte_mknotpresent(pmd_pte(pmd)))
+#define pmd_mksplitting(pmd) pte_pmd(pte_mkspecial(pmd_pte(pmd)))
+#define pmd_mkclean(pmd) pte_pmd(pte_mkclean(pmd_pte(pmd)))
+
+#define pmd_write(pmd) pte_write(pmd_pte(pmd))
+#define pmd_young(pmd) pte_young(pmd_pte(pmd))
+#define pmd_pfn(pmd) pte_pfn(pmd_pte(pmd))
+#define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd))
+#define pmd_special(pmd) pte_special(pmd_pte(pmd))
+
+#define mk_pmd(page, prot) pte_pmd(mk_pte(page, prot))
+
+#define pmd_trans_huge(pmd) (pmd_val(pmd) & _PAGE_HW_SZ)
+#define pmd_trans_splitting(pmd) (pmd_trans_huge(pmd) && pmd_special(pmd))
+
+#define pfn_pmd(pfn, prot) (__pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
+
+static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+{
+ return pte_pmd(pte_modify(pmd_pte(pmd), newprot));
+}
+
+static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+ pmd_t *pmdp, pmd_t pmd)
+{
+ *pmdp = pmd;
+}
+
+extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
+ pmd_t *pmd);
+
+#define has_transparent_hugepage() 1
+
+/* Generic variants assume pgtable_t is struct page *, hence need for these */
+#define __HAVE_ARCH_PGTABLE_DEPOSIT
+extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
+ pgtable_t pgtable);
+
+#define __HAVE_ARCH_PGTABLE_WITHDRAW
+extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
+
+#endif
diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h
index 2994cac1069e..37706837ef75 100644
--- a/arch/arc/include/asm/page.h
+++ b/arch/arc/include/asm/page.h
@@ -64,6 +64,7 @@ typedef unsigned long pgprot_t;
#define pgd_val(x) (x)
#define pgprot_val(x) (x)
#define __pte(x) (x)
+#define __pgd(x) (x)
#define __pgprot(x) (x)
#define pte_pgprot(x) (x)
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index 431a83329324..336267f2e9d9 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -83,11 +83,13 @@
#define _PAGE_PRESENT (1<<9) /* TLB entry is valid (H) */
#if (CONFIG_ARC_MMU_VER >= 4)
-#define _PAGE_SZ (1<<10) /* Page Size indicator (H) */
+#define _PAGE_HW_SZ (1<<10) /* Page Size indicator (H): 0 normal, 1 super */
#endif
#define _PAGE_SHARED_CODE (1<<11) /* Shared Code page with cmn vaddr
usable for shared TLB entries (H) */
+
+#define _PAGE_UNUSED_BIT (1<<12)
#endif
/* vmalloc permissions */
@@ -99,6 +101,10 @@
#define _PAGE_CACHEABLE 0
#endif
+#ifndef _PAGE_HW_SZ
+#define _PAGE_HW_SZ 0
+#endif
+
/* Defaults for every user page */
#define ___DEF (_PAGE_PRESENT | _PAGE_CACHEABLE)
@@ -125,7 +131,7 @@
#define PAGE_KERNEL_NO_CACHE __pgprot(_K_PAGE_PERMS)
/* Masks for actual TLB "PD"s */
-#define PTE_BITS_IN_PD0 (_PAGE_GLOBAL | _PAGE_PRESENT)
+#define PTE_BITS_IN_PD0 (_PAGE_GLOBAL | _PAGE_PRESENT | _PAGE_HW_SZ)
#define PTE_BITS_RWX (_PAGE_EXECUTE | _PAGE_WRITE | _PAGE_READ)
#define PTE_BITS_NON_RWX_IN_PD1 (PAGE_MASK | _PAGE_CACHEABLE)
@@ -299,6 +305,7 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep)
#define PTE_BIT_FUNC(fn, op) \
static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
+PTE_BIT_FUNC(mknotpresent, &= ~(_PAGE_PRESENT));
PTE_BIT_FUNC(wrprotect, &= ~(_PAGE_WRITE));
PTE_BIT_FUNC(mkwrite, |= (_PAGE_WRITE));
PTE_BIT_FUNC(mkclean, &= ~(_PAGE_DIRTY));
@@ -308,6 +315,7 @@ PTE_BIT_FUNC(mkyoung, |= (_PAGE_ACCESSED));
PTE_BIT_FUNC(exprotect, &= ~(_PAGE_EXECUTE));
PTE_BIT_FUNC(mkexec, |= (_PAGE_EXECUTE));
PTE_BIT_FUNC(mkspecial, |= (_PAGE_SPECIAL));
+PTE_BIT_FUNC(mkhuge, |= (_PAGE_HW_SZ));
#define __HAVE_ARCH_PTE_SPECIAL
@@ -381,6 +389,10 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
* remap a physical page `pfn' of size `size' with page protection `prot'
* into virtual address `from'
*/
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#include <asm/hugepage.h>
+#endif
+
#include <asm-generic/pgtable.h>
/* to cope with aliasing VIPT cache */
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 2c7ce8bb7475..62da703a1681 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -580,6 +580,54 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned,
}
}
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+
+void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
+ pmd_t *pmd)
+{
+ pte_t pte = __pte(pmd_val(*pmd));
+ update_mmu_cache(vma, addr, &pte);
+}
+
+void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
+ pgtable_t pgtable)
+{
+ struct list_head *lh = (struct list_head *) pgtable;
+
+ assert_spin_locked(&mm->page_table_lock);
+
+ /* FIFO */
+ if (!pmd_huge_pte(mm, pmdp))
+ INIT_LIST_HEAD(lh);
+ else
+ list_add(lh, (struct list_head *) pmd_huge_pte(mm, pmdp));
+ pmd_huge_pte(mm, pmdp) = pgtable;
+}
+
+pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp)
+{
+ struct list_head *lh;
+ pgtable_t pgtable;
+
+ assert_spin_locked(&mm->page_table_lock);
+
+ pgtable = pmd_huge_pte(mm, pmdp);
+ lh = (struct list_head *) pgtable;
+ if (list_empty(lh))
+ pmd_huge_pte(mm, pmdp) = NULL;
+ else {
+ pmd_huge_pte(mm, pmdp) = (pgtable_t) lh->next;
+ list_del(lh);
+ }
+
+ pte_val(pgtable[0]) = 0;
+ pte_val(pgtable[1]) = 0;
+
+ return pgtable;
+}
+
+#endif
+
/* Read the Cache Build Confuration Registers, Decode them and save into
* the cpuinfo structure for later use.
* No Validation is done here, simply read/convert the BCRs
diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S
index b8b014c6904d..552594897655 100644
--- a/arch/arc/mm/tlbex.S
+++ b/arch/arc/mm/tlbex.S
@@ -205,10 +205,18 @@ ex_saved_reg1:
#endif
lsr r0, r2, PGDIR_SHIFT ; Bits for indexing into PGD
- ld.as r1, [r1, r0] ; PGD entry corresp to faulting addr
- and.f r1, r1, PAGE_MASK ; Ignoring protection and other flags
- ; contains Ptr to Page Table
- bz.d do_slow_path_pf ; if no Page Table, do page fault
+ ld.as r3, [r1, r0] ; PGD entry corresp to faulting addr
+ tst r3, r3
+ bz do_slow_path_pf ; if no Page Table, do page fault
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ and.f 0, r3, _PAGE_HW_SZ ; Is this Huge PMD (thp)
+ add2.nz r1, r1, r0
+ bnz.d 2f ; YES: PGD == PMD has THP PTE: stop pgd walk
+ mov.nz r0, r3
+
+#endif
+ and r1, r3, PAGE_MASK
; Get the PTE entry: The idea is
; (1) x = addr >> PAGE_SHIFT -> masks page-off bits from @fault-addr
@@ -219,6 +227,9 @@ ex_saved_reg1:
lsr r0, r2, (PAGE_SHIFT - 2)
and r0, r0, ( (PTRS_PER_PTE - 1) << 2)
ld.aw r0, [r1, r0] ; get PTE and PTE ptr for fault addr
+
+2:
+
#ifdef CONFIG_ARC_DBG_TLB_MISS_COUNT
and.f 0, r0, _PAGE_PRESENT
bz 1f
--
1.9.1
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2015-09-22 10:36 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-22 10:34 [PATCH v2 00/12] THP support for ARC Vineet Gupta
2015-09-22 10:34 ` [PATCH v2 01/12] ARC: mm: switch pgtable_to to pte_t * Vineet Gupta
2015-09-22 10:34 ` [PATCH v2 02/12] ARC: mm: pte flags comsetic cleanups, comments Vineet Gupta
2015-09-22 10:34 ` [PATCH v2 03/12] ARC: mm: Introduce PTE_SPECIAL Vineet Gupta
2015-09-22 10:34 ` [PATCH v2 04/12] Documentation/features/vm: pte_special now supported by ARC Vineet Gupta
2015-09-22 10:34 ` Vineet Gupta [this message]
2015-09-22 10:34 ` [PATCH v2 06/12] ARCv2: mm: THP: boot validation/reporting Vineet Gupta
2015-09-22 10:34 ` [PATCH v2 07/12] Documentation/features/vm: THP now supported by ARC Vineet Gupta
2015-09-22 10:34 ` [PATCH v2 08/12] mm: move some code around Vineet Gupta
2015-10-09 9:48 ` Kirill A. Shutemov
2015-10-09 10:01 ` Vineet Gupta
2015-09-22 10:34 ` [PATCH v2 09/12] mm,thp: reduce ifdef'ery for THP in generic code Vineet Gupta
2015-10-09 9:53 ` Kirill A. Shutemov
2015-10-09 10:10 ` Vineet Gupta
2015-10-09 10:28 ` Vineet Gupta
2015-09-22 10:34 ` [PATCH v2 10/12] mm,thp: introduce flush_pmd_tlb_range Vineet Gupta
2015-10-09 10:08 ` Kirill A. Shutemov
2015-10-09 10:54 ` Vineet Gupta
2015-09-22 10:34 ` [PATCH v2 11/12] ARCv2: mm: THP: Implement flush_pmd_tlb_range() optimization Vineet Gupta
2015-09-22 10:34 ` [PATCH v2 12/12] ARCv2: Add a DT which enables THP Vineet Gupta
2015-10-01 6:02 ` [PATCH v2 00/12] THP support for ARC Vineet Gupta
2015-10-09 9:33 ` Vineet Gupta
2015-10-09 10:10 ` Kirill A. Shutemov
2015-10-09 11:29 ` Vineet Gupta
2015-10-09 11:43 ` Kirill A. Shutemov
2015-10-09 11:52 ` Vineet Gupta
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=1442918096-17454-6-git-send-email-vgupta@synopsys.com \
--to=vineet.gupta1@synopsys.com \
--cc=akpm@linux-foundation.org \
--cc=aneesh.kumar@linux.vnet.ibm.com \
--cc=kirill.shutemov@linux.intel.com \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=matthew.r.wilcox@intel.com \
--cc=mgorman@suse.de \
--cc=minchan@kernel.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).