eBPF コードのプロファイリング方法は?

2026/07/29 0:55

eBPF コードのプロファイリング方法は?

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

核心メッセージは、Linux カーネルの LSM フレームワーク内の最適化されていない eBPF セキュリティフックがファイルを開く総時間のほぼ 90% を消費し、システム管理者およびセキュリティエンジニアにとって重大なパフォーマンスボトルネックを引き起こすという点です。これを証明するために、研究者たちは低オーバヘッドの C ラインを用いたハネスを使って生 Syscall を呼び出し、カスタム

perf
パスと JIT コンパイルを含む正確なカーネル機器計測を用いて、厳密なテスト手法を開発し、
open
などの操作における eBPF テールコールによって引き起こされる遅延を特定しました。このデータはパフォーマンスチューニングが必須のプロダクション環境において重要であり、介入なしにセキュリティの可観測性機能が直接ファイル操作速度を妨害します。今後、開発者はこれらのホットパスを対象としたキャッシュまたはアルゴリズム上の改善を優先して lag を削減する必要があります。最終的には、この研究は eBPF をカーネル強化のために導入する際には、セキュリティ上の利得がシステムの利用可能性および効率性の受容できないコストによって台無しにならないよう、テールコールチェーンの慎重な最適化が必要であることを示しています。

本文

eBPF ワークロードのパフォーマンス測定手法:ファイルオープンフックによるオーバーヘッド分析

本記事では、eBPF コードを実行する際のパフォーマンスへの影響(オーバーヘッド)を測定するための具体的な手順と手法について解説します。特に OS の核心機能である「ファイルオープン操作」における eBPF フックによるコスト検証を例に挙げます。

目的:簡潔なテスト用アプリケーションの作成

eBPF を使用してファイルオープンフックを追加した際のパフォーマンスオーバーヘッドを測定するためには、依存関係を最小限に抑えた簡易な C テストプログラムが必要です。本稿で用意するコードは、キャッシュが温まった状態(Warm Cache)で同一ファイルを繰り返しオープンし、ファイルシステムやディスク I/O によるノイズを排除した上で、p50/p99 の値を精度よく推定することを目的としています。

ベンチマーク用 C コードの概要

以下のコードは libc の

openat()
ラッパーではなく、
syscall(SYS_openat, …)
を直接呼び出すことで、ライブラリ関数のオーバーヘッドまで含めた純粋なシステムコールコストを測定します。また、メモリ割り当て時に行われるページフォールトを防ぐため、初期にメモリアリーヤを確保し全アクセスすることで温め(Pre-warm)ています。

#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <time.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <sched.h>
#include <sys/mman.h>
#include <sys/syscall.h>

static inline uint64_t now_ns(void) {
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);   /* VDSO を経由するため、システムコールは発生しない */
    return (uint64_t)ts.tv_sec * 1000000000ull + ts.tv_nsec;
}

int main(int argc, char **argv) {
    const char *path = argv[1];
    uint64_t n      = strtoull(argv[2], NULL, 10);
    uint64_t warm   = n / 10;

    /* メモリ領域を事前確保し、ページフォールトを発生させてからロックする */
    uint32_t *d = mmap(NULL, n * sizeof(uint32_t), PROT_READ|PROT_WRITE,
                       MAP_PRIVATE|MAP_ANONYMOUS|MAP_POPULATE, -1, 0);
    mlock(d, n * sizeof(uint32_t));
    for (uint64_t i = 0; i < n; i++) d[i] = 0;   /* メモリを全てアクセスしてフォールトを引き起こす */

    for (uint64_t i = 0; i < n; i++) {          /* ウォームアップ期間として最初の 10%の結果は破棄します。 */
        uint64_t t0 = now_ns();
        long fd = syscall(SYS_openat, AT_FDCWD, path, O_RDONLY);   /* libc のラッパーを使用せず、直接システムコールを呼ぶ */
        uint64_t t1 = now_ns();
        if (fd >= 0) close(fd);
        d[i] = (uint32_t)(t1 - t0);
    }

    /* ループ終了後にのみ結果を出力する */
    for (uint64_t i = warm; i < n; i++) printf("%u\n", d[i]);
    return 0;
}

セットアップ:eBPF プロファイリング環境の準備

eBPF コードのプロファイリングを行う際は、

perf
ツールがシンボルを解決し、問題箇所が自コードのどこにあるかを分析できるようにする必要があります。

1. JIT コンパイルとシンボル公開の有効化

以下のコマンドを実行することで、JIT コンパイルを有効化し、JIT によりコンパイルされた BPF シンボルを

