web-dev-qa-db-ja.com

システムコールとカーネルモジュール(並列カーネルサービス)に関するいくつかの質問

システムコールとカーネルモジュールについていくつか質問があります。

  1. 2つのアプリケーション(AとB)があり、それぞれが異なるコアで実行されていると仮定します。 (A-CPU 0、B-CPU 1)2つのアプリケーションが同じシステムコールを並行して呼び出す場合、それらは並行して実行されますか?もしそうなら、システムコールが実行されるCPUコアは何ですか?システムコールは呼び出し元のCPUコアで実行されますか?

  2. カーネルモジュールがあり、2つのアプリケーション(AとB)がioctlを介して(並列に)カーネルモジュールの同じ関数を呼び出していると仮定します。それらは並行して実行されますか?もしそうなら、カーネルモジュール機能を提供するCPUコアは何ですか。そうでない場合、複数のアプリケーションに並列カーネルモジュール機能を提供するための最も効率的な方法は何でしょうか?

1
Younghyun

SMPサポートが最初にLinuxに追加されたとき、それは "ジャイアントロック" または "BKL" (ビッグカーネルロック)を使用していましたが、これはまだ存在していました 数年前まで 。これにより、カーネルが効果的にシングルスレッドになり(ハードウェア割り込みサービスを除いて)、アクティブにできるシステムコールは1つだけになり、もちろん多くの種類のワークロードのパフォーマンスが制限されました。

時間の経過とともに、BKLはきめ細かいロックに置き換えられ、一部のシステムコールは完全に同時に実行でき、その他のシステムコールは完全には実行できません。簡単な例として、Linuxカーネルで PIDの割り当てとプロセスの作成 を検討してください。 PIDはbitmapで実装され、PID番号の割り当てと解放はロックレスアトミック操作で実行できます。ただし、プロセステーブルのメンテナンスはそれほど単純ではありません。これは、関連するデータ構造の整合性を確保するために「タスクリスト」ロックを使用して行われます(pid_hash)。

質問に答えるには:

2つのアプリケーションが同じシステムコールを並行して呼び出す場合、それらは並行して実行されますか?

現代のカーネルを想定すると、そうです。ただし、システムコールによっては、特定の操作をスピン、譲歩、または延期する場合があります。ミューテックスまたはロックが使用されている場合、同時呼び出しで同じデータ構造を更新したり、同じハードウェアに同時にアクセスしたりすることはできません。

もしそうなら、システムコールが実行されるCPUコアは何ですか?システムコールは呼び出し元のCPUコアで実行されますか?

呼び出し側のCPUで開始し、厳密なアフィニティを設定していない限り、システムコールとシステムの他の場所で何が起こっているかに応じて、may別のCPUに再スケジュールされます。 getcpu() syscallの動作について少し考えると、より明確になるはずです( x86では実際のsyscallではない可能性があります )。

カーネルモジュールがあり、2つのアプリケーション(AとB)がioctlを介して(並列に)カーネルモジュールの同じ関数を呼び出していると仮定します。それらは並行して実行されますか?

はい、モジュールは必要に応じてきめ細かいロックやその他の同期プリミティブを使用することが期待されています。

もしそうなら、カーネルモジュール機能を提供するCPUコアは何ですか。

上記と同じように、呼び出し側のCPUで起動します。

そうでない場合、複数のアプリケーションに並列カーネルモジュール機能を提供するための最も効率的な方法は何でしょうか?

モジュール(およびハードウェア)に応じて、効率は、正しいロックの慎重かつ最小限の使用(おそらく、スピンロックの回避、メモリコピーの削減など)、およびプロセッサアフィニティの正しい使用に依存します。システムコールが同時に処理されない、または処理できない場所について質問している場合、適切な答えを出すのは困難です。ドライバーの一部をマルチスレッドユーザースペースデーモンに委任することで可能になる場合があります(アクセラレーター自体が一度に1つの操作しか実行できず、一部の小さな操作がより高速である暗号化アクセラレーターでこれを観察しましたCPU)。

無料のPDF book Linux Device Drivers(3rd edition) は、この種の作業に非常に役立ちます。特に5:並行性と競合状態

1
mr.spuratic