次の方法で共有


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 よりもはるかに応答性の高い複数のプロセッサに受信キューを動的に分散できることを意味します。

適切な RSS 機能を設定し、間接テーブルを制御するために、ミニポート ドライバー用の 2 つの OID (OID_GEN_RECEIVE_SCALE_PARAMETERS_V2OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES) が RSSv2 で導入されました。 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 の移動なし) または動的 (現在のトラフィック負荷に応じた拡張と結合) です。
Queue ITE をサポートする基になるハードウェア オブジェクト (キュー)。 ハードウェアと間接参照テーブルによっては、構成キューが複数のITEを支えることがあります。 既定のキューで使用されるキューを含むキューの合計数は、通常管理者が設定する構成済みの制限を超えることはできません。
既定のプロセッサ ハッシュを計算できないパケットを受信するプロセッサ。 各 VPort には既定のプロセッサがあります。
プライマリ プロセッサ ProcessorAffinity メンバーとして指定されたプロセッサは、VPort の作成時に NDIS_NIC_SWITCH_VPORT_PARAMETERS 構造体のメンバーです。 このプロセッサは実行時に更新でき、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 フラグを有効にするために必要です。

手記

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

ミニポート アダプターが RSSv2 機能をアドバタイズしない場合、これらの VPort が動的拡散を実行するように要求された場合でも、すべての VMQ 対応 VPort は静的拡散モードのままです。 RSS パラメーター (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 は、キューの数、ITEs の数、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 であり、RSSv1 で処理されたOID_GEN_RECEIVE_SCALE_PARAMETERS OID と同じように処理されます。 この 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 の移動" アクションの配列が含まれています。各アクションには、スケーリング エンティティの 1 つの ITE を別のターゲット CPU に移動するコマンドが含まれています。 配列の要素は、さまざまなスケーリング エンティティ (VPorts) を参照できます。

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

NDIS ドライバーの種類 同期 OID ハンドラー 同期 OID を生成する関数
ミニポート MiniportSynchronousOidRequest N/A
フィルター NdisFSynchronousOidRequest
議定書 N/A NdisSynchronousOidRequest

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

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

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

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

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

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

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

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

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

パラメーター 説明
プライマリ プロセッサ
  • VPort の作成時に指定された Affinity プロセッサで初期化されます。
  • 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 の作成時に指定された Affinity プロセッサで初期化されます。
  • NDIS_RSS_SET_INDIRECTION_ENTRY_FLAG_DEFAULT_PROCESSOR フラグが設定された OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES OID を使用して更新できます。
間接テーブル
  • NumberOfIndirectionTableEntries1に設定されています。
  • 唯一のエントリは、VPort の作成時に指定された Affinity プロセッサで初期化されます。
  • 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 削除シーケンスが開始された後。 たとえば、上位レイヤーは、ITEs を移動する最後の OID が完了した後にのみ、セット フィルター OID を発行します。

RSS 無効化

RSS 無効化中、上位層プロトコルでは、すべての ITEs をプライマリ プロセッサにポイントし、OID を発行して RSS を無効にするか、間接テーブルを as-is のままにして 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要求インターフェイス