Siburlog

SiblogだとSI BlogっぽいのでSiburlogとする

ALLOC_FAIRフラグについて

概要

Linuxカーネルのメモリページ割り当てに関するメモ。 ALLOC_FAIR というフラグについて説明する。

ページ割り当て処理

関数冒頭のコメントで This is the 'heart' of the zoned buddy allocator. と書かれている通り、ページ割り当て処理の中心は関数 __alloc_pages_nodemask() が担っている。 __alloc_pages_nodemask() の処理はざっくり言うと以下の通りである。

  1. First allocation attempt
    • 関数 get_page_from_freelist()でページ割り当てを試みる。 ALLOC_FAIR が指定されるのはこちら(ここだけ)。
  2. Slow path
    • First allocation attemptで失敗した場合、関数 __alloc_pages_slowpath() でページ割り当てを試みる。

First allocation attempt

First allocation attemptの際に、割り当て条件として指定されるフラグの一つが、 ALLOC_FAIR である。 First allocation attemptの処理をbreak downすると以下の通りである。

  1. ローカルノードでの割り当て試行
    • zonelist(説明割愛)で指定されたzone(説明割愛)の内、呼び出し元CPUと同じNUMAノード(ローカルノード)に属するzoneからの割り当てを試行する。
  2. 全ノードでの割り当て試行
    • zonelistで指定された全zoneについて、zonelistの登録順序で、再度割り当てを試行する。

このローカルノードでの割り当て試行を行う際、フラグ ALLOC_FAIR が指定されていると、1つのzoneがlow watermarkに達するまで消費してから次のzoneへ進む「のではなく」、各zoneにおいて一定量 x (= high_wmark_pages(zone) - low_wmark_pages(zone)) で表される量を割り当てたら、もう次のzoneへ進む、というロジックで割り当て試行処理が行われる。 ローカルノードに属するzone群でのページ消費負担を フェア に分散するロジックと理解できる。

他方、全ノードでの割り当て試行では、単純にzonelist順に一つのzoneがlow watermarkに達するまで消費して、次のzoneへ進む、というロジックとなる。

ちなみにローカルノードでの割り当て試行において、全てのzoneでの割当量が一旦 x に達すると、各zoneでいくら割り当てたかのカウンタがリセットされ、再び各zoneにおいて x までは割り当て可能となる。