diff --git a/tests/integration_tests/functional/test_pause_resume.py b/tests/integration_tests/functional/test_pause_resume.py index 4210e3a0d7fb..2013e7a87692 100644 --- a/tests/integration_tests/functional/test_pause_resume.py +++ b/tests/integration_tests/functional/test_pause_resume.py @@ -3,6 +3,7 @@ """Basic tests scenarios for snapshot save/restore.""" import pytest +import time def verify_net_emulation_paused(metrics): @@ -127,3 +128,35 @@ def test_pause_resume_preboot(uvm_nano): # Try to resume microvm when not running, it must fail. with pytest.raises(RuntimeError, match=expected_err): basevm.api.vm.patch(state="Resumed") + + +def test_kvmclock_ctrl(uvm_plain_any): + """ + Test that pausing vCPUs does not trigger a soft lock-up + """ + + microvm = uvm_plain_any + microvm.help.enable_console() + microvm.spawn() + microvm.basic_config() + microvm.add_net_iface() + microvm.start() + + # Launch reproducer in host + # This launches `ls -R /` in a loop inside the guest. The command writes its output in the + # console. This detail is important as it writing in the console seems to increase the probability + # that we will pause the execution inside the kernel and cause a lock up. Setting KVM_CLOCK_CTRL + # bit that informs the guest we're pausing the vCPUs, should avoid that lock up. + microvm.ssh.check_output( + "sh -c 'while true; do ls -R /; done' > /dev/ttyS0 2>&1 < /dev/null &" + ) + + for _ in range(12): + microvm.api.vm.patch(state="Paused") + time.sleep(5) + microvm.api.vm.patch(state="Resumed") + + dmesg = microvm.ssh.check_output("dmesg").stdout + assert "rcu_sched self-detected stall on CPU" not in dmesg + assert "rcu_preempt detected stalls on CPUs/tasks" not in dmesg + assert "BUG: soft lockup -" not in dmesg