Commit d9407ff1 authored by Brett Creeley's avatar Brett Creeley Committed by Jakub Kicinski

pds_core: Prevent health thread from running during reset/remove

The PCIe reset handlers can run at the same time as the
health thread. This can cause the health thread to
stomp on the PCIe reset. Fix this by preventing the
health thread from running while a PCIe reset is happening.

As part of this use timer_shutdown_sync() during reset and
remove to make sure the timer doesn't ever get rearmed.

Fixes: ffa55858 ("pds_core: implement pci reset handlers")
Signed-off-by: default avatarBrett Creeley <brett.creeley@amd.com>
Reviewed-by: default avatarShannon Nelson <shannon.nelson@amd.com>
Reviewed-by: default avatarPrzemek Kitszel <przemyslaw.kitszel@intel.com>
Link: https://lore.kernel.org/r/20240129234035.69802-2-brett.creeley@amd.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 4d322dce
...@@ -293,7 +293,7 @@ static int pdsc_init_pf(struct pdsc *pdsc) ...@@ -293,7 +293,7 @@ static int pdsc_init_pf(struct pdsc *pdsc)
err_out_teardown: err_out_teardown:
pdsc_teardown(pdsc, PDSC_TEARDOWN_REMOVING); pdsc_teardown(pdsc, PDSC_TEARDOWN_REMOVING);
err_out_unmap_bars: err_out_unmap_bars:
del_timer_sync(&pdsc->wdtimer); timer_shutdown_sync(&pdsc->wdtimer);
if (pdsc->wq) if (pdsc->wq)
destroy_workqueue(pdsc->wq); destroy_workqueue(pdsc->wq);
mutex_destroy(&pdsc->config_lock); mutex_destroy(&pdsc->config_lock);
...@@ -420,7 +420,7 @@ static void pdsc_remove(struct pci_dev *pdev) ...@@ -420,7 +420,7 @@ static void pdsc_remove(struct pci_dev *pdev)
*/ */
pdsc_sriov_configure(pdev, 0); pdsc_sriov_configure(pdev, 0);
del_timer_sync(&pdsc->wdtimer); timer_shutdown_sync(&pdsc->wdtimer);
if (pdsc->wq) if (pdsc->wq)
destroy_workqueue(pdsc->wq); destroy_workqueue(pdsc->wq);
...@@ -445,10 +445,24 @@ static void pdsc_remove(struct pci_dev *pdev) ...@@ -445,10 +445,24 @@ static void pdsc_remove(struct pci_dev *pdev)
devlink_free(dl); devlink_free(dl);
} }
static void pdsc_stop_health_thread(struct pdsc *pdsc)
{
timer_shutdown_sync(&pdsc->wdtimer);
if (pdsc->health_work.func)
cancel_work_sync(&pdsc->health_work);
}
static void pdsc_restart_health_thread(struct pdsc *pdsc)
{
timer_setup(&pdsc->wdtimer, pdsc_wdtimer_cb, 0);
mod_timer(&pdsc->wdtimer, jiffies + 1);
}
void pdsc_reset_prepare(struct pci_dev *pdev) void pdsc_reset_prepare(struct pci_dev *pdev)
{ {
struct pdsc *pdsc = pci_get_drvdata(pdev); struct pdsc *pdsc = pci_get_drvdata(pdev);
pdsc_stop_health_thread(pdsc);
pdsc_fw_down(pdsc); pdsc_fw_down(pdsc);
pci_free_irq_vectors(pdev); pci_free_irq_vectors(pdev);
...@@ -486,6 +500,7 @@ void pdsc_reset_done(struct pci_dev *pdev) ...@@ -486,6 +500,7 @@ void pdsc_reset_done(struct pci_dev *pdev)
} }
pdsc_fw_up(pdsc); pdsc_fw_up(pdsc);
pdsc_restart_health_thread(pdsc);
} }
static const struct pci_error_handlers pdsc_err_handler = { static const struct pci_error_handlers pdsc_err_handler = {
......
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