Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2216963/?format=api
{ "id": 2216963, "url": "http://patchwork.ozlabs.org/api/patches/2216963/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/20260327081858.311591-1-christian.poetzsch@kernkonzept.com/", "project": { "id": 18, "url": "http://patchwork.ozlabs.org/api/projects/18/?format=api", "name": "U-Boot", "link_name": "uboot", "list_id": "u-boot.lists.denx.de", "list_email": "u-boot@lists.denx.de", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260327081858.311591-1-christian.poetzsch@kernkonzept.com>", "list_archive_url": null, "date": "2026-03-27T08:18:58", "name": "virtio: add support for SIZE_MAX & SEG_MAX features", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "54dc2595c5358b28294dbd3cdb44b186293fbc25", "submitter": { "id": 88226, "url": "http://patchwork.ozlabs.org/api/people/88226/?format=api", "name": "Christian Pötzsch", "email": "christian.poetzsch@kernkonzept.com" }, "delegate": { "id": 3651, "url": "http://patchwork.ozlabs.org/api/users/3651/?format=api", "username": "trini", "first_name": "Tom", "last_name": "Rini", "email": "trini@ti.com" }, "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/20260327081858.311591-1-christian.poetzsch@kernkonzept.com/mbox/", "series": [ { "id": 497765, "url": "http://patchwork.ozlabs.org/api/series/497765/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=497765", "date": "2026-03-27T08:18:58", "name": "virtio: add support for SIZE_MAX & SEG_MAX features", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/497765/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2216963/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2216963/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<u-boot-bounces@lists.denx.de>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernkonzept.com header.i=@kernkonzept.com\n header.a=rsa-sha256 header.s=mx1 header.b=Upn2YaiM;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)", "phobos.denx.de;\n dmarc=pass (p=none dis=none) header.from=kernkonzept.com", "phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de", "phobos.denx.de;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernkonzept.com header.i=@kernkonzept.com\n header.b=\"Upn2YaiM\";\n\tdkim-atps=neutral", "phobos.denx.de; dmarc=pass (p=none dis=none)\n header.from=kernkonzept.com", "phobos.denx.de; spf=pass\n smtp.mailfrom=christian.poetzsch@kernkonzept.com" ], "Received": [ "from phobos.denx.de (phobos.denx.de\n [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fj13m0QRCz1y1P\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 28 Mar 2026 00:01:08 +1100 (AEDT)", "from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id B577F83DBF;\n\tFri, 27 Mar 2026 14:01:03 +0100 (CET)", "by phobos.denx.de (Postfix, from userid 109)\n id 3968D83F14; Fri, 27 Mar 2026 09:20:42 +0100 (CET)", "from mx.kernkonzept.com (serv1.kernkonzept.com\n [IPv6:2a01:4f8:1c1c:b490::2])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id 2148D83C14\n for <u-boot@lists.denx.de>; Fri, 27 Mar 2026 09:20:40 +0100 (CET)", "from [10.22.3.169] (helo=iris.dd1.int.kernkonzept.com)\n by mx.kernkonzept.com with esmtpsa\n (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.98.2)\n id 1w62Qp-00000006ciW-16M1; Fri, 27 Mar 2026 09:20:39 +0100" ], "X-Spam-Checker-Version": "SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de", "X-Spam-Level": "", "X-Spam-Status": "No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED,\n SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2", "DKIM-Signature": "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n d=kernkonzept.com; s=mx1; h=Content-Transfer-Encoding:Content-Type:\n MIME-Version:Message-ID:Date:Subject:Cc:To:From:References:In-Reply-To:\n Reply-To:Content-ID:Content-Description;\n bh=Z5cq+cuz7Y6OQMPyNZNWafMZ+GzdnDa8E/r2WIWyykY=; b=Upn2YaiMx9ny+UbXA/7YaEqpoF\n IKZg2VuUJGzje75v7rQYkHpVu9GYOplEFDUrHoyEV8bVxNP0TX6GVbAGwdMn8eyXwB7rt3hiHjeUN\n 0Qtme0fxuMjV9NqUgkowf4hMt/1fkIqVio9kjDy6vpdqUva3trZpXa9XTh3fx/vKImWMtwyLqp7Ho\n d5ESonmrpJBTdKhFbWDTtGy7P0jpbhoFEY4jzhyrFBb14+cEoWNRbqCZxXpymjj7CujITA+xYBC36\n KansKUhtFQlEQEiaJ592hgT8FNyHYUecx6blbI+ZM8bpi37Z7Py2dNpniBxMshrehLrXWJjkJzHn6\n cQ4WVgqw==;", "From": "=?utf-8?q?Christian_P=C3=B6tzsch?= <christian.poetzsch@kernkonzept.com>", "To": "u-boot@lists.denx.de", "Cc": "Bin Meng <bmeng.cn@gmail.com>,\n =?utf-8?q?Christian_P=C3=B6tzsch?= <christian.poetzsch@kernkonzept.com>,\n Adam Lackorzynski <adam@l4re.org>", "Subject": "[PATCH] virtio: add support for SIZE_MAX & SEG_MAX features", "Date": "Fri, 27 Mar 2026 09:18:58 +0100", "Message-ID": "<20260327081858.311591-1-christian.poetzsch@kernkonzept.com>", "X-Mailer": "git-send-email 2.47.3", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8bit", "X-Mailman-Approved-At": "Fri, 27 Mar 2026 14:01:00 +0100", "X-BeenThere": "u-boot@lists.denx.de", "X-Mailman-Version": "2.1.39", "Precedence": "list", "List-Id": "U-Boot discussion <u-boot.lists.denx.de>", "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>", "List-Archive": "<https://lists.denx.de/pipermail/u-boot/>", "List-Post": "<mailto:u-boot@lists.denx.de>", "List-Help": "<mailto:u-boot-request@lists.denx.de?subject=help>", "List-Subscribe": "<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>", "Errors-To": "u-boot-bounces@lists.denx.de", "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>", "X-Virus-Scanned": "clamav-milter 0.103.8 at phobos.denx.de", "X-Virus-Status": "Clean" }, "content": "Some virtio implementations may forward the virtio requests directly to\nthe underlying hw. The hw may have some restrictions in how many and how\nbig the requests can be. Therefore, the corresponding virtio device will\nannounce this limitations with the SIZE_MAX & SEG_MAX feature.\n\nAdd support for those features. Split an io request into multiple virtio\nrequests if more than seg_max segments would be used. Also split a\nsingle buffer request into multiple segments if the buffer is bigger\nthen size_max.\n\nSigned-off-by: Christian Pötzsch <christian.poetzsch@kernkonzept.com>\nSigned-off-by: Adam Lackorzynski <adam@l4re.org>\n---\n drivers/virtio/virtio_blk.c | 110 ++++++++++++++++++++++++++++--------\n 1 file changed, 88 insertions(+), 22 deletions(-)", "diff": "diff --git a/drivers/virtio/virtio_blk.c b/drivers/virtio/virtio_blk.c\nindex 3dd0cf36268..80006a49e4a 100644\n--- a/drivers/virtio/virtio_blk.c\n+++ b/drivers/virtio/virtio_blk.c\n@@ -14,6 +14,7 @@\n #include <virtio_ring.h>\n #include <linux/log2.h>\n #include \"virtio_blk.h\"\n+#include <malloc.h>\n \n /**\n * struct virtio_blk_priv - private data for virtio block device\n@@ -23,10 +24,16 @@ struct virtio_blk_priv {\n \tstruct virtqueue *vq;\n \t/** @blksz_shift - log2 of block size divided by 512 */\n \tu32 blksz_shift;\n+\t/** @size_max - maximum segment size */\n+\tu32 size_max;\n+\t/** @seg_max - maximum segment count */\n+\tu32 seg_max;\n };\n \n static const u32 feature[] = {\n \tVIRTIO_BLK_F_BLK_SIZE,\n+\tVIRTIO_BLK_F_SIZE_MAX,\n+\tVIRTIO_BLK_F_SEG_MAX,\n \tVIRTIO_BLK_F_WRITE_ZEROES\n };\n \n@@ -67,50 +74,69 @@ static void virtio_blk_init_data_sg(void *buffer, lbaint_t blkcnt, struct virtio\n \tsg->length = blkcnt * 512;\n }\n \n-static ulong virtio_blk_do_req(struct udevice *dev, u64 sector,\n-\t\t\t lbaint_t blkcnt, void *buffer, u32 type)\n+static ulong virtio_blk_do_single_req(struct udevice *dev, u64 sector,\n+\t\t\t\t lbaint_t blkcnt, char *buffer, u32 type)\n {\n \tstruct virtio_blk_priv *priv = dev_get_priv(dev);\n+\t// The virtio device may have constrains on the maximum segment size.\n+\t// Calculate how many segments we need.\n+\tu32 seg_cnt = (blkcnt * 512) / priv->size_max + 1;\n+\tlbaint_t seg_sec_cnt = priv->size_max / 512;\n \tstruct virtio_blk_outhdr out_hdr;\n \tstruct virtio_blk_discard_write_zeroes wz_hdr;\n \tunsigned int num_out = 0, num_in = 0;\n-\tstruct virtio_sg hdr_sg, wz_sg, data_sg, status_sg;\n-\tstruct virtio_sg *sgs[3];\n+\tstruct virtio_sg **sgs;\n \tu8 status;\n \tint ret;\n+\tu32 i;\n+\n+\t// +2 is header and status descriptor; seg_cnt is the number of data segments\n+\t// required. Needs to be dynamically allocated.\n+\tsgs = calloc(seg_cnt + 2, sizeof(struct virtio_sg *));\n+\tif (!sgs)\n+\t\treturn -ENOMEM;\n+\n+\tfor (i = 0; i < seg_cnt + 2; ++i) {\n+\t\tsgs[i] = malloc(sizeof(struct virtio_sg));\n+\t\tif (!sgs[i])\n+\t\t\tgoto err_free;\n+\t}\n \n-\tsector <<= priv->blksz_shift;\n-\tblkcnt <<= priv->blksz_shift;\n-\tvirtio_blk_init_header_sg(dev, sector, type, &out_hdr, &hdr_sg);\n-\tsgs[num_out++] = &hdr_sg;\n+\tvirtio_blk_init_header_sg(dev, sector, type, &out_hdr, sgs[num_out++]);\n \n \tswitch (type) {\n \tcase VIRTIO_BLK_T_IN:\n-\tcase VIRTIO_BLK_T_OUT:\n-\t\tvirtio_blk_init_data_sg(buffer, blkcnt, &data_sg);\n-\t\tif (type & VIRTIO_BLK_T_OUT)\n-\t\t\tsgs[num_out++] = &data_sg;\n-\t\telse\n-\t\t\tsgs[num_out + num_in++] = &data_sg;\n+\tcase VIRTIO_BLK_T_OUT: {\n+\t\ti = 0;\n+\t\twhile (i < blkcnt) {\n+\t\t\tu32 blk_per_seg = min(blkcnt - i, seg_sec_cnt);\n+\n+\t\t\tif (type & VIRTIO_BLK_T_OUT)\n+\t\t\t\tvirtio_blk_init_data_sg(buffer + i * 512, blk_per_seg,\n+\t\t\t\t\t\t\tsgs[num_out++]);\n+\t\t\telse\n+\t\t\t\tvirtio_blk_init_data_sg(buffer + i * 512, blk_per_seg,\n+\t\t\t\t\t\t\tsgs[num_out + num_in++]);\n+\t\t\ti += blk_per_seg;\n+\t\t}\n \t\tbreak;\n-\n+\t}\n \tcase VIRTIO_BLK_T_WRITE_ZEROES:\n-\t\tvirtio_blk_init_write_zeroes_sg(dev, sector, blkcnt, &wz_hdr, &wz_sg);\n-\t\tsgs[num_out++] = &wz_sg;\n+\t\tvirtio_blk_init_write_zeroes_sg(dev, sector, blkcnt, &wz_hdr,\n+\t\t\t\t\t\tsgs[num_out++]);\n \t\tbreak;\n \n \tdefault:\n-\t\treturn -EINVAL;\n+\t\tgoto err_free;\n \t}\n \n-\tvirtio_blk_init_status_sg(&status, &status_sg);\n-\tsgs[num_out + num_in++] = &status_sg;\n+\tvirtio_blk_init_status_sg(&status, sgs[num_out + num_in++]);\n \tlog_debug(\"dev=%s, active=%d, priv=%p, priv->vq=%p\\n\", dev->name,\n \t\t device_active(dev), priv, priv->vq);\n \n \tret = virtqueue_add(priv->vq, sgs, num_out, num_in);\n \tif (ret)\n-\t\treturn ret;\n+\t\tgoto err_free;\n \n \tvirtqueue_kick(priv->vq);\n \n@@ -119,7 +145,38 @@ static ulong virtio_blk_do_req(struct udevice *dev, u64 sector,\n \t\t;\n \tlog_debug(\"done\\n\");\n \n-\treturn status == VIRTIO_BLK_S_OK ? blkcnt >> priv->blksz_shift : -EIO;\n+err_free:\n+\tfor (i = 0; i < seg_cnt + 2; ++i)\n+\t\tfree(sgs[i]);\n+\tfree(sgs);\n+\n+\treturn status == VIRTIO_BLK_S_OK ? blkcnt : -EIO;\n+}\n+\n+static ulong virtio_blk_do_req(struct udevice *dev, u64 sector,\n+\t\t\t lbaint_t blkcnt, char *buffer, u32 type)\n+{\n+\tstruct virtio_blk_priv *priv = dev_get_priv(dev);\n+\tlbaint_t seg_sec_cnt = priv->size_max / 512;\n+\tu32 i = 0;\n+\tulong ret;\n+\n+\tsector <<= priv->blksz_shift;\n+\tblkcnt <<= priv->blksz_shift;\n+\n+\t// The virtio device may have constrains on the maximum segment count. So\n+\t// send multiple virtio requests one after each other, if so.\n+\twhile (i < blkcnt) {\n+\t\tu32 blk_per_sg = min(blkcnt - i, seg_sec_cnt * priv->seg_max);\n+\n+\t\tret = virtio_blk_do_single_req(dev, sector + i, blk_per_sg,\n+\t\t\t\t\t buffer + i * 512, type);\n+\t\tif (!ret)\n+\t\t\treturn ret;\n+\t\ti += blk_per_sg;\n+\t}\n+\n+\treturn blkcnt >> priv->blksz_shift;\n }\n \n static ulong virtio_blk_read(struct udevice *dev, lbaint_t start,\n@@ -207,6 +264,15 @@ static int virtio_blk_probe(struct udevice *dev)\n \tpriv->blksz_shift = desc->log2blksz - 9;\n \tdesc->lba >>= priv->blksz_shift;\n \n+\tif (virtio_has_feature(dev, VIRTIO_BLK_F_SIZE_MAX))\n+\t\tvirtio_cread(dev, struct virtio_blk_config, size_max, &priv->size_max);\n+\telse\n+\t\tpriv->size_max = -1U;\n+\tif (virtio_has_feature(dev, VIRTIO_BLK_F_SEG_MAX))\n+\t\tvirtio_cread(dev, struct virtio_blk_config, seg_max, &priv->seg_max);\n+\telse\n+\t\tpriv->seg_max = -1U;\n+\n \treturn 0;\n }\n \n", "prefixes": [] }