Message ID | 20230113185942.2516-1-Sergey.Semin@baikalelectronics.ru (mailing list archive) |
---|---|
State | Accepted |
Commit | c63b8fd14a7db719f8252038a790638728c4eb66 |
Headers | show |
Series | [v2] spi: dw: Fix wrong FIFO level setting for long xfers | expand |
On Fri, Jan 13, 2023 at 09:59:42PM +0300, Serge Semin wrote: > Due to using the u16 type in the min_t() macros the SPI transfer length > will be cast to word before participating in the conditional statement > implied by the macro. Thus if the transfer length is greater than 64KB the > Tx/Rx FIFO threshold level value will be determined by the leftover of the > truncated after the type-case length. In the worst case it will cause the > dramatical performance drop due to the "Tx FIFO Empty" or "Rx FIFO Full" > interrupts triggered on each xfer word sent/received to/from the bus. > > The problem can be easily fixed by specifying the unsigned int type in the > min_t() macros thus preventing the possible data loss. LGTM, Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> thanks! > Fixes: ea11370fffdf ("spi: dw: get TX level without an additional variable") > Reported-by: Sergey Nazarov <Sergey.Nazarov@baikalelectronics.ru> > Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> > > --- > > Changelog v2: > - Use min_t(unisgned int, ...) macros instead of just min(). (@Andy) > --- > drivers/spi/spi-dw-core.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c > index 99edddf9958b..c3bfb6c84cab 100644 > --- a/drivers/spi/spi-dw-core.c > +++ b/drivers/spi/spi-dw-core.c > @@ -366,7 +366,7 @@ static void dw_spi_irq_setup(struct dw_spi *dws) > * will be adjusted at the final stage of the IRQ-based SPI transfer > * execution so not to lose the leftover of the incoming data. > */ > - level = min_t(u16, dws->fifo_len / 2, dws->tx_len); > + level = min_t(unsigned int, dws->fifo_len / 2, dws->tx_len); > dw_writel(dws, DW_SPI_TXFTLR, level); > dw_writel(dws, DW_SPI_RXFTLR, level - 1); > > -- > 2.39.0 > >
On Fri, 13 Jan 2023 21:59:42 +0300, Serge Semin wrote: > Due to using the u16 type in the min_t() macros the SPI transfer length > will be cast to word before participating in the conditional statement > implied by the macro. Thus if the transfer length is greater than 64KB the > Tx/Rx FIFO threshold level value will be determined by the leftover of the > truncated after the type-case length. In the worst case it will cause the > dramatical performance drop due to the "Tx FIFO Empty" or "Rx FIFO Full" > interrupts triggered on each xfer word sent/received to/from the bus. > > [...] Applied to broonie/spi.git for-next Thanks! [1/1] spi: dw: Fix wrong FIFO level setting for long xfers commit: 9ef7b7b43eb708c114bb3ce6c0acadd74065bf4e All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark
diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index 99edddf9958b..c3bfb6c84cab 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -366,7 +366,7 @@ static void dw_spi_irq_setup(struct dw_spi *dws) * will be adjusted at the final stage of the IRQ-based SPI transfer * execution so not to lose the leftover of the incoming data. */ - level = min_t(u16, dws->fifo_len / 2, dws->tx_len); + level = min_t(unsigned int, dws->fifo_len / 2, dws->tx_len); dw_writel(dws, DW_SPI_TXFTLR, level); dw_writel(dws, DW_SPI_RXFTLR, level - 1);
Due to using the u16 type in the min_t() macros the SPI transfer length will be cast to word before participating in the conditional statement implied by the macro. Thus if the transfer length is greater than 64KB the Tx/Rx FIFO threshold level value will be determined by the leftover of the truncated after the type-case length. In the worst case it will cause the dramatical performance drop due to the "Tx FIFO Empty" or "Rx FIFO Full" interrupts triggered on each xfer word sent/received to/from the bus. The problem can be easily fixed by specifying the unsigned int type in the min_t() macros thus preventing the possible data loss. Fixes: ea11370fffdf ("spi: dw: get TX level without an additional variable") Reported-by: Sergey Nazarov <Sergey.Nazarov@baikalelectronics.ru> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> --- Changelog v2: - Use min_t(unisgned int, ...) macros instead of just min(). (@Andy) --- drivers/spi/spi-dw-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)