LinuxのCPUスケジューラに、cgroup階層の扱いをかなり深く触る変更が入り始めた。Peter Zijlstraが投稿した「Flatten the pick」パッチ群は、2026年6月30日にtip.gitのsched/coreブランチへ取り込まれた。Phoronixはこの動きを、Linux 7.3に向けた変更として報じている。

狙いは、単純なゲーム向け最適化ではない。CFS/EEVDFがcgroup階層の中で次に走らせるタスクを選ぶとき、これまでは中間ノードが実行可能性を見えにくくし、待ち時間やオーバーヘッドへの不満につながっていた。今回のパッチは、cgroupの階層そのものを壊さず、実際のEEVDFの選択だけを単一のrunqueueへ移す。Linux 7.2が7月6日にrc2へ進んだ時点ではまだ本流入り前だが、次の7.3サイクルでスケジューラの挙動が見える形で変わる可能性が出てきた。

AD

階層を残し、選ぶ場所だけを一段にする

取り込まれた中核コミットは、sched/eevdf: Move to a single runqueueである。短縮commit IDは85570f10a4。ローカルに取得したtip/sched/coreの履歴では、このコミットだけで6ファイルに374行の追加と474行の削除が入っている。変更の大半はkernel/sched/fair.cだ。

従来のfair/cgroupでは、タスクはcgroup階層に沿ってsched_entityとして表現される。階層は、CPU時間の配分や負荷追跡には必要だ。だが、次に実行するタスクを選ぶEEVDFの観点では、中間ノードが複数タスクの状態をまとめてしまい、どのタスクが本当に走れるのかを見えにくくする。Zijlstraのcommit messageは、fair/cgroupへの典型的な不満を「latencies and/or overhead」と説明している。

新しい構造では、cgroup階層と中間のenqueue/dequeue処理は残る。負荷追跡もそのまま使う。その一方で、EEVDFが実際に見るrunqueueはルート側に平らに置かれ、タスクT1、T2、T3を同じ階層で比較する形になる。階層で決まる有効な重みは消えない。se->h_loadとして、enqueue、set_next_task()、tickのタイミングで再計算される。

この設計の意味は、cgroupをやめることではなく、cgroupを守るために選択経路を短くすることにある。階層はリソース配分の情報を持ち続け、EEVDFは「どのタスクを今走らせるか」を余計な中間表現なしに判断する。commit message自身も、これで性能問題がすぐ解決するとは書いていない。階層処理の多くは残るため、まず効くと見込まれているのは待ち時間の側だ。

cpu.weightの意味を、実際に動くCPU数へ寄せる

7本組の前半は、単一runqueueへ移る前の準備としてcgroupの重み計算を組み替えている。最初のパッチはcgroup_modeというdebugfs上の切り替えを追加し、続くパッチでupmaxconcurtasksという複数の方式を入れた。そのうえで、既定値はconcurへ変わる。

ここで問題になっているのは、cpu.weightが階層の深さとCPU数に対して直感どおりに効かないことだ。Zijlstraの説明では、N個のCPUに対して少なくともN個の実行可能タスクがあると、あるcgroup内の重みを各CPUへ配る係数F_g_nは平均でおおむね1/Nへ近づく。階層が深さdを持つと、この影響はおおむね1/(N^d)の形で悪化し、階層をまたいだタスクどうしが公平に競いにくくなる。

concurは、このズレをCPU数だけで雑に膨らませない。計算ではmin(nr_tasks, nr_cpus)、つまり実行可能なタスク数とCPU数の小さい方を使う。単一タスクなら従来のSMPに近く、並列性が増えるとmax方式に近づく。Zijlstraは、この場合のcpu.weightの意味を「アクティブCPUごとの重み」と説明している。

既定値変更のcommitは、debugfsのcgroup_modeを1から2へ変え、calc_group_sharesの既定呼び出し先をcalc_smp_sharesからcalc_concur_sharesへ切り替えている。変更量は小さいが、影響範囲は小さくない。cgroupの重みを過去の挙動に合わせて膨らませていた環境では、変化が表に出る可能性がある。パッチが設定可能なmodeを残しているのは、この移行の荒さを吸収するためでもある。

AD

ゲームの数字は、平均FPSより待ち時間を見る材料だ

この変更が注目された理由の一つは、古いゲーム環境での手元ベンチマークだ。Zijlstraはv3のカバーレターで、Intel Core i7-2600KとAMD Radeon RX 580を使い、Lutris、GE-Proton10-34、Steam Runtime 3上の「Shadows Awakening」を例に出した。裏ではnice付きのspin処理を8本走らせている。

数字は分かりやすい。例示された結果では、最小FPSは4.0から29.0へ、平均FPSは47.5から59.2へ上がった。最大FPSは83.7で変わらない。一方、フレームタイムは平均34.0ミリ秒から17.0ミリ秒へ下がり、最大値は121.2ミリ秒から30.0ミリ秒へ縮んでいる。

ただし、この表を「Linux 7.3でゲーム性能が一律に上がる」と読むのは早い。条件は古いSandy Bridge世代のCPU、Polaris世代のGPU、特定ゲーム、特定の負荷付けに限られる。むしろ読みどころは、平均FPSよりもフレームタイムのばらつきだ。cgroupの中間ノードが実行可能なタスクを見えにくくしていたなら、平らな選択はフレームが詰まる場面を減らす方向に働く。

デスクトップLinuxでは、ゲーム本体、コンポジタ、音声が同時に動く。そこへブラウザやバックグラウンドサービスも重なり、systemd配下のcgroupも絡む。平均性能が足りていても、選択の遅れが一瞬の引っかかりとして見える。今回のパッチは、その引っかかりを作る経路をスケジューラの内部から短くしようとしている。

7.3 merge window前の確認点

現時点で、この変更はLinus Torvaldsのメインラインへ入ったわけではない。kernel.orgの7月7日JST時点の表示では、mainlineは2026年7月6日付けの7.2-rc2であり、stableは7.1.3である。sched/coreへ入ったという事実は、スケジューラ側の取り込み候補として整ったという意味だ。

Phoronixは、これらのパッチが8月後半のLinux 7.3 merge windowに送られる見込みだと伝えている。7本組はv3のカバーレター時点で8ファイル、607行追加、488行削除の規模だった。小さなチューニングというより、cgroupを含むCFS/EEVDFの選択経路を作り替える変更である。

次に見るべき数字は、ゲームの平均FPSでは終わらない。サーバー側では、コンテナやサービスごとのcpu.weightが期待どおりに効くか。デスクトップ側では、負荷が乗った状態でフレームタイムや入力遅延がどう動くか。さらに、commit messageに残るstruct cfs_rqstruct sched_entityの分離、h_curr削除というTODOが、7.3以降の整理につながるかも判断材料になる。Linux 7.3で本流に入れば、cgroup時代の公平性を保ちながら、タスク選択だけをより直接的にする試みが広い環境で試されることになる。