8

ドライバー開発者が、カーネル モードの切り替えをできるだけ回避するのが良いと言っているのをよく耳にします。正確な理由はわかりませんでした。私の理解から始めるには -

  1. システムコールはソフトウェア割り込みです。x86 では、命令 sysenter を使用してトリガーされます。実際には、マシン固有のレジスタからターゲットを取得する分岐命令のように見えます。
  2. システム コールは、実際にはアドレス空間やプロセス コンテキストを変更する必要はありません。
  3. ただし、プロセス スタックにレジスタを保存し、スタック ポインタをカーネル スタックに変更します。

これらの操作の中で、syscall は通常の関数呼び出しのように機能します。ただし、sysenter は、プロセッサ パイプラインで ROB フラッシュを引き起こす可能性のある誤った予測分岐のように動作する可能性があります。それは本当に悪いことではなく、他の予測ミスのブランチと同じです。

Stack Overflow で何人かが回答しているのを聞きました。

  1. syscall にどれくらいの時間がかかるかはわかりません - [me] ええ、でもそれはどの関数にも当てはまります。所要時間は関数によって異なります
  2. よくあるスケジュールスポットです。- [me] プロセスは、ユーザー モードで常に実行されている場合でも、再スケジュールされる可能性があります。たとえば、while(1);コンテキストなしの切り替えは保証されません。

実際の syscall コストはどこから来ているのですか?

4

2 に答える 2

3

質問しているOSを示していません。とにかく答えを試みさせてください。

CPU 命令syscallシステム コールの概念およびそれぞれの OS でのその表現とsysenter混同しないでください。

インテル® 64 および IA-32 アーキテクチャー・デベロッパーズ・マニュアルのボリューム2A (については、 3-392ページを参照) およびボリューム 2B ( 4-463 ページ参照)。また、ちらっと見たり、見たりすることも忘れないでください。 intsysenteriretdsysexit

操作の疑似コードを簡単に数えると、次のようになります。

  • 408行int
  • 55行sysenter

注:既存の答えはその点で正しく、割り込みsysentersyscallはなく、割り込みに関連するものでもありませんが、LinuxおよびWindowsの世界の古いカーネルは、システムコールメカニズムを実装するために割り込みを使用していました。Linux では、これは以前int 0x80は Windowsint 0x2Eでした。その結果、これらのカーネル バージョンでは、それぞれの割り込みの割り込みハンドラーを提供するために IDT を準備する必要がありました。新しいシステムでは、それは本当です。命令はsysentersyscall古い方法を完全に置き換えました。ハンドラーのアドレスでプライミングされるのはMSR(マシン固有のレジスター)です(sysenter以下にリンクされている読み物を参照してください)。0x176sysenter


Windows では ...

Windows でのシステム コールは、Linux と同様に、カーネル モードへの切り替えになります。NT のスケジューラは、スレッドが許可される時間を保証しません。また、スレッドから時間が奪われ、スレッドが枯渇することさえあります。一般に、ユーザー モード コードはカーネル モード コードによってプリエンプトされる可能性があると言えます (ただし、「高度なドライバー作成クラス」で確実に得られる非常に特殊な例外はほとんどありません)。1 つの例だけを見れば、これは完全に理にかなっています。ユーザー モード コードをスワップ アウトすることができます。さらに言えば、アクセスしようとしているデータをスワップ アウトすることもできます。現在、CPU はスワップ/ページング ファイル内のページにアクセスする方法をまったく把握していないため、中間の手順が必要です。また、カーネル モード コードがユーザー モード コードをプリエンプトできる必要があるのもそのためです。IRQL_NOT_LESS_OR_EQUAL. これは、そのメモリにアクセスするコードを先取りできなかったときに、ドライバーがページ メモリにアクセスしたことを意味します。


参考文献

  1. Geoff Chappellによる Windows の SYSENTER と SYSEXIT (私の経験上、常に読む価値があります!)
  2. Linux 2.6 の Sysenter ベースのシステム コール メカニズム
  3. Windows NT プラットフォーム固有の議論: Windows NT システム コールはどのように機能するのですか?
  4. Windows NT プラットフォーム固有の議論: SYSENTER 命令によるシステム コールの最適化
  5. Windows Internals、第 5 版、Russinovich らによる。アル。- 125 ~ 132 ページ。
  6. ReactOSの実装KiFastSystemCall
于 2013-03-05T01:14:43.840 に答える
2

SYSENTER/SYSCALL ソフトウェア割り込みではありません。これらの命令の要点は、IRQ の発行と割り込みハンドラーの呼び出しによって引き起こされるオーバーヘッドを回避することです。

スタックにレジスタを保存するには時間がかかります。これは、syscall コストが発生する場所の 1 つです。

別の場所は、カーネル モード スイッチ自体から来ています。CS、DS、ES、FS、GS などのセグメント レジスタを変更する必要があります。また、実行の CPU リングを変更します。

結論として、関数呼び出しは (セグメンテーションが使用されていない最新のシステムでは) ニアコールであり、syscall はファーコールとリングスイッチを伴います。

于 2012-06-23T13:30:55.250 に答える