萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 作業系統 >  >> Linux 教學

Linux 核心軟中斷機制原始碼分析:irq_cpustat_t 與處理流程

軟中斷是 Linux 核心延遲處理高頻事件的關鍵機制(網路封包接收、塊裝置完成、定時器等)。本文基於 Linux 2.6.12 原始碼,剖析 irq_cpustat_t 架構差異、local_softirq_pending() 存取宏、__raise_softirq_irqoff() 觸發邏輯與 do_softirq() 處理流程。

CPU 相關狀態結構:irq_cpustat_t

定義於 asm/hardirq.h,架構相關:

i386 架構

typedef struct {
    unsigned int __softirq_pending;   // 軟中斷待處理位圖
    unsigned long idle_timestamp;     // 閒置時間戳
    unsigned int __nmi_count;         // NMI 計數
    unsigned int apic_timer_irqs;     // APIC 計時器中斷計數
} ____cacheline_aligned irq_cpustat_t;

ARM 架構

typedef struct {
    unsigned int __softirq_pending;
} ____cacheline_aligned irq_cpustate_t;

____cacheline_align 確保每 CPU 結構獨佔一條快取行,避免虛假共享。全域陣列 irq_stat[NR_CPUS] 儲存各 CPU 狀態。

核心存取宏

#ifndef __ARCH_IRQ_STAT
extern irq_cpustat_t irq_stat[];
#define __IRQ_STAT(cpu, member) (irq_stat[cpu].member)
#endif

#define local_softirq_pending() \
    __IRQ_STAT(smp_processor_id(), __softirq_pending)

smp_processor_id() 返回當前 CPU 編號(單核為 0),宏直接讀取對應 CPU 的 __softirq_pending 位圖。

觸發軟中斷:__raise_softirq_irqoff

#define __raise_softirq_irqoff(nr) \
    do { local_softirq_pending() |= 1UL << (nr); } while (0)

將當前 CPU 的 __softirq_pending 第 nr 位置 1,標記對應軟中斷待處理。nr 對應 enum 定義(HI_SOFTIRQ、TIMER_SOFTIRQ、NET_TX_SOFTIRQ、NET_RX_SOFTIRQ、BLOCK_SOFTIRQ 等)。

處理流程:do_softirq()

在 kernel/softirq.c 中,do_softirq() 輪詢 irq_stat[cpu].__softirq_pending,對每個置位的 bit 呼叫對應 softirq_action 陣列中的處理函式(action->action())。處理過程中:

  • 暫停本地中斷(local_irq_save),防止重入。
  • 清除 pending bit,執行 handler。
  • handler 可能再次觸發軟中斷(如網路驅動 netif_rx 觸發 NET_RX_SOFTIRQ),循環直到 pending 為零或達 MAX_SOFTIRQ_RESTART(預設 10 次),剩餘交由 ksoftirqd 核心執行緒處理。

關鍵設計亮點

  1. Per-CPU 位圖:無鎖存取,極低開銷。
  2. 兩階段處理:硬中斷極短時間內 raise_softirq,耗時工作延遲到軟中斷/執行緒上下文,降低中斷延遲。
  3. ksoftirqd 托底:高負載時防止軟中斷佔用過多 CPU,餓死使用者進程。
  4. 架構無關核心:kernel/softirq.c 通用,架構僅提供 irq_cpustat_t 與 smp_processor_id()。

參考資源

  • 原始碼:include/linux/interrupt.h、asm/hardirq.h、kernel/softirq.c。
  • 《Linux Kernel Development》第 7 章(Robert Love 著)詳細闡述軟中斷設計與演進。

總結

軟中斷以 per-CPU 位圖實現高效延遲處理,irq_cpustat_t 封裝架構差異,raise_softirq/do_softirq 構成觸發-處理閉環。理解此機制對網路驅動開發、高效能伺服器調校、核心除錯至關重要。

copyright © 萬盛學電腦網 all rights reserved