Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
bpf_arenaとstruct_opsを使うのが難しかった話
Search
KANAI Masumi
November 06, 2026
Technology
110
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
bpf_arenaとstruct_opsを使うのが難しかった話
eBPF Japan Meetup #8(
https://ebpf.connpass.com/event/404549/)で使いました
KANAI Masumi
November 06, 2026
More Decks by KANAI Masumi
See All by KANAI Masumi
xk6によるプロトコル追加 -テストライフサイクルと文字列変換の注意点-
masu_mi
1
320
eBPF を拡張したい話 -カーネルモジュールで KFunc を追加する-
masu_mi
0
53
Other Decks in Technology
See All in Technology
eBPF 簡介 2026 版
shunghsiyu
0
180
これだけは抑えておきたい!後悔しない re:Invent の過ごし方 / AWS re:Invent 2026 prestudy
kinunori
2
700
あなたのDartコードは丸見えかもしれない ~reFlutterで暴くFlutterアプリの中身と多層防御~
zozotech
PRO
0
770
セキュリティ専任チームなしで攻撃を先回りするSREが実践したSIEM on Amazon OpenSearch Service
cscengineer
PRO
0
160
re:Invent2026 事前勉強会 歴史と愉しみ方10分LT編
toshi_atsumi
0
120
kaonavi Tech Night#2
kaonavi
0
110
AIに任せられるFlutterコードベースを作る 〜仕様をコードで表し、ハーネスで守る〜
myohei
1
630
【dbts2026】AIエージェントの 判断と探索を変える、 データベース エンジニアリング― 既存DBの処理と依存関係から作る、オペレーショナルオントロジー ―
shisyu_gaku
0
130
OneLakeをデータソースにした AI Search(Foundry IQ)の ライフサイクル管理
ryuseiiida
0
220
Microsoft Entra Kerberos で実現するクラウド デバイス管理
tamaiyutaro
1
350
AWSを利用する上で知っておきたい名前解決の話 2026
nagisa53
2
490
企画からFlutter実装まで、1つの機能を一貫して開発したプロセスと成果物
khiroyuki1003
1
150
Featured
See All Featured
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
790
Building a Scalable Design System with Sketch
lauravandoore
464
34k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.3k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Context Engineering - Making Every Token Count
addyosmani
9
1.3k
Writing Fast Ruby
sferik
630
63k
[SF Ruby Conf 2025] Rails X
palkan
3
1.5k
Believing is Seeing
oripsolob
1
270
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
310
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
320
Paper Plane
katiecoart
PRO
5
54k
Transcript
bpf_arenaとstruct_opsを使うのが難しかった話 s3fs代替を作ってみて気づいた と ⾦井真澄(@masu-mi.bsky.social) / BBSakura Networks株式会社 eBPF Meetup #8
2026-11-06
⾃⼰紹介 • ⾦井真澄 (@masu-mi.bsky.social) • 2021年2⽉ BBSakura Networks 株式会社 中途⼊社
◦ ⼊社前、モバイルコア ◦ ⼊社後、モバイルコアむ • つ • 新卒はウェブ企業 ◦ • も ろそうだな い ば市在住 メディアサービス・オブジェクトストレージ開発 学⽣時代は、完全WKB解析と⾮断熱遷移
会社紹介 持分比率 100 % 49 % 51 % 2019.08~ IX事業
ネットワーク ソリューション ソフトウェア事業 ネットワーククラウド サービスの開発 ソフトウェア ソリューション 3
今⽇の流れ • 背景: s3fs-ebpf 作った動機と概要 • struct_ops をつ う •
bpf_arena をつ う • 反省: s3fs-ebpf の評価と 4
作ったものと動機 s3fs-fuseの代替ファイルシステムを試験⽤に作りま • た FUSEのs3fsは、openやreadのたびにデーモンに処理 ‒ 早 折り返 ほどレイテンシ 渡りS3と通信
る 改善 る ‒ キャッシュ層を追加 て効果を測定 たい ‒ メモリ消費、追加実装 有益 ? ‒ Page Cacheのスケジューラ 素直な実装だ どカーネルモジュールなので実装 楽 • キャッシュ機能を拡充 る ‒ eBPFでカーネル内で判断 る ‒ prewarm などアプリケーション側の知識で追加動作を差 込みたい 5
s3fs-ebpfの構成 ユーザー空間、VFS、⾃作FS、eBPF 、それぞれ別のメモリ領域を参照 る アプリ hitならdaemonまで⾏かない daemon ユーザー空間 GET S3
/dev/s3fs_ebpf カーネル read(2) VFS generic_file_read_iter page cacheのmiss eBPFプログラム fentry、struct_ops ⾃作FS(kmod) read_folio、evict、KFunc 参照するメモリ領域 page cache ファイルの中⾝ ユーザー空間のプロセス 既存のカーネルと外部 出典:masu-mi/s3fs-ebpf(pcacheモード) BPF map 状態と統計 bpf_arena 書いた中⾝ ⾃作FS(kmod) chunk表 kmodのキャッシュ eBPF eBPFの呼び出 6
使ったeBPF機能 難 ったのはbpf_arenaとstruct_opsで、関連 てfentryとKFuncも扱う 機能 使った場所 利⽤⽬的 struct_ops ⾃作FSの関数 ⾃作FS内のキャッシュ操作を交換可能に
る fentry read() 読み取りイベントを観測 bpf_arena daemonとeBPF間 ファイル共有、daemon ら通知(予定) KFunc(BPFへ関数提供) カーネルモジュールで登録 ⻑いループ処理のverifier迂回⽬的 出典:masu-mi/s3fs-ebpf、Linux 6.12 7
使ったeBPF機能 難 ったのはbpf_arenaとstruct_opsで、関連 てfentryとKFuncも扱う 機能 使った場所 採⽤判断 struct_ops ⾃作FSの関数 ⾃作FS内のキャッシュ操作を交換可能に
る -> OK fentry read() 読み取りイベントを観測 -> OK bpf_arena daemonとeBPF間 ファイル共有 -> NG、daemon ら通知(検討中) KFunc(BPFへ関数提供) カーネルモジュールで登録 ⻑いループ処理のverifier迂回⽬的 -> (may_goto, bpf_loop, ) 出典:masu-mi/s3fs-ebpf、Linux 6.12 8
struct_ops アプリ daemon ユーザー空間 GET S3 /dev/s3fs_ebpf カーネル read(2) VFS
generic_file_read_iter page cacheのmiss eBPFプログラム fentry、struct_ops ⾃作FS(kmod) read_folio、evict、KFunc 参照するメモリ領域 page cache ファイルの中⾝ ユーザー空間のプロセス 既存のカーネルと外部 出典:masu-mi/s3fs-ebpf(pcacheモード) BPF map 状態と統計 bpf_arena 旧構成のみ ⾃作FS(kmod) chunk表 kmodのキャッシュ eBPF eBPFの呼び出 9
struct_opsの仕組み struct_opsは構造体を登録で るmap、メンバにeBPFプログラム(fd)も登録で る SEC(".struct_ops.link") struct s3fs_policy_ops sieve_pick_ops = {
.on_admit = (void *)sp_admit, .on_hit = (void *)sp_hit, .pick_victim = (void *)sp_pick, /* ... on_evict, on_insert, ... */ }; 値のメンバの例(sched_ext_ops) SEC(".struct_ops.link") struct s3fs_policy_ops my_ops = { メンバ BPF プログラムの型(BTF)をverifier 関数のほ に持てる 検査 に普通の値(名前・上限値など)もメンバ 型定義はカーネル側(tcp_congestion_ops、 sched_ext_ops、6.9以降はkmodも) 型定義 たモジュール init_memberで受 ⼀式をstruct_opsのmapの値と て登録 bpf_linkで有効に る 取る 、 .on_evict = (void *)my_on_evict, .flags = S3FS_POLICY_F_NO_ON_HIT, .name = "my_policy", }; 10
struct_opsの仕組み struct_opsは構造体を登録で SEC(".struct_ops.link") るmap、メンバにeBPFプログラム(fd)も登録で る BPF_F_LINKフラグ v6.4で追加 struct s3fs_policy_ops sieve_pick_ops
= { .on_admit = (void *)sp_admit, .on_hit = (void *)sp_hit, .pick_victim = (void *)sp_pick, /* ... on_evict, on_insert, ... */ }; 値のメンバの例(sched_ext_ops) SEC(".struct_ops.link") struct s3fs_policy_ops my_ops = { メンバ BPF プログラムの型(BTF)をverifier 関数のほ に持てる 検査 に普通の値(名前・上限値など)もメンバ 型定義はカーネル側(tcp_congestion_ops、 sched_ext_ops、6.9以降はkmodも) 型定義 たモジュール init_memberで受 ⼀式をstruct_opsのmapの値と て登録 bpf_linkで有効に る 取る 、 .on_evict = (void *)my_on_evict, .flags = S3FS_POLICY_F_NO_ON_HIT, .name = "my_policy", }; 11
登録から差し替えまでの流れ mapを書いて登録を準備 、linkの作成、更新、解放でkmodの関数 呼ばれる ユーザー空間の操作 カーネルでの処理 kmodの関数 BPF_MAP_UPDATE_ELEM(mapの 値を書く) メンバ
とに検査、trampolineでkdataを埋 め、READYに る init_member、validate BPF_LINK_CREATE linkを作り、kdataを公開 reg(kdata) BPF_LINK_UPDATE(新しいmapの fd) linkの接続先を新 BPF_LINK_DETACHか、最後のfdの close 接続を外 る いmapに付 替える update(new, old) unreg(kdata) mapの値は書き換えられないので、差し替えは新しいmapへの付け替えで⾏う 出典:Linux 6.12 kernel/bpf/bpf_struct_ops.c 12
kmodでのstruct_opsの登録 kmodは表を1つ⽤意 、register_bpf_struct_opsで登録 る struct s3fs_policy_ops { (*pick_victim)(void); ... };
// 1 static struct s3fs_policy_ops stubs = { stub, ... }; static struct bpf_struct_ops st_ops = { 1 vtableの型と、member との空 関数(cfi_stubs)を⽤意 る 2 bps_struct_ops構造体のインス タンスを作る 3 linkの作成で公開、更新で差 え、解放で撤去 る 4 module_initで型を登録 る // 2 .verifier_ops = &vops, .cfi_stubs = &stubs, .init = init, .init_member = init_member, .reg = reg, .unreg = unreg, .update = update, .owner = THIS_MODULE, .name = "s3fs_policy_ops", }; // 中で reg: { rcu_assign_pointer(active, kdata); /*...*/ } unreg: { // 3 rcu_assign_pointer(active, NULL); 替 synchronize_rcu(); } update: rcu_assign_pointer(active, kdata); synchronize_rcu(); register_bpf_struct_ops(&st_ops, s3fs_policy_ops); // 4 公開と撤去はポインタ1本で⾏い、撤去の後はsynchronize_rcuで待つ 13
kmodが⽤意する部品 struct_opsの型をkmodで提供 るには、検査と公開の部品を べて書 部品 やること なぜ要るか vtableの型と登録 型をBTFに出 BPF側のstructとmemberを名前で照合
る cfi_stubs member verifier_ops 使えるhelperと引数の読み⽅ struct_opsのprogは れで検査 init、init_member、validate 登録時、メンバ と、全メンバの後に 値のメンバと組み合わ を検査 る フレームワーク 必 呼ぶ reg、unreg vtableを公開 kmod ど update BPF_LINK_UPDATEで差 呼び出し側の wrapper rcu_dereference てNULLなら既定値 とに同 型の空関数 、撤去 る 替える ないと登録 -EINVAL。CFIの型を ら読む ら取る れる をフレームワークは知らない ないと-EOPNOTSUPP attachの前はvtable ない fmod_retの約15⾏に対し、約220⾏になった 14
呼び出しの流れ fentryは元の関数に処理を⾜ fentry struct_ops 、struct_opsは実装そのものを置 換える nopを書 換えたcall trampoline BPF
prog (call) kmodの間接call CFIの検査 trampoline 元の関数 続 BPF prog (call) 1回の呼び出しのコストはほぼ同じ stuct_opsは CFI(Kernel Control Flow Integrity: カーネル制御フロー整合性)が挟まる 出典:Linux 6.12 arch/x86/net/bpf_jit_comp.c、kernel/bpf/trampoline.c 15
fentryのtrampoline fentryは、関数の先頭の5バイトのnopを、trampolineへのcallに書 換える attach前 bpf_trampoline(JITが作る) generic_file_read_iter: 引数のレジスタをスタックに保存 endbr64 nop5 /*
was: call __fentry__ */ __bpf_prog_enter push %rbp attach後 generic_file_read_iter: endbr64 BPF prog __bpf_prog_exit call bpf_trampoline push %rbp 関数の続 へ戻る attachしていない関数のコストは、nop 1つだけ 出典:Linux 6.12 kernel/bpf/trampoline.c、arch/x86/net/bpf_jit_comp.c 16
CFIとtrampoline CFIは、関数ポインタで呼ぶ先の関数の型を、ハッシュで確 める 呼ぶ側:kmodのops->on_evict(ino) movl $(-hash), %r10d addl -15(%r11), %r10d
jz 1f ud2 呼ばれる側:struct_opsのtrampoline __cfi_tramp: movl $hash, %eax /* callee's hash */ /* from cfi_stubs */ nop x 11 tramp: /* type mismatch */ endbr64 1: call *%r11 push %rbp ... trampolineは実⾏時に作るのでハッシュを持た 、cfi_stubsの同 eBPF プログラム memberの関数 struct_ops⽤のmapを更新時に、カーネルはkCFU付 呼ばれる側の後半で call xxx とeBPFプログラム呼び出 ら写 のtrampコードを⽣成 ⼊っている cfi_stubsがないと、trampolineに付ける型のハッシュが決まらない 出典:Linux 6.12 arch/x86/net/bpf_jit_comp.c、kernel/bpf/bpf_struct_ops.c 17
アルゴリズムが使うアクセス情報 どのアクセス情報をど まで省 る は、使うアルゴリズムで決まる アルゴリズム 使うアクセス情報 省ける情報 SIEVE(参照ビットが⽴ったものを残す) 参照ビット(1ビット)
回数と時刻 LRU(最近使ったものを残す) 最終アクセスの順序 な S3-FIFO(⼩さいFIFOで再参照されたものだけ をメインに移す) アクセス回数(上限3) 3を超える回数 W-TinyLFU(推定頻度でadmitを決める) cacheにないinoも含めたアクセス頻 度 な 持つ情報を変えると、BPF mapは作り直しになる 18
vtableの範囲 使うアクセス情報 違うので、アルゴリズムを⾜ たびにvtableに関数 増えた 関数 kmodとBPFのどちらが何を持つか on_evict ino とに追い出
てよい を0/1で返 。順序はkmod on_insert、on_remove、pick_victim BPF 順序を持ち、kmod 返ったinoを確 on_size 容量の計上はkmod、予算の配分はBPF on_hit 数えるのはkmod、使い⽅はBPF missの途中のino kmodは追い出 決める める ないので、policyに⼊れない 提案はBPF、確定はkmodと分けないと状態がずれる 出典:docs/design/design-review-checklist.md §3 19
bpf_arena アプリ daemon ユーザー空間 GET S3 /dev/s3fs_ebpf カーネル read(2) VFS
generic_file_read_iter page cacheのmiss eBPFプログラム fentry、struct_ops ⾃作FS(kmod) read_folio、evict、KFunc 参照するメモリ領域 page cache ファイルの中⾝ ユーザー空間のプロセス 既存のカーネルと外部 出典:masu-mi/s3fs-ebpf(pcacheモード) BPF map 状態と統計 bpf_arena 旧構成のみ ⾃作FS(kmod) chunk表 kmodのキャッシュ eBPF eBPFの呼び出 20
bpf_arenaの使い⽅ bpf_arenaはユーザー空間とeBPF間の共有メモリ(最⼤4 GiB) struct { __uint(type, BPF_MAP_TYPE_ARENA); __uint(map_flags, BPF_F_MMAPABLE); __uint(max_entries,
1024); /* pages, up to 4 GiB */ } arena SEC(".maps"); struct node __arena *n = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0); daemonはmapのfdをmmap 、同 ノードを普通のポインタで辿る __arena 付いたものは、コンパイラ arenaの中のメモリと て扱い、参照外 の前にcastを⼊れる 要件:Linux 6.9以降。__arenaの⾃動のcastにはclang 19以降 出典:Linux 6.12 kernel/bpf/arena.c 21
arenaのアドレス解決 eBPF、ユーザープロセスでmmap先のアドレス 異なるので解決⽅法 必要 →ポインタはユーザー空間のアドレスを格納、BPFは下位32bitに⾃分の基底を⾜ て読む user_vm_start user_vm arenaのmmap page
同 kern_vm 物理ページ 4 GiBの予約 arenaの範囲 kern_vm_start kern_vm_start + (u32)user_vm_start page stored n->next : 0x00007f7d_26200040 (user VA) cast_kern : w2 = w2 -> 0x26200040 (offset from kern_vm_start) load : r3 = *(u64 *)(r2 + r12 + off) r12 = kern_vm_start 上位32bitを捨てるので、壊れた値でも予約領域の外に出ない 出典:Linux 6.12 kernel/bpf/arena.c、kernel/bpf/verifier.c 22
BPF_F_NO_USER_CONV arenaのmapにBPF_F_NO_USER_CONVを付 ると、cast_user 1命令になる 付ける場所:arenaのmapの定義 __uint(map_flags, BPF_F_MMAPABLE | BPF_F_NO_USER_CONV); 既定:JITが出す7命令
付けたとき mov mov w2, w1 shl r2, 32 or r2, user_vm_start >> 32 rol r2, 32 xor r11, r11 test w2, w2 w2, w1 verifier 32bitのmovに書 換え、下位32bitだ を残 引 換えに、ユーザー空間はポインタをそのまま辿れない cmove r2, r11 上位32bitにuser_vm_startを戻 、NULLは0のまま 読み書きでkern_vm_startを⾜すのは、付けても付けなくても同じ 出典:Linux 6.12 arch/x86/net/bpf_jit_comp.c、kernel/bpf/verifier.c 23
BPF_F_NO_USER_CONV arenaのmapにBPF_F_NO_USER_CONVを付 ると、cast_user 1命令になる 付ける場所:arenaのmapの定義 __uint(map_flags, BPF_F_MMAPABLE | BPF_F_NO_USER_CONV); 既定:JITが出す7命令
付けたとき mov mov w2, w1 shl r2, 32 or r2, user_vm_start >> 32 rol r2, 32 xor r11, r11 test w2, w2 w2, w1 verifier 32bitのmovに書 換え、下位32bitだ を残 引 換えに、ユーザー空間はポインタをそのまま辿れない ユーザー空間でのarenaの開始アドレス(即値) cmove r2, r11 上位32bitにuser_vm_startを戻 、NULLは0のまま 読み書きでkern_vm_startを⾜すのは、付けても付けなくても同じ 出典:Linux 6.12 arch/x86/net/bpf_jit_comp.c、kernel/bpf/verifier.c 24
cilium/ebpfでのloadの順序 cilium/ebpfでは、arenaを先に作ってmmap て ら、progをload る LoadAndAssign mapを作る user_vm_start 2段のload arenaだ
NewMap progをload 拒否 れる 決まる前にaddr_space_castを検査 る unix.Mmap LoadAndAssign MapReplacements loadで る mmapの前にloadすると、addr_space_castが拒否される 25
addr_space_castのMarshalの不具合 cilium/ebpfの古い版は、addr_space_castのoffを0に書 換えていた .oを読む デコード (だいたい逆アセ) mapのfdや kfuncのIDを埋める Marshalで バイト列に戻
BPF_PROG_LOAD cilium/ebpf loadの前に⾏うリンクとrelocation clangが出した命令 Marshalのあと code off imm ALU64 MOV X off = 1 imm = 1 ALU64 MOV X off = 0 imm = 1 BPF_MOV uses reserved fieldsで拒否 26
addr_space_castのMarshalの不具合 cilium/ebpfの古い版は、addr_space_castのoffを0に書 換えていた .oを読む デコード (だいたい逆アセ) mapのfdや kfuncのIDを埋める Marshalで バイト列に戻
BPF_PROG_LOAD cilium/ebpf loadの前に⾏うリンクとrelocation clangが出した命令 Marshalのあと code off imm ALU64 MOV X off = 1 imm = 1 ALU64 MOV X off = 0 imm = 1 BPF_MOV uses reserved fieldsで拒否 MOV命令クラスは off={ 8,16,32 } のみだったaddr_space_cast(1)が追加 27
addr_space_castのMarshalの不具合 cilium/ebpfの古い版は、addr_space_castのoffを0に書 換えていた .oを読む デコード (だいたい逆アセ) mapのfdや kfuncのIDを埋める Marshalで バイト列に戻
BPF_PROG_LOAD cilium/ebpf loadの前に⾏うリンクとrelocation clangが出した命令 Marshalのあと code off imm ALU64 MOV X off = 1 imm = 1 ALU64 MOV X off = 0 imm = 1 BPF_MOV uses reserved fieldsで拒否 修正はmainに⼊ったが、タグ付きのリリースにはまだない 28
arenaで残る回避策 loadの順序のほ にも、ツールとカーネルの両⽅に回避策 残る 課題 回避策 __arenaのグローバル変数(.addr_space.1)を、cilium/ebpfが 読み込めない arenaの先頭アドレスとオフセットをctxで渡 、毎回組み⽴てる
clang 18以下ではcastなしでビルドが通る clang 19未満を拒否 、.oにcast progがarenaのmapを参照しないと関連付かない asm volatileで参照を作る kmodはkern_vmcaを使えない(未export、例外テーブルがな い) ユーザー側のページをpin て読む(GUP、1回約1.7 µs) ある テストで確 める kmodはarenaのページをpinして読むしかなく、主なread経路から外した 29
ループの書き⽅ 6.12では、can_loopを⾜ ばarenaのlinked listをBPFのまま辿れる 拒否された形 6.12で通る形:can_loop(may_goto命令) while (n) { while
(n && can_loop) { sum += n->payload; sum += n->payload; n = n->next; n = n->next; } } // BPF program is too large. // processed 1000001 insns 上限:1回の実⾏で、subprog 検査:周回の状態 前と同 とに合計8,388,608回(BPF_MAX_LOOPS)。使い切るとループを抜 る になれば打ち切るので、100万命令の予算を周回 とには使わない 資料:commit 011832b97b31「bpf: Introduce may_goto instruction」、selftests/bpf/bpf_experimental.h(can_loop) ループのためにKFuncを書く必要はほぼない 出典:Linux 6.12 kernel/bpf/verifier.c、selftests/bpf/bpf_experimental.h、bpf_arena_list.h 30
s3fs代替の性能と判断 31
s3fs代替の性能 open+read+closeの⼤ な差は、openでS3を確認 ない分 ら来ていた 構造だけ 独⾃キャッシュ 全体 open+read+close(p50) 3.2×
140× 180× open+read+close、openでS3を確認 1.7× 1.27× 1.2× ⼩さいファイル10,000個のcat(warm) 2.9× 34× 39× cold read 300 MiB 0.74× 1.44× 1.27× 新規100 MiBのdurable write 0.97× 1.20× 1.04× 既存10 MiBの途中に4 KiB書く 0.66× 0.71× 0.68× warmのSQLite(OLTP) 1.89× 2.54× 0.97× 場⾯ 構造だ :両⽅キャッシュな 。独⾃キャッシュ:両⽅openのたびにpage cacheを捨てる。全体:両⽅ べてのキャッシュを使う。値は s3fs-fuseの時間÷s3fs-ebpfの時間 s3fs-fuseは新鮮 と⼀貫性のため、openのたびにHEAD HEAD る(open_check=1) 、kernel_cacheな ではpage cacheも捨てる。s3fs-ebpfは2⾏⽬だ 出典:docs/journal/benchmark-results.md §18.48、§18.51、§18.52 openで 32
得られた知⾒ openでS3を確認 ない設計 、⼤ な差の源だった • open+read+closeの180×は、openでS3を確認 • 同 仕事を
ない設計の値で、確認 ると1.2× た構造の差は1.7×で、kmodを⼊れてまで速 なる場⾯は少ない • warmの実アプリはpage cacheのhitで終わり、FS全体の差は±3%に収まる • policyの差はhit rateで23 pt、missに約13 ms • 汎⽤の先読みは、simulatorでGET る条件では時間で18% 増え、hit rateも改善 出典:benchmark-results.md §18.48、§18.50〜§18.52、ann-workload-results.md な った 33
採⽤基準と設計上の注意 機能 とに、採⽤ る条件と、設計で守る と 分 れた 機能 採⽤する条件 設計上の注意
struct_ops カーネル側に判断点の⼀式 めて差 替えたい bpf_arena BPFとユーザー空間 ポインタを含む構造を共有 、読むの その2者だ BPF以外のカーネルのコンテキスト ら読まない。4GiB以下の データ構造でユーザー空間 ら更新あり。ライブラリの対応を 確 める fentry 既存の関数を変え に観測 る 汎⽤関数のhot pathではtrampolineより中⾝ 象を判定 、共有値への書 込みは間引 KFunc カーネルの状態を読む窓⼝や、ロック BPFで書 ない処理を置 あり、実⾏中にまと 、外 フラグを残 要るなど 提案はBPF、確定はカーネルと分 、容量の計上やロックはカー ネルに残 。差 替えはRCUのポインタ1本で⾏う 効 。先頭で対 can_loopで書 るループの代わりに書 ない。ロック、コンテ キスト、終了性の保証はkmodの責任 34
Enabling a Connected Future. Questions? @masu-mi.bsky.social github.com/masu-mi/s3fs-ebpf