Linuxの開発を率いるLinus Torvalds氏は2026年10月13日、大規模言語モデル(LLM)の支援を受けて開発していたファイル読み出しの高速化パッチを、10本のパッチからなる「rcu-free-v3」として公開した。多数のCPUが同じデータを繰り返し読み出す合成ベンチマークでは、処理性能が約23倍に向上したという。しかし、公開後のコードレビューでは、メモリの解放を防ぐ仕組みがあっても、書き込まれていないデータを読み出してしまう可能性のある競合状態が発見された。翌14日には修正案が示され、開発の引き継ぎも決まり、実用化に向けた検証が続いている。
10月10日に公開された初期版は、ノートPCの8スレッド読み出しで約3倍の性能向上を示した試作だった。今回の多コア環境での測定によって、高速化の効果が特に大きくなる条件が明らかになった一方、従来の参照カウントを省略する設計で、データの安全性をどのように保証するかという課題も浮き彫りになった。
64スレッドで約23倍、1スレッドでは小幅な改善
Torvalds氏が読み出し処理の変更コミットで公開した測定結果は、32コア・64スレッドのAMD Ryzen Threadripper 3970Xを使ったものだ。テストでは、btrfs上にある1ページ分の同じファイルに対し、各スレッドが別々のファイル記述子を使用して、先頭から16バイトずつpread()で繰り返し読み出した。測定時間は各回5秒で、条件ごとに3回実施している。
| 読み出しに使うスレッド | 変更前(百万回/秒) | 変更後(百万回/秒) |
|---|---|---|
| 1スレッド | 7.4〜7.6 | 7.7〜7.8 |
| 8コアに各1スレッド | 16.7 | 60.5 |
| 32コアに各1スレッド | 13.4〜13.7 | 236〜237 |
| 64スレッド | 13.3 | 304 |
64スレッドでは読み出し回数が毎秒1,330万回から3億400万回へ増え、約22.9倍の性能向上を記録した。一方、1スレッドでの改善は約1.01〜1.05倍と小さい。これらの倍率は10月13日に公開されたコミットの測定値から算出したもので、64スレッドは304÷13.3、1スレッドは7.7÷7.6〜7.8÷7.4に基づく。なお、1スレッドの倍率は記載された測定値の最大・最小を組み合わせた算術上の範囲であり、統計的な信頼区間ではない。
変更前の実装では、読み出しに使うCPUを増やしても処理性能が頭打ちになり、32スレッドと64スレッドでは8スレッド時よりも読み出し回数が減少していた。これに対し、変更後は32コアまで大幅に性能が向上している。つまり、今回の改善は個々の読み出し処理を劇的に高速化するというより、多数のCPUが同じデータにアクセスする際の競合を減らすことで、大きな効果を発揮するものだ。
ただし、この測定は同じ小さなデータ領域へのアクセスを意図的に集中させた、極端な条件での合成ベンチマークである。Torvalds氏自身もパッチ公開時の投稿で、実際のワークロードでは性能向上の幅がはるかに小さくなると説明している。データベースやWebサーバーなどのアプリケーション全体が23倍高速化するという意味ではない。
比較条件にも注意が必要だ。変更前の測定にはLinux 7.3-rc6を使い、変更後は同じカーネル設定のまま、その上に全パッチを適用した初期段階の実装を使用している。また、測定時のコードは公開されたコードと条件判定の配置が一部異なる。この結果は修正完了後の最終的な性能を保証するものではなく、初期のノートPCで記録した「約3倍」という結果と直接比較して、改善幅がさらに何倍になったと判断することもできない。
参照カウントを省き、RCUでメモリの再利用を遅らせる
従来のLinuxの読み出し処理では、ページキャッシュからデータをコピーする際、メモリを管理する単位である「folio」の参照カウントを増やし、コピーが終わると減らしていた。これは読み出し中に対象のメモリが解放されるのを防ぐための仕組みだ。ただし、ファイルの内容を変更しない読み出し処理であっても、共有されている参照カウントを更新する必要がある。
多数のCPUが同じfolioを読み出す場合、この参照カウントが性能上のボトルネックになる。カウンターを含むキャッシュラインをCPU間で受け渡しながら更新しなければならず、わずか16バイトのデータをコピーする処理よりも、管理情報を更新する負担の方が大きくなるためだ。実際に64スレッドの測定では、読み出し1回当たりのカーネル内命令数が1,094〜1,101から959へ減少した一方、消費CPUサイクルは19,857〜19,939から735〜736へと大幅に低下している。命令数の削減以上に、CPU間の競合を解消した効果が大きかったことが分かる。
今回の改善案は、繰り返し読み出されるfolioについて、実際にメモリを解放する前にRCU(Read-Copy-Update)の猶予期間が経過するまで待つ仕組みを導入する。Linuxの公式ドキュメントで説明されているRCUは、データ構造から対象を取り除く処理と、そのメモリを実際に回収する処理を分離する技術だ。対象が取り除かれた時点ですでに読み出していた処理が、保護された読み取り区間を終了するまで、メモリの再利用を遅らせる。
この仕組みを利用すれば、条件を満たす読み出し処理ではfolioの参照カウントを取得せず、データをユーザー空間のバッファへ直接コピーできる。参照カウントの更新処理そのものを高速化するのではなく、頻繁に使われる読み出し経路から更新を取り除く設計だ。これにより、複数のCPUが同じ管理情報を奪い合う状況を回避できる。
もっとも、すべての読み出しが新しい高速経路を使えるわけではない。対象データがページキャッシュに存在しない場合や、folioが遅延解放の対象になっていない場合には、従来の読み出し経路へ戻る。また、コピー先のユーザー空間のメモリがまだ利用可能な状態になく、ページフォールトの処理が必要な場合も同様だ。RCUの読み取り区間では、ページフォールトの処理に伴う待機を行えないためである。
こうした従来経路への切り替えには、性能上の代償もある。今回のThreadripperでの測定では、コピー先でページフォールトが発生する16バイト読み出しのCPUサイクル数が、変更前の4,397〜4,428から6,022〜6,296へと増加した。高速経路での処理に失敗した後、従来経路に戻ってページフォールトを処理し直す必要があるためだ。共有データを多数のCPUから読み出す処理では大きく高速化する一方、条件によっては従来より処理負荷が増えることになる。
RCUでメモリを保護しても防げなかった競合状態
Linux開発者のKiryl Shutsemau氏は10月13日、filemap_read_rcu_batch()に競合状態が存在することを指摘し、問題が起きる具体的な処理順序を示した。問題は、RCUによって古いメモリが解放されずに残っていても、読み出し対象のデータとファイルサイズの整合性が失われる場合があることだ。
| 順序 | 読み出し側のCPU | 別のCPU |
|---|---|---|
| 1 | コピー元のfolio Aを取得し、ページキャッシュ内にあることを確認 | |
| 2 | キャッシュを不要とする通知によってfolio Aを取り除く。ただし、実際の解放はRCUによって遅延 | |
| 3 | 書き込みによって新しいfolioを配置し、ファイルサイズを拡張 | |
| 4 | 拡張後のファイルサイズを取得 | |
| 5 | 古いfolio Aから、取得したファイルサイズに基づいてデータをコピー |
この順序で処理が進むと、読み出し側は古いfolio Aと、更新後のファイルサイズを組み合わせてしまう。RCUによってfolio Aのメモリ自体は別の用途に再利用されていないものの、新たに書き込まれたデータはそこには存在しない。その結果、読み出し側が書き込まれていない内容までコピーしてしまう可能性がある。つまり、RCUが保証するのは読み出し中のメモリの寿命であり、そのメモリに含まれるデータが現在のファイル内容と一致することまでは保証しない。
最初の修正案では、ファイルサイズを取得した後、コピー元のfolioが引き続きページキャッシュ内の同じ位置に存在するかを再確認する方法が提案された。これに対しTorvalds氏は、確認処理の重複を避けるため、ファイルサイズを読み取る位置も変更する案を示している。翌14日に公開された改訂案では、遅延解放対象であることを示すフラグ、ファイルサイズ、キャッシュ内のコピー元という順序で状態を確認し、必要なメモリ順序の制御を加える構成が示された。
さらに、読み出そうとしているデータが現在も有効かどうかを確認する処理も維持している。対象のfolioが遅延解放の条件を満たしていても、その後にファイルシステム側で状態が変わる可能性があるためだ。修正そのものは小規模でも、その正しさを確認するには、ページキャッシュの入れ替えとファイル更新が並行して起きる場合を考慮しなければならない。
今回のレビューは、ベンチマークで性能が向上しただけでは、並行処理の安全性を保証できないことを改めて示した。ただし、発見された競合状態がLLMの利用によって生じたと断定できる証拠はない。重要なのは、改善案を公開レビューにかけたことで問題が具体化し、修正に向けた議論が進んだ点にある。
メモリ回収への対策は三段構え、実負荷での効果は未検証
今回の設計では、読み出し時の参照カウント更新を減らす代わりに、RCUの猶予期間が経過するまでメモリの再利用を待たなければならない。そのため、解放待ちのメモリが大量に蓄積すると、今度はメモリを確保する処理に悪影響を及ぼす可能性がある。Torvalds氏は解放待ちメモリへの対策を説明した返信で、最新版では以下の三つの仕組みを組み合わせたと説明している。
- 繰り返し読み出されるfolioだけを遅延解放の対象とし、大きなファイルを切り詰めるだけで大量の解放待ちメモリが発生するのを防ぐ。
- CPUごとに解放待ちのメモリが増えた場合は、RCUの猶予期間が早期に終了するよう処理を促す。
- メモリを確保する側も解放待ちのメモリを認識し、メモリ不足と判断する前に回収の完了を待つ。
単純にファイルの切り詰め処理を遅くすれば解決するわけではない。Torvalds氏は、メモリを解放しようとしている処理を制限すると、かえってメモリ不足への対処を妨げる可能性があると説明している。必要なのは、まもなく再利用可能になるメモリを適切に把握し、必要な場面でその回収を待つ仕組みだ。高速化のためにメモリの寿命を延ばす設計だからこそ、メモリ管理全体への影響を慎重に評価する必要がある。
もっとも、どの程度頻繁に読み出されるfolioを対象にすべきか、実際のワークロードでどれほどの性能向上が得られるかについては、議論が続いている。開発者のPedro Falcato氏は10月14日のレビューで、頻繁に読み出されると判定する基準の妥当性を問い、現実的な負荷でどれほどのページが対象になるのかを確認するよう求めた。また、合成ベンチマーク以外で大きな効果が確認できない限り、仮想メモリ管理に大きな変更を加えるだけの価値があるとは言えないとの見解も示している。
したがって、今後の評価では単純な読み出し回数だけでなく、実際のアプリケーションでCPU間の競合がどれだけ減るかを測定する必要がある。そのうえで、得られる性能上の利益が、メモリ回収の待機時間や追加の処理負荷を上回るかを確認しなければならない。初期版で指摘された問題をそのまま最新版の欠陥とみなすことも、対策が追加されたからといって解決済みと判断することも、現時点では適切ではない。
AI利用の開示と、コードの正しさを保証する責任
Torvalds氏は初期版の説明で、今回の開発にClaude Codeを利用したことを明かしている。コードやテストプログラムの作成だけでなく、問題点を整理するためのレビューや説明文の初稿作成にも使用したという。ただし、作業はすべて本人の指示の下で進められ、性能測定も自身のマシンで実施したと説明している。LLMの利用によって開発期間がどの程度短縮されたか、個々の変更にどれほど寄与したかは明らかになっていない。
そもそも、この高速化が対象とする問題は、2024年に実際のユーザーのワークロードをきっかけとして提起されたものだ。その後も複数のLinux開発者が異なる方法で改善を試みており、今回の取り組みもその延長線上にある。LLMを活用した試作で有望な性能が確認され、公開後に専門家が競合状態を発見し、修正案を検討するという一連の経緯を、AIだけで問題を解決した成果として扱うことはできない。
Torvalds氏は10月13日、休暇と翌週のマージ作業によって十分な時間を確保できなくなるとして、Shutsemau氏にパッチシリーズ全体の引き継ぎを依頼した。Shutsemau氏は翌14日、修正案を示すとともに、この依頼を受け入れている。LLMがコード作成を支援しても、その変更が正しいことを説明し、レビューに対応し、継続的に保守する役割は開発者が担う。今回の経緯は、コード生成の効率と、ソフトウェアとしての信頼性を確保する工程が別のものであることを示している。
同じ時期には、Linuxカーネル開発におけるAI利用の申告方法も見直された。AIによる支援を示すAssisted-byタグについて、Sasha Levin氏が提案した削除パッチの第2版に対し、ドキュメントメンテナーのJonathan Corbet氏は10月14日、適用したと回答している。ただし、これはdocs-next向けの文書変更であり、すべての公開ドキュメントや安定版カーネルに直ちに反映されたことを意味するものではない。
また、AI支援を申告するタグの扱いと、提出したコードに対する責任は別の問題だ。Linuxのツール生成コンテンツに関する指針では、提出者が変更内容全体を理解し、レビューで寄せられた質問に答えられることを求めている。使用したツールや、そのツールが影響した部分、実施したテストについての説明も重視しており、内容を説明できない変更は提出すべきではないと定めている。Assisted-byタグの削除をもって、こうした責任まで免除されたと解釈することはできない。
10月17日時点で確認されたLinux本流のファイル読み出しコードには、今回の高速化処理はまだ取り込まれていない。今後は競合状態を修正した実装について、実際のワークロードで十分な性能向上が得られるか、メモリ回収や並行するファイル更新との整合性を維持できるかが検証されることになる。これらの条件を満たせれば、今回の改善案は、多コア環境で共有ファイルの読み出し性能が頭打ちになる問題を解消する有力な手段となる可能性がある。



