Bug 1455819

Summary: Guest failed to start if memory device is backed by hugepages and no memoryBacking is set
Product: Red Hat Enterprise Linux 7 Reporter: Fangge Jin <fjin>
Component: libvirtAssignee: Michal Privoznik <mprivozn>
Status: CLOSED ERRATA QA Contact: yalzhang <yalzhang>
Severity: medium Docs Contact:
Priority: medium    
Version: 7.4CC: dyuan, jsuchane, lhuang, rbalakri, xuzhang, yalzhang
Target Milestone: rcKeywords: Regression, Upstream
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: libvirt-3.7.0-1.el7 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2018-04-10 10:44:33 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1456511, 1469590, 1473046    
Attachments:
Description Flags
libvirtd debug log none

Description Fangge Jin 2017-05-26 08:23:30 UTC
Created attachment 1282503 [details]
libvirtd debug log

Description of problem:
Guest failed to start if memory device is backed by hugepages and no memoryBacking is set

Version-Release number of selected component:
libvirt-3.2.0-6.virtcov.el7.x86_64

How reproducible:
100%

Steps to Reproduce:
0. Install libvirt freshly and start libvirtd service

1.Set hugepages on host:
# sysctl vm.nr_hugepages
vm.nr_hugepages = 600

2.Check hugepages directory permission, it's "root:root":
# ll /dev/hugepages/libvirt/qemu/ -Zd
drwxr-xr-x. root root system_u:object_r:hugetlbfs_t:s0 /dev/hugepages/libvirt/qemu/

3.Prepare a guest with memory device backed by hugepages and without memoryBacking element:
# virsh dumpxml vm2
...
  <maxMemory slots='16' unit='KiB'>2124800</maxMemory>
  <cpu mode='custom' match='exact' check='full'>
    <model fallback='forbid'>Penryn</model>
    <numa>
      <cell id='0' cpus='0-7' memory='512000' unit='KiB'/>
      <cell id='1' cpus='8-15' memory='512000' unit='KiB'/>
    </numa>
...
  <devices>
    <memory model='dimm'>
      <source>
        <nodemask>0</nodemask>
        <pagesize unit='KiB'>2048</pagesize>
      </source>
      <target>
        <size unit='KiB'>131072</size>
        <node>1</node>
      </target>
      <address type='dimm' slot='1'/>
    </memory>
...

4. Start guest:
# virsh start vm2
error: Failed to start domain vm2
error: internal error: qemu unexpectedly closed the monitor: 2017-05-26T07:41:47.267771Z qemu-kvm: -chardev pty,id=charserial0: char device redirected to /dev/pts/2 (label charserial0)
2017-05-26T07:41:47.279254Z qemu-kvm: -object memory-backend-file,id=memdimm1,prealloc=yes,mem-path=/dev/hugepages/libvirt/qemu/6-vm2,size=134217728,host-nodes=0,policy=bind: can't open backing store /dev/hugepages/libvirt/qemu/6-vm2 for guest RAM: Permission denied

5. Set memoryBacking to hugepages in guest xml:
# virsh edit vm2
  <memoryBacking>
    <hugepages/>
  </memoryBacking>

6.Start guest again, succeed:
# virsh start vm2
Domain vm2 started

7.
# ll /dev/hugepages/libvirt/qemu/ -Z
drwx------. qemu qemu system_u:object_r:svirt_image_t:s0:c165,c237 7-vm2


Actual results:
In step4, guest failed to start if memory device is backed by hugepages and no memoryBacking is set

Expected results:
Guest start successfully

Additional info:
This works well on RHEL7.3

Comment 2 Michal Privoznik 2017-06-07 15:51:03 UTC
Patches proposed upstream:

https://www.redhat.com/archives/libvir-list/2017-June/msg00395.html

Comment 3 Michal Privoznik 2017-06-13 14:45:27 UTC
I've just pushed the patches upstream:

commit 5b24d250629ab4ead365878933156586983770e3
Author:     Michal Privoznik <mprivozn>
AuthorDate: Wed Jun 7 14:47:37 2017 +0200
Commit:     Michal Privoznik <mprivozn>
CommitDate: Tue Jun 13 16:39:39 2017 +0200

    qemuDomainAttachMemory: Crate hugepage dir if needed
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1455819
    
    It may happen that a domain is started without any huge pages.
    However, user might try to attach a DIMM module later. DIMM
    backed by huge pages (why would somebody want to mix regular and
    huge pages is beyond me). Therefore we have to create the dir if
    we haven't done so far.
    
    Signed-off-by: Michal Privoznik <mprivozn>
    Reviewed-by: John Ferlan <jferlan>

commit 055c7c48f715f984e1070a5a9a9db3e7a7e271bc
Author:     Michal Privoznik <mprivozn>
AuthorDate: Wed Jun 7 13:38:14 2017 +0200
Commit:     Michal Privoznik <mprivozn>
CommitDate: Tue Jun 13 16:38:53 2017 +0200

    qemuProcessBuildDestroyHugepagesPath: create path more frequently
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1455819
    
    Currently, the per-domain path for huge pages mmap() for qemu is
    created iff domain has memoryBacking and hugepages in it
    configured. However, this alone is not enough because there can
    be a DIMM module with hugepages configured too.
    
    Signed-off-by: Michal Privoznik <mprivozn>
    Reviewed-by: John Ferlan <jferlan>

v3.4.0-100-g5b24d2506

Comment 4 Michal Privoznik 2017-08-08 11:16:53 UTC
Moving to POST per comment 3.

Comment 6 yalzhang@redhat.com 2017-10-24 13:31:45 UTC
Reproduce this bug on
libvirt-3.2.0-14.el7_4.3.x86_64
qemu-kvm-rhev-2.9.0-16.el7_4.9.x86_64

Then upgrade the libvirt to libvirt-3.8.0-1.el7.x86_64 and test, the result is expected.
 
0. Enable hugepages
# sysctl vm.nr_hugepages=600

1. Prepare a vm without <memoryBacking> but a dimm device using hugepage
# virsh dumpxml rhel7
...
 <maxMemory slots='16' unit='KiB'>2124800</maxMemory>
  <memory unit='KiB'>1155072</memory>
  <currentMemory unit='KiB'>1048576</currentMemory>
  <vcpu placement='static' current='1'>16</vcpu>
...
 <cpu>
    <numa>
      <cell id='0' cpus='0-7' memory='512000' unit='KiB'/>
      <cell id='1' cpus='8-15' memory='512000' unit='KiB'/>
    </numa>
  </cpu>
...
<devices>
   <memory model='dimm'>
      <source>
        <nodemask>0</nodemask>
        <pagesize unit='KiB'>2048</pagesize>
      </source>
      <target>
        <size unit='KiB'>131072</size>
        <node>1</node>
      </target>
      <address type='dimm' slot='1'/>
    </memory>
...
</devices>

2. the guest can start successfully.

# virsh start rhel7
Domain rhel7 started

# ll /dev/hugepages/libvirt/qemu -Z
drwx------. qemu qemu system_u:object_r:svirt_image_t:s0:c789,c952 7-rhel7

3. attach a dimm

# cat dimm.xml 
<memory model='dimm'>
      <source>
        <nodemask>0</nodemask>
        <pagesize unit='KiB'>2048</pagesize>
      </source>
      <target>
        <size unit='KiB'>10240</size>
        <node>0</node>
      </target>
    </memory>

# virsh attach-device rhel7 dimm.xml
Device attached successfully

4.check the xml,the memory attached successfully.

Comment 10 errata-xmlrpc 2018-04-10 10:44:33 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHEA-2018:0704