diff options
Diffstat (limited to 'fs/proc/task_mmu.c')
| -rw-r--r-- | fs/proc/task_mmu.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index f0ec9edab2f3..85b0ef890b28 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
| @@ -423,7 +423,7 @@ struct mem_size_stats { | |||
| 423 | }; | 423 | }; |
| 424 | 424 | ||
| 425 | static void smaps_account(struct mem_size_stats *mss, struct page *page, | 425 | static void smaps_account(struct mem_size_stats *mss, struct page *page, |
| 426 | bool compound, bool young, bool dirty) | 426 | bool compound, bool young, bool dirty, bool locked) |
| 427 | { | 427 | { |
| 428 | int i, nr = compound ? 1 << compound_order(page) : 1; | 428 | int i, nr = compound ? 1 << compound_order(page) : 1; |
| 429 | unsigned long size = nr * PAGE_SIZE; | 429 | unsigned long size = nr * PAGE_SIZE; |
| @@ -450,24 +450,31 @@ static void smaps_account(struct mem_size_stats *mss, struct page *page, | |||
| 450 | else | 450 | else |
| 451 | mss->private_clean += size; | 451 | mss->private_clean += size; |
| 452 | mss->pss += (u64)size << PSS_SHIFT; | 452 | mss->pss += (u64)size << PSS_SHIFT; |
| 453 | if (locked) | ||
| 454 | mss->pss_locked += (u64)size << PSS_SHIFT; | ||
| 453 | return; | 455 | return; |
| 454 | } | 456 | } |
| 455 | 457 | ||
| 456 | for (i = 0; i < nr; i++, page++) { | 458 | for (i = 0; i < nr; i++, page++) { |
| 457 | int mapcount = page_mapcount(page); | 459 | int mapcount = page_mapcount(page); |
| 460 | unsigned long pss = (PAGE_SIZE << PSS_SHIFT); | ||
| 458 | 461 | ||
| 459 | if (mapcount >= 2) { | 462 | if (mapcount >= 2) { |
| 460 | if (dirty || PageDirty(page)) | 463 | if (dirty || PageDirty(page)) |
| 461 | mss->shared_dirty += PAGE_SIZE; | 464 | mss->shared_dirty += PAGE_SIZE; |
| 462 | else | 465 | else |
| 463 | mss->shared_clean += PAGE_SIZE; | 466 | mss->shared_clean += PAGE_SIZE; |
| 464 | mss->pss += (PAGE_SIZE << PSS_SHIFT) / mapcount; | 467 | mss->pss += pss / mapcount; |
| 468 | if (locked) | ||
| 469 | mss->pss_locked += pss / mapcount; | ||
| 465 | } else { | 470 | } else { |
| 466 | if (dirty || PageDirty(page)) | 471 | if (dirty || PageDirty(page)) |
| 467 | mss->private_dirty += PAGE_SIZE; | 472 | mss->private_dirty += PAGE_SIZE; |
| 468 | else | 473 | else |
| 469 | mss->private_clean += PAGE_SIZE; | 474 | mss->private_clean += PAGE_SIZE; |
| 470 | mss->pss += PAGE_SIZE << PSS_SHIFT; | 475 | mss->pss += pss; |
| 476 | if (locked) | ||
| 477 | mss->pss_locked += pss; | ||
| 471 | } | 478 | } |
| 472 | } | 479 | } |
| 473 | } | 480 | } |
| @@ -490,6 +497,7 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr, | |||
| 490 | { | 497 | { |
| 491 | struct mem_size_stats *mss = walk->private; | 498 | struct mem_size_stats *mss = walk->private; |
| 492 | struct vm_area_struct *vma = walk->vma; | 499 | struct vm_area_struct *vma = walk->vma; |
| 500 | bool locked = !!(vma->vm_flags & VM_LOCKED); | ||
| 493 | struct page *page = NULL; | 501 | struct page *page = NULL; |
| 494 | 502 | ||
| 495 | if (pte_present(*pte)) { | 503 | if (pte_present(*pte)) { |
| @@ -532,7 +540,7 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr, | |||
| 532 | if (!page) | 540 | if (!page) |
| 533 | return; | 541 | return; |
| 534 | 542 | ||
| 535 | smaps_account(mss, page, false, pte_young(*pte), pte_dirty(*pte)); | 543 | smaps_account(mss, page, false, pte_young(*pte), pte_dirty(*pte), locked); |
| 536 | } | 544 | } |
| 537 | 545 | ||
| 538 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 546 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
| @@ -541,6 +549,7 @@ static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr, | |||
| 541 | { | 549 | { |
| 542 | struct mem_size_stats *mss = walk->private; | 550 | struct mem_size_stats *mss = walk->private; |
| 543 | struct vm_area_struct *vma = walk->vma; | 551 | struct vm_area_struct *vma = walk->vma; |
| 552 | bool locked = !!(vma->vm_flags & VM_LOCKED); | ||
| 544 | struct page *page; | 553 | struct page *page; |
| 545 | 554 | ||
| 546 | /* FOLL_DUMP will return -EFAULT on huge zero page */ | 555 | /* FOLL_DUMP will return -EFAULT on huge zero page */ |
| @@ -555,7 +564,7 @@ static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr, | |||
| 555 | /* pass */; | 564 | /* pass */; |
| 556 | else | 565 | else |
| 557 | VM_BUG_ON_PAGE(1, page); | 566 | VM_BUG_ON_PAGE(1, page); |
| 558 | smaps_account(mss, page, true, pmd_young(*pmd), pmd_dirty(*pmd)); | 567 | smaps_account(mss, page, true, pmd_young(*pmd), pmd_dirty(*pmd), locked); |
| 559 | } | 568 | } |
| 560 | #else | 569 | #else |
| 561 | static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr, | 570 | static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr, |
| @@ -737,11 +746,8 @@ static void smap_gather_stats(struct vm_area_struct *vma, | |||
| 737 | } | 746 | } |
| 738 | } | 747 | } |
| 739 | #endif | 748 | #endif |
| 740 | |||
| 741 | /* mmap_sem is held in m_start */ | 749 | /* mmap_sem is held in m_start */ |
| 742 | walk_page_vma(vma, &smaps_walk); | 750 | walk_page_vma(vma, &smaps_walk); |
| 743 | if (vma->vm_flags & VM_LOCKED) | ||
| 744 | mss->pss_locked += mss->pss; | ||
| 745 | } | 751 | } |
| 746 | 752 | ||
| 747 | #define SEQ_PUT_DEC(str, val) \ | 753 | #define SEQ_PUT_DEC(str, val) \ |
