From: Wadim Mueller <wafgo01@gmail.com>
To: qemu-devel@nongnu.org
Cc: qemu-arm@nongnu.org, "Peter Maydell" <peter.maydell@linaro.org>,
"Philippe Mathieu-Daudé" <philmd@mailo.com>,
"Bin Meng" <bmeng.cn@gmail.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Fabiano Rosas" <farosas@suse.de>,
"Wadim Mueller" <wafgo01@gmail.com>
Subject: [RFC PATCH v2 03/14] hw/sd/sdhci: complete non-interrupt ADMA descriptor chains in one pass
Date: Thu, 20 Aug 2026 14:48:03 +0200 [thread overview]
Message-ID: <20260820124824.618671-4-wafgo01@gmail.com> (raw)
In-Reply-To: <20260820124824.618671-1-wafgo01@gmail.com>
sdhci_do_adma() returns to the main loop after every descriptor and relies
on a timer re-entry to pick up the next one. For a descriptor chain whose
entries do not request an interrupt this makes the transfer rate depend
from the virtual clock rather than on the guest's programming, which
significantly slows down large transfers and makes guest-visible timing
depend on host timer behaviour.
Keep processing the chain in the same invocation while no descriptor asks
for an interrupt and the transfer has not finished, and only fall back to
the deferred path when the guest actually requested a notification.
A qtest reproducer is added later in this series.
Signed-off-by: Wadim Mueller <wafgo01@gmail.com>
---
This patch can be dropped once Bin Meng's SDHCI series
https://patchwork.ozlabs.org/project/qemu-devel/list/?series=515264
(which needs series=513930 applied first) is merged - it covers the
same AM64x failure, see
https://lore.kernel.org/qemu-devel/20260810124519.34501-1-wafgo01@gmail.com/
It is included here only so that the series works on actual master.
hw/sd/sdhci-internal.h | 9 +++++++++
hw/sd/sdhci.c | 23 +++++++++++++++++++++--
2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
index 4aeed120bf..e6ce12617e 100644
--- a/hw/sd/sdhci-internal.h
+++ b/hw/sd/sdhci-internal.h
@@ -277,6 +277,15 @@ FIELD(SDHC_MAXCURR, V18_VDD2, 32, 8); /* since v4.20 */
#define SDHC_INSERTION_DELAY (NANOSECONDS_PER_SECOND)
#define SDHC_TRANSFER_DELAY 100
#define SDHC_ADMA_DESCS_PER_DELAY 5
+/*
+ * Upper bound on ADMA2 descriptors handled in a single sdhci_do_adma()
+ * call, as a safety valve against a malformed or circular descriptor
+ * list. A well-formed transfer terminates far below this via END or
+ * blkcnt == 0 (even a 4 GiB transfer built from 64 KiB TRAN descriptors
+ * is only ~64K descriptors); the bound merely guarantees the loop makes
+ * a decision instead of spinning forever.
+ */
+#define SDHC_ADMA_MAX_DESCRIPTORS (1 << 20)
#define SDHC_CMD_RESPONSE (3 << 0)
enum {
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index e58a610397..9a5dd1d93f 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -780,7 +780,6 @@ static void sdhci_do_adma(SDHCIState *s)
const MemTxAttrs attrs = { .memory = true };
ADMADescr dscr = {};
MemTxResult res = MEMTX_ERROR;
- int i;
if (s->trnmod & SDHC_TRNS_BLK_CNT_EN && !s->blkcnt) {
/* Stop Multiple Transfer */
@@ -788,7 +787,27 @@ static void sdhci_do_adma(SDHCIState *s)
return;
}
- for (i = 0; i < SDHC_ADMA_DESCS_PER_DELAY; ++i) {
+ /*
+ * Process the descriptor chain to completion (END or blkcnt == 0),
+ * yielding to the guest only for a descriptor carrying the INT
+ * attribute (a DMA-boundary interrupt, handled at the end of the loop).
+ *
+ * Historically at most SDHC_ADMA_DESCS_PER_DELAY descriptors were
+ * handled per call before rescheduling SDHC_TRANSFER_DELAY ns later on
+ * QEMU_CLOCK_VIRTUAL. That pacing is only needed so a guest can observe
+ * the intermediate DMA-interrupt state; a bulk transfer that requests
+ * no interrupt does not need slicing, and throttling it across many
+ * virtual-clock round-trips can make it race a guest-side transfer
+ * timeout. Run such chains to completion in one call instead.
+ *
+ * SDHC_ADMA_MAX_DESCRIPTORS bounds the loop so a malformed or circular
+ * chain cannot spin here forever; on overflow, break to the reschedule
+ * path so the main loop stays responsive.
+ */
+ for (unsigned int adma_descs = 0; ; adma_descs++) {
+ if (adma_descs >= SDHC_ADMA_MAX_DESCRIPTORS) {
+ break;
+ }
s->admaerr &= ~SDHC_ADMAERR_LENGTH_MISMATCH;
get_adma_description(s, &dscr);
--
2.43.0
next prev parent reply other threads:[~2026-08-20 12:50 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-20 12:48 [RFC PATCH v2 00/14] hw/arm: add TI AM64x SoC and am64-virt machine Wadim Mueller
2026-08-20 12:48 ` [RFC PATCH v2 01/14] hw/i2c/omap_i2c: add a dedicated CONFIG_OMAP_I2C symbol Wadim Mueller
2026-08-24 15:39 ` Alex Bennée
2026-08-20 12:48 ` [RFC PATCH v2 02/14] hw/i2c/omap_i2c: implement soft reset and NACK reporting Wadim Mueller
2026-08-20 12:48 ` Wadim Mueller [this message]
2026-08-24 15:53 ` [RFC PATCH v2 03/14] hw/sd/sdhci: complete non-interrupt ADMA descriptor chains in one pass Alex Bennée
2026-08-20 12:48 ` [RFC PATCH v2 04/14] hw/char: add TI AM64x UART model Wadim Mueller
2026-08-20 12:48 ` [RFC PATCH v2 05/14] hw/timer: add TI K3 DMTimer model Wadim Mueller
2026-08-20 12:48 ` [RFC PATCH v2 06/14] hw/misc: add TI K3 CTRL_MMR, GTC, DDRSS, SDHCI PHY and TRNG models Wadim Mueller
2026-08-20 12:48 ` [RFC PATCH v2 07/14] hw/misc: add TI RAT (region address translation) model Wadim Mueller
2026-08-20 12:48 ` [RFC PATCH v2 08/14] hw/misc: add TI mailbox (IPC) model Wadim Mueller
2026-08-20 12:48 ` [RFC PATCH v2 09/14] hw/misc: add TI K3 secure proxy model Wadim Mueller
2026-08-20 12:48 ` [RFC PATCH v2 10/14] hw/misc: add TI DMSC (TI-SCI system controller) model Wadim Mueller
2026-08-20 12:48 ` [RFC PATCH v2 11/14] hw/arm: add TI K3 combined boot image parser Wadim Mueller
2026-08-20 12:48 ` [RFC PATCH v2 12/14] hw/arm: add TI AM64x SoC model Wadim Mueller
2026-08-20 12:48 ` [RFC PATCH v2 13/14] hw/arm: add the am64-virt machine Wadim Mueller
2026-08-20 12:48 ` [RFC PATCH v2 14/14] tests: add AM64x unit, qtest and functional tests Wadim Mueller
2026-08-20 16:25 ` Alex Bennée
2026-08-22 21:04 ` Wadim Mueller
2026-08-24 15:39 ` Alex Bennée
2026-08-21 10:26 ` [RFC PATCH v2 00/14] hw/arm: add TI AM64x SoC and am64-virt machine Alex Bennée
2026-08-22 21:06 ` Wadim Mueller
2026-08-21 16:35 ` Nick Huang
2026-08-22 21:07 ` Wadim Mueller
2026-08-22 5:22 ` Bin Meng
2026-08-22 21:13 ` Wadim Mueller
2026-08-24 11:51 ` Nick Huang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260820124824.618671-4-wafgo01@gmail.com \
--to=wafgo01@gmail.com \
--cc=bmeng.cn@gmail.com \
--cc=farosas@suse.de \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@mailo.com \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox