Separate gve_setup_device_resources into two distinct functions: - gve_alloc_device_resources: allocates host DMA memory structures (counter array, IRQ doorbells, ptype LUT). - gve_configure_device_resources: registers and configures those allocated resources with the device hardware.
Symmetrically, partition gve_teardown_device_resources into a function for freeing memory and one for deconfiguring resources. This clean separation allows device resources to be re-configured with the hardware during device reset recovery without re-allocating host memory. Signed-off-by: Jasper Tran O'Leary <[email protected]> Reviewed-by: Joshua Washington <[email protected]> --- drivers/net/gve/gve_ethdev.c | 172 +++++++++++++++++------------- 1 file changed, 97 insertions(+), 75 deletions(-) diff --git a/drivers/net/gve/gve_ethdev.c b/drivers/net/gve/gve_ethdev.c index 680fc9947..44810b864 100644 --- a/drivers/net/gve/gve_ethdev.c +++ b/drivers/net/gve/gve_ethdev.c @@ -742,15 +742,20 @@ gve_free_queues(struct rte_eth_dev *dev) static void gve_free_counter_array(struct gve_priv *priv) { - rte_memzone_free(priv->cnt_array_mz); - priv->cnt_array = NULL; + if (priv->cnt_array_mz) { + rte_memzone_free(priv->cnt_array_mz); + priv->cnt_array_mz = NULL; + priv->cnt_array = NULL; + } } - static void gve_free_irq_db(struct gve_priv *priv) { - rte_memzone_free(priv->irq_dbs_mz); - priv->irq_dbs = NULL; + if (priv->irq_dbs_mz) { + rte_memzone_free(priv->irq_dbs_mz); + priv->irq_dbs_mz = NULL; + priv->irq_dbs = NULL; + } } static void @@ -805,33 +810,38 @@ gve_teardown_flow_subsystem(struct gve_priv *priv) } static void -gve_teardown_device_resources(struct gve_priv *priv) +gve_free_device_resources(struct gve_priv *priv) +{ + gve_free_nic_ts_report(priv); + gve_free_ptype_lut_dqo(priv); + gve_free_counter_array(priv); + gve_free_irq_db(priv); + gve_free_rss_config(&priv->rss_config); +} + +static void +gve_deconfigure_device_resources(struct gve_priv *priv) { struct gve_process_private *process_priv; int err; - process_priv = rte_eth_devices[priv->port_id].process_private; - - /* Tell device its resources are being freed */ - if (gve_get_device_resources_ok(priv)) { - err = process_priv->ctrl_ops->free_db_resources(priv); - if (err) - PMD_DRV_LOG(ERR, - "Could not deconfigure device resources: err=%d", - err); - } + if (!gve_get_device_resources_ok(priv)) + return; if (priv->nic_ts_report_mz) { rte_atomic_store_explicit(&priv->nic_ts_thread_should_stop, 1, rte_memory_order_relaxed); rte_thread_join(priv->nic_ts_thread_id, NULL); - gve_free_nic_ts_report(priv); } - gve_free_ptype_lut_dqo(priv); - gve_free_counter_array(priv); - gve_free_irq_db(priv); - gve_free_rss_config(&priv->rss_config); + process_priv = rte_eth_devices[priv->port_id].process_private; + if (process_priv->ctrl_ops->free_db_resources) { + err = process_priv->ctrl_ops->free_db_resources(priv); + if (err) + PMD_DRV_LOG(ERR, + "Could not deconfigure device resources: err=%d", + err); + } gve_clear_device_resources_ok(priv); } @@ -864,8 +874,9 @@ gve_dev_close(struct rte_eth_dev *dev) priv->zombie_rx_queues = NULL; priv->zombie_tx_queues = NULL; - gve_teardown_device_resources(priv); + gve_deconfigure_device_resources(priv); process_priv->ctrl_ops->free_ctrl_plane(priv); + gve_free_device_resources(priv); pthread_mutex_destroy(&priv->flow_rule_lock); pthread_mutex_destroy(&priv->nic_ts_lock); @@ -907,8 +918,9 @@ gve_dev_reset(struct rte_eth_dev *dev) * destroyed on dev_close. */ gve_free_queues(dev); - gve_teardown_device_resources(priv); + gve_deconfigure_device_resources(priv); process_priv->ctrl_ops->free_ctrl_plane(priv); + gve_free_device_resources(priv); err = gve_init_priv(priv, true); if (err != 0) { @@ -1574,36 +1586,27 @@ gve_setup_nic_timestamp(struct gve_priv *priv) { int err; - if (priv->clk_read_type == GVE_DEV_CLK_UNSUPPORTED) + if (!priv->nic_ts_report_mz) return; rte_atomic_store_explicit(&priv->nic_ts_read_fails, 0, rte_memory_order_relaxed); rte_atomic_store_explicit(&priv->nic_ts_stale, 1, rte_memory_order_relaxed); - err = gve_alloc_nic_ts_report(priv); - if (err == 0) { - gve_read_nic_clock(priv); - rte_atomic_store_explicit(&priv->nic_ts_thread_should_stop, 0, - rte_memory_order_relaxed); - err = rte_thread_create_internal_control(&priv->nic_ts_thread_id, "gve-ts", - gve_nic_ts_thread, priv); - if (err != 0) { - PMD_DRV_LOG(ERR, "Failed to create NIC clock sync thread, err=%d", err); - gve_free_nic_ts_report(priv); - } - } else { - PMD_DRV_LOG(ERR, "Failed to allocate memory for NIC timestamping subsystem. Please reset device to retry."); + gve_read_nic_clock(priv); + rte_atomic_store_explicit(&priv->nic_ts_thread_should_stop, 0, + rte_memory_order_relaxed); + err = rte_thread_create_internal_control(&priv->nic_ts_thread_id, "gve-ts", + gve_nic_ts_thread, priv); + if (err != 0) { + PMD_DRV_LOG(ERR, "Failed to create NIC clock sync thread, err=%d", err); + gve_free_nic_ts_report(priv); } } static int -gve_setup_device_resources(struct gve_priv *priv) +gve_alloc_device_resources(struct gve_priv *priv) { - struct gve_process_private *process_priv; char z_name[RTE_MEMZONE_NAMESIZE]; const struct rte_memzone *mz; - int err = 0; - - process_priv = rte_eth_devices[priv->port_id].process_private; snprintf(z_name, sizeof(z_name), "gve_%s_cnt_arr", priv->pci_dev->device.name); mz = rte_memzone_reserve_aligned(z_name, @@ -1619,34 +1622,56 @@ gve_setup_device_resources(struct gve_priv *priv) snprintf(z_name, sizeof(z_name), "gve_%s_irqmz", priv->pci_dev->device.name); mz = rte_memzone_reserve_aligned(z_name, - sizeof(*priv->irq_dbs) * (priv->num_ntfy_blks), + sizeof(*priv->irq_dbs) * priv->num_ntfy_blks, rte_socket_id(), RTE_MEMZONE_IOVA_CONTIG, PAGE_SIZE); if (mz == NULL) { PMD_DRV_LOG(ERR, "Could not alloc memzone for irq_dbs"); - err = -ENOMEM; - goto free_cnt_array; + goto err_free; } priv->irq_dbs = (struct gve_irq_db *)mz->addr; priv->irq_dbs_mz = mz; - err = process_priv->ctrl_ops->get_interrupt_dbs(priv); - if (unlikely(err)) { - PMD_DRV_LOG(ERR, "Could not config device resources: err=%d", err); - goto free_irq_dbs; - } if (!gve_is_gqi(priv)) { priv->ptype_lut_dqo = rte_zmalloc("gve_ptype_lut_dqo", sizeof(struct gve_ptype_lut), 0); if (priv->ptype_lut_dqo == NULL) { PMD_DRV_LOG(ERR, "Failed to alloc ptype lut."); - err = -ENOMEM; - goto free_irq_dbs; + goto err_free; } + } + + if (priv->clk_read_type != GVE_DEV_CLK_UNSUPPORTED) { + if (gve_alloc_nic_ts_report(priv) != 0) + PMD_DRV_LOG(ERR, "Failed to allocate memory for NIC timestamping subsystem."); + } + + return 0; + +err_free: + gve_free_device_resources(priv); + return -ENOMEM; +} + +static int +gve_configure_device_resources(struct gve_priv *priv) +{ + struct gve_process_private *process_priv; + int err; + + process_priv = rte_eth_devices[priv->port_id].process_private; + + err = process_priv->ctrl_ops->get_interrupt_dbs(priv); + if (unlikely(err)) { + PMD_DRV_LOG(ERR, "Could not config device resources: err=%d", err); + return err; + } + + if (!gve_is_gqi(priv)) { err = process_priv->ctrl_ops->get_ptype_map(priv); if (unlikely(err)) { PMD_DRV_LOG(ERR, "Failed to get ptype map: err=%d", err); - goto free_ptype_lut; + return err; } } gve_setup_nic_timestamp(priv); @@ -1654,15 +1679,6 @@ gve_setup_device_resources(struct gve_priv *priv) gve_set_device_resources_ok(priv); return 0; -free_ptype_lut: - rte_free(priv->ptype_lut_dqo); - priv->ptype_lut_dqo = NULL; -free_irq_dbs: - gve_free_irq_db(priv); -free_cnt_array: - gve_free_counter_array(priv); - - return err; } static void @@ -1797,19 +1813,19 @@ gve_init_priv(struct gve_priv *priv, bool skip_describe_device) err = process_priv->ctrl_ops->get_device_properties(priv); if (err) { PMD_DRV_LOG(ERR, "Could not get device information: err=%d", err); - goto free_adminq; + goto free_ctrl_plane; } num_ntfy = pci_dev_msix_vec_count(priv->pci_dev); if (num_ntfy <= 0) { PMD_DRV_LOG(ERR, "Could not count MSI-x vectors"); err = -EIO; - goto free_adminq; + goto free_ctrl_plane; } else if (num_ntfy < GVE_MIN_MSIX) { PMD_DRV_LOG(ERR, "GVE needs at least %d MSI-x vectors, but only has %d", GVE_MIN_MSIX, num_ntfy); err = -EINVAL; - goto free_adminq; + goto free_ctrl_plane; } priv->num_registered_pages = 0; @@ -1867,8 +1883,11 @@ setup_device: "Failed to set up flow subsystem: err=%d, flow steering will be disabled.", err); } + err = gve_alloc_device_resources(priv); + if (err) + goto free_flow_subsystem; - err = gve_setup_device_resources(priv); + err = gve_configure_device_resources(priv); if (err) goto free_flow_subsystem; @@ -1877,16 +1896,19 @@ free_flow_subsystem: if (gve_get_flow_subsystem_ok(priv)) gve_teardown_flow_subsystem(priv); free_queue_configs: - rte_free(priv->zombie_tx_queues); - priv->zombie_tx_queues = NULL; - rte_free(priv->zombie_rx_queues); - priv->zombie_rx_queues = NULL; - rte_free(priv->txq_configs); - priv->txq_configs = NULL; - rte_free(priv->rxq_configs); - priv->rxq_configs = NULL; -free_adminq: + if (!skip_describe_device) { + rte_free(priv->zombie_tx_queues); + priv->zombie_tx_queues = NULL; + rte_free(priv->zombie_rx_queues); + priv->zombie_rx_queues = NULL; + rte_free(priv->txq_configs); + priv->txq_configs = NULL; + rte_free(priv->rxq_configs); + priv->rxq_configs = NULL; + } +free_ctrl_plane: process_priv->ctrl_ops->free_ctrl_plane(priv); + gve_free_device_resources(priv); return err; } -- 2.56.0.307.g5fe7bd680c-goog

