差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン 前のリビジョン 次のリビジョン | 前のリビジョン | ||
linux:kernel:cgroup:memory.txt翻訳 [2013/03/28 11:49] – [2.3. 共有メモリのカウント] tenforward | linux:kernel:cgroup:memory.txt翻訳 [2013/08/21 15:43] (現在) – [11. メモリプレッシャー] tenforward | ||
---|---|---|---|
行 1: | 行 1: | ||
- | <color red> | + | <color red> |
+ | |||
+ | 多分,3.10 ベース. | ||
====== メモリリソースコントローラ ====== | ====== メモリリソースコントローラ ====== | ||
行 36: | 行 38: | ||
* タスクを移動することによりカウントの移動 (再カウント) が選択可能 | * タスクを移動することによりカウントの移動 (再カウント) が選択可能 | ||
* 使用量のしきい値の通知 | * 使用量のしきい値の通知 | ||
+ | * メモリプレッシャーの通知 | ||
* oom-killer が knob と oom-notifier を無効にすること | * oom-killer が knob と oom-notifier を無効にすること | ||
* root cgroup には制限のコントロールがない | * root cgroup には制限のコントロールがない | ||
行 61: | 行 64: | ||
| | ||
| | ||
+ | | ||
| | ||
(See sysctl' | (See sysctl' | ||
行 382: | 行 386: | ||
ここで total = file + anon + unevictable である.(訳注: | ここで total = file + anon + unevictable である.(訳注: | ||
+ | |||
+ | ===== 6. 階層構造サポート ===== | ||
+ | |||
+ | メモリコントローラは深い階層構造と階層構造のアカウンティングをサポートしている.階層構造は cgroup ファイルシステム内に適切な cgroup を作成することにより作成される.例として考えられるのは,以下のような cgroup ファイルシステムの改造構造である. | ||
+ | |||
+ | < | ||
+ | root | ||
+ | / | ||
+ | / | ||
+ | | ||
+ | | \ | ||
+ | | \ | ||
+ | d e | ||
+ | </ | ||
+ | |||
+ | 上記の図で,階層構造のアカウンティングが有効になっている場合,e の全てのメモリ使用量は root まで祖先をさかのぼってカウントされる (c と root).階層構造のアカウンティングを有効にするのは memory.use_hierarchy を有効にする.もし,祖先の 1 つが制限を超えた場合,回収アルゴリズムはその祖先とその祖先の子供のタスクから回収を行う. | ||
+ | |||
+ | ==== 6.1. 階層構造のアカウンティングと回収を有効にする ==== | ||
+ | |||
+ | デフォルトでは,メモリ cgroup は階層構造機能が無効になっている.このサポートを有効にするには,root cgroup の memory.use_hierarchy ファイルに 1 を書き込む. | ||
+ | |||
+ | < | ||
+ | |||
+ | この機能を無効にするには | ||
+ | |||
+ | < | ||
+ | |||
+ | 注意1: 有効化/ | ||
+ | |||
+ | 注意2: panic_on_oom が 2 に設定されている時,いずれかの cgroup で OOM イベントが発生した場合,全システムがパニックとなる. | ||
+ | |||
+ | ===== 7. ソフトリミット ===== | ||
+ | |||
+ | ソフトリミットは以下のようにコマンドを使うことで設定できる.(この例ではソフトリミットを 256MiB と仮定している) | ||
+ | |||
+ | < | ||
+ | |||
+ | これを 1G に変えたい場合は,いつでも以下のように実行することが可能である. | ||
+ | |||
+ | < | ||
+ | |||
+ | 注意1: ソフトリミットは長い時間に渡って効果がある.これはメモリ cgroup 間でバランスを取るためにメモリの回収が呼び出されるからである. | ||
+ | |||
+ | 注意2: ソフトリミットはハードリミットよりも常に少ない値で設定することを推奨する.さもないとハードリミットに先に到達してしまう. | ||
+ | |||
+ | ===== 8. タスクマイグレーション時のチャージの移動 ===== | ||
+ | |||
+ | ユーザはタスクマイグレーションと同時にタスクに関係するチャージを移動することが可能である.これは元の cgroup からタスクのページをアンチャージして,新しい cgroup にチャージするということである.この機能は CONFIG_MMU でない環境ではサポートされない.ページテーブルが欠如しているためである. | ||
+ | |||
+ | ==== 8.1. インターフェース ==== | ||
+ | |||
+ | この機能はデフォルトでは無効になっている.目的の memory.move_charge_at_immigrate に書き込むことで有効化,無効化が可能である. | ||
+ | |||
+ | もし有効化したい場合: | ||
+ | |||
+ | < | ||
+ | |||
+ | 注意: move_charge_at_immigrate のぞれぞれのビットはどの種類のチャージを移動させるべきかという意味を持っている.8.2 を参照. | ||
+ | |||
+ | 注意: チャージは mm-> | ||
+ | |||
+ | 注意: 移動先の cgroup にタスクの充分なスペースが見つけられない場合,メモリを回収することによりスペースを作成しようとする.もし充分なスペースを作ることが出来ない場合は,タスクマイグレーションは失敗する. | ||
+ | |||
+ | 注意: 大量のチャージを移動させる場合,数秒かかる場合がある. | ||
+ | |||
+ | ==== 8.2. 移動するチャージのタイプ ==== | ||
+ | |||
+ | move_charge_at_immigrate のそれぞれのチャージはどのタイプのチャージを移動させるべきかという意味を持つ.しかしいずれにしても,ページやスワップのアカウントは,タスクの現在の (古い) メモリ cgroup へチャージされた時だけ移動させることができることに注意しなければならない. | ||
+ | |||
+ | ^ bit ^ どのタイプのチャージが移動するか ^ | ||
+ | | 0 | ターゲットとなるタスクが使う匿名ページとそれのスワップのチャージ.スワップのチャージを移動できるには,スワップ拡張 (2.4参照) を有効にしなければならない | | ||
+ | | 1 | ターゲットとなるタスクによってマッピングされたファイルページ (通常のファイル,tmpfsファイル (e.g. ipc 共有メモリ),tmpfs ファイルのスワップ).匿名ページとは違って,タスクがマップした範囲のファイルページ (とスワップ) はページフォールトが起こってない場合でも移動するだろう.すなわち,そのタスクの " | ||
+ | |||
+ | (訳注) 0=無効,1=匿名ページとそのスワップ,2=ファイルページ,3=両方指定 | ||
+ | ==== 8.3. TODO ==== | ||
+ | * チャージを移動させる全ての操作は cgroup_mutex 配下で実行される.これは,mutex を長時間保持する良くない振るまいである.なので技が少し必要かもしれない. | ||
+ | |||
+ | ===== 9. メモリのしきい値 ===== | ||
+ | |||
+ | メモリ cgroup は cgroup 通知 API (cgroups.txt 参照) を使ったメモリのしきい値を実装している.これにより複数のメモリやmemswのしきい値を登録でき,それが超えた場合に通知を受けとることができる. | ||
+ | |||
+ | しきい値を登録するには,アプリケーションは以下のようにしなければならない. | ||
+ | |||
+ | * eventfd(2) を使って eventfd を作成する | ||
+ | * memory.usage_in_bytes か memory.memsw.usage_in_bytes を open する | ||
+ | * "< | ||
+ | |||
+ | ===== 10. OOM コントロール ===== | ||
+ | |||
+ | memory.oom_control ファイルは OOM 通知や他のコントロールを行うためのファイルである. | ||
+ | |||
+ | メモリ cgroup は cgroup 通知 API (cgroups.txt を参照) を使った OOM 通知を実装している.これにより複数の OOM 通知配送を登録でき,OOM が起こった時に通知を受けとることができる. | ||
+ | |||
+ | 通知を登録するには,アプリケーションは以下のようにしなければならない. | ||
+ | |||
+ | * eventfd(2) を使って eventfd を作成する | ||
+ | * memory.oom_control ファイルを open する | ||
+ | * "< | ||
+ | |||
+ | アプリケーションは OOM が起こると eventfd を通して通知を受けとる.OOM 通知は root cgroup では機能しない. | ||
+ | |||
+ | OOM-killer を無効にするには memory.oom_control ファイルに " | ||
+ | |||
+ | < | ||
+ | |||
+ | この操作は階層構造のトップの cgroup でのみ可能である.OOM-killer が無効化された場合,割り当て可能なメモリを要求したとき,cgroup 配下のタスクは,メモリ cgroup の OOM-waitqueue 内でハングアップするかスリープするだろう. | ||
+ | |||
+ | このようなタスクを実行するには,cgroup の OOM ステータスを以下のように緩和する必要がある. | ||
+ | * 制限を大きくするか,使用量を削減する | ||
+ | * いくつかのタスクを他のグループに移動させ,アカウンティングも移動させる | ||
+ | * いくつかファイルを削減する (tmpfs 上の?) | ||
+ | |||
+ | そして,タスクを停止させ,再度実行する. | ||
+ | |||
+ | 以下を見ることで,OOM の現在の状態を見ます. | ||
+ | * oom_kill_disable 0 or 1 (1 の時,oom-killer は無効化されている) | ||
+ | * under_oom 0 or 1 (1 の時,メモリ cgroup は OOM 状態にあり,タスクは停止している可能性がある) | ||
+ | |||
+ | ===== 11. メモリプレッシャー ===== | ||
+ | |||
+ | プレッシャーレベルの通知はメモリアロケーションのコストをモニタリングするのに使う事ができる.これはプレッシャーをもとにしており,アプリケーションは自身のメモリリソースに様々な管理戦略を実装することが可能になる.プレッシャーレベルは以下のように定義される. | ||
+ | |||
+ | " | ||
+ | |||
+ | " | ||
+ | |||
+ | " | ||
+ | |||
+ | イベントは,処理されるまで上流に伝搬する.すなわちイベントは貫通はしないということである.これがどういうことかを以下にしめす.例えば,3 つの cgroup A-> | ||
+ | |||
+ | memory.pressure_level ファイルは eventfd を設定するためだけに使われる.通知を登録するために,アプリケーションは | ||
+ | |||
+ | - eventfd(2) を使って eventfd を作成する | ||
+ | - memory.pressure_level を open する | ||
+ | - "< | ||
+ | |||
+ | アプリケーションは,メモリプレッシャーが指定したレベル (か高いレベル) に達した時,eventfd を通して通知を受け取る.memory.pressure_level に対する read/write 操作は実装されていない. | ||
+ | |||
+ | テスト: | ||
+ | |||
+ | ここに小さなサンプルスクリプトがある.これは新しい cgroup を作成し,メモリリミットを設定し,cgroup に通知を設定し,それから子供の cgroup に対して深刻なプレッシャーを与えるスクリプトである. | ||
+ | |||
+ | < | ||
+ | # cd / | ||
+ | # mkdir foo | ||
+ | # cd foo | ||
+ | # cgroup_event_listener memory.pressure_level low & | ||
+ | # echo 8000000 > memory.limit_in_bytes | ||
+ | # echo 8000000 > memory.memsw.limit_in_bytes | ||
+ | # echo $$ > tasks | ||
+ | # dd if=/ | ||
+ | </ | ||
+ | |||
+ | (多数の通知が予測され,最終的には oom-killer が発動するだろう) | ||
+ | |||
+ | |||
+ | ===== 12. TODO ===== | ||
+ | |||
+ | - huge ページのアカウンティングサポート (分離したコントローラとして) | ||
+ | - cgroup ごとのスキャナーが最初に共有されていないページを回収するようにする | ||
+ | - コントローラに共有ページに対するアカウントを教える | ||
+ | - 制限には達していないが,使用量が制限に近づいている時に,バックグラウンドで回収を開始する | ||
+ | |||
+ | ===== Summary ===== | ||
+ | |||
+ | 全体的に,メモリコントローラは stable なコントローラであり,コミュニティ内で広く議論とコメントがなされてきた | ||
+ | |||
+ | ===== References ===== | ||
+ | |||
+ | - Singh, Balbir. RFC: Memory Controller, http:// | ||
+ | - Singh, Balbir. Memory Controller (RSS Control), \\ http:// | ||
+ | - Emelianov, Pavel. Resource controllers based on process cgroups http:// | ||
+ | - Emelianov, Pavel. RSS controller based on process cgroups (v2) http:// | ||
+ | - Emelianov, Pavel. RSS controller based on process cgroups (v3) http:// | ||
+ | - Menage, Paul. Control Groups v10, http:// | ||
+ | - Vaidyanathan, | ||
+ | - Singh, Balbir. RSS controller v2 test results (lmbench), http:// | ||
+ | - Singh, Balbir. RSS controller v2 AIM9 results http:// | ||
+ | - Singh, Balbir. Memory controller v6 test results, http:// | ||
+ | - Singh, Balbir. Memory controller introduction (v6), http:// | ||
+ | - Corbet, Jonathan, Controlling memory use in cgroups, http:// | ||