mm/memcontorl.cのmem_cgroup_charge_statistics()のとこです。カーネルは毎度ながら4.1.15。
mem_cgroup_charge_statistics()のコードはこんな感じです。見たままですね。
828 static void mem_cgroup_charge_statistics(struct mem_cgroup *memcg, 829 struct page *page, 830 int nr_pages) 831 { 832 /* 833 * Here, RSS means 'mapped anon' and anon's SwapCache. Shmem/tmpfs is 834 * counted as CACHE even if it's on ANON LRU. 835 */ 836 if (PageAnon(page)) 837 __this_cpu_add(memcg->stat->count[MEM_CGROUP_STAT_RSS], 838 nr_pages); 839 else 840 __this_cpu_add(memcg->stat->count[MEM_CGROUP_STAT_CACHE], 841 nr_pages); 842 843 if (PageTransHuge(page)) 844 __this_cpu_add(memcg->stat->count[MEM_CGROUP_STAT_RSS_HUGE], 845 nr_pages); 846 847 /* pagein of a big page is an event. So, ignore page size */ 848 if (nr_pages > 0) 849 __this_cpu_inc(memcg->stat->events[MEM_CGROUP_EVENTS_PGPGIN]); 850 else { 851 __this_cpu_inc(memcg->stat->events[MEM_CGROUP_EVENTS_PGPGOUT]); 852 nr_pages = -nr_pages; /* for event */ 853 } 854 855 __this_cpu_add(memcg->stat->nr_page_events, nr_pages); 856 }
chargeはmem_cgroup構造体のメンバ変数statに対して行っています。変数はmem_cgroup構造体のこの部分で定義されていて、__percpuが付いているのでcpu毎にデータがあります。この構造体はmm/memcontrol.cで宣言されていてるので他では使わないようです。
321 /* 322 * percpu counter. 323 */ 324 struct mem_cgroup_stat_cpu __percpu *stat;
mem_cgroup_stat_cpu構造体もmm/memcontrol.cにあります。内容はこのようになってます。
128 struct mem_cgroup_stat_cpu { 129 long count[MEM_CGROUP_STAT_NSTATS]; 130 unsigned long events[MEMCG_NR_EVENTS]; 131 unsigned long nr_page_events; 132 unsigned long targets[MEM_CGROUP_NTARGETS]; 133 };
targetsについては今回のコード中では使用されてません。 MEM_CGROUP_STAT_NSTATSなどはenum型でinclude/linux/memcontrol.hにて定義されています。
32 /* 33 * The corresponding mem_cgroup_stat_names is defined in mm/memcontrol.c, 34 * These two lists should keep in accord with each other. 35 */ 36 enum mem_cgroup_stat_index { 37 /* 38 * For MEM_CONTAINER_TYPE_ALL, usage = pagecache + rss. 39 */ 40 MEM_CGROUP_STAT_CACHE, /* # of pages charged as cache */ 41 MEM_CGROUP_STAT_RSS, /* # of pages charged as anon rss */ 42 MEM_CGROUP_STAT_RSS_HUGE, /* # of pages charged as anon huge */ 43 MEM_CGROUP_STAT_FILE_MAPPED, /* # of pages charged as file rss */ 44 MEM_CGROUP_STAT_WRITEBACK, /* # of pages under writeback */ 45 MEM_CGROUP_STAT_SWAP, /* # of pages, swapped out */ 46 MEM_CGROUP_STAT_NSTATS, 47 };
例えば、RSSページの場合は↓なので、インデックス1番目の要素にnr_pagesを足してます。
__this_cpu_add(memcg->stat->count[MEM_CGROUP_STAT_RSS], nr_pages);
nr_pagesはmem_cgroup_commit_charge()で設定していて、THPでない場合は1、THPの場合は以下の部分で計算してます。
5542 if (PageTransHuge(page)) { 5543 nr_pages <<= compound_order(page); 5544 VM_BUG_ON_PAGE(!PageTransHuge(page), page); 5545 }
mem_cgroup_charge_statistics()の前半はページの種別に応じたchargeを行っていて、後半のところはpagein/pageoutのどちらのイベントかで処理が変わりますが、基本はそれぞれのイベント発生回数を増やしてますね。pageoutの場合はnr_pagesの符号を負にしてます。 そして、最後にnr_page_eventsにnr_pagesを足します。pageout時は引く感じですね。
855 __this_cpu_add(memcg->stat->nr_page_events, nr_pages);
( ´ー`)フゥー...
- 作者: 片山暁雄,松下享平,大槻健,大瀧隆太,鈴木貴典,竹之下航洋,松井基勝
- 出版社/メーカー: 技術評論社
- 発売日: 2017/04/12
- メディア: Kindle版
- この商品を含むブログを見る