iavf: Refactor iavf state machine tracking
authorMateusz Palczewski <mateusz.palczewski@intel.com>
Thu, 19 Aug 2021 08:47:40 +0000 (08:47 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 Mar 2022 18:09:37 +0000 (19:09 +0100)
[ Upstream commit 45eebd62999d37d13568723524b99d828e0ce22c ]

Replace state changes of iavf state machine
with a method that also tracks the previous
state the machine was on.

This change is required for further work with
refactoring init and watchdog state machines.

Tracking of previous state would help us
recover iavf after failure has occurred.

Signed-off-by: Jakub Pawlak <jakub.pawlak@intel.com>
Signed-off-by: Jan Sokolowski <jan.sokolowski@intel.com>
Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/intel/iavf/iavf.h
drivers/net/ethernet/intel/iavf/iavf_main.c
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c

index 6766446a33f49b13b6385026585c90827b630ab8..ce1e2fb22e09283302ad55e740b145a4f4ce6fa5 100644 (file)
@@ -309,6 +309,7 @@ struct iavf_adapter {
        struct iavf_hw hw; /* defined in iavf_type.h */
 
        enum iavf_state_t state;
+       enum iavf_state_t last_state;
        unsigned long crit_section;
 
        struct delayed_work watchdog_task;
@@ -378,6 +379,15 @@ struct iavf_device {
 extern char iavf_driver_name[];
 extern struct workqueue_struct *iavf_wq;
 
+static inline void iavf_change_state(struct iavf_adapter *adapter,
+                                    enum iavf_state_t state)
+{
+       if (adapter->state != state) {
+               adapter->last_state = adapter->state;
+               adapter->state = state;
+       }
+}
+
 int iavf_up(struct iavf_adapter *adapter);
 void iavf_down(struct iavf_adapter *adapter);
 int iavf_process_config(struct iavf_adapter *adapter);
index 07170b77d42b6028e15ef4ebc33ed9cc1e1e301f..bd1fb3774769b0c301d31f2e87a572cffd7c143f 100644 (file)
@@ -963,7 +963,7 @@ static void iavf_configure(struct iavf_adapter *adapter)
  **/
 static void iavf_up_complete(struct iavf_adapter *adapter)
 {
-       adapter->state = __IAVF_RUNNING;
+       iavf_change_state(adapter, __IAVF_RUNNING);
        clear_bit(__IAVF_VSI_DOWN, adapter->vsi.state);
 
        iavf_napi_enable_all(adapter);
@@ -1698,7 +1698,7 @@ static int iavf_startup(struct iavf_adapter *adapter)
                iavf_shutdown_adminq(hw);
                goto err;
        }
-       adapter->state = __IAVF_INIT_VERSION_CHECK;
+       iavf_change_state(adapter, __IAVF_INIT_VERSION_CHECK);
 err:
        return err;
 }
@@ -1722,7 +1722,7 @@ static int iavf_init_version_check(struct iavf_adapter *adapter)
        if (!iavf_asq_done(hw)) {
                dev_err(&pdev->dev, "Admin queue command never completed\n");
                iavf_shutdown_adminq(hw);
-               adapter->state = __IAVF_STARTUP;
+               iavf_change_state(adapter, __IAVF_STARTUP);
                goto err;
        }
 
@@ -1745,8 +1745,7 @@ static int iavf_init_version_check(struct iavf_adapter *adapter)
                        err);
                goto err;
        }
-       adapter->state = __IAVF_INIT_GET_RESOURCES;
-
+       iavf_change_state(adapter, __IAVF_INIT_GET_RESOURCES);
 err:
        return err;
 }
@@ -1862,7 +1861,7 @@ static int iavf_init_get_resources(struct iavf_adapter *adapter)
        if (netdev->features & NETIF_F_GRO)
                dev_info(&pdev->dev, "GRO is enabled\n");
 
-       adapter->state = __IAVF_DOWN;
+       iavf_change_state(adapter, __IAVF_DOWN);
        set_bit(__IAVF_VSI_DOWN, adapter->vsi.state);
        rtnl_unlock();
 
@@ -1910,7 +1909,7 @@ static void iavf_watchdog_task(struct work_struct *work)
                goto restart_watchdog;
 
        if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
-               adapter->state = __IAVF_COMM_FAILED;
+               iavf_change_state(adapter, __IAVF_COMM_FAILED);
 
        switch (adapter->state) {
        case __IAVF_COMM_FAILED:
@@ -1921,7 +1920,7 @@ static void iavf_watchdog_task(struct work_struct *work)
                        /* A chance for redemption! */
                        dev_err(&adapter->pdev->dev,
                                "Hardware came out of reset. Attempting reinit.\n");
-                       adapter->state = __IAVF_STARTUP;
+                       iavf_change_state(adapter, __IAVF_STARTUP);
                        adapter->flags &= ~IAVF_FLAG_PF_COMMS_FAILED;
                        queue_delayed_work(iavf_wq, &adapter->init_task, 10);
                        clear_bit(__IAVF_IN_CRITICAL_TASK,
@@ -1971,9 +1970,10 @@ static void iavf_watchdog_task(struct work_struct *work)
                goto restart_watchdog;
        }
 
-               /* check for hw reset */
+       /* check for hw reset */
        reg_val = rd32(hw, IAVF_VF_ARQLEN1) & IAVF_VF_ARQLEN1_ARQENABLE_MASK;
        if (!reg_val) {
+               iavf_change_state(adapter, __IAVF_RESETTING);
                adapter->flags |= IAVF_FLAG_RESET_PENDING;
                adapter->aq_required = 0;
                adapter->current_op = VIRTCHNL_OP_UNKNOWN;
@@ -2053,7 +2053,7 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)
        adapter->netdev->flags &= ~IFF_UP;
        clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section);
        adapter->flags &= ~IAVF_FLAG_RESET_PENDING;
-       adapter->state = __IAVF_DOWN;
+       iavf_change_state(adapter, __IAVF_DOWN);
        wake_up(&adapter->down_waitqueue);
        dev_info(&adapter->pdev->dev, "Reset task did not complete, VF disabled\n");
 }
@@ -2165,7 +2165,7 @@ continue_reset:
        }
        iavf_irq_disable(adapter);
 
-       adapter->state = __IAVF_RESETTING;
+       iavf_change_state(adapter, __IAVF_RESETTING);
        adapter->flags &= ~IAVF_FLAG_RESET_PENDING;
 
        /* free the Tx/Rx rings and descriptors, might be better to just
@@ -2265,11 +2265,14 @@ continue_reset:
 
                iavf_configure(adapter);
 
+               /* iavf_up_complete() will switch device back
+                * to __IAVF_RUNNING
+                */
                iavf_up_complete(adapter);
 
                iavf_irq_enable(adapter, true);
        } else {
-               adapter->state = __IAVF_DOWN;
+               iavf_change_state(adapter, __IAVF_DOWN);
                wake_up(&adapter->down_waitqueue);
        }
        clear_bit(__IAVF_IN_CLIENT_TASK, &adapter->crit_section);
@@ -3277,7 +3280,7 @@ static int iavf_close(struct net_device *netdev)
                adapter->flags |= IAVF_FLAG_CLIENT_NEEDS_CLOSE;
 
        iavf_down(adapter);
-       adapter->state = __IAVF_DOWN_PENDING;
+       iavf_change_state(adapter, __IAVF_DOWN_PENDING);
        iavf_free_traffic_irqs(adapter);
 
        clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section);
@@ -3661,7 +3664,7 @@ init_failed:
                        "Failed to communicate with PF; waiting before retry\n");
                adapter->flags |= IAVF_FLAG_PF_COMMS_FAILED;
                iavf_shutdown_adminq(hw);
-               adapter->state = __IAVF_STARTUP;
+               iavf_change_state(adapter, __IAVF_STARTUP);
                queue_delayed_work(iavf_wq, &adapter->init_task, HZ * 5);
                goto out;
        }
@@ -3687,7 +3690,7 @@ static void iavf_shutdown(struct pci_dev *pdev)
        if (iavf_lock_timeout(adapter, __IAVF_IN_CRITICAL_TASK, 5000))
                dev_warn(&adapter->pdev->dev, "failed to set __IAVF_IN_CRITICAL_TASK in %s\n", __FUNCTION__);
        /* Prevent the watchdog from running. */
-       adapter->state = __IAVF_REMOVE;
+       iavf_change_state(adapter, __IAVF_REMOVE);
        adapter->aq_required = 0;
        clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section);
 
@@ -3760,7 +3763,7 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        hw->back = adapter;
 
        adapter->msg_enable = BIT(DEFAULT_DEBUG_LEVEL_SHIFT) - 1;
-       adapter->state = __IAVF_STARTUP;
+       iavf_change_state(adapter, __IAVF_STARTUP);
 
        /* Call save state here because it relies on the adapter struct. */
        pci_save_state(pdev);
@@ -3928,7 +3931,7 @@ static void iavf_remove(struct pci_dev *pdev)
                dev_warn(&adapter->pdev->dev, "failed to set __IAVF_IN_CRITICAL_TASK in %s\n", __FUNCTION__);
 
        /* Shut down all the garbage mashers on the detention level */
-       adapter->state = __IAVF_REMOVE;
+       iavf_change_state(adapter, __IAVF_REMOVE);
        adapter->aq_required = 0;
        adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
        iavf_free_all_tx_resources(adapter);
index 8be3151f2c62b5c4d4ffd03dd1d935a4ee6fb15a..ff479bf7214433755a193951c51cad33afceefa2 100644 (file)
@@ -1460,7 +1460,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
                iavf_free_all_tx_resources(adapter);
                iavf_free_all_rx_resources(adapter);
                if (adapter->state == __IAVF_DOWN_PENDING) {
-                       adapter->state = __IAVF_DOWN;
+                       iavf_change_state(adapter, __IAVF_DOWN);
                        wake_up(&adapter->down_waitqueue);
                }
                break;