Receive Side Scaling Version 2 (RSSv2)

Receive Side Scaling は、マルチプロセッサ システムでのネットワーク データの処理に関連するシステム パフォーマンスを高めます。 NDIS 6.80 以降では、RSS バージョン 2 (RSSv2) がサポートされています。これは、キューの動的な VPort 単位の拡散を提供することにより RSS を拡張します。

概要

RSSv1 と比較して、RSSv2 は CPU 負荷の測定から間接テーブルの更新までの時間を短縮します。 これにより、トラフィックの多い状況での速度低下を回避できます。 これを実現するため、RSSv2 は、要求を処理するプロセッサ コンテキストの IRQL = DISPATCH_LEVEL でそのアクションを実行し、現在のプロセッサをポイントする間接テーブル エントリのサブセットでのみ動作します。 これは、RSSv2 が RSSv1 よりもはるかに応答性の高い複数のプロセッサに受信キューを動的に分散できることを意味します。

ミニポート ドライバーの RSSv2 には、OID_GEN_RECEIVE_SCALE_PARAMETERS_V2OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES の 2 つの OID が導入されています。これらはそれぞれ、適切な RSS 機能の設定と、間接テーブルの制御を行います。 OID_GEN_RECEIVE_SCALE_PARAMETERS_V2 は通常の OID ですが、OID_GEN_RSS_SET_INDIRECTION_ENTRIES は NDIS_STATUS_PENDING を返すことができない同期 OID です。 これらの OID について詳しくは、個々のリファレンス ページをご覧ください。 同期 OID について詳しくは、「NDIS 6.80 の同期 OID 要求インターフェイス」をご覧ください。

RSSv2 の用語

このトピックでは、次の用語を使用しています。

任期 定義
RSSv1 第 1 世代は、サイド スケーリング メカニズムを受け取ります。 OID_GEN_RECEIVE_SCALE_PARAMETERS を使用します。
RSSv2 このトピックで説明されている、Windows 10 バージョン 1803 以降でサポートされている第 2 世代の受信側スケーリング メカニズム。
スケーリング エンティティ ネイティブ RSS モードのミニポート アダプター自体、または RSSv2 モードの VPort。
ITE 特定のスケーリング エンティティの間接テーブル エントリ (ITE)。 VPort あたりの ITE の合計数が、VMQ モードでは NumberOfIndirectionTableEntriesPerNonDefaultPFVPort または NumberOfIndirectionTableEntriesForDefaultVPort、ネイティブ RSS の場合は 128 を超えることはできません。 NumberOfIndirectionTableEntriesPerNonDefaultPFVPortNumberOfIndirectionTableEntriesForDefaultVPort は、NDIS_NIC_SWITCH_CAPABILITIES 構造のメンバーです。
スケーリング モード 実行時の ITE の処理方法を制御する VPort 単位の vmswitch ポリシー。 これは、静的 (負荷の変化による ITE の移動なし) または動的 (現在のトラフィック負荷に応じて拡張および結合) です。
キュー ITE を支えている、基になるハードウェア オブジェクト (キュー)。 ハードウェアと間接テーブルによっては、構成キューが複数の IT を支えていることがあります。 既定のキューで使用されるキューを含むキューの合計数は、通常管理者が設定する構成済みの制限を超えることはできません。
既定のプロセッサ ハッシュを計算できないパケットを受信するプロセッサ。 VPort ごとに既定のプロセッサがあります。
プライマリ プロセッサ VPort の作成時に、NDIS_NIC_SWITCH_VPORT_PARAMETERS 構造の ProcessorAffinity メンバーとして指定されたプロセッサ。 このプロセッサは実行時に更新することができ、VMQ トラフィックの転送先を指定します。
ソース CPU ITE が現在マッピングされているプロセッサ。
対象の CPU ITE が再マッピングされているプロセッサ (RSSv2 を使用)。
アクター CPU RSSv2 要求が行われているプロセッサ。

ミニポート ドライバーでの RSSv2 機能のアドバタイズ

ミニポート ドライバーは、NDIS_RSS_CAPS_SUPPORTS_INDEPENDENT_ENTRY_MOVE フラグを持つ NDIS_RECEIVE_SCALE_CAPABILITIES 構造の CapabilitiesFlags メンバーを設定することによって、RSSv2 のサポートをアドバタイズします。 この機能は、RSSv2 の CPU 負荷分散機能を有効にするために必要です。加えて、既定以外の VPort (VMQ) の RSSv1 動的分散を有効にする NDIS_RECEIVE_FILTER_DYNAMIC_PROCESSOR_AFFINITY_CHANGE_SUPPORTED フラグも必要です。

Note

上位層プロトコルでは、RSSv2 ミニポート ドライバーの既定の VPort のプライマリ プロセッサを移動できることを前提としています。

