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) \ |