From patchwork Thu Jun 16 00:18:34 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas Meneghel Rodrigues X-Patchwork-Id: 883822 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p5G0Is65024511 for ; Thu, 16 Jun 2011 00:18:54 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753538Ab1FPASu (ORCPT ); Wed, 15 Jun 2011 20:18:50 -0400 Received: from mx1.redhat.com ([209.132.183.28]:30278 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753506Ab1FPASt (ORCPT ); Wed, 15 Jun 2011 20:18:49 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p5G0InPU016037 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 15 Jun 2011 20:18:49 -0400 Received: from justice.redhat.com (vpn-8-107.rdu.redhat.com [10.11.8.107]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p5G0IdYt003559; Wed, 15 Jun 2011 20:18:43 -0400 From: Lucas Meneghel Rodrigues To: autotest@test.kernel.org Cc: kvm@vger.kernel.org, ypu@redhat.com, Lucas Meneghel Rodrigues Subject: [PATCH 1/3] virt: Add Transparent Hugepages setup v2 Date: Wed, 15 Jun 2011 21:18:34 -0300 Message-Id: <1308183516-5247-2-git-send-email-lmr@redhat.com> In-Reply-To: <1308183516-5247-1-git-send-email-lmr@redhat.com> References: <1308183516-5247-1-git-send-email-lmr@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Thu, 16 Jun 2011 00:18:54 +0000 (UTC) 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 --- 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): """