Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Ryzen SEGV Battle
Search
Satoru Takeuchi
PRO
October 12, 2017
Programming
3
1.1k
Ryzen SEGV Battle
The result of the analysis of so called SEGV (or segfault) problem in Ryzen processor
Satoru Takeuchi
PRO
October 12, 2017
Tweet
Share
More Decks by Satoru Takeuchi
See All by Satoru Takeuchi
ハイテク休憩
sat
PRO
2
180
利きプロセススケジューラ
sat
PRO
5
3.1k
俺とVSCode Python Debugger Extension
sat
PRO
1
200
コード再利用のしくみ ライブラリ
sat
PRO
3
65
AWKへの愛を語る
sat
PRO
3
540
syncコマンドのデータ同期 完了待ちやエラー検出
sat
PRO
0
110
動作中のLinux環境の全メモリを見る
sat
PRO
1
120
Linuxの時間を10秒止める
sat
PRO
2
220
プロセスへのメモリ割り当て4 - 実際に使うときにメモリを獲得するデマンドページング(実践編)
sat
PRO
1
150
Other Decks in Programming
See All in Programming
PHPで学ぶプログラミングの教訓 / Lessons in Programming Learned through PHP
nrslib
4
390
Jakarta EE meets AI
ivargrimstad
0
280
Amazon S3 NYJavaSIG 2024-12-12
sullis
0
110
range over funcの使い道と非同期N+1リゾルバーの夢 / about a range over func
mackee
0
110
なまけものオバケたち -PHP 8.4 に入った新機能の紹介-
tanakahisateru
1
130
AppRouterを用いた大規模サービス開発におけるディレクトリ構成の変遷と問題点
eiganken
1
150
フロントエンドのディレクトリ構成どうしてる? Feature-Sliced Design 導入体験談
osakatechlab
8
4.1k
毎日13時間もかかるバッチ処理をたった3日で60%短縮するためにやったこと
sho_ssk_
1
350
技術的負債と向き合うカイゼン活動を1年続けて分かった "持続可能" なプロダクト開発
yuichiro_serita
0
150
fs2-io を試してたらバグを見つけて直した話
chencmd
0
240
testcontainers のススメ
sgash708
1
130
生成AIでGitHubソースコード取得して仕様書を作成
shukob
0
530
Featured
See All Featured
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2k
No one is an island. Learnings from fostering a developers community.
thoeni
19
3k
A better future with KSS
kneath
238
17k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
1.2k
Learning to Love Humans: Emotional Interface Design
aarron
274
40k
VelocityConf: Rendering Performance Case Studies
addyosmani
326
24k
Scaling GitHub
holman
459
140k
Rails Girls Zürich Keynote
gr2m
94
13k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
Six Lessons from altMBA
skipperchong
27
3.5k
The Pragmatic Product Professional
lauravandoore
32
6.3k
Transcript
Ryzen SEGV Battle Sep 23 2017 Satoru Takeuchi
[email protected]
twitter:
satoru_takeuchi 1
はじめに • 最新のRyzen 1800X(8core 16 thread)搭載のPCを新調 • linuxカーネル(defconfig)のビルド速度は1分(先代マシンの5倍高速) 2
終わりの始まり • 何度かカーネルビルドしたらgccがSEGV吐いて死亡 • 先代マシンでは起きない 3 ./include/trace/perf.h:41:9: internal compiler error:
Segmentation fault struct hlist_head *head; \ ^ ... Please submit a full bug report, with preprocessed source if appropriate. See <file:///usr/share/doc/gcc-5/README.Bugs> for instructions.
容疑者 4 gccやgccが依存するライブラリ Linux kernel ハードウェア 可能性 高 可能性 低
検証環境 • ハードウェア ◦ CPU: Ryzen 1800X ◦ マザーボード: ASUS
PRIME X370-PRO ◦ BIOS: 常に最新。設定はSVM有効化以外はデフォルト ▪ バージョン: 0504(AGESA1.0.0.4)~0805(AGESA1.0.0.6a) ◦ DIMM: Kingston KVR24N17S8/8 * 4 (8 * 4 = 32GB) ▪ QVLには載ってないがAMDからOKが出ている ▪ Memtest86パス、およびRowHammerテストを一晩生存 ◦ GPU: GeForce GTX 1060 • ソフトウェア(OSはUbunru16.04) ◦ kernel: 4.8.0-5[468]-generic, その時々の最新upstream kernel ◦ gcc: gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 5
切り分け: gcc or not • 無限ビルドスクリプトを流したら10回に1回程度失敗 ◦ 失敗する箇所は毎回異なる • 少なくとも問題はgccとその依存ライブラリではありえない
◦ gccは入力(ソースコード)が同じなら出力も同じ ◦ シングルスレッド、非シグナルドリブン => 何らかの競合でもなさそう 6
容疑者 7 gccやgccが依存するライブラリ Linux kernel ハードウェア 可能性 高 可能性 低
教えてGoogle • Gentoo Forumで同じ/非常に似てる事象が話題に ◦ Linux kernel以外のビルドでも再現 : LibreOffice, mesa…
◦ 多種多様なHW/SW構成で発生 ◦ Ryzenでのみ起きる 8
Gentoo Forumに参戦 9 • Ubuntuでも起きるよ • distro依存じゃないよ • gcc関係ないよ •
この方法で確実に再現できたよ
記録抹殺刑 10 フォーラムへの発言履歴が抹消される Ubuntuの話すんな
AMDに報告 • AMDサポートフォーラムの既存スレッドを利用 ◦ 公式の方法 ◦ たくさんの人が困っていることを示して重要度を上げてもらいたい ◦ みんなで情報共有したほうが問題を切り分けしやすい •
Gentooフォーラムとtwitter(後述)を含めると数十人から再現報告あり 11
twitter上での不穏な動き • 同志を見つけたい&面白ネタなのでtwitterで逐次進捗をつぶやいてた 12
twitter上での不穏な動き • 同志を見つけたい&面白ネタなのでtwitterで逐次進捗をつぶやいてた • 「RyzenはgccでSEGVが起こせるらしい」「やった、出た!」「出ない…」 13
twitter上での不穏な動き • 同志を見つけたい&面白ネタなのでtwitterで逐次進捗をつぶやいてた • 「RyzenはgccでSEGVが起こせるらしい」「やった、出た!」「出ない…」 • 「Ryzen買うのはガチャ」「起きたら当たり石」「修正品は詫び石」 14
• ルール ◦ SEGV再現試験を実施 ◦ ひたすら結果と調査状況を twitterにつぶやく ◦ ハッシュタグは#Ryzen_SEGV_Battle 15
知人からの激励 16 ど R う Y で Z す E
か N !? ん 直 じ ん ゃ な ね い !? な 半 直 る 分 っ ん く て じ ら も ゃ い 性 ね に 能 !? こ 俺 と 何 し か た 悪 !? い
Youtubeで生配信される 17
解析: linuxカーネル or not? • WSL(bash on Windows)において、同じ手順で問題発生 ◦ fork()の失敗という形で顕在化
• NetBSDでも同じ手順でのSEGV発生事例あり • 3つのOS全てに同じ/類似のバグがある確率 <<< ハード問題の確率 18 make[3]: fork: Invalid argument make[2]: *** [arch/x86/realmode/rm/realmode.bin] Error 2 make[1]: *** [arch/x86/realmode] Error 2 make[1]: *** Waiting for unfinished jobs.... make: *** [arch/x86] Error 2 make: *** Waiting for unfinished jobs....
容疑者 19 gccやgccが依存するライブラリ Linux kernel ハードウェア 可能性 高 可能性 低
ここから先、自分ができること • ソフト屋の観点から事象の詳細調査&問題の所在を絞り込む • 根本原因はモノを作ったAMDにしかわからない • 原因不明のままSW/HW設定を変えたら直った…ではまずい ◦ 本当に直っている根拠が無い ◦
HW設定変更による別のトラブル (パーツが壊れる等)は避けたい • ベンダが根本原因を特定した上での公式解決策が必要 20
• SEGVと言っても原因はいろいろ • ftraceを使ってシグナルイベントをトレース 具体的にどんなSEGV? 21 TRACEDIR=/sys/kernel/debug/tracing/ echo 1 >
${TRACEDIR}/events/signal/signal_generate/enable echo '!stacktrace' > ${TRACEDIR}/events/signal/signal_generate/trigger echo 'stacktrace if sig == 11' > ${TRACEDIR}/events/signal/signal_generate/trigger echo 1 > ${TRACEDIR}/tracing_on echo > ${TRACEDIR}/trace
トレース結果 code=128 comm=cc1 pid=19539 grp=0 res=0 <...>-19539 [014] d... 3257.455416:
<stack trace> => send_signal => force_sig_info => do_general_protection => general_protection 22 • General Protection Fault(GPF)で死亡 ◦ アクセス許可が無いメモリに触る ◦ ユーザプログラムから特権命令を実行 ◦ その他色々
もうちょっと深堀り • GPFの詳細をログに出すカーネルパッチを作成 23 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -514,10
+514,9 @@ do_general_protection(struct pt_regs *regs, long error_code) tsk->thread.error_code = error_code; tsk->thread.trap_nr = X86_TRAP_GP; - if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && - printk_ratelimit()) { - pr_info("%s[%d] general protection ip:%lx sp:%lx error:%lx", - tsk->comm, task_pid_nr(tsk), + if (show_unhandled_signals) { + pr_err("CPU%u: %s[%d] general protection ip:%lx sp:%lx error:%lx", + tsk->cpu, tsk->comm, task_pid_nr(tsk), regs->ip, regs->sp, error_code);
カスタムカーネルのログ • エラーコード0: セグメント違反ならセレクタのindexになるので、それ以外 24 traps: CPU2: cc1[15404] general protection
ip:e4f4f4 sp:7ffe1aefc4a0 error:0 in cc1[400000+13d4000] traps: CPU15: cc1[31616] general protection ip:d0d253 sp:7fffd764db60 error:0 in cc1[400000+13d4000] traps: CPU3: cc1[14060] general protection ip:1131185 sp:7ffc6b6f71b0 error:0 in cc1[400000+13d4000] traps: CPU8: cc1[18405] general protection ip:d0d253 sp:7ffc7ac2e930 error:0 in cc1[400000+13d4000] traps: CPU0: cc1[31556] general protection ip:fc0d7c sp:7ffede8d0630 error:0 in cc1[400000+13d4000] ...
• メモリアクセスしていないのにSEGVが起きていることがある SEGVに実行していた命令 * d0d0c9: 45 01 ee add %r13d,%r14d
* d0d253: e9 e3 fe ff ff jmpq d0d13b <_Z19cselib_process_insnP8rtx_insn@@Base+0x38b> *1131150: 41 c6 44 24 04 35 movb $0x35,0x4(%r12) *113117d: 41 83 ed 71 sub $0x71,%r13d *1131185: 66 43 f7 84 12 60 2e testw $0x204,0x1622e60(%r10,%r10,1) *1131190: 0f 84 1a 05 00 00 je 11316b0 <_cpp_lex_token@@Base+0x6a0> *11311ad: 45 8d 6c 32 8f lea -0x71(%r10,%rsi,1),%r13d * fe41ba: 76 24 jbe fe41e0 <_Z16get_nonzero_bitsPK9tree_node@@Base+0x40> * e4f4f4: 48 85 c0 test %rax,%rax * e4f4f4: 48 85 c0 test %rax,%rax * fc0d7c: 48 85 c0 test %rax,%rax ... 25
新キャラ登場 • スーパーハカーHideki Eirakuさん • Ryzen SEGV Battle開幕「後」にRyzenを購入 • 純粋に「何が起きているか」に興味を持ったらしい
26
えいらくさんの解析手法 • BitVisor(ハイパーバイザの一つ)を使用 • SEGV発生時にLinux VMを停止させて、その時の状態を調査 • SEGV発生直前のbranchに関する情報をLastBranchRecordから採取 ◦ LastBranchFromIP:
最後のbranchは、どの命令から飛んだか ◦ LastBranchToIP: 最後のbranchは、どの命令に飛んだか 27 ハードウェア BitVisor linux SEGV発生 トラップ
IPとLast Branch Recordの情報 • SEGV時rip(0x0101356e) • LastBranchFromIP(0xc67aee), LastBranchToIP(0x01013560) 28 =>
0x101356e <_Z22private_is_attribute_pPKcmPK9tree_node+14>: jb 0x1013588 <_Z22private_is_attribute_pPKcmPK9tree_node+40> c67aee: e8 6d ba 3a 00 callq 1013560 メモリアクセス無し
スタックの確認 • SEGV時rip(0x0101356e) • LastBranchFromIP(0xc67aee), LastBranchToIP(0x01013560) • rsp(0x7ffe731e3668)の中身 29 =>
0x101356e <_Z22private_is_attribute_pPKcmPK9tree_node+14>: jb 0x1013588 <_Z22private_is_attribute_pPKcmPK9tree_node+40> c67aee: e8 6d ba 3a 00 callq 1013560 0x7ffe731e3668: 0x0000000000c67af3 0x000000fb00000010 • 恐らく現在のスタックフレームから の戻りアドレス • LastBranchFromIPの次の命令
SEGV時の各種レジスタの確認 • LastBranchToIPからの実行の流れ 30 1013560: 48 83 ec 08 sub
$0x8,%rsp 1013564: 8b 42 20 mov 0x20(%rdx),%eax 1013567: 48 39 f0 cmp %rsi,%rax 101356a: 75 1c jne 1013588 101356c: 48 8b 72 18 mov 0x18(%rdx),%rsi • rspは戻りアドレスを指している • 辻褄が合わない RIP LastBranchToIP 以下5命令を実行したはず
仮説 • call時にLastBranchToIPから0x40バイト低位の命令に飛んだ? ◦ 事前調査で「ripが0x40バイト手前にあれば辻褄が合いそう」という例が複数あったらしい 31 1013520: 48 8b 57
10 mov 0x10(%rdi),%rdx 1013524: b8 01 00 00 00 mov $0x1,%eax 1013529: 48 85 d2 test %rdx,%rdx 101352c: 74 e9 je 1013517 101352e: 48 8b 4a 10 mov 0x10(%rdx),%rcx rip - 0x40 LastBranchToIP - 0x40 以下5命令を実行した?
仮説の検証: 1個目の命令 • (0x10 + rdi)とrdxが等しい => 辻褄が合う 32 1013520:
48 8b 57 10 mov 0x10(%rdi),%rdx 1013524: b8 01 00 00 00 mov $0x1,%eax 1013529: 48 85 d2 test %rdx,%rdx 101352c: 74 e9 je 1013517 101352e: 48 8b 4a 10 mov 0x10(%rdx),%rcx (gdb) x/xg 0x10+$rdi 0x15b7afd: 0x000a656c63796320 (gdb) p/x $rdx $5 = 0xa656c63796320 この間rdi,rdxは変更なし
仮説の検証: 2-4個目の命令 • 0x101352でジャンプしていない & eaxは0x1 => 辻津が合う 33 1013520:
48 8b 57 10 mov 0x10(%rdi),%rdx 1013524: b8 01 00 00 00 mov $0x1,%eax 1013529: 48 85 d2 test %rdx,%rdx 101352c: 74 e9 je 1013517 101352e: 48 8b 4a 10 mov 0x10(%rdx),%rcx (gdb) p/x $rax $6 = 0x1 rdx = 0xa656c63796320 != 0
仮説の検証: 5個目の(実際に動いてた?)命令 • 0x10 + rdx(= 0xa656c63796320)は現在のx86_64 CPUの仮想アドレス空間 (48bit)を超えているのでGPF発生 =>
辻褄が合う 34 1013520: 48 8b 57 10 mov 0x10(%rdi),%rdx 1013524: b8 01 00 00 00 mov $0x1,%eax 1013529: 48 85 d2 test %rdx,%rdx 101352c: 74 e9 je 1013517 101352e: 48 8b 4a 10 mov 0x10(%rdx),%rcx
仮説の検証: BitVisorによるデータ修正&実行再開 1. 1つ目の命令((LastBranchToIP - 40) = 0x1013520)から死亡時までに変更された レジスタ(%rdx, %eax,
各種フラグレジスタ)を復元 2. 本来あるべきripからlinux VM実行を再開 3. 継続動作に成功 => 辻褄が合う 続きはえいらくさんのブログで… 35 1013520: 48 8b 57 10 mov 0x10(%rdi),%rdx 1013524: b8 01 00 00 00 mov $0x1,%eax 1013529: 48 85 d2 test %rdx,%rdx 101352c: 74 e9 je 1013517 101352e: 48 8b 4a 10 mov 0x10(%rdx),%rcx 巻き戻し
0x40バイトずれについての考察 • これですべて説明つく? ◦ 説明つくものもあれば、まだ不明なものもある ◦ ずれてからしばらく実行継続すると、最終的に何が起きても不思議ではない ▪ 途中でcall/jmpするかも ▪
0x40バイト完走後はどこを実行するか不明 • SEGV以外の事象は起きないの? ◦ futex()待ちでwaitすることもある ◦ VM起動中に負荷を流すとシステムが超スローダウン ◦ 現時点でSIGILLやオブジェクトファイルの破壊は未確認 • 0x40バイトはキャッシュラインのサイズ => キャッシュに何か問題が? ◦ uop cache切っても問題が出る人がいるので uop cacheだけでは説明つかなさそう 36
結局どのハードが原因? • 有志のユーザから出た対処案は、どれも一部の人にしか効果なし ◦ CPU以外のパーツ変更 ◦ メモリ周波数、枚数の変更、 ECCメモリの使用 ◦ CPU(コア、アンコア)の電圧変更、uop
cache無効化、ハイパースレッド無効化 ◦ Kernel Address Space Location Randomization(KASLR)無効化 • 全員に共通しているハードはCPUのみ • 仮説: 様々な要素が発生確率に影響する何らかの根本原因がRyzenに存在? 37
サポートフォーラムでのAMDの反応 • ユーザによる報告、解析結果を全無視、ダンマリ => 炎上 38 AMD
サポート担当者を動かす方法の一例 1. 問題があることを認識してもらう => done 2. 再現させる => done 3.
インパクトの大きさを訴える => done 4. 具体的に何が悪いのかを明らかにする => done 5. 偉い人にエスカレーション ◦ AMDに知り合いはいない 39
AMDのCEOに直訴 40
大成功 41 • 速攻でサポートコミュニティ上に個別 対応開始のアナウンス • 自分はすぐ交換対応に
SEGV廃人へのプレゼント • 交換手続き中にマシンが使えないとtwitterでぼやいていた • tamtamさんという方がRyzenを買ってくれた ◦ 面識無し ◦ Twitter上での過去の絡みも無し 42
デュアルRyzen(1socket)
SEGV廃人へのプレゼント • 交換手続き中にマシンが使えないとtwitterでぼやいていた • tamtamさんという方がRyzenを買ってくれた ◦ 面識無し ◦ Twitter上での過去の絡みも無し •
プレゼントされた石でもあっさり再現 ◦ 再現頻度は低下(数十分~数時間程度に一回 ) 43 デュアルRyzen(1socket)
交換品の再現試験 • SEGVは起きなくなったが別の2つの問題が発生 ◦ 数分~数十分に一回 MCE ◦ ◦ 数十分~数時間に一回ハング •
他の人の交換状況: 1名は問題解決。残り4,5人は引き続きSEGV発生 44 [ 627.958024] mce: [Hardware Error]: Machine check events logged [ 627.958027] [Hardware Error]: Corrected error, no action required. [ 627.958034] [Hardware Error]: CPU:13 (17:1:1) MC3_STATUS[-|CE|MiscV|-|-|-|-|SyndV|-]: 0x9820000000000150 [ 627.958037] [Hardware Error]: IPID: 0x000300b000000000, Syndrome: 0x000000002a000503 [ 627.958040] [Hardware Error]: Decode Unit Extended Error Code: 0 [ 627.958041] [Hardware Error]: Decode Unit Error: uop cache tag parity error. [ 627.958044] [Hardware Error]: cache level: RESV, tx: INSN, mem-tx: IRD
サポートフォーラムでのAMDの反応 • またダンマリ。炎上 45 AMD
転機 • RedditにおいてEPYCでも問題が起きると噂に ◦ gccとは異なる独自再現プログラムを使用 46
転機 • RedditにおいてEPYCでも問題が起きると噂に ◦ gccとは異なる独自再現プログラムを使用 • 再現プログラムのバグと判明 => AMDもRedditに火消しをしにきた 47
転機 • RedditにおいてEPYCでも問題が起きると噂に ◦ gccとは異なる独自再現プログラムを使用 • 再現プログラムのバグと判明 => AMDもRedditに火消しをしにきた •
その直後、AMDがPhoronix(技術系ニュースサイト)に対してコメント ◦ 初期のRyzenにはgcc負荷によるSEGV問題が存在する(原因についてはほぼ言及無し ) ◦ EPYC、Threadripperでは起きない(Ryzen Proについては言及無し ) ◦ 問題が起きるユーザには個別対応する (事実上SEGV問題テスト済みの石への交換 ) 48
二回目のRMA 49 トライRyzen(1socket)
ついに24時間の耐久テストをパス • 約4か月がかりで、ようやく終戦 50
その後 • 市場に出回ってる古いRyzenは回収されていない模様 • 現時点で確実にSEGVしない石を手に入れる方法 1. 買う 2. SEGVするかどうか確認 3.
当たり石ならRMA • AMDはまたダンマリ。サポートフォーラムは絶賛炎上中 51
サポートフォーラムのSEGVスレへの投稿数 52 6/12 直訴& 個別対応開始 8/7 AMDが問題を認める
めでたしめでたし 53 AMD