為來賓啟用大頁面時出現 libvirt 錯誤
virt-manager
我正在嘗試通過(和命令行)使用 libvirt 和 KVM 設置一個支持大頁面的 VM,virsh
並且在啟用域 XML 中的選項時出現錯誤。不知道問題出在哪裡。我正在使用升級到 14.10 的 Ubuntu 14.04 和以下軟體包版本:
- libvirt-bin 1.2.8-0ubuntu11
- qemu-kvm 2.1+dfsg-4ubuntu6
細節
我已經按照本指南配置了大頁面。以下是有關目前配置的一些資訊:
$ hugeadm --explain Total System Memory: 15808 MB Mount Point Options /dev/hugepages rw,relatime,mode=1770,gid=126 Huge page pools: Size Minimum Current Maximum Default 2097152 2176 2176 2176 * Huge page sizes with configured pools: 2097152 $ getent group kvm kvm:x:126:chaicko $ cat /proc/meminfo | grep Huge AnonHugePages: 591872 kB HugePages_Total: 2176 HugePages_Free: 2176 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB
這是域 XML:
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'> <name>win8</name> <uuid>b85bbb9a-745f-4293-a990-1e1726240ef0</uuid> <memory unit='KiB'>4194304</memory> <currentMemory unit='KiB'>4194304</currentMemory> <memoryBacking> <hugepages/> </memoryBacking> <vcpu placement='static'>4</vcpu> <os> <type arch='x86_64' machine='pc-i440fx-utopic'>hvm</type> </os> <features> <acpi/> <apic/> <pae/> </features> <cpu mode='custom' match='exact'> <model fallback='allow'>Haswell</model> </cpu> <clock offset='localtime'> <timer name='rtc' tickpolicy='catchup'/> <timer name='pit' tickpolicy='delay'/> <timer name='hpet' present='no'/> </clock> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>restart</on_crash> <pm> <suspend-to-mem enabled='no'/> <suspend-to-disk enabled='no'/> </pm> <devices> <emulator>/usr/bin/qemu-system-x86_64</emulator> <disk type='block' device='disk'> <driver name='qemu' type='raw' cache='none' io='native'/> <source dev='/dev/vmvg/win8'/> <target dev='vda' bus='virtio'/> <boot order='2'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> </disk> <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/home/chaicko/Downloads/virtio-win-0.1-81.iso'/> <target dev='hda' bus='ide'/> <readonly/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/home/chaicko/Downloads/WINDOWS_8.1_Pro_X64/Windows_8.1_Pro_X64.iso'/> <target dev='hdb' bus='ide'/> <readonly/> <boot order='1'/> <address type='drive' controller='0' bus='0' target='0' unit='1'/> </disk> <controller type='usb' index='0' model='ich9-ehci1'> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x7'/> </controller> <controller type='usb' index='0' model='ich9-uhci1'> <master startport='0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0' multifunction='on'/> </controller> <controller type='usb' index='0' model='ich9-uhci2'> <master startport='2'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x1'/> </controller> <controller type='usb' index='0' model='ich9-uhci3'> <master startport='4'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x2'/> </controller> <controller type='pci' index='0' model='pci-root'/> <controller type='ide' index='0'> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> </controller> <controller type='virtio-serial' index='0'> <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> </controller> <controller type='scsi' index='0'> <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/> </controller> <interface type='network'> <mac address='52:54:00:48:ca:09'/> <source network='default'/> <model type='virtio'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> <serial type='pty'> <target port='0'/> </serial> <console type='pty'> <target type='serial' port='0'/> </console> <channel type='spicevmc'> <target type='virtio' name='com.redhat.spice.0'/> <address type='virtio-serial' controller='0' bus='0' port='1'/> </channel> <input type='tablet' bus='usb'/> <input type='mouse' bus='ps2'/> <input type='keyboard' bus='ps2'/> <graphics type='spice' autoport='yes'/> <sound model='ich6'> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> </sound> <video> <model type='qxl' ram='65536' vram='65536' heads='1'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> </video> <hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/> </hostdev> <hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x01' slot='0x00' function='0x1'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/> </hostdev> <redirdev bus='usb' type='spicevmc'> </redirdev> <redirdev bus='usb' type='spicevmc'> </redirdev> <redirdev bus='usb' type='spicevmc'> </redirdev> <redirdev bus='usb' type='spicevmc'> </redirdev> <memballoon model='virtio'> <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/> </memballoon> </devices> <qemu:commandline> <qemu:arg value='-drive'/> <qemu:arg value='if=pflash,readonly,format=raw,file=/usr/share/qemu/OVMF.fd'/> </qemu:commandline> </domain>
問題
如果我刪除該
<memoryBacking>
選項,那麼它可以工作,但如果沒有,它會失敗並出現以下錯誤:error: internal error: process exited while connecting to monitor:
我還取消了以下行的註釋
/etc/libvirt/qemu.conf
:hugetlbfs_mount = "/dev/hugepages"
通過 shell 執行 qemu 來指示使用大頁面確實有效(
-mem-path /dev/hugepages
)。我究竟做錯了什麼?任何幫助表示讚賞。
回答我自己的問題,為了
libvirt
在Ubuntu中使用大頁面,您只需KVM_HUGEPAGES=1
在文件中設置/etc/default/qemu-kvm
並重新啟動。這與此錯誤修復有關。
根據 libvirt 文件,本節標題為:記憶體支持。
可選的 memoryBacking 元素可能包含幾個影響虛擬記憶體頁面如何被主機頁面支持的元素。
大頁面 這告訴虛擬機管理程序應該使用大頁面而不是正常的本機頁面大小來分配來賓的記憶體。從 1.2.5 開始,可以為每個 numa 節點更具體地設置大頁面。頁面元素被引入。它有一個強制屬性 size,它指定應該使用哪些大頁面(在支持不同大小的大頁面的系統上特別有用)。size 屬性的預設單位是千字節(1024 的乘數)。如果要使用不同的單位,請使用可選的單位屬性。對於具有 NUMA 的系統,可選的 nodeset 屬性可能會派上用場,因為它將給定來賓的 NUMA 節點與某些巨頁大小相關聯。在範常式式碼段中,除了節點 4 之外,每個 NUMA 節點都使用 1 GB 的大頁面。有關正確的語法,請參閱此.
nosharepages 指示管理程序禁用此域的共享頁面(記憶體合併,KSM)。從 1.0.6 開始
鎖定 當管理程序設置和支持時,屬於域的記憶體頁面將被鎖定在主機的記憶體中,並且不允許主機將它們換出。對於 QEMU/KVM,這需要使用 hard_limit記憶體調整元素並將其設置為為域配置的最大記憶體加上 QEMU 程序本身消耗的任何記憶體。從 1.0.6 開始
例子
<domain> ... <memoryBacking> <hugepages> <page size="1" unit="G" nodeset="0-3,5"/> <page size="2" unit="M" nodeset="4"/> </hugepages> <nosharepages/> <locked/> </memoryBacking> ... </domain>
既然你沒有說,我假設你想將所有記憶體分配給這個特定的客人。如果是這樣,您可能會嘗試完全省略此部分。
替代方向
我在這篇標題為:如何設置 KVM 來賓以使用 HugePages?顯示如何設置如下:
摘抄
在主機上掛載 HugeTLB 文件系統
您可以使用任何所需的掛載點,我們在這裡創建了 /hugepages
mkdir -p /hugepages mount -t hugetlbfs hugetlbfs /hugepages
這也可以通過 中的條目來實現
/etc/fstab
,例如hugetlbfs /hugepages hugetlbfs defaults 0 0
增加主機上的記憶體鎖定限制
/etc/security/limits.conf
根據您所需的記憶體使用情況更改以下值# Lock max 8Gb soft memlock 8388608 hard memlock 8388608
保留 HugePages 並讓 KVM 組訪問它們
/etc/sysctl.conf
根據您所需的記憶體使用情況更改以下行vm.nr_hugepages = 4096 vm.hugetlb_shm_group = 36
將 HugePage 支持添加到 KVM 來賓定義
將以下內容添加到現有 KVM 來賓的來賓配置中。這可以通過
virsh edit <guestname>
或virsh define <guest.xml>
<memoryBacking> <hugepages/> </memoryBacking>
重啟主機
這是將連續記憶體重新分配給 HugePages 所必需的
開始客人
確認來賓有 HugePage 支持檢查
qemu-kvm
與該來賓關聯的程序是否存在 -mem-path
在執行命令中ps -ef | grep qemu root 4182 1 1 17:35 ? 00:00:42 /usr/libexec/qemu-kvm -S -M rhel5.4.0 -m 1024 -mem-prealloc -mem-path /hugepages/libvirt/qemu -smp 1 -name vm1 -uuid 3f1f3a98-89f8-19ac-b5b5-bf496e2ed9be -no-kvm-pit-reinjection -monitor pty -pidfile /var/run/libvirt/qemu//vm1.pid -boot c -drive file=/vmimages/vm1,if=ide,index=0,boot=on,cache=none -drive file=,if=ide,media=cdrom,index=2 -net nic,macaddr=54:52:00:00:00:01,vlan=0 -net tap,fd=15,script=,vlan=0,ifname=vnet0 -serial pty -parallel none -usb -vnc 127.0.0.1:0 -k en-us
確認在系統上使用 HugePage
在這裡我們可以看到 HugePages 在啟動時被分配,以及為客人使用/保留
cat /proc/meminfo | grep Huge HugePages_Total: 4096 HugePages_Free: 873 HugePages_Rsvd: 761 Hugepagesize: 2048 kB
根本原因
為 KVM 來賓分配記憶體的預設方法是使用正常 4k 頁面。這可能導致
- 佔用不必要和低效記憶體的大型頁表
- 增加的記憶體碎片可能會減慢一些需要連續記憶體的基於核心的操作(例如:磁碟寫入、網路訪問)
- 增加頁面錯誤,這可能會減慢所有應用程序的速度
- 冒著將虛擬來賓的組件交換到磁碟的風險,這會導致很大的性能損失
使用 HugePages,頁表大小顯著減少,記憶體的連續區域被映射,並且 HugePages 不能被設計交換。
**注意:**對於 RHEL6 上的 KVM,這些步驟不是必需的,它使用透明 HugePages 動態映射連續的 2Mb 記憶體區域,但也允許將記憶體分解為 4k 頁面以與 KSM 合併或在系統處於記憶體壓力時交換.
如果需要 HugePages 而不是透明 HugePages,則上述步驟可以應用於 RHEL6。