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]>
---
 .mailmap                          |  1 +
 drivers/net/gve/base/gve_adminq.c | 68 +++++++++++++++++++++++++------
 drivers/net/gve/gve_ethdev.h      |  1 +
 3 files changed, 57 insertions(+), 13 deletions(-)

diff --git a/.mailmap b/.mailmap
index 3ab7364668..7f7590866b 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1009,6 +1009,7 @@ Mario Carrillo <[email protected]>
 Mário Kuka <[email protected]>
 Mariusz Drost <[email protected]>
 Mark Asselstine <[email protected]>
+Mark Blasko <[email protected]>
 Mark Bloch <[email protected]> <[email protected]>
 Mark Gillott <[email protected]>
 Mark Kavanagh <[email protected]>
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

Reply via email to