-
Notifications
You must be signed in to change notification settings - Fork 13
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
HS58 Linux crash in tcp_check_space when running iperf3 #163
Comments
It looks that reproduction rate can be decreased (how much is still to be determined, not sure if it is fix or not) by the following patch
here are listings of the tcp_rcv_established in the default, and optimize(0) variants: |
After few more days of testing, still no reproduction with optimize(0) patch. |
Another stack trace, now with PCIe eth adapter based on RTL8169
|
I had a look at difference between vmlinux with optimize(0) patch and without it. It looks that it’s not only these two functions affected, but in fact few more functions that with default optimization were inlined (or optimized-out - it’s difficult to determine that) and with optimize(0) are just regular functions. This is the list functions present only with optimize(0) patch: |
The issue reproduces also with ATLD atomic implementation. |
I've tried to reproduce the issue in NSIM(HS58x3 configuration + virtio for ethernet adapter) but without success. It works with no errors. |
Example cache operations that I can see being used when iperf is running. Operations originate from our PCIe WiFi driver: dma_cache_wback_inv addr 0x8728c740 sz 2048 It can be seen that not all operations are aligned to cache line (64B). |
With another PCIe-Eth adapter that we also observe this issue, the cache operations look like below.
There are only two cache operations used when iperf3 is running:
|
SmaRT traces + TLB dump from Metaware Debugger: |
Currently we're using a workaround described in #163 (comment) I did some experiments to determine which part of the code has to have O0 optimization applied and here are the results. The calling order is: tcp_rcv_established → tcp_data_snd_check → tcp_check_space
Conclusion 1: Conclusion 2: As you can see, the conclusions are contradicting. The only explanation I can come up with is that it isn’t an issue in specific place of the code, but rather some timing or other problem elsewhere. Here are the listings for mentioned functions for all cases: |
Looking at stack traces, I can see that it's always one of registers (r0 usually, might depend on debug changes introduced) that contains invalid value. Could it be that there is something gets wrong on context switches ? Would it be possible to add a simple check of context on save/restore (basic checksum, or just a sum, calculated on store and vefiried on restore) to ensure nothing gets lost ? |
I added the following change to the tcp_check_space to catch the issue earlier:
From what I see, only these two instructions were added to the tcp_check_space, it didn't change any other part of this function. I was able to reproduce issue with this change, here is what I can see in mdb: Here are SmaRT traces for each core: It's interesting, that SmaRT trace for core 1 doesn't match with its call stack. Also, it looks that it was in fact r14 that is corrupted, as before call to tcp_check_space r14 is copied to r0: it might be that r14 gets corrupted in another function - __tcp_push_pending_frames. |
Here is yet another reproduction, SmaRT: smart-log-core-1.txt |
I think this issue can be linked with #168. |
Could you check this patch? |
@xxkent I tried with this patch but it's the same Do I understand correctly that SmaRT is showing full trace of instructions executed by a particular CPU (even if there was a context switch at some point in time), and registers of one core should not be affected by other cores ? |
Yes, SmaRT shows last executed instructions for a particular core(3 traces from 3 cpu in your case). These traces can include switched context also. |
Contents of dcache for each core + L2 cache: According to the contents of data cache for core 1 where the issue triggered, the ldd.ab r14[sp, 8] instruction operates on a memory location that belong to two data cache lines. For some reason, r15 got loaded with correct value while r14 didn't. Regarding why there is "multi_cpu_stop" called, it looks like a result of clock source switching (see function timekeeping_notify) |
I'm testing now with kernel option CONFIG_ARC_HAS_LL64=n. No reproduction within 3 days. Buildroot didn't require change as it's not passing "mll64" to gcc, and from what I see by default gcc is not using these double load/store instructions. What's interesting, this change is similar to optimize(0) workaround, as from what I see with optimize(0) compiler is not using double load/store instruction - at least for affected functions. |
This is what I see with -off=flush_dcache it looks like the value that should have been loaded to r14 (at address 0x81c35cbc) is in L1 data cache line marked as dirty, and it's different to what memory view shows on the same address. On the contrary, data that has been loaded to r15 is the same in cache and memory. Any thoughts on this ? |
Using Linux branch abrodkin-arc64-5.15.y, updated to Linux 5.15.127. Built with arc-2023.09 buildroot, using 2023.09 toolchain with latest patches.
Linux running in SMP mode.
I can observe crash in tcp_check_space, when running iperf3 over PCIe WiFi or Eth adapter, see below:
Let iperf3 run for minutes or hours (usually)
From my observations:
The text was updated successfully, but these errors were encountered: