12

Linux カーネルの元のコードは次のとおりです。

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が無効になった後、現在のパスをプリエンプトできる実行パスはないと思います。

すべての一般的なハード IRQ が無効になっているため、softirq は発生せず、スケジュール ホイールをキックするティックもありません。現在の道は安全だと思います。では、なぜあるのpreempt_disable()ですか?

4

2 に答える 2

8

私が知る限り、呼び出しは、2002 年 12 月 4 日に Dave Miller によって 2.5.51 でリリースされたpreempt_disable()を含む、かなりの数のロック プリミティブに追加されました。spin_lock_irqコミット メッセージは役に立ちません。「[SPINLOCK]: 非 SMP noping スピン/rwlock マクロを修正する」とだけ書かれています。

プリエンプティブル カーネルのドキュメントの下での適切なロックは、これを十分に説明していると思います。「割り込み禁止を使用したプリエンプションの防止」と題された最後のセクションが始まり、

It is possible to prevent a preemption event using local_irq_disable and
local_irq_save.  Note, when doing so, you must be very careful ...
于 2012-11-07T06:10:52.343 に答える
5

Sharp が言及したパッチをざっと読んだところ、irq を無効にすると暗黙的にプリエンプションを無効にできますが、危険であることがわかりました。

ただし、irq が無効になっていることに依存することは危険なビジネスであることに注意してください。プリエンプション カウントを 0 に減らす任意の spin_unlock() は、再スケジュールをトリガーできます。単純な printk() でさえ、そのような再スケジュールを引き起こす可能性があります。したがって、この種のことがコード パスで発生しないことがわかっている場合にのみ、暗黙的なプリエンプションの無効化に依存してください。最善のポリシーは、暗黙的なプリエンプションの無効化に依存するのは、短い時間だけであり、独自のコード内にとどまっている間だけです。

于 2015-11-26T01:02:02.540 に答える