質問の前にちょっと雑談。Linux 2.4 カーネルはプリエンティブではないため、カーネル モードでシステム コールを処理しているときにコンテキスト スイッチが必要な場合は、フラグを立てるために set_need_resched のみを実行し、ユーザー モードに戻るときに、フラグを付けてコンテキスト切り替えを行います。
これをプリエンプティブ カーネルを持つ Linux 2.6 と比較してみましょう。カーネル 2.4 をそのまま使用して、set_need_resched (フラグを上げる) を schedule() (再スケジューリングのディレクティブ実行) に変更することはできません。そのため、Linux カーネル 2.6 にはカウンター preempt_count があり、spin_lock() で毎回増加し、で減少します。 spin_unlock()。
実際には、このフィールド「preempt_count」によって、カーネルをプリエンプトできるかどうかが決まります。たとえば、クロック割り込みからの復帰で、次の条件の場合:
(current->need_resched == 1) && (current->preempt_count == 0)
が true の場合、カーネルは context-switch を実行します。
問題は、スピンロック タイプのロックが保持されているときに、Linux 2.6 のカーネルがプリエンプションを防止する理由です。
カーネルがプリエンプションを防げなかった場合に起こりうるシナリオは何ですか? できるだけ具体的な例を教えてください。
ありがとうございました。