Manajemen buffer data jaringan

Manajemen buffer adalah fitur yang memungkinkan driver klien Kartu Antarmuka Jaringan (NIC) dan sistem operasi untuk bekerja sama saat mengalokasikan buffer data paket dari memori sistem untuk jalur data transmisi (Tx) dan menerima (Rx). Ini dapat menghasilkan performa yang lebih cepat untuk NIC, manajemen seumur hidup memori yang lebih mudah untuk driver klien NIC, dan lebih banyak kontrol untuk sistem melalui memori.

Manfaat manajemen buffer di NetAdapterCx

Pilihan di mana buffer data dialokasikan dari memori sistem untuk payload paket sangat penting untuk performa jalur data. Di NetAdapterCx, model manajemen buffer dioptimalkan untuk perangkat keras NIC berkemampuan DMA, dan cara terbaik bagi driver klien untuk memanfaatkannya adalah dengan membiarkan sistem mengalokasikan buffer data atas nama mereka untuk jalur Tx dan Rx. Namun, driver klien masih dapat memengaruhi di mana dan bagaimana sistem mengalokasikan buffer data sehingga dapat dengan mudah dikonsumsi oleh perangkat keras klien.

Pertimbangkan NIC berkemampu DMA yang khas, misalnya. Ada manfaat serval untuk pendekatan ini:

  1. Buffer data dialokasikan dan dikosongkan oleh sistem. Oleh karena itu, driver klien dibebaskan dari beban manajemen seumur hidup memori.
  2. Sistem memastikan bahwa buffer data yang dialokasikan siap untuk perangkat keras NIC berdasarkan kemampuan yang dideklarasikan oleh driver klien. Kemudian, driver klien cukup memprogram buffer data ke perangkat keras mereka apa adanya tanpa melakukan operasi pemetaan DMA tambahan.
  3. Sistem dapat mempertimbangkan kebutuhan aplikasi lapisan atas saat mengalokasikan buffer data, sehingga dapat memutuskan untuk mengoptimalkan performa end-to-end global alih-alih hanya performa end-to-end lokal.

Untuk NIC kapabilitas non-DMA seperti dongle jaringan berbasis USB, atau untuk NIC tingkat lanjut/perangkat lunak lainnya, model manajemen buffer juga menyediakan opsi untuk meninggalkan manajemen buffer data sepenuhnya kepada driver klien.

Cara memanfaatkan manajemen buffer

Penting

Jika perangkat keras Anda berkemampuan DMA, Anda harus membuat objek WDFDMAENABLER sebelum mengatur kemampuan Rx dan Tx Anda. Saat Anda mengonfigurasi objek WDFDMAENABLER dengan struktur WDF_DMA_ENABLER_CONFIG , pastikan untuk mengatur anggota WdmDmaVersionOverride ke 3 untuk menentukan DMA versi 3.

Untuk ikut serta dalam manajemen buffer, ikuti langkah-langkah berikut:

  1. Saat memulai adaptor bersih Anda, tetapi sebelum memanggil NetAdapterStart, beri tahu sistem tentang kemampuan dan batasan buffer data perangkat keras Anda menggunakan struktur data NET_ADAPTER_RX_CAPABILITIES dan NET_ADAPTER_TX_CAPABILITIES untuk jalur Rx dan Tx masing-masing.
  2. Inisialisasi dua struktur kemampuan dengan memanggil salah satu fungsi inisialisasi. Misalnya, driver klien NIC berkemampuan DMA akan menggunakan NET_ADAPTER_TX_CAPABILITIES_INIT_FOR_DMA dan NET_ADAPTER_RX_CAPABILITIES_INIT_SYSTEM_MANAGED_DMA untuk mendeklarasikan kemampuan DMA perangkat kerasnya dan untuk menginstruksikan sistem untuk sepenuhnya mengelola buffer data atas namanya.
  3. Teruskan struktur kemampuan Tx dan Rx yang diinisialisasi ke metode NetAdapterSetDatapathCapabilities .

Contoh

Contoh berikut mengilustrasikan langkah-langkah dasar yang diuraikan di bagian sebelumnya tentang cara mulai menggunakan manajer buffer di driver klien NIC Anda. Contohnya menggunakan DMA untuk Tx dan Rx, sehingga sebelumnya membuat objek WDFDMAENABLER yang disimpan di ruang konteks perangkatnya.

Perhatikan bahwa contoh ini juga menetapkan beberapa petunjuk tentang buffer fragmennya setelah menginisialisasi struktur kemampuan Tx dan Rx. Petunjuk ini dapat digunakan oleh NetAdapterCx dan driver protokol untuk meningkatkan performa.

Penanganan kesalahan telah dibiarkan untuk kejelasan.

VOID
MyAdapterSetDatapathCapabilities(
    _In_ NETADAPTER Adapter
)
{
    // Get the device context
    PMY_DEVICE_CONTEXT deviceContext = GetMyContextFromDevice(Adapter);

    // Set various capabilities such as link layer MTU size, link layer capabilities, and power capabilities
    ...   

    // Initialize the Tx DMA capabilities structure
    NET_ADAPTER_DMA_CAPABILITIES txDmaCapabilities;
    NET_ADAPTER_DMA_CAPABILITIES_INIT(&txDmaCapabilities,
                                      deviceContext->dmaEnabler);

    // Set Tx capabilities
    NET_ADAPTER_TX_CAPABILITIES txCapabilities;
    NET_ADAPTER_TX_CAPABILITIES_INIT_FOR_DMA(&txCapabilities,
                                             &txDmaCapabilities,
                                             1);
    txCapabilities.FragmentRingNumberOfElementsHint = deviceContext->NumTransmitControlBlocks * MAX_PHYS_BUF_COUNT;
    txCapabilities.MaximumNumberOfFragments = MAX_PHYS_BUF_COUNT;

    // Initialize the Rx DMA capabilities structure
    NET_ADAPTER_DMA_CAPABILITIES rxDmaCapabilities;
    NET_ADAPTER_DMA_CAPABILITIES_INIT(&rxDmaCapabilities,
                                      deviceContext->dmaEnabler);

    // Set Rx capabilities
    NET_ADAPTER_RX_CAPABILITIES rxCapabilities;
    NET_ADAPTER_RX_CAPABILITIES_INIT_SYSTEM_MANAGED_DMA(&rxCapabilities,
                                                        &rxDmaCapabilities,
                                                        MAX_PACKET_SIZE + FRAME_CRC_SIZE + RSVD_BUF_SIZE,
                                                        1);
    rxCapabilities.FragmentBufferAlignment = 64;
    rxCapabilities.FragmentRingNumberOfElementsHint = deviceContext->NumReceiveBuffers;

    // Set the adapter's datapath capabilities
    NetAdapterSetDatapathCapabilities(Adapter, 
                                      &txCapabilities, 
                                      &rxCapabilities);
}