[PATCH 1/3] virt: Add Transparent Hugepages setup v2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

Signed-off-by: Yiqiao Pu <ypu@xxxxxxxxxx
Signed-off-by: Lucas Meneghel Rodrigues <lmr@xxxxxxxxxx>
---
 client/virt/virt_test_setup.py |  143 +++++++++++++++++++++++++++++++++++++++-
 1 files changed, 142 insertions(+), 1 deletions(-)

diff --git a/client/virt/virt_test_setup.py b/client/virt/virt_test_setup.py
index 3e1f5b5..792ffe6 100644
--- a/client/virt/virt_test_setup.py
+++ b/client/virt/virt_test_setup.py
@@ -1,11 +1,152 @@
 """
 Library to perform pre/post test setup for KVM autotest.
 """
-import os, logging
+import os, logging, re, sre
 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")
+
+        # test_cfg holds all the desired host config values we want to set
+        # before THP tests
+        test_cfg={"%s/defrag" % self.thp_path: "yes",
+                  "%s/enabled" % self.thp_path: "always",
+                  "%s/khugepaged/defrag" % self.thp_path: "yes",
+                  "%s/khugepaged/scan_sleep_millisecs" % self.thp_path: "100",
+                  "%s/khugepaged/pages_to_scan" % self.thp_path: "4096",
+                  "%s/khugepaged/alloc_sleep_millisecs" % self.thp_path: "100",
+                  "/sys/kernel/mm/ksm/run": "1",
+                  "/proc/sys/vm/nr_hugepages":"0"}
+        if os.path.isfile("%s/khugepaged/enabled" % self.thp_path):
+            test_cfg["%s/khugepaged/enabled" % self.thp_path] = "always"
+        if os.path.isfile("%s/khugepaged/max_ptes_none" % self.thp_path):
+            test_cfg["%s/khugepaged/max_ptes_none" % self.thp_path] = "511"
+            test_cfg["%s/defrag" % self.thp_path] = "always"
+
+        tmp_list = []
+        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]
+
+        self.original_config = {}
+        # Save host current config, so we can restore it during cleanup
+        for path in test_cfg:
+            param = open(path, 'r').read()
+            if ("enabled" in param) or ("defrag" in param):
+                param = re.split("\[|\]", param)[1] + '\n'
+            self.original_config[path] = param
+
+        self.test_config = test_cfg
+
+
+    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 set_params(self, path_dict={}, filename="", value=""):
+        """
+        Sets the value of a config file for a given path.
+
+        @param path_dict: Dict of files' paths {path : value}
+        @param filename: Name of file to setup
+        @param value: Value set to the configuration files
+        """
+        for path in path_dict.keys():
+            if path in filename:
+                try:
+                    file(path, "w").write(value)
+                except IOError, e:
+                    raise THPWriteConfigError("Can not set %s to %s: %s" %
+                                              (value, filename, e))
+
+
+    def khugepaged_test(self):
+        """
+        Start, stop and frequency change test for khugepaged.
+        """
+        status_list = ["never", "always", "never"]
+        for status in status_list:
+            self.set_params(self.test_config, "enabled", status)
+            try:
+                utils.run('pgrep khugepaged')
+            except error.CmdError:
+                raise THPKhugepagedError("khugepaged can not be set to "
+                                         "status %s" % status)
+
+
+    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(self.original_config[path])
+            p_file.close()
+
+
 class HugePageConfig(object):
     def __init__(self, params):
         """
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux