現在、カーネル モジュールを構築しており、SMP の問題に最適な方法で対処したいと考えています。
現在、一連のオブジェクトがあり、それぞれが特定の CPU にバインドされています。次のコードはこれを示しています。
struct my_object {
int a_field;
};
struct my_object cpu_object[NR_CPUS];
/*
* cpu_object[i] is "bound" to CPU number "i" !
*/
を呼び出すだけsmp_processor_id()
で、現在のコードが実行されているプロセッサが表示されます。したがって、foo
上記の CPU バウンド オブジェクトを使用して何らかの作業を行う関数がある場合、次のようになります。
void foo()
{
int cpu = smp_processor_id();
do_some_work_with(cpu_object[cpu]);
}
問題は次のとおりです。
cpu
割り当てとdo_some_work_with
?の間に CPU スイッチはありません。do_some_work_with()
でのみ実行されcpu
ますか?
当時、私が考えている解決策は次のとおりです。
- スピンロックを使用してプリエンプションを無効にする
- でCPUを入手
smp_processor_id
- 現在のタスクのプロセッサ アフィニティを設定して、現在の CPU に固定する
- 再度プリエンプションを有効にし、ロックを解除します
- 仕事をする
do_some_work_with()
- アフィニティを以前の状態にリセットする
私にとってそれは非常に野蛮であり、それを行うためのよりスマートで軽量な方法があるかどうか疑問に思っていました.
前もって感謝します。
編集:コメントに記載されているように、なぜそのような機能が必要だと感じるのかを説明するために編集します。ファイルシステムレベルでオンザフライ暗号化を実行する必要があります。
そのために、カーネル組み込みの暗号化サポート (struct crypto_tfm
およびその仲間) を使用します。元号はこちら…
マルチコア マシンでは、複数の R/W 操作を同時に実行できます。共通の fs レイヤーはそれを行い、それをうまく行います。しかし、ここに来て、物事を台無しにします:
- の
struct crypto_tfm
ようなオブジェクトが暗号化操作を担当します - 一部のパラメーター (秘密鍵と初期化ベクトル) が変更され、すべてのプロセスが台無しになるため、同じ変換オブジェクトを同時に使用することはできません。
- 以下に説明する単純な解決策は、crypto に組み込まれた複雑な暗号割り当てシステムのため、まったく問題外です。
crypto_tfm
変換を割り当てる- 暗号化操作を実行する
- 変換オブジェクトを解放する
- 変換オブジェクトを保護するために保持されているロックを解放するために、1 つのタスクが別のタスクを待機する必要があるため、1 つの変換のみが使用可能な従来のスキームでは、複数の同時 R/W 操作が防止されます。
これらの理由から、複数の変換オブジェクトを処理する必要があります。同時 R/W を可能にする効率的なスキームを見つけなければなりません。ここでの私の「Y」は、「シンプルできちんとした...そして間違っている解決策」だと感じています。どんな提案でも大歓迎です。
注:元の質問で提供したようなソリューションを使用する場合、CPU 負荷分散への大きな影響を避けるために、非常に短いセクションに制限します。