Search code examples
dpdk

DPDK Number of ports must be even


I spent some time trying to figure out how to fix the "number of ports must be even" error. I've seen this answer which explains how to run DPDK inside a VM. I was wondering if there is a solution that does not require one.

My platform: Debian 10, Linux 5.8 (on a laptop) with an e1000e NIC driver

What I want to do: Make the skeleton (basicfwd) app work

My problem: rte_eth_dev_count_avail returns 0

What I did up until now: I followed the documentation and tried to setup a vfio_pci driver to my ethernet device.

Two things:

  • When I bind a device with the vfio_pci driver it loses its IP interface

  • I can't create VF devices because I can't write in /sys/bus/pci/devices/ even when I su root

The skeleton program is not working with this so I tried using another driver.

I bound the device to the uio_pci_generic driver. It does bind to it but the app still doesn't work. Here is the dpdk-devbind.py --status output:

Network devices using DPDK-compatible driver
============================================
0000:00:1f.6 'Device 0d4f' drv=uio_pci_generic unused=e1000e

What happens when I launch the program:

$ sudo ./build/examples/dpdk-skeleton -l 0-3 -n 4 -a 0000:00:1f.6 

EAL: Detected 8 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Detected static linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'VA'
EAL: Probing VFIO support...
EAL: No legacy callbacks, legacy socket not created
EAL: Error - exiting with code: 1
  Cause: Error: number of ports must be even

Thanks for reading, any help is appreciated !


Solution

  • In VM I am able to get e1000 bind with the following steps

    1. Start VM with 82540EM Gigabit Ethernet Controller
    2. Download and build DPDK 21.02
    3. insmod igb_uio or modprobe uio_pci_generic
    4. bind with vfio-pci fails with vfio-pci: probe of 0000:00:08.0 failed with error -22
    5. start the application with ./a.out -l 1 --log-level=pmd,8

    build application: gcc basicfwd.c $(pkg-config --libs --cflags --static libdpdk

    Logs:

    e1000_null_phy_generic(): e1000_null_phy_generic
    e1000_read_phy_reg_m88(): e1000_read_phy_reg_m88
    e1000_null_ops_generic(): e1000_null_ops_generic
    e1000_read_phy_reg_mdic(): e1000_read_phy_reg_mdic
    e1000_null_phy_generic(): e1000_null_phy_generic
    e1000_read_phy_reg_m88(): e1000_read_phy_reg_m88
    e1000_null_ops_generic(): e1000_null_ops_generic
    e1000_read_phy_reg_mdic(): e1000_read_phy_reg_mdic
    e1000_null_phy_generic(): e1000_null_phy_generic
    e1000_setup_copper_link_generic(): Unable to establish link!!!
    e1000_setup_link_generic(): Initializing the Flow Control address, type and timer regs
    e1000_set_fc_watermarks_generic(): e1000_set_fc_watermarks_generic
    e1000_clear_hw_cntrs_82540(): e1000_clear_hw_cntrs_82540
    e1000_clear_hw_cntrs_base_generic(): e1000_clear_hw_cntrs_base_generic
    e1000_check_for_copper_link_generic(): e1000_check_for_copper_link
    e1000_phy_has_link_generic(): e1000_phy_has_link_generic
    e1000_read_phy_reg_m88(): e1000_read_phy_reg_m88
    e1000_null_ops_generic(): e1000_null_ops_generic
    e1000_read_phy_reg_mdic(): e1000_read_phy_reg_mdic
    e1000_null_phy_generic(): e1000_null_phy_generic
    e1000_read_phy_reg_m88(): e1000_read_phy_reg_m88
    e1000_null_ops_generic(): e1000_null_ops_generic
    e1000_read_phy_reg_mdic(): e1000_read_phy_reg_mdic
    e1000_null_phy_generic(): e1000_null_phy_generic
    e1000_null_ops_generic(): e1000_null_ops_generic
    eth_em_dev_init(): port_id 0 vendorID=0x8086 deviceID=0x100e
    

    note: unmodified skeleton requires an even number of ports to work properly.

    Hence there is no issue with e1000 and DPDK usability

    [EDIT-1] had a live debug with Jeremy, the issue is now reproduced on a physical machine with physical NIC (an not emulated e1000). Checking the PCIe details the physical NIC is not in the list of supported Intel DPDK NIC. Requested to use a physical NIC recommend from DPDK.