Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 14 Sep 2021 00:48:00 GMT
From:      Kevin Bowling <kbowling@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 71d226bbd9f4 - stable/12 - ixgbe: fix infinite recursion on PCIe link down
Message-ID:  <202109140048.18E0m0le044965@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/12 has been updated by kbowling (ports committer):

URL: https://cgit.FreeBSD.org/src/commit/?id=71d226bbd9f426f7bbc67d0b775eafce7dd7317b

commit 71d226bbd9f426f7bbc67d0b775eafce7dd7317b
Author:     Guinan Sun <guinanx.sun@intel.com>
AuthorDate: 2020-07-09 08:00:31 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2021-09-14 00:42:36 +0000

    ixgbe: fix infinite recursion on PCIe link down
    
    In some corner cases the functions ixgbe_clear_rar_generic and
    ixgbe_clear_vmdq_generic may call one another leading to infinite
    recursion.
    
    When ixgbe_clear_vmdq_generic is called with IXGBE_CLEAR_VMDQ_ALL
    flag, it's going to clear MPSAR registers, and proceed to call
    ixgbe_clear_rar_generic, which in turn will clear the RAR registers,
    and recursively call back ixgbe_clear_vmdq_generic. Normally, the
    latter would detect that MPSAR registers have already been cleared
    and terminate the recursion.
    
    However, when PCIe link is down, and before the driver has had the
    opportunity to shut itself down, all register reads return 0xFFFFFFFF,
    and all register writes fail silently. In such case, because
    ixgbe_clear_vmdq_generic blindly assumes that clearing MPSAR registers
    succeeded, it's going to always call ixgbe_clear_rar_generic, which
    in turn will always call back ixgbe_clear_vmdq_generic, creating
    infinite recursion.
    
    This patch re-reads MPSAR register values after they had been cleared.
    In case of PCIe link failure, the values read will be non-zero, which
    will terminate the recursion. On the other hand, under normal
    circumstances the value read from MPSAR registers is going to be equal
    to the value previously written, so this patch is expected not to cause
    any regressions.
    
    Signed-off-by: Robert Konklewski <robertx.konklewski@intel.com>
    Signed-off-by: Guinan Sun <guinanx.sun@intel.com>
    Reviewed-by: Wei Zhao <wei.zhao1@intel.com>
    
    Approved by:    imp
    Obtained from:  DPDK (2d04b9e856125197ec8e967471426d56ab7efcf0)
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D31621
    
    (cherry picked from commit 8270b7174c48417a4d5f3effa4a4f4588205e687)
---
 sys/dev/ixgbe/ixgbe_common.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/dev/ixgbe/ixgbe_common.c b/sys/dev/ixgbe/ixgbe_common.c
index 7a39efa7787d..509d592cca3b 100644
--- a/sys/dev/ixgbe/ixgbe_common.c
+++ b/sys/dev/ixgbe/ixgbe_common.c
@@ -3813,11 +3813,11 @@ s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
 	if (vmdq == IXGBE_CLEAR_VMDQ_ALL) {
 		if (mpsar_lo) {
 			IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0);
-			mpsar_lo = 0;
+			mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
 		}
 		if (mpsar_hi) {
 			IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0);
-			mpsar_hi = 0;
+			mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
 		}
 	} else if (vmdq < 32) {
 		mpsar_lo &= ~(1 << vmdq);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202109140048.18E0m0le044965>