net/enetc: do not stall in clean Tx ring
authorAlex Marginean <alexandru.marginean@nxp.com>
Mon, 2 Mar 2020 14:32:00 +0000 (20:02 +0530)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 18 Mar 2020 09:21:41 +0000 (10:21 +0100)
Don't read the hardware CI register in a loop, read it once, clean up
and exit.
The issue with reading the register in a loop is that we're stalling
here trying to catch up with hardware which keeps sending traffic as
long as it has traffic to send, so in effect we could be waiting here
for the Tx ring to be drained by hardware, instead of us doing Rx in
that meantime.
At the time we return the function there may be new BDs in the ring that
could be cleaned, we're just leaving those there for the next time.

Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Acked-by: Gagandeep Singh <g.singh@nxp.com>
drivers/net/enetc/enetc_rxtx.c

index 81b0ef3..b7ecb75 100644 (file)
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2018-2019 NXP
+ * Copyright 2018-2020 NXP
  */
 
 #include <stdbool.h>
@@ -21,12 +21,24 @@ enetc_clean_tx_ring(struct enetc_bdr *tx_ring)
 {
        int tx_frm_cnt = 0;
        struct enetc_swbd *tx_swbd;
-       int i;
+       int i, hwci;
 
        i = tx_ring->next_to_clean;
        tx_swbd = &tx_ring->q_swbd[i];
-       while ((int)(enetc_rd_reg(tx_ring->tcisr) &
-              ENETC_TBCISR_IDX_MASK) != i) {
+
+       hwci = (int)(enetc_rd_reg(tx_ring->tcisr) &
+                    ENETC_TBCISR_IDX_MASK);
+
+       /* we're only reading the CI index once here, which means HW may update
+        * it while we're doing clean-up.  We could read the register in a loop
+        * but for now I assume it's OK to leave a few Tx frames for next call.
+        * The issue with reading the register in a loop is that we're stalling
+        * here trying to catch up with HW which keeps sending traffic as long
+        * as it has traffic to send, so in effect we could be waiting here for
+        * the Tx ring to be drained by HW, instead of us doing Rx in that
+        * meantime.
+        */
+       while (i != hwci) {
                rte_pktmbuf_free(tx_swbd->buffer_addr);
                tx_swbd->buffer_addr = NULL;
                tx_swbd++;