Can DPDK selectively init NIC ports

1.1k views Asked by At

I'm using an dual-port NIC, Mellanox ConnectX-5, and the DPDK version is dpdk-stable-19.11.3. After configuration, the call of rte_eth_dev_count_avail() returns 2. But only one port of my ConnectX-5 NIC is connected to the other machine. All I can find is to init all available ports like this.

RTE_ETH_FOREACH_DEV(portid)
    if (port_init(portid, mbuf_pool) != 0)
        rte_exit(EXIT_FAILURE, "Cannot init port %u\n", portid);

Can dpdk selectively init ports? Or is there any way to make rte_eth_dev_count_avail() returning 1?

2

There are 2 answers

4
Vipin Varghese On BEST ANSWER

Yes one can selectively init ports by passing the right PCIe Bus:Device:Function address as a whitelist. Hence only desired ports will pop up in the application.

How to do it:

  1. create a dummy application to take in all DPDK port.
  2. Initialize and start the dpdk ports. Check for link-state and create port-mask (global variable) which filters in application logic.
  3. Invoke rte_eth_dev_stop & rte_eth_dev_close for link down ports.
  4. Invoke rte_eal_cleanup.
  5. Use the port-mask, as an argument for execv to invoke your desired DPDK application.

this way you can run your application with valid ports to it.

But relying on rte_eth_link_get is tricky because

  • if the other end is connected to dpdk-pktgen, first your DPDK application has to init the NIC locally.
  • if connected to linux box, the nic has to be bought up first with ifconfig [other nic] up
  • at times one needs to check link.link_speed if its valid.
  • certain PMD needs write to PCIe mapped register, hence has to dev_configure and port_init to get a reliable reading for link status.

Hence safest and recommended way to use is identify the NIC PCIe B:D:F in Linux driver and then whitelist the ports by using option -w for the desired port under igb_uio/virtio-pci. This can be done by bind all NIC back in linux by

  1. lshw -c network -businfo will list NIC and PCIe Bus:Device:Function with kerel device name and driver.
  2. use ethtool [eth device name] | grep Link to identify the link is connected.

for reference, you can use https://github.com/vipinpv85/DPDK-APP_SAMPLES/blob/master/auto-baseaddr-selector.c as template for dummy applciation.

3
Sunil Bojanapally On

Another quick way to assign a particular port out all available ports to DPDK application by using DPDK tool dpdk-devbind.py and EAL port initialization will pick port which is assigned to UIO/VFIO kernel driver. Below are devbind script steps to identify port current status and how to bind required port to DPDK.

[root@linux usertools]# ./dpdk-devbind.py --status

Network devices using kernel driver
===================================
0000:00:03.0 '82540EM Gigabit Ethernet Controller 100e' if= drv=e1000 unused=vfio-pci
0000:00:04.0 '82540EM Gigabit Ethernet Controller 100e' if= drv=e1000 unused=vfio-pci

[root@linux usertools]# ./dpdk-devbind.py --bind=vfio-pci 00:04.0
[root@linux usertools]# ./dpdk-devbind.py --status

Network devices using DPDK-compatible driver
============================================
0000:00:04.0 '82540EM Gigabit Ethernet Controller 100e' drv=vfio-pci unused=e1000

Network devices using kernel driver
===================================
0000:00:03.0 '82540EM Gigabit Ethernet Controller 100e' if= drv=e1000 unused=vfio-pci

[EDIT-1] based on the updated question from author, the request is identify from the available DPDK ports which is connected? as mentioned above answer one needs to use rte_eth_link_get