Supporto KDNET del debugger 2PF

In questo argomento viene descritto come abilitare il driver NDIS miniport per il supporto del debugger 2PF per consentire prestazioni migliori per schede ad alta velocità, spesso usate nei data center. Questa funzionalità è disponibile in Windows 11 e versioni successive.

Quando si abilita il debug del kernel in una scheda di interfaccia di rete, il supporto per il debug del kernel assume il controllo del dispositivo fisico per fornire sia il debug del kernel che la connessione di rete nella casella. Ciò funziona correttamente sulle schede di interfaccia di rete a larghezza di banda ridotta (1-10 Gbps), ma su dispositivi con velocità effettiva elevata che supportano 10-40 Gbps, i moduli di estendibilità del kernel che comunicano con l'hardware in genere non possono tenere il passo con la quantità di traffico proveniente dallo stack di rete Di Windows, quindi questo riduce le prestazioni complessive del sistema.

L'uso della funzionalità PCI multiple Physical Function (PF) per KDNET consente di abilitare il debug senza alcun impatto sulle prestazioni.

La funzione fisica (PF) è una funzione PCI Express (PCIe) di una scheda di rete che supporta l'interfaccia SR-IOV (Single Root I/O Virtualization). Il pf include la funzionalità estesa SR-IOV nello spazio di configurazione PCIe. La funzionalità viene usata per configurare e gestire la funzionalità SR-IOV della scheda di rete, ad esempio l'abilitazione della virtualizzazione e l'esposizione di funzioni virtuali PCIe.

Il pf supporta la struttura di funzionalità estesa SR-IOV nello spazio di configurazione PCIe. Questa struttura è definita nella specifica PCI-SIG Single Root I/O Virtualization and Sharing 1.1.

Il trasporto del debugger sfrutta i vantaggi di più driver miniport abilitati per 2PF o 2PF. Per consentire il debug di sistemi di server ad alta velocità, è consigliabile che i fornitori di schede di interfaccia di rete consentano 2PF in tutte le schede di interfaccia di rete che supportano più pf nel firmware della scheda di rete.

Per informazioni sulla configurazione del supporto 2PF per testare una connessione, vedere Configurazione del debug in modalità kernel 2PF con KDNET.

Panoramica dell'architettura PF KDNET multipla

  • La funzionalità Multiple PF (2PF) consiste nell'aggiungere/assegnare un nuovo PF alla porta di rete PCI originale(ad esempio Bus.dev.fun0.0).

  • Il nuovo pf aggiunto (ad esempio bus.dev.fun0.1) viene usato solo da KDNET per instradare i pacchetti debugger verso/dalla destinazione.

  • Il file PF originale verrà usato dal driver NIC della posta in arrivo di Windows per instradare i pacchetti di rete di Windows (TCP/IP).

  • L'uso di questo approccio consente a entrambi i driver di funzionare in parallelo con l'interferimento tra loro.

  • Entrambi i driver verranno eseguiti sullo spazio di configurazione PCI partizionato

    • Il driver Di Windows Inbox verrà esaurito dalla porta di rete originale in bus.dev.fun0.0

    • KDNET-KDNET-Ext. il modulo verrà esaurito dal pf aggiunto in bus.dev.fun0.1, in questo modo si garantisce che il driver della scheda di interfaccia di rete posta in arrivo di Windows non venga influenzato dalla condivisione della scheda di interfaccia di rete con KDNET.

  • Lo strumento kdnet.exe modalità utente configura la funzionalità 2PF usando il driver Posta in arrivo di Windows aggiungendo codici IOCTL specifici per aggiungere/rimuovere KDNET PF.

Diagramma che mostra due stack di rete, uno che supporta 2PF usando una configurazione combinata di schede PCI.

Requisiti di progettazione delle funzionalità PFS multipli

  1. La funzionalità KDNET 2PF deve funzionare per tutti gli scenari KD correnti, ad esempio gestione avvio, caricatore del sistema operativo, WinResume, Hyper-V, SK e così via, sistema operativo NT o Windows Desktop.

  2. Il riavvio del sistema sarà necessario quando si aggiunge un nuovo pf per un dispositivo viene apportata una modifica necessaria alla configurazione BCD per le impostazioni di debug. Ciò significa che la configurazione per un pf aggiuntivo deve essere persistente tra gli avvio.

  3. KDNET 2PF deve essere usato solo dal debugger per assicurarsi che non siano presenti altri driver Ethernet Windows/UEFI che accedono/eseguono dal percorso PCI 2PF quando il debugger possiede il dispositivo di debug (il percorso 2PF è configurato usando dbgsettings::busparams).

  4. I driver Ethernet Windows o UEFI non possono esaurire il KDNET 2PF aggiunto anche quando KDNET non è abilitato nel sistema.

  5. La funzionalità 2PF deve supportare un meccanismo dinamico per l'aggiunta/abilitazione e la rimozione/disabilitazione della funzionalità nella scheda di interfaccia di rete corrente.

  6. I driver miniport di Windows implementeranno la funzionalità 2PF tramite la manutenzione degli NDIS OID seguenti.

Nome OID Descrizione
OID_KDNET_ENUMERATE_PFS Enumera i file PFS nella bus.dev.fun corrente (BDF), in cui è in esecuzione il driver miniport.
OID_KDNET_ADD_PF Aggiunge un pf alla funzione BDF corrente, in cui è in esecuzione il driver miniport.
OID_KDNET_REMOVE_PF Rimuove il file PF aggiunto dall'oggetto passato in BDF.
OID_KDNET_QUERY_PF_INFORMATION Esegue una query sui dati delle informazioni PF dall'oggetto passato in BDF.

Gli OID e le relative strutture sono definiti nei file ntddndis.h e kdnetpf.h rilasciati con il WDK pubblico.

Vedere i dettagli seguenti sui parametri input/output per ogni OID e le informazioni fornite nel file di intestazione kdnetpf.h.

  1. KDNET deve essere configurato tramite la funzionalità KDNET 2PF in NICS in cui è disponibile più funzionalità PF e la scheda di interfaccia di rete abilita la funzionalità 2PF seguendo tutti i requisiti descritti in precedenza.

Interfaccia PF multipla KDNET per i driver della scheda di interfaccia di rete di Windows

Per supportare i driver Miniport interfaccia PF multiple KDNET dovranno implementare la gestione dei quattro NDIS OID seguenti.

  • OID_KDNET_ENUMERATE_PFS

  • OID_KDNET_ADD_PF

  • OID_KDNET_REMOVE_PF

  • OID_KDNET_QUERY_PF_INFORMATION

Questi ID e strutture vengono popolati nei file ntddndis.h e kdnetpf.h nella versione WDK pubblica in questo percorso:

<WDK root directory>\ddk\inc\ndis

Questi file sono disponibili anche in Windows SDK e sono disponibili in questa directory.

\Program Files (x86)\Windows Kits\10\Include\<Version for example 10.0.21301.0>\shared

Lo strumento client (kdnet.exe) usa un IOCTL NDIS privato per instradare gli ID NDIS KDNET 2PF ai driver miniport.

Id NDIS con più funzionalità PF

La funzionalità Multiple PF viene gestita usando questi quattro OID NDIS.

1. Enumerare i file PFS sulla porta primaria BDF miniport usando OID: OID_KDNET_ENUMERATE_PFS, vedere la definizione seguente.

  • OID_KDNET_ENUMERATE_PFS restituisce un elenco di tutti i file BDF associati alla porta primaria specificata da cui viene eseguito il driver miniport. La porta è rappresentata dal bus.dev.fun (BDF). L'operazione elenca/enumera l'elenco di file PDF associati solo alla bus.dev.fun (porta BDF) da cui il driver miniport è in esecuzione nel sistema, poiché ogni driver miniport può determinare la posizione BDF.

  • L'elenco di file PDF verrà restituito al client tramite un'operazione di query NDIS.

  • L'OID OID_KDNET_ENUMERATE_PFS è associato alla struttura NDIS_KDNET_ENUMERATE_PFS .

  • Il gestore driver OID_KDNET_ENUMERATE_PFS restituirà un buffer contenente l'elenco PFS con ogni elemento PF descritto dal tipo NDIS_KDNET_PF_ENUM_ELEMENT.

    Il campo PfNumber contiene il numero di funzione PF, ad esempio bus.dev.divertimento)

    Il campo PfState contiene i valori possibili dello stato PF, ovvero ogni tipo di elemento descritto da NDIS_KDNET_PF_STATE enumerazione.

    NDIS_KDNET_PF_STATE::NdisKdNetPfStatePrimary : si tratta di un pf primario e viene in genere usato solo dal driver miniport.

    NDIS_KDNET_PF_STATE::NdisKdnetPfStateEnabled : si tratta di un pf secondario aggiunto, usato da KDNET.

    NDIS_KDNET_PF_STATE::NdisKdnetPfStateConfigured : si tratta di un pf aggiunto, ma viene aggiunto/configurato e non viene usato.

  • Se le dimensioni del buffer di output dell'elenco PF non sono sufficienti per allocare l'elenco PFS effettivo, il gestore OID deve restituire E_NOT_SUFFICIENT_BUFFER il valore restituito dell'errore, insieme alle dimensioni del buffer necessarie, in modo che lo strumento client possa allocare il buffer di dimensioni necessarie e quindi il client può effettuare un'altra chiamata con la dimensione corretta del buffer allocata. Inoltre, il campo di stato della richiesta OID (descritto da NDIS_IOCTL_OID_REQUEST_INFO.status) deve essere impostato su uguale a NDIS_STATUS_BUFFER_TOO_SHORT.

