From: Mark Blasko <[email protected]> Introduce a pthread_mutex to protect the admin queue operations. Locking was added around gve_adminq_execute_cmd and the batch queue creation/destruction functions.
Signed-off-by: Mark Blasko <[email protected]> Reviewed-by: Joshua Washington <[email protected]> Reviewed-by: Jasper Tran O'Leary <[email protected]> --- drivers/net/gve/base/gve_adminq.c | 68 +++++++++++++++++++++++++------ drivers/net/gve/gve_ethdev.h | 1 + 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/drivers/net/gve/base/gve_adminq.c b/drivers/net/gve/base/gve_adminq.c index 9c5316fb00..28661fb6cd 100644 --- a/drivers/net/gve/base/gve_adminq.c +++ b/drivers/net/gve/base/gve_adminq.c @@ -216,6 +216,7 @@ gve_process_device_options(struct gve_priv *priv, int gve_adminq_alloc(struct gve_priv *priv) { + pthread_mutexattr_t mutexattr; uint8_t pci_rev_id; priv->adminq = gve_alloc_dma_mem(&priv->adminq_dma_mem, PAGE_SIZE); @@ -241,6 +242,12 @@ int gve_adminq_alloc(struct gve_priv *priv) priv->adminq_get_ptype_map_cnt = 0; priv->adminq_cfg_flow_rule_cnt = 0; + pthread_mutexattr_init(&mutexattr); + pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED); + pthread_mutexattr_setrobust(&mutexattr, PTHREAD_MUTEX_ROBUST); + pthread_mutex_init(&priv->adminq_lock, &mutexattr); + pthread_mutexattr_destroy(&mutexattr); + /* Setup Admin queue with the device */ rte_pci_read_config(priv->pci_dev, &pci_rev_id, sizeof(pci_rev_id), RTE_PCI_REVISION_ID); @@ -304,6 +311,7 @@ void gve_adminq_free(struct gve_priv *priv) return; gve_adminq_release(priv); gve_free_dma_mem(&priv->adminq_dma_mem); + pthread_mutex_destroy(&priv->adminq_lock); gve_clear_admin_queue_ok(priv); } @@ -418,7 +426,10 @@ static int gve_adminq_issue_cmd(struct gve_priv *priv, (tail & priv->adminq_mask)) { int err; - /* Flush existing commands to make room. */ + /* Flush existing commands to make room. + * Note: This kicks the doorbell for all staged commands. + * Any failure here means we failed after attempting to kick. + */ err = gve_adminq_kick_and_wait(priv); if (err) return err; @@ -509,17 +520,24 @@ static int gve_adminq_execute_cmd(struct gve_priv *priv, u32 tail, head; int err; + pthread_mutex_lock(&priv->adminq_lock); tail = ioread32be(&priv->reg_bar0->adminq_event_counter); head = priv->adminq_prod_cnt; - if (tail != head) + if (tail != head) { /* This is not a valid path */ - return -EINVAL; + err = -EINVAL; + goto unlock_and_return; + } err = gve_adminq_issue_cmd(priv, cmd_orig); if (err) - return err; + goto unlock_and_return; - return gve_adminq_kick_and_wait(priv); + err = gve_adminq_kick_and_wait(priv); + +unlock_and_return: + pthread_mutex_unlock(&priv->adminq_lock); + return err; } static int gve_adminq_execute_extended_cmd(struct gve_priv *priv, u32 opcode, @@ -693,13 +711,19 @@ int gve_adminq_create_tx_queues(struct gve_priv *priv, u32 num_queues) int err; u32 i; + pthread_mutex_lock(&priv->adminq_lock); + for (i = 0; i < num_queues; i++) { err = gve_adminq_create_tx_queue(priv, i); if (err) - return err; + goto unlock_and_return; } - return gve_adminq_kick_and_wait(priv); + err = gve_adminq_kick_and_wait(priv); + +unlock_and_return: + pthread_mutex_unlock(&priv->adminq_lock); + return err; } static int gve_adminq_create_rx_queue(struct gve_priv *priv, u32 queue_index) @@ -747,13 +771,19 @@ int gve_adminq_create_rx_queues(struct gve_priv *priv, u32 num_queues) int err; u32 i; + pthread_mutex_lock(&priv->adminq_lock); + for (i = 0; i < num_queues; i++) { err = gve_adminq_create_rx_queue(priv, i); if (err) - return err; + goto unlock_and_return; } - return gve_adminq_kick_and_wait(priv); + err = gve_adminq_kick_and_wait(priv); + +unlock_and_return: + pthread_mutex_unlock(&priv->adminq_lock); + return err; } static int gve_adminq_destroy_tx_queue(struct gve_priv *priv, u32 queue_index) @@ -779,13 +809,19 @@ int gve_adminq_destroy_tx_queues(struct gve_priv *priv, u32 num_queues) int err; u32 i; + pthread_mutex_lock(&priv->adminq_lock); + for (i = 0; i < num_queues; i++) { err = gve_adminq_destroy_tx_queue(priv, i); if (err) - return err; + goto unlock_and_return; } - return gve_adminq_kick_and_wait(priv); + err = gve_adminq_kick_and_wait(priv); + +unlock_and_return: + pthread_mutex_unlock(&priv->adminq_lock); + return err; } static int gve_adminq_destroy_rx_queue(struct gve_priv *priv, u32 queue_index) @@ -811,13 +847,19 @@ int gve_adminq_destroy_rx_queues(struct gve_priv *priv, u32 num_queues) int err; u32 i; + pthread_mutex_lock(&priv->adminq_lock); + for (i = 0; i < num_queues; i++) { err = gve_adminq_destroy_rx_queue(priv, i); if (err) - return err; + goto unlock_and_return; } - return gve_adminq_kick_and_wait(priv); + err = gve_adminq_kick_and_wait(priv); + +unlock_and_return: + pthread_mutex_unlock(&priv->adminq_lock); + return err; } static int gve_set_desc_cnt(struct gve_priv *priv, diff --git a/drivers/net/gve/gve_ethdev.h b/drivers/net/gve/gve_ethdev.h index 0577f03974..524e48e723 100644 --- a/drivers/net/gve/gve_ethdev.h +++ b/drivers/net/gve/gve_ethdev.h @@ -339,6 +339,7 @@ struct gve_priv { struct gve_tx_queue **txqs; struct gve_rx_queue **rxqs; + pthread_mutex_t adminq_lock; /* Protects AdminQ command execution */ uint32_t stats_report_len; const struct rte_memzone *stats_report_mem; uint16_t stats_start_idx; /* start index of array of stats written by NIC */ -- 2.54.0.563.g4f69b47b94-goog

