diff options
Diffstat (limited to 'mm')
| -rw-r--r-- | mm/filemap_xip.c | 2 | ||||
| -rw-r--r-- | mm/rmap.c | 14 |
2 files changed, 10 insertions, 6 deletions
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c index 380ab402d711..8b710ca13247 100644 --- a/mm/filemap_xip.c +++ b/mm/filemap_xip.c | |||
| @@ -185,7 +185,7 @@ __xip_unmap (struct address_space * mapping, | |||
| 185 | address = vma->vm_start + | 185 | address = vma->vm_start + |
| 186 | ((pgoff - vma->vm_pgoff) << PAGE_SHIFT); | 186 | ((pgoff - vma->vm_pgoff) << PAGE_SHIFT); |
| 187 | BUG_ON(address < vma->vm_start || address >= vma->vm_end); | 187 | BUG_ON(address < vma->vm_start || address >= vma->vm_end); |
| 188 | pte = page_check_address(page, mm, address, &ptl); | 188 | pte = page_check_address(page, mm, address, &ptl, 1); |
| 189 | if (pte) { | 189 | if (pte) { |
| 190 | /* Nuke the page table entry. */ | 190 | /* Nuke the page table entry. */ |
| 191 | flush_cache_page(vma, address, pte_pfn(*pte)); | 191 | flush_cache_page(vma, address, pte_pfn(*pte)); |
| @@ -224,10 +224,14 @@ unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma) | |||
| 224 | /* | 224 | /* |
| 225 | * Check that @page is mapped at @address into @mm. | 225 | * Check that @page is mapped at @address into @mm. |
| 226 | * | 226 | * |
| 227 | * If @sync is false, page_check_address may perform a racy check to avoid | ||
| 228 | * the page table lock when the pte is not present (helpful when reclaiming | ||
| 229 | * highly shared pages). | ||
| 230 | * | ||
| 227 | * On success returns with pte mapped and locked. | 231 | * On success returns with pte mapped and locked. |
| 228 | */ | 232 | */ |
| 229 | pte_t *page_check_address(struct page *page, struct mm_struct *mm, | 233 | pte_t *page_check_address(struct page *page, struct mm_struct *mm, |
| 230 | unsigned long address, spinlock_t **ptlp) | 234 | unsigned long address, spinlock_t **ptlp, int sync) |
| 231 | { | 235 | { |
| 232 | pgd_t *pgd; | 236 | pgd_t *pgd; |
| 233 | pud_t *pud; | 237 | pud_t *pud; |
| @@ -249,7 +253,7 @@ pte_t *page_check_address(struct page *page, struct mm_struct *mm, | |||
| 249 | 253 | ||
| 250 | pte = pte_offset_map(pmd, address); | 254 | pte = pte_offset_map(pmd, address); |
| 251 | /* Make a quick check before getting the lock */ | 255 | /* Make a quick check before getting the lock */ |
| 252 | if (!pte_present(*pte)) { | 256 | if (!sync && !pte_present(*pte)) { |
| 253 | pte_unmap(pte); | 257 | pte_unmap(pte); |
| 254 | return NULL; | 258 | return NULL; |
| 255 | } | 259 | } |
| @@ -281,7 +285,7 @@ static int page_referenced_one(struct page *page, | |||
| 281 | if (address == -EFAULT) | 285 | if (address == -EFAULT) |
| 282 | goto out; | 286 | goto out; |
| 283 | 287 | ||
| 284 | pte = page_check_address(page, mm, address, &ptl); | 288 | pte = page_check_address(page, mm, address, &ptl, 0); |
| 285 | if (!pte) | 289 | if (!pte) |
| 286 | goto out; | 290 | goto out; |
| 287 | 291 | ||
| @@ -450,7 +454,7 @@ static int page_mkclean_one(struct page *page, struct vm_area_struct *vma) | |||
| 450 | if (address == -EFAULT) | 454 | if (address == -EFAULT) |
| 451 | goto out; | 455 | goto out; |
| 452 | 456 | ||
| 453 | pte = page_check_address(page, mm, address, &ptl); | 457 | pte = page_check_address(page, mm, address, &ptl, 1); |
| 454 | if (!pte) | 458 | if (!pte) |
| 455 | goto out; | 459 | goto out; |
| 456 | 460 | ||
| @@ -704,7 +708,7 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma, | |||
| 704 | if (address == -EFAULT) | 708 | if (address == -EFAULT) |
| 705 | goto out; | 709 | goto out; |
| 706 | 710 | ||
| 707 | pte = page_check_address(page, mm, address, &ptl); | 711 | pte = page_check_address(page, mm, address, &ptl, 0); |
| 708 | if (!pte) | 712 | if (!pte) |
| 709 | goto out; | 713 | goto out; |
| 710 | 714 | ||
