aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/task_mmu.c87
1 files changed, 47 insertions, 40 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 78fd3621f565..5cd06fa3106b 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -333,56 +333,63 @@ struct mem_size_stats {
333 u64 pss; 333 u64 pss;
334}; 334};
335 335
336static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, 336
337 struct mm_walk *walk) 337static void smaps_pte_entry(pte_t ptent, unsigned long addr,
338 struct mm_walk *walk)
338{ 339{
339 struct mem_size_stats *mss = walk->private; 340 struct mem_size_stats *mss = walk->private;
340 struct vm_area_struct *vma = mss->vma; 341 struct vm_area_struct *vma = mss->vma;
341 pte_t *pte, ptent;
342 spinlock_t *ptl;
343 struct page *page; 342 struct page *page;
344 int mapcount; 343 int mapcount;
345 344
346 split_huge_page_pmd(walk->mm, pmd); 345 if (is_swap_pte(ptent)) {
347 346 mss->swap += PAGE_SIZE;
348 pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); 347 return;
349 for (; addr != end; pte++, addr += PAGE_SIZE) { 348 }
350 ptent = *pte;
351 349
352 if (is_swap_pte(ptent)) { 350 if (!pte_present(ptent))
353 mss->swap += PAGE_SIZE; 351 return;
354 continue; 352
355 } 353 page = vm_normal_page(vma, addr, ptent);
354 if (!page)
355 return;
356
357 if (PageAnon(page))
358 mss->anonymous += PAGE_SIZE;
359
360 mss->resident += PAGE_SIZE;
361 /* Accumulate the size in pages that have been accessed. */
362 if (pte_young(ptent) || PageReferenced(page))
363 mss->referenced += PAGE_SIZE;
364 mapcount = page_mapcount(page);
365 if (mapcount >= 2) {
366 if (pte_dirty(ptent) || PageDirty(page))
367 mss->shared_dirty += PAGE_SIZE;
368 else
369 mss->shared_clean += PAGE_SIZE;
370 mss->pss += (PAGE_SIZE << PSS_SHIFT) / mapcount;
371 } else {
372 if (pte_dirty(ptent) || PageDirty(page))
373 mss->private_dirty += PAGE_SIZE;
374 else
375 mss->private_clean += PAGE_SIZE;
376 mss->pss += (PAGE_SIZE << PSS_SHIFT);
377 }
378}
356 379
357 if (!pte_present(ptent)) 380static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
358 continue; 381 struct mm_walk *walk)
382{
383 struct mem_size_stats *mss = walk->private;
384 struct vm_area_struct *vma = mss->vma;
385 pte_t *pte;
386 spinlock_t *ptl;
359 387
360 page = vm_normal_page(vma, addr, ptent); 388 split_huge_page_pmd(walk->mm, pmd);
361 if (!page)
362 continue;
363 389
364 if (PageAnon(page)) 390 pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
365 mss->anonymous += PAGE_SIZE; 391 for (; addr != end; pte++, addr += PAGE_SIZE)
366 392 smaps_pte_entry(*pte, addr, walk);
367 mss->resident += PAGE_SIZE;
368 /* Accumulate the size in pages that have been accessed. */
369 if (pte_young(ptent) || PageReferenced(page))
370 mss->referenced += PAGE_SIZE;
371 mapcount = page_mapcount(page);
372 if (mapcount >= 2) {
373 if (pte_dirty(ptent) || PageDirty(page))
374 mss->shared_dirty += PAGE_SIZE;
375 else
376 mss->shared_clean += PAGE_SIZE;
377 mss->pss += (PAGE_SIZE << PSS_SHIFT) / mapcount;
378 } else {
379 if (pte_dirty(ptent) || PageDirty(page))
380 mss->private_dirty += PAGE_SIZE;
381 else
382 mss->private_clean += PAGE_SIZE;
383 mss->pss += (PAGE_SIZE << PSS_SHIFT);
384 }
385 }
386 pte_unmap_unlock(pte - 1, ptl); 393 pte_unmap_unlock(pte - 1, ptl);
387 cond_resched(); 394 cond_resched();
388 return 0; 395 return 0;