| 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))) |