Luca Coelho <luca@xxxxxxxxx> writes: > From: Johannes Berg <johannes.berg@xxxxxxxxx> > > When we read device memory, we lock a spinlock, write the address we > want to read from the device and then spin in a loop reading the data > in 32-bit quantities from another register. > > As the description makes clear, this is rather inefficient, incurring > a PCIe bus transaction for every read. In a typical device today, we > want to read 786k SMEM if it crashes, leading to 192k register reads. > Occasionally, we've seen the whole loop take over 20 seconds and then > triggering the soft lockup detector. > > Clearly, it is unreasonable to spin here for such extended periods of > time. > > To fix this, break the loop down into an outer and an inner loop, and > break out of the inner loop if more than half a second elapsed. To > avoid too much overhead, check for that only every 128 reads, though > there's no particular reason for that number. Then, unlock and relock > to obtain NIC access again, reprogram the start address and continue. > > This will keep (interrupt) latencies on the CPU down to a reasonable > time. > > Signed-off-by: Johannes Berg <johannes.berg@xxxxxxxxx> > Signed-off-by: Mordechay Goodstein <mordechay.goodstein@xxxxxxxxx> > Signed-off-by: Luca Coelho <luciano.coelho@xxxxxxxxx> I'll queue this to v5.10. -- https://patchwork.kernel.org/project/linux-wireless/list/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches