Linux Kernel(2.6)の実装に関するメモ書き

排他制御関連


Rev.2を表示中。最新版はこちら

割り込み禁止

cli()で割り込み禁止状態にする。マルチプロセッサ環境においては意味がない。

CONFIG_SMP定義の有無によって異なる。

CONFIG_SMP未定義時
cli命令実行するだけ


CONFIG_SMP定義時
定義がない。

2.4では全CPUで割り込みを禁止していた。
(RemoteCPUでは割り込みハンドラ実行を遅延させている)

そもそも、マルチプロセッサでは割り込み禁止だけでは
排他制御はできない。
spinlockによるプロセッサ間の排他も必要。

<-- このためにspin_lock_irqsave()があり、
cli()は意味がなくなったため消された。


プロセッサ間の排他制御(スピンロック)


spin_lock()
        SpinLock取得
        取得できるまでSpin

spin_lock_irqsave()
        LocalCPUについてcliで割り込み禁止にして、
        SpinLock取得

        割り込みハンドラからもlockを取ろうとする場合は、
        DeadLock防止のため、こちらを使用する。

        LocalCPUについて割り込み禁止しておかないと
        通常ContextでSpinLock取得した後、
        割り込みが発生して同じSpinLockを取ろうとした時、
        DeadLockする。
        他のCPUの割り込みは禁止にする必要はない。


セマフォ

lock_kernel()
        カーネルセマフォ(kernel_sem)を取得。
        down()によりセマフォが取れなければ
        TASK_UNINTERRUPTIBLE状態でSleepする。


プリエンプションの抑止

preempt_disable()
        current_thread_info()->preempt_countをインクリメントして
        プリエンプションを抑止

        プリエンプト処理は例外/割り込みからカーネルモードに
        もどる時(entry.S::resume_kernel)にTIF_NEED_RESCHEDが立っていたら
        プロセスを切り替えることでおこなっているが、
        preempt_countが0でなければプロセス切り替えが
        発生しないようにしている。

        spin_lockxxx()をするとpreempt_disable()も実行され、
        暗黙でプリエンプションは不可とされる。

最終更新 2006/06/22 17:10:47 - kztomita
(2006/03/27 12:57:59 作成)


リンク
最近更新したページ
検索