私のカーネル構成では、CONFIG_PREEMPTが設定されていません。割り込みハンドラーではschedule()が許可されていないため、Linuxカーネルでラウンドロビンタイプのスケジューリングをどのように実装しますか。つまり、誰がスケジューラを頻繁に呼び出すか。entry_32.Sでは、CONFIG_PREEMPTが設定されている場合にのみpreempt_schedule_irqを呼び出します。
1 に答える
何が起こるかというと、CPU のタイマーがカーネルに頻繁に割り込むように設定されているということです。しかし、割り込みコンテキストからスケジュールを呼び出すことはできませんよね? したがって、カーネルが行うことは巧妙なトリックです。ハンドラの実行中に現在実行中のタスクを変更し、リターンします。これが効果的に行うことは、ハンドラーの下からコンテキストを切り替えて、ハンドラーが完了すると同時に、次に実行するコンテキストが実行される次のタスクになることです。読んでくださいdo_context_switch
(IIRCはそれが呼ばれていると思います)、現在の実行の下からスタックとコンテキストを切り替え、別のコンテキストで同じ機能を再開することがわかります。
またCONFIG_PREEMPT
、カーネル コンテキストでのカーネル コード プリエンプションにのみ適用されます。ユーザー空間のタスクは常にプリエンプトされます。これが意味するのは、実行を開始するカーネルコードが完了するまで実行されることです (自分で schedule() を呼び出したり、I/O を待機するブロックなどを除いて...)。通常、カーネルは、ロックを取得するとスレッドがスリープ状態になる可能性がある場合を除いて、ロックを保持していない限りプリエンプトできます。