Bagikan melalui


Dukungan Debugger 2PF KDNET

Topik ini menjelaskan cara mengaktifkan driver NDIS miniport Anda untuk dukungan debugger 2PF untuk memungkinkan peningkatan performa untuk adaptor kecepatan tinggi, sering digunakan di pusat data. Fitur ini tersedia di Windows 11 dan yang lebih baru.

Saat mengaktifkan debugging kernel pada NIC, dukungan debugging kernel mengambil alih kendali perangkat fisik untuk menyediakan debugging kernel dan koneksi jaringan pada sistem. Ini berfungsi dengan baik pada NIC dengan bandwidth rendah untuk konsumen (1-10 Gbps), tetapi pada perangkat berdaya pengiriman tinggi yang mendukung 10-40+ Gbps, modul ekstensibilitas debugging kernel yang berkomunikasi dengan perangkat keras umumnya tidak dapat mengimbangi jumlah lalu lintas dari tumpukan jaringan Windows, sehingga menurunkan performa sistem secara keseluruhan.

Menggunakan fitur PCI multiple Physical Function (PF) untuk KDNET memungkinkan debugging diaktifkan dengan dampak performa yang hampir tidak ada.

Fungsi Fisik (PF) adalah fungsi PCI Express (PCIe) dari adaptor jaringan yang mendukung antarmuka virtualisasi I/O root tunggal (SR-IOV). PF mencakup Kemampuan Ekstensi SR-IOV dalam ruang Konfigurasi PCIe. Kemampuan ini digunakan untuk mengonfigurasi dan mengelola fungsionalitas SR-IOV adaptor jaringan, seperti mengaktifkan virtualisasi dan mengekspos Fungsi Virtual PCIe (VF).

PF mendukung struktur SR-IOV Extended Capability di ruang konfigurasi PCIe-nya. Struktur ini didefinisikan dalam spesifikasi Virtualisasi Akar Tunggal I/O dan Berbagi 1.1 PCI-SIG.

Transport debugger akan memanfaatkan driver miniport yang kompatibel dengan beberapa driver atau diaktifkan dengan fitur 2PF. Untuk memungkinkan debugging sistem server berkecepatan tinggi, disarankan agar vendor NIC mengaktifkan 2PF di semua NIC yang mendukung beberapa PF di firmware kartu jaringan.

Untuk informasi tentang mengonfigurasi dukungan 2PF untuk menguji koneksi, lihat Menyiapkan 2PF Kernel-Mode Debugging menggunakan KDNET.

Beberapa gambaran umum arsitektur PF KDNET

  • Fungsionalitas Multiple PF (2PF) adalah menambahkan/menetapkan PF baru ke port jaringan PCI asli (misalnya Bus.dev.fun0.0).

  • PF baru yang ditambahkan (misalnya bus.dev.fun0.1) hanya digunakan oleh KDNET untuk merutekan paket Debugger ke/dari target.

  • PF asli akan digunakan oleh driver NIC kotak masuk Windows untuk merutekan paket jaringan Windows (TCP/IP) .

  • Menggunakan pendekatan ini kedua pengendali dapat bekerja secara paralel tanpa mengganggu pekerjaan satu sama lain.

  • Kedua driver akan berjalan di atas ruang konfigurasi PCI yang dipartisi

    • Driver Windows Inbox akan kehabisan port jaringan asli pada bus.dev.fun0.0

    • KDNET-KDNET-Ext. modul akan kehabisan PF yang ditambahkan pada bus.dev.fun0.1, Cara ini memastikan bahwa driver NIC kotak masuk Windows tidak terpengaruh dengan berbagi NIC dengan KDNET.

  • Alat mode pengguna kdnet.exe mengonfigurasi fitur 2PF menggunakan driver kotak masuk Windows dengan menambahkan kode IOCTL tertentu untuk menambahkan/menghapus KDNET PF.

Diagram yang memperlihatkan dua tumpukan jaringan, dengan salah satunya mendukung 2PF melalui konfigurasi gabungan kartu PCI.

Persyaratan desain untuk beberapa PF

  1. Fitur KDNET 2PF perlu berfungsi untuk semua skenario KD saat ini baik itu OS pra-NT (misalnya Boot Manager, OS loader, WinResume, Hyper-V, SK, dll.), NT OS, atau Windows Desktop.

  2. Memulai ulang sistem akan diperlukan ketika menambahkan PF baru ke perangkat yang mengakibatkan perubahan yang diperlukan pada konfigurasi BCD untuk pengaturan debugging. Ini berarti bahwa konfigurasi untuk PF tambahan harus persisten di seluruh boot.

  3. KDNET 2PF harus digunakan hanya oleh debugger untuk memastikan bahwa tidak ada driver ethernet Windows/UEFI lainnya yang mengakses/menjalankan dari lokasi PCI 2PF ketika debugger memiliki perangkat debug (lokasi 2PF dikonfigurasi menggunakan dbgsettings::busparams).

  4. Driver Windows atau UEFI Ethernet tidak dapat kehabisan KDNET 2PF yang ditambahkan bahkan ketika KDNET tidak diaktifkan dalam sistem.

  5. Fitur 2PF harus mendukung mekanisme dinamis untuk menambahkan/mengaktifkan dan menghapus/menonaktifkan fungsionalitas pada NIC saat ini.

  6. Driver miniport Windows akan mengimplementasikan fitur 2PF melalui layanan OID NDIS berikut.

Nama OID Deskripsi
OID_KDNET_ENUMERATE_PFS Mendaftar PF pada bus.dev.fun (BDF) saat ini, tempat driver miniport berjalan.
OID_KDNET_ADD_PF Menambahkan PF ke BDF saat ini, tempat driver miniport berjalan.
OID_KDNET_REMOVE_PF Menghapus PF yang ditambahkan dari BDF yang diberikan.
OID_KDNET_QUERY_PF_INFORMATION Mengkueri data informasi PF dari yang diteruskan di BDF.

OID dan strukturnya didefinisikan dalam file ntddndis.h dan kdnetpf.h yang dirilis dengan WDK publik.

Lihat detail di bawah ini tentang parameter Input/Output untuk setiap OID dan informasi yang disediakan dalam file header kdnetpf.h.

  1. KDNET harus dikonfigurasi melalui fitur KDNET 2PF pada NICS di mana beberapa fitur PF tersedia, dan NIC mengaktifkan fungsionalitas 2PF dengan mengikuti semua persyaratan yang dijelaskan di atas.

Antarmuka PF Ganda KDNET untuk Driver NIC Windows

Untuk mendukung driver KDNET Multiple PF Interface Miniport perlu menerapkan penanganan empat OID NDIS berikut.

  • OID_KDNET_ENUMERATE_PFS

  • OID_KDNET_ADD_PF

  • OID_KDNET_REMOVE_PF

  • OID_KDNET_QUERY_PF_INFORMATION

OID dan struktur ini diisi dalam file ntddndis.h dan kdnetpf.h dalam rilis WDK publik pada jalur ini:

<WDK root directory>\ddk\inc\ndis

File-file ini juga tersedia di Windows SDK, dan dapat ditemukan di direktori ini.

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

Alat klien (kdnet.exe) menggunakan IOCTL NDIS privat untuk merutekan OID NDIS KDNET 2PF ke driver miniport.

Fitur Multiple PF OID NDIS

Fitur Multiple PF dioperasikan dengan menggunakan keempat OID NDIS ini.

1. Hitung PFs pada port utama miniport BDF menggunakan OID: OID_KDNET_ENUMERATE_PFS, lihat definisi berikut.

  • OID_KDNET_ENUMERATE_PFS mengembalikan daftar semua BDF yang terkait dengan port utama yang diberikan dari tempat driver miniport berjalan. Pelabuhan diwakili oleh bus.dev.fun (BDF). Operasi ini akan mencantumkan/menghitung daftar PDF yang hanya terkait ke bus.dev.fun (port BDF) dari mana driver miniport berjalan pada sistem, karena setiap driver miniport dapat menentukan lokasi BDF-nya.

  • Daftar PF akan dikembalikan ke klien melalui operasi NDIS Query.

  • OID OID_KDNET_ENUMERATE_PFS terkait dengan struktur NDIS_KDNET_ENUMERATE_PFS.

  • Handler driver OID_KDNET_ENUMERATE_PFS akan mengembalikan buffer yang berisi daftar PF dengan setiap elemen PF yang dijelaskan oleh tipe NDIS_KDNET_PF_ENUM_ELEMENT.

    Bidang PfNumber berisi Nomor Fungsi PF, (misalnya bus.dev.menyenangkan)

    Bidang PfState berisi nilai status PF yang mungkin- setiap jenis elemen yang dijelaskan oleh enum NDIS_KDNET_PF_STATE.

    NDIS_KDNET_PF_STATE::NdisKdNetPfStatePrimary - Ini adalah PF utama dan biasanya hanya digunakan oleh driver miniport.

    NDIS_KDNET_PF_STATE::NdisKdnetPfStateEnabled - Ini adalah PF sekunder tambahan, yang digunakan oleh KDNET.

    NDIS_KDNET_PF_STATE::NdisKdnetPfStateConfigured - Ini adalah PF tambahan, tetapi hanya ditambahkan/dikonfigurasi dan tidak digunakan.

  • Jika ukuran buffer output daftar PF tidak cukup besar untuk mengalokasikan daftar PF aktual, maka handler OID perlu mengembalikan nilai kesalahan E_NOT_SUFFICIENT_BUFFER, bersama dengan ukuran buffer yang diperlukan, sehingga alat klien dapat mengalokasikan buffer dengan ukuran yang dibutuhkan, dan kemudian klien dapat melakukan panggilan lain setelah ukuran buffer yang sesuai telah dialokasikan. Selain itu, bidang status permintaan OID (dijelaskan oleh NDIS_IOCTL_OID_REQUEST_INFO.status) harus diatur agar sama dengan NDIS_STATUS_BUFFER_TOO_SHORT.

