commitの前にmem_cgroup_try_charge()を呼んでいるので、commitの処理では重要な関数。
mem_cgroup_try_charge()自体はそんなに処理はなくて、メインなのはtry_charge()関数。mem_cgroup_try_charge()の処理は
memcgが無効なら何もしないで終了。
5468 if (mem_cgroup_disabled()) 5469 goto out;
charge対象のページがswap cacheですでにcharge済みなら何もしないで終了。charge済みならmem_cgroupが設定されているのは前に見たところ。
5471 if (PageSwapCache(page)) { 5472 /* 5473 * Every swap fault against a single page tries to charge the 5474 * page, bail as early as possible. shmem_unuse() encounters 5475 * already charged pages, too. The USED bit is protected by 5476 * the page lock, which serializes swap cache removal, which 5477 * in turn serializes uncharging. 5478 */ 5479 if (page->mem_cgroup) 5480 goto out; 5481 } 5482
THPの場合はページ数を再計算。THPじゃない場合は1が設定済み。
5483 if (PageTransHuge(page)) { 5484 nr_pages <<= compound_order(page); 5485 VM_BUG_ON_PAGE(!PageTransHuge(page), page); 5486 }
mem_cgroup構造体を取得。pageの使われ方によって取得方法が違います。
5488 if (do_swap_account && PageSwapCache(page)) 5489 memcg = try_get_mem_cgroup_from_page(page); 5490 if (!memcg) 5491 memcg = get_mem_cgroup_from_mm(mm);
ここがメインの処理。
5493 ret = try_charge(memcg, gfp_mask, nr_pages); 5494
cssの参照数を減らす。
5495 css_put(&memcg->css); 5496
try_charge()の戻り値チェック。css_put()はエラーの有無に関わらず行う模様。try_charge()は整数値を返し、成功時0を返します。戻り値が-EINTRだった場合は、memcgにルートのmemcgを設定しなおしています。
5497 if (ret == -EINTR) { 5498 memcg = root_mem_cgroup; 5499 ret = 0; 5500 }
取得したstruct mem_cgroupを引数で渡されたmemcgpにセットして終了。
5501 out: 5502 *memcgp = memcg; 5503 return ret; 5504 }
本編とも言えるtry_charge()はまた次回。
システム障害はなぜ二度起きたか みずほ、12年の教訓(日経BP Next ICT選書)
- 作者: 日経コンピュータ
- 出版社/メーカー: 日経BP社
- 発売日: 2014/02/28
- メディア: Kindle版
- この商品を含むブログ (10件) を見る