mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
thp: call pmdp_invalidate() with correct virtual address
Sebastian Ott and Gerald Schaefer reported random crashes on s390. It was bisected to my THP refcounting patchset. The problem is that pmdp_invalidated() called with wrong virtual address. It got offset up by HPAGE_PMD_SIZE by loop over ptes. The solution is to introduce new variable to be used in loop and don't touch 'haddr'. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Reported-and-tested-by: Gerald Schaefer <gerald.schaefer@de.ibm.com> Reported-and-tested-by Sebastian Ott <sebott@linux.vnet.ibm.com> Reviewed-by: Will Deacon <will.deacon@arm.com> Cc: Christian Borntraeger <borntraeger@de.ibm.com> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Sasha Levin <sasha.levin@oracle.com> Cc: Jerome Marchand <jmarchan@redhat.com> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
84e54c46b2
commit
2ac015e293
@ -2836,6 +2836,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
|
||||
pgtable_t pgtable;
|
||||
pmd_t _pmd;
|
||||
bool young, write, dirty;
|
||||
unsigned long addr;
|
||||
int i;
|
||||
|
||||
VM_BUG_ON(haddr & ~HPAGE_PMD_MASK);
|
||||
@ -2865,7 +2866,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
|
||||
pgtable = pgtable_trans_huge_withdraw(mm, pmd);
|
||||
pmd_populate(mm, &_pmd, pgtable);
|
||||
|
||||
for (i = 0; i < HPAGE_PMD_NR; i++, haddr += PAGE_SIZE) {
|
||||
for (i = 0, addr = haddr; i < HPAGE_PMD_NR; i++, addr += PAGE_SIZE) {
|
||||
pte_t entry, *pte;
|
||||
/*
|
||||
* Note that NUMA hinting access restrictions are not
|
||||
@ -2886,9 +2887,9 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
|
||||
}
|
||||
if (dirty)
|
||||
SetPageDirty(page + i);
|
||||
pte = pte_offset_map(&_pmd, haddr);
|
||||
pte = pte_offset_map(&_pmd, addr);
|
||||
BUG_ON(!pte_none(*pte));
|
||||
set_pte_at(mm, haddr, pte, entry);
|
||||
set_pte_at(mm, addr, pte, entry);
|
||||
atomic_inc(&page[i]._mapcount);
|
||||
pte_unmap(pte);
|
||||
}
|
||||
@ -2938,7 +2939,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
|
||||
pmd_populate(mm, pmd, pgtable);
|
||||
|
||||
if (freeze) {
|
||||
for (i = 0; i < HPAGE_PMD_NR; i++, haddr += PAGE_SIZE) {
|
||||
for (i = 0; i < HPAGE_PMD_NR; i++) {
|
||||
page_remove_rmap(page + i, false);
|
||||
put_page(page + i);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user