2. Tambahkan PCI PF ke port utama BDF miniport (OID: OID_KDNET_ADD_PF, lihat definisi di bawah)

  • Tambahkan PF ke port utama miniport. Port diwakili oleh BDF.

  • PF yang baru ditambahkan akan dikembalikan ke klien melalui operasi Kueri NDIS.

  • OID OID_KDNET_ADD_PF dikaitkan dengan struktur NDIS_KDNET_ADD_PF.

  • Handler driver OID_KDNET_ADD_PF akan mengembalikan ULONG yang berisi menambahkan nomor fungsi PF.

  • Permintaan OID ini hanya akan memiliki satu parameter Output: AddedFunctionNumber. AddedFunctionNumber menunjukkan nilai nomor Fungsi yang ditambahkan pada lokasi PCI miniport (BDF miniport). Utilitas kdnet.exe akan menerima nilai ini dan mengatur dbgsettings::busparams untuk menunjuk ke PF yang ditambahkan.

Nota

PF yang ditambahkan dapat digunakan secara eksklusif oleh KDNET, sehingga driver Windows NIC dikonfigurasi secara khusus agar tidak berjalan pada PF tambahan. Ini juga berlaku ketika KDNET tidak diaktifkan pada sistem dan PF telah ditambahkan ke port.

3. Hapus PCI PF (OID: OID_KDNET_REMOVE_PF, lihat definisi di bawah )

  • Hapus PF dari port yang telah ditentukan. Port diwakili oleh BDF.

  • OID OID_KDNET_REMOVE_PF terkait dengan struktur NDIS_KDNET_REMOVE_PF.

  • OID OID_KDNET_REMOVE_PF memiliki port BDF input dan mengembalikan ULONG yang berisi dihapus nomor fungsi PF melalui operasi Metode NDIS.

  • Fungsi ini hanya akan berhasil pada PF yang telah ditambahkan dengan menggunakan OID_KDNET_ADD_PF OID.

  • Permintaan OID ini akan memiliki port BDF input dari mana BDF perlu dihapus. Fungsi ini memiliki parameter Output FunctionNumber. Output FunctionNumber akan berisi nilai nomor Fungsi yang dihapus.

4. Mengkueri informasi PF PCI (OID: OID_KDNET_QUERY_PF_INFORMATION, lihat definisi di bawah)

  • Kode OID ini memungkinkan pengambilan data PF tertentu pada port yang ditentukan. Port diwakili oleh BDF.

  • Informasi PF yang diminta akan dikembalikan ke klien melalui operasi Metode NDIS.

  • OID OID_KDNET_QUERY_PF_INFORMATION dikaitkan dengan struktur NDIS_KDNET_QUERY_PF_INFORMATION.

  • OID OID_KDNET_QUERY_PF_INFORMATION memiliki port BDF input dan mengembalikan buffer yang berisi data berikut:

    • Alamat MAC: Alamat jaringan PF KDNET baru yang ditetapkan jika ada.

    • Tag Penggunaan: Menjelaskan entitas yang memiliki port PF. Ini berisi nilai konstan yang dijelaskan oleh enum NDIS_KDNET_PF_USAGE_TAG.

    • Jumlah Maksimum PF: Berisi ULONG dengan jumlah maksimum PF yang dapat ditambahkan ke BDF yang diberikan.

    • ID Perangkat: Berisi ID perangkat yang terkait dengan port BDF yang diberikan. Ini diperlukan untuk kasus di mana NIC FW menetapkan ID perangkat baru ke port PF KDNET baru yang ditambahkan.

  • OID ini meminta informasi mengenai semua port BDF yang diteruskan (BDF adalah parameter input untuk operasi ini), oleh karena itu tidak selalu terkait dengan BDF saat ini dari mana driver berjalan.

OID NDIS untuk KDNET di 2PF

file Ntddndis.h mendefinisikan 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)

file Kdnetpf.h menjelaskan jenis dan struktur yang terkait dengan OID 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)

Lihat juga

Menyiapkan 2PF Kernel-Mode Debugging menggunakan KDNET

OID Jaringan

header kdnetpf.h