ミニポート アダプターが RSSv2 機能をアドバタイズしない場合、これらの VPort が動的拡散を実行するよう要求された場合でも、すべての VMQ 対応 VPort は静的拡散モードのままです。 RSS パラメーター RSSv1 OID (OID_GEN_RECEIVE_SCALE_PARAMETERS の構成用の RSSv1 OID は、静的拡散モードのままになっているこれらの VPort に使用されます。

ミニポート ドライバーは、RSSv1 または RSSv2 のいずれかの 1 つの RSS 制御メカニズムを実装する必要があります。 ドライバーが RSSv2 サポートをアドバタイズする場合、NDIS は、必要に応じて RSSv1 OID を RSSv2 OID に変換し、VPort 単位の拡散を構成します。 ミニポート ドライバーは、2 つの新しい OID をサポートし、RSSv1 OID_GEN_RECEIVE_SCALE_PARAMETERS OID の動作を次のように変更する必要があります。

  • OID_GEN_RECEIVE_SCALE_PARAMETERS は、RSSv2 でのクエリ要求にのみ使用され、RSS パラメーターの設定には使用されません。
  • OID_GEN_RECEIVE_SCALE_PARAMETERS_V2 は、キューの数、ITE の数、RSS の有効化/無効化、ハッシュ キーの更新など、スケーリング エンティティのパラメーターを構成するために使用されるクエリとセット OID です。
  • OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES は、間接テーブル エントリの変更を実行するために使用されるメソッド OID です。

RSSv2 OID の処理

OID_GEN_RECEIVE_SCALE_PARAMETERS は、特定のスケーリング エンティティの現在の RSS パラメーターのクエリにのみ使用されます。 RSSv1 では、この OID を使用してパラメーターを設定します。 RSSv2 対応ミニポート ドライバーの場合、NDIS はドライバーのこの役割の変換を自動的に実行し、代わりにパラメーターを設定する次の 2 つの OID を発行します。

OID_GEN_RECEIVE_SCALE_PARAMETERS_V2 は標準 OID であり、OID_GEN_RECEIVE_SCALE_PARAMETERS OID が RSSv1 で処理されたのと同じように処理されます。 この OID は、NDIS 6.80 より前の NDIS 軽量フィルター ドライバー (LWF) には表示されません。

ただし、OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES は、NDIS_STATUS_PENDING を返すことができない同期 OID です。 この OID は、OID を生成したプロセッサ コンテキストで実行および完了する必要があります。 OID_GEN_RECEIVE_SCALE_PARAMETERS_V2 と同様、NDIS 6.80 より前の NDIS LWF からも見えません。 NDIS 6.80 以降の LWF では、この OID を遅延させたり、別のプロセッサに移動したりすることはできません。 そのペイロードには、シンプルな "ITE の移動" アクションの配列が含まれています。各アクションには、スケーリング エンティティの単一の ITE を別のターゲット CPU に移動するコマンドが含まれています。 配列の要素は、さまざまなスケーリング エンティティ (VPorts) を参照できます。

NDIS ドライバー、ミニポート、フィルター、プロトコルの各種類には、同期 OID 要求インターフェイスをサポートするためのエントリ ポイントがあります。

NDIS ドライバーの種類 同期 OID ハンドラー 同期 OID を生成する関数
ミニポート MiniportSynchronousOidRequest 該当なし
Assert NdisFSynchronousOidRequest
Protocol 該当なし NdisSynchronousOidRequest

RSS 状態遷移、ITE 更新プログラム、プライマリ/既定のプロセッサ

ステアリング パラメーター

RSSv2 では、RSS の状態 (有効または無効) に応じて、トラフィックを適切な CPU に誘導するためにさまざまなパラメーターが使用されます。 RSS を無効にすると、プライマリ プロセッサのみがトラフィックの転送に使用されます。 RSS が有効になると、既定のプロセッサとすべての ITE の両方がトラフィックの転送に使用されます。 これらのステアリング パラメーターは、次の表にまとめられているように "アクティブ" または "非アクティブ" としてラベル付けされます。

ステアリング パラメーター RSS を無効に設定 RSS を有効に設定
プライマリ プロセッサ アクティブです 非アクティブ
既定のプロセッサ 非アクティブ アクティブです
ITE[0..N] 非アクティブ アクティブです

ステアリング パラメーターがアクティブな状態になると、トラフィックが送信されます。 パラメーターを非アクティブにする RSS 状態遷移の瞬間から、ミニポート ドライバーは、逆遷移が再度アクティブになるまで、パラメーターへの変更を追跡する必要があります。 つまり、ミニポート ドライバーは、既定のプロセッサと間接テーブル エントリに対するすべての更新を追跡する必要がある一方で、そのスケーリング エンティティに対して RSS は無効になっています。 RSS が有効になると、既定のプロセッサと間接参照テーブルの現在の追跡状態が有効になります。

たとえば、ソフトウェア vRSS が既に有効になっているシナリオを考えてみましょう。 この場合、間接テーブルは既に上位層プロトコルに存在し、上位層のソフトウェア拡散コードによってアクティブに使用されます。 ハードウェア RSS の有効化時、間接テーブルエントリを移動する更新プログラムがハードウェアに発行されて実行される前に、すべてのエントリがプライマリ プロセッサをポイントし始めると、プライマリ プロセッサで短い遅延が発生する可能性があります。 ミニポート ドライバーが既定のプロセッサと ITE の情報を追跡している場合、上位層で既に想定されている場所にトラフィックを転送できます。

ミニポート ドライバーは、非アクティブなステアリング パラメーターのすべての更新を追跡する必要がありますが、RSS 状態の変更がこれらのパラメーターをアクティブにしようとするまで、これらのパラメーターの検証を遅延させる必要がある点に注意してください。 たとえば、ハードウェア RSS が無効なときにソフトウェアが拡散した場合、上位層プロトコルでは、(アダプターの RSS セットの外部を含む) 拡散に任意のプロセッサを使用できます。 上位層は、RSS 状態遷移の時点で、すべての非アクティブ パラメーターが新しい RSS 状態に対して有効であることを保証します。 ただし、追跡対象の非アクティブなステアリング パラメーターが無効であることが検出された場合、ミニポート ディレクトリは引き続きパラメーターを検証し、RSS 状態の遷移を失敗させる必要があります。

初期状態とステアリング パラメーターの更新

次の表では、作成後 (VPort の作成後など) のスケーリング エンティティの初期状態と、パラメーターを更新する方法について説明します。

パラメーター 説明
プライマリ プロセッサ
  • VPort の作成時に指定されたアフィニティ プロセッサによって初期化されます。
  • NDIS_RSS_SET_INDIRECTION_ENTRY_FLAG_PRIMARY_PROCESSOR フラグが設定された OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES OID を使用して更新できます。
  • NDIS_NIC_SWITCH_VPORT_PARAMS_PROCESSOR_AFFINITY_CHANGED フラグが設定された OID_NIC_SWITCH_VPORT_PARAMETERS OID を使用して更新することができます (これは、既存のコマンドレットの互換性パスです)。
  • NDIS_NIC_SWITCH_VPORT_PARAMS_PROCESSOR_AFFINITY_CHANGED フラグを持つ OID_NIC_SWITCH_VPORT_PARAMETERS OID を使用して読み取ることができます (これは、既存のコマンドレットの互換性パスです)。
  • プライマリ プロセッサの初期化後移動は、既定のプロセッサや間接参照テーブルの内容には影響を与えません。
既定のプロセッサ
  • VPort の作成時に指定されたアフィニティ プロセッサによって初期化されます。
  • NDIS_RSS_SET_INDIRECTION_ENTRY_FLAG_DEFAULT_PROCESSOR フラグが設定された OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES OID を使用して更新できます。
間接テーブル
  • NumberOfIndirectionTableEntries1 に設定されています。
  • 唯一のエントリは、VPort の作成時に指定されたアフィニティ プロセッサで初期化されます。
  • OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES OID を使用して更新できます。

ITE への更新と、対応するエントリが現在ポイントしているプロセッサから (OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES を使用して) プライマリ/既定のプロセッサが呼び出されます。 特定の VPort の場合、上位層では、ITE を移動したり、プライマリ/既定のプロセッサを設定したりするための OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES OID が発行されないようにします。

  1. OID_GEN_RECEIVE_SCALE_PARAMETERS_V2 が進行中です。
  2. VPort 削除シーケンスが開始された後。 たとえば、上位層は、ITE を移動する最後の OID が完了した後のみ、設定フィルター OID を発行します。

RSS の無効化

RSS の無効化時、上位層プロトコルでは、すべての ITE をプライマリ プロセッサにポイントし、OID を発行して RSS を無効にするか、間接テーブルをそのままにして RSS を無効にするかを選択できます。 どちらの場合も、受信トラフィックはプライマリ プロセッサをターゲットにする必要があります。

RSSv2 では、RSSv1 からの要件が保持されます。この要件では、最初に RSS を無効にしなくても、上位層プロトコルで VPort を削除することが許可されます。 上位層は、VPort の受信フィルターを 0 に設定できるため、受信トラフィックが VPort 経由で流れないようにして、RSS を無効にせずに VPort の削除を進めます。 上位層では、VPort の削除時または削除後に OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES OID が発行されないことが保証されます。

RSS の無効化時と VPort の削除時の両方で、ミニポート ドライバーは、以前のキュー移動のために存在する可能性がある保留中の内部操作を処理する必要があります。

RSSv2 インバリアント

上位層プロトコルでは、管理機能または ITE の移動を実行する前に、重要なインバリアントへの違反が防止されます。 次に例を示します。

  1. キューの数を減らす前に、上位層では、間接テーブルが VPort の新しいキュー数よりも多くのプロセッサを参照することが防止されます。
  2. 上位層は、VPort の現在構成されているキューの数に違反する間接テーブルの更新を要求してはなりません。 ミニポート ドライバーは、これを適用し、エラーを返す必要があります。
  3. VMMQ-RESTRICTED アダプターの間接指定テーブル エントリの数を変更する前に、上位レイヤーでは、間接指定テーブルの内容が 2 の累乗に正規化されていることを確認します。

OID_GEN_RECEIVE_SCALE_PARAMETERS_V2

OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES

NDIS 6.80 の同期 OID 要求インターフェイス