qemu: Introduce label-size for NVDIMMs

For NVDIMM devices it is optionally possible to specify the size
of internal storage for namespaces. Namespaces are a feature that
allows users to partition the NVDIMM for different uses.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Michal Privoznik 2017-02-27 11:20:26 +01:00
parent 04dc668a31
commit e433546bef
10 changed files with 151 additions and 0 deletions

View File

@ -7123,6 +7123,9 @@ qemu-kvm -net nic,model=? /dev/null
&lt;target&gt; &lt;target&gt;
&lt;size unit='KiB'&gt;524288&lt;/size&gt; &lt;size unit='KiB'&gt;524288&lt;/size&gt;
&lt;node&gt;1&lt;/node&gt; &lt;node&gt;1&lt;/node&gt;
&lt;label&gt;
&lt;size unit='KiB'&gt;128&lt;/size&gt;
&lt;/label&gt;
&lt;/target&gt; &lt;/target&gt;
&lt;/memory&gt; &lt;/memory&gt;
&lt;/devices&gt; &lt;/devices&gt;
@ -7204,6 +7207,20 @@ qemu-kvm -net nic,model=? /dev/null
attach the memory to. The element shall be used only if the guest has attach the memory to. The element shall be used only if the guest has
NUMA nodes configured. NUMA nodes configured.
</p> </p>
<p>
For NVDIMM type devices one can optionally use
<code>label</code> and its subelement <code>size</code>
to configure the size of namespaces label storage
within the NVDIMM module. The <code>size</code> element
has usual meaning described
<a href="#elementsMemoryAllocation">here</a>.
For QEMU domains the following restrictions apply:
</p>
<ol>
<li>the minimum label size is 128KiB,</li>
<li>the remaining size (total-size - label-size) has to be aligned to
4KiB</li>
</ol>
</dd> </dd>
</dl> </dl>

View File

@ -4810,6 +4810,13 @@
<ref name="unsignedInt"/> <ref name="unsignedInt"/>
</element> </element>
</optional> </optional>
<optional>
<element name="label">
<element name="size">
<ref name="scaledInteger"/>
</element>
</element>
</optional>
</interleave> </interleave>
</element> </element>
</define> </define>

View File

@ -13785,6 +13785,24 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node,
&def->size, true, false) < 0) &def->size, true, false) < 0)
goto cleanup; goto cleanup;
if (def->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM) {
if (virDomainParseMemory("./label/size", "./label/size/@unit", ctxt,
&def->labelsize, false, false) < 0)
goto cleanup;
if (def->labelsize && def->labelsize < 128) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("nvdimm label must be at least 128KiB"));
goto cleanup;
}
if (def->labelsize >= def->size) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("label size must be smaller than NVDIMM size"));
goto cleanup;
}
}
ret = 0; ret = 0;
cleanup: cleanup:
@ -19468,6 +19486,15 @@ virDomainMemoryDefCheckABIStability(virDomainMemoryDefPtr src,
return false; return false;
} }
if (src->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM &&
src->labelsize != dst->labelsize) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target NVDIMM label size '%llu' doesn't match "
"source NVDIMM label size '%llu'"),
src->labelsize, dst->labelsize);
return false;
}
return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info); return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info);
} }
@ -22624,6 +22651,13 @@ virDomainMemoryTargetDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, "<size unit='KiB'>%llu</size>\n", def->size); virBufferAsprintf(buf, "<size unit='KiB'>%llu</size>\n", def->size);
if (def->targetNode >= 0) if (def->targetNode >= 0)
virBufferAsprintf(buf, "<node>%d</node>\n", def->targetNode); virBufferAsprintf(buf, "<node>%d</node>\n", def->targetNode);
if (def->labelsize) {
virBufferAddLit(buf, "<label>\n");
virBufferAdjustIndent(buf, 2);
virBufferAsprintf(buf, "<size unit='KiB'>%llu</size>\n", def->labelsize);
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</label>\n");
}
virBufferAdjustIndent(buf, -2); virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</target>\n"); virBufferAddLit(buf, "</target>\n");

View File

@ -2014,6 +2014,7 @@ struct _virDomainMemoryDef {
int model; /* virDomainMemoryModel */ int model; /* virDomainMemoryModel */
int targetNode; int targetNode;
unsigned long long size; /* kibibytes */ unsigned long long size; /* kibibytes */
unsigned long long labelsize; /* kibibytes; valid only for NVDIMM */
virDomainDeviceInfo info; virDomainDeviceInfo info;
}; };

