High ping latency is observed when icmp echo requests are
sent from a VPP VF and icmp echo replies get delayed by
~3 seconds which at times, also results in packet loss.

With WB_ON_ITR, the descriptor writeback interval lives in
the IAVF_VFINT_ITRN1 register. This register only resets
during a VF reset, so it could be left with a stale or
uninitialized value causing unreliable or high latency
writeback like high ping latency with VPP VF.

This patch fixes the issue by adding explicit reinitialization
of the separate ITR index interval register (IAVF_VFINT_ITRN1)
to a known 2us value and does not rely on the dynamic control
register (IAVF_VFINT_DYN_CTLN1) for the same.
Also, added a low interval value of 2us in IAVF_VFINT_DYN_CTLN1
ITR index 0 ensuring prompt writeback in polling mode
regardless of what the PF's adaptive algorithm has set in ITRN.

Fixes: ead06572bd8f ("net/iavf: fix performance with writeback policy")
Fixes: a08f9cb698c3 ("net/iavf: fix Rx queue interrupt setting")
Cc: [email protected]

Signed-off-by: Anurag Mandal <[email protected]>
---
 drivers/net/intel/iavf/iavf_ethdev.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/net/intel/iavf/iavf_ethdev.c 
b/drivers/net/intel/iavf/iavf_ethdev.c
index bdf650b822..971c10cefe 100644
--- a/drivers/net/intel/iavf/iavf_ethdev.c
+++ b/drivers/net/intel/iavf/iavf_ethdev.c
@@ -862,6 +862,16 @@ static int iavf_config_rx_queues_irqs(struct rte_eth_dev 
*dev,
                                       (0 << 
IAVF_VFINT_DYN_CTLN1_ITR_INDX_SHIFT) |
                                       IAVF_VFINT_DYN_CTLN1_WB_ON_ITR_MASK |
                                       (2UL << 
IAVF_VFINT_DYN_CTLN1_INTERVAL_SHIFT));
+                       /* The interval value lives in the separate 
IAVF_VFINT_ITRN1
+                        * index register, which is only cleared on a VF reset
+                        * It is not implicitly re-initialized by the DYN_CTLN1 
write
+                        * above, so if it was left dirty by a previous 
configuration,
+                        * program it explicitly here to the same 2us interval 
for
+                        * ITR index 0.
+                        */
+                       IAVF_WRITE_REG(hw,
+                                      IAVF_VFINT_ITRN1(0, vf->msix_base - 1),
+                                      2UL);
                        /* debug - check for success! the return value
                         * should be 2, offset is 0x2800
                         */
@@ -2078,9 +2088,16 @@ iavf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, 
uint16_t queue_id)
                return -EIO;
        }
 
+       /* Set the ITR for index zero, to 2us to make sure that
+        * sufficient time for aggregation to occur, but not to
+        * increase the latency drastically.
+        */
+
        IAVF_WRITE_REG(hw,
                      IAVF_VFINT_DYN_CTLN1(msix_intr - IAVF_RX_VEC_START),
-                     IAVF_VFINT_DYN_CTLN1_WB_ON_ITR_MASK);
+                     (0 << IAVF_VFINT_DYN_CTLN1_ITR_INDX_SHIFT) |
+                     IAVF_VFINT_DYN_CTLN1_WB_ON_ITR_MASK |
+                     (2UL << IAVF_VFINT_DYN_CTLN1_INTERVAL_SHIFT));
 
        IAVF_WRITE_FLUSH(hw);
        return 0;
-- 
2.25.1

Reply via email to