Linuxカーネルは、割り込み処理中にどのプロセスが起きるのかをどのように把握しますか?

Linuxカーネルは、割り込み処理中にどのプロセスが起きるのかをどのように把握しますか?

本を読んでいますLinuxカーネルの開発前の章プロセススケジューリング。 61ページ、一部立ち上がる、最初の段落は次のとおりです。

覚醒はwake_up()で処理されます。みんな指定された待機キューで待機しているジョブ。それ第1四半期:これは何をit意味するのか? )は仕事の(第2四半期:どんなミッションですか?すべての覚醒作業ですか?)ステータスがTASK_RUNNINGの場合、enqueue_task()を呼び出してRed-Blackツリーにジョブを追加し、wake-upジョブの優先順位が現在のジョブの優先順位より高い場合はneed_reschedが設定されます。イベントを発生させるコードは通常wake_up()自体を呼び出します。たとえば、ハードディスクからデータが到着すると、VFSはデータを待機するプロセスを保持する待機キューでwake_up()を呼び出します。

私は上記の状況について非常に混乱しています。データを読み込んだ後、ディスクが中断されたが、より完全な画像がある前の段落の例を使用します。以下にエラーや不完全な部分がある場合は訂正してください。

  1. 一部のユーザープロセスはブロック読み取り操作を実行してシステムコールをトリガーし、そのプロセスはカーネル領域にあります。

  2. カーネルは必要なデータを要求するようにディスクコントローラを設定し、プロセスをスリープモードにします(プロセスはキューに入れられます)。カーネルは実行する他のプロセスをスケジュールします。

  3. ディスク割り込みが発生しました。 CPUは現在実行中のプロセスを一時停止し、ディスク割り込み処理にジャンプします。

  4. ディスクコントローラは割り込み処理中に起動し、ディスクから読み取られたデータをメインメモリに転送します(CPUの指示に従って、またはDMAを介して)。

  5. (わかりません。修正してください。)段落が示すように、VFSはデータを待つプロセスを保持する待機キューでwake_up()を呼び出します。

私の具体的な質問は次のとおりです。

第1四半期(引用符を参照):おそらくそれ2番目の文は関数を表しますwake_up()。機能がwake_up目覚める理由は何ですか?みんなそのディスクのデータを待っているジョブではなくジョブ?

第2四半期(引用符を参照):try_to_wake_up()特定のジョブの状態をTASK_RUNNINGに設定する必要があることはどういうわけか?または、try_to_wake_up()すべてのウェイクアップジョブのステータスをTASK_RUNNINGに設定しますか?

第3四半期:カーネルが管理しなければならない待ち行列は何ですか?キューが2つ以上の場合、ディスクデータを待機するプロセスがそのキューに入るようにどのキューを選択するのか、カーネルはどのように知りますか?

第4四半期:今、待機プロセスがあるキューを知っているとします。カーネルはどのプロセスがディスクからデータを待っているかをどうやって知ることができますか?ディスクデータを要求するプロセスに関連する一部の情報(プロセスのPID、メモリアドレスなど)がディスクコントローラに渡されることを想像できます。その後、割り込み処理が完了した後、ディスクコントローラ(またはカーネル?)はこの情報を使用してキューにあるプロセスを見つけます。

私が目覚めたプロセスの絵を完成させるのを手伝ってください!ありがとうございます!

答え1

Q1: 「それ」はですwake_up。すべての仕事を目覚めさせるディスクデータを待っています。そのデータを待たなかった場合は、そのキューで待機していない可能性があります。

Q2:質問を理解したかどうかわかりません。各ウェイクアップキューエントリには、ジョブへのポインタが含まれています。try_to_wake_up目覚めなければならないタスクへのポインタを受け取ります。関数ごとに1回呼び出されます。

Q3:並んで待っている人が多いです。可能なすべてのイベントに1つあります。ディスクドライバは、各ディスク要求に対して待ち行列を設定する。たとえば、ファイルシステムドライバが特定のディスクブロックの内容を望む場合、ディスクドライバにブロックを要求し、要求はファイルシステム要求を発行したアクションから始まります。同じブロックに対する別の要求が入っていてそのブロックがまだ処理されていない場合は、別のエントリがキューに追加される可能性があります。

割り込みが発生すると、ディスクドライバはハードウェアから渡された情報に基づいてどのディスクに利用可能なデータがあるかを確認し、そのディスクのカーネルデータを含むデータ構造を調べて、どの要求を満たす必要があるかを確認します。このデータ構造内には、何よりもデータが書き込まれる場所と、次に何をすべきかを示す対応するウェイクアップキューがあります。

Q4:プロセスはファイルの読み取りなどのシステムコールを実行します。これは、ディスクからデータをロードする必要があるかどうかを判断するファイルシステムドライバの一部のコードをトリガします。このコードはディスクドライバに要求し、呼び出しプロセスを要求のキューに追加します。 (実際にはより多くのレイヤーがありますが、わかります)。キューイベントが発生するのを待つコードは、ファイルシステムドライバが提供する関数で、データをプロセスのメモリにコピーし、システムコールがread返されるようにします。

答え2

Gillesの答えに基づいて

第2四半期:よくわかりませんが、本の内容を割り込みハンドラ呼び出しとして解釈します。wake_up() 一度 (キュー識別子をパラメータとして渡す)そのキューの各プロセスをwake_up() 呼び出します。try_to_wake_up()(これはGilesの答えを繰り返します。第1四半期:すべてのジョブを起動せずに、呼び出されたイベントに関連付けられているキューにあるジョブのみを起動しますwake_up()。 )

第3四半期:すべての待機キューは、一部のカーネルコード(主にデバイスドライバだけでなく他のコード)によって「所有」されます。キューを所有するルーチンは、キューが属するイベントの一意の属性に基づいて一意の識別子を割り当てます。ドライバ/その他のモジュールがプロセスをスリープ状態にするときに、プロセスをどのキューに入れるかをIDで指定します。呼び出されたルーチンwake_up()(通常は割り込みハンドラ)は、プロセスをスリープモードに切り替えるのと同じモジュールの一部である必要があるため、発生したイベントに対応するキューの識別子がわかります。

私が最後にUnixカーネルのソースコードを見たとき(数年前)、ディスクドライバは各I / O要求に対して異なるイベントIDを持っていました。 Gillesが言ったように、複数のプロセスが同時に同じファイルを読み取る場合は、同じイベントを待っている可能性があります。 (もちろんこれも関連しています。第1四半期.)

第4四半期:私は「ディスクコントローラ」という言葉を聞くと、ハードウェアを思い出します。しかし、それ以外はディスクが正しいです。ドライバー (カーネルのソフトウェアモジュール)は(少なくとも潜在的に)アクセスできます。みんなこれを呼び出すプロセスに関する情報 (ディスク I/O など) 、メモリアドレスなどを待ち行列に入れます。これが何でもtry_to_wake_up()プロセスを起こすだけで十分です。


引用した段落の最後の文は、「...VFSは待ち行列からwake_up()を呼び出します...」です。これが実際に正しいかどうか疑問に思います。ファイルシステムコードはディスクドライバの上の階層です。割り込み(ディスクハードウェアからCPUに渡される信号)は、ディスク割り込みハンドラ(ディスクドライバの一部)によって処理され、待機中のプロセスを起こすことを望みますwake_up()。その後、ドライバはファイルシステムコードを起動します。 (この用語は不正確かもしれません。ファイルシステムコードが処理を再開できるように、ドライバが何かをすると言う方が良いでしょう)。 。 、プロセスは再びスリープモードに切り替わります。

第4段階に問題があります。デバイスがDMAを使用している場合、データ転送が完了するまで中断はありません。

答え3

あなたが言った問題、起きるみんな待機プロセスは「thundering herd」の問題として知られています。リソースが利用可能になると、多くのプロセスが起動し、どのプロセスがリソースに排他的にアクセスするかを確認するために競合し、残りのプロセスは再びスリープ状態になります。これはプロセッサが多い場合に問題になるため、ここで競合するプロセッサが多いです。最新バージョンのLinuxでは、スタンバイプロセスを起こしてこの問題を解決します。

ほとんどの場合、特定のイベントを待つ1つ(または複数の)プロセスがあります(プロセスが待機できるイベントの数は固定されておらず、少数は言うまでもありません)。

Gilesの答えはあなたのポイントを詳しく説明し、ここに追加することはあまりありません。

関連情報