diff options
| author | Kirill A. Shutemov <kirill.shutemov@linux.intel.com> | 2018-01-31 19:17:43 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-31 20:18:37 -0500 |
| commit | c58f0bb77ed8bf93dfdde762b01cb67eebbdfc29 (patch) | |
| tree | a18b4f4fe6b9ec8df74deec51eb81d053c12ed89 /include | |
| parent | 146500e9604cece72d4bed1cd15fac789220c795 (diff) | |
asm-generic: provide generic_pmdp_establish()
Patch series "Do not lose dirty bit on THP pages", v4.
Vlastimil noted that pmdp_invalidate() is not atomic and we can lose
dirty and access bits if CPU sets them after pmdp dereference, but
before set_pmd_at().
The bug can lead to data loss, but the race window is tiny and I haven't
seen any reports that suggested that it happens in reality. So I don't
think it worth sending it to stable.
Unfortunately, there's no way to address the issue in a generic way. We
need to fix all architectures that support THP one-by-one.
All architectures that have THP supported have to provide atomic
pmdp_invalidate() that returns previous value.
If generic implementation of pmdp_invalidate() is used, architecture
needs to provide atomic pmdp_estabish().
pmdp_estabish() is not used out-side generic implementation of
pmdp_invalidate() so far, but I think this can change in the future.
This patch (of 12):
This is an implementation of pmdp_establish() that is only suitable for
an architecture that doesn't have hardware dirty/accessed bits. In this
case we can't race with CPU which sets these bits and non-atomic
approach is fine.
Link: http://lkml.kernel.org/r/20171213105756.69879-2-kirill.shutemov@linux.intel.com
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: David Daney <david.daney@cavium.com>
Cc: David Miller <davem@davemloft.net>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Nitin Gupta <nitin.m.gupta@oracle.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vineet Gupta <vgupta@synopsys.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/asm-generic/pgtable.h | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 868e68561f91..118ca2eb7a32 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h | |||
| @@ -309,6 +309,21 @@ extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, | |||
| 309 | extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); | 309 | extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); |
| 310 | #endif | 310 | #endif |
| 311 | 311 | ||
| 312 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
| 313 | /* | ||
| 314 | * This is an implementation of pmdp_establish() that is only suitable for an | ||
| 315 | * architecture that doesn't have hardware dirty/accessed bits. In this case we | ||
| 316 | * can't race with CPU which sets these bits and non-atomic aproach is fine. | ||
| 317 | */ | ||
| 318 | static inline pmd_t generic_pmdp_establish(struct vm_area_struct *vma, | ||
| 319 | unsigned long address, pmd_t *pmdp, pmd_t pmd) | ||
| 320 | { | ||
| 321 | pmd_t old_pmd = *pmdp; | ||
| 322 | set_pmd_at(vma->vm_mm, address, pmdp, pmd); | ||
| 323 | return old_pmd; | ||
| 324 | } | ||
| 325 | #endif | ||
| 326 | |||
| 312 | #ifndef __HAVE_ARCH_PMDP_INVALIDATE | 327 | #ifndef __HAVE_ARCH_PMDP_INVALIDATE |
| 313 | extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, | 328 | extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, |
| 314 | pmd_t *pmdp); | 329 | pmd_t *pmdp); |