/proc/kallsyms
に公開します。これにより
perf report
がプログラム名や関数名を直接表示できるようになります(未知のアドレスではなく)。

sudo sysctl -w net.core.bpf_jit_enable=1
sudo sysctl -w net.core.bpf_jit_kallsyms=1

2. シンボルの確認

eBPF コードを実行した後、シンボルが正しく読み込めているかを確認します。LSM フックを測定しているため「lsm」を検出できるはずです。

# LSM フックの公開状況確認
sudo bpftool prog show | rg -A4 ' lsm '

# シンボルの公開状況確認(カーネルバージョンに合わせてカスタムパスを使用)
sudo rg 'bpf_prog_[0-9a-f]+_ '/proc/kallsyms | rg 'security|path|file|open'

3. 環境への適応(カスタムツール版の場合)

標準パッケージに含まれていない場合や、特定のカーネルバージョン向けにビルドされた

perf
を使用する場合、パスを明示的に設定します。本稿の例では以下の場所を使用しています。

PERF=/usr/lib/linux-tools/6.8.0-134-generic/perf

測定の実施:ベースラインと eBPF アタッチ後の比較

必要なツールが用意できたら、まずは eBPF コードを実行しない状態での**基準(ベースライン)**を測定し、その後 eBPF フックをアタッチした状態での測定を行います。

ベースライン測定

eBPF を使用しない状態で

/etc/hostname
ファイルを開く操作を繰り返し、p50/p99 を計算します。この際、CPU コアの固定高優先度の実行を設定することで、ノイズを低減し正確なベンチマークを取ります。

sudo taskset -c 3 chrt -f 99 ./bench /etc/hostname 100000 > /tmp/samples.txt
  • taskset -c 3
    : 実行を CPU コア 3 に固定し、CPU 間遷移によるノイズを低減します。
  • chrt -f 99
    : ベンチマークに極めて高い優先度を付与します。通常のプログラムのほとんどよりも先に実行され、完了するかブロックされるか中断されるまで継続的に動作します。
  • 結果: C コードでは最初の 10%(ウォームアップ期間)の結果は破棄されているため、出力ファイル
    /tmp/samples.txt
    には 90,000 サンプルのデータが含まれます。

eBPF アタッチ後の測定

eBPF コードを実行中(またはフックをアタッチした状態)でも同様に測定します。今回は

perf record
を使用してコールスタックを記録し、内核モードにおける CPU クロックスイクルのみをサンプリングします。

sudo "$PERF" record \
    -g \                              # コールスタックの記録
    --call-graph fp                  # フレームポインターを用いてスタックを展開
    -e cycles:k                      # ユーザー空間以外(システムコール、VFS、LSM、eBPF 実行など)の CPU クロックスイクルのみサンプリング
    -F 997                           # 1 秒間に 997 サンプル(非整数値により周期的なバイアスを回避)
    -o ~/perf.data                   # 出力ファイル
    -- \
    taskset -c 3 chrt -f 99 ./bench /etc/hostname 200000 \
    > /tmp/samples.txt               # ベンチマーク結果も同時に出力

データの解析

取得したデータをソートして表示し、パフォーマンスボトルネックを特定します。

sudo "$PERF" report -i ~/perf.data --stdio --sort comm,dso,symbol > perf.txt

フレイムグラフ解析と最適化の方向性

perf.data
に対して Inferno を用いて生成されたフレイムグラフから、以下のコールスタックがパフォーマンスのボトルネックとなっていることが確認できます。

  • bpf_lsm_file_open
    : eBPF LSM フック自体の実行コスト
  • テイルコール(Tail Call)系列:
    • do_dentry_open
      : 89.52%
    • 0xffffffffc0288c18
      : 89.30%
    • bpf_prog_b06f413955402a4b_tail_call_security_check
      : 87.40%
    • bpf_prog_934361d723613c1c_enforce_access_policy
      : 77.57%
    • bpf_prog_a0f18f4b0b140d77_path_check_callback
      : 57.87%
    • ...および下位の処理 (
      bpf_probe_read_kernel
      ,
      copy_from_kernel_nofault
      など)

考察と最適化方針

本記事の焦点は特定の数値そのものではなく、プロファイリング手法そのものにあります。観測されるオーバーヘッドは、フックが具体的にどのような処理を行うかに大きく依存するためです。

上記の結果から時間を費やす箇所を分析した結果、以下のような対策を検討できます。

  1. eBPF コードの最適化:
    perf-tune
    を用いて、eBPF が動作している際の C コード(または BPF コード)のパフォーマンス向上を図ります。
  2. アルゴリズムの改善: キャッシングの実装や、問題箇所に基づいたロジックの見直しを行います。

