SysAK 應用抖動診斷篇—— eBPF又立功了! | 龍蜥技術

OpenAnolis小助手發表於2022-05-20

文 / 系統運維 SIG

編者按: 還記得曾經風靡一時的狄仁傑探案系列之《 他抖任他抖,IO診斷在我手 》、 《netinfo:揭開網路抖動面紗的神器 》、《 coredump 瘦身風雲 》等帶大家領略了青囊在網路、IO、記憶體等領域叱吒風雲的魅力。如今,系統運維 SIG 組重磅歸來,前面已介紹了  Kernel module 對付 IO 夯,今天繼續分享 eBPF 硬扛系統中斷,快隨我一起來看看 SysAK 是如何打造一款效能開銷不大、安全可靠、且靈活的關中斷檢測工具。

一、背景

日常業務執行時會經常受到各種各樣的干擾而產生抖動、影響客戶體驗。其中的一種干擾源是關中斷,當關中斷過久時可能會導致業務程式排程不及時、資料收發延遲等,這種干擾已經伴隨  Linux 核心存在很長時間了,因而 Linux 核心包括業界也有不少相關的關中斷檢測手段。這裡列舉幾個比較典型方案:
1、核心最大關中斷檢查
核心自身在系統中所有的關/開中斷路徑中新增了 TRACE_IRQ_OFF 的 trace 點,以對系統中所有開/關中斷進行監控。
優點:關中斷檢測精確且全面,同時課觀測到關中斷的時間、甚至堆疊。
缺點:依賴於 CONFIG_IRQSOFF_TRACER 核心配置,該配置在不少發行版不支援。插樁點太多而且是熱路徑,對效能影響較大。
2、watchdog/hardlock detecter
核心註冊一個 PMU 硬體 event 定期檢查自己註冊的 watchdog hrtimer 中斷是否有及時更新時間戳。
優點:週期性的檢測,對效能影響小,適用於系統中關中斷或者中斷處理有 BUG 的情況。
缺點:監控的粒度太大,無法提供更細粒度級別的系統觀察指標。對於一些無 PMU 硬體 event 的虛擬化環境該方案不生效。
3、trace_irq_handler_exit/trace_irq_handler_exit  &&  irq_enter/irq_exit
在所有中斷處理函式的入口/出口安插 trace 以及時間記錄。
優點:提供所有中斷處理時長的原始資料。
缺點:只能夠觀察到中斷處理的時間情況,對於其他關中斷路徑無法監控,沒有 threshold 觸發機制,需要人工事後分析。
4、其他開源檢查工具
在 Github 上也有不少相關的關中斷檢查工具,它們以 .ko 模組方式提供,利用 hrtimer 定時器檢查到期時間是否超過預期時間。
優點:週期取樣系統開銷不大,提供了毫秒級的監控粒度。
缺點:以第三方模組方式提供,穩定性無法保障。hrtimer 作為普通中斷,需要等到關中斷恢復後才能檢測到,精確度無法保障。同時,對於中斷函式延遲的情況會丟失掉前一箇中斷的資訊。
上面的各個檢測機制各有千秋,也有各自的缺陷和不滿足的場景。且看 SysAK 是如何打造一款效能開銷不大、安全可靠、且靈活的關中斷檢測工具。

二、技術選擇

上面的工具選用的技術、實現手段和檢測邏輯不同,導致了在不同場景中有著不同的場景中有著不同的優劣。而對於生產環境而言,監控工具的穩定性和工具的開銷是比較重要的考慮因素。因而在核心熱路徑使用插樁以及使用核心模組的方式都不是太理想的選擇:前者可能在某些場景下對效能產生較大影響,後者對於核心模組的編碼安全性要求非常高,稍不注意容易引發系統當機,對於批量部署的生產環境風險太大。
面對上面兩個問題有沒有方案或者技術手段能夠解決呢?當然有。
針對核心模組的安全問題, eBPF 絕對是 Linux 業界當前最好的解決方案 ,不僅安全而且還提供了大量易用的庫來提升程式設計體驗。
而熱路徑插樁的效能問題,在關中斷時間過長這個場景中,使用定時取樣、檢查的方式即可解決,而取樣當首選的還是 perf 事件取樣。

三、方案設計

針對前面的背景和應用場景分析初步完成了技術選型,此時關中斷檢測工具大致原理也基本有了原型:
如果系統支援 perf  硬體取樣(HW)事件,首先使用 eBPF 啟動一個核心定時器,定時器週期性產生中斷並在中斷處理函式中定時更新一個標誌,然後 perf HW 事件再週期檢查該標誌是否按時更新,以此來判斷時鐘中斷是否有按時產生或者延時發生的情況。
對於不支援 perf HW 的系統,我們無法利用 perf HW 事件了。退而求其次,我們同樣通過 eBPF 需要啟動核心定時器,定時器中斷函式會檢查本次定時器中斷到期時間與預期時間是否有差異,以此來判斷中斷是否有延遲的情況。

四、技術實現

實際上要實現上面的功能,需要解決如下幾個問題:
1) eBPF 如何安裝定時器?
2) 如何把 perf 事件觸發後我們的檢查邏輯掛接到 perf 事件回撥處理中?
3) 如何根據系統對於 perf 硬體取樣事件的支援與否讓 eBPF 選擇不同的檢查機制?
1、 eBPF 安 裝定時器
在前面設計分析中,我們瞭解到要使用 eBPF 啟動核心定時器來做一箇中斷樣本。不過很不巧, eBPF  在 Linux-5.15 以下的核心版本不支援定時器建立。幸好條條道路通羅馬,perf SW 事件中的  PERF_COUNT_SW_CPU_CLOCK 的事件其在 Linux  核心的底層就是通過高精度時鐘實現的。因此只要巧妙的利用利用了這個原理,然後結合 eBPF 就能實現我們需要的 eBPF 定時器。
2、 eBPF prog 處理函式關聯到 perf HW/SW 事件 overflow 回撥函式
雖然 perf 在使用者態提供來 perf_event_open 系統呼叫和 ioctl 方式來建立 perf HW 和 perf SW 事件取樣 (如前面 PERF_COUNT_SW_CPU_CLOCK 事件,以及 perf 硬體事件 PERF_COUNT_HW_CPU_CYCLES,通過 man perf_event_open 檢視更詳細的資訊) ,但是傳統的使用者態  perf 使用中並不能在這些事件觸發後在核心去實施我們想要的 hack  動作,例如執行我們需要進行關中斷檢測的回撥函式,只能夠在核心程式碼或者核心模組中呼叫  perf_event_create_kernel_counter 函式註冊我們需要的回撥函式到 perf 事件的  overflow_handler 上達成我們的目的。
然而這個窘境隨著 eBPF 的出現帶來了變化。 Perf event 為 ebpf 提供了專門的 ioctl 通道,以便為 ebpf 在核心中施展它的超能力(別忘了 eBPF 程式碼本質上還是在核心執行)。而 eBPF 與使用者態又有著天然的"親和力",這樣使用者態就可以非常方便的通過 ioctl 往 perf 事件掛接自己的回撥處理邏輯。在程式碼層面上就是利用:
ioctl(PERF_EVENT_IOC_SET_BPF)
來將 eBPF prog 處理函式註冊到 perf event 的 overflow_handler 回撥處理中。
3、針對系統是否支援 perf HW 事件選擇不同的檢查策略
通過 perf_event_open 系統呼叫的返回值判斷系統是否支援 perf HW 事件。
同時在 eBPF 中定義兩組 prog,如果支援 perf HW 則 attach HW 事件檢測的 prog,否則 attach SW 事件檢測的 prog。

五、執行流程

本章主要對工具的實現做一個詳細的分解。下圖是工具執行的一個簡單原理圖:
整個流程如下:
1.首先進行引數解析,包括閾值、執行時間、日誌記錄檔案指定等等引數對解析。
2.進行 eBPF 初始化,這一步主要是載入 eBPF 程式。
3.安裝 eBPF 事件。首先建立 perf event,接著將 ebpf prog attach 關聯到 perf event,最後建立一個poll event,並監聽。於此同時 perf event 開始工作,perf event 觸發後將呼叫 eBPF prog 程式執行。 eBPF prog 程式檢測到閾值事件後喚醒使用者態到 poll 任務。
4.使用者態 poll 被喚醒後將結果寫到日誌檔案。

六、工具使用

安裝 SysAK 後,使用如下命令:

sysak irqoff [--help] [-t THRESH(ms)] [-f LOGFILE] [duration(s)]
-t:關中斷的門限值,單位是 ms。
-f:指定 irqoff 結果記錄的檔案。
duration:工具的執行時長,如果不指定預設會一直執行。
通過核心模組建立 worker 來構造了一個長時關中斷的場景,下面是通過 irqoff 抓取的結果展示。

TIME(irqoff)          CPU       COMM            TID           LAT(us)
2022-05-05_11:45:19    3       kworker/3:0     379531        1000539
<0xffffffffc04e2072> owner_func
<0xffffffff890b1c5b> process_one_work
<0xffffffff890b1eb9> worker_thread
<0xffffffff890b7818> kthread
<0xffffffff89a001ff> ret_from_fork
結果中有若干部分組成:
第一行 是 log header。總共 5 列,從左到右依次是 時間戳(模組資訊) 、關中斷長的 CPU、關中斷長的 current 執行緒 ID、總的關中斷延時。
第二 行對應 log header 的實際資訊。
第三 行及後面是抓取到關中斷的現場堆疊資訊,方便進行下一步對原始碼進行分析。

相關連結地址可移步龍蜥公眾號(OpenAnolis龍蜥)2022年5月19日相同推送檢視。

—— 完 ——


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70004278/viewspace-2895856/,如需轉載,請註明出處,否則將追究法律責任。

相關文章