xuartlite: fix race condition and receive overrun in XUartLite_SendBuffer#384
Open
dxmake wants to merge 1 commit into
Open
xuartlite: fix race condition and receive overrun in XUartLite_SendBuffer#384dxmake wants to merge 1 commit into
dxmake wants to merge 1 commit into
Conversation
…ffer
This commit addresses two critical bugs found in the XUartLite v3.11
driver when operating in interrupt-driven mode with heavy bidirectional
(concurrent TX and RX) traffic on a Zynq-7000 platform.
---
Bug 1: Race condition causing Data Abort (bus error)
Root Cause:
XUartLite_SendBuffer() is called from both normal (non-interrupt)
context via XUartLite_Send(), and from interrupt context via the
shared TX/RX interrupt handler. The original implementation reads
the StatusRegister *before* disabling interrupts, then uses that
stale status to drive the FIFO fill loop. If an RX interrupt fires
between reading the status register and disabling interrupts, the
interrupt handler may also write to the TX FIFO. Both contexts
writing to the same 16-byte FIFO concurrently can overflow it,
triggering an AXI bus fault and a Data Abort.
Fix:
After disabling interrupts, re-read StatusRegister before entering
the FIFO fill loop. This guarantees the FIFO status used for
transmission reflects the hardware state *after* interrupts are
disabled, eliminating the window where interrupt-context FIFO writes
could race with normal-context writes.
As an alternative workaround, callers can bracket XUartLite_Send()
with XUartLite_DisableInterrupt() / XUartLite_EnableInterrupt().
---
Bug 2: Receive overrun errors during heavy transmission
Root Cause:
The original byte-by-byte FIFO fill loop writes at most a few bytes
per call. When optimized to batch-write up to the full 16-byte FIFO
capacity, filling all 16 slots causes ReceiveOverrunErrors under
concurrent full-duplex traffic. This suggests a hardware-level
boundary condition in the AXI UART Lite IP core: a completely full
TX FIFO interferes with or stalls the RX path, causing incoming
data loss. The original byte-by-byte approach masked this because
it never filled the FIFO completely in one atomic write sequence.
Fix:
Limit the batch write to 15 bytes (FIFO depth - 1), leaving one
FIFO slot free. This avoids the fully-saturated state that triggers
the RX overrun condition.
---
Testing:
- Platform: Xilinx Zynq-7000 (XC7Z020), AXI UART Lite v3.11
- Baud rate: 921600, full-duplex, -O0
- Bug 1: Data Abort reliably reproduced; eliminated with the
re-read-after-disable fix and/or caller-side interrupt bracketing.
- Bug 2: Batch size 16 → ReceiveOverrunErrors observed; batch size
15 → zero overruns across >1,000,000 bytes of continuous transfer.
Signed-off-by: <julongjian> <talk5600@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This commit addresses two critical bugs found in the XUartLite v3.11 driver when operating in interrupt-driven mode with heavy bidirectional (concurrent TX and RX) traffic on a Zynq-7000 platform.
Bug 1: Race condition causing Data Abort (bus error)
Root Cause:
XUartLite_SendBuffer() is called from both normal (non-interrupt)
context via XUartLite_Send(), and from interrupt context via the
shared TX/RX interrupt handler. The original implementation reads
the StatusRegister before disabling interrupts, then uses that
stale status to drive the FIFO fill loop. If an RX interrupt fires
between reading the status register and disabling interrupts, the
interrupt handler may also write to the TX FIFO. Both contexts
writing to the same 16-byte FIFO concurrently can overflow it,
triggering an AXI bus fault and a Data Abort.
Fix:
After disabling interrupts, re-read StatusRegister before entering
the FIFO fill loop. This guarantees the FIFO status used for
transmission reflects the hardware state after interrupts are
disabled, eliminating the window where interrupt-context FIFO writes
could race with normal-context writes.
As an alternative workaround, callers can bracket XUartLite_Send()
with XUartLite_DisableInterrupt() / XUartLite_EnableInterrupt().
Bug 2: Receive overrun errors during heavy transmission
Root Cause:
The original byte-by-byte FIFO fill loop writes at most a few bytes
per call. When optimized to batch-write up to the full 16-byte FIFO
capacity, filling all 16 slots causes ReceiveOverrunErrors under
concurrent full-duplex traffic. This suggests a hardware-level
boundary condition in the AXI UART Lite IP core: a completely full
TX FIFO interferes with or stalls the RX path, causing incoming
data loss. The original byte-by-byte approach masked this because
it never filled the FIFO completely in one atomic write sequence.
Fix:
Limit the batch write to 15 bytes (FIFO depth - 1), leaving one
FIFO slot free. This avoids the fully-saturated state that triggers
the RX overrun condition.
Testing:
Please do not submit a Pull Request via github. Our project makes use of mailing lists for patch submission and review. For more details please see https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842172/Create+and+Submit+a+Patch