关于在Linux中从/proc/kpageflags读取页面标志的问题



我正在尝试编写一个Linux程序来检查进程的脏内存页。
我在Linux-4.18.20中使用/proc/kpageflags,其中第4位是页面的脏标志。
下面的代码是映射一个文件并写入其中的一部分,使这些页面变脏,如下所示

if (fd >= 0) {
vaddr = mmap(0, 0x10000, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (vaddr != (void *) -1) {
printf("mmaped address at %pn", 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.
}
}
}

从/proc/pid/smaps中,我得到了我所期望的如下内容,

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

其中56kB是干净的,8kB是脏的。
但是通过读取/proc/pid/pagemap和/proc/kpageflags,相应的页面没有设置"脏"位,即页面标志如下,

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不是'1' !
我的测试有什么问题吗?
或者有没有其他方法来读取/知道进程的Vaddr/Phyaddr是否脏?

通过阅读Linux代码,我得到了答案。
/proc/pid/smaps输出使用来自pte和page结构体的标志。在上面的例子中,dirty位设置在pte中,而不是在page struct中,所以smaps也会将该页计算为"dirty"。
但是/proc/kpageflags只计算页面结构中的标志,其中'dirty'在上面的情况下没有设置,这意味着页面是'clean'。

最新更新