これにより、eBPF コードによるパフォーマンスへの影響を明確に把握し、必要な最適化の箇所を特定することが可能です。

同じ日のほかのニュース

一覧に戻る →

2026/07/29 5:52

OpenAIがCodex Securityをオープンソース化した

## Japanese Translation: `@openai/codex-security` ツールは、コードベース内に直接存在するセキュリティ脆弱性を特定、検証、修正することを目的とした CLI と TypeScript SDK です。このツールにより、チームはリポジトリの走査、コード変更のレビュー、発見結果の自動追跡が可能となり、安全な開発ライフサイクルが効率化されます。ユーザーはワークフローにこれらのチェックを簡単に統合できます:ローカルでの使用には `npm install @openai/codex-security` でインストールし、`npx codex-security login` でログインし、`npx codex-security scan .` で走査を実行します。継続的インテグレーション(CI)パイプラインでは、ログインを必要とせず `OPENAI_API_KEY` 環境変数を設定することで自動化がサポートされます。该软件は現代的な環境(Node.js 22+ または Python 3.10+)で動作し、GitHub Actions などの既存の CI システムにシームレスに統合できます。TypeScript SDK を活用することで、開発者はビルドプロセス内でチェックをプログラム的に初期化し、レポートパスを直接ログ出力できます。この反応的な修正から能動的な予防への転換により、チームは手動介入なしで効率的に堅牢なセキュリティ標準を維持できるようになります。

2026/07/29 1:58

Substack の書き手にはウェブサイトが必要です。

## 日本語訳: 著者は、長期的な生存を確保するため、Substack を単なる配信チャネルとして厳格に扱うべきであり、主なデジタル居宅としては見なしてはならない。`substack.com` などのプラットフォームへの一依存はリスクが高く、同社は規約を変更した場合、著者がコンテンツや可见性(視認性)を失う可能性があるためであり、過去に Twitter、Medium、Reddit、Facebook が直面した状況と同様です。「デジタルテナント」または「デジタル小作農家」として突然の立ち退きに晒されることを避けるために、クリエイターは自らの独立したドメイン所有し、ホームベース(主要サイト)を自らコントロールする必要があります。著者ジョン・スカルズィはこの戦略を例示しており、その 28 年間の歴史を持つ独立ブログが安定的な錨(アンカー)として機能し、ソーシャルメディアはそのトラフィックをそちらへ誘導するための単なる増幅器として使用しています。このアプローチは POSSE(自サイトの公開他サイトへの Syndication:Publish On Your Own Site, Syndicate Elsewhere)手法と整合しており、RSS フィードを通じて著者の「事実上の真実源」から発信されたコンテンツが外部プラットフォームへと配信されることを保証します。これにより、将来の企業崩壊、アルゴリズムのシフト、無警告で少数派やローカライズされた声を沈黙させる可能性があるエコーチェンバーに対する防護策となります。独立したデジタル居宅を確保することで、著者は過渡的なエコシステムに対する耐性を保証し、ユーザーもクリエイターも利得志向のアルゴリズムに人質となるのを防ぎます。

2026/07/29 5:58

ハーフライフを Mac OS 9 に移植

## Japanese Translation: ### サマリー: ハーフライフシリーズが、オリジナルタイトル発売から 28 年ぶりに、PowerPC ベースのマッキン托しコンピュータ向けの初プレイ可能版をリリースしました。これは GitHub ユーザー doctashay が Xash3D FWGS エンジンのフォーク(GoldSrc テクノロジーのリ実装)を用いて作成したものであり、Valve による過去のキャンセルされた計画や、Intel チップへの移行後の 2013 年版に続く長らくの空白を埋めるものです。このファングレードリリースには、『ハーフライフ』、『ブルー・シフト』、『オポージング・フォース』および『Uplink』のデモが含まれ、マルチプレイヤー対応を含み、開始から終了までフルプレイ可能です。Mac OS 9.0 以降で G3 や G4 プロセッサーなどのレガシーハードウェア上で動作し、廃棄されたシステムにも新たな生命を与え、これまでこれらのプラットフォームでは入手不可能だった象徴的なタイトルへのアクセスを維持します。この成就是マッキン托しゲームコミュニティにとって重要ですが、性能はユーザーのグラフィックカードに大きく依存します。VRAM が限られたデバイス(8MB 未満の iMac や iBook など)では動作が困難な場合があります。まだ公式 Valve プロダクトではありませんが、このリリースは PowerPC マクintosh の計算機史におけるキャンセルされた時代を成功裡に蘇らせます。