From 04e6a6f955f4bdd16c49cdf0bfe7cf5eb9618095 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 8 Oct 2012 16:34:03 -0700 Subject: [PATCH] --- yaml --- r: 332475 b: refs/heads/master c: b676b293fb48672904ee1b9828cb50b4eed01717 h: refs/heads/master i: 332473: edcbcf8eae7111bac9f4a9773947c02b18d5581f 332471: f8939cf603d68e9a23e623edf5ede20758051884 v: v3 --- [refs] | 2 +- trunk/include/linux/huge_mm.h | 2 +- trunk/mm/huge_memory.c | 11 ++++++++++- trunk/mm/memory.c | 2 +- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index a508fc08817a..ff135b3aab19 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e90bdb7f52f94204c78fb40b0804645defdebd71 +refs/heads/master: b676b293fb48672904ee1b9828cb50b4eed01717 diff --git a/trunk/include/linux/huge_mm.h b/trunk/include/linux/huge_mm.h index 6ab47af5a849..b31cb7da0346 100644 --- a/trunk/include/linux/huge_mm.h +++ b/trunk/include/linux/huge_mm.h @@ -11,7 +11,7 @@ extern int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm, extern int do_huge_pmd_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, pmd_t *pmd, pmd_t orig_pmd); -extern struct page *follow_trans_huge_pmd(struct mm_struct *mm, +extern struct page *follow_trans_huge_pmd(struct vm_area_struct *vma, unsigned long addr, pmd_t *pmd, unsigned int flags); diff --git a/trunk/mm/huge_memory.c b/trunk/mm/huge_memory.c index 08a943b9cf95..3a8d6b7d95db 100644 --- a/trunk/mm/huge_memory.c +++ b/trunk/mm/huge_memory.c @@ -971,11 +971,12 @@ int do_huge_pmd_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, return ret; } -struct page *follow_trans_huge_pmd(struct mm_struct *mm, +struct page *follow_trans_huge_pmd(struct vm_area_struct *vma, unsigned long addr, pmd_t *pmd, unsigned int flags) { + struct mm_struct *mm = vma->vm_mm; struct page *page = NULL; assert_spin_locked(&mm->page_table_lock); @@ -998,6 +999,14 @@ struct page *follow_trans_huge_pmd(struct mm_struct *mm, _pmd = pmd_mkyoung(pmd_mkdirty(*pmd)); set_pmd_at(mm, addr & HPAGE_PMD_MASK, pmd, _pmd); } + if ((flags & FOLL_MLOCK) && (vma->vm_flags & VM_LOCKED)) { + if (page->mapping && trylock_page(page)) { + lru_add_drain(); + if (page->mapping) + mlock_vma_page(page); + unlock_page(page); + } + } page += (addr & ~HPAGE_PMD_MASK) >> PAGE_SHIFT; VM_BUG_ON(!PageCompound(page)); if (flags & FOLL_GET) diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index 45bb6d296b6f..fb135ba4aba9 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -1528,7 +1528,7 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, spin_unlock(&mm->page_table_lock); wait_split_huge_page(vma->anon_vma, pmd); } else { - page = follow_trans_huge_pmd(mm, address, + page = follow_trans_huge_pmd(vma, address, pmd, flags); spin_unlock(&mm->page_table_lock); goto out;