文書の過去の版を表示しています。
Memory Resource Controller の Kernel Memory Accounting サポート
Linux 3.8 でメモリコントローラでカーネルメモリの使用量のチェックが可能になった.(→ 1.7. The memory resource controller supports accounting of kernel memory (Linux 3.8 on Kernelnewbies)
この動きは少し注意が必要である.
- root グループには効かない (tcp バッファの制限サポートの際の動きと同じ)
- 子グループを作成し,制限値を設定した所からアカウンティングが始まる
- カーネルメモリのカウンタ (memory.kmem.usage_in_bytes) に値が足されると,メインカウンタ (memory.usage_in_bytes, memory.memsw.usage_in_bytes) にも足される.つまりメインカウンタはユーザメモリ + カーネルメモリのカウンタである.
↑の 3 の確認
メモリコントローラは mm/memcontrol.c に処理が記述されている.カーネルメモリのカウンタへ値を加える操作は memcg_charge_kmem 関数でなされているようだ.
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; /* * Conditions under which we can wait for the oom_killer. Those are * the same conditions tested by the core page allocator */ may_oom = (gfp & __GFP_FS) && !(gfp & __GFP_NORETRY); _memcg = memcg; ret = __mem_cgroup_try_charge(NULL, gfp, size >> PAGE_SHIFT, &_memcg, may_oom); if (ret == -EINTR) { /* * __mem_cgroup_try_charge() chosed to bypass to root due to * OOM kill or fatal signal. Since our only options are to * either fail the allocation or charge it to this cgroup, do * it as a temporary condition. But we can't fail. From a * kmem/slab perspective, the cache has already been selected, * by mem_cgroup_kmem_get_cache(), so it is too late to change * our minds. * * This condition will only trigger if the task entered * memcg_charge_kmem in a sane state, but was OOM-killed during * __mem_cgroup_try_charge() above. Tasks that were already * dying when the allocation triggers should have been already * directed to the root cgroup in memcontrol.h */ 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 が返るので,その後に進む