2017-12-30 53 views
0

質問の前で少し議論。カーネルモードでシステムコールを処理しているときにcontext-switchが必要な場合は、set_need_reschedを実行してフラグを立ててから、ユーザーモードに戻ると、フラグを立ててコンテキストスイッチを実行します。linux 2.6スケジューリングとプリエンプション - preempt_countの使用

先行カーネルを持つlinux 2.6と比較することができます。 カーネルを2.4にしてset_need_resched(raiseフラグ)をschedule()(ディスケジューリングのディレクティブ実行)に変更することはできません。Linuxカーネル2.6では、spin_lock()で毎回増加するカウンタpreempt_countがあり、 on spin_unlock()。

実際には、このフィールド "preempt_count"は、カーネルがプリエンプトできるかどうかを決定します。たとえば、クロック割り込みからの復帰時に、条件:

(current->need_resched == 1) && (current->preempt_count == 0) 

がtrueの場合、カーネルはコンテキストスイッチを実行します。

この質問は、タイプ2.6のスピンロックのロックが保持されている場合、Linux 2.6のカーネルがプリエンプションを防止する理由です。

カーネルがプリエンプションを防止しなかった場合に起こり得るシナリオは何ですか?できるだけ詳しく具体的な例を教えてもらえますか?

ありがとうございます。

+0

カーネルコードがスピンロックを保持した後にlinuxがカーネルプリエンプションを無効にする理由(https://stackoverflow.com/questions/18254713/why-linux-disables-kernel-preemption-after-the-kernel-コードホールドスピンロック) – Tsyvarev

答えて

0

mutexやセマフォのようなスリープ可能なロックについて読んだことはありますか?それらの場合、ロックが取れない場合、スレッドはそれ自体をスリープ状態にすることができ、例えば、スリープすることができる。ロック所有者(眠っている場合)が作業をより速く完了できるように、優先順位を貸しています。特に、ロックを取ろうとしているスレッドがCPU上で実行され、ロック所有者が引き続き実行されることが考えられます。

一方、スピンロックでは、誰も眠らないということです。つまり、特にビジーな待機(つまりCPU上での滞在)がロック所有者をブロックしないことを意味します。ロックが保持されている場合、所有者はどこかで実行されています。しかし、それが眠ると言いましょう。これは、待機中のスレッドが、所有者が仕事に戻ることができないため、時間を浪費することを意味します。スケジューラがそれを十分に決めた後でのみ、それは先取りされるだろうが、ウェイターと所有者との間には何の関係も確立されていない。したがって、特に、それはロックの所有者がまだ実行するチャンスを得ていない間、ウェイターがCPUを忙しく待って続けることになるかもしれません。

少なくとも、パフォーマンス上の大きな問題になります。実際には、カーネルが進歩を遂げることができない高負荷下でのライブロックにつながるだけです。

関連する問題