From nobody Sun Feb 8 12:31:54 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) client-ip=63.128.21.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1606999052; cv=none; d=zohomail.com; s=zohoarc; b=e1wPVH33RflZTbT9SmO/ht7GIab1A9hebDXnKWoPCPCBZk9GSIE+yDb43iME3rHPfDWmN9OzMn/RP8zrfFLThlQaEd8raVzFyycwjQ4HOnAPO91erm7vfxEkiEFivNxiqCuF3f5RljSmJgMDPKZpb1jACTgpJM4TpXaomQNRlOA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1606999052; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=DcbqRjieDaNnBo+8cXUdSASyiY59dyUrbGraM/lpqwc=; b=aa/6QU3gHmHiotm4hK1nw30cQD6s5AjP8Wk52fKNMGoqm2xuy2COCS9pIfFHGqIzPsVdoIfQq6p6fEKEEB5SBBaCFmPQ6tkcaBtZkeFKI9lyuwQhgKPlK9X9fpWeY4cTpQ+bwJTq1Jvccb3Suz1q/8MYJx1IKSnxCmNR2uHj7ks= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by mx.zohomail.com with SMTPS id 1606999052552780.4156293194721; Thu, 3 Dec 2020 04:37:32 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-136-4BvXi-bWPUqMexhTCKNyZQ-1; Thu, 03 Dec 2020 07:37:28 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 77111185E49F; Thu, 3 Dec 2020 12:37:23 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 54FF15D6BA; Thu, 3 Dec 2020 12:37:23 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 1F8EA5002F; Thu, 3 Dec 2020 12:37:23 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 0B3CbLhE003338 for ; Thu, 3 Dec 2020 07:37:21 -0500 Received: by smtp.corp.redhat.com (Postfix) id C4C9D5C1D0; Thu, 3 Dec 2020 12:37:21 +0000 (UTC) Received: from localhost.localdomain (unknown [10.40.192.239]) by smtp.corp.redhat.com (Postfix) with ESMTP id 456775C1C2 for ; Thu, 3 Dec 2020 12:37:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1606999051; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=DcbqRjieDaNnBo+8cXUdSASyiY59dyUrbGraM/lpqwc=; b=N96xbZLIBtWqmLObQ0YamarIzkh7GZmWUOq3xVgidWvI3Z8TffJJXnG4c8ijMjRGIcDyEC ppOuMbIOepglQhAwJPBW0MQJYyf+uo8LnV8id06ylo5ts2/oLcOhYQ6Zujz0eInOcFwXCc N7s1b8n+63Y+1WHFNDSK+98B+yi/ZaA= X-MC-Unique: 4BvXi-bWPUqMexhTCKNyZQ-1 From: Michal Privoznik To: libvir-list@redhat.com Subject: [PATCH v2 20/27] conf: Introduce virtio-mem model Date: Thu, 3 Dec 2020 13:36:23 +0100 Message-Id: <468ab48a9fb8d17aa4dfbfc68f7ac732981787f0.1606998426.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" QEMU gained this new virtio-mem model. It's similar to pc-dimm in a sense that guest uses it as memory, but in a sense very different from it as it can dynamically change allocation, without need for hotplug. More specifically, the device has two attributes more (it has more of course, but these two are important here): 1) block-size - the granularity of the device. You can imagine the device being divided into blocks, each 'block-size' long. 2) requested-size - the portion of the device that is in use by the guest. And it all works like this: at guest startup/hotplug both block-size and requested-size are specified. When sysadmin wants to give some more memory to the guest, or take some back, they change the 'requested-size' attribute which is propagated to the guest where virtio-mem module takes corresponding action. This means, that 'requested-size' must be a whole number product of 'block-size' and of course has to be in rage [0, max-size] (including). The 'max-size' is yet another attribute but if not set it's "inherited" from corresponding memory-backend-* object. Therefore, two new elements are introduced under , to reflect these attributes: 4194304 0 2048 524288
The intent here is that will be allowed to change via virDomainUpdateDeviceFlags() API. Note, QEMU does inform us about success of allocation via an event - this is covered in next patches. Signed-off-by: Michal Privoznik --- docs/formatdomain.rst | 22 ++++ docs/schemas/domaincommon.rng | 10 ++ src/conf/domain_conf.c | 103 ++++++++++++++++-- src/conf/domain_conf.h | 5 + .../memory-hotplug-virtio-mem.xml | 78 +++++++++++++ ...emory-hotplug-virtio-mem.x86_64-latest.xml | 1 + tests/qemuxml2xmltest.c | 1 + 7 files changed, 213 insertions(+), 7 deletions(-) create mode 100644 tests/qemuxml2argvdata/memory-hotplug-virtio-mem.xml create mode 120000 tests/qemuxml2xmloutdata/memory-hotplug-virtio-mem.x86_= 64-latest.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index ca6bc0432e..3990728939 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -7187,6 +7187,17 @@ Example: usage of the memory devices + + + /tmp/virtio_mem + + + 1048576 + 0 + 2048 + 524288 + + /tmp/virtio_pmem @@ -7300,6 +7311,17 @@ Example: usage of the memory devices so other backend types should use the ``readonly`` element. :since:`= Since 5.0.0` =20 + ``block`` + The size of an individual block, granularity of division of memory mo= dule. + Must be power of two and at least equal to size of a transparent huge= page + (2MiB on x84_64). The default is hypervisor dependant. This is valid = for + ``virtio`` model only and mutually exclusive with ``pmem``. + + ``requested`` + The total size of blocks exposed to the guest. Must respect ``block`` + granularity. This is valid for ``virtio`` model only and mutually + exclusive with ``pmem``. + :anchor:`` =20 IOMMU devices diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index b385bae84c..d478b639fa 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -6053,6 +6053,16 @@ + + + + + + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 935bea1804..0551f6f266 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6764,10 +6764,23 @@ virDomainMemoryDefValidate(const virDomainMemoryDef= *mem, return -1; } } else { - /* TODO: plain virtio-mem behaves differently then virtio-pmem= */ - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("virtio-mem is not supported yet. is = required")); - return -1; + if (mem->requestedsize > mem->size) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("requested size must be smaller than @siz= e")); + return -1; + } + + if (!VIR_IS_POW2(mem->blocksize)) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("block size must be a power of two")); + return -1; + } + + if (mem->requestedsize % mem->blocksize !=3D 0) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("requested size must be an integer multip= le of block size")); + return -1; + } } break; =20 @@ -16774,9 +16787,25 @@ virDomainMemorySourceDefParseXML(xmlNodePtr node, case VIR_DOMAIN_MEMORY_MODEL_VIRTIO: def->s.virtio.path =3D virXPathString("string(./path)", ctxt); =20 - if (virXPathBoolean("boolean(./pmem)", ctxt)) + if (virXPathBoolean("boolean(./pmem)", ctxt)) { def->s.virtio.pmem =3D true; + } else { + if (virDomainParseMemory("./pagesize", "./pagesize/@unit", ctx= t, + &def->s.virtio.pagesize, false, false= ) < 0) + return -1; =20 + if ((nodemask =3D virXPathString("string(./nodemask)", ctxt)))= { + if (virBitmapParse(nodemask, &def->s.virtio.sourceNodes, + VIR_DOMAIN_CPUMASK_LEN) < 0) + return -1; + + if (virBitmapIsAllClear(def->s.virtio.sourceNodes)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Invalid value of 'nodemask': %s"), n= odemask); + return -1; + } + } + } break; =20 case VIR_DOMAIN_MEMORY_MODEL_NONE: @@ -16812,7 +16841,8 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node, &def->size, true, false) < 0) return -1; =20 - if (def->model =3D=3D VIR_DOMAIN_MEMORY_MODEL_NVDIMM) { + switch (def->model) { + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: if (virDomainParseMemory("./label/size", "./label/size/@unit", ctx= t, &def->labelsize, false, false) < 0) return -1; @@ -16831,6 +16861,27 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node, =20 if (virXPathBoolean("boolean(./readonly)", ctxt)) def->readonly =3D true; + + break; + + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO: + if (!def->s.virtio.pmem) { + if (virDomainParseMemory("./block", "./block/@unit", ctxt, + &def->blocksize, false, false) < 0) + return -1; + + if (virDomainParseMemory("./requested", "./requested/@unit", c= txt, + &def->requestedsize, false, false) < = 0) + return -1; + } + + break; + + case VIR_DOMAIN_MEMORY_MODEL_NONE: + case VIR_DOMAIN_MEMORY_MODEL_DIMM: + case VIR_DOMAIN_MEMORY_MODEL_LAST: + /* nada */ + break; } =20 return 0; @@ -18649,7 +18700,9 @@ virDomainMemoryFindByDefInternal(virDomainDefPtr de= f, /* target info -> always present */ if (tmp->model !=3D mem->model || tmp->targetNode !=3D mem->targetNode || - tmp->size !=3D mem->size) + tmp->size !=3D mem->size || + tmp->blocksize !=3D mem->blocksize || + tmp->requestedsize !=3D mem->requestedsize) continue; =20 switch (mem->model) { @@ -24255,6 +24308,22 @@ virDomainMemoryDefCheckABIStability(virDomainMemor= yDefPtr src, return false; } =20 + if (src->blocksize !=3D dst->blocksize) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target memory device block size '%llu' doesn't m= atch " + "source memory device block size '%llu'"), + dst->blocksize, src->blocksize); + return false; + } + + if (src->requestedsize !=3D dst->requestedsize) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target memory device requested size '%llu' doesn= 't match " + "source memory device requested size '%llu'"), + dst->requestedsize, src->requestedsize); + return false; + } + switch (src->model) { case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: if (src->labelsize !=3D dst->labelsize) { @@ -27967,6 +28036,18 @@ virDomainMemorySourceDefFormat(virBufferPtr buf, =20 if (def->s.virtio.pmem) virBufferAddLit(&childBuf, "\n"); + + if (def->s.virtio.sourceNodes) { + if (!(bitmap =3D virBitmapFormat(def->s.virtio.sourceNodes))) + return -1; + + virBufferAsprintf(&childBuf, "%s\n", bitm= ap); + } + + if (def->s.virtio.pagesize) { + virBufferAsprintf(&childBuf, "%llu\n", + def->s.virtio.pagesize); + } break; =20 case VIR_DOMAIN_MEMORY_MODEL_NONE: @@ -27998,6 +28079,14 @@ virDomainMemoryTargetDefFormat(virBufferPtr buf, if (def->readonly) virBufferAddLit(&childBuf, "\n"); =20 + if (def->blocksize) { + virBufferAsprintf(&childBuf, "%llu\n", + def->blocksize); + + virBufferAsprintf(&childBuf, "%llu\n", + def->requestedsize); + } + virXMLFormatElement(buf, "target", NULL, &childBuf); } =20 diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index efaa4c5473..f16dc0a029 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2327,8 +2327,11 @@ struct _virDomainMemoryDef { bool pmem; } nvdimm; /* VIR_DOMAIN_MEMORY_MODEL_NVDIMM */ struct { + // nodemask + hugepages + no prealloc char *path; /* Required for pmem, otherwise optional */ bool pmem; + virBitmapPtr sourceNodes; + unsigned long long pagesize; /* kibibytes */ } virtio; /* VIR_DOMAIN_MEMORY_MODEL_VIRTIO */ } s; =20 @@ -2337,6 +2340,8 @@ struct _virDomainMemoryDef { int targetNode; unsigned long long size; /* kibibytes */ unsigned long long labelsize; /* kibibytes; valid only for NVDIMM */ + unsigned long long blocksize; /* kibibytes, valid for virtio-mem only = */ + unsigned long long requestedsize; /* kibibytes, valid for virtio-mem o= nly */ bool readonly; /* valid only for NVDIMM */ =20 /* required for QEMU NVDIMM ppc64 support */ diff --git a/tests/qemuxml2argvdata/memory-hotplug-virtio-mem.xml b/tests/q= emuxml2argvdata/memory-hotplug-virtio-mem.xml new file mode 100644 index 0000000000..0c8d1d970e --- /dev/null +++ b/tests/qemuxml2argvdata/memory-hotplug-virtio-mem.xml @@ -0,0 +1,78 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 1099511627776 + 8388608 + 8388608 + 2 + + hvm + + + + qemu64 + + + + + + + destroy + restart + destroy + + /usr/bin/qemu-system-i386 + + + + +
+ + +
+ + +
+ + + + + +
+ + + + 1048576 + 0 + 2048 + 524288 + +
+ + + + 1-3 + 2048 + + + 2097152 + 0 + 2048 + 1048576 + +
+ + + + /tmp/virtio_mem + + + 4194304 + 0 + 2048 + 524288 + +
+ + + diff --git a/tests/qemuxml2xmloutdata/memory-hotplug-virtio-mem.x86_64-late= st.xml b/tests/qemuxml2xmloutdata/memory-hotplug-virtio-mem.x86_64-latest.x= ml new file mode 120000 index 0000000000..a9d298129c --- /dev/null +++ b/tests/qemuxml2xmloutdata/memory-hotplug-virtio-mem.x86_64-latest.xml @@ -0,0 +1 @@ +../qemuxml2argvdata/memory-hotplug-virtio-mem.xml \ No newline at end of file diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index e804db8aee..00d8f171bc 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1239,6 +1239,7 @@ mymain(void) DO_TEST("memory-hotplug-nvdimm-ppc64", QEMU_CAPS_DEVICE_SPAPR_PCI_HOST= _BRIDGE, QEMU_CAPS_DEVICE_NVDIMM); DO_TEST_CAPS_LATEST("memory-hotplug-virtio-pmem"); + DO_TEST_CAPS_LATEST("memory-hotplug-virtio-mem"); =20 DO_TEST("net-udp", NONE); =20 --=20 2.26.2