Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.2/patches/2224340/?format=api
{ "id": 2224340, "url": "http://patchwork.ozlabs.org/api/1.2/patches/2224340/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260417-sdcard-performance-b4-v4-4-119e66be10c2@avm.de/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/1.2/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260417-sdcard-performance-b4-v4-4-119e66be10c2@avm.de>", "list_archive_url": null, "date": "2026-04-17T09:51:37", "name": "[v4,4/7] hw/sd/sdhci: Don't use bounce buffer for ADMA", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "2200c7b2ac0666ad2805e9bb291dcc340a8e92c6", "submitter": { "id": 91343, "url": "http://patchwork.ozlabs.org/api/1.2/people/91343/?format=api", "name": "Christian Speich", "email": "c.speich@avm.de" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260417-sdcard-performance-b4-v4-4-119e66be10c2@avm.de/mbox/", "series": [ { "id": 500297, "url": "http://patchwork.ozlabs.org/api/1.2/series/500297/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=500297", "date": "2026-04-17T09:51:34", "name": "hw/sd: Improve performance of read/write/erase", "version": 4, "mbox": "http://patchwork.ozlabs.org/series/500297/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2224340/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2224340/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=avm.de header.i=@avm.de header.a=rsa-sha256\n header.s=mail header.b=nPXTiVnF;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fxr264FKVz1yDF\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 17 Apr 2026 19:59:10 +1000 (AEST)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wDfxF-0002zn-Tr; Fri, 17 Apr 2026 05:57:42 -0400", "from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <c.speich@avm.de>)\n id 1wDfxB-0002pw-Qu; Fri, 17 Apr 2026 05:57:37 -0400", "from mail.avm.de ([2001:bf0:244:244::119])\n by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <c.speich@avm.de>)\n id 1wDfx9-000387-Gb; Fri, 17 Apr 2026 05:57:37 -0400", "from [172.16.0.1] (helo=mail.avm.de)\n by mail.avm.de with ESMTP (eXpurgate 4.55.2)\n (envelope-from <c.speich@avm.de>)\n id 69e20406-1e6c-7f0000032729-7f000001b2e8-1\n for <multiple-recipients>; Fri, 17 Apr 2026 11:57:26 +0200", "from mail-notes.avm.de (mail-notes.avm.de [172.16.0.1])\n by mail.avm.de (Postfix) with ESMTP;\n Fri, 17 Apr 2026 11:57:26 +0200 (CEST)", "from [127.0.1.1] ([172.17.89.139])\n by mail-notes.avm.de (HCL Domino Release 14.0FP4)\n with ESMTP id 2026041711572444-2977 ;\n Fri, 17 Apr 2026 11:57:24 +0200" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=avm.de; s=mail;\n t=1776419846; bh=q4twjt2E4pRsujRgtku8JrJOS12+2byH1d3KqcJv0Gs=;\n h=From:Date:Subject:References:In-Reply-To:To:Cc:From;\n b=nPXTiVnF2AK6Ttv8AoR1MwnTHSiIYhlXGM4JBKlgYBxOmn0oGotNRrHG1okQcR40x\n m/naXhu8wUZXHOYyF0JYwIqIhnYV+wvLE2RBQ1t6+UnVU2sD4/cgxOmIPmwh7TaC2h\n BK6oQd+SVbLHO7iHzXoUqvNNioNqPlSEsZz64PS4=", "From": "Christian Speich <c.speich@avm.de>", "Date": "Fri, 17 Apr 2026 11:51:37 +0200", "Subject": "[PATCH v4 4/7] hw/sd/sdhci: Don't use bounce buffer for ADMA", "MIME-Version": "1.0", "Message-Id": "<20260417-sdcard-performance-b4-v4-4-119e66be10c2@avm.de>", "References": "<20260417-sdcard-performance-b4-v4-0-119e66be10c2@avm.de>", "In-Reply-To": "<20260417-sdcard-performance-b4-v4-0-119e66be10c2@avm.de>", "To": "qemu-devel@nongnu.org", "Cc": "=?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= <philmd@linaro.org>,\n Bin Meng <bmeng.cn@gmail.com>, qemu-block@nongnu.org,\n Marcel Apfelbaum <marcel.apfelbaum@gmail.com>,\n Yanan Wang <wangyanan55@huawei.com>, Zhao Liu <zhao1.liu@intel.com>,\n Christian Speich <c.speich@avm.de>", "X-Mailer": "b4 0.14.2", "X-MIMETrack": "Itemize by SMTP Server on ANIS1/AVM(Release 14.0FP4|March 10,\n 2025) at 17.04.2026 11:57:24,\n Serialize by Router on ANIS1/AVM(Release 14.0FP4|March 10, 2025) at\n 17.04.2026 11:57:26, Serialize complete at 17.04.2026 11:57:26", "X-TNEFEvaluated": "1", "Content-Transfer-Encoding": "7bit", "Content-Type": "text/plain; charset=\"utf-8\"", "X-purgate-ID": "149429::1776419846-34F1E373-3203CE97/0/0", "X-purgate-type": "clean", "X-purgate-size": "6515", "X-purgate-Ad": "Categorized by eleven eXpurgate (R) https://www.eleven.de", "X-purgate": [ "This mail is considered clean (visit https://www.eleven.de for\n further information)", "clean" ], "Received-SPF": "pass client-ip=2001:bf0:244:244::119;\n envelope-from=c.speich@avm.de; helo=mail.avm.de", "X-Spam_score_int": "-25", "X-Spam_score": "-2.6", "X-Spam_bar": "--", "X-Spam_report": "(-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.54,\n DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no", "X-Spam_action": "no action", "X-BeenThere": "qemu-devel@nongnu.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "qemu development <qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org" }, "content": "Currently, ADMA will temporarily store data into a local bounce buffer\nwhen transferring it. This will produce unneeded copies of the data and\nlimit us to the bounce buffer size for each step.\n\nThis patch now maps the requested DMA address and passes this buffer\ndirectly to sdbus_{read,write}_data. This allows to pass much larger\nbuffers down to increase the performance. sdbus_{read,write}_data is\nalready able to handle arbitrary length and alignments, so we do not\nneed to ensure this.\n\nSigned-off-by: Christian Speich <c.speich@avm.de>\n---\n hw/sd/sdhci.c | 102 +++++++++++++++++++++++++++++++---------------------------\n 1 file changed, 55 insertions(+), 47 deletions(-)", "diff": "diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c\nindex c86dfa281f4b0218bf6dda7a38d46abfc9638450..6e07711478cb6ca046a7d371a82e2c682ebbda00 100644\n--- a/hw/sd/sdhci.c\n+++ b/hw/sd/sdhci.c\n@@ -775,7 +775,7 @@ static void get_adma_description(SDHCIState *s, ADMADescr *dscr)\n \n static void sdhci_do_adma(SDHCIState *s)\n {\n- unsigned int begin, length;\n+ unsigned int length;\n const uint16_t block_size = s->blksize & BLOCK_SIZE_MASK;\n const MemTxAttrs attrs = { .memory = true };\n ADMADescr dscr = {};\n@@ -817,66 +817,74 @@ static void sdhci_do_adma(SDHCIState *s)\n if (s->trnmod & SDHC_TRNS_READ) {\n s->prnsts |= SDHC_DOING_READ;\n while (length) {\n- if (s->data_count == 0) {\n- sdbus_read_data(&s->sdbus, s->fifo_buffer, block_size);\n- }\n- begin = s->data_count;\n- if ((length + begin) < block_size) {\n- s->data_count = length + begin;\n- length = 0;\n- } else {\n- s->data_count = block_size;\n- length -= block_size - begin;\n- }\n- res = dma_memory_write(s->dma_as, dscr.addr,\n- &s->fifo_buffer[begin],\n- s->data_count - begin,\n- attrs);\n- if (res != MEMTX_OK) {\n+ dma_addr_t dma_len = length;\n+\n+ void *buf = dma_memory_map(s->dma_as, dscr.addr, &dma_len,\n+ DMA_DIRECTION_FROM_DEVICE,\n+ attrs);\n+\n+ if (buf == NULL) {\n+ res = MEMTX_ERROR;\n break;\n+ } else {\n+ res = MEMTX_OK;\n }\n- dscr.addr += s->data_count - begin;\n- if (s->data_count == block_size) {\n- s->data_count = 0;\n- if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {\n- s->blkcnt--;\n- if (s->blkcnt == 0) {\n- break;\n- }\n+\n+ sdbus_read_data(&s->sdbus, buf, dma_len);\n+ length -= dma_len;\n+ dscr.addr += dma_len;\n+\n+ dma_memory_unmap(s->dma_as, buf, dma_len,\n+ DMA_DIRECTION_FROM_DEVICE, dma_len);\n+\n+ if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {\n+ size_t transfered = s->data_count + dma_len;\n+\n+ s->blkcnt -= transfered / block_size;\n+ s->data_count = transfered % block_size;\n+\n+ if (s->blkcnt == 0) {\n+ s->data_count = 0;\n+ break;\n }\n }\n }\n } else {\n s->prnsts |= SDHC_DOING_WRITE;\n while (length) {\n- begin = s->data_count;\n- if ((length + begin) < block_size) {\n- s->data_count = length + begin;\n- length = 0;\n- } else {\n- s->data_count = block_size;\n- length -= block_size - begin;\n- }\n- res = dma_memory_read(s->dma_as, dscr.addr,\n- &s->fifo_buffer[begin],\n- s->data_count - begin,\n- attrs);\n- if (res != MEMTX_OK) {\n+ dma_addr_t dma_len = length;\n+\n+ void *buf = dma_memory_map(s->dma_as, dscr.addr, &dma_len,\n+ DMA_DIRECTION_TO_DEVICE, attrs);\n+\n+ if (buf == NULL) {\n+ res = MEMTX_ERROR;\n break;\n+ } else {\n+ res = MEMTX_OK;\n }\n- dscr.addr += s->data_count - begin;\n- if (s->data_count == block_size) {\n- sdbus_write_data(&s->sdbus, s->fifo_buffer, block_size);\n- s->data_count = 0;\n- if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {\n- s->blkcnt--;\n- if (s->blkcnt == 0) {\n- break;\n- }\n+\n+ sdbus_write_data(&s->sdbus, buf, dma_len);\n+ length -= dma_len;\n+ dscr.addr += dma_len;\n+\n+ dma_memory_unmap(s->dma_as, buf, dma_len,\n+ DMA_DIRECTION_TO_DEVICE, dma_len);\n+\n+ if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {\n+ size_t transfered = s->data_count + dma_len;\n+\n+ s->blkcnt -= transfered / block_size;\n+ s->data_count = transfered % block_size;\n+\n+ if (s->blkcnt == 0) {\n+ s->data_count = 0;\n+ break;\n }\n }\n }\n }\n+\n if (res != MEMTX_OK) {\n s->data_count = 0;\n if (s->errintstsen & SDHC_EISEN_ADMAERR) {\n", "prefixes": [ "v4", "4/7" ] }