開発

Linux 7.2カーネル、/proc/filesystems読み取りを最大444%高速化

Linux 7.2カーネルが/proc/filesystemsの読み取りを最大444%高速化。libselinuxが予想以上に頻繁に参照していたファイルシステム一覧を、RCU化と事前生成により劇的に改善した。

6分で読める SINGULISM 編集チームが確認・編集

Linux 7.2カーネル、/proc/filesystems読み取りを最大444%高速化
Photo by Gabriel Heinzer on Unsplash

Linux 7.2カーネルに向けた注目すべき最適化の一つが、/proc/filesystemsの読み取り性能向上である。Phoronixの報道によれば、この変更により最大444%の高速化が実現するという。

/proc/filesystemsは、動作中のカーネルが対応しているファイルシステムの一覧を取得するための仮想ファイルである。一見すると、それほど頻繁に参照されるとは思われないこのファイルが、実際には驚くほど高い頻度で読み取られている。その要因は、SELinuxライブラリ(libselinux)による参照にある。

予想以上に重かった /proc/filesystems

libselinuxは、多数のプログラムにリンクされている。その範囲は、エディタやシェルユーティリティなど、SELinuxとは直接関係のないプログラムにも及ぶ。今回の最適化に関するプルリクエストの中で、Christian Brauner氏は次のように指摘している。「libselinuxが/proc/filesystemsを読み取るため、このファイルは非常に頻繁に読まれる。影響を受けるプログラムは驚くほど多く、sedのようなコマンドラインツールも含まれる。」

従来の実装では、/proc/filesystemsの読み取り時に、カーネルは手動で管理されたリンクリストを走査し、エントリごとにprintf形式で文字列を生成していた。この処理は、ポインターチェイシングと逐次的な文字列生成を伴うため、高頻度のアクセスが発生する環境では無視できないオーバーヘッドとなっていた。

RCU化と事前生成がもたらす効果

Linux 7.2カーネルで導入された改善は、複数の要素から構成される。

第一の変更点は、ファイルシステムリストのRCU(Read-Copy-Update)化である。RCUは、読み取り専用のアクセスをロックフリーで実行できる同期機構で、読み取り側のオーバーヘッドを極限まで削減する。従来の実装では、/proc/filesystemsを開くたびに参照カウントの管理が発生していたが、RCU化によりこれらの処理が不要となった。

第二の変更点は、読み取り時に出力される文字列の事前生成とキャッシュである。従来は、読み取りのたびに全エントリを逐次的に文字列変換していた。新しい実装では、ファイルシステムの一覧が変更されない限り、事前に生成された文字列をキャッシュから返す。これにより、ポインターチェイシングと逐次的なprintf呼び出しが完全に排除される。

第三の変更点として、/procファイルをfs/proc/ディレクトリ外から永続的なものとしてマークできる仕組みが導入された。これにより、ファイルシステム関連のコードから/procの内部構造をより適切に操作できるようになる。

現実のパフォーマンスに与える影響

444%という高速化率は、単なる理論値ではない。libselinuxがリンクされているプログラムは非常に多く、サーバー環境やコンテナ環境では特に顕著な効果が期待される。

具体的には、ファイルシステムの一覧を頻繁に取得する操作、例えばコンテナの起動やファイルのアクセス制御チェック、システムコールのラッパー処理などでボトルネックが解消される。コンテナを多数動作させる環境では、この変更がシステム全体の応答性に寄与する可能性がある。

Linus Torvalds氏は、この改善をLinux 7.2カーネルにマージした。Linux 7.2カーネルは、多数のパフォーマンス改善を含むメジャーリリースとして位置づけられており、今回の最適化もその一部である。

編集部の見解

今回の最適化は、「予想外のボトルネック」が現実のシステム性能に与える影響を再認識させる事例である。/proc/filesystemsのような、一見すると低負荷に見えるファイルが、ライブラリのリンク関係によって高頻度でアクセスされるという構造は、システム全体のプロファイリングの重要性を示している。短期的には、Linux 7.2にアップデートする組織で、特にSELinuxを有効にしている環境において、システムコール処理のレイテンシ改善が観測されるはずだ。特にCI/CDパイプラインやコンテナの頻繁な起動・停止を行う環境では、累積的な効果が無視できない。

長期的に見れば、今回の改善手法は他の/procファイルやsysfsの最適化にも応用可能である。RCU化と事前生成・キャッシュの組み合わせは、読み取り頻度が高く書き込みが稀な仮想ファイルシステムの性能を向上させる一般的なパターンとして、今後のカーネル開発に影響を与える可能性がある。また、この事例は、カーネルの小さな変更がユーザーランドのパフォーマンスに大きく影響することを示しており、エンジニアリングの判断におけるトレードオフの難しさを浮き彫りにしている。

編集部として一つ問いたい。/proc以下の同様のファイルで、同様の最適化が必要なものは他に存在しないのだろうか。また、ユーザーランドのリンク構造がカーネルの最適化判断に与える影響を、より体系的に評価する仕組みは必要ではないか。

参考

よくある質問

/proc/filesystemsを頻繁に読み取る原因は何か
SELinuxライブラリ(libselinux)が、多くのプログラムにリンクされているためです。sedのような基本的なコマンドからサーバープロセスまで、libselinuxをリンクしたプログラムが起動時に/proc/filesystemsを読み取ります。
今回の最適化はどのような仕組みで実現されたか
ファイルシステムリストのRCU化、出力文字列の事前生成とキャッシュ、/procファイルの永続的マーク機能の3点が主要な要素です。従来のリンクリスト走査と逐次的なprintf処理を排除し、読み取り時のオーバーヘッドを削減しています。
444%の高速化はどのような環境で期待できるか
コンテナ環境やサーバーなど、libselinuxがリンクされたプログラムを多数実行するシステムで特に顕著です。コンテナの起動やファイルアクセス制御チェックが頻繁に行われる環境では、システム全体の応答性向上に寄与します。
出典: Phoronix

コメント

← トップへ戻る