割り込み処理とソフト割り込み処理の排他メカニズム

下記フラグを利用して、割り込み処理、ソフト割り込み処理の排他が行われている。

   unsigned int   global_irq_lock;
   unsigned int   global_bh_lock;

   struct {
        unsigned int __local_irq_count;
        unsigned int __local_bh_count;
		:
   } irq_stat[NR_CPUS]

まず、各フラグの利用方法(どこで設定され、どこから参照されるか)に関して説明する。

  • global_irq_lock ... 全割り込み禁止フラグ
    • ● 全割り込み禁止(global_cli()関数)時に設定する。 global_sti()関数で解除。
    • 割り込みハンドラ起動(handle_IRQ_event関数)時に、 上記変数がクリアされるのを待ちビジーウェイト(irq_enter)する。
    • 旧BHハンドラ(bh_action関数)では、上記フラグが セットされているとき(hardirq_trylock関数)は起動をスキップする。
    • 他CPUからの全割り込み禁止要求時(global_cti()関数) その他のCPUでの割り込み禁止処理が終了(global_sti()関数) するのをビジーウェイトする。
  • local_irq_count ... ローカルCPU上で動作している割り込みハンドラのネスト数
    • ● 割り込みハンドラ起動(handle_IRQ_event関数)時にカウントアップ (irq_enter関数). 終了時にカウントダウン(irq_exit)する。
    • ソフト割り込みハンドラ(do_softirq関数)では、上記フラグが セットされているとき(in_interupt関数)は起動をスキップする。 ローカルCPU上で割り込みハンドラが動いているときは起動しない。
    • 旧BHハンドラ(bh_action関数)では、上記フラグが セットされているとき(hardirq_trylock関数)は起動をスキップする。
    • 他CPUからの全割り込み禁止(global_cti()関数)を行う場合、 全てのCPUの上記変数がクリアされるまで終了を待ち合わせる。
  • global_bh_lock ... 旧BHハンドラ実行中を示すフラグ
    • ● 旧BHハンドラ起動時(bh_action関数)設定、処理後解除する。 (spin_trylock(global_bh_lock)処理)
    • 旧BHハンドラ起動するときに、別の他CPU上で動作していたら (上記フラグが既に立っていたら)処理をスキップする。
  • local_bh_count ... ローカルCPU上で動作しているソフト割り込みハンドラ実行中を示すフラグ
    • ● ソフト割り込み(do_softirq)起動時カウントアップ (local_bh_disable関数)し、終了時にカウントダウン (local_bh_enable関数)する。
    • ソフト割り込みハンドラ(do_softirq関数)では、上記フラグが セットされているとき(in_interupt関数)は起動をスキップする。 同じCPU上でソフト割り込みハンドラがネストすることを避ける。
    • プロセッサ間割り込み(smp_call_function)処理中もBHハンドラの 起動を抑制するためにカウントアップする。
    • 他CPUからの全割り込み禁止(global_cti関数)でソフト 割り込みハンドラ終了を待ち合わせるために参照。

これらの動きをまとめると、

  1. global_cliによる割り込み禁止状態と割り込みハンドラ または旧BHハンドラはシステム上に共存できない。
  2. 割り込みハンドラと旧BHハンドラはシステム上に共存できる。 ただし割り込みハンドラを優先的に動作させる。
  3. 旧BHハンドラはシステム上に一つだけ存在できる。
  4. ソフト割り込みハンドラは、上記のものと完全に独立して動作。 ただし割り込みハンドラを優先的に動作させる。
img128.gif

(NIS)HirokazuTakahashi
2000年12月09日 (土) 23時55分06秒 JST
1