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

pds_core: Rework teardown/setup flow to be more common

Currently the teardown/setup flow for driver probe/remove is quite
a bit different from the reset flows in pdsc_fw_down()/pdsc_fw_up().
One key piece that's missing are the calls to pci_alloc_irq_vectors()
and pci_free_irq_vectors(). The pcie reset case is calling
pci_free_irq_vectors() on reset_prepare, but not calling the
corresponding pci_alloc_irq_vectors() on reset_done. This is causing
unexpected/unwanted interrupt behavior due to the adminq interrupt
being accidentally put into legacy interrupt mode. Also, the
pci_alloc_irq_vectors()/pci_free_irq_vectors() functions are being
called directly in probe/remove respectively.

Fix this inconsistency by making the following changes:
  1. Always call pdsc_dev_init() in pdsc_setup(), which calls
     pci_alloc_irq_vectors() and get rid of the now unused
     pds_dev_reinit().
  2. Always free/clear the pdsc->intr_info in pdsc_teardown()
     since this structure will get re-alloced in pdsc_setup().
  3. Move the calls of pci_free_irq_vectors() to pdsc_teardown()
     since pci_alloc_irq_vectors() will always be called in
     pdsc_setup()->pdsc_dev_init() for both the probe/remove and
     reset flows.
  4. Make sure to only create the debugfs "identity" entry when it
     doesn't already exist, which it will in the reset case because
     it's already been created in the initial call to pdsc_dev_init().

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>
Link: https://lore.kernel.org/r/20240129234035.69802-7-brett.creeley@amd.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent e96094c1
...@@ -404,10 +404,7 @@ int pdsc_setup(struct pdsc *pdsc, bool init) ...@@ -404,10 +404,7 @@ int pdsc_setup(struct pdsc *pdsc, bool init)
int numdescs; int numdescs;
int err; int err;
if (init)
err = pdsc_dev_init(pdsc); err = pdsc_dev_init(pdsc);
else
err = pdsc_dev_reinit(pdsc);
if (err) if (err)
return err; return err;
...@@ -479,10 +476,9 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing) ...@@ -479,10 +476,9 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing)
for (i = 0; i < pdsc->nintrs; i++) for (i = 0; i < pdsc->nintrs; i++)
pdsc_intr_free(pdsc, i); pdsc_intr_free(pdsc, i);
if (removing) {
kfree(pdsc->intr_info); kfree(pdsc->intr_info);
pdsc->intr_info = NULL; pdsc->intr_info = NULL;
} pdsc->nintrs = 0;
} }
if (pdsc->kern_dbpage) { if (pdsc->kern_dbpage) {
...@@ -490,6 +486,7 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing) ...@@ -490,6 +486,7 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing)
pdsc->kern_dbpage = NULL; pdsc->kern_dbpage = NULL;
} }
pci_free_irq_vectors(pdsc->pdev);
set_bit(PDSC_S_FW_DEAD, &pdsc->state); set_bit(PDSC_S_FW_DEAD, &pdsc->state);
} }
......
...@@ -281,7 +281,6 @@ int pdsc_devcmd_locked(struct pdsc *pdsc, union pds_core_dev_cmd *cmd, ...@@ -281,7 +281,6 @@ int pdsc_devcmd_locked(struct pdsc *pdsc, union pds_core_dev_cmd *cmd,
union pds_core_dev_comp *comp, int max_seconds); union pds_core_dev_comp *comp, int max_seconds);
int pdsc_devcmd_init(struct pdsc *pdsc); int pdsc_devcmd_init(struct pdsc *pdsc);
int pdsc_devcmd_reset(struct pdsc *pdsc); int pdsc_devcmd_reset(struct pdsc *pdsc);
int pdsc_dev_reinit(struct pdsc *pdsc);
int pdsc_dev_init(struct pdsc *pdsc); int pdsc_dev_init(struct pdsc *pdsc);
void pdsc_reset_prepare(struct pci_dev *pdev); void pdsc_reset_prepare(struct pci_dev *pdev);
......
...@@ -64,6 +64,10 @@ DEFINE_SHOW_ATTRIBUTE(identity); ...@@ -64,6 +64,10 @@ DEFINE_SHOW_ATTRIBUTE(identity);
void pdsc_debugfs_add_ident(struct pdsc *pdsc) void pdsc_debugfs_add_ident(struct pdsc *pdsc)
{ {
/* This file will already exist in the reset flow */
if (debugfs_lookup("identity", pdsc->dentry))
return;
debugfs_create_file("identity", 0400, pdsc->dentry, debugfs_create_file("identity", 0400, pdsc->dentry,
pdsc, &identity_fops); pdsc, &identity_fops);
} }
......
...@@ -316,13 +316,6 @@ static int pdsc_identify(struct pdsc *pdsc) ...@@ -316,13 +316,6 @@ static int pdsc_identify(struct pdsc *pdsc)
return 0; return 0;
} }
int pdsc_dev_reinit(struct pdsc *pdsc)
{
pdsc_init_devinfo(pdsc);
return pdsc_identify(pdsc);
}
int pdsc_dev_init(struct pdsc *pdsc) int pdsc_dev_init(struct pdsc *pdsc)
{ {
unsigned int nintrs; unsigned int nintrs;
......
...@@ -438,7 +438,6 @@ static void pdsc_remove(struct pci_dev *pdev) ...@@ -438,7 +438,6 @@ static void pdsc_remove(struct pci_dev *pdev)
mutex_destroy(&pdsc->config_lock); mutex_destroy(&pdsc->config_lock);
mutex_destroy(&pdsc->devcmd_lock); mutex_destroy(&pdsc->devcmd_lock);
pci_free_irq_vectors(pdev);
pdsc_unmap_bars(pdsc); pdsc_unmap_bars(pdsc);
pci_release_regions(pdev); pci_release_regions(pdev);
} }
...@@ -470,7 +469,6 @@ void pdsc_reset_prepare(struct pci_dev *pdev) ...@@ -470,7 +469,6 @@ void pdsc_reset_prepare(struct pci_dev *pdev)
pdsc_stop_health_thread(pdsc); pdsc_stop_health_thread(pdsc);
pdsc_fw_down(pdsc); pdsc_fw_down(pdsc);
pci_free_irq_vectors(pdev);
pdsc_unmap_bars(pdsc); pdsc_unmap_bars(pdsc);
pci_release_regions(pdev); pci_release_regions(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
......
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