Поделиться через


Поддержка отладчика 2PF KDNET

В этом разделе описывается, как включить поддержку отладчика 2PF для минипорта NDIS, чтобы обеспечить повышенную производительность для высокоскоростных адаптеров, часто используемых в центрах обработки данных. Эта функция доступна в Windows 11 и более поздних версиях.

При включении отладки ядра в сетевом адаптере поддержка отладки ядра берет на себя физическое устройство, чтобы обеспечить отладку ядра и сетевое подключение в поле. Это хорошо работает на сетевых адаптерах с низкой пропускной способностью потребителей (1–10 Гбит/с), но на устройствах с высокой пропускной способностью, поддерживающих 10–40 Гбит/с, модули расширяемости ядра, которые разговаривают с оборудованием, как правило, не могут поддерживать объем трафика, поступающий из сетевого стека Windows, поэтому это снижает общую производительность системы.

Использование функции PCI с несколькими физическими функциями (PF) для KDNET позволяет включить отладку практически без влияния на производительность.

Физическая функция (PF) — это функция PCI Express (PCIe) сетевого адаптера, который поддерживает единый корневой интерфейс виртуализации ввода-вывода (SR-IOV). PF включает расширенную возможность SR-IOV в пространстве конфигурации PCIe. Эта возможность используется для настройки функций SR-IOV сетевого адаптера и управления ими, таких как включение виртуализации и предоставление виртуальных функций PCIe.

PF поддерживает структуру расширенных возможностей SR-IOV в пространстве конфигурации PCIe. Эта структура определена в спецификации PCI-SIG Single Root I/O Virtualization and Sharing 1.1.

Транспорт отладчика будет использовать несколько или 2PF-драйверов минипорта. Чтобы разрешить отладку систем высокоскоростных серверов, рекомендуется включить поставщики сетевых адаптеров 2PF во всех сетевых адаптерах, поддерживающих несколько PF в сетевом карта встроенного ПО.

Сведения о настройке поддержки 2PF для тестирования подключения см. в разделе Настройка отладки режима ядра 2PF с помощью KDNET.

Обзор архитектуры нескольких PF KDNET

  • Функция нескольких PF (2PF) — добавить или назначить новый PF для исходного сетевого порта PCI (например, Bus.dev.fun0.0).

  • Новый добавленный PF (например, bus.dev.fun0.1) используется только KDNET для маршрутизации пакетов отладчика в целевой объект или из нее.

  • Исходный PF будет использоваться драйвером сетевой карты для папки "Входящие" Windows для маршрутизации сетевых пакетов Windows (TCP/IP).

  • С помощью этого подхода оба драйвера могут работать параллельно в режиме w/o, мешая друг другу работать.

  • Оба драйвера будут выполняться по секционированного пространства конфигурации PCI

    • Драйвер папки "Входящие" Windows выйдет из исходного сетевого порта в bus.dev.fun0.0

    • KDNET-KDNET-Ext. модуль завершится из добавленного PF в bus.dev.fun0.1, таким образом гарантирует, что драйвер сетевой карты windows inbox не влияет на общий доступ к сетевому адаптеру с KDNET.

  • Средство kdnet.exe пользовательского режима настраивает функцию 2PF с помощью драйвера папки "Входящие", добавив определенные коды IOCTL для добавления и удаления KDNET PF.

Схема с двумя сетевыми стеками, одна поддерживающая 2PF с помощью объединенной настройки PCI карта.

Требования к проектированию функций нескольких PFS

  1. Функция KDNET 2PF должна работать для всех текущих сценариев KD, будь то предварительная ОС NT (например, диспетчер загрузки, загрузчик ОС, WinResume, Hyper-V, SK и т. д.), NT OS или Настольный компьютер Windows.

  2. Перезагрузка системы потребуется при добавлении нового PF для устройства, что приведет к изменению конфигурации BCD для отладки параметров. Это означает, что конфигурация дополнительного PF должна быть постоянной во время загрузки.

  3. KDNET 2PF следует использовать только отладчиком, чтобы убедиться, что в расположении PCI 2PF нет других драйверов Ethernet Windows/UEFI, работающих в расположении PCI 2PF, когда отладчик владеет отладочным устройством (расположение 2PF настроено с помощью dbgsettings::busparams).

  4. Драйверы Ethernet Windows или UEFI не могут выйти из добавленной KDNET 2PF, даже если KDNET не включена в системе.

  5. Функция 2PF должна поддерживать динамический механизм добавления и включения и удаления и отключения функциональных возможностей текущей сетевой карты.

  6. Драйверы мини-порта Windows реализуют функцию 2PF с помощью обслуживания следующих NDIS OID.

Имя OID Description
OID_KDNET_ENUMERATE_PFS Перечисляет PFs в текущем bus.dev.fun (BDF), где выполняется драйвер мини-порта.
OID_KDNET_ADD_PF Добавляет PF в текущий BDF, где выполняется минипорт-драйвер.
OID_KDNET_REMOVE_PF Удаляет добавленный PF из переданного в BDF.
OID_KDNET_QUERY_PF_INFORMATION Запрашивает данные сведений PF из переданного в BDF.

OIDs и их структуры определяются в файлах ntddndis.h и kdnetpf.h, выпущенных с общедоступным WDK.

Дополнительные сведения см. в параметрах входных и выходных данных для каждого OID и сведений, предоставленных в файле заголовка kdnetpf.h.

  1. KDNET следует настроить с помощью функции KDNET 2PF в сетевых адаптерах, где доступна несколько функций PF, а сетевой адаптер обеспечивает 2PF функциональные возможности, следуя всем описанным выше требованиям.

