From 472fa1b17c270ce44a2640dad0da27f4867b5088 Mon Sep 17 00:00:00 2001 From: Igor Romanov Date: Mon, 11 Oct 2021 17:48:40 +0300 Subject: [PATCH] net/sfc: support multiple device probe Support probing the device multiple times so that additional port representors can be created with hotplug EAL API. To hotplug a representor, the PF must be hotplugged with different representor device argument. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/sfc_ethdev.c | 55 ++++++++++++++++++++++++------------ drivers/net/sfc/sfc_repr.c | 35 +++++++++++++---------- 2 files changed, 57 insertions(+), 33 deletions(-) diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 2e34647e87..4aa4382c82 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -2493,31 +2493,40 @@ sfc_parse_rte_devargs(const char *args, struct rte_eth_devargs *devargs) } static int -sfc_eth_dev_create(struct rte_pci_device *pci_dev, - struct sfc_ethdev_init_data *init_data, - struct rte_eth_dev **devp) +sfc_eth_dev_find_or_create(struct rte_pci_device *pci_dev, + struct sfc_ethdev_init_data *init_data, + struct rte_eth_dev **devp, + bool *dev_created) { struct rte_eth_dev *dev; + bool created = false; int rc; - rc = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name, - sizeof(struct sfc_adapter_shared), - eth_dev_pci_specific_init, pci_dev, - sfc_eth_dev_init, init_data); - if (rc != 0) { - SFC_GENERIC_LOG(ERR, "Failed to create sfc ethdev '%s'", - pci_dev->device.name); - return rc; - } - dev = rte_eth_dev_allocated(pci_dev->device.name); if (dev == NULL) { - SFC_GENERIC_LOG(ERR, "Failed to find allocated sfc ethdev '%s'", + rc = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name, + sizeof(struct sfc_adapter_shared), + eth_dev_pci_specific_init, pci_dev, + sfc_eth_dev_init, init_data); + if (rc != 0) { + SFC_GENERIC_LOG(ERR, "Failed to create sfc ethdev '%s'", + pci_dev->device.name); + return rc; + } + + created = true; + + dev = rte_eth_dev_allocated(pci_dev->device.name); + if (dev == NULL) { + SFC_GENERIC_LOG(ERR, + "Failed to find allocated sfc ethdev '%s'", pci_dev->device.name); - return -ENODEV; + return -ENODEV; + } } *devp = dev; + *dev_created = created; return 0; } @@ -2578,6 +2587,7 @@ static int sfc_eth_dev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, struct sfc_ethdev_init_data init_data; struct rte_eth_devargs eth_da; struct rte_eth_dev *dev; + bool dev_created; int rc; if (pci_dev->device.devargs != NULL) { @@ -2599,13 +2609,21 @@ static int sfc_eth_dev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, return -ENOTSUP; } - rc = sfc_eth_dev_create(pci_dev, &init_data, &dev); + /* + * Driver supports RTE_PCI_DRV_PROBE_AGAIN. Hence create device only + * if it does not already exist. Re-probing an existing device is + * expected to allow additional representors to be configured. + */ + rc = sfc_eth_dev_find_or_create(pci_dev, &init_data, &dev, + &dev_created); if (rc != 0) return rc; rc = sfc_eth_dev_create_representors(dev, ð_da); if (rc != 0) { - (void)rte_eth_dev_destroy(dev, sfc_eth_dev_uninit); + if (dev_created) + (void)rte_eth_dev_destroy(dev, sfc_eth_dev_uninit); + return rc; } @@ -2621,7 +2639,8 @@ static struct rte_pci_driver sfc_efx_pmd = { .id_table = pci_id_sfc_efx_map, .drv_flags = RTE_PCI_DRV_INTR_LSC | - RTE_PCI_DRV_NEED_MAPPING, + RTE_PCI_DRV_NEED_MAPPING | + RTE_PCI_DRV_PROBE_AGAIN, .probe = sfc_eth_dev_pci_probe, .remove = sfc_eth_dev_pci_remove, }; diff --git a/drivers/net/sfc/sfc_repr.c b/drivers/net/sfc/sfc_repr.c index 83ac733312..4dbb6bdaa3 100644 --- a/drivers/net/sfc/sfc_repr.c +++ b/drivers/net/sfc/sfc_repr.c @@ -908,6 +908,7 @@ sfc_repr_create(struct rte_eth_dev *parent, uint16_t representor_id, struct sfc_repr_init_data repr_data; char name[RTE_ETH_NAME_MAX_LEN]; int ret; + struct rte_eth_dev *dev; if (snprintf(name, sizeof(name), "net_%s_representor_%u", parent->device->name, representor_id) >= @@ -916,20 +917,24 @@ sfc_repr_create(struct rte_eth_dev *parent, uint16_t representor_id, return -ENAMETOOLONG; } - memset(&repr_data, 0, sizeof(repr_data)); - repr_data.pf_port_id = parent->data->port_id; - repr_data.repr_id = representor_id; - repr_data.switch_domain_id = switch_domain_id; - repr_data.mport_sel = *mport_sel; - - ret = rte_eth_dev_create(parent->device, name, - sizeof(struct sfc_repr_shared), - NULL, NULL, - sfc_repr_eth_dev_init, &repr_data); - if (ret != 0) - SFC_GENERIC_LOG(ERR, "%s() failed to create device", __func__); - - SFC_GENERIC_LOG(INFO, "%s() done: %s", __func__, rte_strerror(-ret)); + dev = rte_eth_dev_allocated(name); + if (dev == NULL) { + memset(&repr_data, 0, sizeof(repr_data)); + repr_data.pf_port_id = parent->data->port_id; + repr_data.repr_id = representor_id; + repr_data.switch_domain_id = switch_domain_id; + repr_data.mport_sel = *mport_sel; + + ret = rte_eth_dev_create(parent->device, name, + sizeof(struct sfc_repr_shared), + NULL, NULL, + sfc_repr_eth_dev_init, &repr_data); + if (ret != 0) { + SFC_GENERIC_LOG(ERR, "%s() failed to create device", + __func__); + return ret; + } + } - return ret; + return 0; } -- 2.20.1