Skip to content

Commit 6acb881

Browse files
Nitin Guptagregkh
authored andcommitted
sparc64: update pmdp_invalidate() to return old pmd value
[ Upstream commit a8e654f ] It's required to avoid losing dirty and accessed bits. [[email protected]: add a `do' to the do-while loop] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Nitin Gupta <[email protected]> Signed-off-by: Kirill A. Shutemov <[email protected]> Cc: David Miller <[email protected]> Cc: Vlastimil Babka <[email protected]> Cc: Andrea Arcangeli <[email protected]> Cc: Michal Hocko <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]> Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 78185a9 commit 6acb881

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

arch/sparc/include/asm/pgtable_64.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,7 @@ void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
980980
pmd_t *pmd);
981981

982982
#define __HAVE_ARCH_PMDP_INVALIDATE
983-
extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
983+
extern pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
984984
pmd_t *pmdp);
985985

986986
#define __HAVE_ARCH_PGTABLE_DEPOSIT

arch/sparc/mm/tlb.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -219,17 +219,28 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
219219
}
220220
}
221221

222+
static inline pmd_t pmdp_establish(struct vm_area_struct *vma,
223+
unsigned long address, pmd_t *pmdp, pmd_t pmd)
224+
{
225+
pmd_t old;
226+
227+
do {
228+
old = *pmdp;
229+
} while (cmpxchg64(&pmdp->pmd, old.pmd, pmd.pmd) != old.pmd);
230+
231+
return old;
232+
}
233+
222234
/*
223235
* This routine is only called when splitting a THP
224236
*/
225-
void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
237+
pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
226238
pmd_t *pmdp)
227239
{
228-
pmd_t entry = *pmdp;
229-
230-
pmd_val(entry) &= ~_PAGE_VALID;
240+
pmd_t old, entry;
231241

232-
set_pmd_at(vma->vm_mm, address, pmdp, entry);
242+
entry = __pmd(pmd_val(*pmdp) & ~_PAGE_VALID);
243+
old = pmdp_establish(vma, address, pmdp, entry);
233244
flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
234245

235246
/*
@@ -240,6 +251,8 @@ void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
240251
if ((pmd_val(entry) & _PAGE_PMD_HUGE) &&
241252
!is_huge_zero_page(pmd_page(entry)))
242253
(vma->vm_mm)->context.thp_pte_count--;
254+
255+
return old;
243256
}
244257

245258
void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,

0 commit comments

Comments
 (0)