Linuxカーネルスピンオフロックとスピンオフロックirq分析

2021 ワード

Linuxカーネルの中でいつspin_を使いますか?ロックはいつspin_を使いますか?ロックIqisaveは紛らわしいです.まずコードがどのように実現されているかを見てください.
spin_ロックの呼び出し関係
     spin_ロック
            |
           + ----->  raw_spin_ロック
𞓜
+-->  _raw_spin_ロック
                         |
                        +--------> __raw_spin_ロック
static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
        preempt_disable();
        spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
        LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
}
spin_ロックirqの呼び出し関係
    spin_ロックirq
                |
               +-------> raw_spin_ロックirq
                                           |
                                          +---------> _raw_spin_ロックirq
                                                                      |
                                                                      +------------> __raw_spin_ロックirq
static inline void __raw_spin_lock_irq(raw_spinlock_t *lock)
{
        local_irq_disable();
        preempt_disable();
        spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
        LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
}
二人の違いは一つしかないと思います.ロカコールをしますか?irq_disable()関数は、ローカル中断を禁止するかどうかです.
どんな場合にもスピンオフを使うロックirqは安全です.地元の中断も禁止されているし、核の不法占拠も禁止されているからです.
spin_ロック比spin_ロックirqは速度が速いですが、どんな場合でも安全です.
例を挙げます.プロセスAでspin_を呼び出しました.ロック(&lock)はその後、臨界エリアに入ります.この時、割り込みが来ました.
この割り込みは、プロセスAと同じCPUでも実行されており、この割り込み処理プログラムにおいても、スピンオフ(&lock)が実行されます.
同一のロックを取得しようとします.同じCPU上で中断されているため、プロセスAはTASK_INTERRUPT状態に設定されます.
中断処理プログラムがロックを獲得できない、忙しいなど、プロセスAが中断状態に設定されているため、スケジュールは
プロセスAを再スケジュールできませんでした.これでデッドロックになります.
ただし、この割り込み処理プログラムが異なるCPU上で実行されていると、デッドロックは発生しません.異なるCPU上での割り込みは発生しません.
プロセスAの状態は、TASK_INTERUPTとして設定されていますが、取り替えるだけです.中断処理プログラムが忙しいなど、取り換えられたら、プロセスAはまだチャンスがあります.
CPUを取得し、臨界領域を実行して終了します.
このロックは割り込み処理プログラムでは使用されないことを明確にしておく必要があります.