buddy allocator: __rmqueue_smallest()を調べる

前回の「buffered_rmqueue()めも - φ(・・*)ゞ ウーン カーネルとか弄ったりのメモ」続きとして、__rmqueue_smallest()を読みます。 これは割と分かりやすい感じです。

では、見ていきます。

関数のプロトタイプはこうなっていて、引数はpageを確保する対象のzone、pageを確保する量のorder、そして、 migratetypeです。migratetypeはinclude/linux/mmzone.hで定義されているenum型の定数です。変数名はMIGRATE_で始まります。

static inline
1001 struct page *__rmqueue_smallest(struct zone *zone, unsigned int order,
1002                                                 int migratetype)
  • pageの確保はorderを起点としてforループで、pageを確保できるか調べていく

  • まず、orderをインデックスとして、zoneから空きpageを管理しているfree_area構造体を取得  アクセス方法は zone->free_area[current_order] 。  free_area構造体はリストの配列と、空きブロック(チャンク?)数を保持する変数を持つ構造体

  • free_area構造体のリスト配列「free_list」をインデックスをmigratetypeとして使って、migratetypeに該当するリストにアクセスし、リストが空なら次に大きいorderを調べるため、continueする

  • 空きがあったら、list_entryマクロでpageを取り出し、page構造体のlruリストからpageを外す

  • page構造体のmapcountを-1にセットと、同じく、page構造体のprivateを0にセット  mapcountは2通りの使い方をされていて、一つはこのpageを指しているpteの数。もうひとつはpage構造体のcountの代わりにリファレンスカウンタとして使う場合。というのがpage構造体にかかれているんだけど、ここではpageがfreeでbuddy allocatorが管理している状態の場合というのを表すのに使っている。include/linux/mm.hのコメントによると。

  • free_area構造体から空きblock数を減らす

  • order分のメモリを確保するのに、orderより大きいところからblockを確保した場合は、expand()でblockを分割する  ここは別途ちゃんと見てみよ。

  • page構造体のindexをmigratetypeに設定する

  • 最後にpageをreturnして終了

Running Lean ―実践リーンスタートアップ (THE LEAN SERIES)

Running Lean ―実践リーンスタートアップ (THE LEAN SERIES)