#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);
}
//...
1条答案
按热度按时间t2a7ltrp1#
当Linux内核计算PSS(成比例的集合大小)时,内核在字节级别处理该值(实际上,内核在更细粒度的级别计算PSS。参见下面的代码片段。)。
如您所见,为了计算每个页面的
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。对于
/proc/<pid>/smaps_rollup
,内核聚合vma
的每个smaps
中的值,包括小于1 KB的丢弃值,然后以KB为单位打印该值。这就是smaps
中的PSS之和不同于smaps_rollup
中的PSS值的原因。