View File

@ -3519,6 +3519,9 @@ qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem)
if (mem->targetNode >= 0) if (mem->targetNode >= 0)
virBufferAsprintf(&buf, "node=%d,", mem->targetNode); virBufferAsprintf(&buf, "node=%d,", mem->targetNode);
if (mem->labelsize)
virBufferAsprintf(&buf, "label-size=%llu,", mem->labelsize * 1024);
virBufferAsprintf(&buf, "memdev=mem%s,id=%s", virBufferAsprintf(&buf, "memdev=mem%s,id=%s",
mem->info.alias, mem->info.alias); mem->info.alias, mem->info.alias);

View File

@ -0,0 +1,26 @@
LC_ALL=C \
PATH=/bin \
HOME=/home/test \
USER=test \
LOGNAME=test \
QEMU_AUDIO_DRV=none \
/usr/bin/qemu \
-name QEMUGuest1 \
-S \
-machine pc,accel=tcg,nvdimm=on \
-m size=219136k,slots=16,maxmem=1099511627776k \
-smp 2,sockets=2,cores=1,threads=1 \
-numa node,nodeid=0,cpus=0-1,mem=214 \
-object memory-backend-file,id=memnvdimm0,prealloc=yes,mem-path=/tmp/nvdimm,\
share=no,size=536870912 \
-device nvdimm,node=0,label-size=131072,memdev=memnvdimm0,id=nvdimm0,slot=0 \
-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
-nographic \
-nodefaults \
-monitor unix:/tmp/lib/domain--1-QEMUGuest1/monitor.sock,server,nowait \
-no-acpi \
-boot c \
-usb \
-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3

View File

@ -0,0 +1,59 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<maxMemory slots='16' unit='KiB'>1099511627776</maxMemory>
<memory unit='KiB'>1267710</memory>
<currentMemory unit='KiB'>1267710</currentMemory>
<vcpu placement='static' cpuset='0-1'>2</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<idmap>
<uid start='0' target='1000' count='10'/>
<gid start='0' target='1000' count='10'/>
</idmap>
<cpu>
<topology sockets='2' cores='1' threads='1'/>
<numa>
<cell id='0' cpus='0-1' memory='219136' unit='KiB'/>
</numa>
</cpu>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>
<controller type='ide' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
</controller>
<controller type='usb' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</memballoon>
<memory model='nvdimm' access='private'>
<source>
<path>/tmp/nvdimm</path>
</source>
<target>
<size unit='KiB'>523264</size>
<node>0</node>
<label>
<size unit='KiB'>128</size>
</label>
</target>
<address type='dimm' slot='0'/>
</memory>
</devices>
</domain>

View File

@ -2338,6 +2338,8 @@ mymain(void)
QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_OBJECT_MEMORY_FILE); QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST("memory-hotplug-nvdimm-access", QEMU_CAPS_MACHINE_OPT, QEMU_CAPS_DEVICE_NVDIMM, DO_TEST("memory-hotplug-nvdimm-access", QEMU_CAPS_MACHINE_OPT, QEMU_CAPS_DEVICE_NVDIMM,
QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_OBJECT_MEMORY_FILE); QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST("memory-hotplug-nvdimm-label", QEMU_CAPS_MACHINE_OPT, QEMU_CAPS_DEVICE_NVDIMM,
QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST("machine-aeskeywrap-on-caps", DO_TEST("machine-aeskeywrap-on-caps",
QEMU_CAPS_MACHINE_OPT, QEMU_CAPS_AES_KEY_WRAP, QEMU_CAPS_MACHINE_OPT, QEMU_CAPS_AES_KEY_WRAP,

View File

@ -0,0 +1 @@
../qemuxml2argvdata/qemuxml2argv-memory-hotplug-nvdimm-label.xml

View File

@ -1080,6 +1080,7 @@ mymain(void)
DO_TEST("memory-hotplug-dimm", NONE); DO_TEST("memory-hotplug-dimm", NONE);
DO_TEST("memory-hotplug-nvdimm", NONE); DO_TEST("memory-hotplug-nvdimm", NONE);
DO_TEST("memory-hotplug-nvdimm-access", NONE); DO_TEST("memory-hotplug-nvdimm-access", NONE);
DO_TEST("memory-hotplug-nvdimm-label", NONE);
DO_TEST("net-udp", NONE); DO_TEST("net-udp", NONE);
DO_TEST("video-virtio-gpu-device", NONE); DO_TEST("video-virtio-gpu-device", NONE);