Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions KVM/qemu/boot_vm_in_hugepage.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
- boot_vm_in_hugepage:
virt_test_type = qemu
type = boot
start_vm = no
kill_vm_on_error = yes
login_timeout = 240
setup_hugepages = yes
Expand All @@ -15,6 +16,7 @@
expected_hugepage_size = 2048
- specify_hp_file:
kernel_hp_file = "/sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages"
vm_hugepage_mountpoint = "/mnt/kvm_hugepage_2m"
- 1G:
variants:
- @default:
Expand All @@ -27,7 +29,22 @@
expected_hugepage_size = 1048576
- specify_hp_file:
kernel_hp_file = "/sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages"
vm_hugepage_mountpoint = "/mnt/kvm_hugepage_1g"
mem = 4096
- low_mem_nxhp:
variants:
- @default:
no tdvm
is_low_mem = yes
mem = 1024
- high_mem_nxhp:
variants:
- @default:
no tdvm
is_high_mem = yes
setup_hugepages = no
manual_hugepage_setup = yes

variants:
- vm:
reboot_method = shell
Expand Down
133 changes: 97 additions & 36 deletions KVM/qemu/tests/boot.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,61 +12,122 @@
# Copy from tp-qemu

from provider import dmesg_router # pylint: disable=unused-import
import re
import time

from avocado.utils import cpu
from virttest import env_process
from virttest import error_context
from virttest import test_setup
from virttest import utils_misc
from virttest import utils_test


def _get_hugepage_size_mb(params):
kernel_hp_file = params.get("kernel_hp_file", "/proc/sys/vm/nr_hugepages")
if kernel_hp_file != "/proc/sys/vm/nr_hugepages":
match = re.search(r"hugepages-(\d+)kB", kernel_hp_file)
if match:
return max(int(match.group(1)) // 1024, 1)

with open("/proc/meminfo", "r", encoding="utf-8") as meminfo_file:
for line in meminfo_file:
if line.startswith("Hugepagesize:"):
return max(int(line.split()[1]) // 1024, 1)

raise ValueError("Could not determine hugepage size from /proc/meminfo")


def _update_dynamic_params(test, params):
params["start_vm"] = "yes"

if params.get_boolean("is_high_mem"):
host_cpu = cpu.online_count()
host_free_mem = utils_misc.get_usable_memory_size()
hugepage_size_mb = _get_hugepage_size_mb(params)
aligned_mem = (host_free_mem // 2 // hugepage_size_mb) * hugepage_size_mb
if aligned_mem < hugepage_size_mb:
test.cancel("Platform doesn't have enough free memory for one hugepage-backed guest")
params["smp"] = params["vcpu_maxcpus"] = max(host_cpu // 2, 1)
params["mem"] = aligned_mem
elif params.get_boolean("is_low_mem"):
params["mem"] = params.get_numeric("mem", 1024)

if params.get("vm_secure_guest_type") == "tdx":
host_cpu = cpu.online_count()
if params.get_numeric("smp", 1) > host_cpu:
test.cancel("Platform doesn't support to run this test")


def _setup_manual_hugepages(params):
hugepage_config = test_setup.HugePageConfig(params)
suggest_mem = hugepage_config.setup()
if suggest_mem is not None:
hugepage_size_mb = _get_hugepage_size_mb(params)
params["mem"] = (suggest_mem // hugepage_size_mb) * hugepage_size_mb
if not params.get("hugepage_path"):
params["hugepage_path"] = hugepage_config.hugepage_path
return hugepage_config


@error_context.context_aware
def run(test, params, env):
"""
Qemu reboot test:
1) Log into a guest
3) Send a reboot command or a system_reset monitor command (optional)
4) Wait until the guest is up again
5) Log into the guest to verify it's up again
Boot a guest with hugepage-related settings and optionally reboot it.

:param test: QEMU test object
:param params: Dictionary with the test parameters
:param env: Dictionary with test environment.
"""

timeout = float(params.get("login_timeout", 240))
serial_login = params.get("serial_login", "no") == "yes"
vms = env.get_all_vms()
for vm in vms:
error_context.context("Try to log into guest '%s'." % vm.name,
test.log.info)
if serial_login:
session = vm.wait_for_serial_login(timeout=timeout)
else:
session = vm.wait_for_login(timeout=timeout)
session.close()

if params.get("rh_perf_envsetup_script"):
for vm in vms:
if serial_login:
session = vm.wait_for_serial_login(timeout=timeout)
else:
session = vm.wait_for_login(timeout=timeout)
utils_test.service_setup(vm, session, test.virtdir)
session.close()
if params.get("reboot_method"):
hugepage_config = None
try:
_update_dynamic_params(test, params)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should have a check before calling it directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only the 2 new adding tests need this function call, right?


if params.get_boolean("manual_hugepage_setup"):
hugepage_config = _setup_manual_hugepages(params)

vm_name = params["main_vm"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

boot.py is used by boot_vm_in_hugepage.cfg and multi_vms.cfg, did you test both of their cases?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that when testcases in these two fields run separately (like only hugepage or only multi_vm) should have no problem, but when mixed, like running both hugepage and multi_vm testcases in one run, the hugepage cases will fail, the way to fix this is kill the qemu process manually.

env_process.preprocess_vm(test, params, env, vm_name)

timeout = float(params.get("login_timeout", 240))
serial_login = params.get("serial_login", "no") == "yes"
vms = env.get_all_vms()
for vm in vms:
error_context.context("Reboot guest '%s'." % vm.name,
error_context.context("Try to log into guest '%s'." % vm.name,
test.log.info)
if params["reboot_method"] == "system_reset":
time.sleep(int(params.get("sleep_before_reset", 10)))
# Reboot the VM
if serial_login:
session = vm.wait_for_serial_login(timeout=timeout)
else:
session = vm.wait_for_login(timeout=timeout)
for i in range(int(params.get("reboot_count", 1))):
session = vm.reboot(session,
params["reboot_method"],
0,
timeout,
serial_login)
session.close()

if params.get("rh_perf_envsetup_script"):
for vm in vms:
if serial_login:
session = vm.wait_for_serial_login(timeout=timeout)
else:
session = vm.wait_for_login(timeout=timeout)
utils_test.service_setup(vm, session, test.virtdir)
session.close()

if params.get("reboot_method"):
for vm in vms:
error_context.context("Reboot guest '%s'." % vm.name,
test.log.info)
if params["reboot_method"] == "system_reset":
time.sleep(int(params.get("sleep_before_reset", 10)))
if serial_login:
session = vm.wait_for_serial_login(timeout=timeout)
else:
session = vm.wait_for_login(timeout=timeout)
for _ in range(int(params.get("reboot_count", 1))):
session = vm.reboot(session,
params["reboot_method"],
0,
timeout,
serial_login)
session.close()
finally:
if hugepage_config is not None:
hugepage_config.cleanup()