Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
277 views
in Technique[技术] by (71.8m points)

memory management - Question on reading page flags from /proc/kpageflags in Linux

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

By reading the Linux code, I got the answer.
The /proc/pid/smaps output is using flags from both pte and page struct. In above case, dirty bit is set in pte, not in page struct, so smaps will also count that page as 'dirty'.
But /proc/kpageflags is counting only flags from page struct, in which 'dirty' is NOT set in above case, which means page is 'clean'.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...