memoization でeBPFのCPU負荷を約90%削減
原題: Dropping eBPF CPU Cost by About 90% with Memoization (Not AI Gen)
なぜ重要か
eBPFベースのセキュリティエージェントにおいてmemoizationでCPU負荷を劇的に削減した実装例は、低レイヤーセキュリティツールの設計指針として業界参照価値が高い。
ソフトウェアエンジニアのNathan Naveenは、eBPFセキュリティエージェントにinode単位のキャッシュ(memoization)を導入することで、カーネルのCPUコストを約90%削減したと発表した。2026年9月11日付のブログ記事で詳細を公開。関連コードはGitHubリポジトリ「bomfather/agent」でオープンソースとして公開されている。
Nathan Naveenと兄弟が共同開発するeBPFセキュリティエージェントは、ファイルオープン時にLSMフックを使いパスを再構築し、親dentryを遡りながらポリシーを照合する設計になっていた。ポリシーの照合自体(許可・拒否の判定)よりも、「どのポリシーが適用されるかを特定する処理」がCPUコストの大半を占めていることをプロファイリングで発見した。
特にPostgresのように同一ディレクトリ配下の複数ファイルに繰り返しアクセスするケースでは、毎回フルパスのdentryウォークが発生し、同じ作業が何度も重複していた。例えば`/var/lib/postgres/data/base/123`、`/234`、`/345`それぞれに対して独立してパス走査が行われていた。
解決策として採用したのがinode単位のキャッシュだ。dentryはポインタであるためeBPFマップに直接格納できない。そこでキャッシュキーを「マウント名前空間ID・マウントID・inode番号」の3フィールドで構成した。inode番号のみでは異なるマウントツリー間で重複が生じるため、マウントIDと名前空間IDを組み合わせることで安全に一意性を確保している。
キャッシュの値はアクセスインデックス(ポリシーをビットマスクで表現した際のビット位置)とキャッシュ状態の2つで構成され、マップタイプには`BPF_MAP_TYPE_LRU_HASH`を採用、最大エントリ数は1万件に設定した。
一度解決済みのinodeへのアクセスはキャッシュを参照するだけで処理が完結し、パスウォーク全体をスキップできる。この変更によりカーネルCPUコストが約90%削減されたと報告している。実装の全コードはGitHub(https://github.com/bomfather/agent)で公開中だ。