diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/hugetlb.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 2ef66a2a148d..6df8065039eb 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -2237,6 +2237,12 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2237 | + (vma->vm_pgoff >> PAGE_SHIFT); | 2237 | + (vma->vm_pgoff >> PAGE_SHIFT); |
2238 | mapping = (struct address_space *)page_private(page); | 2238 | mapping = (struct address_space *)page_private(page); |
2239 | 2239 | ||
2240 | /* | ||
2241 | * Take the mapping lock for the duration of the table walk. As | ||
2242 | * this mapping should be shared between all the VMAs, | ||
2243 | * __unmap_hugepage_range() is called as the lock is already held | ||
2244 | */ | ||
2245 | spin_lock(&mapping->i_mmap_lock); | ||
2240 | vma_prio_tree_foreach(iter_vma, &iter, &mapping->i_mmap, pgoff, pgoff) { | 2246 | vma_prio_tree_foreach(iter_vma, &iter, &mapping->i_mmap, pgoff, pgoff) { |
2241 | /* Do not unmap the current VMA */ | 2247 | /* Do not unmap the current VMA */ |
2242 | if (iter_vma == vma) | 2248 | if (iter_vma == vma) |
@@ -2250,10 +2256,11 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2250 | * from the time of fork. This would look like data corruption | 2256 | * from the time of fork. This would look like data corruption |
2251 | */ | 2257 | */ |
2252 | if (!is_vma_resv_set(iter_vma, HPAGE_RESV_OWNER)) | 2258 | if (!is_vma_resv_set(iter_vma, HPAGE_RESV_OWNER)) |
2253 | unmap_hugepage_range(iter_vma, | 2259 | __unmap_hugepage_range(iter_vma, |
2254 | address, address + huge_page_size(h), | 2260 | address, address + huge_page_size(h), |
2255 | page); | 2261 | page); |
2256 | } | 2262 | } |
2263 | spin_unlock(&mapping->i_mmap_lock); | ||
2257 | 2264 | ||
2258 | return 1; | 2265 | return 1; |
2259 | } | 2266 | } |