Re: [PATCH] thp: move preallocated PTE page table on move_huge_pmd()
2013/12/4 Kirill A. Shutemov : > Andrey Wagin reported crash on VM_BUG_ON() in pgtable_pmd_page_dtor() > with fallowing backtrace: > > [] free_pgd_range+0x2bf/0x410 > [] free_pgtables+0xce/0x120 > [] unmap_region+0xe0/0x120 > [] ? move_page_tables+0x526/0x6b0 > [] do_munmap+0x249/0x360 > [] move_vma+0x144/0x270 > [] SyS_mremap+0x3b9/0x510 > [] system_call_fastpath+0x16/0x1b > > The crash can be reproduce with this test case: > > #define _GNU_SOURCE > #include > #include > #include > > #define MB (1024 * 1024UL) > #define GB (1024 * MB) > > int main(int argc, char **argv) > { > char *p; > int i; > > p = mmap((void *) GB, 10 * MB, PROT_READ | PROT_WRITE, > MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); > for (i = 0; i < 10 * MB; i += 4096) > p[i] = 1; > mremap(p, 10 * MB, 10 * MB, MREMAP_FIXED | MREMAP_MAYMOVE, 2 * GB); > return 0; > } > > Due to split PMD lock, we now store preallocated PTE tables for THP > pages per-PMD table. It means we need to move them to other PMD table > if huge PMD moved there. > > Signed-off-by: Kirill A. Shutemov > Reported-by: Andrey Vagin My tests were working for the night without any problem. Thanks for the quick response. Tested-by: Andrey Vagin > --- > mm/huge_memory.c | 12 +++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > index bccd5a628ea6..33a5dc492810 100644 > --- a/mm/huge_memory.c > +++ b/mm/huge_memory.c > @@ -1481,8 +1481,18 @@ int move_huge_pmd(struct vm_area_struct *vma, struct > vm_area_struct *new_vma, > pmd = pmdp_get_and_clear(mm, old_addr, old_pmd); > VM_BUG_ON(!pmd_none(*new_pmd)); > set_pmd_at(mm, new_addr, new_pmd, pmd_mksoft_dirty(pmd)); > - if (new_ptl != old_ptl) > + if (new_ptl != old_ptl) { > + pgtable_t pgtable; > + > + /* > +* Move preallocated PTE page table if new_pmd is on > +* different PMD page table. > +*/ > + pgtable = pgtable_trans_huge_withdraw(mm, old_pmd); > + pgtable_trans_huge_deposit(mm, new_pmd, pgtable); > + > spin_unlock(new_ptl); > + } > spin_unlock(old_ptl); > } > out: > -- > 1.8.4.4 > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] thp: move preallocated PTE page table on move_huge_pmd()
On Wed, Dec 04, 2013 at 09:03:06PM +0200, Kirill A. Shutemov wrote: > Andrey Wagin reported crash on VM_BUG_ON() in pgtable_pmd_page_dtor() > with fallowing backtrace: > > [] free_pgd_range+0x2bf/0x410 > [] free_pgtables+0xce/0x120 > [] unmap_region+0xe0/0x120 > [] ? move_page_tables+0x526/0x6b0 > [] do_munmap+0x249/0x360 > [] move_vma+0x144/0x270 > [] SyS_mremap+0x3b9/0x510 > [] system_call_fastpath+0x16/0x1b > > The crash can be reproduce with this test case: > > #define _GNU_SOURCE > #include > #include > #include > > #define MB (1024 * 1024UL) > #define GB (1024 * MB) > > int main(int argc, char **argv) > { > char *p; > int i; > > p = mmap((void *) GB, 10 * MB, PROT_READ | PROT_WRITE, > MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); > for (i = 0; i < 10 * MB; i += 4096) > p[i] = 1; > mremap(p, 10 * MB, 10 * MB, MREMAP_FIXED | MREMAP_MAYMOVE, 2 * GB); > return 0; > } > > Due to split PMD lock, we now store preallocated PTE tables for THP > pages per-PMD table. It means we need to move them to other PMD table > if huge PMD moved there. > > Signed-off-by: Kirill A. Shutemov > Reported-by: Andrey Vagin looks good to me. Reviewed-by: Naoya Horiguchi > --- > mm/huge_memory.c | 12 +++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > index bccd5a628ea6..33a5dc492810 100644 > --- a/mm/huge_memory.c > +++ b/mm/huge_memory.c > @@ -1481,8 +1481,18 @@ int move_huge_pmd(struct vm_area_struct *vma, struct > vm_area_struct *new_vma, > pmd = pmdp_get_and_clear(mm, old_addr, old_pmd); > VM_BUG_ON(!pmd_none(*new_pmd)); > set_pmd_at(mm, new_addr, new_pmd, pmd_mksoft_dirty(pmd)); > - if (new_ptl != old_ptl) > + if (new_ptl != old_ptl) { > + pgtable_t pgtable; > + > + /* > + * Move preallocated PTE page table if new_pmd is on > + * different PMD page table. > + */ > + pgtable = pgtable_trans_huge_withdraw(mm, old_pmd); > + pgtable_trans_huge_deposit(mm, new_pmd, pgtable); > + > spin_unlock(new_ptl); > + } > spin_unlock(old_ptl); > } > out: > -- > 1.8.4.4 > > -- > To unsubscribe, send a message with 'unsubscribe linux-mm' in > the body to majord...@kvack.org. For more info on Linux MM, > see: http://www.linux-mm.org/ . > Don't email: mailto:"d...@kvack.org";> em...@kvack.org > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] thp: move preallocated PTE page table on move_huge_pmd()
Andrey Wagin reported crash on VM_BUG_ON() in pgtable_pmd_page_dtor() with fallowing backtrace: [] free_pgd_range+0x2bf/0x410 [] free_pgtables+0xce/0x120 [] unmap_region+0xe0/0x120 [] ? move_page_tables+0x526/0x6b0 [] do_munmap+0x249/0x360 [] move_vma+0x144/0x270 [] SyS_mremap+0x3b9/0x510 [] system_call_fastpath+0x16/0x1b The crash can be reproduce with this test case: #define _GNU_SOURCE #include #include #include #define MB (1024 * 1024UL) #define GB (1024 * MB) int main(int argc, char **argv) { char *p; int i; p = mmap((void *) GB, 10 * MB, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); for (i = 0; i < 10 * MB; i += 4096) p[i] = 1; mremap(p, 10 * MB, 10 * MB, MREMAP_FIXED | MREMAP_MAYMOVE, 2 * GB); return 0; } Due to split PMD lock, we now store preallocated PTE tables for THP pages per-PMD table. It means we need to move them to other PMD table if huge PMD moved there. Signed-off-by: Kirill A. Shutemov Reported-by: Andrey Vagin --- mm/huge_memory.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index bccd5a628ea6..33a5dc492810 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1481,8 +1481,18 @@ int move_huge_pmd(struct vm_area_struct *vma, struct vm_area_struct *new_vma, pmd = pmdp_get_and_clear(mm, old_addr, old_pmd); VM_BUG_ON(!pmd_none(*new_pmd)); set_pmd_at(mm, new_addr, new_pmd, pmd_mksoft_dirty(pmd)); - if (new_ptl != old_ptl) + if (new_ptl != old_ptl) { + pgtable_t pgtable; + + /* +* Move preallocated PTE page table if new_pmd is on +* different PMD page table. +*/ + pgtable = pgtable_trans_huge_withdraw(mm, old_pmd); + pgtable_trans_huge_deposit(mm, new_pmd, pgtable); + spin_unlock(new_ptl); + } spin_unlock(old_ptl); } out: -- 1.8.4.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/