使用/proc/pid/maps和/proc/pid/pagemap在4级x64-64 linux机器中计算进程(带pid)的总页表大小

eqqqjvef  于 2023-06-05  发布在  Linux
关注(0)|答案(1)|浏览(243)

我需要使用C中的/proc/pid/maps和/proc/pid/pagemap接口以编程方式计算Linux中给定进程的总页表大小。
我现在如何获得一个页面条目和计算的页面框架号码使用这些接口。但我不知道如何计算表的大小给出了这些信息。
下面是我的代码:

void alltablesize(int pid) {
    //open /proc/pid/maps to read virtual addresses
    char file_path[50];
    sprintf(file_path, MAPS_FILE, pid);

    FILE *maps = fopen(file_path, "r");
    if(maps == NULL) {
        perror("Failed to open /proc/pid/maps");
        return;
    }

    char line[256];
    uint64_t start, end;
    uint64_t vpn, pfn;

    uint64_t num_entries;
    uint64_t total_page_size;

    while(fgets(line, sizeof(line), maps) != NULL) {
        char fname[256];
        sscanf(line, "%lx-%lx %*s %*lx %*x:%*x %*d %s", &start, &end, fname);

        for(vpn = start/PAGE_SIZE; vpn < end/PAGE_SIZE; vpn++) {
            //open 7proc/pid/pagemap to extract information about the va
            char pagemap_path[50];
            sprintf(pagemap_path, PAGEMAP_FILE, pid);

            int pagemap_fd = open(pagemap_path, O_RDONLY);
            if (pagemap_fd == -1) {
                perror("Failed to open /proc/pid/pagemap");
                fclose(maps);
                return;
            }

            uint64_t entry;                         //entry is 64 bits
            off_t offset = vpn * PAGEMAP_LENGTH;
            lseek(pagemap_fd, offset, SEEK_SET);
            read(pagemap_fd, &entry, sizeof(uint64_t));

            pfn = get_pfn(entry);
            num_entries++;
        }
    }
}
gkl3eglg

gkl3eglg1#

回想一下,地址是由以下各项分解的:

0..11  - ignore
12..20 - last level index
21..30 - second last level index
31..39 - third last level index
40..47 - fourth last level index

如果页面有效(即存在于最后一级索引中),则必须在它上面的每个级别中都有一个页面。因此,一页内存将需要4页页页表。然而,如果它们的虚拟地址在位21..63中匹配,则可以有多达512 [12..20]个页共享页表的这4个页。
这递归地应用;因此在页表每一级上,在必须向上一级添加新页之前,最多可以有512个连续条目。
这意味着您需要按地址处理Map,并重新构造这些索引,以确定需要多少个索引。
一个额外的复杂性是大页面。例如,我可以有一个2 M(512 * 4096)的大页面,而不是一个“最后一级页表”,这样就可以跳过最后一个。还有1G的大页面,覆盖了“倒数第二层页表”。

相关问题