Skip to content

SPI is totally broken on 5.10 / RPi4 #4100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mdevaev opened this issue Jan 28, 2021 · 9 comments
Closed

SPI is totally broken on 5.10 / RPi4 #4100

mdevaev opened this issue Jan 28, 2021 · 9 comments

Comments

@mdevaev
Copy link
Contributor

mdevaev commented Jan 28, 2021

Describe the bug
When trying to use SPI on 5.10, a crash occurs in the kernel:

[  122.388314] rcu: INFO: rcu_sched self-detected stall on CPU
[  122.393915] rcu: 	3-....: (2099 ticks this GP) idle=676/1/0x40000002 softirq=2548/2548 fqs=1036 
[  122.402723] 	(t=2100 jiffies g=2505 q=679)
[  122.406825] NMI backtrace for cpu 3
[  122.410320] CPU: 3 PID: 512 Comm: python3 Tainted: G         C        5.10.10-1-ARCH #1
[  122.418342] Hardware name: BCM2711
[  122.421762] [<c020f0a0>] (unwind_backtrace) from [<c020ae7c>] (show_stack+0x10/0x14)
[  122.429527] [<c020ae7c>] (show_stack) from [<c0dd7d24>] (dump_stack+0xa4/0xc4)
[  122.436772] [<c0dd7d24>] (dump_stack) from [<c09647c8>] (nmi_cpu_backtrace+0xc8/0xf4)
[  122.444624] [<c09647c8>] (nmi_cpu_backtrace) from [<c09648f8>] (nmi_trigger_cpumask_backtrace+0x104/0x140)
[  122.454305] [<c09648f8>] (nmi_trigger_cpumask_backtrace) from [<c0dd115c>] (rcu_dump_cpu_stacks+0xe4/0x10c)
[  122.464076] [<c0dd115c>] (rcu_dump_cpu_stacks) from [<c02a2494>] (rcu_sched_clock_irq+0x7cc/0xa54)
[  122.473683] [<c02a2494>] (rcu_sched_clock_irq) from [<c02ae484>] (update_process_times+0x5c/0x84)
[  122.483830] [<c02ae484>] (update_process_times) from [<c02c0558>] (tick_sched_handle+0x54/0x60)
[  122.493814] [<c02c0558>] (tick_sched_handle) from [<c02c0aa8>] (tick_sched_timer+0x7c/0x118)
[  122.503522] [<c02c0aa8>] (tick_sched_timer) from [<c02aece0>] (__hrtimer_run_queues+0x17c/0x338)
[  122.513591] [<c02aece0>] (__hrtimer_run_queues) from [<c02afbe4>] (hrtimer_interrupt+0x124/0x2b4)
[  122.523737] [<c02afbe4>] (hrtimer_interrupt) from [<c0c07f54>] (arch_timer_handler_phys+0x28/0x30)
[  122.533990] [<c0c07f54>] (arch_timer_handler_phys) from [<c0293960>] (handle_percpu_devid_irq+0x7c/0x224)
[  122.544876] [<c0293960>] (handle_percpu_devid_irq) from [<c028da24>] (__handle_domain_irq+0x7c/0xd0)
[  122.555363] [<c028da24>] (__handle_domain_irq) from [<c0976f38>] (gic_handle_irq+0x80/0x94)
[  122.565090] [<c0976f38>] (gic_handle_irq) from [<c0200af8>] (__irq_svc+0x58/0x74)
[  122.573954] Exception stack(0xccc33ca0 to 0xccc33ce8)
[  122.579701] 3ca0: 00000000 f010ed5b f080d000 00000000 c3e5ab80 c3e5a800 00000003 c3e5ab80
[  122.589278] 3cc0: ccc33e58 bf21d000 c3999800 ffffe000 c1afda00 ccc33cf0 bf21b188 bf21b384
[  122.598852] 3ce0: 60010013 ffffffff
[  122.603043] [<c0200af8>] (__irq_svc) from [<bf21b384>] (bcm2835_spi_transfer_one+0x31c/0xb50 [spi_bcm2835])
[  122.614200] [<bf21b384>] (bcm2835_spi_transfer_one [spi_bcm2835]) from [<c0a8ed40>] (spi_transfer_one_message+0x250/0x668)
[  122.626657] [<c0a8ed40>] (spi_transfer_one_message) from [<c0a90cd0>] (__spi_pump_messages+0x39c/0x7c8)
[  122.637450] [<c0a90cd0>] (__spi_pump_messages) from [<c0a913bc>] (__spi_sync+0x2b4/0x2d4)
[  122.647033] [<c0a913bc>] (__spi_sync) from [<c0a91400>] (spi_sync+0x24/0x3c)
[  122.654801] [<c0a91400>] (spi_sync) from [<bf2e82d0>] (spidev_sync+0x44/0x58 [spidev])
[  122.664143] [<bf2e82d0>] (spidev_sync [spidev]) from [<bf2e8414>] (spidev_sync_read+0x84/0xa8 [spidev])
[  122.674972] [<bf2e8414>] (spidev_sync_read [spidev]) from [<bf2e8ea0>] (spidev_read+0x3c/0xb8 [spidev])
[  122.685790] [<bf2e8ea0>] (spidev_read [spidev]) from [<c04270e0>] (vfs_read+0xb4/0x32c)
[  122.695234] [<c04270e0>] (vfs_read) from [<c0427854>] (ksys_read+0xb0/0xe4)
[  122.702924] [<c0427854>] (ksys_read) from [<c0200040>] (ret_fast_syscall+0x0/0x4c)
[  122.711910] Exception stack(0xccc33fa8 to 0xccc33ff0)
[  122.717668] 3fa0:                   b6706608 beec01f8 00000003 009e59a0 00000000 00000000
[  122.727255] 3fc0: b6706608 beec01f8 b67cc070 00000003 b6f68550 009e5a48 009e5a4f 00000008
[  122.736863] 3fe0: b660ef2c beec0190 b65fce58 b6b718cc

