全部產品
Search
文件中心

Alibaba Cloud Linux:ksoftirqd延遲排查說明

更新時間:Oct 11, 2024

softirq(非強制中斷)是Linux核心中的一種機制,將插斷要求中不重要的部分從hardirq(硬中斷)延後到softirq處理。當softirq負載較高時(任務數量過多或總處理時間過長),核心會將這些任務轉移到名為ksoftirqd的percpu線程中執行,由調度器負責平衡該線程與其他使用者任務之間的公平性。本文以Alibaba Cloud Linux 3系統為例介紹如何利用ksoftirqd進行延遲排查。

確認softirq延遲問題

  1. 下載bpftrace指令碼至ECS執行個體任意目錄下,例如/tmp

    <tmp>需替換為softirq_net_latency.bt指令碼存放的目錄。

    sudo wget -P <tmp> https://gitee.com/dtcccccc/softirq_net_latency/raw/master/softirq_net_latency.bt
  2. 安裝bpftrace。

    sudo yum install -y bpftrace
  3. 執行以下命令,通過bpftrace來檢測是否存在超過100ms的NET_RX類型的softirq延遲。

    <tmp>需替換為softirq_net_latency.bt指令碼實際所在目錄。

    sudo bpftrace <tmp>/softirq_net_latency.bt 100000

    如果指令碼輸出的延遲報告超過了100ms,則表明系統中存在softirq的延遲問題。

    • 如果報告的進程名稱(comm)為ksoftirqd/$cpu,則說明延遲是由於ksoftirqd線程得不到調度導致的。

      儘管softirq任務已被轉移至普通優先順序的ksoftirqd核心線程進行處理,但由於該線程處理任務所需時間相對較短,絕大部分時間處於睡眠狀態,因此核心調度策略仍然傾向於優先調度該線程。在這種情況下,調度延遲依然顯著,需對可能的異常情況進行排查,例如當前CPU上是否存在優先順序更高的即時任務,或某個任務在核心態中耗時過長,導致ksoftirqd核心線程無法獲得調度等。

    • 如果不屬於上述情境,則表明softirq正在中斷上下文中運行,並且之前的hardirq執行時間過長(此情況極為罕見),需對核心及驅動進行排查。

      1. 使用top工具查看對應CPU上的hardirq佔比,可以確認到該CPU上的hardirq佔比較高。

      2. 通過監控/proc/interrupts檔案的內容變化(該檔案會展示系統啟動以來每種中斷在每個CPU上的觸發總次數,使用者可以隔一小段時間取樣來對比差異)查看哪些中斷在目標CPU上的觸發次數增多,從而進一步排查對應裝置的驅動。

配置ftrace記錄系統日誌

  1. 下載softirq_ftrace.patch補丁檔案至softirq_net_latency.bt指令碼所在目錄。

    <tmp>需替換為softirq_net_latency.bt指令碼所在目錄。

    sudo wget -P <tmp> https://gitee.com/dtcccccc/softirq_net_latency/raw/master/softirq_ftrace.patch
  2. 配置ftrace收集必要的系統資訊。

    sudo sh -c 'echo "irq:softirq_raise irq:softirq_entry sched:sched_switch sched:sched_wakeup raw_syscalls:sys_enter raw_syscalls:sys_exit" > /sys/kernel/debug/tracing/set_event'
    sudo sh -c 'echo 1 > /sys/kernel/debug/tracing/tracing_on'
  3. 開啟ftrace日誌記錄,捕獲到softirq高延遲時關閉日誌記錄。

    <tmp>需替換為softirq_net_latency.bt指令碼所在目錄。

    cd <tmp>
    sudo patch -p1 < <tmp>/softirq_ftrace.patch
    sudo bpftrace --unsafe <tmp>/softirq_net_latency.bt 100000

異常診斷分析

  1. 以bpftrace列印以下報告為例,進一步跟蹤cpu11上的ksoftirqd線程調度異常。

    High IRQ-to-softirq latency: 132169 usec (132 ms) on CPU:11 comm:ksoftirqd/11
  2. 通過日誌裡的時間戳記(單位為秒)可以觀察softirq_raise與softirq_entry間隔較遠的那一次,記錄下對應時間戳記,然後進入trace日誌分析調度事件。

    vec=3表示網路類型的非強制中斷。

    sudo su
    cd /sys/kernel/debug/tracing/per_cpu/cpu11/
    grep "vec=3" ./trace

參考以下排查方向。

  • 日誌最左側為當時正在執行的任務,觀察目標時間戳記範圍期間正在執行的任務。通過chrt -p $pid命令查看任務的調度策略,如果為SCHED_DEADLINE、SCHED_FIFO或SCHED_RR,則說明該任務優先順序高於普通任務(包括ksoftird核心線程),因此ksoftird被壓製得不到調度。

  • 如果任務的優先順序不在上述範圍內,則說明它也同屬於普通進程。需要考慮該任務可能陷入核心態的時間過長。在日誌中表現為:在較長時間範圍內,當前進程持續為該任務,且未發生任何調度切換。另一個常見現象是syscall_enter事件與其對應的syscall_exit之間的跨度較大,覆蓋了整個不發生調度切換的時間。在這種情況下,應結合任務的具體行為以及所調用的syscall進行深入分析以確定原因。

  • 如果trace日誌中提示當前進程屬於SCHED_OTHER/SCHED_NORMAL普通優先順序,並且沒有持續很久的系統調用,甚至發生過調度切換到其他普通進程,則應考慮核心調度器可能存在某些異常。請聯絡我們並提供上述資訊,以便進行進一步排查。