On Mon, Apr 23, 2012 at 05:35:12PM +0900, KAMEZAWA Hiroyuki wrote: [...]
For example, looking into this code flow:
-> page_add_file_rmap() (mm/rmap.c) -> mem_cgroup_inc_page_stat(page, MEMCG_NR_FILE_MAPPED) (include/linux/memcontrol.h) -> void mem_cgroup_update_page_stat(page, MEMCG_NR_FILE_MAPPED, 1) (mm/memcontrol.c)
And then:
void mem_cgroup_update_page_stat(struct page *page, enum mem_cgroup_page_stat_item idx, int val) { ... switch (idx) { case MEMCG_NR_FILE_MAPPED: idx = MEM_CGROUP_STAT_FILE_MAPPED; break; default: BUG(); }
this_cpu_add(memcg->stat->count[idx], val); ...
}
So, clearly, this function only bothers updating _FILE_MAPPED only, leaving _CACHE alone.
[...]
NACK. CACHE is updated at charge()/uncharge()...inserting/removing page cache to radix-tree.
Interesting; true, we have charge/uncharge in __do_fault()/do_wp_page and friends. So, we seem to update FILE_MAPPED in the rmap via cgroup_dec/inc_page_stat, and CACHE is updated via charge/uncharge. Hm.
The code in memory.c is full of if/else ifs, and I wonder if there's some discrepancy in there, but briefly looking it looks fine. The code looks correct indeed, but I'm getting the wrong stats. :-/
Thanks,