virt-manager
명령줄을 통해 libvirt 및 KVM을 사용하여 대용량 페이지 지원이 포함된 VM을 설정하려고 하는데 virsh
도메인 XML에서 옵션을 활성화하면 오류가 발생합니다. 문제가 어디에 있는지 모릅니다.
다음 패키지 버전과 함께 14.10으로 업그레이드된 Ubuntu 14.04를 사용하고 있습니다.
- libvirt-빈 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"
쉘을 통해 qemu를 실행하면 huge Pages 사용이 작동함을 나타냅니다( -mem-path /dev/hugepages
).
내가 뭘 잘못했나요? 도움을 주시면 감사하겠습니다.
답변1
libvirt 문서에 따르면 이 섹션의 제목은 다음과 같습니다.메모리 지원.
선택적 memoryBacking 요소에는 호스트 페이지가 가상 메모리 페이지를 백업하는 방법에 영향을 미치는 여러 요소가 포함될 수 있습니다.
큰 페이지이는 일반적인 기본 페이지 크기 대신 대용량 페이지를 사용하여 게스트 메모리를 할당해야 함을 하이퍼바이저에 알려줍니다. 1.2.5부터 hugepages는 각 Numa 노드에 대해 보다 구체적으로 설정할 수 있습니다. 페이지 요소를 소개합니다. 여기에는 어떤 hugepage를 사용해야 하는지 지정하는 필수 속성 크기가 있습니다(특히 다양한 크기의 hugepage를 지원하는 시스템에 유용함). 크기 속성의 기본 단위는 킬로바이트(1024의 배수)입니다. 다른 단위를 사용하려면 선택적 단위 속성을 사용하세요. NUMA가 있는 시스템의 경우 선택적 노드 세트 속성은 지정된 게스트의 NUMA 노드를 특정 대형 페이지 크기와 연결하므로 편리할 수 있습니다. 샘플 코드 조각에서 노드 4를 제외한 각 NUMA 노드는 1GB의 hugepage를 사용합니다. 올바른 구문은 다음을 참조하세요.이것.
공유 페이지 없음이 도메인에 대한 공유 페이지(메모리 병합, 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>
당신이 그렇게 말하지 않았기 때문에 나는 당신이 이 특정 게스트에게 모든 메모리를 할당하기를 원한다고 가정합니다. 그렇다면 이 섹션을 완전히 생략해 보세요.
대체 방향
이 기사에서 다음 제목의 RHEL 5 및 6 단계를 찾았습니다.HugePages를 사용하도록 KVM 게스트를 어떻게 설정합니까?다음과 같이 설정하는 방법을 보여줍니다.
발췌호스트에 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
KVM 게스트 정의에 HugePage 지원 추가
기존 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는 설계상 스왑이 불가능합니다.
노트:이러한 단계는 투명한 HugePages를 사용하여 연속 2Mb 메모리 영역을 동적으로 매핑할 뿐만 아니라 시스템에 메모리 부족이 있을 때 KSM과 병합하거나 스와핑하기 위해 메모리를 4k 페이지로 나눌 수 있는 RHEL6의 KVM에는 필요하지 않습니다.
투명한 HugePages 대신 HugePages가 필요한 경우 위 단계를 RHEL6에 적용할 수 있습니다.
답변2
libvirt
대용량 페이지 사용 에 대한 내 질문에 답하기우분투KVM_HUGEPAGES=1
, 파일에 설정 /etc/default/qemu-kvm
하고 다시 시작하면 됩니다.
이것과 관련이 있습니다버그 수정.
답변3
qemu-system-x86_64: 게스트 RAM의 백업 저장소를 매핑할 수 없습니다. 메모리를 할당할 수 없습니다.
게스트 메모리가 대용량 페이지에 할당된 양을 초과하지 않는지 확인하십시오.