割り込み関連のエラーは、システムクラッシュ、応答不能、パフォーマンス低下を引き起こす可能性があります。以下に、段階的な調査手順を示します。
1. 割り込み登録状態の確認
# 全割り込み統計の表示
cat /proc/interrupts
# 特定デバイスの割り込み確認(例:GPIO)
grep gpio /proc/interrupts
確認ポイント:
- IRQ番号がデバイスツリーと一致しているか
- 割り込み発生回数に異常がないか
- 各CPUコアに割り込みが均等に分散されているか
2. 割り込み処理レイテンシの測定
ftraceを利用した遅延計測:
echo function_graph > /sys/kernel/debug/tracing/current_tracer
echo 1 > /sys/kernel/debug/tracing/events/irq/enable
echo 1 > /sys/kernel/debug/tracing/tracing_on
# 割り込み発生後に以下のコマンドで確認
cat /sys/kernel/debug/tracing/trace
異常の目安:
- 割り込み処理に100μs以上かかる場合は最適化が必要
iret_exceptionが頻発する場合はスタックオーバーフローの可能性
3. よくあるエラータイプとその調査
| 現象 | 調査項目 |
|---|---|
| システムフリーズ | 割り込み処理内のブロッキング処理を確認 |
| デバイス応答なし | 割り込み線が誤って共有されていないか検証 |
| データ消失 | 割り込みストーム(次項参照)の有無を確認 |
| ランダムクラッシュ | kmemleakを使いメモリ破壊を調査 |
4. 割り込みストームの診断
watch -n 0.5 "cat /proc/interrupts | grep [IRQ]"
対策:
- ハードウェア:電気的ノイズや信号品質をチェック
- ドライバ:割り込みステータスレジスタのクリア処理を確認
- カーネル設定:
CONFIG_DEBUG_SHIRQを有効化
5. 割り込みコンテキストの問題検出
禁止操作リスト:
spin_lock_irqsave()の使用が必要kmalloc(GFP_KERNEL)などスリープ可能な関数の呼び出し- 10μsを超える長時間処理
デバッグコード例:
// 割り込みハンドラ内で使用
if (in_interrupt())
printk("現在割り込みコンテキストで実行中\n");
6. デバイスツリー設定の検証
デバイスツリーノード例:
my_device {
compatible = "vendor,device";
interrupt-parent = <&gpio>;
interrupts = <14 IRQ_TYPE_EDGE_RISING>;
};
確認項目:
interruptsパラメータがハードウェア仕様に合致しているかdtc -I dtb -O dts /proc/device-treeで逆コンパイルし実機と比較
7. 高度なデバッグツール
- GDB + JTAG:割り込みベクタテーブルの異常を捉える
- perf:
perf record -e irq:irq_handler_entryでプロファイル - SysRqマジックキー:
echo t > /proc/sysrq-triggerでスタックトレース取得
非常時対応:
システムが完全に応答しない場合、ハードウェアリセット後にCONFIG_DEBUG_LLを有効にしたカーネルをロードし、シリアル経由でoopsメッセージを確認します。
これらの手順で、大半の割り込み問題(約90%)の原因を特定できます。ハードウェアの信号計測とソフトウェアログの解析を併用することが成功の鍵です。複雑な問題では、オシロスコープで割り込み信号のタイミングを観測する必要がある場合もあります。