Skip to content

Commit

Permalink
iavf: Refactor iavf state machine tracking
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mateusz Palczewski authored and Tony Nguyen committed Oct 18, 2021
1 parent 041c614 commit 45eebd6
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 18 deletions.
10 changes: 10 additions & 0 deletions drivers/net/ethernet/intel/iavf/iavf.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,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;
Expand Down Expand Up @@ -393,6 +394,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);
Expand Down
37 changes: 20 additions & 17 deletions drivers/net/ethernet/intel/iavf/iavf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,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);
Expand Down Expand Up @@ -1729,7 +1729,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;
}
Expand All @@ -1753,7 +1753,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;
}

Expand All @@ -1776,8 +1776,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;
}
Expand Down Expand Up @@ -1893,7 +1892,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();

Expand Down Expand Up @@ -1941,7 +1940,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:
Expand All @@ -1952,7 +1951,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);
mutex_unlock(&adapter->crit_lock);
Expand Down Expand Up @@ -1999,9 +1998,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;
Expand Down Expand Up @@ -2081,7 +2081,7 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)
adapter->netdev->flags &= ~IFF_UP;
mutex_unlock(&adapter->crit_lock);
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");
}
Expand Down Expand Up @@ -2191,7 +2191,7 @@ static void iavf_reset_task(struct work_struct *work)
}
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
Expand Down Expand Up @@ -2291,11 +2291,14 @@ static void iavf_reset_task(struct work_struct *work)

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);
}
mutex_unlock(&adapter->client_lock);
Expand Down Expand Up @@ -3297,7 +3300,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);

mutex_unlock(&adapter->crit_lock);
Expand Down Expand Up @@ -3679,7 +3682,7 @@ static void iavf_init_task(struct work_struct *work)
"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;
}
Expand All @@ -3705,7 +3708,7 @@ static void iavf_shutdown(struct pci_dev *pdev)
if (iavf_lock_timeout(&adapter->crit_lock, 5000))
dev_warn(&adapter->pdev->dev, "failed to acquire crit_lock in %s\n", __FUNCTION__);
/* Prevent the watchdog from running. */
adapter->state = __IAVF_REMOVE;
iavf_change_state(adapter, __IAVF_REMOVE);
adapter->aq_required = 0;
mutex_unlock(&adapter->crit_lock);

Expand Down Expand Up @@ -3778,7 +3781,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);
Expand Down Expand Up @@ -3954,7 +3957,7 @@ static void iavf_remove(struct pci_dev *pdev)
dev_warn(&adapter->pdev->dev, "failed to acquire crit_lock 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);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1735,7 +1735,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;
Expand Down

0 comments on commit 45eebd6

Please sign in to comment.