To reproduce

  • The problem is found on Arch Linux ARM and the backtrace is obtained there as well. Reproducing the problem on Raspbian with the latest kernel from rpi-update results in a complete system hang (no uart console, no ping, nothing). I guess it's the same problem.
  • Install fresh Raspbian
  • Update kernel using rpi-update, install python3-spidev.
  • Add dtparam=spi=on to /boot/config.txt. Also reproduced with dtoverlay=spi0-1cs (I really need it).
  • Reboot.
  • Run this script:
    import spidev
    spi = spidev.SpiDev(0, 0)
    spi.mode = 0
    spi.max_speed_hz = 200000
    while 1:
        spi.xfer(b"\0" * 8)
  • Crash will occur in a 10-20 seconds.

System

  • Raspberry Pi 4 Model B Rev 1.1
  • Arch Linux ARM / any fresh Raspbian
  • Firmware a5bf70c44ba93e99f955a66530916240a1661132 / Jan 21 2021 16:03:55 or Arch, 382bdb0bc62235141318b3511ee1ab9a8d7712e4 / Jan 25 2021 18:47:41 on Raspbian.
  • `Linux pikvm 5.10.10-1-ARCH var->green.length may be left uninitialized #1 SMP Mon Jan 25 21:57:16 UTC 2021 armv7l GNU/Linux

Logs
Full dmesg obtained on Arch: dmesg.txt.

@pelwell
Copy link
Contributor

pelwell commented Jan 28, 2021

What is the last known working version?

@mdevaev
Copy link
Contributor Author

mdevaev commented Jan 28, 2021

5.4.83-7 arch is working

@pelwell
Copy link
Contributor

pelwell commented Jan 28, 2021

I can reproduce using the master rpi-update branch, and the stable branch (on 5.4.83) seems fine.

I've had an SPI RFID reader working on 5.10, but clearly that's not tickling this particular issue. Sigh.

Thanks for the report...

@mdevaev
Copy link
Contributor Author

mdevaev commented Jan 28, 2021

I wonder why reader works. Is there a separate driver?

I'll wait for the fix. Let me know if you need anything.

@pelwell
Copy link
Contributor

pelwell commented Jan 28, 2021

A coffee would be nice.

@mdevaev
Copy link
Contributor Author

mdevaev commented Jan 28, 2021

I'm afraid that the coffee will cool down a little while it will go to you from Russia :)

pelwell added a commit that referenced this issue Jan 28, 2021
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
pelwell added a commit that referenced this issue Jan 28, 2021
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
@pelwell
Copy link
Contributor

pelwell commented Jan 28, 2021

Most of the changes between 5.4 and 5.10 look harmless - changing some initialisation and function prototypes, etc. The only ones that stood out were some optimisations that changed while loops into do {} while loops in order to avoid the test before the first iteration - see 26751de. Using your sample code (and for reasons not yet known) each transfer of 8 bytes is being followed by a transfer of 0 bytes, which is fatal if the initial count is 0 - by the time the count is checked it will already have been decremented, and if the check is only that the count is non-zero then it will loop for a very long time.

Zero-length transfers are tripping up the decision whether to use DMA, interrupts or polling because 0 is not less than the smallest byte_limit value of 0.

Reverting to 5.4 shows that zero length transfers are still occurring and not handled optimally, but checking the count at the start of the loop means it exits correctly.

The zero length transfer must come from the spidev library - each ioctl() to perform a transfer is followed by a zero-length read on the file handle; I'm not going to dig further. Reverting the above-mentioned commit fixes the problem, but we can do better - the zero-length transfer can be filtered at transfer_one entry point (with a suitable warning the first time).

Fixes/workarounds are now in rpi-5.10.y and rpi-5.11.y.

@popcornmix
Copy link
Collaborator

The fix is also in latest rpi-update kernel.

@mdevaev
Copy link
Contributor Author

mdevaev commented Jan 28, 2021

I confirm that the problem has been fixed. Thank you for sorting this out so quickly, you awesome :)

@mdevaev mdevaev closed this as completed Jan 28, 2021
popcornmix pushed a commit that referenced this issue Feb 4, 2021
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
it-is-a-robot pushed a commit to openeuler-mirror/raspberrypi-kernel that referenced this issue Feb 11, 2021
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: raspberrypi/linux#4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
it-is-a-robot pushed a commit to openeuler-mirror/raspberrypi-kernel that referenced this issue Feb 11, 2021
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: raspberrypi/linux#4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
fengguang pushed a commit to 0day-ci/linux that referenced this issue Feb 11, 2021
With the introduction of 26751de ("spi: bcm2835: Micro-optimise
FIFO loops") it has become apparent that some users might initiate
zero-length SPI transfers. A fact the micro-optimization omitted, and
which turned out to cause crashes[1].

Instead of changing the micro-optimization itself, use a bigger hammer
and skip zero-length transfers altogether for drivers using the default
transfer_one_message() implementation.

Reported-by: Phil Elwell <[email protected]>
Fixes: 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
Signed-off-by: Nicolas Saenz Julienne <[email protected]>

[1] raspberrypi/linux#4100
fengguang pushed a commit to 0day-ci/linux that referenced this issue Feb 14, 2021
With the introduction of 26751de ("spi: bcm2835: Micro-optimise
FIFO loops") it has become apparent that some users might initiate
zero-length SPI transfers. A fact the micro-optimization omitted, and
which turned out to cause crashes[1].

Instead of changing the micro-optimization itself, use a bigger hammer
and skip zero-length transfers altogether for drivers using the default
transfer_one_message() implementation.

Reported-by: Phil Elwell <[email protected]>
Fixes: 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
Signed-off-by: Nicolas Saenz Julienne <[email protected]>

[1] raspberrypi/linux#4100
Link: https://lore.kernel.org/r/[email protected]

Signed-off-by: Mark Brown <[email protected]>
popcornmix pushed a commit that referenced this issue Feb 16, 2021
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
it-is-a-robot pushed a commit to openeuler-mirror/raspberrypi-kernel that referenced this issue Feb 24, 2021
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: raspberrypi/linux#4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
Signed-off-by: Fang Yafen <[email protected]>
it-is-a-robot pushed a commit to openeuler-mirror/raspberrypi-kernel that referenced this issue Feb 25, 2021
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: raspberrypi/linux#4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
Signed-off-by: Fang Yafen <[email protected]>
it-is-a-robot pushed a commit to openeuler-mirror/raspberrypi-kernel that referenced this issue Feb 25, 2021
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: raspberrypi/linux#4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
Signed-off-by: Fang Yafen <[email protected]>
it-is-a-robot pushed a commit to openeuler-mirror/raspberrypi-kernel that referenced this issue Feb 27, 2021
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: raspberrypi/linux#4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
Signed-off-by: Fang Yafen <[email protected]>
it-is-a-robot pushed a commit to openeuler-mirror/raspberrypi-kernel that referenced this issue Feb 27, 2021
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: raspberrypi/linux#4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
Signed-off-by: Fang Yafen <[email protected]>
nareshkamboju pushed a commit to nareshkamboju/linux that referenced this issue Mar 2, 2021
[ Upstream commit b306320 ]

With the introduction of 26751de ("spi: bcm2835: Micro-optimise
FIFO loops") it has become apparent that some users might initiate
zero-length SPI transfers. A fact the micro-optimization omitted, and
which turned out to cause crashes[1].

Instead of changing the micro-optimization itself, use a bigger hammer
and skip zero-length transfers altogether for drivers using the default
transfer_one_message() implementation.

Reported-by: Phil Elwell <[email protected]>
Fixes: 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
Signed-off-by: Nicolas Saenz Julienne <[email protected]>

[1] raspberrypi/linux#4100
Link: https://lore.kernel.org/r/[email protected]

Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
woodsts pushed a commit to woodsts/linux-stable that referenced this issue Mar 4, 2021
[ Upstream commit b306320 ]

With the introduction of 26751de ("spi: bcm2835: Micro-optimise
FIFO loops") it has become apparent that some users might initiate
zero-length SPI transfers. A fact the micro-optimization omitted, and
which turned out to cause crashes[1].

Instead of changing the micro-optimization itself, use a bigger hammer
and skip zero-length transfers altogether for drivers using the default
transfer_one_message() implementation.

Reported-by: Phil Elwell <[email protected]>
Fixes: 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
Signed-off-by: Nicolas Saenz Julienne <[email protected]>

[1] raspberrypi/linux#4100
Link: https://lore.kernel.org/r/[email protected]

Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
gregkh pushed a commit to gregkh/linux that referenced this issue Mar 4, 2021
[ Upstream commit b306320 ]

With the introduction of 26751de ("spi: bcm2835: Micro-optimise
FIFO loops") it has become apparent that some users might initiate
zero-length SPI transfers. A fact the micro-optimization omitted, and
which turned out to cause crashes[1].

Instead of changing the micro-optimization itself, use a bigger hammer
and skip zero-length transfers altogether for drivers using the default
transfer_one_message() implementation.

Reported-by: Phil Elwell <[email protected]>
Fixes: 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
Signed-off-by: Nicolas Saenz Julienne <[email protected]>

[1] raspberrypi/linux#4100
Link: https://lore.kernel.org/r/[email protected]

Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
it-is-a-robot pushed a commit to openeuler-mirror/kernel that referenced this issue Mar 6, 2021
raspberrypi inclusion
category: feature
bugzilla: 50432

--------------------------------

A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: raspberrypi/linux#4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
Signed-off-by: Fang Yafen <[email protected]>
Signed-off-by: Zheng Zengkai <[email protected]>
popcornmix pushed a commit that referenced this issue Mar 16, 2021
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Mar 10, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Mar 10, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Mar 10, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Mar 10, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Mar 13, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Mar 13, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Mar 17, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Mar 24, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Mar 25, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Mar 25, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Mar 31, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Apr 7, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Apr 7, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Apr 10, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Apr 14, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Apr 14, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Apr 14, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
nmbath pushed a commit to victronenergy/linux that referenced this issue Apr 22, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: raspberrypi/linux#4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Apr 24, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Apr 24, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Apr 24, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Apr 28, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue Apr 28, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue May 6, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue May 6, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue May 14, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue May 14, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue May 20, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue May 20, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
popcornmix pushed a commit that referenced this issue May 23, 2025
A relatively recent commit ([1]) contained optimisation for the PIO
SPI FIFO-filling functions. The commit message includes the phrase
"[t]he blind and counted loops are always called with nonzero count".
This is technically true, but it is still possible for count to become
zero before the loop is entered - if tfr->len is zero. Moving the loop
exit condition to the end of the loop saves a few cycles, but results
in a near-infinite loop should the revised count be zero on entry.

Strangely, zero-lengthed transfers aren't filtered by the SPI framework
and, even more strangely, the Python3 spidev library is triggering them
for no obvious reason.

Avoid the problem completely by bailing out of the main transfer
function early if trf->len is zero, although there may be a case for
moving the mitigation into the framework.

See: #4100

Signed-off-by: Phil Elwell <[email protected]>

[1] 26751de ("spi: bcm2835: Micro-optimise FIFO loops")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants