亚欧色一区w666天堂,色情一区二区三区免费看,少妇特黄A片一区二区三区,亚洲人成网站999久久久综合,国产av熟女一区二区三区

  • 發布文章
  • 消息中心
點贊
收藏
評論
分享
原創

DPDK vdev 的使用

2025-06-17 09:18:19
26
0

本文介紹 DPDK 中 vdev 的創建方式和簡單的使用方式。

用戶編寫的 DPDK 應用使用 DPDK 的 API 來發送和接收網絡數據包。這些 API 隱藏了底下網卡硬件的差異和編程環境的差異,提供統一的編程接口。這些 API 統稱為環境抽象層 EAL(Environment Abstraction Layer)。

PMD (Poll Mode Driver) 是 DPDK 提供的用戶態網卡驅動,不同網卡有自己對應的 PMD,以靜態或動態鏈接方式使用。一般 DPDK 應用編譯時鏈接了很多類型的 PMD,我們也可以適當裁剪來去除平時用不到的 PMD。

攜帶多種 PMD 時,應用程序用一套業務邏輯代碼和收發網絡數據包的 API 就能操作不同的網卡來完成工作。

 

為了這套網絡數據包從應用層到網卡物理層能對接起來,需要打通從 EAL 層的收發包 API 到物理網卡的收發包。

這里一共分為以下幾個層次:

  1. 用戶配置應用程序使用到哪些物理網卡
  2. 應用層使用物理網卡對應的網口號調用統一的 EAL 收發包 API
  3. EAL 收發包 API 使用物理網卡對應的 PMD 的收發包 API
  4. PMD 從物理網卡收發網絡數據包

其中物理網口的網口號分配,EAL API 與 PMD API 的對應,PMD 與物理網卡的對應都是 DPDK 自動完成的。

上面的 4 個步驟的執行過程如下(跟上面不是一一對應)。

  1. 用戶為使用到的網卡綁定 DPDK 需要的設備驅動,例如 igb_uio/uio_generic_pci/vfio_pci,有些網卡不需要綁定,例如 MLNX 的網卡。
  2. 應用程序鏈接的 PMD 在應用程序全局初始化時注冊到對應的 bus 的驅動列表上。一般的物理網卡對應 pci bus, 虛擬類型的網絡設備對應 vdev bus。
  3. DPDK 框架初始化時,會查找系統的網絡設備,這步由不同的 bus 自己查找自己所管理的設備。
  4. DPDK 初始化過程中,調用 bus 的 probe 過程來關聯 PMD 與對應的設備,例如物理網卡或虛擬網絡設備。DPDK 會為查找到的網絡設備分配網口號,并創建一個以太網設備對象 ethdev, ethdev 的收發包 API 關聯到 PMD 的 API。
  5. PMD 收發網絡包時,直接操作物理網卡對應的內存和寄存器來完成收發功能。

DPDK 中虛擬網絡設備 vdev 與物理網卡不一樣,沒有直接對應的物理設備,不像在 linux 中可以通過查找 pci bus 來收集設備列表,vdev 只能通過 api 來創建虛擬設備,并且有自己對應的 bus 類型 vdev。

vdev 的設備來源包括命令行參數和直接的 api 調用。其中命令行參數最終也是調 api 來創建虛擬設備。

常用的虛擬設備包括 bonding, virtio_user, net_pcap 等。

vdev 介紹

下面介紹一下 vdev 的創建和設備參數的使用

通過 EAL 參數創建

./dpdk-testpmd -l 1-3 -n 4 -a 01:00.0 -a 01:00.1 \
    --vdev "net_bonding0,mode=2,xmit_policy=l23,member=0000:01:00.0,member=0000:01:00.1" \
    -- -i --portmask=0x3 --nb-cores=2

上面命令行參數指定了 2 個物理設備 01:00.0 和 01:00.1,還有一個 vdev, 類型是 net_bonding

通過命令行方式創建 vdev 時,設備類型后面帶了詳細的設備參數。

