Message ID | 20210716122033.22568-1-pali@kernel.org |
---|---|
State | New |
Headers | show |
Series | [stable-4.14] PCI: aardvark: Don't rely on jiffies while holding spinlock | expand |
On Fri, Jul 16, 2021 at 02:20:33PM +0200, Pali Rohár wrote: > From: Remi Pommarel <repk@triplefau.lt> > > commit 7fbcb5da811be7d47468417c7795405058abb3da upstream. > > advk_pcie_wait_pio() can be called while holding a spinlock (from > pci_bus_read_config_dword()), then depends on jiffies in order to > timeout while polling on PIO state registers. In the case the PIO > transaction failed, the timeout will never happen and will also cause > the cpu to stall. > > This decrements a variable and wait instead of using jiffies. > > Signed-off-by: Remi Pommarel <repk@triplefau.lt> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> > Reviewed-by: Andrew Murray <andrew.murray@arm.com> > Acked-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com> > --- > This is backport to 4.14 kernel. Backport of upstream commit can be done > automatically by git cherry-pick command if merge.renamelimit variable is > set to at least 12711. > --- > drivers/pci/host/pci-aardvark.c | 10 +++++----- > 1 file changed, 5 insertions(+), 5 deletions(-) Also queued up to 4.19, thanks. greg k-h
diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c index c1db09fbbe04..5dbbf3d7de36 100644 --- a/drivers/pci/host/pci-aardvark.c +++ b/drivers/pci/host/pci-aardvark.c @@ -185,7 +185,8 @@ (PCIE_CONF_BUS(bus) | PCIE_CONF_DEV(PCI_SLOT(devfn)) | \ PCIE_CONF_FUNC(PCI_FUNC(devfn)) | PCIE_CONF_REG(where)) -#define PIO_TIMEOUT_MS 1 +#define PIO_RETRY_CNT 500 +#define PIO_RETRY_DELAY 2 /* 2 us*/ #define LINK_WAIT_MAX_RETRIES 10 #define LINK_WAIT_USLEEP_MIN 90000 @@ -413,17 +414,16 @@ static void advk_pcie_check_pio_status(struct advk_pcie *pcie) static int advk_pcie_wait_pio(struct advk_pcie *pcie) { struct device *dev = &pcie->pdev->dev; - unsigned long timeout; - - timeout = jiffies + msecs_to_jiffies(PIO_TIMEOUT_MS); + int i; - while (time_before(jiffies, timeout)) { + for (i = 0; i < PIO_RETRY_CNT; i++) { u32 start, isr; start = advk_readl(pcie, PIO_START); isr = advk_readl(pcie, PIO_ISR); if (!start && isr) return 0; + udelay(PIO_RETRY_DELAY); } dev_err(dev, "config read/write timed out\n");