ソフト割り込み
Rev.7を表示中。最新版はこちら。
1.割り込みの種類
Linuxではソフトウェアで行う割り込み処理に様々な種類がある。Kernel2.6ではソフト割り込みとタスクレットのみとなっている。すでに無くなっているものも含めて以下に示す。1.1 BH (Bottom Half)
Linux初期の頃からある割り込み処理形式。
登録数は32まで。
マルチプロセッサのシステムでも複数同時実行はされない(どれか1つのCPUでしか実行されない)。
Kernel 2.4の実装としては高優先度タスクレットとして登録され実行されている。
Kernel 2.6では削除された。
登録数は32まで。
マルチプロセッサのシステムでも複数同時実行はされない(どれか1つのCPUでしか実行されない)。
Kernel 2.4の実装としては高優先度タスクレットとして登録され実行されている。
Kernel 2.6では削除された。
1.2 タスクキュー
BHの拡張。
一つのBHに複数のハンドラを登録できるようにして、BHの数の制限を回避している。
タスクキューはBHの中で処理される。
Kernel 2.6では削除された。
タスクキューの例:
tq_immediate 即実行用タスクキュー
tq_timer タイマ用タスクキュー
一つのBHに複数のハンドラを登録できるようにして、BHの数の制限を回避している。
タスクキューはBHの中で処理される。
Kernel 2.6では削除された。
タスクキューの例:
tq_immediate 即実行用タスクキュー
tq_timer タイマ用タスクキュー
1.3 ソフト割り込み
現在使用されている割り込み処理。
マルチプロセッサの場合、各プロセッサで同じ割り込みが動作可能。
マルチプロセッサの場合、各プロセッサで同じ割り込みが動作可能。
1.4 タスクレット
ソフト割り込みの一つ。
複数のハンドラを登録できる。
複数のCPUで同時実行できるが同じタスクレットは同時実行されない。
デバイスドライバなどの割り込み処理はタスクレットを使って実装されている。
複数のハンドラを登録できる。
複数のCPUで同時実行できるが同じタスクレットは同時実行されない。
デバイスドライバなどの割り込み処理はタスクレットを使って実装されている。
2.実装関連
2.1 ソフトウェア割り込み
softirq_vec[]がソフトウェア割り込みのベクタテーブルで、ここにソフト割り込みのハンドラが登録される。現在(linux-2.6.16.1)は下図に示す割り込みが使用されている。新たに割り込み処理を作成する場合はソフト割り込みではなく、できるだけタスクレットとして実装すること(linux/interrupt.h参照)。
ソフトウェア割り込みはカーネルスレッド(ksoftirqd)にて実行される。
ソフトウェア割り込みのベクタテーブル
softirq_vec[][関連ルーチン]
+--------------+
| | HI_SOFTIRQ:tasklet_hi_action()
+--------------+
| | TIMER_SOFTIRQ
+--------------+
| | NET_TX_SOFTIRQ
+--------------+
| | NET_RX_SOFTIRQ
+--------------+
| | BLOCK_SOFTIRQ
+--------------+
| | TASKLET_SOFTIRQ:tasklet_action()
+--------------+
:
+--------------+
| |
+--------------+
32エントリ
open_softirq()
ソフト割り込みを登録する。
(softirq_vec[]にハンドラを登録)
(softirq_vec[]にハンドラを登録)
raise_softirq()
ソフトウェア割り込みをスケジュールする
(pendingフラグを立ててksoftirqd()をWakeupする)
(pendingフラグを立ててksoftirqd()をWakeupする)
2.2 タスクレット
タスクレットはソフトウェア割り込みの中に実装されている(TASKLET_SOFTIRQ)。タスクレットのベクタテーブルは下図のようになっている。CPU毎にリストが存在し、そこにスケジュールされているタスクレットのtasklet_structがチェーンされる。
タスクレットのベクタテーブル
tasklet_vec[] (HI_SOFTIRQ用にtasklet_hi_vec[]もある)
+--------------+
| CPU#0 | --> tasklet_struct -> tasklet_struct ->
+--------------+
| CPU#1 |
+--------------+
:
[関連関数]
tasklet_init()
tasklet_structを構築
タスクレットのハンドラもここに登録される。
タスクレットのハンドラもここに登録される。
tasklet_schedule()
タスクレット処理をスケジュールする。
tasklet_vec[]の自CPUのエントリにtasklet_structをチェーンして、TASKLET_SOFTIRQをスケジュールしている。
tasklet_vec[]の自CPUのエントリにtasklet_structをチェーンして、TASKLET_SOFTIRQをスケジュールしている。