KDNET с несколькими интерфейсами PF для драйверов сетевого адаптера Windows

Для поддержки драйверов минипорта интерфейса KDNET Multiple PF потребуется реализовать обработку следующих четырех NDIS OID.

  • OID_KDNET_ENUMERATE_PFS

  • OID_KDNET_ADD_PF

  • OID_KDNET_REMOVE_PF

  • OID_KDNET_QUERY_PF_INFORMATION

Эти OID и структуры заполняются в файлах ntddndis.h и kdnetpf.h в общедоступном выпуске WDK по этому пути:

<WDK root directory>\ddk\inc\ndis

Эти файлы также доступны в пакете SDK для Windows и находятся в этом каталоге.

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

Клиентское средство (kdnet.exe) использует частный NDIS IOCTL для маршрутизации OIDNET 2PF NDIS на минипорт-драйверы.

Функция NDIS NDIS OIDs с несколькими PF

Функция нескольких PF управляется с помощью этих четырех NDIS OID.

1. Перечисление PFS на первичном порту минипорта BDF с помощью OID: OID_KDNET_ENUMERATE_PFS см. определение ниже.

  • OID_KDNET_ENUMERATE_PFS возвращает список всех BDFs, связанных с заданным основным портом, из которого работает мини-драйвер. Порт представлен bus.dev.fun (BDF). Операция будет перечислять список PFS, которые связаны только с bus.dev.fun (порт BDF), из которого выполняется мини-драйвер в системе, так как каждый драйвер мини-порта может определить свое расположение BDF.

  • Список PFS будет возвращен клиенту с помощью операции запроса NDIS.

  • OID_KDNET_ENUMERATE_PFS OID связан с структурой NDIS_KDNET_ENUMERATE_PFS.

  • Обработчик драйвера OID_KDNET_ENUMERATE_PFS возвращает буфер, содержащий список PFS с каждым элементом PF, описанным типом NDIS_KDNET_PF_ENUM_ELEMENT.

    Поле PfNumber содержит номер функции PF (например, bus.dev.весело)

    Поле PfState содержит возможные значения состояния PF— каждый тип элемента, описанный NDIS_KDNET_PF_STATE перечислением.

    NDIS_KDNET_PF_STATE::NdisKdNetPfStatePrimary — это основной PF, который обычно используется только драйвером минипорта.

    NDIS_KDNET_PF_STATE::NdisKdnetPfStateEnabled — это добавленный дополнительный PF, используемый KDNET.

    NDIS_KDNET_PF_STATE::NdisKdnetPfStateConfigured — это добавленная PF, но она только добавлена или настроена и не используется.

  • Если размер выходного буфера списка PF недостаточно велик, чтобы выделить фактический список PFS, обработчик OID должен возвращать E_NOT_SUFFICIENT_BUFFER возвращаемое значение ошибки вместе с требуемым размером буфера, поэтому клиентское средство может выделить необходимый буфер размера, а затем клиент может вызвать другой вызов с правильным размером буфера, выделенным. Кроме того, поле состояния запроса OID (описано NDIS_IOCTL_OID_REQUEST_INFO.status) должно быть равно NDIS_STATUS_BUFFER_TOO_SHORT.

2. Добавьте PCI PF в минипорт BDF основной порт (OID: OID_KDNET_ADD_PF, см. определение ниже)

  • Добавьте PF в основной порт мини-порта. Порт представлен BDF.

  • Добавленный PF будет возвращен клиенту с помощью операции запроса NDIS.

  • OID_KDNET_ADD_PF OID связан с структурой NDIS_KDNET_ADD_PF.

  • Обработчик драйвера OID_KDNET_ADD_PF вернет ULONG, содержащий добавленный номер функции PF.

  • Этот запрос OID будет иметь только один выходной параметр: AddedFunctionNumber. Указывает AddedFunctionNumber добавленное значение номера функции в расположении минипорта PCI (минипорт BDF). Программа kdnet.exe получит это значение и установит dbgsettings::busparams для точек на добавленный PF.

Примечание.

Добавленный PF можно использовать исключительно KDNET, поэтому драйверы сетевого адаптера Windows NIC автоматически выполняются в добавленном PF, поэтому это также применяется, если KDNET включена в системе, а 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 и возвращает ULONG, содержащий удаленный номер функции PF с помощью операции метода NDIS.

  • Эта функция будет выполнена успешно только на PFS, добавленных с помощью OID_KDNET_ADD_PF OID.

  • Этот запрос OID будет иметь входной порт BDF, из которого необходимо удалить BDF. Эта функция имеет выходной параметр 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 перечислением.

    • Максимальное число PFS: содержит ULONG с максимальным числом PFS, которые можно добавить в заданный BDF.

    • Идентификатор устройства: содержит идентификатор устройства, связанный с заданным портом BDF. Это необходимо для случаев, когда NIC FW назначает новый идентификатор устройства новому добавленного порта KDNET PF.

  • Этот OID запрашивает сведения для любого переданного порта BDF (BDF является входным параметром для этой операции), поэтому он не обязательно связан с текущим BDF, из которого работает драйвер.

NDIS OIDs для KDNET на 2PF

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)

См. также

Настройка отладки в режиме ядра 2PF с помощью KDNET

Сетевые OIDs

заголовок kdnetpf.h