阿里飞绪: poll 性能回归分析
Aliyun Linux 2 是為云上應(yīng)用程序特別優(yōu)化的開源操作系統(tǒng),上游包括 4.19 LTS 內(nèi)核、CentOS 7.6 軟件包,為阿里云基礎(chǔ)設(shè)施深度優(yōu)化,致力于為云上用戶提供最佳體驗(yàn)。
Aliyun Linux 2 4.19.24 發(fā)布之后,使用 will-it-scale testbench 性能測試發(fā)現(xiàn) poll1\poll2 等系統(tǒng)調(diào)用,相較于 Aliyun Linux 1 4.4.95 存在一定程度的性能下降。
will-it-scale 使用每秒鐘完成的系統(tǒng)調(diào)用次數(shù)來衡量系統(tǒng)調(diào)用的性能,以下為各個(gè)內(nèi)核版本下使用 will-it-scale 測試 poll1 性能的結(jié)果。
| 845 萬次每秒 | 860 萬次每秒 | 720 萬次每秒 |
Aliyun Linux 2 4.19.24 下的 poll1 性能相較于 Aliyun Linux 1 4.4.95 存在 16.2% 的性能下降,此外 poll2 也存在 7.5% 的性能下降。
結(jié)論
git bisect 發(fā)現(xiàn)以下 commit 影響了 poll1 的性能變化:
5b710f34e194 (x86/uaccess: Enable hardened usercopy)
236222d39347 (x86/uaccess: Optimize copy_user_enhanced_fast_string() for short strings)
21d375b6b34f (x86/entry/64: Remove the SYSCALL64 fast path)
will-it-scale 測得的 poll1 性能數(shù)據(jù)如下:
| 4.4 | 845 |
| 5b710f34e194~ | 836 |
| 5b710f34e194 | 750 |
| 236222d39347~ | 739 |
| 236222d39347 | 771 |
| 21d375b6b34f~ | 756 |
| 21d375b6b34f | 724 |
| 4.19.24 | 720 |
分析
x86/uaccess: Enable hardened usercopy
5b710f34e194 (x86/uaccess: Enable hardened usercopy)?帶來?10.29%?的性能下降。
該 commit 在 v4.8-rc2 合入主線,其在 copy_from_user()/copy_to_user() 路徑中添加 check_object_size() 檢查,以防止內(nèi)核內(nèi)存泄漏 (kernel memory exposure)或堆溢出 (heap overflow exploit) 等。該檢查會(huì)提升系統(tǒng)的安全性,但也帶來了一定的性能開銷。
x86/uaccess: Enable hardened usercopyEnables CONFIG_HARDENED_USERCOPY checks on x86. This is done both in copy_*_user() and __copy_*_user() because copy_*_user() actually calls down to _copy_*_user() and not __copy_*_user().x86/uaccess: Optimize copy_user_enhanced_fast_string() for short strings
236222d39347 (x86/uaccess: Optimize copy_user_enhanced_fast_string() for short strings)?帶來?4.44%?的性能提升。
該 commit 在 v4.13-rc1 合入主線。
當(dāng)處理器支持 ERMS (Enhanced REP MOVSB) 特性時(shí),可以使用?rep movsb?指令優(yōu)化內(nèi)存拷貝操作,但是依據(jù)?Intel 64 and IA-32 Architectures Optimization Reference Manual,該優(yōu)化在拷貝的數(shù)據(jù)量較大時(shí)效果明顯,而當(dāng)拷貝的數(shù)據(jù)量較小時(shí),rep movsb 指令本身存在的開銷會(huì)導(dǎo)致其優(yōu)化效果不明顯。
因而該 commit 在 64 字節(jié)以下的內(nèi)存拷貝中,將 rep movsb 替換為顯式的循環(huán)操作,從而帶來一定的性能提升。
x86/uaccess: Optimize copy_user_enhanced_fast_string() for short stringscommit 236222d39347e0e486010f10c1493e83dbbdfba8 upstream.According to the Intel datasheet, the REP MOVSB instruction exposes a pretty heavy setup cost (50 ticks), which hurts short string copy operations.This change tries to avoid this cost by calling the explicit loop available in the unrolled code for strings shorter than 64 bytes.The 64 bytes cutoff value is arbitrary from the code logic point of view - it has been selected based on measurements, as the largest value that still ensures a measurable gain.Micro benchmarks of the __copy_from_user() function with lengths in the [0-63] range show this performance gain (shorter the string, larger the gain):- in the [55%-4%] range on Intel Xeon(R) CPU E5-2690 v4 - in the [72%-9%] range on Intel Core i7-4810MQOther tested CPUs - namely Intel Atom S1260 and AMD Opteron 8216 - show no difference, because they do not expose the ERMS feature bit.x86/entry/64: Remove the SYSCALL64 fast path
21d375b6b34f (x86/entry/64: Remove the SYSCALL64 fast path)?帶來?4.23%?的性能下降。
該 commit 在 v4.16-rc2 合入主線。該 commit 為修復(fù) spectre 漏洞移除了 x86 64 syscall 入口的 fast path,而全部走 slow path,從而造成了一定的性能損失。
spectre 漏洞是 2018 年爆出的處理器安全漏洞,其實(shí)際利用處理器的分支預(yù)測功能所潛在的問題,利用旁路攻擊方式造成內(nèi)核數(shù)據(jù)泄露。以下簡單描述該攻擊方式的原理。
當(dāng)處理器執(zhí)行間接跳轉(zhuǎn)指令,例如執(zhí)行?call *<mem>?指令時(shí),<mem>?表示一個(gè)內(nèi)存地址,該地址處的內(nèi)存保存了一個(gè)絕對地址,call 指令需要跳轉(zhuǎn)到該絕對地址。
此時(shí) call 指令首先需要獲取?<mem>?內(nèi)存的值,當(dāng)該地址處的內(nèi)存不處于 cache 中時(shí),處理器就必須執(zhí)行讀內(nèi)存操作,由于讀內(nèi)存操作相當(dāng)耗時(shí),此時(shí)處理器硬件會(huì)執(zhí)行分支預(yù)測功能。
處理器硬件內(nèi)部使用 BTB (Branch Target Buffer) 來緩存 (間接跳轉(zhuǎn)指令的原地址, 跳轉(zhuǎn)指令的目標(biāo)地址) 這一對數(shù)據(jù),處理器硬件的分支預(yù)測即使用 BTB 來預(yù)測當(dāng)前執(zhí)行的間接跳轉(zhuǎn)指令對應(yīng)的目標(biāo)跳轉(zhuǎn)地址。
然而該機(jī)制存在的一個(gè)問題是,同一個(gè)處理器上的不同應(yīng)用程序會(huì)共用同一個(gè) BTB,因而 spectre 漏洞的原理即是 attacker 通過用戶態(tài)程序執(zhí)行特定的間接跳轉(zhuǎn)指令來訓(xùn)練當(dāng)前處理器的 BTB,從而使同一處理器上運(yùn)行的 Linux 內(nèi)核運(yùn)行間接跳轉(zhuǎn)指令時(shí),分支預(yù)測功能就會(huì)被誤導(dǎo)跳轉(zhuǎn)到 attacker 設(shè)計(jì)的一個(gè)特定地址上。
attacker 可以使用 eBPF 機(jī)制將 attacker 編寫的攻擊代碼注入到內(nèi)核中,而通過之前描述的機(jī)制 attacker 可以使內(nèi)核的間接跳轉(zhuǎn)指令在預(yù)測執(zhí)行過程中,跳轉(zhuǎn)執(zhí)行 attacker 注入的 eBPF 代碼,這樣通過 cache 旁路攻擊就可以獲取內(nèi)核的內(nèi)存數(shù)據(jù),從而造成數(shù)據(jù)泄漏。
而 syscall fast path 的移除正是與 spectre 漏洞有關(guān)。Linux 內(nèi)核中,x86 64 syscall 入口實(shí)現(xiàn)有兩條路徑以調(diào)用對應(yīng)的系統(tǒng)調(diào)用。
第一條路徑是用匯編寫的 fast path,若當(dāng)前沒有開啟 trace 相關(guān)的功能,則會(huì)根據(jù)系統(tǒng)調(diào)用號直接在 sys_call_table 中查找對應(yīng)的 syscall handler 地址,并跳轉(zhuǎn)執(zhí)行該 syscall handler。
call?*sys_call_table(,?%rax,?8)另外一條是用 C 寫的 slow path,當(dāng)前開啟 trace 相關(guān)功能時(shí),只能執(zhí)行 slow path 即 do_syscall_64() 函數(shù)。
由于 fast path 中使用了間接跳轉(zhuǎn)指令,容易遭受 spectre 漏洞的影響,因而在經(jīng)過一系列的討論之后,社區(qū)暫時(shí)移除了 x86 syscall 的 fast path 入口,而全部走 slow paith, 而這也給系統(tǒng)調(diào)用的性能帶來了一定的回退。
x86/entry/64: Remove the SYSCALL64 fast path The SYCALLL64 fast path was a nice, if small, optimization back in the good old days when syscalls were actually reasonably fast. Now there is PTI to slow everything down, and indirect branches are verboten, making everything messier. The retpoline code in the fast path is particularly nasty.Just get rid of the fast path. The slow path is barely slower.掃描下方二維碼關(guān)注"Linux閱碼場"
感謝您的耐心閱讀,請隨手轉(zhuǎn)發(fā)一下或者點(diǎn)個(gè)“在看”吧~
總結(jié)
以上是生活随笔為你收集整理的阿里飞绪: poll 性能回归分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql数据库被勒索删库怎么办
- 下一篇: 我的世界服务器背景音乐修改,我的世界怎么