Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

So if n processes are sharing a library L with size M then the contribution to their PSS is M/n.

Now imagine one of the process terminates. So the contribution would be M/(n-1).

Q1: My question is how soon is this change reflected in the PSS values of processes still running and using the shared library?

Q2: As a trivial case suppose only two processes are using a shared lib L of size 100K. PSS contribution to each process is 50K. Now when P2 dies it is the only process using L. So its PSS should increase and become 100K. How soon will this happen, as soon as P2 dies, or after some time? After how much time?

share|improve this question

1 Answer 1

up vote 1 down vote accepted

The change is reflected immediately. There is no caching along the way. When you read /proc/<pid>/smaps, you actually trigger a traversal of that process's page table. Information about the mappings is accumulated along the way, then displayed, without any caching.

The code behind the /proc/<pid>/smaps file is in fs/proc/task_mmu.c, specifically the show_smap function.
That function does a walk_page_range with smaps_pte_range as the PTE callback. smaps_pte_range itself accumulates the information in a struct mem_size_stats.

The part of that code responsible for PSS does:

mapcount = page_mapcount(page);
if (mapcount >= 2) {
    if (pte_dirty(ptent) || PageDirty(page))
        mss->shared_dirty += ptent_size;
    else
        mss->shared_clean += ptent_size;
    mss->pss += (ptent_size << PSS_SHIFT) / mapcount;
} else {
    if (pte_dirty(ptent) || PageDirty(page))
        mss->private_dirty += ptent_size;
    else
        mss->private_clean += ptent_size;
    mss->pss += (ptent_size << PSS_SHIFT);
}

(You can see here that pages can only be accounted in the Shared part if it is actually mapped more than once - it's accounted as private otherwise.)

page_mapcount is defined inline in linux/mm.h and simply accesses a struct page:

static inline int page_mapcount(struct page *page)
{
    return atomic_read(&(page)->_mapcount) + 1;
}

So PSS is "always up to date".

share|improve this answer
    
Thanks for the clear and to the point answer! –  abc Mar 15 '12 at 17:58

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.