Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux 核心軟中斷深度解析:資料結構、觸發機制與處理流程

編輯:Linux 教學

軟中斷簡介

將可延遲的處理從硬中斷處理程序中分離,使其在開啟中斷狀態下執行,即為軟中斷。這大幅縮短硬中斷響應時間,對即時應用至關重要。本文基於 Linux Kernel 4.0 深入剖析軟中斷流程細節。

軟中斷資料結構

目前有 10 種軟中斷(由 NR_SOFTIRQS 定義),透過 softirq_vec[NR_SOFTIRQS] 陣列管理,全 CPU 共用。

軟中斷註冊

使用 open_softirq() 將處理函數與編號綁定。網路子系統註冊收發封包處理函數:

open_softirq(NET_TX_SOFTIRQ, net_tx_action);
open_softirq(NET_RX_SOFTIRQ, net_rx_action);

軟中斷啟用機制

每個 CPU 擁有 32-bit 位圖 __softirq_pending 維護本 CPU 的軟中斷啟用狀態:

typedef struct {
    unsigned int __softirq_pending;
    #ifdef CONFIG_SMP
    unsigned int ipi_irqs[NR_IPI];
    #endif
} ____cacheline_aligned irq_cpustat_t;

irq_cpustat_t irq_stat[NR_CPUS] ____cacheline_aligned;

啟用時機一:irq_exit

在 irq_exit 中可能啟用軟中斷,條件為:

if (!in_interrupt() && local_softirq_pending())
    invoke_softirq();

條件含義:不在硬中斷中、不在軟中斷中、本 CPU 位圖有置位。體現硬中斷優先、軟中斷不嵌套原則。invoke_softirq 會喚醒 ksoftirqd 執行緒處理,或直接呼叫 __do_softirq 即時處理(區分當前堆疊或獨立軟中斷堆疊)。即時處理期間禁止搶佔。

啟用時機二:raise_softirq

網卡從非 NAPI 演進到 NAPI,展現軟中斷優勢:將收封包任務最大程度移至軟中斷,極大簡化硬中斷。raise_softirq 呼叫 __raise_softirq_irqoff 在指定 CPU 位圖置位。置位操作需在關中斷下完成以避免競爭。

啟用時機三:ksoftirqd 核心執行緒

每個 CPU 有一個 ksoftirqd 執行緒專門處理大量軟中斷:

DEFINE_PER_CPU(struct task_struct *, ksoftirqd);

核心函數 run_ksoftirqd 循環:關中斷檢查位圖、有則執行 __do_softirq、開中斷。執行前可被搶佔,執行後不可搶佔,與硬中斷處理哲學一致:執行期間不允許排程。

啟用時機四:其他位置(如 netif_rx_ni)

執行 do_softirq 前關搶佔,確保軟中斷執行期間不被排程。

啟用時機五:local_bh_enable

if (unlikely(!in_interrupt() && local_softirq_pending()))
    do_softirq();

異常處理與軟中斷共享資料時,進入臨界區關軟中斷,離開時開啟,此即為一個啟用時機。

「啟用」而非「呼叫」:外圍僅修改本 CPU 位圖,最終由核心機制(ksoftirqd、通過 in_interrupt 檢查的處理)真正處理。原則:誰啟用誰處理,哪個 CPU 的硬中斷帶來的軟中斷由哪個 CPU 處理,充分發揮 SMP 優勢。多 CPU 平行處理同類型軟中斷時,需自行保護共享資料結構(可重入代價)。

核心處理函數:do_softirq

檢查重入條件(不在硬/軟中斷中),符合則處理:

pending = local_softirq_pending();
if (pending) __do_softirq();

在關中斷保護下完成。局部變數 pending 未傳入 __do_softirq,僅判斷非使用,判斷值與實際使用值可能有差異。此檢查達到:同 CPU 軟中斷不嵌套、嵌套硬中斷中不處理軟中斷。同 CPU 上 __do_softirq 序列化,多 CPU 間平行,故同類型軟中斷仍需保護共享資料。

核心處理函數:__do_softirq

三階段分析:

  1. 準備階段:關閉軟中斷(防嵌套)。
  2. 核心階段:關硬中斷、讀取並清空位圖、開硬中斷。循環執行所有被啟用軟中斷(最多 10 次 MAX_SOFTIRQ_RESTART),因使用使用者進程堆疊不可久佔。退出條件:總時間超限、被搶佔(開中斷後)、達 10 次。
  3. 結尾階段:關硬中斷、開軟中斷。

若 10 次循環仍未清空位圖(期間大量硬中斷帶來新軟中斷),交給 ksoftirqd 處理。循環意義:處理期間可能進入新硬中斷帶來新軟中斷(僅在本 CPU 位圖置位),需反覆處理直到位圖清空。

防嵌套流程:關軟中斷包含原子性加 1。若路徑 A 在原子操作前被 B 打斷,B 處理完硬/軟中斷返回 A,A 接著執行原子操作,後續軟中斷處理空轉(已被 B 處理)。若在原子操作後被打斷,B 執行硬中斷但不執行軟中斷(嵌套檢查失敗),返回 A,A 額外處理 B 的軟中斷。

preempt_count 中的軟中斷位雙重作用:防單 CPU 嵌套、保證執行期間不被搶佔。

總結

中斷時序雖複雜,皆逃不出兩原則:硬中斷可打斷硬中斷(不同類型);硬中斷可打斷軟中斷(軟中斷不打斷硬中斷,亦不打斷軟中斷)。所有複雜時序皆為這兩者疊加。

Copyright © Windows教程網 All Rights Reserved