[PATCH 4/9] net/gve: separate device resource alloc and config
Jasper Tran O'Leary
jtranoleary at google.com
Tue Oct 27 19:54:13 CET 2026
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 <jtranoleary at google.com>
Reviewed-by: Joshua Washington <joshwash at google.com>
---
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
More information about the dev
mailing list