We need to mirror logic in move_ptes() wrt need_rmap_locks to get proper serialization file THP. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> --- mm/mremap.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/mm/mremap.c b/mm/mremap.c index 3fa0a467df66..88fa7ab1a8ce 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -192,17 +192,27 @@ unsigned long move_page_tables(struct vm_area_struct *vma, break; if (pmd_trans_huge(*old_pmd)) { if (extent == HPAGE_PMD_SIZE) { + struct address_space *mapping = NULL; + struct anon_vma *anon_vma = NULL; bool moved; - VM_BUG_ON_VMA(vma->vm_file || !vma->anon_vma, - vma); /* See comment in move_ptes() */ - if (need_rmap_locks) - anon_vma_lock_write(vma->anon_vma); + if (need_rmap_locks) { + if (vma->vm_file) { + mapping = vma->vm_file->f_mapping; + i_mmap_lock_write(mapping); + } + if (vma->anon_vma) { + anon_vma = vma->anon_vma; + anon_vma_lock_write(anon_vma); + } + } moved = move_huge_pmd(vma, new_vma, old_addr, new_addr, old_end, old_pmd, new_pmd); - if (need_rmap_locks) - anon_vma_unlock_write(vma->anon_vma); + if (anon_vma) + anon_vma_unlock_write(anon_vma); + if (mapping) + i_mmap_unlock_write(mapping); if (moved) { need_flush = true; continue; -- 2.8.0.rc3 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html