SMP環境下でのTLB Consistencyについて

SMP環境下でのTLB Consistencyについてまとめてみる。
UNIX INTERNALS - THE NEW FRONTIERSを参考にした。


カーネル仮想メモリのアドレステーブルをメモリ上に管理しており、CPUは今アクセスしたばかりの仮想アドレス:物理アドレスの組み合わせを一定数(32個とか64個とか)キャッシュしているのがTLB、と見る事が出来る。
そのようにみると、CPUの一般的なキャッシュにおけるキャッシュコヒーレンシのような問題が発生する。
が、一般的なアーキテクチャではTLBのコヒーレンシを保つ機構が存在しない。
この為、OS側でコヒーレンシを保つ必要がある。(このコヒーレンシの事をTLB Consistencyと呼んでいる)
通常、この処理はInter-Processor Interrupt(IPI)を用いて実装されており、一例としてはMach TLB shootdown algorithmがあげられる。

Mach TLB shootdown algorithm

今、pmapを変更し自分のTLBをフラッシュしようとしているCPUがあるとする。
これをイニシエータと呼ぶ。
一方、イニシエータが変更しようとしているpmap上にあるエントリをTLBに乗せているCPU群をレスポンダと呼ぶ。

イニシエータは先ず割り込みを無効化してpmapアクティブフラグを無効化する。
次にpmapにロックをかけ、invalidateするTLBエントリをキューに積み、IPIを送信する。
全てのCPUのpmapアクティブフラグが無効になるまで待つ。

レスポンダはIPI割り込みを受けて割り込み無効化を行い、pmapアクティブフラグを無効にする。
イニシエータがpmapをアンロックするまで待つ。

イニシエータは全てのCPUのpmapアクティブフラグが無効になってからpmapを書き換え、TLBをフラッシュし、pmapをアンロック、アクティブフラグを有効化して割り込みを再開し処理を終了する。

レスポンダはpmapがアンロックされた段階でキューからinvalidateリクエストを取り出して実行(TLBをフラッシュ)、アクティブフラグを有効化、割り込みを再開し割り込みベクタから元の作業に戻る。

以上のように、ロックと待ち合わせを用いてpmapを壊さないようにしている。
→タイミングによっては、CPU Aがpmapから削除したある仮想アドレスをCPU Bが変更しており、後から書き戻してしまうといったような状態が考えられうるので、これを防がなければならない。

どんな時にshootdownが必要になるか?

例えば:

  • invalidateするページがカーネルページ
  • invalidateするページがプロセス間共有されてて、複数のプロセッサ間で参照されてる
  • マルチスレッドシステムの場合、一プロセスのスレッドが複数のプロセッサで動いてる時。 一つのスレッドがマッピングを変えたら、全部のスレッドで同じように見えなきゃいけない。