diff options
author | Gerald Schaefer <gerald.schaefer@de.ibm.com> | 2012-10-08 19:30:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-09 03:22:29 -0400 |
commit | 46dcde735c9d8953bbd8d105ca6779e5b5300c28 (patch) | |
tree | 48298fd35d0ef0091541bad482f06202aba97ad3 | |
parent | e3ebcf64381188a2744a9829a4eb5c2b60f1974c (diff) |
thp: introduce pmdp_invalidate()
On s390, a valid page table entry must not be changed while it is attached
to any CPU. So instead of pmd_mknotpresent() and set_pmd_at(), an IDTE
operation would be necessary there. This patch introduces the
pmdp_invalidate() function, to allow architecture-specific
implementations.
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Hillf Danton <dhillf@gmail.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | include/asm-generic/pgtable.h | 5 | ||||
-rw-r--r-- | mm/huge_memory.c | 3 | ||||
-rw-r--r-- | mm/pgtable-generic.c | 11 |
3 files changed, 17 insertions, 2 deletions
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 044939f21c1..ebdd74fb8d6 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h | |||
@@ -170,6 +170,11 @@ extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable); | |||
170 | extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm); | 170 | extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm); |
171 | #endif | 171 | #endif |
172 | 172 | ||
173 | #ifndef __HAVE_ARCH_PMDP_INVALIDATE | ||
174 | extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, | ||
175 | pmd_t *pmdp); | ||
176 | #endif | ||
177 | |||
173 | #ifndef __HAVE_ARCH_PTE_SAME | 178 | #ifndef __HAVE_ARCH_PTE_SAME |
174 | static inline int pte_same(pte_t pte_a, pte_t pte_b) | 179 | static inline int pte_same(pte_t pte_a, pte_t pte_b) |
175 | { | 180 | { |
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 9ea6d195376..bec6243b696 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
@@ -1361,8 +1361,7 @@ static int __split_huge_page_map(struct page *page, | |||
1361 | * SMP TLB and finally we write the non-huge version | 1361 | * SMP TLB and finally we write the non-huge version |
1362 | * of the pmd entry with pmd_populate. | 1362 | * of the pmd entry with pmd_populate. |
1363 | */ | 1363 | */ |
1364 | set_pmd_at(mm, address, pmd, pmd_mknotpresent(*pmd)); | 1364 | pmdp_invalidate(vma, address, pmd); |
1365 | flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); | ||
1366 | pmd_populate(mm, pmd, pgtable); | 1365 | pmd_populate(mm, pmd, pgtable); |
1367 | ret = 1; | 1366 | ret = 1; |
1368 | } | 1367 | } |
diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c index 29867e083d3..e642627da6b 100644 --- a/mm/pgtable-generic.c +++ b/mm/pgtable-generic.c | |||
@@ -159,3 +159,14 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm) | |||
159 | } | 159 | } |
160 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | 160 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |
161 | #endif | 161 | #endif |
162 | |||
163 | #ifndef __HAVE_ARCH_PMDP_INVALIDATE | ||
164 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
165 | void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, | ||
166 | pmd_t *pmdp) | ||
167 | { | ||
168 | set_pmd_at(vma->vm_mm, address, pmdp, pmd_mknotpresent(*pmdp)); | ||
169 | flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); | ||
170 | } | ||
171 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | ||
172 | #endif | ||