Commit ddbb8d5d authored by Shiraz Saleem's avatar Shiraz Saleem Committed by Jeff Kirsher

i40e: Close client on suspend and restore client MSIx on resume

During suspend client MSIx vectors are freed while they are still
in use causing a crash on entering S3.

Fix this calling client close before freeing up its MSIx vectors.
Also update the client MSIx vectors on resume before client
open is called.

Fixes commit b980c063 ("i40e: shutdown all IRQs and disable MSI-X
when suspended")
Reported-by: default avatarStefan Assmann <sassmann@redhat.com>
Signed-off-by: default avatarShiraz Saleem <shiraz.saleem@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 88244a48
...@@ -1041,6 +1041,7 @@ void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi); ...@@ -1041,6 +1041,7 @@ void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi);
void i40e_notify_client_of_netdev_close(struct i40e_vsi *vsi, bool reset); void i40e_notify_client_of_netdev_close(struct i40e_vsi *vsi, bool reset);
void i40e_notify_client_of_vf_enable(struct i40e_pf *pf, u32 num_vfs); void i40e_notify_client_of_vf_enable(struct i40e_pf *pf, u32 num_vfs);
void i40e_notify_client_of_vf_reset(struct i40e_pf *pf, u32 vf_id); void i40e_notify_client_of_vf_reset(struct i40e_pf *pf, u32 vf_id);
void i40e_client_update_msix_info(struct i40e_pf *pf);
int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id); int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id);
/** /**
* i40e_irq_dynamic_enable - Enable default interrupt generation settings * i40e_irq_dynamic_enable - Enable default interrupt generation settings
......
...@@ -287,6 +287,17 @@ int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id) ...@@ -287,6 +287,17 @@ int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id)
return capable; return capable;
} }
void i40e_client_update_msix_info(struct i40e_pf *pf)
{
struct i40e_client_instance *cdev = pf->cinst;
if (!cdev || !cdev->client)
return;
cdev->lan_info.msix_count = pf->num_iwarp_msix;
cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector];
}
/** /**
* i40e_client_add_instance - add a client instance struct to the instance list * i40e_client_add_instance - add a client instance struct to the instance list
* @pf: pointer to the board struct * @pf: pointer to the board struct
...@@ -328,9 +339,6 @@ static void i40e_client_add_instance(struct i40e_pf *pf) ...@@ -328,9 +339,6 @@ static void i40e_client_add_instance(struct i40e_pf *pf)
return; return;
} }
cdev->lan_info.msix_count = pf->num_iwarp_msix;
cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector];
mac = list_first_entry(&cdev->lan_info.netdev->dev_addrs.list, mac = list_first_entry(&cdev->lan_info.netdev->dev_addrs.list,
struct netdev_hw_addr, list); struct netdev_hw_addr, list);
if (mac) if (mac)
...@@ -340,6 +348,8 @@ static void i40e_client_add_instance(struct i40e_pf *pf) ...@@ -340,6 +348,8 @@ static void i40e_client_add_instance(struct i40e_pf *pf)
cdev->client = registered_client; cdev->client = registered_client;
pf->cinst = cdev; pf->cinst = cdev;
i40e_client_update_msix_info(pf);
} }
/** /**
......
...@@ -10594,6 +10594,9 @@ static int i40e_restore_interrupt_scheme(struct i40e_pf *pf) ...@@ -10594,6 +10594,9 @@ static int i40e_restore_interrupt_scheme(struct i40e_pf *pf)
if (err) if (err)
goto err_unwind; goto err_unwind;
if (pf->flags & I40E_FLAG_IWARP_ENABLED)
i40e_client_update_msix_info(pf);
return 0; return 0;
err_unwind: err_unwind:
...@@ -14344,6 +14347,11 @@ static int __maybe_unused i40e_suspend(struct device *dev) ...@@ -14344,6 +14347,11 @@ static int __maybe_unused i40e_suspend(struct device *dev)
del_timer_sync(&pf->service_timer); del_timer_sync(&pf->service_timer);
cancel_work_sync(&pf->service_task); cancel_work_sync(&pf->service_task);
/* Client close must be called explicitly here because the timer
* has been stopped.
*/
i40e_notify_client_of_netdev_close(pf->vsi[pf->lan_vsi], false);
if (pf->wol_en && (pf->hw_features & I40E_HW_WOL_MC_MAGIC_PKT_WAKE)) if (pf->wol_en && (pf->hw_features & I40E_HW_WOL_MC_MAGIC_PKT_WAKE))
i40e_enable_mc_magic_wake(pf); i40e_enable_mc_magic_wake(pf);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment