Currently, the driver does not include any reset functionality and hence cannot be reset by the application. This patch introduces a driver callback for the `rte_eth_dev_reset` function which will reset the device.
Also, as a precaution, null out device pointers to rx and tx queue arrays when we release the queues during a reset. Signed-off-by: Jasper Tran O'Leary <[email protected]> Reviewed-by: Joshua Washington <[email protected]> --- drivers/net/gve/gve_ethdev.c | 40 ++++++++++++++++++++++++++++++++++++++++ drivers/net/gve/gve_rx.c | 2 ++ drivers/net/gve/gve_rx_dqo.c | 2 ++ drivers/net/gve/gve_tx.c | 2 ++ drivers/net/gve/gve_tx_dqo.c | 2 ++ 5 files changed, 48 insertions(+) diff --git a/drivers/net/gve/gve_ethdev.c b/drivers/net/gve/gve_ethdev.c index 6341d89..d62f74b 100644 --- a/drivers/net/gve/gve_ethdev.c +++ b/drivers/net/gve/gve_ethdev.c @@ -12,6 +12,8 @@ #include "gve_rss.h" #include <ethdev_driver.h> +static int gve_init_priv(struct gve_priv *priv, bool skip_describe_device); + static void gve_write_version(uint8_t *driver_version_register) { @@ -550,6 +552,42 @@ gve_dev_close(struct rte_eth_dev *dev) return err; } +static int +gve_dev_reset(struct rte_eth_dev *dev) +{ + struct gve_priv *priv = dev->data->dev_private; + int err = 0; + + if (rte_eal_process_type() != RTE_PROC_PRIMARY) { + PMD_DRV_LOG(ERR, + "Device reset on port %u not supported in secondary processes.", + dev->data->port_id); + return -EPERM; + } + + if (dev->data->dev_started) { + PMD_DRV_LOG(ERR, + "Must stop device on port %u before reset.", + dev->data->port_id); + return -EBUSY; + } + + /* Tear down all device resources before re-initializing. */ + gve_free_queues(dev); + gve_teardown_device_resources(priv); + gve_adminq_free(priv); + + err = gve_init_priv(priv, true); + if (err != 0) { + PMD_DRV_LOG(ERR, + "Failed to re-init device on port %u after reset.", + dev->data->port_id); + return err; + } + + return 0; +} + static int gve_verify_driver_compatibility(struct gve_priv *priv) { @@ -1068,6 +1106,7 @@ static const struct eth_dev_ops gve_eth_dev_ops = { .dev_start = gve_dev_start, .dev_stop = gve_dev_stop, .dev_close = gve_dev_close, + .dev_reset = gve_dev_reset, .dev_infos_get = gve_dev_info_get, .rx_queue_setup = gve_rx_queue_setup, .tx_queue_setup = gve_tx_queue_setup, @@ -1094,6 +1133,7 @@ static const struct eth_dev_ops gve_eth_dev_ops_dqo = { .dev_start = gve_dev_start, .dev_stop = gve_dev_stop, .dev_close = gve_dev_close, + .dev_reset = gve_dev_reset, .dev_infos_get = gve_dev_info_get, .rx_queue_setup = gve_rx_queue_setup_dqo, .tx_queue_setup = gve_tx_queue_setup_dqo, diff --git a/drivers/net/gve/gve_rx.c b/drivers/net/gve/gve_rx.c index 7a91c31..625649c 100644 --- a/drivers/net/gve/gve_rx.c +++ b/drivers/net/gve/gve_rx.c @@ -290,6 +290,8 @@ gve_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid) rte_memzone_free(q->qres_mz); q->qres = NULL; rte_free(q); + + dev->data->rx_queues[qid] = NULL; } int diff --git a/drivers/net/gve/gve_rx_dqo.c b/drivers/net/gve/gve_rx_dqo.c index a0ef21b..3aa82b3 100644 --- a/drivers/net/gve/gve_rx_dqo.c +++ b/drivers/net/gve/gve_rx_dqo.c @@ -252,6 +252,8 @@ gve_rx_queue_release_dqo(struct rte_eth_dev *dev, uint16_t qid) rte_memzone_free(q->qres_mz); q->qres = NULL; rte_free(q); + + dev->data->rx_queues[qid] = NULL; } static void diff --git a/drivers/net/gve/gve_tx.c b/drivers/net/gve/gve_tx.c index 015ea96..5c73c21 100644 --- a/drivers/net/gve/gve_tx.c +++ b/drivers/net/gve/gve_tx.c @@ -547,6 +547,8 @@ gve_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid) rte_memzone_free(q->qres_mz); q->qres = NULL; rte_free(q); + + dev->data->tx_queues[qid] = NULL; } int diff --git a/drivers/net/gve/gve_tx_dqo.c b/drivers/net/gve/gve_tx_dqo.c index 64141ac..4c632d7 100644 --- a/drivers/net/gve/gve_tx_dqo.c +++ b/drivers/net/gve/gve_tx_dqo.c @@ -379,6 +379,8 @@ gve_tx_queue_release_dqo(struct rte_eth_dev *dev, uint16_t qid) rte_memzone_free(q->qres_mz); q->qres = NULL; rte_free(q); + + dev->data->tx_queues[qid] = NULL; } static int -- 2.52.0.351.gbe84eed79e-goog