2. Aggiungere PCI PF alla porta primaria BDF miniport (OID: OID_KDNET_ADD_PF, vedere la definizione seguente)

  • Aggiungere un pf alla porta primaria miniport. La porta è rappresentata dalla funzione BDF.

  • Il pf appena aggiunto verrà restituito al client tramite un'operazione di query NDIS.

  • L'OID OID_KDNET_ADD_PF è associato alla struttura NDIS_KDNET_ADD_PF .

  • Il gestore del driver OID_KDNET_ADD_PF restituirà un ULONG contenente il numero di funzione PF aggiunto .

  • Questa richiesta OID avrà un solo parametro di output: AddedFunctionNumber. Indica AddedFunctionNumber il valore del numero di funzione aggiunto nella posizione PCI miniport (miniport BDF). L'utilità kdnet.exe riceverà questo valore e imposta dbgsettings::busparams in modo che punti al file PF aggiunto.

Nota

Il file PF aggiunto può essere usato esclusivamente da KDNET, quindi i driver della scheda di interfaccia di rete di Windows vengono eseguiti espressamente *NOT* su un pf aggiunto, quindi questo vale anche quando KDNET è *NOT* abilitato nel sistema e il file PF è stato aggiunto alla porta.

3. Rimuovere PCI PF (OID: OID_KDNET_REMOVE_PF, vedere la definizione seguente)

  • Rimuovere un pf dalla porta specificata. La porta è rappresentata dalla funzione BDF.

  • L'OID OID_KDNET_REMOVE_PF è associato alla struttura NDIS_KDNET_REMOVE_PF .

  • L'OID OID_KDNET_REMOVE_PF ha una porta BDF di input e restituisce un ULONG contenente il numero di funzione PF rimosso tramite un'operazione del metodo NDIS.

  • Questa funzione avrà esito positivo solo sui file PDF aggiunti tramite l'OID OID_KDNET_ADD_PF .

  • Questa richiesta OID avrà la porta BDF di input da cui deve essere rimossa la funzione BDF. Questa funzione ha un parametro Output di FunctionNumber. L'output FunctionNumber conterrà il valore del numero di funzione rimosso.

4. Eseguire query sulle informazioni PF PCI (OID: OID_KDNET_QUERY_PF_INFORMATION, vedere la definizione seguente)

  • Questo codice OID consente di eseguire query su dati PF specifici su una determinata porta. La porta è rappresentata dalla funzione BDF.

  • Le informazioni PF richieste verranno restituite al client tramite un'operazione del metodo NDIS.

  • L'OID OID_KDNET_QUERY_PF_INFORMATION è associato alla struttura NDIS_KDNET_QUERY_PF_INFORMATION .

  • L'OID OID_KDNET_QUERY_PF_INFORMATION ha una porta BDF di input e restituisce un buffer contenente i dati seguenti:

    • Indirizzo MAC: indirizzo di rete del nuovo pf KDNET assegnato, se presente.

    • Tag di utilizzo: descrive l'entità proprietaria della porta PF. Contiene un valore costante descritto da NDIS_KDNET_PF_USAGE_TAG enumerazione.

    • Numero massimo di PFS: contiene una ULONG con il numero massimo di PFS che è possibile aggiungere alla funzione BDF specificata.

    • ID dispositivo: contiene l'ID dispositivo associato alla porta BDF specificata. Questa operazione è necessaria per i casi in cui il fw della scheda di interfaccia di rete assegna un nuovo ID dispositivo alla nuova porta PF KDNET aggiunta.

  • Questo OID richiede le informazioni per qualsiasi porta BDF passata (BDF è un parametro di input per questa operazione), quindi non è necessariamente correlato alla funzione BDF corrente da cui viene eseguito il driver.

NDIS OID per KDNET su 2PF

Il file Ntddndis.h definisce gli ID predefiniti.

#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)

Il file Kdnetpf.h descrive il tipo e le strutture associate agli ID NDIS.

#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)

Vedi anche

Configurazione del debug in modalità kernel 2PF con KDNET

ID di rete

Intestazione kdnetpf.h