Linuxカーネル割り込みシリーズのマルチプロセッサシステムでの割り込み処理



Interrupt Handling Multiprocessor System Linux Kernel Interrupt Series



プロセッサ間割り込み(IPI)
原作者はLinux割り込みコラムシリーズを持っています
複数の割り込み処理アイコン

1.プロセッサ間割り込み(コア間割り込み)

1.マルチプロセッサシステムでは、オペレーティングシステムは、通常は処理中の割り込み(IPI)を介して、複数のプロセッサ間で操作を調整する必要があります。
2. IPIは、プロセッサによって発行され、プロセッサ間の通信または同期を容易にするために他のプロセッサによって受信される特別なハードウェア割り込みです。
3.一般に、IPIとデバイス割り込みを区別することは明確ではありません。プロセッサが割り込みを受信したときに、別のプロセッサが端末を処理するのに合理的であることがわかった場合、IPIメカニズムを使用して端末を他のプロセッサに渡し、プロセッサの負荷分散を実現できます。
4. CPUが別のCPUに割り込み信号を送信すると、CPUは自身のローカルAPICとターゲットCPUが所有するローカルAPICのICR(割り込みコマンドレジスタ)に割り込みベクタを格納します。割り込みをトリガーする識別子。 IPI割り込み信号はAPICバスを介してターゲットAPICに送信され、割り込みを受信したAPICは独自のCPUのように割り込みを送信します。
5. LinuxはIA32のSMPシステム用に5つのIPIを定義しており、割り込みベクタ番号は251〜255です。
(1)CALL_FUNCTION_VECTOR:それ自体を除くすべてのCPUに送信され、指定された機能を強制的に実行します。
(2)RESCHEDDULE_VECTOR:端末のCPU再スケジュールです
(3)INVLIDATE_TLB_VECTOR:中断されたCPUに自身のTLBキャッシュコンテンツを破棄させます
(4)ERROR_APIC_VECTOR:間違ったAPICベクトル、決して起こらないはずです
(5)SPUROUS_APIC_VECTOR:偽のAPICベクトル、決して起こらないはずです
http://www.docin.com/p-70820238.htmlも参照してください。



第二に、親和性を中断します

1.割り込みアフィニティは、1つ以上の割り込みサービスルーチンを特定のCPUにバインドして実行することです。
2.割り込みアフィニティは、/ proc / irqディレクトリ内の操作ファイルによって制御されます。登録された割り込みサービスプログラムのハードウェアデバイスの場合、/ proc / irqディレクトリに割り込み番号で名前が付けられたディレクトリがあり、そのディレクトリにsmp_affinityファイルがあります(SMPアーキテクチャでのみ使用可能)。これはCPUのビットマスクであり、各ビットはCPUに対応し、割り込みのアフィニティを設定するために使用できます。デフォルトは0xFFFFFFFFです。これは、割り込みが処理のためにすべてのCPUに送信されることを意味します。割り込みコントローラーがIRQアフィニティーをサポートしていない場合、このデフォルト値は変更できません。
0x0に設定できないことに注意してください。これは、割り込みを処理するすべてのCPUが無効になることを意味します。
3.アフィニティを使用すると、マルチプロセッシングシステムの各CPUの負荷を分散できます。

3、負荷分散を中断します

負荷の高いCPUの割り込みを、処理のために比較的アイドル状態のCPUに移行することです。
実装コードはarch i386 kernel io-apic.cにあり、balanced_irq_init関数は割り込みロードバランシングモジュールを初期化し、同時に特定のバランシング処理を実行するカーネルスレッドkirqdを作成します。
また、kirqdは5秒ごとにdo_irq_balanced関数を呼び出して、割り込みマイグレーションを実行します。



static int __init balanced_irq_init(void) { int i struct cpuinfo_x86 *c cpumask_t tmp cpus_shift_right(tmp, cpu_online_map, 2) c = &boot_cpu_data /* When not overwritten by the command line ask subarchitecture. */ if (irqbalance_disabled == IRQBALANCE_CHECK_ARCH) irqbalance_disabled = NO_BALANCE_IRQ if (irqbalance_disabled) return 0 /* disable irqbalance completely if there is only one processor online */ if (num_online_cpus() 1 && !cpus_empty(tmp)) physical_balance = 1 for (i = 0 i = 0) return 0 else printk(KERN_ERR 'balanced_irq_init: failed to spawn balanced_irq') failed: for (i = 0 i