diff --git a/qemu/tests/cfg/cpu_device_hotplug.cfg b/qemu/tests/cfg/cpu_device_hotplug.cfg new file mode 100644 index 0000000000000000000000000000000000000000..1cd16964068673190e6f95dd228aed566dbac4ff --- /dev/null +++ b/qemu/tests/cfg/cpu_device_hotplug.cfg @@ -0,0 +1,81 @@ +- cpu_device_hotplug_test: install setup image_copy unattended_install.cdrom + mem = 4096 + virt_test_type = qemu + type = cpu_device_hotplug + cpu_hotplug_timeout = 2000 + n_cpus_add = 1 + kill_vm = yes + iterations = 5 + onoff_iterations = 100 + login_timeout = 240 + only ppc64le + kill_vm = yes + smp = 8 + vcpu_maxcpus = 240 + auto_cpu_model = "no" + cpu_hotplug_cmd = 'device_add CPU_MODEL-spapr-cpu-core,id=core{0},core-id={0}' + cpu_hotunplug_cmd = 'device_del core{0}' + variants: + - add_one_cpu: + + - add_32_cpu: + n_cpus_add = 32 + - add_64_cpu: + n_cpus_add = 64 + - add_96_cpu: + n_cpus_add = 96 + - add_128_cpu: + n_cpus_add = 128 + - add_160_cpu: + n_cpus_add = 160 + - add_192_cpu: + n_cpus_add = 192 + - add_224_cpu: + n_cpus_add = 224 + - add_max_cpu: + n_cpus_add = 240 + - nonexist_vcpu: + type = nonexist_vcpu_hotplug + nonexist_vcpu = -1 256 + - remove_one_cpu: + unplug = "yes" + + - remove_32_cpu: + unplug = "yes" + n_cpus_remove = 32 + - remove_64_cpu: + unplug = "yes" + n_cpus_remove = 64 + - remove_96_cpu: + unplug = "yes" + n_cpus_remove = 96 + - remove_128_cpu: + unplug = "yes" + n_cpus_remove = 128 + - remove_160_cpu: + unplug = "yes" + n_cpus_remove = 160 + - remove_192_cpu: + unplug = "yes" + n_cpus_remove = 192 + - remove_224_cpu: + unplug = "yes" + n_cpus_remove = 224 + - remove_max_cpu: + unplug = "yes" + n_cpus_remove = 240 + + variants: + - smp8_c1_t4: + smp = 8 + used_cpus = 8 + vcpu_cores = 1 + vcpu_threads = 4 + vcpu_maxcpus = 240 + + - smp8_c2_t2: + smp = 8 + used_cpus = 8 + vcpu_cores = 2 + vcpu_threads = 2 + vcpu_maxcpus = 240 diff --git a/qemu/tests/cpu_device_hotplug.py b/qemu/tests/cpu_device_hotplug.py new file mode 100644 index 0000000000000000000000000000000000000000..356f90a76265a20b05ebc0a547f96e2465d5b9e4 --- /dev/null +++ b/qemu/tests/cpu_device_hotplug.py @@ -0,0 +1,101 @@ +import logging +import re +import time + +from autotest.client.shared import error + +from virttest import utils_misc + + +@error.context_aware +def run(test, params, env): + """ + Runs vCPU hotplug tests based on CPU device: + """ + + def hotplug(vm, current_cpus, total_cpus, vcpu_threads): + for cpu in range(current_cpus, total_cpus): + error.context("hot-pluging vCPU %s" % cpu, logging.info) + vm.hotplug_vcpu(cpu_id=cpu, plug_command=hotplug_cmd) + time.sleep(0.1) + time.sleep(5) + + def hotunplug(vm, current_cpus, total_cpus, vcpu_threads): + for cpu in range(current_cpus, total_cpus): + error.context("hot-unpluging vCPU %s" % cpu, logging.info) + vm.hotplug_vcpu(cpu_id=cpu, plug_command=unplug_cmd, unplug="yes") + time.sleep(0.1) + # Need more time to unplug, so sleeping more than hotplug. + time.sleep(10) + + def verify(vm, total_cpus): + output = vm.monitor.send_args_cmd("info cpus") + logging.debug("Output of info CPUs:\n%s", output) + + cpu_regexp = re.compile("CPU #(\d+)") + total_cpus_monitor = len(cpu_regexp.findall(output)) + if total_cpus_monitor != total_cpus: + raise error.TestFail("Monitor reports %s CPUs, when VM should have" + " %s" % (total_cpus_monitor, total_cpus)) + error.context("hotplugging finished, let's wait a few sec and" + " check CPUs quantity in guest.", logging.info) + if not utils_misc.wait_for(lambda: utils_misc.check_if_vm_vcpu_match( + total_cpus, vm), + 60 + total_cpus, first=10, + step=5.0, text="retry later"): + raise error.TestFail("CPU quantity mismatch cmd after hotplug !") + error.context("rebooting the vm and check CPU quantity !", + logging.info) + session = vm.reboot() + if not utils_misc.check_if_vm_vcpu_match(total_cpus, vm): + raise error.TestFail("CPU quantity mismatch cmd after hotplug " + "and reboot !") + + error.context("boot the vm, with '-smp X,maxcpus=Y' option," + "thus allow hotplug vcpu", logging.info) + + vm = env.get_vm(params["main_vm"]) + vm.verify_alive() + + timeout = int(params.get("login_timeout", 360)) + session = vm.wait_for_login(timeout=timeout) + + n_cpus_add = int(params.get("n_cpus_add", 1)) + n_cpus_remove = int(params.get("n_cpus_remove", 1)) + maxcpus = int(params.get("maxcpus", 240)) + current_cpus = int(params.get("smp", 2)) + onoff_iterations = int(params.get("onoff_iterations", 20)) + hotplug_cmd = params.get("cpu_hotplug_cmd", "") + unplug_cmd = params.get("cpu_hotunplug_cmd", "") + vcpu_cores = int(params.get("vcpu_cores", 1)) + vcpu_threads = int(params.get("vcpu_threads", 1)) + cpu_model = params.get("cpu_model", "host") + unplug = params.get("unplug", "no") + total_cpus = current_cpus + + if unplug == "yes": + n_cpus_add = n_cpus_remove + + hotplug_cmd = hotplug_cmd.replace("CPU_MODEL", cpu_model) + + if (n_cpus_add * vcpu_threads) + current_cpus > maxcpus: + logging.warn("CPU quantity more than maxcpus, set it to %s", maxcpus) + total_cpus = maxcpus + else: + total_cpus = current_cpus + (n_cpus_add * vcpu_threads) + + logging.info("current_cpus=%s, total_cpus=%s", current_cpus, total_cpus) + error.context("check if CPUs in guest matches qemu cmd " + "before hot-plug", logging.info) + if not utils_misc.check_if_vm_vcpu_match(current_cpus, vm): + raise error.TestError("CPU quantity mismatch cmd before hotplug !") + hotplug(vm, current_cpus, total_cpus, vcpu_threads) + verify(vm, total_cpus) + + if unplug == "yes": + hotunplug(vm, current_cpus, total_cpus, vcpu_threads) + + total_cpus = total_cpus - (n_cpus_remove * vcpu_threads) + if total_cpus <= 0: + total_cpus = current_cpus + verify(vm, total_cpus)