linux中的smaps和smaps_rollup有什么区别

c3frrgcw  于 2023-02-11  发布在  Linux
关注(0)|答案(1)|浏览(375)

linux中的smaps和smaps_rollup有什么区别?我不知道为什么所有进程中的smaps和smaps_rollup之和的PSS大小不同。我想知道这些命令是如何得到PSS大小的。

t2a7ltrp

t2a7ltrp1#

当Linux内核计算PSS(成比例的集合大小)时,内核在字节级别处理该值(实际上,内核在更细粒度的级别计算PSS。参见下面的代码片段。)。

for (i = 0; i < nr; i++, page++) {
        int mapcount = page_mapcount(page);
        unsigned long pss = PAGE_SIZE << PSS_SHIFT;
        if (mapcount >= 2)
            pss /= mapcount;
        smaps_page_accumulate(mss, page, PAGE_SIZE, pss, dirty, locked,
                      mapcount < 2);
    }

如您所见,为了计算每个页面的pss,内核在使用该值之前将其除以页面的mapcount。因此,实际值可以在字节级别表示。例如,如果一个页面由三个进程Map,则每个进程将获得该页面的pss大小的4KB/3(1365.333字节)。
当用户请求打印/proc/<pid>/smaps时,内核为目标进程中的每个vma打印smaps,而/proc/<pid>/smaps_rollup打印smaps的总和,问题是,内核打印/proc/<pid>/smaps的值(对于/proc/<pid>/smaps_rollup也是如此)。这意味着小于1 KB的PSS值将被丢弃。参见下面的代码片段。所有打印的值都右移10。

#define SEQ_PUT_DEC(str, val) \
        seq_put_decimal_ull_width(m, str, (val) >> 10, 8)

/* Show the contents common for smaps and smaps_rollup */
static void __show_smap(struct seq_file *m, const struct mem_size_stats *mss,
    bool rollup_mode)
{
    SEQ_PUT_DEC("Rss:            ", mss->resident);
    SEQ_PUT_DEC(" kB\nPss:            ", mss->pss >> PSS_SHIFT);
    SEQ_PUT_DEC(" kB\nPss_Dirty:      ", mss->pss_dirty >> PSS_SHIFT);
    if (rollup_mode) {
        /*
         * These are meaningful only for smaps_rollup, otherwise two of
         * them are zero, and the other one is the same as Pss.
         */
        SEQ_PUT_DEC(" kB\nPss_Anon:       ",
            mss->pss_anon >> PSS_SHIFT);
        SEQ_PUT_DEC(" kB\nPss_File:       ",
            mss->pss_file >> PSS_SHIFT);
        SEQ_PUT_DEC(" kB\nPss_Shmem:      ",
            mss->pss_shmem >> PSS_SHIFT);
    }
//...

对于/proc/<pid>/smaps_rollup,内核聚合vma的每个smaps中的值,包括小于1 KB的丢弃值,然后以KB为单位打印该值。这就是smaps中的PSS之和不同于smaps_rollup中的PSS值的原因。

相关问题