Linux
kernel

Linuxプロセスアドレス空間 メモリリージョン操作

More than 1 year has passed since last update.

詳解Linuxカーネルの9章プロセスアドレス空間に関連する、メモリリージョンを操作する関数を読んだ。

カーネルバージョン

v4.1.10

データ構造

プロセスから見える仮想アドレス空間の情報はtask_struct->mmで管理される。
割り当てるメモリリージョンはmm_struct->mm_rbのRed-blackツリーでメモリ番号順にソートされた、vm_area_structの単位で管理される。

メモリリージョンが管理するメモリの領域は開始・終了アドレスであらわす。

unsigned long vm_start;         /* Our start address within vm_mm. */
unsigned long vm_end;           /* The first byte after our end address within vm_mm. */

これらのデータ構造はカーネル内のメモリの確保と解放を管理するだけで、ページテーブルへの登録は別途行う必要がある(と思う)。

メモリリージョンを直接操作する関数

基本的にはmm_rbからアドレス(範囲)を指定して検索する。また、ツリーの探索を省略するためのキャッシュをプロセスごとに持っている。
2.6.x時点のmm->mmap_cachetask_struct->vmacacheとなっていて、各プロセスごとに4つvmaのキャッシュを格納できる配列となっている。操作はvmacache_*関数で行っている。

find_vma

addr < vm_endとなる最小のvm_area_structを検索する。検索対象のvm_area_structにaddrが含まれている必要はない。

  1. current->vmacacheを検索
  2. mm_rbを検索し、対象のvmaがあればreturn、なかった場合はNULL。

find_vma_intersection

引数のアドレス範囲start_addr, end_addrと重なるvmaを返す。
find_vma(mm, start_addr)の戻り値に対して、end_addr <= vma.vm_start となるかどうか。

その他

空き範囲の検索、リージョンの追加のための関数がある。

ページテーブルへの追加

do_mmapは読めていないが、関連する関数が2.6.xより大きく変わっている事がわかった。
make_page_present()ではなく、populate_vma_page_range()でページテーブルへの追加は行われていると思われる。