From: Lucas Meneghel Rodrigues <lookkas@gmail.com>
To: autotest@test.kernel.org
Cc: aarcange@redhat.com, kvm@vger.kernel.org
Subject: [PATCH 1/3] virt: Add Transparent Hugepages setup
Date: Mon, 27 Jun 2011 13:26:41 -0300 [thread overview]
Message-ID: <1309192003-5456-2-git-send-email-lookkas@gmail.com> (raw)
In-Reply-To: <1309192003-5456-1-git-send-email-lookkas@gmail.com>
From: Yiqiao Pu <ypu@redhat.com>
This class configures khugepaged to active mode, with
functions to restore original guest configuration.
Changes from v1:
* Rather than a pre/post script, config is now part of
the framework
* No need to store configuration in files anymore to restore
host khugepaged original behavior
Changes from v2:
* Walk through the thp config directory. And test khugepaged
with the default value in system.
* Add 5s sleep time in khugepaged test
Changes from v3:
* Replace custom function is_writeable with trying to open
the file for writing.
* Remove some intermediate assignmentes of class attributes.
Signed-off-by: Yiqiao Pu <ypu@redhat.com>
Signed-off-by: Lucas Meneghel Rodrigues <lmr@redhat.com>
---
client/virt/virt_test_setup.py | 186 +++++++++++++++++++++++++++++++++++++++-
1 files changed, 185 insertions(+), 1 deletions(-)
diff --git a/client/virt/virt_test_setup.py b/client/virt/virt_test_setup.py
index 3e1f5b5..2717014 100644
--- a/client/virt/virt_test_setup.py
+++ b/client/virt/virt_test_setup.py
@@ -1,11 +1,195 @@
"""
Library to perform pre/post test setup for KVM autotest.
"""
-import os, logging
+import os, logging, time, re, sre, random
from autotest_lib.client.common_lib import error
from autotest_lib.client.bin import utils
+class THPError(Exception):
+ """
+ Base exception for Transparent Hugepage setup.
+ """
+ pass
+
+
+class THPNotSupportedError(THPError):
+ """
+ Thrown when host does not support tansparent hugepages.
+ """
+ pass
+
+
+class THPWriteConfigError(THPError):
+ """
+ Thrown when host does not support tansparent hugepages.
+ """
+ pass
+
+
+class THPKhugepagedError(THPError):
+ """
+ Thrown when khugepaged is not behaving as expected.
+ """
+ pass
+
+
+class TransparentHugePageConfig(object):
+ def __init__(self, test, params):
+ """
+ Find paths for transparent hugepages and kugepaged configuration. Also,
+ back up original host configuration so it can be restored during
+ cleanup.
+ """
+ self.params = params
+
+ RH_THP_PATH = "/sys/kernel/mm/redhat_transparent_hugepage"
+ UPSTREAM_THP_PATH = "/sys/kernel/mm/transparent_hugepage"
+ if os.path.isdir(RH_THP_PATH):
+ self.thp_path = RH_THP_PATH
+ elif os.path.isdir(UPSTREAM_THP_PATH):
+ self.thp_path = UPSTREAM_THP_PATH
+ else:
+ raise THPNotSupportedError("System doesn't support transparent "
+ "hugepages")
+
+ tmp_list = []
+ test_cfg = {}
+ test_config = self.params.get("test_config", None)
+ if test_config is not None:
+ tmp_list = re.split(';', test_config)
+ while len(tmp_list) > 0:
+ tmp_cfg = tmp_list.pop()
+ test_cfg[re.split(":", tmp_cfg)[0]] = sre.split(":", tmp_cfg)[1]
+ # Save host current config, so we can restore it during cleanup
+ # We will only save the writeable part of the config files
+ original_config = {}
+ # List of files that contain string config values
+ self.file_list_str = []
+ # List of files that contain integer config values
+ self.file_list_num = []
+ for f in os.walk(self.thp_path):
+ base_dir = f[0]
+ if f[2]:
+ for name in f[2]:
+ f_dir = os.path.join(base_dir, name)
+ parameter = file(f_dir, 'r').read()
+ try:
+ # Verify if the path in question is writable
+ f = open(f_dir, 'w')
+ f.close()
+ if re.findall("\[(.*)\]", parameter):
+ original_config[f_dir] = re.findall("\[(.*)\]",
+ parameter)[0]
+ self.file_list_str.append(f_dir)
+ else:
+ original_config[f_dir] = int(parameter)
+ self.file_list_num.append(f_dir)
+ except IOError:
+ pass
+
+ self.test_config = test_cfg
+ self.original_config = original_config
+
+
+ def set_env(self):
+ """
+ Applies test configuration on the host.
+ """
+ if self.test_config:
+ for path in self.test_config.keys():
+ file(path, 'w').write(self.test_config[path])
+
+
+ def value_listed(self, value):
+ """
+ Get a parameters list from a string
+ """
+ value_list = []
+ for i in re.split("\[|\]|\n+|\s+", value):
+ if i:
+ value_list.append(i)
+ return value_list
+
+
+ def khugepaged_test(self):
+ """
+ Start, stop and frequency change test for khugepaged.
+ """
+ def check_status_with_value(action_list, file_name):
+ """
+ Check the status of khugepaged when set value to specify file.
+ """
+ for (a, r) in action_list:
+ open(file_name, "w").write(a)
+ time.sleep(5)
+ try:
+ utils.run('pgrep khugepaged')
+ if r != 0:
+ raise THPKhugepagedError("Khugepaged still alive when"
+ "transparent huge page is "
+ "disabled")
+ except error.CmdError:
+ if r == 0:
+ raise THPKhugepagedError("Khugepaged could not be set to"
+ "status %s" % a)
+
+
+ for file_path in self.file_list_str:
+ action_list = []
+ if re.findall("enabled", file_path):
+ # Start and stop test for khugepaged
+ value_list = self.value_listed(open(file_path,"r").read())
+ for i in value_list:
+ if re.match("n", i, re.I):
+ action_stop = (i, 256)
+ for i in value_list:
+ if re.match("[^n]", i, re.I):
+ action = (i, 0)
+ action_list += [action_stop, action, action_stop]
+ action_list += [action]
+
+ check_status_with_value(action_list, file_path)
+ else:
+ value_list = self.value_listed(open(file_path,"r").read())
+ for i in value_list:
+ action = (i, 0)
+ action_list.append(action)
+ check_status_with_value(action_list, file_path)
+
+ for file_path in self.file_list_num:
+ action_list = []
+ value = int(open(file_path, "r").read())
+ if value != 0 and value != 1:
+ new_value = random.random()
+ action_list.append((str(int(value * new_value)),0))
+ action_list.append((str(int(value * ( new_value + 1))),0))
+ else:
+ action_list.append(("0", 0))
+ action_list.append(("1", 0))
+
+ check_status_with_value(action_list, file_path)
+
+
+ def setup(self):
+ """
+ Configure host for testing. Also, check that khugepaged is working as
+ expected.
+ """
+ self.set_env()
+ self.khugepaged_test()
+
+
+ def cleanup(self):
+ """:
+ Restore the host's original configuration after test
+ """
+ for path in self.original_config:
+ p_file = open(path, 'w')
+ p_file.write(str(self.original_config[path]))
+ p_file.close()
+
+
class HugePageConfig(object):
def __init__(self, params):
"""
--
1.7.5.4
next prev parent reply other threads:[~2011-06-27 16:26 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-06-27 16:26 [PATCH 0/3] Transparent Hugepages tests v4 Lucas Meneghel Rodrigues
2011-06-27 16:26 ` Lucas Meneghel Rodrigues [this message]
2011-06-27 16:26 ` [PATCH 2/3] KVM test: Add Transparent Hugepages subtests Lucas Meneghel Rodrigues
2011-06-27 16:26 ` [PATCH 3/3] Add THP test variants to tests_base.cfg.sample Lucas Meneghel Rodrigues
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1309192003-5456-2-git-send-email-lookkas@gmail.com \
--to=lookkas@gmail.com \
--cc=aarcange@redhat.com \
--cc=autotest@test.kernel.org \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox