Open1

[訳] The burstable CFS bandwidth controller

Tsubasa NagasawaTsubasa Nagasawa

LWN の The burstable CFS bandwidth controller の日本語訳です。

カーネルの CFS 帯域幅コントローラーは cgroup 毎に利用可能な CPU 時間を効率的に制御できる。特定のプロセスが CPU 時間を大幅に消費するのを防ぎ、CPU 時間を使いたい全てのプロセスに十分な時間を確保できる。とはいえ当然のことながら、帯域幅コントローラーが全てのワークロードに完璧に対応できるわけではない。Huaixin Chang の一連のパッチは、バーストするレイテンシの影響を受けやすいワークロードでより良く動作することを目指している。

帯域幅コントローラーは “Completely Fair Scheduling (完全に公平なスケジューリング)” (CFS) タスク (”リアルタイムプロセス”と対比して”通常プロセス”とも呼ばれる) にのみ適用される。リアルタイムタスクのCPU 使用率は別の方法で処理される。帯域幅コントローラーは cgroup に適用する制限を管理する 2 つのパラメータを提供している。

  • cpu.cfs_quota_us は各計算期間の中でグループ毎に利用可能な CPU 時間 (μs 単位)
  • cpu.cfs_period_us は各計算期間の長さ (μs 単位)

例えば、cpu.cfs_quota_us を 50000 に cpu.cfs_period_us を 100000 に設定すると、グループは 100 ms 毎に 50 ms の CPU 時間を消費することができる。cpu.cfs_quota_us を 25000 に cpu.cfs_period_us を 50000 に設定すると、50 ms 毎に 25 ms の CPU 時間を消費することができる。どちらの場合も、グループは 1 CPU の 50% を消費することができるが、後者の場合、その時間はより頻繁に短い間隔でやってくる。

上記の 2 つのケースの違いが重要である。cgroup がシングルプロセスで 30 ms 実行に必要だとする。最初のケースだと、30 ms は 50 ms よりも短いので、プロセスはスロットリングすることなくタスクを処理し終える。2 つ目のケースだと、プロセスは 25 ms 実行された後に中断される。次の 50 ms 期間が来るのを待ってから処理を再開し、ジョブを完了できる。ワークロードがレイテンシに影響を受けやすい場合、それを考慮して帯域制限コントローラーのパラメータを設定する必要がある。

この仕組みは、決まった CPU 時間を常に要求するワークロードだとそれなりにうまく機能する。あるプロセスの使用量が、ほとんどの期間で制限に対して少ないが、突発的にバーストして制限よりも多くの CPU 時間を必要とする場合を考える。レイテンシが問題にならない場合、プロセスが次の期間を待ってから作業を完了することは問題にならないかもしれない。しかし、レイテンシが問題になる場合、この遅延は非常に気掛かりとなる。

この問題を回避する方法はある。1 つはもちろん、ワークロードのバーストを処理するのに十分なクォータ (上限) を該当のプロセスに割り当てる方法だが、そうすると、該当のプロセスは全体としてより多くの CPU 時間を消費することになる。システム管理者は、そのような対応を望まないかもしれない。特にお金が絡んでいて、実際に使われる CPU 時間が限られている場合はなおさらだ。他の方法だと、制限と期間の両方を増やすこともできる。その場合も、プロセスが次の期間を待つことになれば、その分レイテンシが増える可能性はある。

Chang の一連のパッチでは別の方法を可能にした。cgroup は未使用のクォータの一部をある期間から次の期間に繰り越せるようになった。新しいパラメータである cpu.cfs_burst.us は、この方法で繰り越せる CPU 時間の最大値である。例えば、グループのクォータとして 25 ms を、間隔として 50 ms を設定した場合を考える。cpu.cfs_burst_us を 40000 (40 ms) に設定すると、そのグループに属するプロセスは、前回の期間で 15 ms 以上を使わずに繰り越している場合にのみ、ある期間の中で 40 ms まで実行しきる。これにより、長い期間を設定してもクォータの範囲内に収めつつ、バーストにも対応できるようになる。

別の角度から見ると、cpu.cfs_burtst_us が設定されている場合、クォータは以前と異なる解釈になる。クォータは上限の絶対値ではなく、期間毎にグループの CPU 時間の Account に振り込まれた CPU 時間の量であり、バーストによってその Account の値に上限を設定できる。バーストしがちなグループは、必要な時のために、限られた CPU 時間をその Account に貯めておくことができる。

デフォルトで cpu.cfs_burst_us は 0 である。バーストの仕組みは無効化されており、これまでの挙動のままである。システム全体のバーストの利用を sysctl で無効化できる。sysctl にある別のノブ (sysctl_sched_cfs_bw_burst_onset_percent) を指定すると、コントローラーは各期間の開始時に、直前の期間で蓄積されて時間に関係なく、各グループにバーストのクォータに対して指定した割合の CPU 時間を渡す。

一連のパッチは Burstable コントローラーを使用した時のベンチマークの結果を含んでおり、最悪のケースで桁違いにレイテンシが改善されている。