Debugger 2PF KDNET-Unterstützung
In diesem Thema wird beschrieben, wie Sie Ihren Miniport-NDIS-Treiber für die Unterstützung von 2PF-Debuggern aktivieren, um eine höhere Leistung für Hochgeschwindigkeitsadapter zu ermöglichen, die häufig in Rechenzentren verwendet werden. Dieses Feature ist in Windows 11 und höher verfügbar.
Beim Aktivieren des Kerneldebuggings auf einer NIC übernimmt die Kerneldebuggingunterstützung das physische Gerät, um sowohl ein Kerneldebugging als auch eine Netzwerkverbindung im Feld bereitzustellen. Dies funktioniert gut für NICs mit geringer Bandbreite für Verbraucher (1-10 GBit/s), aber auf Geräten mit hohem Durchsatz, die 10-40 GBit/s unterstützen, können die Kerneldebugging-Erweiterungsmodule, die mit der Hardware sprechen, im Allgemeinen nicht mit der Menge des Datenverkehrs, der aus dem Windows-Netzwerkstapel stammt, aufhalten, sodass dies die Gesamtleistung des Systems beeinträchtigt.
Die Verwendung der FUNKTION PCI multiple Physical Function (PF) für KDNET ermöglicht die Aktivierung des Debuggings ohne Leistungseinbußen.
Die physische Funktion (PF) ist eine PCI Express(PCIe)-Funktion eines Netzwerkadapters, der die einzelne I/O-Virtualisierungsschnittstelle (SR-IOV) unterstützt. Die PF enthält die erweiterte SR-IOV-Funktion im PCIe-Konfigurationsbereich. Die Funktion wird verwendet, um die SR-IOV-Funktionalität des Netzwerkadapters zu konfigurieren und zu verwalten, z. B. zum Aktivieren der Virtualisierung und Zum Verfügbarmachen von virtuellen PCIe-Funktionen (VFs).
Die PF unterstützt die erweiterte SR-IOV-Funktionsstruktur im PCIe-Konfigurationsbereich. Diese Struktur wird in der Spezifikation PCI-SIG Single Root I/O Virtualization and Sharing 1.1 definiert.
Der Debuggertransport nutzt mehrere oder 2PF-aktivierte Miniporttreiber. Um das Debuggen von Systemen mit Hochgeschwindigkeitsservern zu ermöglichen, wird empfohlen, dass NIC-Anbieter 2PF in allen NICs aktivieren, die mehrere PF im Netzwerk Karte Firmware unterstützen.
Informationen zum Konfigurieren der 2PF-Unterstützung zum Testen einer Verbindung finden Sie unter Einrichten des 2PF-Kernelmodusdebuggings mit KDNET.
Übersicht über mehrere PF-KDNET-Architekturen
Die Funktionalität mehrerer PF (2PF) besteht darin, dem ursprünglichen PCI-Netzwerkanschluss (z. B. Bus.dev.fun0.0) einen neuen PF hinzuzufügen/zuzuweisen.
Die neue hinzugefügte PF (z. B. bus.dev.fun0.1) wird nur von KDNET verwendet, um Debuggerpakete an/vom Ziel zu leiten.
Die ursprüngliche PF wird vom Windows-Posteingangs-NIC-Treiber verwendet, um die Windows-Netzwerkpakete (TCP/IP) weiterzuleiten.
Bei verwendung dieses Ansatzes können beide Faktoren parallel arbeiten, indem sie sich gegenseitig stören.
Beide Treiber werden über den partitionierten PCI-Konfigurationsraum ausgeführt.
Der Windows-Posteingangstreiber hat den ursprünglichen Netzwerkport bei bus.dev nicht mehr.fun0.0
KDNET-KDNET-Ext. die hinzugefügte PF bei bus.dev wird nicht mehr hinzugefügt.fun0.1, Auf diese Weise wird sichergestellt, dass der Windows-Posteingangs-NIC-Treiber nicht durch die Freigabe der NIC mit KDNET beeinträchtigt wird.
Das kdnet.exe Benutzermodustool konfiguriert das 2PF-Feature mithilfe des Windows-Posteingangstreibers, indem bestimmte IOCTL-Codes hinzugefügt werden, um KDNET PF hinzuzufügen/zu entfernen.
Designanforderungen für mehrere PFs
Das KDNET 2PF-Feature muss für alle aktuellen KD-Szenarien funktionieren, unabhängig davon, ob es sich um das Vorab-NT-Betriebssystem (z. B. Start-Manager, Betriebssystemladeprogramm, WinResume, Hyper-V, SK usw.), NT OS oder Windows Desktop handelt.
Ein Neustart des Systems ist erforderlich, wenn ein neues PF für ein Gerät hinzugefügt wird, was zu einer Änderung der BCD-Konfiguration für Debuggingeinstellungen führt. Dies bedeutet, dass die Konfiguration für einen zusätzlichen PF für den Start beständig sein muss.
Der KDNET 2PF sollte nur vom Debugger verwendet werden, um sicherzustellen, dass kein anderer Windows/UEFI-Ethernet-Treiber über den PCI 2PF-Speicherort zugreift/ausgeführt wird, wenn der Debugger das Debuggerät besitzt (der 2PF-Speicherort wird mit dbgsettings::busparams konfiguriert).
Windows- oder UEFI-Ethernet-Treiber können nicht aus dem hinzugefügten KDNET 2PF ausgehen, auch wenn KDNET nicht im System aktiviert ist.
Das 2PF-Feature sollte einen dynamischen Mechanismus zum Hinzufügen/Aktivieren und Entfernen/Deaktivieren der Funktionalität auf der aktuellen NIC unterstützen.
Die Windows-Miniporttreiber implementieren das 2PF-Feature über die Wartung der folgenden NDIS-OIDs.
OID-Name | Beschreibung |
---|---|
OID_KDNET_ENUMERATE_PFS | Listet PFs auf dem aktuellen bus.dev.fun (BDF) auf, wobei der Miniporttreiber ausgeführt wird. |
OID_KDNET_ADD_PF | Fügt eine PF zur aktuellen BDF hinzu, wobei der Miniporttreiber ausgeführt wird. |
OID_KDNET_REMOVE_PF | Entfernt die hinzugefügte PF aus dem übergebenen BDF. |
OID_KDNET_QUERY_PF_INFORMATION | Fragt PF-Informationsdaten aus dem übergebenen BDF ab. |
Die OIDs und ihre Strukturen werden in ntddndis.h- und kdnetpf.h-Dateien definiert, die mit dem öffentlichen WDK veröffentlicht werden.
Weitere Informationen zu den Eingabe-/Ausgabeparametern für die einzelnen OID und die Informationen in der Headerdatei "kdnetpf.h" finden Sie unten.
- KDNET sollte über das KDNET 2PF-Feature auf NICS konfiguriert werden, wobei mehrere PF-Funktionen verfügbar sind, und die NIC ermöglicht die 2PF-Funktionalität, indem alle oben beschriebenen Anforderungen erfüllt werden.
KDNET Multiple PF Interface für Windows NIC-Treiber
Zur Unterstützung der KDNET Multiple PF Interface Miniport-Treiber müssen die Behandlung der folgenden vier NDIS-OIDs implementiert werden.
OID_KDNET_ENUMERATE_PFS
OID_KDNET_ADD_PF
OID_KDNET_REMOVE_PF
OID_KDNET_QUERY_PF_INFORMATION
Diese OIDs und Strukturen werden in den Dateien ntddndis.h und kdnetpf.h in der öffentlichen WDK-Version auf diesem Pfad aufgefüllt:
<WDK root directory>\ddk\inc\ndis
Diese Dateien sind auch im Windows SDK verfügbar und finden Sie in diesem Verzeichnis.
\Program Files (x86)\Windows Kits\10\Include\<Version for example 10.0.21301.0>\shared
Das Clienttool (kdnet.exe) verwendet ein privates NDIS IOCTL, um die KDNET 2PF NDIS OIDs an die Miniporttreiber weiterzuleiten.
Die Mehrfach-PF-Funktion NDIS-OIDs
Das Feature "Multiple PF" wird mit diesen vier NDIS-OIDs betrieben.
1. Aufzählen von PFs auf dem primären Miniport-BDF-Port mithilfe von OID: OID_KDNET_ENUMERATE_PFS, siehe Definition unten.
OID_KDNET_ENUMERATE_PFS gibt eine Liste aller BDFs zurück, die dem angegebenen primären Port zugeordnet sind, von dem der Miniporttreiber ausgeführt wird. Der Port wird durch die bus.dev.fun (BDF) dargestellt. Der Vorgang listet/listet die Liste der PFs auf, die nur dem bus.dev.fun (BDF-Port) zugeordnet sind, von dem aus der Miniporttreiber auf dem System ausgeführt wird, da jeder Miniporttreiber seinen BDF-Speicherort bestimmen kann.
Die Liste der PFs wird über einen NDIS-Abfragevorgang an den Client zurückgegeben.
Das OID_KDNET_ENUMERATE_PFS OID ist der NDIS_KDNET_ENUMERATE_PFS Struktur zugeordnet.
Der OID_KDNET_ENUMERATE_PFS Treiberhandler gibt einen Puffer zurück, der die Liste der PFs mit jedem PF-Element enthält, das vom Typ NDIS_KDNET_PF_ENUM_ELEMENT beschrieben wird.
Das Feld "PfNumber" enthält die PF-Funktionsnummer (z. B. bus.dev).Spaß)
Das Feld "PfState" enthält den PF-Zustand, der mögliche Werte enthält. Jeder Elementtyp, der durch NDIS_KDNET_PF_STATE Enumeration beschrieben wird.
NDIS_KDNET_PF_STATE::NdisKdNetPfStatePrimary – Dies ist eine primäre PF und wird normalerweise nur vom Miniporttreiber verwendet.
NDIS_KDNET_PF_STATE::NdisKdnetPfStateEnabled – Dies ist eine hinzugefügte sekundäre PF, die von KDNET verwendet wird.
NDIS_KDNET_PF_STATE::NdisKdnetPfStateConfigured – Dies ist eine hinzugefügte PF, aber sie wird nur hinzugefügt/konfiguriert und wird nicht verwendet.
Wenn die Größe des PF-Listenausgabepuffers nicht groß genug ist, um die tatsächliche PFs-Liste zuzuweisen, muss der OID-Handler fehlerrückgabewert zusammen mit der erforderlichen Puffergröße zurückgeben
E_NOT_SUFFICIENT_BUFFER
, damit das Clienttool den erforderlichen Größenpuffer zuordnen kann, und der Client kann dann einen weiteren Aufruf mit der richtigen Puffergröße vornehmen. Darüber hinaus sollte das OID-Anforderungsstatusfeld (beschrieben durch NDIS_IOCTL_OID_REQUEST_INFO.status) auf "gleich"NDIS_STATUS_BUFFER_TOO_SHORT
festgelegt werden.
2. Hinzufügen von PCI PF zum primären Miniport-BDF-Port (OID: OID_KDNET_ADD_PF, siehe Definition unten)
Fügen Sie einen PF zum primären Miniportport hinzu. Der Port wird durch die BDF dargestellt.
Die neu hinzugefügte PF wird über einen NDIS-Abfragevorgang an den Client zurückgegeben.
Die OID_KDNET_ADD_PF OID ist der NDIS_KDNET_ADD_PF Struktur zugeordnet.
Der OID_KDNET_ADD_PF Treiberhandler gibt eine ULONG zurück, die die hinzugefügte PF-Funktionsnummer enthält.
Diese OID-Anforderung hat nur einen Ausgabeparameter:
AddedFunctionNumber
. DerAddedFunctionNumber
Wert der hinzugefügten Funktionsnummer an der Miniport-PCI-Position (BDF-Miniport). Das kdnet.exe Hilfsprogramm erhält diesen Wert und setup dbgsettings::busparams auf die hinzugefügte PF.
Hinweis
Die hinzugefügte PF kann ausschließlich von KDNET verwendet werden, sodass Windows NIC-Treiber so manipuliert werden, dass *NOT* explizit auf einem hinzugefügten PF ausgeführt wird. Dies gilt auch, wenn KDNET auf dem System aktiviert ist und die PF dem Port hinzugefügt wurde.
3. Entfernen SIE PCI PF (OID: OID_KDNET_REMOVE_PF, siehe Definition unten)
Entfernen Sie eine PF aus dem angegebenen Port. Der Port wird durch die BDF dargestellt.
Das OID_KDNET_REMOVE_PF OID ist der NDIS_KDNET_REMOVE_PF Struktur zugeordnet.
Die OID_KDNET_REMOVE_PF OID verfügt über einen BDF-Eingabeport und gibt eine ULONG zurück, die die entfernte PF-Funktionsnummer über einen NDIS-Methodenvorgang enthält.
Diese Funktion ist nur auf den PFs erfolgreich, die mithilfe des OID_KDNET_ADD_PF OID hinzugefügt wurden.
Diese OID-Anforderung verfügt über den BDF-Eingabeport, von dem die BDF entfernt werden muss. Diese Funktion weist einen Output-Parameter von
FunctionNumber
. Die AusgabeFunctionNumber
enthält den entfernten Funktionsnummernwert.
4. Abfrage PCI PF-Informationen (OID: OID_KDNET_QUERY_PF_INFORMATION, siehe Definition unten)
Dieser OID-Code ermöglicht das Abfragen bestimmter PF-Daten für einen bestimmten Port. Der Port wird durch die BDF dargestellt.
Die angeforderten PF-Informationen werden über einen NDIS-Methodenvorgang an den Client zurückgegeben.
Das OID_KDNET_QUERY_PF_INFORMATION OID ist der NDIS_KDNET_QUERY_PF_INFORMATION Struktur zugeordnet.
Der OID_KDNET_QUERY_PF_INFORMATION OID verfügt über einen BDF-Eingabeport und gibt einen Puffer zurück, der die folgenden Daten enthält:
MAC-Adresse: Netzwerkadresse des zugewiesenen neuen KDNET PF, falls vorhanden.
Verwendungstag: Beschreibt die Entität, die den PF-Port besitzt. Sie enthält einen konstanten Wert, der durch NDIS_KDNET_PF_USAGE_TAG Enumeration beschrieben wird.
Maximale Anzahl von PFs: Enthält eine ULONG mit der maximalen Anzahl von PFs, die der angegebenen BDF hinzugefügt werden können.
Geräte-ID: Enthält die Geräte-ID, die dem angegebenen BDF-Port zugeordnet ist. Dies ist für Fälle erforderlich, in denen die NIC FW dem neuen hinzugefügten KDNET PF-Port eine neue Geräte-ID zuweist.
Diese OID fordert die Informationen für alle übergebenen BDF-Port an (BDF ist ein Eingabeparameter für diesen Vorgang), sodass sie nicht unbedingt mit der aktuellen BDF verbunden ist, von der der Treiber ausgeführt wird.
NDIS OIDs für KDNET auf 2PF
Die Datei Ntddndis.h definiert die OIDs.
#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)
Die Datei "Kdnetpf.h " beschreibt den Typ und die Strukturen, die den NDIS-OIDs zugeordnet sind.
#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)