Swap関連データ構造
1. 概要
Swap領域に関するデータ構造のまとめ。
2. データ構造
2.1 Swap領域の一覧
システム内の全Swap領域(*1)を管理しているデータ構造を図1に示す。
システム内の全Swap領域の情報はswap_info[]配列に格納されている。この配列は各Swap領域を管理するstruct swap_info_structを格納しており(ポインタではなくそのものを格納)、有効なエントリのswap_info_structにはSWAP_USEDフラグがセットされている。この配列の大きさはMAX_SWAP_FILES(32)で固定となっているため、システムで使用できる最大のSwap領域は32個までとなる。swaponにより、Swap領域が追加されるとswap_info配列から空きエントリが探され、新しいエントリが構築される。
また、配列とは別にswap_listというリストがある。swap_listは有効なswap_info_structを優先度順に繋げたリスト。このリストを順番にたどることで優先度の高いものから順番にSwap領域を取得することができる。
優先度はSwapを行うときに、どのSwap領域を使用するかを決めるのに使用する。ルールは以下のとおり。
- 優先度が最も高いものを選ぶ
- 同じ優先度のものがある場合は、ラウンドロビンで選択
- 空き領域がなくなるまで、低優先度のものが選択されることはない
struct swap_info_structについては2.2参照。
(*1) cat /proc/swaps で出力される各エントリ
2.2 各Swap領域
各Swap領域はstruct swap_info_structで管理される(図2)。swap_info_structを元に主に以下の管理を行う
- Swap領域がどのパーティション/ファイルを使用するか
- Swap領域のサイズ
- Swap領域→ディスクブロックへのマッピング
- 使用/未使用領域の管理
swap_info_structの各フィールドの説明を表1に示す。
フィールド |
説明 |
---|---|
prio |
優先度 |
swap_file |
Swap領域が使用しているデバイス/ファイル(*1)のstruct fileへのポインタ。 通常はSwapパーティションを使用するが、この場合は、Swapパーティションのデバイスファイル(/dev/hda2等)のstruct fileへのポインタを保持する。通常のファイルをスワップ領域として使っている場合は、そのファイルのstruct fileへのポインタを保持する。 |
extent_list |
スワップ領域の空間をディスクブロックにマップする構造体struct swap_extentのリスト。連続ブロックとなる領域につき1エントリを使用する。詳細は2.3参照 |
swap_map |
スワップ領域の各ページの参照カウンタテーブル。0なら未使用。1ページにつき2Byteの領域を使用するので、スワップ領域のページ数(max)×2Byteの領域が確保されている。 |
max |
スワップ領域のサイズ(ページ数)(*2) |
(*2) LinuxはSwapはページ単位に行われるので、スワップ領域の大きさもページ単位で管理している。
2.3 ディスクブロックへのマッピング(swap_extent)
swap_info_structのextent_listはSwap領域の空間がディスク上のどのブロックにマッピングされるかを決める。extent_listにはstruct swap_extentがチェーンされており、1つのswap_extentはディスク上で連続したブロックの領域を表す。表2にswap_extentの各フィールドの説明を示す。
フィールド |
説明 |
---|---|
start_page |
Swap領域のstart_pageからnr_pages分のマップであることを示す |
nr_pages |
|
start_block |
Swap領域のstart_pageからnr_pagesの空間がディスク上のどのブロックにマップされているかを示す。 |
Swap領域としてディスクパーティション(Swapパーティション)を使用している場合は、swap_extentは非常に単純になる(図3)。この場合、スワップ領域の空間はスワップパーティションにそのままストレートにマップされるので、swap_extentは1つのみ存在する。
start_pageは0、nr_pagesはスワップ領域のサイズ分(スワップパーティションのサイズ)、start_blockは0。
(ページサイズ4KB,ブロックサイズ1KBの例)
スワップ領域にファイルシステム上のファイルを指定している場合は、多少複雑になる。ファイルシステム上のファイルはディスク上で連続ブロックになっているとは限らないので、連続ブロックとなる領域を切り出して各々に1つのswap_extentが割り当てられる(図4)。
なお、LinuxのSwap処理はページ単位に行われる。このため、ページアウト時の処理を簡単にするためにページ境界内で非連続となるディスクブロック(図中の濃い灰色の部分)はスワップ領域としては使用されないようになっている。
2.4 swp_entry_t
Swap処理のなかでよく出てくる構造体swp_entry_t。これはスワップ領域内のページを指定するのに使う。
swp_entry_tは図5に示すようにただのunsigned longで、ここにSwap領域の種類(Type)とSwap領域内でのページオフセット(offset)を格納している。Typeは全Swap領域の情報を格納したswap_info[]配列のIndexとなる。
swp_entry_tを構築する関数としてswp_entry(type, offset)がある。逆にswp_entry_tからtype,offstを取り出す関数としてswp_type(entry), swp_offset(entry)がある。