diff --git a/libvirt/tests/cfg/sriov/locked_memory_check/sriov_with_hotplug_memory.cfg b/libvirt/tests/cfg/sriov/locked_memory_check/sriov_with_hotplug_memory.cfg new file mode 100644 index 0000000000..6c7598133e --- /dev/null +++ b/libvirt/tests/cfg/sriov/locked_memory_check/sriov_with_hotplug_memory.cfg @@ -0,0 +1,24 @@ +- sriov.locked_memory_check.hotplug_memory: + type = sriov_with_hotplug_memory + start_vm = "no" + mem_dict1 = {'mem_model': 'dimm', 'target': {'size': 1, 'size_unit': 'G', 'node': 0}, 'alias': {'name': 'ua-d9cbe3cc-40fe-4aed-b245-874c534e8362'}} + mem_dict2 = {'mem_model': 'dimm', 'target': {'size': 1, 'size_unit': 'G', 'node': 0}} + only x86_64, aarch64 + variants dev_type: + - hostdev_interface: + iface_dict = {'managed': 'yes', 'type_name': 'hostdev', 'hostdev_address': {'type_name': 'pci', 'attrs': vf_pci_addr}, 'alias': {'name': 'ua-89cbe690-6c6c-4f2f-adac-5826fe52ea74'}} + - hostdev_device: + variants dev_source: + - vf_address: + hostdev_dict = {'alias': {'name': 'ua-1bcbabff-f022-4d4f-ae8c-13f2d3a07906'}, 'mode': 'subsystem', 'type': 'pci', 'source': {'untyped_address': vf_pci_addr}, 'managed': 'yes'} + - pf_address: + hostdev_dict = {'alias': {'name': 'ua-1bcbabff-f022-4d4f-ae8c-13f2d3a07906'}, 'mode': 'subsystem', 'type': 'pci', 'source': {'untyped_address': pf_pci_addr}, 'managed': 'yes'} + variants: + - with_hostdev: + - without_hostdev: + without_hostdev = "yes" + variants mem_set: + - without_hardlimit: + vm_attrs = {'max_mem_rt': 6291456, 'max_mem_rt_slots': 32, 'max_mem_rt_unit': 'K', 'vcpu': 8, 'cpu': {'numa_cell': [{'id': '0', 'cpus': '0-3', 'memory': '1048576', 'unit': 'K'}, {'id': '1', 'cpus': '4-7', 'memory': '1048576', 'unit': 'K'}]}} + - with_hardlimit: + vm_attrs = {'max_mem_rt': 6291456, 'max_mem_rt_slots': 32, 'max_mem_rt_unit': 'K', 'vcpu': 8, 'memtune': {'hard_limit': 10485760, 'hard_limit_unit': 'K'},'cpu': {'numa_cell': [{'id': '0', 'cpus': '0-3', 'memory': '1048576', 'unit': 'K'}, {'id': '1', 'cpus': '4-7', 'memory': '1048576', 'unit': 'K'}]}} diff --git a/libvirt/tests/src/sriov/locked_memory_check/sriov_with_hotplug_memory.py b/libvirt/tests/src/sriov/locked_memory_check/sriov_with_hotplug_memory.py new file mode 100644 index 0000000000..f3e841c355 --- /dev/null +++ b/libvirt/tests/src/sriov/locked_memory_check/sriov_with_hotplug_memory.py @@ -0,0 +1,140 @@ +from virttest import virsh + +from virttest.libvirt_xml import vm_xml +from virttest.libvirt_xml.devices import memory +from virttest.utils_libvirt import libvirt_memory +from virttest.utils_test import libvirt + +from provider.sriov import sriov_base + +# Define several bytes +one_G_bytes = 1073741824 +two_G_bytes = 2147483648 +sf_M_bytes = 67108864 + + +def run(test, params, env): + """ + Hotplug memory to vm with hostdev type device and check the memory lock limit. + """ + def setup_test(vm_name, dev_type, iface_dict): + """ + Prepare vm xml with device and memory setting then start guest. + + :params vm_name: the vm name + :params dev_type: the device type, includes hostdev device and interface + :params iface_dict: the dict of hostdev interface/device + :params return: the list of vmxml and with_hostdev_device value + """ + test.log.info("SETUP_STEP1: prepare vm xml with memory setting.") + vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) + vmxml.setup_attrs(**vm_attrs) + vmxml.sync() + with_hostdev_device = False + if not without_hostdev: + test.log.info("SETUP_STEP2: prepare vm xml with device.") + sriov_test_obj.setup_default(dev_name=dev_name) + iface_dev = sriov_test_obj.create_iface_dev(dev_type, iface_dict) + libvirt.add_vm_device(vmxml, iface_dev) + with_hostdev_device = True + return vmxml, with_hostdev_device + + def check_memory_limit(vmxml, current_mem, with_hostdev_device=True, mem_change=True): + """ + Check the locked memory limit. + + :params vmxml: the vm xml + :params exp_mem: the expected current memory + :params with_hostdev_device: boolean to use check if the vm has hostdev device + :params mem_change: boolean to use check if the MEMLOCK is changed + """ + if int(current_mem) != int(vmxml.get_current_mem() * 1024): + test.fail("The current memory is incorrect after hot-unplugged.") + + # With_hardlimit: MEMLOCK value is equal to the hard_limit value + if mem_set == "with_hardlimit": + expr_memlock = libvirt_memory.normalize_mem_size( + vmxml.memtune.hard_limit, + vmxml.memtune.hard_limit_unit) + + # Without_hardlimit: MEMLOCK value is current memory + 1G + if mem_set == "without_hardlimit": + if without_hostdev and not with_hostdev_device: + expr_memlock = sf_M_bytes + if with_hostdev_device: + if not mem_change: + expr_memlock = current_mem + two_G_bytes + else: + expr_memlock = current_mem + one_G_bytes + + if not libvirt_memory.comp_memlock(expr_memlock): + test.fail("Unable to get correct MEMLOCK!") + + def hotplug_mem_device(vm_name, mem_dict, current_mem): + """ + Hotplug the memory device and check locked memory limit. + + :params vm_name: the vm name + :params mem_dict: the dict of memory device + :params current_mem: the expected current memory + """ + memxml = memory.Memory() + memxml.setup_attrs(**mem_dict) + virsh.attach_device(vm_name, memxml.xml, debug=True, ignore_status=False) + vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) + check_memory_limit(vmxml, current_mem) + + vm_name = params.get("main_vm", "avocado-vt-vm1") + vm = env.get_vm(vm_name) + dev_type = params.get("dev_type", "") + dev_source = params.get("dev_source", "") + mem_set = params.get("mem_set", "") + vm_attrs = eval(params.get("vm_attrs", "{}")) + mem_dict1 = eval(params.get("mem_dict1", "{}")) + mem_dict2 = eval(params.get("mem_dict2", "{}")) + without_hostdev = "yes" == params.get("without_hostdev", "no") + + vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) + backup_vmxml = vmxml.copy() + + sriov_test_obj = sriov_base.SRIOVTest(vm, test, params) + if dev_type == "hostdev_device" and dev_source.startswith("pf"): + dev_name = sriov_test_obj.pf_dev_name + else: + dev_name = sriov_test_obj.vf_dev_name + iface_dict = sriov_test_obj.parse_iface_dict() + + try: + vmxml, with_hostdev_device = setup_test(vm_name, dev_type, iface_dict) + test.log.info("TEST_STEP1: Start the vm and check locked memory limit.") + vm.start() + vm_session = vm.wait_for_serial_login(timeout=240).close + test.log.debug("The current guest xml is:%s", vmxml) + default_mem = libvirt_memory.normalize_mem_size( + vmxml.get_current_mem(), + vmxml.get_current_mem_unit()) + check_memory_limit(vmxml, default_mem, with_hostdev_device) + if without_hostdev: + test.log.info("TEST_STEP: Hotplug iface device and check locked memory limit.") + iface_dev = sriov_test_obj.create_iface_dev(dev_type, iface_dict) + virsh.attach_device(vm_name, iface_dev.xml, debug=True, ignore_status=False) + vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) + check_memory_limit(vmxml, default_mem, with_hostdev_device=True) + test.log.info("TEST_STEP2: Hotplug 1st memory device and check locked memory limit.") + first_mem = default_mem + one_G_bytes + hotplug_mem_device(vm_name, mem_dict1, first_mem) + test.log.info("TEST_STEP3: Hotplug 2nd memory device and check locked memory limit.") + second_mem = first_mem + one_G_bytes + hotplug_mem_device(vm_name, mem_dict2, second_mem) + test.log.info("TEST_STEP4: Hot-unplug 2nd memory device and check locked memory limit.") + memxml = vm_xml.VMXML.new_from_dumpxml(vm_name).get_devices('memory')[-1] + virsh.detach_device(vm_name, memxml.xml) + vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) + check_memory_limit(vmxml, first_mem, mem_change=False) + if without_hostdev: + test.log.info("TEST_STEP: Hot-unplug iface device and check locked memory limit.") + virsh.detach_device(vm_name, iface_dev.xml, debug=True, ignore_status=False) + vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) + check_memory_limit(vmxml, first_mem, with_hostdev_device=False) + finally: + sriov_test_obj.teardown_default(dev_name=dev_name)