diff mbox series

[v2] spi: dw: Fix wrong FIFO level setting for long xfers

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

Commit Message

Serge Semin Jan. 13, 2023, 6:59 p.m. UTC
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(-)

Comments

Andy Shevchenko Jan. 13, 2023, 7:17 p.m. UTC | #1
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
> 
>
Mark Brown Jan. 16, 2023, 1:16 p.m. UTC | #2
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 mbox series

Patch

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);