デバッガーの 2PF KDNET サポート
このトピックでは、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 Single Root I/O Virtualization and Sharing 1.1 仕様で定義されています。
デバッガー トランスポートは、複数の 2PF 対応ミニポート ドライバーを利用します。 高速サーバーのシステムのデバッグを可能にするために、NIC ベンダーは、ネットワークカードファームウェアで複数の PF をサポートするすべての NIC で 2PF を有効にすることをお勧めします。
接続をテストするための 2PF サポートの構成については、KDNET を使用した 2PF カーネル・モード・デバッグのセットアップを参照してください。
複数 PF KDNET アーキテクチャの概要
Multiple PF (2PF) 機能は、新しい PF を元の PCI ネットワーク ポート (Bus.dev.fun0.0 など) に追加/割り当てることです。
新しく追加された PF (例: bus.dev.fun0.1) は、ターゲットとの間でデバッガー パケットをルーティングするために KDNET によってのみ使用されます。
元の PF は、Windows ネットワーク パケット (TCP/IP) をルーティングするために Windows 受信トレイ NIC ドライバーによって使用されます。
このアプローチを使用すると、両方のドライバーが互いの作業に干渉することなく並行して動作できます。
どちらのドライバも、パーティション分割されたPCI構成空間上で実行されます
Windowsインボックスドライバは、bus.dev 時に元のネットワークポートを使い果たしますfun0.0。
KDNET-KDNET-Ext. モジュールは、bus.dev.fun0.1 で追加 PF から実行されます。この技法を活用して、KDNET と NIC を共有し、Windows 受信トレイ NIC ドライバーが影響を受けないようにします。
kdnet.exe ユーザー モード ツールは、特定の IOCTL コードを追加して KDNET PF を追加/削除することで、Windows 受信トレイ ドライバーを使用して 2PF 機能を構成します。
複数のPFは設計要件を備えています
KDNET 2PF 機能は、NT より前の OS (ブート マネージャー、OS ローダー、WinResume、Hyper-V、SK など)、NT OS、Windows デスクトップのいずれであっても、現在のすべての KD シナリオで機能する必要があります。
デバイスの新しい PF を追加すると、デバッグ設定のために BCD 構成の変更が必要になった場合は、システムの再起動が必要になります。 つまり、追加の PF の設定は、ブート後も永続的でなければなりません。
KDNET 2PF は、デバッガーがデバッグ デバイスを所有している場合に、PCI 2PF の場所からアクセス/実行されている他の Windows/UEFI イーサネット ドライバーがないことを確認するために、デバッガーでのみ使用する必要があります (2PF の場所は dbgsettings::busparams を使用して構成されます)。
Windows または UEFI イーサネット ドライバーは、システムで KDNET が有効になっていない場合でも、追加された 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ヘッダー・ファイルで提供される情報については、以下の詳細を参照してください。
- KDNET は、複数の PF 機能が使用可能な NICS で KDNET 2PF 機能を使用して構成する必要があり、NIC は上記のすべての要件に従って 2PF 機能を有効にします。
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 ポート) にのみ 関連付けられている UDF の一覧が一覧表示または列挙されます。これは、すべてのミニポート ドライバーがその BDF の場所を決定できるためです。
PF の一覧は、NDIS クエリ操作を介してクライアントに返されます。
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 を追加します。 ポートは BDF で表されます。
新しく追加された PF は、NDIS クエリ操作を介してクライアントに返されます。
OID_KDNET_ADD_PF ドライバー ハンドラーは、追加された PF 関数番号を含む ULONG を返します。
この OID 要求には、出力パラメーターが 1 つだけ含まれます
AddedFunctionNumber
。 ミニポートAddedFunctionNumber
PCI の場所に追加された関数番号の値を示します (BDF ミニポート)。 kdnet.exe ユーティリティはこの値を受け取り、追加された PF を指すように dbgsettings::busparams を設定します。
Note
追加された PF は KDNET によって排他的に使用できるため、Windows NIC ドライバーは追加された PF で明示的に *NOT* 実行されるようにトリガーされるため、システムで KDNET が *NOT* 有効になっていて、PF がポートに追加されている場合にも適用されます。
3. PCI PF を削除する (OID: OID_KDNET_REMOVE_PF、以下の定義を参照)
指定されたポートから PF を 削除します。 ポートは BDF で表されます。
OID_KDNET_REMOVE_PF OID は、NDIS_KDNET_REMOVE_PF構造体に関連付けられています。
OID_KDNET_REMOVE_PF OID には入力 BDF ポートがあり、NDIS メソッド操作を介して削除された PF 関数番号を含む ULONG を返します。
この関数は、OID_KDNET_ADD_PF OID を使用して追加された CF でのみ成功します。
この OID 要求には、BDF を削除する必要がある入力 BDF ポートがあります。 この関数の Output パラメーターは次のとおりです
FunctionNumber
。 出力FunctionNumber
には、削除された関数番号の値が含まれます。
4. PCI PF 情報のクエリ (OID: OID_KDNET_QUERY_PF_INFORMATION、以下の定義を参照)
この OID コードを使用すると、特定のポートで特定の PF データに対してクエリを 実行できます。 ポートは 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 含まれています。
PF の最大数: 指定された BDF に追加できる PF の最大数を含む 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 (e.g. 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 is 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)