diff options
author | KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> | 2010-09-22 16:05:06 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-09-22 20:22:39 -0400 |
commit | 1c2499ae87f828eabddf6483b0dfc11da1100c07 (patch) | |
tree | be394bdb6d8bd1732a2635eca62e5b2eca04c07a /fs/proc | |
parent | 142092e577255e33a4ab74c6baad04c9fb887927 (diff) |
/proc/pid/smaps: fix dirty pages accounting
Currently, /proc/<pid>/smaps has wrong dirty pages accounting.
Shared_Dirty and Private_Dirty output only pte dirty pages and ignore
PG_dirty page flag. It is difference against documentation, but also
inconsistent against Referenced field. (Referenced checks both pte and
page flags)
This patch fixes it.
Test program:
large-array.c
---------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
char array[1*1024*1024*1024L];
int main(void)
{
memset(array, 1, sizeof(array));
pause();
return 0;
}
---------------------------------------------------
Test case:
1. run ./large-array
2. cat /proc/`pidof large-array`/smaps
3. swapoff -a
4. cat /proc/`pidof large-array`/smaps again
Test result:
<before patch>
00601000-40601000 rw-p 00000000 00:00 0
Size: 1048576 kB
Rss: 1048576 kB
Pss: 1048576 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 218992 kB <-- showed pages as clean incorrectly
Private_Dirty: 829584 kB
Referenced: 388364 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
<after patch>
00601000-40601000 rw-p 00000000 00:00 0
Size: 1048576 kB
Rss: 1048576 kB
Pss: 1048576 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 1048576 kB <-- fixed
Referenced: 388480 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Acked-by: Hugh Dickins <hughd@google.com>
Cc: Matt Mackall <mpm@selenic.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/task_mmu.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 271afc48b9a5..1dbca4e8cc16 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -363,13 +363,13 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, | |||
363 | mss->referenced += PAGE_SIZE; | 363 | mss->referenced += PAGE_SIZE; |
364 | mapcount = page_mapcount(page); | 364 | mapcount = page_mapcount(page); |
365 | if (mapcount >= 2) { | 365 | if (mapcount >= 2) { |
366 | if (pte_dirty(ptent)) | 366 | if (pte_dirty(ptent) || PageDirty(page)) |
367 | mss->shared_dirty += PAGE_SIZE; | 367 | mss->shared_dirty += PAGE_SIZE; |
368 | else | 368 | else |
369 | mss->shared_clean += PAGE_SIZE; | 369 | mss->shared_clean += PAGE_SIZE; |
370 | mss->pss += (PAGE_SIZE << PSS_SHIFT) / mapcount; | 370 | mss->pss += (PAGE_SIZE << PSS_SHIFT) / mapcount; |
371 | } else { | 371 | } else { |
372 | if (pte_dirty(ptent)) | 372 | if (pte_dirty(ptent) || PageDirty(page)) |
373 | mss->private_dirty += PAGE_SIZE; | 373 | mss->private_dirty += PAGE_SIZE; |
374 | else | 374 | else |
375 | mss->private_clean += PAGE_SIZE; | 375 | mss->private_clean += PAGE_SIZE; |