mem_cgroup_try_charge()の処理めも

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()はまた次回。