]> git.droids-corp.org - dpdk.git/commitdiff
net/ena: prevent double doorbell
authorIgor Chauskin <igorch@amazon.com>
Tue, 26 Jan 2021 18:32:26 +0000 (19:32 +0100)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 29 Jan 2021 17:16:12 +0000 (18:16 +0100)
Add per-tx-ring flag for packets that were pushed to HW but await
doorbell. That is to prevent a situation when a doorbell is sent due to
reaching Tx burst threshold and next send fails (e.g., due to queue
full). In such case we shouldn't send another doorbell because there are
no actual packets waiting for transmission.

Fixes: c7519ea5eb8d ("net/ena: call additional doorbells if needed")
Cc: stable@dpdk.org
Signed-off-by: Igor Chauskin <igorch@amazon.com>
Reviewed-by: Michal Krawczyk <mk@semihalf.com>
drivers/net/ena/ena_ethdev.c
drivers/net/ena/ena_ethdev.h

index 8a937d7f278a1fef8fe668cd4526b90313bf7882..7acbf5e3051614bf397b8cd443f64a183e35b9ef 100644 (file)
@@ -1282,6 +1282,7 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev,
        txq->ring_size = nb_desc;
        txq->size_mask = nb_desc - 1;
        txq->numa_socket_id = socket_id;
+       txq->pkts_without_db = false;
 
        txq->tx_buffer_info = rte_zmalloc("txq->tx_buffer_info",
                                          sizeof(struct ena_tx_buffer) *
@@ -2522,6 +2523,7 @@ static int ena_xmit_mbuf(struct ena_ring *tx_ring, struct rte_mbuf *mbuf)
                        tx_ring->id);
                ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq);
                tx_ring->tx_stats.doorbells++;
+               tx_ring->pkts_without_db = false;
        }
 
        /* prepare the packet's descriptors to dma engine */
@@ -2603,7 +2605,7 @@ static uint16_t eth_ena_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
        for (sent_idx = 0; sent_idx < nb_pkts; sent_idx++) {
                if (ena_xmit_mbuf(tx_ring, tx_pkts[sent_idx]))
                        break;
-
+               tx_ring->pkts_without_db = true;
                rte_prefetch0(tx_pkts[ENA_IDX_ADD_MASKED(sent_idx, 4,
                        tx_ring->size_mask)]);
        }
@@ -2612,10 +2614,11 @@ static uint16_t eth_ena_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
                ena_com_free_q_entries(tx_ring->ena_com_io_sq);
 
        /* If there are ready packets to be xmitted... */
-       if (sent_idx > 0) {
+       if (likely(tx_ring->pkts_without_db)) {
                /* ...let HW do its best :-) */
                ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq);
                tx_ring->tx_stats.doorbells++;
+               tx_ring->pkts_without_db = false;
        }
 
        ena_tx_cleanup(tx_ring);
index 7bb74a1d0605dd04af94d1db059f1745a46244d9..ae235897eeb722289193c8582f42f296b1f709d6 100644 (file)
@@ -100,6 +100,10 @@ struct ena_ring {
 
        enum ena_ring_type type;
        enum ena_admin_placement_policy_type tx_mem_queue_type;
+
+       /* Indicate there are Tx packets pushed to the device and wait for db */
+       bool pkts_without_db;
+
        /* Holds the empty requests for TX/RX OOO completions */
        union {
                uint16_t *empty_tx_reqs;