lkml.org 
[lkml]   [2022]   [Jul]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 106/201] i40e: Fix erroneous adapter reinitialization during recovery process
    Date
    From: Dawid Lukwinski <dawid.lukwinski@intel.com>

    [ Upstream commit f838a63369818faadec4ad1736cfbd20ab5da00e ]

    Fix an issue when driver incorrectly detects state
    of recovery process and erroneously reinitializes interrupts,
    which results in a kernel error and call trace message.

    The issue was caused by a combination of two factors:
    1. Assuming the EMP reset issued after completing
    firmware recovery means the whole recovery process is complete.
    2. Erroneous reinitialization of interrupt vector after detecting
    the above mentioned EMP reset.

    Fixes (1) by changing how recovery state change is detected
    and (2) by adjusting the conditional expression to ensure using proper
    interrupt reinitialization method, depending on the situation.

    Fixes: 4ff0ee1af016 ("i40e: Introduce recovery mode support")
    Signed-off-by: Dawid Lukwinski <dawid.lukwinski@intel.com>
    Signed-off-by: Jan Sokolowski <jan.sokolowski@intel.com>
    Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
    Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
    Link: https://lore.kernel.org/r/20220715214542.2968762-1-anthony.l.nguyen@intel.com
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/net/ethernet/intel/i40e/i40e_main.c | 13 +++++--------
    1 file changed, 5 insertions(+), 8 deletions(-)

    diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
    index 02594e4d6258..c801b128e5b2 100644
    --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
    +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
    @@ -10631,7 +10631,7 @@ static int i40e_reset(struct i40e_pf *pf)
    **/
    static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
    {
    - int old_recovery_mode_bit = test_bit(__I40E_RECOVERY_MODE, pf->state);
    + const bool is_recovery_mode_reported = i40e_check_recovery_mode(pf);
    struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
    struct i40e_hw *hw = &pf->hw;
    i40e_status ret;
    @@ -10639,13 +10639,11 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
    int v;

    if (test_bit(__I40E_EMP_RESET_INTR_RECEIVED, pf->state) &&
    - i40e_check_recovery_mode(pf)) {
    + is_recovery_mode_reported)
    i40e_set_ethtool_ops(pf->vsi[pf->lan_vsi]->netdev);
    - }

    if (test_bit(__I40E_DOWN, pf->state) &&
    - !test_bit(__I40E_RECOVERY_MODE, pf->state) &&
    - !old_recovery_mode_bit)
    + !test_bit(__I40E_RECOVERY_MODE, pf->state))
    goto clear_recovery;
    dev_dbg(&pf->pdev->dev, "Rebuilding internal switch\n");

    @@ -10672,13 +10670,12 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
    * accordingly with regard to resources initialization
    * and deinitialization
    */
    - if (test_bit(__I40E_RECOVERY_MODE, pf->state) ||
    - old_recovery_mode_bit) {
    + if (test_bit(__I40E_RECOVERY_MODE, pf->state)) {
    if (i40e_get_capabilities(pf,
    i40e_aqc_opc_list_func_capabilities))
    goto end_unlock;

    - if (test_bit(__I40E_RECOVERY_MODE, pf->state)) {
    + if (is_recovery_mode_reported) {
    /* we're staying in recovery mode so we'll reinitialize
    * misc vector here
    */
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-07-27 19:17    [W:4.205 / U:0.340 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site