DPDK EAL 的命令行參數可以指定三種設備類型參數

enum rte_devtype {
	RTE_DEVTYPE_ALLOWED, // 對應 -a
	RTE_DEVTYPE_BLOCKED, // 對應 -b
	RTE_DEVTYPE_VIRTUAL, // 對應 --vdev
};

allow list 是允許使用的 pci 設備列表,block list 是禁止使用的 pci 設備列表,virtual 的 vdev 設備的參數。

vdev 設備初始化分為四步:

  1. 注冊 vdev bus, 注冊 vdev 對應的 PMD 到 vdev bus 的驅動列表
  2. 處理 EAL 參數 - eal_parse_args(argc, argv) ,包括 allow/block list, vdev
  3. scan bus 上注冊的設備 - rte_bus_scan(),
    1. pci 設備從系統目錄尋找
    2. vdev 設備從 EAL 參數解析得到的設備參數列表中找
  1. 已找到的設備,查找設備匹配的驅動并進行驅動 probe,處理設備參數 - rte_bus_probe()

對應 eal 初始化函數

// lib/eal/linux/eal.c
eal_parse_args(int argc, char **argv) {
    ...
    eal_parse_args(argc, argv);
    ...
    rte_bus_scan(); // pci 存入 pci bus 的 device list 中,vdev 存入 vdev device list 中
    ...
    rte_bus_probe();
    ...
}

在 pci 設備初始化完后,會為 vdev 分配網口號。

通過封裝過的 API 創建

