diff options
| author | Tony Luck <tony.luck@intel.com> | 2005-05-17 18:53:14 -0400 |
|---|---|---|
| committer | Tony Luck <tony.luck@intel.com> | 2005-05-17 18:53:14 -0400 |
| commit | 325a479c4c110db278ef3361460a48c4093252cc (patch) | |
| tree | bcfbf4d0647d9442045639a5c19da59d55190e81 /mm/rmap.c | |
| parent | ebcc80c1b6629a445f7471cc1ddb48faf8a84e70 (diff) | |
| parent | 7f9eaedf894dbaa08c157832e9a6c9c03ffed1ed (diff) | |
Merge with temp tree to get David's gdb inferior calls patch
Diffstat (limited to 'mm/rmap.c')
| -rw-r--r-- | mm/rmap.c | 113 |
1 files changed, 50 insertions, 63 deletions
| @@ -243,6 +243,42 @@ unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma) | |||
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | /* | 245 | /* |
| 246 | * Check that @page is mapped at @address into @mm. | ||
| 247 | * | ||
| 248 | * On success returns with mapped pte and locked mm->page_table_lock. | ||
| 249 | */ | ||
| 250 | static pte_t *page_check_address(struct page *page, struct mm_struct *mm, | ||
| 251 | unsigned long address) | ||
| 252 | { | ||
| 253 | pgd_t *pgd; | ||
| 254 | pud_t *pud; | ||
| 255 | pmd_t *pmd; | ||
| 256 | pte_t *pte; | ||
| 257 | |||
| 258 | /* | ||
| 259 | * We need the page_table_lock to protect us from page faults, | ||
| 260 | * munmap, fork, etc... | ||
| 261 | */ | ||
| 262 | spin_lock(&mm->page_table_lock); | ||
| 263 | pgd = pgd_offset(mm, address); | ||
| 264 | if (likely(pgd_present(*pgd))) { | ||
| 265 | pud = pud_offset(pgd, address); | ||
| 266 | if (likely(pud_present(*pud))) { | ||
| 267 | pmd = pmd_offset(pud, address); | ||
| 268 | if (likely(pmd_present(*pmd))) { | ||
| 269 | pte = pte_offset_map(pmd, address); | ||
| 270 | if (likely(pte_present(*pte) && | ||
| 271 | page_to_pfn(page) == pte_pfn(*pte))) | ||
| 272 | return pte; | ||
| 273 | pte_unmap(pte); | ||
| 274 | } | ||
| 275 | } | ||
| 276 | } | ||
| 277 | spin_unlock(&mm->page_table_lock); | ||
| 278 | return ERR_PTR(-ENOENT); | ||
| 279 | } | ||
| 280 | |||
| 281 | /* | ||
| 246 | * Subfunctions of page_referenced: page_referenced_one called | 282 | * Subfunctions of page_referenced: page_referenced_one called |
| 247 | * repeatedly from either page_referenced_anon or page_referenced_file. | 283 | * repeatedly from either page_referenced_anon or page_referenced_file. |
| 248 | */ | 284 | */ |
| @@ -251,9 +287,6 @@ static int page_referenced_one(struct page *page, | |||
| 251 | { | 287 | { |
| 252 | struct mm_struct *mm = vma->vm_mm; | 288 | struct mm_struct *mm = vma->vm_mm; |
| 253 | unsigned long address; | 289 | unsigned long address; |
| 254 | pgd_t *pgd; | ||
| 255 | pud_t *pud; | ||
| 256 | pmd_t *pmd; | ||
| 257 | pte_t *pte; | 290 | pte_t *pte; |
| 258 | int referenced = 0; | 291 | int referenced = 0; |
| 259 | 292 | ||
| @@ -263,39 +296,18 @@ static int page_referenced_one(struct page *page, | |||
| 263 | if (address == -EFAULT) | 296 | if (address == -EFAULT) |
| 264 | goto out; | 297 | goto out; |
| 265 | 298 | ||
| 266 | spin_lock(&mm->page_table_lock); | 299 | pte = page_check_address(page, mm, address); |
| 267 | 300 | if (!IS_ERR(pte)) { | |
| 268 | pgd = pgd_offset(mm, address); | 301 | if (ptep_clear_flush_young(vma, address, pte)) |
| 269 | if (!pgd_present(*pgd)) | 302 | referenced++; |
| 270 | goto out_unlock; | ||
| 271 | |||
| 272 | pud = pud_offset(pgd, address); | ||
| 273 | if (!pud_present(*pud)) | ||
| 274 | goto out_unlock; | ||
| 275 | |||
| 276 | pmd = pmd_offset(pud, address); | ||
| 277 | if (!pmd_present(*pmd)) | ||
| 278 | goto out_unlock; | ||
| 279 | |||
| 280 | pte = pte_offset_map(pmd, address); | ||
| 281 | if (!pte_present(*pte)) | ||
| 282 | goto out_unmap; | ||
| 283 | |||
| 284 | if (page_to_pfn(page) != pte_pfn(*pte)) | ||
| 285 | goto out_unmap; | ||
| 286 | |||
| 287 | if (ptep_clear_flush_young(vma, address, pte)) | ||
| 288 | referenced++; | ||
| 289 | |||
| 290 | if (mm != current->mm && !ignore_token && has_swap_token(mm)) | ||
| 291 | referenced++; | ||
| 292 | 303 | ||
| 293 | (*mapcount)--; | 304 | if (mm != current->mm && !ignore_token && has_swap_token(mm)) |
| 305 | referenced++; | ||
| 294 | 306 | ||
| 295 | out_unmap: | 307 | (*mapcount)--; |
| 296 | pte_unmap(pte); | 308 | pte_unmap(pte); |
| 297 | out_unlock: | 309 | spin_unlock(&mm->page_table_lock); |
| 298 | spin_unlock(&mm->page_table_lock); | 310 | } |
| 299 | out: | 311 | out: |
| 300 | return referenced; | 312 | return referenced; |
| 301 | } | 313 | } |
| @@ -502,9 +514,6 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma) | |||
| 502 | { | 514 | { |
| 503 | struct mm_struct *mm = vma->vm_mm; | 515 | struct mm_struct *mm = vma->vm_mm; |
| 504 | unsigned long address; | 516 | unsigned long address; |
| 505 | pgd_t *pgd; | ||
| 506 | pud_t *pud; | ||
| 507 | pmd_t *pmd; | ||
| 508 | pte_t *pte; | 517 | pte_t *pte; |
| 509 | pte_t pteval; | 518 | pte_t pteval; |
| 510 | int ret = SWAP_AGAIN; | 519 | int ret = SWAP_AGAIN; |
| @@ -515,30 +524,9 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma) | |||
| 515 | if (address == -EFAULT) | 524 | if (address == -EFAULT) |
| 516 | goto out; | 525 | goto out; |
| 517 | 526 | ||
| 518 | /* | 527 | pte = page_check_address(page, mm, address); |
| 519 | * We need the page_table_lock to protect us from page faults, | 528 | if (IS_ERR(pte)) |
| 520 | * munmap, fork, etc... | 529 | goto out; |
| 521 | */ | ||
| 522 | spin_lock(&mm->page_table_lock); | ||
| 523 | |||
| 524 | pgd = pgd_offset(mm, address); | ||
| 525 | if (!pgd_present(*pgd)) | ||
| 526 | goto out_unlock; | ||
| 527 | |||
| 528 | pud = pud_offset(pgd, address); | ||
| 529 | if (!pud_present(*pud)) | ||
| 530 | goto out_unlock; | ||
| 531 | |||
| 532 | pmd = pmd_offset(pud, address); | ||
| 533 | if (!pmd_present(*pmd)) | ||
| 534 | goto out_unlock; | ||
| 535 | |||
| 536 | pte = pte_offset_map(pmd, address); | ||
| 537 | if (!pte_present(*pte)) | ||
| 538 | goto out_unmap; | ||
| 539 | |||
| 540 | if (page_to_pfn(page) != pte_pfn(*pte)) | ||
| 541 | goto out_unmap; | ||
| 542 | 530 | ||
| 543 | /* | 531 | /* |
| 544 | * If the page is mlock()d, we cannot swap it out. | 532 | * If the page is mlock()d, we cannot swap it out. |
| @@ -604,7 +592,6 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma) | |||
| 604 | 592 | ||
| 605 | out_unmap: | 593 | out_unmap: |
| 606 | pte_unmap(pte); | 594 | pte_unmap(pte); |
| 607 | out_unlock: | ||
| 608 | spin_unlock(&mm->page_table_lock); | 595 | spin_unlock(&mm->page_table_lock); |
| 609 | out: | 596 | out: |
| 610 | return ret; | 597 | return ret; |
| @@ -708,7 +695,6 @@ static void try_to_unmap_cluster(unsigned long cursor, | |||
| 708 | } | 695 | } |
| 709 | 696 | ||
| 710 | pte_unmap(pte); | 697 | pte_unmap(pte); |
| 711 | |||
| 712 | out_unlock: | 698 | out_unlock: |
| 713 | spin_unlock(&mm->page_table_lock); | 699 | spin_unlock(&mm->page_table_lock); |
| 714 | } | 700 | } |
| @@ -860,3 +846,4 @@ int try_to_unmap(struct page *page) | |||
| 860 | ret = SWAP_SUCCESS; | 846 | ret = SWAP_SUCCESS; |
| 861 | return ret; | 847 | return ret; |
| 862 | } | 848 | } |
| 849 | |||
