====== Memory Resource Controller の Kernel Memory Accounting サポート ======
**注意!! ここに書いてある事は調査途中の事であり間違いの可能性が大きいです.**
Linux 3.8 でメモリコントローラでカーネルメモリの使用量のチェックが可能になった.(→ [[http://kernelnewbies.org/Linux_3.8#head-5e0aaa977a9d3203a6deead13431651f9e3aa9ea|1.7. The memory resource controller supports accounting of kernel memory]] (Linux 3.8 on Kernelnewbies)
この動きは少し注意が必要である.
- root グループには制限は効かない (カーネルメモリに限らずメモリコントローラ全体に言える話)
- root グループの使用量カウント (usage_in_bytes) はカウントされたりされなかったりするので適当.
- 子グループを作成し,制限値を設定した所からアカウンティングが始まる
- カーネルメモリのカウンタ (memory.kmem.usage_in_bytes) に値が足されると,メインカウンタ (memory.usage_in_bytes, memory.memsw.usage_in_bytes) にも足される.つまりメインカウンタはユーザメモリ + カーネルメモリのカウンタである.
===== ↑の 3 の確認 =====
メモリコントローラは mm/memcontrol.c に処理が記述されている.カーネルメモリのカウンタへ値を加える操作は memcg_charge_kmem 関数でなされているようだ.(以下のコードはコメントを削除している.3.8.2 のコード)
static int memcg_charge_kmem(struct mem_cgroup *memcg, gfp_t gfp, u64 size)
{
struct res_counter *fail_res;
struct mem_cgroup *_memcg;
int ret = 0;
bool may_oom;
ret = res_counter_charge(&memcg->kmem, size, &fail_res); ... (1)
if (ret)
return ret;
may_oom = (gfp & __GFP_FS) && !(gfp & __GFP_NORETRY); ... (2)
_memcg = memcg;
ret = __mem_cgroup_try_charge(NULL, gfp, size >> PAGE_SHIFT,
&_memcg, may_oom); ... (3)
if (ret == -EINTR) {
res_counter_charge_nofail(&memcg->res, size, &fail_res);
if (do_swap_account)
res_counter_charge_nofail(&memcg->memsw, size,
&fail_res);
ret = 0;
} else if (ret)
res_counter_uncharge(&memcg->kmem, size);
return ret;
}
* (1) で kmem のリソースカウンタへのチャージがなされる.ここで制限値にかからずチャージが終われば 0 が返るので,その後に進む
* (2) oom 状態かどうか判断? 要確認
* (3) 要調査
===== tcp バッファのアカウンティングはメインカウンタに影響を及ぼすのか? =====
要調査