int bond_port_id = rte_eth_bond_create("net_bonding0", BONDING_MODE_BALANCE, 0);
rte_eth_dev_configure(BOND_PORT, 1, 1, ...;
rte_eth_bond_member_add(bond_port_id, 0);
rte_eth_bond_member_add(bond_port_id, 1);
rte_eth_rx_queue_setup(bond_port_id, 0, ...);
rte_eth_tx_queue_setup(bond_port_id, 0, ...);
rte_eth_dev_start(bond_port_id);

net_bonding 有很多參數,通過 API 方式創建 vdev 時,rte_eth_bond_create 里只指定了 mode 和 socket_id,其他參數需要通過 API 來設置,例如 bonding 的 member 和 master。

rte_eth_bond_create 內部創建流程
rte_eth_bond_create
  rte_vdev_init
    insert_vdev // 插入全局列表 vdev_device_list
      rte_devargs_insert // 這一步是將參數對象插入全局列表 devargs_list,后續可以處理
    vdev_probe_all_drivers // probe 階段會解析設備參數和執行初始化

通過 hotplug api 創建

rte_eal_hotplug_add("vdev", "virtio_user0", "path=/dev/vhost-net");

內部處理流程

rte_eal_hotplug_add
  build_devargs
  rte_dev_probe
    local_dev_probe
      rte_devargs_insert
      da->bus->scan() // vdev_scan
      dev=da->bus->find_device // rte_vdev_find_device
      dev->bus->plug(dev) // vdev_plug 內部調 vdev_probe_all_drivers

上面的 vdev_scan 步驟跟 rte_vdev_init 中的 insert_vdev 效果差不多,都是將 device 放入 vdev_device_list, 有什么區別,為什么不統一成一個?

secondary 進程調用 vdev_action VDEV_SCAN_ONE 時會調 insert_vdev

device 介紹常用(通用)參數。

EAL 創建和 API 創建對比

EAL 的好處是可以在不修改程序邏輯的情況下,只修改程序運行時的命令行參數就能為程序提供額外功能支持。例如應用程序原來只處理一個網口的報文,現在通過命令行創建 bonding, 應用程序只處理這個 bonding 接口,實際底下可以通過命令行參數指定多個物理口成員。

API 相比 EAL 參數的好處理是可以動態修改,例如 bonding 設備可以動態添加和刪除 member。

查看 PMD 支持哪些參數

usertools/dpdk-pmdinfo.py dpdk-testpmd | jq '.[] | select(.name=="net_bonding")'

0條評論
0 / 1000
c****x
1文章數
0粉絲數
c****x
1 文章 | 0 粉絲
c****x
1文章數
0粉絲數
c****x
1 文章 | 0 粉絲
原創

DPDK vdev 的使用

2025-06-17 09:18:19
26
0

本文介紹 DPDK 中 vdev 的創建方式和簡單的使用方式。

用戶編寫的 DPDK 應用使用 DPDK 的 API 來發送和接收網絡數據包。這些 API 隱藏了底下網卡硬件的差異和編程環境的差異,提供統一的編程接口。這些 API 統稱為環境抽象層 EAL(Environment Abstraction Layer)。

PMD (Poll Mode Driver) 是 DPDK 提供的用戶態網卡驅動,不同網卡有自己對應的 PMD,以靜態或動態鏈接方式使用。一般 DPDK 應用編譯時鏈接了很多類型的 PMD,我們也可以適當裁剪來去除平時用不到的 PMD。

攜帶多種 PMD 時,應用程序用一套業務邏輯代碼和收發網絡數據包的 API 就能操作不同的網卡來完成工作。

 

為了這套網絡數據包從應用層到網卡物理層能對接起來,需要打通從 EAL 層的收發包 API 到物理網卡的收發包。

這里一共分為以下幾個層次:

  1. 用戶配置應用程序使用到哪些物理網卡
  2. 應用層使用物理網卡對應的網口號調用統一的 EAL 收發包 API
  3. EAL 收發包 API 使用物理網卡對應的 PMD 的收發包 API
  4. PMD 從物理網卡收發網絡數據包

其中物理網口的網口號分配,EAL API 與 PMD API 的對應,PMD 與物理網卡的對應都是 DPDK 自動完成的。

上面的 4 個步驟的執行過程如下(跟上面不是一一對應)。

  1. 用戶為使用到的網卡綁定 DPDK 需要的設備驅動,例如 igb_uio/uio_generic_pci/vfio_pci,有些網卡不需要綁定,例如 MLNX 的網卡。
  2. 應用程序鏈接的 PMD 在應用程序全局初始化時注冊到對應的 bus 的驅動列表上。一般的物理網卡對應 pci bus, 虛擬類型的網絡設備對應 vdev bus。
  3. DPDK 框架初始化時,會查找系統的網絡設備,這步由不同的 bus 自己查找自己所管理的設備。
  4. DPDK 初始化過程中,調用 bus 的 probe 過程來關聯 PMD 與對應的設備,例如物理網卡或虛擬網絡設備。DPDK 會為查找到的網絡設備分配網口號,并創建一個以太網設備對象 ethdev, ethdev 的收發包 API 關聯到 PMD 的 API。
  5. PMD 收發網絡包時,直接操作物理網卡對應的內存和寄存器來完成收發功能。

DPDK 中虛擬網絡設備 vdev 與物理網卡不一樣,沒有直接對應的物理設備,不像在 linux 中可以通過查找 pci bus 來收集設備列表,vdev 只能通過 api 來創建虛擬設備,并且有自己對應的 bus 類型 vdev。

vdev 的設備來源包括命令行參數和直接的 api 調用。其中命令行參數最終也是調 api 來創建虛擬設備。

常用的虛擬設備包括 bonding, virtio_user, net_pcap 等。

vdev 介紹

下面介紹一下 vdev 的創建和設備參數的使用

通過 EAL 參數創建

./dpdk-testpmd -l 1-3 -n 4 -a 01:00.0 -a 01:00.1 \
    --vdev "net_bonding0,mode=2,xmit_policy=l23,member=0000:01:00.0,member=0000:01:00.1" \
    -- -i --portmask=0x3 --nb-cores=2

上面命令行參數指定了 2 個物理設備 01:00.0 和 01:00.1,還有一個 vdev, 類型是 net_bonding

通過命令行方式創建 vdev 時,設備類型后面帶了詳細的設備參數。

DPDK EAL 的命令行參數可以指定三種設備類型參數

enum rte_devtype {
	RTE_DEVTYPE_ALLOWED, // 對應 -a
	RTE_DEVTYPE_BLOCKED, // 對應 -b
	RTE_DEVTYPE_VIRTUAL, // 對應 --vdev
};

allow list 是允許使用的 pci 設備列表,block list 是禁止使用的 pci 設備列表,virtual 的 vdev 設備的參數。

vdev 設備初始化分為四步:

  1. 注冊 vdev bus, 注冊 vdev 對應的 PMD 到 vdev bus 的驅動列表
  2. 處理 EAL 參數 - eal_parse_args(argc, argv) ,包括 allow/block list, vdev
  3. scan bus 上注冊的設備 - rte_bus_scan(),
    1. pci 設備從系統目錄尋找
    2. vdev 設備從 EAL 參數解析得到的設備參數列表中找
  1. 已找到的設備,查找設備匹配的驅動并進行驅動 probe,處理設備參數 - rte_bus_probe()

對應 eal 初始化函數

// lib/eal/linux/eal.c
eal_parse_args(int argc, char **argv) {
    ...
    eal_parse_args(argc, argv);
    ...
    rte_bus_scan(); // pci 存入 pci bus 的 device list 中,vdev 存入 vdev device list 中
    ...
    rte_bus_probe();
    ...
}

在 pci 設備初始化完后,會為 vdev 分配網口號。

通過封裝過的 API 創建

int bond_port_id = rte_eth_bond_create("net_bonding0", BONDING_MODE_BALANCE, 0);
rte_eth_dev_configure(BOND_PORT, 1, 1, ...;
rte_eth_bond_member_add(bond_port_id, 0);
rte_eth_bond_member_add(bond_port_id, 1);
rte_eth_rx_queue_setup(bond_port_id, 0, ...);
rte_eth_tx_queue_setup(bond_port_id, 0, ...);
rte_eth_dev_start(bond_port_id);

net_bonding 有很多參數,通過 API 方式創建 vdev 時,rte_eth_bond_create 里只指定了 mode 和 socket_id,其他參數需要通過 API 來設置,例如 bonding 的 member 和 master。

rte_eth_bond_create 內部創建流程
rte_eth_bond_create
  rte_vdev_init
    insert_vdev // 插入全局列表 vdev_device_list
      rte_devargs_insert // 這一步是將參數對象插入全局列表 devargs_list,后續可以處理
    vdev_probe_all_drivers // probe 階段會解析設備參數和執行初始化

通過 hotplug api 創建

rte_eal_hotplug_add("vdev", "virtio_user0", "path=/dev/vhost-net");

內部處理流程

rte_eal_hotplug_add
  build_devargs
  rte_dev_probe
    local_dev_probe
      rte_devargs_insert
      da->bus->scan() // vdev_scan
      dev=da->bus->find_device // rte_vdev_find_device
      dev->bus->plug(dev) // vdev_plug 內部調 vdev_probe_all_drivers

上面的 vdev_scan 步驟跟 rte_vdev_init 中的 insert_vdev 效果差不多,都是將 device 放入 vdev_device_list, 有什么區別,為什么不統一成一個?

secondary 進程調用 vdev_action VDEV_SCAN_ONE 時會調 insert_vdev

device 介紹常用(通用)參數。

EAL 創建和 API 創建對比

EAL 的好處是可以在不修改程序邏輯的情況下,只修改程序運行時的命令行參數就能為程序提供額外功能支持。例如應用程序原來只處理一個網口的報文,現在通過命令行創建 bonding, 應用程序只處理這個 bonding 接口,實際底下可以通過命令行參數指定多個物理口成員。

API 相比 EAL 參數的好處理是可以動態修改,例如 bonding 設備可以動態添加和刪除 member。

查看 PMD 支持哪些參數

usertools/dpdk-pmdinfo.py dpdk-testpmd | jq '.[] | select(.name=="net_bonding")'

文章來自個人專欄
文章 | 訂閱
0條評論
0 / 1000
請輸入你的評論
0
0