From patchwork Mon Oct 4 19:38:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Schoenebeck X-Patchwork-Id: 12534733 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3EFCFC433F5 for ; Mon, 4 Oct 2021 20:12:21 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DEEE1613C8 for ; Mon, 4 Oct 2021 20:12:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org DEEE1613C8 Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=crudebyte.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:43418 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mXUJw-0003au-1N for qemu-devel@archiver.kernel.org; Mon, 04 Oct 2021 16:12:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43582) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mXUG0-0005iK-O6; Mon, 04 Oct 2021 16:08:16 -0400 Received: from lizzy.crudebyte.com ([91.194.90.13]:55945) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mXUFx-00019F-99; Mon, 04 Oct 2021 16:08:16 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=crudebyte.com; s=lizzy; h=Cc:To:Subject:Date:From:References:In-Reply-To: Message-Id:Content-Type:Content-Transfer-Encoding:MIME-Version:Content-ID: Content-Description; bh=gbyhVmoZkXJH8ENNg3VoBX0nDZYMIONufEqWD5tBHlk=; b=RnfjC KyPnNYMKQeWdNAoCwC9LVSEMeI0gFEmpsgRC5Wtq5l4dbsmFjBlA1TGt1tYhVAJHyemXwt09T24Gp AAtKkg4QORw7UA6mR7WTMufC4rrrYzgYiWxO2r2JWjBju2oFR3CCW1UPIgyufGiJV6c7YFFhWnHGb hOlQXkCDVyfTA9ipi+b7vIyfJVhehtB/ZflLaKQITec3DafyhemzFBNqCYVteXIfGpFJl1zPU5qZ9 FB5vCObOk79q2z1Wj315k9/+x3fjEu+lsN5J2h9JfnpbZpPcaLGJdj3oo4by9YBgTcSstuNretXJM 9G+AigDJ/frSWPmbYDNAOxjJMUmyQ==; Message-Id: In-Reply-To: References: From: Christian Schoenebeck Date: Mon, 4 Oct 2021 21:38:04 +0200 Subject: [PATCH v2 1/3] virtio: turn VIRTQUEUE_MAX_SIZE into a variable To: qemu-devel@nongnu.org Cc: =?unknown-8bit?b?Ik1pY2hhZWwgUy4gVHNpcmtpbiIgPG1zdEByZWRoYXQuY29tPiw=?= =?unknown-8bit?q?_Greg_Kurz_=3Cgroug=40kaod=2Eorg=3E=2C?= =?unknown-8bit?q?_Raphael_Norwitz_=3Craphael=2Enorwitz=40nutanix=2Ecom=3E=2C?= =?unknown-8bit?q?_Kevin_Wolf_=3Ckwolf=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Hanna_Reitz_=3Chreitz=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Stefan_Hajnoczi_=3Cstefanha=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Laurent_Vivier_=3Clvivier=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Amit_Shah_=3Camit=40kernel=2Eorg=3E=2C?= =?unknown-8bit?q?_=22Marc-Andr=C3=A9_Lureau=22_=3Cmarcandre=2Elureau=40redha?= =?unknown-8bit?q?t=2Ecom=3E=2C?= =?unknown-8bit?q?_Paolo_Bonzini_=3Cpbonzini=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Gerd_Hoffmann_=3Ckraxel=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Jason_Wang_=3Cjasowang=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Fam_Zheng_=3Cfam=40euphon=2Enet=3E=2C?= =?unknown-8bit?q?_=22Dr=2E_David_Alan_Gilbert=22_=3Cdgilbert=40redhat=2Ecom?= =?unknown-8bit?q?=3E=2C?= =?unknown-8bit?q?_David_Hildenbrand_=3Cdavid=40redhat=2Ecom=3E=2C?= =?unknown-8bit?b?ICJHb25nbGVpIChBcmVpKSIgPGFyZWkuZ29uZ2xlaUBodWF3ZWkuY29t?= =?unknown-8bit?b?Piw=?= =?unknown-8bit?q?_Eric_Auger_=3Ceric=2Eauger=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_qemu-block=40nongnu=2Eorg=2C?= =?unknown-8bit?q?_virtio-fs=40redhat=2Ecom?= Received-SPF: none client-ip=91.194.90.13; envelope-from=c9dea2e27ae19b2b9a51e8f08687067bf3e47bd5@lizzy.crudebyte.com; helo=lizzy.crudebyte.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Refactor VIRTQUEUE_MAX_SIZE to effectively become a runtime variable per virtio user. Reasons: (1) VIRTQUEUE_MAX_SIZE should reflect the absolute theoretical maximum queue size possible. Which is actually the maximum queue size allowed by the virtio protocol. The appropriate value for VIRTQUEUE_MAX_SIZE would therefore be 32768: https://docs.oasis-open.org/virtio/virtio/v1.1/cs01/virtio-v1.1-cs01.html#x1-240006 Apparently VIRTQUEUE_MAX_SIZE was instead defined with a more or less arbitrary value of 1024 in the past, which limits the maximum transfer size with virtio to 4M (more precise: 1024 * PAGE_SIZE, with the latter typically being 4k). (2) Additionally the current value of 1024 poses a hidden limit, invisible to guest, which causes a system hang with the following QEMU error if guest tries to exceed it: virtio: too many write descriptors in indirect table (3) Unfortunately not all virtio users in QEMU would currently work correctly with the new value of 32768. So let's turn this hard coded global value into a runtime variable as a first step in this commit, configurable for each virtio user by passing a corresponding value with virtio_init() call. Signed-off-by: Christian Schoenebeck Reviewed-by: Greg Kurz --- hw/9pfs/virtio-9p-device.c | 3 ++- hw/block/vhost-user-blk.c | 2 +- hw/block/virtio-blk.c | 3 ++- hw/char/virtio-serial-bus.c | 2 +- hw/display/virtio-gpu-base.c | 2 +- hw/input/virtio-input.c | 2 +- hw/net/virtio-net.c | 15 ++++++++------- hw/scsi/virtio-scsi.c | 2 +- hw/virtio/vhost-user-fs.c | 2 +- hw/virtio/vhost-user-i2c.c | 3 ++- hw/virtio/vhost-vsock-common.c | 2 +- hw/virtio/virtio-balloon.c | 4 ++-- hw/virtio/virtio-crypto.c | 3 ++- hw/virtio/virtio-iommu.c | 2 +- hw/virtio/virtio-mem.c | 2 +- hw/virtio/virtio-pmem.c | 2 +- hw/virtio/virtio-rng.c | 2 +- hw/virtio/virtio.c | 35 +++++++++++++++++++++++----------- include/hw/virtio/virtio.h | 5 ++++- 19 files changed, 57 insertions(+), 36 deletions(-) diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c index 54ee93b71f..cd5d95dd51 100644 --- a/hw/9pfs/virtio-9p-device.c +++ b/hw/9pfs/virtio-9p-device.c @@ -216,7 +216,8 @@ static void virtio_9p_device_realize(DeviceState *dev, Error **errp) } v->config_size = sizeof(struct virtio_9p_config) + strlen(s->fsconf.tag); - virtio_init(vdev, "virtio-9p", VIRTIO_ID_9P, v->config_size); + virtio_init(vdev, "virtio-9p", VIRTIO_ID_9P, v->config_size, + VIRTQUEUE_MAX_SIZE); v->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output); } diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index ba13cb87e5..336f56705c 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -491,7 +491,7 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp) } virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK, - sizeof(struct virtio_blk_config)); + sizeof(struct virtio_blk_config), VIRTQUEUE_MAX_SIZE); s->virtqs = g_new(VirtQueue *, s->num_queues); for (i = 0; i < s->num_queues; i++) { diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index f139cd7cc9..9c0f46815c 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -1213,7 +1213,8 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) virtio_blk_set_config_size(s, s->host_features); - virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK, s->config_size); + virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK, s->config_size, + VIRTQUEUE_MAX_SIZE); s->blk = conf->conf.blk; s->rq = NULL; diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index f01ec2137c..9ad9111115 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -1045,7 +1045,7 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp) config_size = offsetof(struct virtio_console_config, emerg_wr); } virtio_init(vdev, "virtio-serial", VIRTIO_ID_CONSOLE, - config_size); + config_size, VIRTQUEUE_MAX_SIZE); /* Spawn a new virtio-serial bus on which the ports will ride as devices */ qbus_init(&vser->bus, sizeof(vser->bus), TYPE_VIRTIO_SERIAL_BUS, diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c index c8da4806e0..20b06a7adf 100644 --- a/hw/display/virtio-gpu-base.c +++ b/hw/display/virtio-gpu-base.c @@ -171,7 +171,7 @@ virtio_gpu_base_device_realize(DeviceState *qdev, g->virtio_config.num_scanouts = cpu_to_le32(g->conf.max_outputs); virtio_init(VIRTIO_DEVICE(g), "virtio-gpu", VIRTIO_ID_GPU, - sizeof(struct virtio_gpu_config)); + sizeof(struct virtio_gpu_config), VIRTQUEUE_MAX_SIZE); if (virtio_gpu_virgl_enabled(g->conf)) { /* use larger control queue in 3d mode */ diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c index 54bcb46c74..345eb2cce7 100644 --- a/hw/input/virtio-input.c +++ b/hw/input/virtio-input.c @@ -258,7 +258,7 @@ static void virtio_input_device_realize(DeviceState *dev, Error **errp) assert(vinput->cfg_size <= sizeof(virtio_input_config)); virtio_init(vdev, "virtio-input", VIRTIO_ID_INPUT, - vinput->cfg_size); + vinput->cfg_size, VIRTQUEUE_MAX_SIZE); vinput->evt = virtio_add_queue(vdev, 64, virtio_input_handle_evt); vinput->sts = virtio_add_queue(vdev, 64, virtio_input_handle_sts); } diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index f205331dcf..f74b5f6268 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1746,9 +1746,9 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf, VirtIONet *n = qemu_get_nic_opaque(nc); VirtIONetQueue *q = virtio_net_get_subqueue(nc); VirtIODevice *vdev = VIRTIO_DEVICE(n); - VirtQueueElement *elems[VIRTQUEUE_MAX_SIZE]; - size_t lens[VIRTQUEUE_MAX_SIZE]; - struct iovec mhdr_sg[VIRTQUEUE_MAX_SIZE]; + VirtQueueElement *elems[vdev->queue_max_size]; + size_t lens[vdev->queue_max_size]; + struct iovec mhdr_sg[vdev->queue_max_size]; struct virtio_net_hdr_mrg_rxbuf mhdr; unsigned mhdr_cnt = 0; size_t offset, i, guest_offset, j; @@ -1783,7 +1783,7 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf, total = 0; - if (i == VIRTQUEUE_MAX_SIZE) { + if (i == vdev->queue_max_size) { virtio_error(vdev, "virtio-net unexpected long buffer chain"); err = size; goto err; @@ -2532,7 +2532,7 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) for (;;) { ssize_t ret; unsigned int out_num; - struct iovec sg[VIRTQUEUE_MAX_SIZE], sg2[VIRTQUEUE_MAX_SIZE + 1], *out_sg; + struct iovec sg[vdev->queue_max_size], sg2[vdev->queue_max_size + 1], *out_sg; struct virtio_net_hdr_mrg_rxbuf mhdr; elem = virtqueue_pop(q->tx_vq, sizeof(VirtQueueElement)); @@ -2564,7 +2564,7 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) out_num = iov_copy(&sg2[1], ARRAY_SIZE(sg2) - 1, out_sg, out_num, n->guest_hdr_len, -1); - if (out_num == VIRTQUEUE_MAX_SIZE) { + if (out_num == vdev->queue_max_size) { goto drop; } out_num += 1; @@ -3364,7 +3364,8 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) } virtio_net_set_config_size(n, n->host_features); - virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size); + virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size, + VIRTQUEUE_MAX_SIZE); /* * We set a lower limit on RX queue size to what it always was. diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 51fd09522a..5e5e657e1d 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -973,7 +973,7 @@ void virtio_scsi_common_realize(DeviceState *dev, int i; virtio_init(vdev, "virtio-scsi", VIRTIO_ID_SCSI, - sizeof(VirtIOSCSIConfig)); + sizeof(VirtIOSCSIConfig), VIRTQUEUE_MAX_SIZE); if (s->conf.num_queues == VIRTIO_SCSI_AUTO_NUM_QUEUES) { s->conf.num_queues = 1; diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c index c595957983..ae1672d667 100644 --- a/hw/virtio/vhost-user-fs.c +++ b/hw/virtio/vhost-user-fs.c @@ -220,7 +220,7 @@ static void vuf_device_realize(DeviceState *dev, Error **errp) } virtio_init(vdev, "vhost-user-fs", VIRTIO_ID_FS, - sizeof(struct virtio_fs_config)); + sizeof(struct virtio_fs_config), VIRTQUEUE_MAX_SIZE); /* Hiprio queue */ fs->hiprio_vq = virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output); diff --git a/hw/virtio/vhost-user-i2c.c b/hw/virtio/vhost-user-i2c.c index d172632bb0..eeb1d8853a 100644 --- a/hw/virtio/vhost-user-i2c.c +++ b/hw/virtio/vhost-user-i2c.c @@ -220,7 +220,8 @@ static void vu_i2c_device_realize(DeviceState *dev, Error **errp) return; } - virtio_init(vdev, "vhost-user-i2c", VIRTIO_ID_I2C_ADAPTER, 0); + virtio_init(vdev, "vhost-user-i2c", VIRTIO_ID_I2C_ADAPTER, 0, + VIRTQUEUE_MAX_SIZE); i2c->vhost_dev.nvqs = 1; i2c->vq = virtio_add_queue(vdev, 4, vu_i2c_handle_output); diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c index 4ad6e234ad..a81fa884a8 100644 --- a/hw/virtio/vhost-vsock-common.c +++ b/hw/virtio/vhost-vsock-common.c @@ -201,7 +201,7 @@ void vhost_vsock_common_realize(VirtIODevice *vdev, const char *name) VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev); virtio_init(vdev, name, VIRTIO_ID_VSOCK, - sizeof(struct virtio_vsock_config)); + sizeof(struct virtio_vsock_config), VIRTQUEUE_MAX_SIZE); /* Receive and transmit queues belong to vhost */ vvc->recv_vq = virtio_add_queue(vdev, VHOST_VSOCK_QUEUE_SIZE, diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 5a69dce35d..067c73223d 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -886,7 +886,7 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp) int ret; virtio_init(vdev, "virtio-balloon", VIRTIO_ID_BALLOON, - virtio_balloon_config_size(s)); + virtio_balloon_config_size(s), VIRTQUEUE_MAX_SIZE); ret = qemu_add_balloon_handler(virtio_balloon_to_target, virtio_balloon_stat, s); @@ -909,7 +909,7 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp) s->svq = virtio_add_queue(vdev, 128, virtio_balloon_receive_stats); if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) { - s->free_page_vq = virtio_add_queue(vdev, VIRTQUEUE_MAX_SIZE, + s->free_page_vq = virtio_add_queue(vdev, vdev->queue_max_size, virtio_balloon_handle_free_page_vq); precopy_add_notifier(&s->free_page_hint_notify); diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c index 54f9bbb789..1e70d4d2a8 100644 --- a/hw/virtio/virtio-crypto.c +++ b/hw/virtio/virtio-crypto.c @@ -810,7 +810,8 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp) return; } - virtio_init(vdev, "virtio-crypto", VIRTIO_ID_CRYPTO, vcrypto->config_size); + virtio_init(vdev, "virtio-crypto", VIRTIO_ID_CRYPTO, vcrypto->config_size, + VIRTQUEUE_MAX_SIZE); vcrypto->curr_queues = 1; vcrypto->vqs = g_malloc0(sizeof(VirtIOCryptoQueue) * vcrypto->max_queues); for (i = 0; i < vcrypto->max_queues; i++) { diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 1b23e8e18c..ca360e74eb 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -974,7 +974,7 @@ static void virtio_iommu_device_realize(DeviceState *dev, Error **errp) VirtIOIOMMU *s = VIRTIO_IOMMU(dev); virtio_init(vdev, "virtio-iommu", VIRTIO_ID_IOMMU, - sizeof(struct virtio_iommu_config)); + sizeof(struct virtio_iommu_config), VIRTQUEUE_MAX_SIZE); memset(s->iommu_pcibus_by_bus_num, 0, sizeof(s->iommu_pcibus_by_bus_num)); diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c index df91e454b2..1d9d01b871 100644 --- a/hw/virtio/virtio-mem.c +++ b/hw/virtio/virtio-mem.c @@ -738,7 +738,7 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp) vmem->bitmap = bitmap_new(vmem->bitmap_size); virtio_init(vdev, TYPE_VIRTIO_MEM, VIRTIO_ID_MEM, - sizeof(struct virtio_mem_config)); + sizeof(struct virtio_mem_config), VIRTQUEUE_MAX_SIZE); vmem->vq = virtio_add_queue(vdev, 128, virtio_mem_handle_request); host_memory_backend_set_mapped(vmem->memdev, true); diff --git a/hw/virtio/virtio-pmem.c b/hw/virtio/virtio-pmem.c index d1aeb90a31..82b54b00c5 100644 --- a/hw/virtio/virtio-pmem.c +++ b/hw/virtio/virtio-pmem.c @@ -124,7 +124,7 @@ static void virtio_pmem_realize(DeviceState *dev, Error **errp) host_memory_backend_set_mapped(pmem->memdev, true); virtio_init(vdev, TYPE_VIRTIO_PMEM, VIRTIO_ID_PMEM, - sizeof(struct virtio_pmem_config)); + sizeof(struct virtio_pmem_config), VIRTQUEUE_MAX_SIZE); pmem->rq_vq = virtio_add_queue(vdev, 128, virtio_pmem_flush); } diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c index cc8e9f775d..0e91d60106 100644 --- a/hw/virtio/virtio-rng.c +++ b/hw/virtio/virtio-rng.c @@ -215,7 +215,7 @@ static void virtio_rng_device_realize(DeviceState *dev, Error **errp) return; } - virtio_init(vdev, "virtio-rng", VIRTIO_ID_RNG, 0); + virtio_init(vdev, "virtio-rng", VIRTIO_ID_RNG, 0, VIRTQUEUE_MAX_SIZE); vrng->vq = virtio_add_queue(vdev, 8, handle_input); vrng->quota_remaining = vrng->conf.max_bytes; diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 240759ff0b..60e094d96a 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -1419,8 +1419,8 @@ static void *virtqueue_split_pop(VirtQueue *vq, size_t sz) VirtIODevice *vdev = vq->vdev; VirtQueueElement *elem = NULL; unsigned out_num, in_num, elem_entries; - hwaddr addr[VIRTQUEUE_MAX_SIZE]; - struct iovec iov[VIRTQUEUE_MAX_SIZE]; + hwaddr addr[vdev->queue_max_size]; + struct iovec iov[vdev->queue_max_size]; VRingDesc desc; int rc; @@ -1492,7 +1492,7 @@ static void *virtqueue_split_pop(VirtQueue *vq, size_t sz) if (desc.flags & VRING_DESC_F_WRITE) { map_ok = virtqueue_map_desc(vdev, &in_num, addr + out_num, iov + out_num, - VIRTQUEUE_MAX_SIZE - out_num, true, + vdev->queue_max_size - out_num, true, desc.addr, desc.len); } else { if (in_num) { @@ -1500,7 +1500,7 @@ static void *virtqueue_split_pop(VirtQueue *vq, size_t sz) goto err_undo_map; } map_ok = virtqueue_map_desc(vdev, &out_num, addr, iov, - VIRTQUEUE_MAX_SIZE, false, + vdev->queue_max_size, false, desc.addr, desc.len); } if (!map_ok) { @@ -1556,8 +1556,8 @@ static void *virtqueue_packed_pop(VirtQueue *vq, size_t sz) VirtIODevice *vdev = vq->vdev; VirtQueueElement *elem = NULL; unsigned out_num, in_num, elem_entries; - hwaddr addr[VIRTQUEUE_MAX_SIZE]; - struct iovec iov[VIRTQUEUE_MAX_SIZE]; + hwaddr addr[vdev->queue_max_size]; + struct iovec iov[vdev->queue_max_size]; VRingPackedDesc desc; uint16_t id; int rc; @@ -1620,7 +1620,7 @@ static void *virtqueue_packed_pop(VirtQueue *vq, size_t sz) if (desc.flags & VRING_DESC_F_WRITE) { map_ok = virtqueue_map_desc(vdev, &in_num, addr + out_num, iov + out_num, - VIRTQUEUE_MAX_SIZE - out_num, true, + vdev->queue_max_size - out_num, true, desc.addr, desc.len); } else { if (in_num) { @@ -1628,7 +1628,7 @@ static void *virtqueue_packed_pop(VirtQueue *vq, size_t sz) goto err_undo_map; } map_ok = virtqueue_map_desc(vdev, &out_num, addr, iov, - VIRTQUEUE_MAX_SIZE, false, + vdev->queue_max_size, false, desc.addr, desc.len); } if (!map_ok) { @@ -2249,7 +2249,7 @@ void virtio_queue_set_num(VirtIODevice *vdev, int n, int num) * nonexistent states, or to set it to an invalid size. */ if (!!num != !!vdev->vq[n].vring.num || - num > VIRTQUEUE_MAX_SIZE || + num > vdev->queue_max_size || num < 0) { return; } @@ -2400,7 +2400,7 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, break; } - if (i == VIRTIO_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE) + if (i == VIRTIO_QUEUE_MAX || queue_size > vdev->queue_max_size) abort(); vdev->vq[i].vring.num = queue_size; @@ -3239,13 +3239,25 @@ void virtio_instance_init_common(Object *proxy_obj, void *data, } void virtio_init(VirtIODevice *vdev, const char *name, - uint16_t device_id, size_t config_size) + uint16_t device_id, size_t config_size, + uint16_t queue_max_size) { BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); int i; int nvectors = k->query_nvectors ? k->query_nvectors(qbus->parent) : 0; + if (queue_max_size > VIRTQUEUE_MAX_SIZE || + !is_power_of_2(queue_max_size)) + { + error_report( + "virtio: invalid queue_max_size (= %" PRIu16 "), must be a " + "power of 2 and between 1 ... %d.", + queue_max_size, VIRTQUEUE_MAX_SIZE + ); + abort(); + } + if (nvectors) { vdev->vector_queues = g_malloc0(sizeof(*vdev->vector_queues) * nvectors); @@ -3258,6 +3270,7 @@ void virtio_init(VirtIODevice *vdev, const char *name, qatomic_set(&vdev->isr, 0); vdev->queue_sel = 0; vdev->config_vector = VIRTIO_NO_VECTOR; + vdev->queue_max_size = queue_max_size; vdev->vq = g_malloc0(sizeof(VirtQueue) * VIRTIO_QUEUE_MAX); vdev->vm_running = runstate_is_running(); vdev->broken = false; diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 8bab9cfb75..a37d1f7d52 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -89,6 +89,7 @@ struct VirtIODevice size_t config_len; void *config; uint16_t config_vector; + uint16_t queue_max_size; uint32_t generation; int nvectors; VirtQueue *vq; @@ -166,7 +167,9 @@ void virtio_instance_init_common(Object *proxy_obj, void *data, size_t vdev_size, const char *vdev_name); void virtio_init(VirtIODevice *vdev, const char *name, - uint16_t device_id, size_t config_size); + uint16_t device_id, size_t config_size, + uint16_t queue_max_size); + void virtio_cleanup(VirtIODevice *vdev); void virtio_error(VirtIODevice *vdev, const char *fmt, ...) GCC_FMT_ATTR(2, 3); From patchwork Mon Oct 4 19:38:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Schoenebeck X-Patchwork-Id: 12534737 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 943A2C433F5 for ; Mon, 4 Oct 2021 20:16:38 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0718661108 for ; Mon, 4 Oct 2021 20:16:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 0718661108 Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=crudebyte.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:51716 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mXUO5-0000qE-4g for qemu-devel@archiver.kernel.org; Mon, 04 Oct 2021 16:16:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43596) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mXUG3-0005pe-4I; Mon, 04 Oct 2021 16:08:19 -0400 Received: from lizzy.crudebyte.com ([91.194.90.13]:50659) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mXUG0-0001Gn-J6; Mon, 04 Oct 2021 16:08:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=crudebyte.com; s=lizzy; h=Cc:To:Subject:Date:From:References:In-Reply-To: Message-Id:Content-Type:Content-Transfer-Encoding:MIME-Version:Content-ID: Content-Description; bh=niZRlBBn+bQaFDTfXlNLeVkVNE2pBTzoMOrfXS/Qsf8=; b=AhrMs TA6jBLNxwEjo0Q1CdPEks+1IAOzfw9xFc5lvidbVF/7LqilAfHN03W6NsN2+Jmw687bTM1J4sevYL 54lbnAiidvGzl69qwdKG2pKzQRdLVnr3EOPqagD8Hd8YYsdnny1BmP34NA7FpkWGqmbqtPWIt00RP 6TYdFgsvKFCH5KQeOP5JecSXUQKTXM/sRUvji3wrp4BrWZ8jWa/2iXtGh6713+LKQMROFvSqWyUru wp6d8w3x8/u5jaCp2wGgkenvMq72UdC6jsWpcuH8HU+IXwH9zvDy/ixHb7TazRqZEQo4qx6UirQdO d9SB19N7xyzJuV2hMvgDQGLD4buPA==; Message-Id: In-Reply-To: References: From: Christian Schoenebeck Date: Mon, 4 Oct 2021 21:38:08 +0200 Subject: [PATCH v2 2/3] virtio: increase VIRTQUEUE_MAX_SIZE to 32k To: qemu-devel@nongnu.org Cc: =?unknown-8bit?b?Ik1pY2hhZWwgUy4gVHNpcmtpbiIgPG1zdEByZWRoYXQuY29tPiw=?= =?unknown-8bit?q?_Greg_Kurz_=3Cgroug=40kaod=2Eorg=3E=2C?= =?unknown-8bit?q?_Raphael_Norwitz_=3Craphael=2Enorwitz=40nutanix=2Ecom=3E=2C?= =?unknown-8bit?q?_Kevin_Wolf_=3Ckwolf=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Hanna_Reitz_=3Chreitz=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Stefan_Hajnoczi_=3Cstefanha=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Laurent_Vivier_=3Clvivier=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Amit_Shah_=3Camit=40kernel=2Eorg=3E=2C?= =?unknown-8bit?q?_=22Marc-Andr=C3=A9_Lureau=22_=3Cmarcandre=2Elureau=40redha?= =?unknown-8bit?q?t=2Ecom=3E=2C?= =?unknown-8bit?q?_Paolo_Bonzini_=3Cpbonzini=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Gerd_Hoffmann_=3Ckraxel=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Jason_Wang_=3Cjasowang=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Fam_Zheng_=3Cfam=40euphon=2Enet=3E=2C?= =?unknown-8bit?q?_=22Dr=2E_David_Alan_Gilbert=22_=3Cdgilbert=40redhat=2Ecom?= =?unknown-8bit?q?=3E=2C?= =?unknown-8bit?q?_David_Hildenbrand_=3Cdavid=40redhat=2Ecom=3E=2C?= =?unknown-8bit?b?ICJHb25nbGVpIChBcmVpKSIgPGFyZWkuZ29uZ2xlaUBodWF3ZWkuY29t?= =?unknown-8bit?b?Piw=?= =?unknown-8bit?q?_Eric_Auger_=3Ceric=2Eauger=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_qemu-block=40nongnu=2Eorg=2C?= =?unknown-8bit?q?_virtio-fs=40redhat=2Ecom?= Received-SPF: none client-ip=91.194.90.13; envelope-from=d39e127ecae12fa18bf01d1e405eb4010a275cf5@lizzy.crudebyte.com; helo=lizzy.crudebyte.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Raise the maximum possible virtio transfer size to 128M (more precisely: 32k * PAGE_SIZE). See previous commit for a more detailed explanation for the reasons of this change. For not breaking any virtio user, all virtio users transition to using the new macro VIRTQUEUE_LEGACY_MAX_SIZE instead of VIRTQUEUE_MAX_SIZE, so they are all still using the old value of 1k with this commit. On the long-term, each virtio user should subsequently either switch from VIRTQUEUE_LEGACY_MAX_SIZE to VIRTQUEUE_MAX_SIZE after checking that they support the new value of 32k, or otherwise they should replace the VIRTQUEUE_LEGACY_MAX_SIZE macro by an appropriate value supported by them. Signed-off-by: Christian Schoenebeck --- hw/9pfs/virtio-9p-device.c | 2 +- hw/block/vhost-user-blk.c | 6 +++--- hw/block/virtio-blk.c | 6 +++--- hw/char/virtio-serial-bus.c | 2 +- hw/input/virtio-input.c | 2 +- hw/net/virtio-net.c | 12 ++++++------ hw/scsi/virtio-scsi.c | 2 +- hw/virtio/vhost-user-fs.c | 6 +++--- hw/virtio/vhost-user-i2c.c | 2 +- hw/virtio/vhost-vsock-common.c | 2 +- hw/virtio/virtio-balloon.c | 2 +- hw/virtio/virtio-crypto.c | 2 +- hw/virtio/virtio-iommu.c | 2 +- hw/virtio/virtio-mem.c | 2 +- hw/virtio/virtio-mmio.c | 4 ++-- hw/virtio/virtio-pmem.c | 2 +- hw/virtio/virtio-rng.c | 3 ++- include/hw/virtio/virtio.h | 20 +++++++++++++++++++- 18 files changed, 49 insertions(+), 30 deletions(-) diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c index cd5d95dd51..9013e7df6e 100644 --- a/hw/9pfs/virtio-9p-device.c +++ b/hw/9pfs/virtio-9p-device.c @@ -217,7 +217,7 @@ static void virtio_9p_device_realize(DeviceState *dev, Error **errp) v->config_size = sizeof(struct virtio_9p_config) + strlen(s->fsconf.tag); virtio_init(vdev, "virtio-9p", VIRTIO_ID_9P, v->config_size, - VIRTQUEUE_MAX_SIZE); + VIRTQUEUE_LEGACY_MAX_SIZE); v->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output); } diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index 336f56705c..e5e45262ab 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -480,9 +480,9 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp) error_setg(errp, "queue size must be non-zero"); return; } - if (s->queue_size > VIRTQUEUE_MAX_SIZE) { + if (s->queue_size > VIRTQUEUE_LEGACY_MAX_SIZE) { error_setg(errp, "queue size must not exceed %d", - VIRTQUEUE_MAX_SIZE); + VIRTQUEUE_LEGACY_MAX_SIZE); return; } @@ -491,7 +491,7 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp) } virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK, - sizeof(struct virtio_blk_config), VIRTQUEUE_MAX_SIZE); + sizeof(struct virtio_blk_config), VIRTQUEUE_LEGACY_MAX_SIZE); s->virtqs = g_new(VirtQueue *, s->num_queues); for (i = 0; i < s->num_queues; i++) { diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 9c0f46815c..5883e3e7db 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -1171,10 +1171,10 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) return; } if (!is_power_of_2(conf->queue_size) || - conf->queue_size > VIRTQUEUE_MAX_SIZE) { + conf->queue_size > VIRTQUEUE_LEGACY_MAX_SIZE) { error_setg(errp, "invalid queue-size property (%" PRIu16 "), " "must be a power of 2 (max %d)", - conf->queue_size, VIRTQUEUE_MAX_SIZE); + conf->queue_size, VIRTQUEUE_LEGACY_MAX_SIZE); return; } @@ -1214,7 +1214,7 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) virtio_blk_set_config_size(s, s->host_features); virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK, s->config_size, - VIRTQUEUE_MAX_SIZE); + VIRTQUEUE_LEGACY_MAX_SIZE); s->blk = conf->conf.blk; s->rq = NULL; diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index 9ad9111115..2d4285ab53 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -1045,7 +1045,7 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp) config_size = offsetof(struct virtio_console_config, emerg_wr); } virtio_init(vdev, "virtio-serial", VIRTIO_ID_CONSOLE, - config_size, VIRTQUEUE_MAX_SIZE); + config_size, VIRTQUEUE_LEGACY_MAX_SIZE); /* Spawn a new virtio-serial bus on which the ports will ride as devices */ qbus_init(&vser->bus, sizeof(vser->bus), TYPE_VIRTIO_SERIAL_BUS, diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c index 345eb2cce7..b6b77488f2 100644 --- a/hw/input/virtio-input.c +++ b/hw/input/virtio-input.c @@ -258,7 +258,7 @@ static void virtio_input_device_realize(DeviceState *dev, Error **errp) assert(vinput->cfg_size <= sizeof(virtio_input_config)); virtio_init(vdev, "virtio-input", VIRTIO_ID_INPUT, - vinput->cfg_size, VIRTQUEUE_MAX_SIZE); + vinput->cfg_size, VIRTQUEUE_LEGACY_MAX_SIZE); vinput->evt = virtio_add_queue(vdev, 64, virtio_input_handle_evt); vinput->sts = virtio_add_queue(vdev, 64, virtio_input_handle_sts); } diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index f74b5f6268..5100978b07 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -636,7 +636,7 @@ static int virtio_net_max_tx_queue_size(VirtIONet *n) return VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE; } - return VIRTQUEUE_MAX_SIZE; + return VIRTQUEUE_LEGACY_MAX_SIZE; } static int peer_attach(VirtIONet *n, int index) @@ -3365,7 +3365,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) virtio_net_set_config_size(n, n->host_features); virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size, - VIRTQUEUE_MAX_SIZE); + VIRTQUEUE_LEGACY_MAX_SIZE); /* * We set a lower limit on RX queue size to what it always was. @@ -3373,23 +3373,23 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) * help from us (using virtio 1 and up). */ if (n->net_conf.rx_queue_size < VIRTIO_NET_RX_QUEUE_MIN_SIZE || - n->net_conf.rx_queue_size > VIRTQUEUE_MAX_SIZE || + n->net_conf.rx_queue_size > VIRTQUEUE_LEGACY_MAX_SIZE || !is_power_of_2(n->net_conf.rx_queue_size)) { error_setg(errp, "Invalid rx_queue_size (= %" PRIu16 "), " "must be a power of 2 between %d and %d.", n->net_conf.rx_queue_size, VIRTIO_NET_RX_QUEUE_MIN_SIZE, - VIRTQUEUE_MAX_SIZE); + VIRTQUEUE_LEGACY_MAX_SIZE); virtio_cleanup(vdev); return; } if (n->net_conf.tx_queue_size < VIRTIO_NET_TX_QUEUE_MIN_SIZE || - n->net_conf.tx_queue_size > VIRTQUEUE_MAX_SIZE || + n->net_conf.tx_queue_size > VIRTQUEUE_LEGACY_MAX_SIZE || !is_power_of_2(n->net_conf.tx_queue_size)) { error_setg(errp, "Invalid tx_queue_size (= %" PRIu16 "), " "must be a power of 2 between %d and %d", n->net_conf.tx_queue_size, VIRTIO_NET_TX_QUEUE_MIN_SIZE, - VIRTQUEUE_MAX_SIZE); + VIRTQUEUE_LEGACY_MAX_SIZE); virtio_cleanup(vdev); return; } diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 5e5e657e1d..f204e8878a 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -973,7 +973,7 @@ void virtio_scsi_common_realize(DeviceState *dev, int i; virtio_init(vdev, "virtio-scsi", VIRTIO_ID_SCSI, - sizeof(VirtIOSCSIConfig), VIRTQUEUE_MAX_SIZE); + sizeof(VirtIOSCSIConfig), VIRTQUEUE_LEGACY_MAX_SIZE); if (s->conf.num_queues == VIRTIO_SCSI_AUTO_NUM_QUEUES) { s->conf.num_queues = 1; diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c index ae1672d667..decc5def39 100644 --- a/hw/virtio/vhost-user-fs.c +++ b/hw/virtio/vhost-user-fs.c @@ -209,9 +209,9 @@ static void vuf_device_realize(DeviceState *dev, Error **errp) return; } - if (fs->conf.queue_size > VIRTQUEUE_MAX_SIZE) { + if (fs->conf.queue_size > VIRTQUEUE_LEGACY_MAX_SIZE) { error_setg(errp, "queue-size property must be %u or smaller", - VIRTQUEUE_MAX_SIZE); + VIRTQUEUE_LEGACY_MAX_SIZE); return; } @@ -220,7 +220,7 @@ static void vuf_device_realize(DeviceState *dev, Error **errp) } virtio_init(vdev, "vhost-user-fs", VIRTIO_ID_FS, - sizeof(struct virtio_fs_config), VIRTQUEUE_MAX_SIZE); + sizeof(struct virtio_fs_config), VIRTQUEUE_LEGACY_MAX_SIZE); /* Hiprio queue */ fs->hiprio_vq = virtio_add_queue(vdev, fs->conf.queue_size, vuf_handle_output); diff --git a/hw/virtio/vhost-user-i2c.c b/hw/virtio/vhost-user-i2c.c index eeb1d8853a..b248ddbe93 100644 --- a/hw/virtio/vhost-user-i2c.c +++ b/hw/virtio/vhost-user-i2c.c @@ -221,7 +221,7 @@ static void vu_i2c_device_realize(DeviceState *dev, Error **errp) } virtio_init(vdev, "vhost-user-i2c", VIRTIO_ID_I2C_ADAPTER, 0, - VIRTQUEUE_MAX_SIZE); + VIRTQUEUE_LEGACY_MAX_SIZE); i2c->vhost_dev.nvqs = 1; i2c->vq = virtio_add_queue(vdev, 4, vu_i2c_handle_output); diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c index a81fa884a8..73e6b72bba 100644 --- a/hw/virtio/vhost-vsock-common.c +++ b/hw/virtio/vhost-vsock-common.c @@ -201,7 +201,7 @@ void vhost_vsock_common_realize(VirtIODevice *vdev, const char *name) VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev); virtio_init(vdev, name, VIRTIO_ID_VSOCK, - sizeof(struct virtio_vsock_config), VIRTQUEUE_MAX_SIZE); + sizeof(struct virtio_vsock_config), VIRTQUEUE_LEGACY_MAX_SIZE); /* Receive and transmit queues belong to vhost */ vvc->recv_vq = virtio_add_queue(vdev, VHOST_VSOCK_QUEUE_SIZE, diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 067c73223d..890fb15ed3 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -886,7 +886,7 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp) int ret; virtio_init(vdev, "virtio-balloon", VIRTIO_ID_BALLOON, - virtio_balloon_config_size(s), VIRTQUEUE_MAX_SIZE); + virtio_balloon_config_size(s), VIRTQUEUE_LEGACY_MAX_SIZE); ret = qemu_add_balloon_handler(virtio_balloon_to_target, virtio_balloon_stat, s); diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c index 1e70d4d2a8..e13b6091d6 100644 --- a/hw/virtio/virtio-crypto.c +++ b/hw/virtio/virtio-crypto.c @@ -811,7 +811,7 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp) } virtio_init(vdev, "virtio-crypto", VIRTIO_ID_CRYPTO, vcrypto->config_size, - VIRTQUEUE_MAX_SIZE); + VIRTQUEUE_LEGACY_MAX_SIZE); vcrypto->curr_queues = 1; vcrypto->vqs = g_malloc0(sizeof(VirtIOCryptoQueue) * vcrypto->max_queues); for (i = 0; i < vcrypto->max_queues; i++) { diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index ca360e74eb..845df78842 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -974,7 +974,7 @@ static void virtio_iommu_device_realize(DeviceState *dev, Error **errp) VirtIOIOMMU *s = VIRTIO_IOMMU(dev); virtio_init(vdev, "virtio-iommu", VIRTIO_ID_IOMMU, - sizeof(struct virtio_iommu_config), VIRTQUEUE_MAX_SIZE); + sizeof(struct virtio_iommu_config), VIRTQUEUE_LEGACY_MAX_SIZE); memset(s->iommu_pcibus_by_bus_num, 0, sizeof(s->iommu_pcibus_by_bus_num)); diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c index 1d9d01b871..7a39550cde 100644 --- a/hw/virtio/virtio-mem.c +++ b/hw/virtio/virtio-mem.c @@ -738,7 +738,7 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp) vmem->bitmap = bitmap_new(vmem->bitmap_size); virtio_init(vdev, TYPE_VIRTIO_MEM, VIRTIO_ID_MEM, - sizeof(struct virtio_mem_config), VIRTQUEUE_MAX_SIZE); + sizeof(struct virtio_mem_config), VIRTQUEUE_LEGACY_MAX_SIZE); vmem->vq = virtio_add_queue(vdev, 128, virtio_mem_handle_request); host_memory_backend_set_mapped(vmem->memdev, true); diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c index 7b3ebca178..ae0cc223e9 100644 --- a/hw/virtio/virtio-mmio.c +++ b/hw/virtio/virtio-mmio.c @@ -174,7 +174,7 @@ static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned size) if (!virtio_queue_get_num(vdev, vdev->queue_sel)) { return 0; } - return VIRTQUEUE_MAX_SIZE; + return VIRTQUEUE_LEGACY_MAX_SIZE; case VIRTIO_MMIO_QUEUE_PFN: if (!proxy->legacy) { qemu_log_mask(LOG_GUEST_ERROR, @@ -348,7 +348,7 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value, } break; case VIRTIO_MMIO_QUEUE_NUM: - trace_virtio_mmio_queue_write(value, VIRTQUEUE_MAX_SIZE); + trace_virtio_mmio_queue_write(value, VIRTQUEUE_LEGACY_MAX_SIZE); virtio_queue_set_num(vdev, vdev->queue_sel, value); if (proxy->legacy) { diff --git a/hw/virtio/virtio-pmem.c b/hw/virtio/virtio-pmem.c index 82b54b00c5..5f4d375b58 100644 --- a/hw/virtio/virtio-pmem.c +++ b/hw/virtio/virtio-pmem.c @@ -124,7 +124,7 @@ static void virtio_pmem_realize(DeviceState *dev, Error **errp) host_memory_backend_set_mapped(pmem->memdev, true); virtio_init(vdev, TYPE_VIRTIO_PMEM, VIRTIO_ID_PMEM, - sizeof(struct virtio_pmem_config), VIRTQUEUE_MAX_SIZE); + sizeof(struct virtio_pmem_config), VIRTQUEUE_LEGACY_MAX_SIZE); pmem->rq_vq = virtio_add_queue(vdev, 128, virtio_pmem_flush); } diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c index 0e91d60106..ab075b22b6 100644 --- a/hw/virtio/virtio-rng.c +++ b/hw/virtio/virtio-rng.c @@ -215,7 +215,8 @@ static void virtio_rng_device_realize(DeviceState *dev, Error **errp) return; } - virtio_init(vdev, "virtio-rng", VIRTIO_ID_RNG, 0, VIRTQUEUE_MAX_SIZE); + virtio_init(vdev, "virtio-rng", VIRTIO_ID_RNG, 0, + VIRTQUEUE_LEGACY_MAX_SIZE); vrng->vq = virtio_add_queue(vdev, 8, handle_input); vrng->quota_remaining = vrng->conf.max_bytes; diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index a37d1f7d52..fe0f13266b 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -48,7 +48,25 @@ size_t virtio_feature_get_config_size(const VirtIOFeature *features, typedef struct VirtQueue VirtQueue; -#define VIRTQUEUE_MAX_SIZE 1024 +/* + * This is meant as transitional measure for VIRTQUEUE_MAX_SIZE's old value + * of 1024 to its new value of 32768. On the long-term virtio users should + * either switch to VIRTQUEUE_MAX_SIZE, provided they support 32768, + * otherwise they should replace this macro on their side with an + * appropriate value actually supported by them. + * + * Once all virtio users switched, this macro will be removed. + */ +#define VIRTQUEUE_LEGACY_MAX_SIZE 1024 + +/* + * Reflects the absolute theoretical maximum queue size (in amount of pages) + * ever possible, which is actually the maximum queue size allowed by the + * virtio protocol. This value therefore construes the maximum transfer size + * possible with virtio (multiplied by system dependent PAGE_SIZE); assuming + * a typical page size of 4k this would be a maximum transfer size of 128M. + */ +#define VIRTQUEUE_MAX_SIZE 32768 typedef struct VirtQueueElement { From patchwork Mon Oct 4 19:38:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Schoenebeck X-Patchwork-Id: 12534731 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 58AEDC433F5 for ; Mon, 4 Oct 2021 20:10:51 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0CCDF613D2 for ; Mon, 4 Oct 2021 20:10:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 0CCDF613D2 Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=crudebyte.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:38766 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mXUIU-0000Ik-2i for qemu-devel@archiver.kernel.org; Mon, 04 Oct 2021 16:10:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43616) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mXUG7-00060n-Ry; Mon, 04 Oct 2021 16:08:26 -0400 Received: from lizzy.crudebyte.com ([91.194.90.13]:36813) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mXUG6-0001MW-5e; Mon, 04 Oct 2021 16:08:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=crudebyte.com; s=lizzy; h=Cc:To:Subject:Date:From:References:In-Reply-To: Message-Id:Content-Type:Content-Transfer-Encoding:MIME-Version:Content-ID: Content-Description; bh=f4VjqFwtddhhj6avEVv72Wovsfu0a2P1y6ipMsVQxmA=; b=IygOj m3X/nSIkD2nnaQX8vUWiOXXWCOtw0SeHxoPvSZECg4Yeg9rTx+lD1LdOdl9L7NXoCA++t8jqwI8WV vyz59+yFPJTi9Dbj4279T5Lv3uaQLRs914I4tikhhrwEriiIbPIJcNYt5bVBG6HU3jSaRdweDrUQJ ScW/vbDJY9QXwo6rpeVWCdoJYjuD931OoPLRhcbMVXjNvY9GES/SOpKzX2gvIcnJ9oYBElXAMjhjK 71en4UlA3VR/XruMdBBw7aN9yvfErHlFXIHEKYkOVaq8pEe5Ccv4DceCafHRsowEbeX0giB9vz1xb OJTKFPQeBJqTP0lGDJOog/GlF8knQ==; Message-Id: In-Reply-To: References: From: Christian Schoenebeck Date: Mon, 4 Oct 2021 21:38:12 +0200 Subject: [PATCH v2 3/3] virtio-9p-device: switch to 32k max. transfer size To: qemu-devel@nongnu.org Cc: =?unknown-8bit?b?Ik1pY2hhZWwgUy4gVHNpcmtpbiIgPG1zdEByZWRoYXQuY29tPiw=?= =?unknown-8bit?q?_Greg_Kurz_=3Cgroug=40kaod=2Eorg=3E=2C?= =?unknown-8bit?q?_Raphael_Norwitz_=3Craphael=2Enorwitz=40nutanix=2Ecom=3E=2C?= =?unknown-8bit?q?_Kevin_Wolf_=3Ckwolf=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Hanna_Reitz_=3Chreitz=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Stefan_Hajnoczi_=3Cstefanha=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Laurent_Vivier_=3Clvivier=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Amit_Shah_=3Camit=40kernel=2Eorg=3E=2C?= =?unknown-8bit?q?_=22Marc-Andr=C3=A9_Lureau=22_=3Cmarcandre=2Elureau=40redha?= =?unknown-8bit?q?t=2Ecom=3E=2C?= =?unknown-8bit?q?_Paolo_Bonzini_=3Cpbonzini=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Gerd_Hoffmann_=3Ckraxel=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Jason_Wang_=3Cjasowang=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_Fam_Zheng_=3Cfam=40euphon=2Enet=3E=2C?= =?unknown-8bit?q?_=22Dr=2E_David_Alan_Gilbert=22_=3Cdgilbert=40redhat=2Ecom?= =?unknown-8bit?q?=3E=2C?= =?unknown-8bit?q?_David_Hildenbrand_=3Cdavid=40redhat=2Ecom=3E=2C?= =?unknown-8bit?b?ICJHb25nbGVpIChBcmVpKSIgPGFyZWkuZ29uZ2xlaUBodWF3ZWkuY29t?= =?unknown-8bit?b?Piw=?= =?unknown-8bit?q?_Eric_Auger_=3Ceric=2Eauger=40redhat=2Ecom=3E=2C?= =?unknown-8bit?q?_qemu-block=40nongnu=2Eorg=2C?= =?unknown-8bit?q?_virtio-fs=40redhat=2Ecom?= Received-SPF: none client-ip=91.194.90.13; envelope-from=ae0464f653ef20292e335ba3de0d62ab3ce8c72c@lizzy.crudebyte.com; helo=lizzy.crudebyte.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" 9pfs supports the new maximum virtio queue size of 32k, so let's switch the 9pfs virtio transport from 1k to 32k. This will allow a maximum 'msize' option (maximum message size) by 9p client of approximately 128M (assuming 4k page size, in practice slightly smaller, e.g. with Linux client minus 2 pages). Signed-off-by: Christian Schoenebeck --- hw/9pfs/virtio-9p-device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c index 9013e7df6e..cd5d95dd51 100644 --- a/hw/9pfs/virtio-9p-device.c +++ b/hw/9pfs/virtio-9p-device.c @@ -217,7 +217,7 @@ static void virtio_9p_device_realize(DeviceState *dev, Error **errp) v->config_size = sizeof(struct virtio_9p_config) + strlen(s->fsconf.tag); virtio_init(vdev, "virtio-9p", VIRTIO_ID_9P, v->config_size, - VIRTQUEUE_LEGACY_MAX_SIZE); + VIRTQUEUE_MAX_SIZE); v->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output); }