このトピックでは、高速アダプターのパフォーマンス向上を可能にする 2PF デバッガーのサポートのミニポート NDIS ドライバーを有効にする方法について説明します。多くの場合、データ センターで使用されます。 この機能は、Windows 11 以降で使用できます。
NIC でカーネル デバッグを有効にすると、カーネル デバッグのサポートによって物理デバイスが引き継がれ、ボックスにカーネル デバッグとネットワーク接続の両方が提供されます。 これは、コンシューマーの低帯域幅 NIC (1 ~ 10 Gbps) で正常に動作します。 ただし、10 ~ 40 Gbps をサポートする高スループット デバイスでは、カーネル デバッグ機能拡張モジュールは Windows ネットワーク スタックからのトラフィックに対応できません。 その結果、システム全体のパフォーマンスが低下します。
KDNET に PCI 複数物理機能 (PF) 機能を使用すると、パフォーマンスにほとんど影響を与えずにデバッグを有効にすることができます。
物理機能 (PF) は、単一ルート I/O 仮想化 (SR-IOV) インターフェイスをサポートするネットワーク アダプターの PCI Express (PCIe) 関数です。 PF には、PCIe 構成スペースに SR-IOV 拡張機能が含まれています。 この機能は、仮想化の有効化や PCIe Virtual Functions (VFs) の公開など、ネットワーク アダプターの SR-IOV 機能を構成および管理するために使用されます。
PF は、PCIe 構成スペースの SR-IOV 拡張機能構造をサポートしています。 この構造は、 PCI-SIG シングル ルート I/O 仮想化および共有 1.1 仕様で定義されています。
デバッガー トランスポートは、複数または 2PF 対応ミニポート ドライバーを利用します。 高速サーバーのシステムのデバッグを可能にするために、NIC ベンダーは、ネットワーク カード ファームウェアで複数の PF をサポートするすべての NIC で 2PF を有効にすることをお勧めします。
接続をテストするための 2PF サポートの構成については、 KDNET を使用した 2PF Kernel-Mode デバッグのセットアップを参照してください。
複数の PF KDNET アーキテクチャの概要
Multiple PF (2PF) 機能は、元の PCI ネットワーク ポート (Bus.dev.fun0.0 など) に新しい PF を追加または割り当てることです。
新しく追加された PF (bus.dev.fun0.1 など) は、KDNET によってのみ使用され、デバッガー パケットをターゲットと送受信します。
Windows 受信トレイ NIC ドライバーは、元の PF を使用して Windows ネットワーク パケット (TCP/IP) をルーティングします。
この方法を使用すると、両方のドライバーが互いに干渉しながら並列で動作できます。
どちらのドライバーも、パーティション分割された PCI 構成領域を介して実行されます
Windows 受信トレイ ドライバーは、bus.dev 元のネットワーク ポートを使い切ります。fun0.0
KDNET-KDNET-Ext.モジュールは、bus.dev で追加された PF を使い切ります。fun0.1、この方法では、KDNET と NIC を共有することで、Windows 受信トレイ NIC ドライバーが影響を受けないようにします。
kdnet.exe ユーザー モード ツールは、KDNET PF を追加または削除する特定の IOCTL コードを追加することによって、Windows 受信トレイ ドライバーを使用して 2PF 機能を構成します。
複数の UDF 機能の設計要件
KDNET 2PF 機能は、NT OS (ブート マネージャー、OS ローダー、WinResume、Hyper-V、SK など)、NT OS、Windows デスクトップなど、現在のすべての KD シナリオで機能する必要があります。
デバイスの新しい PF を追加してデバッグ設定の BCD 構成を変更する場合は、システムの再起動が必要です。 この要件は、追加の PF の構成がブート間で永続的である必要があることを意味します。
KDNET 2PF はデバッグにのみ使用してください。 これにより、デバッガーがデバイスを所有しているときに、Windows または UEFI イーサネット ドライバーが PCI 2PF の場所にアクセスしないようにします。 2PF の場所は、dbgsettings::busparams を使用して構成されます。
システムで KDNET が有効になっていない場合でも、Windows または UEFI イーサネット ドライバーが追加された KDNET 2PF を使い果たすことはできません。
2PF 機能は、現在の NIC の機能を追加、有効化、および削除/無効化するための動的メカニズムをサポートする必要があります。
Windows ミニポート ドライバーは、次の NDIS OID を提供して 2PF 機能を実装します。
| OID 名 | 説明 |
|---|---|
| OID_KDNET_ENUMERATE_PFS | ミニポート ドライバーが実行されている現在の bus.dev.fun (BDF) 上の GIF を列挙します。 |
| OID_KDNET_ADD_PF | ミニポート ドライバーが実行されている現在の BDF に PF を追加します。 |
| OID_KDNET_REMOVE_PF | 渡された BDF から追加された PF を削除します。 |
| OID_KDNET_QUERY_PF_INFORMATION | 渡された BDF から PF 情報データを照会します。 |
OID とその構造は、パブリック WDK で解放される ntddndis.h ファイルと kdnetpf.h ファイルで定義されます。
各 OID の入出力パラメーターと kdnetpf.h ヘッダー ファイルで提供される情報については、次の詳細を参照してください。
- 複数の PC をサポートする NIC で KDNET 2PF 機能を使用して KDNET を構成します。 2PF 機能を有効にするには、NIC がこのセクションで説明されているすべての要件を満たしていることを確認します。
Windows NIC ドライバー用 KDNET マルチ PF インターフェイス
KDNET マルチ PF インターフェイスをサポートするには、ミニポート ドライバーは、次の 4 つの NDIS OID の処理を実装する必要があります。
OID_KDNET_ENUMERATE_PFS
OID_KDNET_ADD_PF
OID_KDNET_REMOVE_PF
OID_KDNET_QUERY_PF_INFORMATION
これらの OID と構造体は、このパスのパブリック WDK リリースの ntddndis.h ファイルと kdnetpf.h ファイルに設定されます。
<WDK root directory>\ddk\inc\ndis
これらのファイルは Windows SDK でも使用でき、このディレクトリにあります。
\Program Files (x86)\Windows Kits\10\Include\<Version for example 10.0.21301.0>\shared
クライアント ツール (kdnet.exe) は、プライベート NDIS IOCTL を使用して KDNET 2PF NDIS OID をミニポート ドライバーにルーティングします。
複数の PF 機能 NDIS OID
複数の PF 機能は、これら 4 つの NDIS OID を使用して動作します。
1. OID を使用してミニポート BDF プライマリ ポートの GIF を列挙する: OID_KDNET_ENUMERATE_PFS、次の定義を参照してください。
OID_KDNET_ENUMERATE_PFS は、ミニポート ドライバーが実行されている特定のプライマリ ポートに関連付けられているすべての BDF の一覧を返します。 bus.dev.fun (BDF) はポートを表します。 この操作では、ミニポート ドライバーが実行される bus.dev.fun (BDF ポート) にのみ関連付けられている INF が一覧表示されます。 各ミニポート ドライバーは、その BDF の場所を決定できます。
NDIS クエリ操作を使用して、クライアントに、UDF の一覧が返されます。
OID_KDNET_ENUMERATE_PFS OID は、NDIS_KDNET_ENUMERATE_PFS構造体に関連付けられています。
OID_KDNET_ENUMERATE_PFS ドライバー ハンドラーは、型NDIS_KDNET_PF_ENUM_ELEMENTで記述された各 PF 要素を含む、PFs リストを含むバッファーを返します。
PfNumber フィールドには、PF 関数番号 (bus.dev など) が含まれています。楽しい)
PfState フィールドには、PF 状態が可能な値 (列挙型で記述される各要素の型 ) NDIS_KDNET_PF_STATE 含まれます。
NDIS_KDNET_PF_STATE::NdisKdNetPfStatePrimary - これはプライマリ PF であり、通常はミニポート ドライバーによってのみ使用されます。
NDIS_KDNET_PF_STATE::NdisKdnetPfStateEnabled - KDNET によって使用される追加のセカンダリ PF です。
NDIS_KDNET_PF_STATE::NdisKdnetPfStateConfigured - これは追加された PF ですが、追加/構成のみであり、使用されません。
PF リストの出力バッファー サイズが実際のPFリストを割り当てるのに十分な大きさでない場合、OID ハンドラーは、必要なバッファー サイズと共にエラー戻り値
E_NOT_SUFFICIENT_BUFFER返す必要があります。そのため、クライアント ツールは必要なサイズ バッファーを割り当てることができ、クライアントは適切なバッファー サイズを割り当てて別の呼び出しを行うことができます。 さらに、OID 要求の状態フィールド (NDIS_IOCTL_OID_REQUEST_INFO.status で説明) は、NDIS_STATUS_BUFFER_TOO_SHORTに設定する必要があります。
2. ミニポート BDF プライマリ ポートに PCI PF を追加します (OID: OID_KDNET_ADD_PF、 次の定義を参照してください)
ミニポート プライマリ ポートに PF を追加します。 bus.dev.fun (BDF) はポートを表します。
新しく追加された PF は、NDIS クエリ操作を介してクライアントに返されます。
OID_KDNET_ADD_PF OID は、NDIS_KDNET_ADD_PF構造体に関連付けられています。
OID_KDNET_ADD_PF ドライバー ハンドラーは、追加された PF 関数番号を含む ULONG を返します。
この OID 要求に含まれる出力パラメーターは 1 つだけです:
AddedFunctionNumber。AddedFunctionNumberは、ミニポート PCI の場所 (BDF ミニポート) に追加された関数番号の値を示します。 kdnet.exe ユーティリティはこの値を受け取り、追加された PF を指す dbgsettings::busparams を設定します。
注
KDNET では、追加された PF を排他的に使用できます。 Windows NIC ドライバーは、追加された PF で明示的に *NOT* 実行されるようにトリガーされます。 これは、KDNET がシステムで *NOT* 有効になっていて、PF がポートに追加されている場合にも当てはまります。
3. PCI PF を削除する (OID: OID_KDNET_REMOVE_PF、次の定義を参照)
指定されたポートから PF を削除します。 bus.dev.fun (BDF) はポートを表します。
OID_KDNET_REMOVE_PF OID は、NDIS_KDNET_REMOVE_PF構造体に関連付けられています。
OID_KDNET_REMOVE_PF OID には入力 BDF ポートがあり、NDIS メソッド操作を介して削除された PF 関数番号を含む ULONG を返します。
この関数は、 OID_KDNET_ADD_PF OID を使用して追加された INF でのみ成功します。
この OID 要求には、BDF を削除する必要がある入力 BDF ポートがあります。 この関数には、
FunctionNumberの Output パラメーターがあります。 出力FunctionNumberには、削除された関数番号の値が含まれています。
4. PCI PF 情報のクエリ (OID: OID_KDNET_QUERY_PF_INFORMATION、次の定義を参照)
この OID コードを使用すると、 特定のポートで特定の PF データに対してクエリを実行できます。 bus.dev.fun (BDF) はポートを表します。
要求された PF 情報は、NDIS メソッド操作を介してクライアントに返されます。
OID_KDNET_QUERY_PF_INFORMATION OID は、NDIS_KDNET_QUERY_PF_INFORMATION構造体に関連付けられています。
OID_KDNET_QUERY_PF_INFORMATION OID には入力 BDF ポートがあり、次のデータを含むバッファーが返されます。
MAC アドレス: 割り当てられた新しい KDNET PF のネットワーク アドレス (存在する場合)。
使用法タグ: PF ポートを所有するエンティティについて説明します。 これには、列挙型によって記述された定数値 NDIS_KDNET_PF_USAGE_TAG 含まれています。
[VM の最大数]: 指定された BDF に追加できる最大数の CF を含む ULONG が含まれます。
デバイス ID: 指定された BDF ポートに関連付けられているデバイス ID が含まれます。 これは、NIC FW が新しく追加された KDNET PF ポートに新しいデバイス ID を割り当てる場合に必要です。
この OID は、BDF ポートで渡された情報を要求します (BDF はこの操作の入力パラメーターです)。 ドライバーの実行場所の現在の BDF に必ずしも関連 しているわけではありません 。
2PF 上の KDNET 用 NDIS OID
Ntddndis.h ファイルは OID を定義します。
#if (NDIS_SUPPORT_NDIS686)
//
// Optional OIDs to handle network multiple PF feature.
//
#define OID_KDNET_ENUMERATE_PFS 0x00020222
#define OID_KDNET_ADD_PF 0x00020223
#define OID_KDNET_REMOVE_PF 0x00020224
#define OID_KDNET_QUERY_PF_INFORMATION 0x00020225
#endif // (NDIS_SUPPORT_NDIS686)
Kdnetpf.h ファイルは、NDIS OID に関連付けられている型と構造体を記述します。
#if (NDIS_SUPPORT_NDIS686)
//
// Used to query/add/remove Physical function on a network port.
// These structures are used by these OIDs:
// OID_KDNET_ENUMERATE_PFS
// OID_KDNET_ADD_PF
// OID_KDNET_REMOVE_PF
// OID_KDNET_QUERY_PF_INFORMATION
// These OIDs handle PFs that are primary intended to be used by KDNET.
//
//
// PCI location of the port to query
//
typedef struct _NDIS_KDNET_BDF
{
ULONG SegmentNumber;
ULONG BusNumber;
ULONG DeviceNumber;
ULONG FunctionNumber;
ULONG Reserved;
} NDIS_KDNET_BDF, *PNDIS_KDNET_PCI_BDF;
//
// PF supported states.
//
typedef enum _NDIS_KDNET_PF_STATE
{
NdisKdNetPfStatePrimary = 0x0,
NdisKdnetPfStateEnabled = 0x1,
NdisKdnetPfStateConfigured = 0x2,
} NDIS_KDNET_PF_STATE,*PNDIS_KDNET_PF_STATE;
//
// PF Usage Tag
// Used to indicate the entity that owns the PF.
// Used by the query NdisKdnetQueryUsageTag.
//
typedef enum _NDIS_KDNET_PF_USAGE_TAG
{
NdisKdnetPfUsageUnknown = 0x0,
NdisKdnetPfUsageKdModule = 0x1,
} NDIS_KDNET_PF_USAGE_TAG,*PNDIS_KDNET_PF_USAGE_TAG;
//
// PF element array structure
//
typedef struct _NDIS_KDNET_PF_ENUM_ELEMENT
{
NDIS_OBJECT_HEADER Header;
//
// PF value (for example, if <bus.dev.fun>, then PF value = fun)
//
ULONG PfNumber;
//
// The PF state value (defined by NDIS_KDNET_PF_STATE)
//
NDIS_KDNET_PF_STATE PfState;
} NDIS_KDNET_PF_ENUM_ELEMENT, *PNDIS_KDNET_PF_ENUM_ELEMENT;
#define NDIS_KDNET_PF_ENUM_ELEMENT_REVISION_1 1
#define NDIS_SIZEOF_KDNET_PF_ENUM_ELEMENT_REVISION_1 \
RTL_SIZEOF_THROUGH_FIELD(NDIS_KDNET_PF_ENUM_ELEMENT, PfState)
//
// This structure describes the data required to enumerate the list of PF
// Used by OID_KDNET_ENUMERATE_PFS.
//
typedef struct _NDIS_KDNET_ENUMERATE_PFS
{
NDIS_OBJECT_HEADER Header;
//
// The size of each element is the sizeof(NDIS_KDNET_PF_ENUM_ELEMENT)
//
ULONG ElementSize;
//
// The number of elements in the returned array
//
ULONG NumberOfElements;
//
// Offset value to the first element of the returned array.
// Each array element is defined by NDIS_KDNET_PF_ENUM_ELEMENT.
//
ULONG OffsetToFirstElement;
} NDIS_KDNET_ENUMERATE_PFS, *PNDIS_KDNET_ENUMERATE_PFS;
#define NDIS_KDNET_ENUMERATE_PFS_REVISION_1 1
#define NDIS_SIZEOF_KDNET_ENUMERATE_PFS_REVISION_1 \
RTL_SIZEOF_THROUGH_FIELD(NDIS_KDNET_ENUMERATE_PFS,
OffsetToFirstElement)
//
// This structure indicates the data required to add a PF to the BDF port.
// Used by OID_KDNET_ADD_PF.
//
typedef struct _NDIS_KDNET_ADD_PF
{
NDIS_OBJECT_HEADER Header;
//
// One element containing the added PF port number
//
ULONG AddedFunctionNumber;
} NDIS_KDNET_ADD_PF, *PNDIS_KDNET_ADD_PF;
#define NDIS_KDNET_ADD_PF_REVISION_1 1
#define NDIS_SIZEOF_KDNET_ADD_PF_REVISION_1 \
RTL_SIZEOF_THROUGH_FIELD(NDIS_KDNET_ADD_PF, AddedFunctionNumber)
//
// This structure indicates the data required to remove a PF from the BDF port.
// Used by OID_KDNET_REMOVE_PF.
//
typedef struct _NDIS_KDNET_REMOVE_PF
{
NDIS_OBJECT_HEADER Header;
//
// PCI location that points to the PF that needs to be removed
//
NDIS_KDNET_BDF Bdf;
//
// One element containing the removed PF port
//
ULONG FunctionNumber;
} NDIS_KDNET_REMOVE_PF, *PNDIS_KDNET_REMOVE_PF;
#define NDIS_KDNET_REMOVE_PF_REVISION_1 1
#define NDIS_SIZEOF_KDNET_REMOVE_PF_REVISION_1 \
RTL_SIZEOF_THROUGH_FIELD(NDIS_KDNET_REMOVE_PF, FunctionNumber)
//
// This structure describes the data required to query the PF management data
// Used by OID_KDNET_QUERY_PF_INFORMATION
//
typedef struct _NDIS_KDNET_QUERY_PF_INFORMATION
{
NDIS_OBJECT_HEADER Header;
//
// PF PCI location to query for
//
NDIS_KDNET_BDF Bdf;
//
// PF assigned MAC address
//
UCHAR NetworkAdddress[6];
//
// PF Usage tag described by NDIS_KDNET_PF_USAGE_TAG
//
ULONG UsageTag;
//
// Maximum number of Pfs that can be associated to the Primary BDF.
//
ULONG MaximumNumberOfSupportedPfs;
//
// KDNET PF device ID (Used if there's a new added PF and
// the FW assigns a new DeviceID to the added KDNET PF)
//
ULONG DeviceId;
} NDIS_KDNET_QUERY_PF_INFORMATION, *PNDIS_KDNET_QUERY_PF_INFORMATION;
#define NDIS_KDNET_QUERY_PF_INFORMATION_REVISION_1 1
#define NDIS_SIZEOF_KDNET_QUERY_PF_INFORMATION_REVISION_1 \
RTL_SIZEOF_THROUGH_FIELD(NDIS_KDNET_QUERY_PF_INFORMATION, DeviceId)
#endif // (NDIS_SUPPORT_NDIS686)