Blame view
mm/pgtable-generic.c
4.6 KB
e2cda3226 thp: add pmd mang... |
1 2 3 4 5 6 7 |
/* * mm/pgtable-generic.c * * Generic pgtable methods declared in asm-generic/pgtable.h * * Copyright (C) 2010 Linus Torvalds */ |
f95ba941d mm/pgtable-generi... |
8 |
#include <linux/pagemap.h> |
e2cda3226 thp: add pmd mang... |
9 10 11 12 13 |
#include <asm/tlb.h> #include <asm-generic/pgtable.h> #ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS /* |
cef23d9db mm,generic: only ... |
14 15 |
* Only sets the access flags (dirty, accessed), as well as write * permission. Furthermore, we know it always gets set to a "more |
e2cda3226 thp: add pmd mang... |
16 17 18 19 20 21 22 23 24 25 26 27 28 |
* permissive" setting, which allows most architectures to optimize * this. We return whether the PTE actually changed, which in turn * instructs the caller to do things like update__mmu_cache. This * used to be done in the caller, but sparc needs minor faults to * force that call on sun4c so we changed this macro slightly */ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, pte_t *ptep, pte_t entry, int dirty) { int changed = !pte_same(*ptep, entry); if (changed) { set_pte_at(vma->vm_mm, address, ptep, entry); |
cef23d9db mm,generic: only ... |
29 |
flush_tlb_fix_spurious_fault(vma, address); |
e2cda3226 thp: add pmd mang... |
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
} return changed; } #endif #ifndef __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS int pmdp_set_access_flags(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp, pmd_t entry, int dirty) { #ifdef CONFIG_TRANSPARENT_HUGEPAGE int changed = !pmd_same(*pmdp, entry); VM_BUG_ON(address & ~HPAGE_PMD_MASK); if (changed) { set_pmd_at(vma->vm_mm, address, pmdp, entry); flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); } return changed; #else /* CONFIG_TRANSPARENT_HUGEPAGE */ BUG(); return 0; #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ } #endif #ifndef __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH int ptep_clear_flush_young(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) { int young; young = ptep_test_and_clear_young(vma, address, ptep); if (young) flush_tlb_page(vma, address); return young; } #endif #ifndef __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH int pmdp_clear_flush_young(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp) { int young; |
d8c37c480 thp: add HPAGE_PM... |
72 73 74 |
#ifdef CONFIG_TRANSPARENT_HUGEPAGE VM_BUG_ON(address & ~HPAGE_PMD_MASK); #else |
e2cda3226 thp: add pmd mang... |
75 76 |
BUG(); #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |
e2cda3226 thp: add pmd mang... |
77 78 79 80 81 82 83 84 85 86 87 88 89 |
young = pmdp_test_and_clear_young(vma, address, pmdp); if (young) flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); return young; } #endif #ifndef __HAVE_ARCH_PTEP_CLEAR_FLUSH pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) { pte_t pte; pte = ptep_get_and_clear((vma)->vm_mm, address, ptep); |
8d1acce45 mm: Only flush th... |
90 91 |
if (pte_accessible(pte)) flush_tlb_page(vma, address); |
e2cda3226 thp: add pmd mang... |
92 93 94 95 96 |
return pte; } #endif #ifndef __HAVE_ARCH_PMDP_CLEAR_FLUSH |
b3697c025 fix non-x86 build... |
97 |
#ifdef CONFIG_TRANSPARENT_HUGEPAGE |
e2cda3226 thp: add pmd mang... |
98 99 100 101 |
pmd_t pmdp_clear_flush(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp) { pmd_t pmd; |
e2cda3226 thp: add pmd mang... |
102 103 104 105 106 |
VM_BUG_ON(address & ~HPAGE_PMD_MASK); pmd = pmdp_get_and_clear(vma->vm_mm, address, pmdp); flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); return pmd; } |
b3697c025 fix non-x86 build... |
107 |
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |
e2cda3226 thp: add pmd mang... |
108 109 110 |
#endif #ifndef __HAVE_ARCH_PMDP_SPLITTING_FLUSH |
b3697c025 fix non-x86 build... |
111 |
#ifdef CONFIG_TRANSPARENT_HUGEPAGE |
73636b1aa arch/tile: allow ... |
112 113 |
void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp) |
e2cda3226 thp: add pmd mang... |
114 |
{ |
e2cda3226 thp: add pmd mang... |
115 116 117 118 119 |
pmd_t pmd = pmd_mksplitting(*pmdp); VM_BUG_ON(address & ~HPAGE_PMD_MASK); set_pmd_at(vma->vm_mm, address, pmdp, pmd); /* tlb flush only to serialize against gup-fast */ flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); |
e2cda3226 thp: add pmd mang... |
120 |
} |
b3697c025 fix non-x86 build... |
121 |
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |
e2cda3226 thp: add pmd mang... |
122 |
#endif |
e3ebcf643 thp: remove assum... |
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
#ifndef __HAVE_ARCH_PGTABLE_DEPOSIT #ifdef CONFIG_TRANSPARENT_HUGEPAGE void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable) { assert_spin_locked(&mm->page_table_lock); /* FIFO */ if (!mm->pmd_huge_pte) INIT_LIST_HEAD(&pgtable->lru); else list_add(&pgtable->lru, &mm->pmd_huge_pte->lru); mm->pmd_huge_pte = pgtable; } #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ #endif #ifndef __HAVE_ARCH_PGTABLE_WITHDRAW #ifdef CONFIG_TRANSPARENT_HUGEPAGE /* no "address" argument so destroys page coloring of some arch */ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm) { pgtable_t pgtable; assert_spin_locked(&mm->page_table_lock); /* FIFO */ pgtable = mm->pmd_huge_pte; if (list_empty(&pgtable->lru)) mm->pmd_huge_pte = NULL; else { mm->pmd_huge_pte = list_entry(pgtable->lru.next, struct page, lru); list_del(&pgtable->lru); } return pgtable; } #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ #endif |
46dcde735 thp: introduce pm... |
162 163 164 165 166 167 168 169 170 171 172 |
#ifndef __HAVE_ARCH_PMDP_INVALIDATE #ifdef CONFIG_TRANSPARENT_HUGEPAGE void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp) { set_pmd_at(vma->vm_mm, address, pmdp, pmd_mknotpresent(*pmdp)); flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); } #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ #endif |