カーネルは4.1.15。mem_cgroup_commit_charge()はchargeの処理で呼ばれる関数。
今回はここで使われる関数の詳細は調べないで、大まかな流れを把握するのが目標。
LXRで検索するとmm/filemap.cとかmm/swapfile.c、mm/memory.cなんかから呼ばれてます。 mem_cgroup_commit_charge()自体は40行ほどの関数。引数はcharge対象のpage構造体、所属するmemcgの構造体、最後のlrucareはpageがすでにLRUで管理されているかを示すbool値です。
5522 void mem_cgroup_commit_charge(struct page *page, struct mem_cgroup *memcg, 5523 bool lrucare) 5524 { 5525 unsigned int nr_pages = 1; 5526
処理を見ていきます。
5527 VM_BUG_ON_PAGE(!page->mapping, page); 5528 VM_BUG_ON_PAGE(PageLRU(page) && !lrucare, page); 5529
最初にassertがあります。VM_BUG_ON_PAGEマクロは1番目の引数がif文に使われる条件で、2番目に渡しているpage構造体は値をdumpするのに使います。 最初のチェックは見たままで、2番めのほうはPageLRUマクロではpageがLRUに乗ってるのに、lrucareはfalseっていう矛盾のチェックです。
5530 if (mem_cgroup_disabled()) 5531 return;
memcgが使われてないなら何もしないですよね。
5532 /* 5533 * Swap faults will attempt to charge the same page multiple 5534 * times. But reuse_swap_page() might have removed the page 5535 * from swapcache already, so we can't check PageSwapCache(). 5536 */ 5537 if (!memcg) 5538 return; 5539
swapの処理でcharge済みのページを再度chargeしないようにらしいです。 コメントによるとreuse_swap_page()の場合、swapcacheからpageがなくなっているのでPageSwapCache()を使ってチェックできないと。
5540 commit_charge(page, memcg, lrucare); 5541
commit_charge()は名前の割にchargeの処理してないように見えるけど?今回はここの実装は見ないのでこんな関数を呼ぶよという程度で。
5542 if (PageTransHuge(page)) { 5543 nr_pages <<= compound_order(page); 5544 VM_BUG_ON_PAGE(!PageTransHuge(page), page); 5545 } 5546
THP(Transparent Huge Pages)の場合のチェックですね。
5547 local_irq_disable(); 5548 mem_cgroup_charge_statistics(memcg, page, nr_pages); 5549 memcg_check_events(memcg, page); 5550 local_irq_enable(); 5551
割り込みを無効にして、mem_cgroup_charge_statistics()で実際に値を増やしてますね。↓のような処理があるので。
836 if (PageAnon(page)) 837 __this_cpu_add(memcg->stat->count[MEM_CGROUP_STAT_RSS], 838 nr_pages);
次にmemcg_check_events()を呼んで、chargeしたことによりsoft limitを超えるかチェックして、超えたら何か処理してます。ここまでやったら割り込みを有効に戻します。
5552 if (do_swap_account && PageSwapCache(page)) { 5553 swp_entry_t entry = { .val = page_private(page) }; 5554 /* 5555 * The swap entry might not get freed for a long time, 5556 * let's not wait for it. The page already received a 5557 * memory+swap charge, drop the swap entry duplicate. 5558 */ 5559 mem_cgroup_uncharge_swap(entry); 5560 } 5561 }
chargeしたのがswap時の場合ですね。if文の条件が真の場合はすでにcharge済みなのでmem_cgroup_uncharge_swap()でunchargeして今回のcharge分を戻します。
( ´ー`)フゥー...
- 作者: リチャード・ジョーンズ,アントニー・ホスキング,エリオット・モス
- 出版社/メーカー: 翔泳社
- 発売日: 2016/03/14
- メディア: Kindle版
- この商品を含むブログ (3件) を見る