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
5
2.9k
俺とVSCode Python Debugger Extension
sat
PRO
1
180
コード再利用のしくみ ライブラリ
sat
PRO
3
49
AWKへの愛を語る
sat
PRO
3
520
syncコマンドのデータ同期 完了待ちやエラー検出
sat
PRO
0
64
動作中のLinux環境の全メモリを見る
sat
PRO
1
95
Linuxの時間を10秒止める
sat
PRO
2
210
プロセスへのメモリ割り当て4 - 実際に使うときにメモリを獲得するデマンドページング(実践編)
sat
PRO
1
120
プロセスへのメモリ割り当て(3) 実際に使うときにメモリを獲得するデマンドページング
sat
PRO
1
73
Other Decks in Programming
See All in Programming
Make Impossible States Impossibleを 意識してReactのPropsを設計しよう
ikumatadokoro
0
170
macOS でできる リアルタイム動画像処理
biacco42
9
2.4k
AI時代におけるSRE、 あるいはエンジニアの生存戦略
pyama86
6
1.1k
TypeScriptでライブラリとの依存を限定的にする方法
tutinoko
2
670
2024/11/8 関西Kaggler会 2024 #3 / Kaggle Kernel で Gemma 2 × vLLM を動かす。
kohecchi
5
920
광고 소재 심사 과정에 AI를 도입하여 광고 서비스 생산성 향상시키기
kakao
PRO
0
170
よくできたテンプレート言語として TypeScript + JSX を利用する試み / Using TypeScript + JSX outside of Web Frontend #TSKaigiKansai
izumin5210
6
1.7k
受け取る人から提供する人になるということ
little_rubyist
0
230
WebフロントエンドにおけるGraphQL(あるいはバックエンドのAPI)との向き合い方 / #241106_plk_frontend
izumin5210
4
1.4k
ローコードSaaSのUXを向上させるためのTypeScript
taro28
1
610
.NET のための通信フレームワーク MagicOnion 入門 / Introduction to MagicOnion
mayuki
1
1.6k
イベント駆動で成長して委員会
happymana
1
320
Featured
See All Featured
Building Adaptive Systems
keathley
38
2.3k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
169
50k
Embracing the Ebb and Flow
colly
84
4.5k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
10 Git Anti Patterns You Should be Aware of
lemiorhan
654
59k
Typedesign – Prime Four
hannesfritz
40
2.4k
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.4k
How To Stay Up To Date on Web Technology
chriscoyier
788
250k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
720
Building a Modern Day E-commerce SEO Strategy
aleyda
38
6.9k
StorybookのUI Testing Handbookを読んだ
zakiyama
27
5.3k
Docker and Python
trallard
40
3.1k
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