I am trying to write a Linux program to check a process's dirty memory page.
I am using /proc/kpageflags in Linux-4.18.20, which bit 4 is the dirty flag for the page.
Below code is to mmap a file and write a part of it, to make those pages dirty, as follows,
if (fd >= 0) {
vaddr = mmap(0, 0x10000, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (vaddr != (void *) -1) {
printf("mmaped address at %p
", vaddr);
for (i = 0; i < 0x10000; i ++) {
c = vaddr[i]; /// Load file into memory page, clean.
}
for (i = 0; i < 0x2000; i ++) {
vaddr[i] = 'a'; /// Write memory page make it dirty.
}
}
}
And from /proc/pid/smaps, I got what I expected as follows,
7f1a497db000-7f1a497eb000 rw-p 00000000 08:11 4741474 /mnt/test/process/dumpfile
Size: 64 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 64 kB
Pss: 64 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 56 kB <<<=
Private_Dirty: 8 kB <<<-
Referenced: 64 kB
Anonymous: 8 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB
VmFlags: rd wr mr mw me ac sd
where 56kB is clean, 8kB is dirty.
But by reading /proc/pid/pagemap and /proc/kpageflags, the corresponding page does NOT have 'dirty' bit set, that is the page flag is as follows,
0x7f1a497db000 : pfn 3de54e pageflags are 5868
0x7f1a497dc000 : pfn 3de834 pageflags are 5868
0x7f1a497dd000 : pfn 3cc920 pageflags are 80000082c
0x7f1a497de000 : pfn 3c970b pageflags are 80000082c
0x7f1a497df000 : pfn 3bf8e9 pageflags are 80000082c
0x7f1a497e0000 : pfn 3c14f8 pageflags are 80000082c
0x7f1a497e1000 : pfn 3ccef4 pageflags are 80000082c
0x7f1a497e2000 : pfn 3ccef5 pageflags are 80000082c
0x7f1a497e3000 : pfn 3cc4e8 pageflags are 80000082c
0x7f1a497e4000 : pfn 3cc4e9 pageflags are 80000082c
0x7f1a497e5000 : pfn 3cced0 pageflags are 80000082c
0x7f1a497e6000 : pfn 3cced1 pageflags are 80000082c
0x7f1a497e7000 : pfn 3cc158 pageflags are 80000082c
0x7f1a497e8000 : pfn 3cc159 pageflags are 80000082c
0x7f1a497e9000 : pfn 3cc456 pageflags are 80000082c
0x7f1a497ea000 : pfn 3cc457 pageflags are 80000082c
Bit 4 is NOT '1' !
Is there anything wrong in my testing?
Or is there any other way to read/know if process's Vaddr/Phyaddr is dirty or not?
question from:
https://stackoverflow.com/questions/65915960/question-on-reading-page-flags-from-proc-kpageflags-in-linux 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…