Some NICs have only one PCI address associated with multiple ports. This patch extends the dpdk-devargs option's format to cater for such devices. Whereas before only one of N ports associated with one PCI address could be added, now N can.
This patch allows for the following use of the dpdk-devargs option: ovs-vsctl set Interface myport options:dpdk-devargs=0000:06:00.0,X Where X is an unsigned integer representing one of multiple ports associated with the PCI address provided. This patch has not been tested. Signed-off-by: Ciara Loftus <[email protected]> --- lib/netdev-dpdk.c | 79 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 63 insertions(+), 16 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index c60f46f..c3562a3 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -1214,30 +1214,77 @@ netdev_dpdk_lookup_by_port_id(dpdk_port_t port_id) } static dpdk_port_t +process_devargs_index(char *name, int idx) +{ + int i = 0; + struct rte_eth_dev_info dev_info; + char pci_addr[PCI_PRI_STR_SIZE]; + dpdk_port_t offset_port_id = DPDK_ETH_PORT_ID_INVALID; + + for (i = 0; i < RTE_MAX_ETHPORTS; i++) { + if (!rte_eth_dev_is_valid_port(i)) { + continue; + } + rte_eth_dev_info_get(i, &dev_info); + rte_pci_device_name(&dev_info.pci_dev->addr, pci_addr, + sizeof(pci_addr)); + if (!strcmp(pci_addr, name)) { + offset_port_id = i + idx; + if (rte_eth_dev_is_valid_port(offset_port_id)) { + rte_eth_dev_info_get(offset_port_id, &dev_info); + rte_pci_device_name(&dev_info.pci_dev->addr, pci_addr, + sizeof(pci_addr)); + if (!strcmp(pci_addr, name)) { + return offset_port_id; + } else { + break; + } + } else { + break; + } + } + } + + VLOG_INFO("Invalid PCI offset %i for device %s", idx, name); + return DPDK_ETH_PORT_ID_INVALID; +} + +static dpdk_port_t netdev_dpdk_process_devargs(struct netdev_dpdk *dev, const char *devargs, char **errp) { - /* Get the name up to the first comma. */ - char *name = xmemdup0(devargs, strcspn(devargs, ",")); + char *devargs_copy = xmemdup0((devargs), strlen(devargs)); + char *name, *idx_str; + unsigned idx; dpdk_port_t new_port_id = DPDK_ETH_PORT_ID_INVALID; - if (!rte_eth_dev_count() - || rte_eth_dev_get_port_by_name(name, &new_port_id) - || !rte_eth_dev_is_valid_port(new_port_id)) { - /* Device not found in DPDK, attempt to attach it */ - if (!rte_eth_dev_attach(devargs, &new_port_id)) { - /* Attach successful */ - dev->attached = true; - VLOG_INFO("Device '%s' attached to DPDK", devargs); - } else { - /* Attach unsuccessful */ - new_port_id = DPDK_ETH_PORT_ID_INVALID; - VLOG_WARN_BUF(errp, "Error attaching device '%s' to DPDK", - devargs); + name = strtok_r(devargs_copy, ",", &devargs_copy); + idx_str = strtok_r(devargs_copy, ",", &devargs_copy); + + if (idx_str) { + idx = atoi(idx_str); + new_port_id = process_devargs_index(name, idx); + } else { + if (!rte_eth_dev_count() + || rte_eth_dev_get_port_by_name(name, &new_port_id) + || !rte_eth_dev_is_valid_port(new_port_id)) { + /* Device not found in DPDK, attempt to attach it */ + if (!rte_eth_dev_attach(devargs, &new_port_id)) { + /* Attach successful */ + dev->attached = true; + VLOG_INFO("Device '%s' attached to DPDK", devargs); + } else { + /* Attach unsuccessful */ + new_port_id = DPDK_ETH_PORT_ID_INVALID; + } } } - free(name); + if (new_port_id == DPDK_ETH_PORT_ID_INVALID) { + VLOG_WARN_BUF(errp, "Error attaching device '%s' to DPDK", + devargs); + } + return new_port_id; } -- 2.7.5 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
