import logging, time, commands, os, string, re
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils
from autotest_lib.client.virt import virt_test_utils, aexpect, virt_test_setup
@error.context_aware
def run_trans_hugepage(test, params, env):
"""
KVM kernel hugepages user side test:
1) Smoke test
2) Stress test
@param test: KVM test object.
@param params: Dictionary with test parameters.
@param env: Dictionary with the test environment.
"""
def get_mem_status(params, type):
if type == "host":
info = utils.system_output("cat /proc/meminfo")
else:
info = session.cmd("cat /proc/meminfo")
for h in re.split("\n+", info):
if h.startswith("%s" % params):
output = re.split('\s+', h)[1]
return output
dd_timeout = float(params.get("dd_timeout", 900))
nr_ah = []
mem = params['mem']
failures = []
debugfs_flag = 1
debugfs_path = os.path.join(test.tmpdir, 'debugfs')
mem_path = os.path.join("/tmp", 'thp_space')
login_timeout = float(params.get("login_timeout", "3600"))
error.context("smoke test setup")
if not os.path.ismount(debugfs_path):
if not os.path.isdir(debugfs_path):
os.makedirs(debugfs_path)
utils.run("mount -t debugfs none %s" % debugfs_path)
test_config = virt_test_setup.TransparentHugePageConfig(test, params)
vm = virt_test_utils.get_living_vm(env, params.get("main_vm"))
session = virt_test_utils.wait_for_login(vm, timeout=login_timeout)
try:
# Check khugepage is used by guest
test_config.setup()
logging.info("Smoke test start")
error.context("smoke test")
nr_ah_before = get_mem_status('AnonHugePages', 'host')
if nr_ah_before <= 0:
e_msg = 'smoke: Host is not using THP'
logging.error(e_msg)
failures.append(e_msg)
# Protect system from oom killer
if int(get_mem_status('MemFree', 'guest')) / 1024 < mem :
mem = int(get_mem_status('MemFree', 'guest')) / 1024
session.cmd("mkdir -p %s" % mem_path)
session.cmd("mount -t tmpfs -o size=%sM none %s" % (str(mem), mem_path))
count = mem / 4
session.cmd("dd if=/dev/zero of=%s/1 bs=4000000 count=%s" %
(mem_path, count), timeout=dd_timeout)
nr_ah_after = get_mem_status('AnonHugePages', 'host')
if nr_ah_after <= nr_ah_before:
e_msg = ('smoke: Host did not use new THP during dd')
logging.error(e_msg)
failures.append(e_msg)
if debugfs_flag == 1:
if int(open('%s/kvm/largepages' % debugfs_path, 'r').read()) <= 0:
e_msg = 'smoke: KVM is not using THP'
logging.error(e_msg)
failures.append(e_msg)
logging.info("Smoke test finished")
# Use parallel dd as stress for memory
count = count / 3
logging.info("Stress test start")
error.context("stress test")
cmd = "rm -rf %s/*; for i in `seq %s`; do dd " % (mem_path, count)
cmd += "if=/dev/zero of=%s/$i bs=4000000 count=1& done;wait" % mem_path
output = session.cmd_output(cmd, timeout=dd_timeout)
if len(re.findall("No space", output)) > count * 0.05:
e_msg = "stress: Too many dd instances failed in guest"
logging.error(e_msg)
failures.append(e_msg)
try:
output = session.cmd('pidof dd')
except Exception:
output = None
if output is not None:
for i in re.split('\n+', output):
session.cmd('kill -9 %s' % i)
session.cmd("umount %s" % mem_path)
logging.info("Stress test finished")
finally:
error.context("all tests cleanup")
if os.path.ismount(debugfs_path):
utils.run("umount %s" % debugfs_path)
if os.path.isdir(debugfs_path):
os.removedirs(debugfs_path)
session.close()
test_config.cleanup()
error.context("")
if failures:
raise error.TestFail("THP base test reported %s failures:\n%s" %
(len(failures), "\n".join(failures)))