Blame test/python_framework/huge_page_organizer.py

Packit 345191
#
Packit 345191
#  Copyright (C) 2017 Intel Corporation.
Packit 345191
#  All rights reserved.
Packit 345191
#
Packit 345191
#  Redistribution and use in source and binary forms, with or without
Packit 345191
#  modification, are permitted provided that the following conditions are met:
Packit 345191
#  1. Redistributions of source code must retain the above copyright notice(s),
Packit 345191
#     this list of conditions and the following disclaimer.
Packit 345191
#  2. Redistributions in binary form must reproduce the above copyright notice(s),
Packit 345191
#     this list of conditions and the following disclaimer in the documentation
Packit 345191
#     and/or other materials provided with the distribution.
Packit 345191
#
Packit 345191
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
Packit 345191
#  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
Packit 345191
#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
Packit 345191
#  EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
Packit 345191
#  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit 345191
#  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
Packit 345191
#  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
Packit 345191
#  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
Packit 345191
#  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
Packit 345191
#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 345191
#
Packit 345191
Packit 345191
from cmd_helper import CMD_helper
Packit 345191
import os
Packit 345191
import itertools
Packit 345191
Packit 345191
"""
Packit 345191
Huge_page_organizer sets hugepages per NUMA node and restores initial setup of hugepages.
Packit 345191
It writes and reads from the same file, so using Huge_page_organizer with parallel
Packit 345191
execution may cause undefined behaviour.
Packit 345191
"""
Packit 345191
class Huge_page_organizer(object):
Packit 345191
Packit 345191
    cmd_helper = CMD_helper()
Packit 345191
    path = "/sys/devices/system/node/node{0}/hugepages/hugepages-2048kB/nr_hugepages"
Packit 345191
    restore_values = []
Packit 345191
Packit 345191
    def __restore(self):
Packit 345191
        """Restore initial setup of hugepages."""
Packit 345191
        for node_id, restore_value in enumerate(self.restore_values):
Packit 345191
            self.__set_nr_hugepages(node_id, restore_value)
Packit 345191
Packit 345191
    def __get_nr_hugepages(self, node_id):
Packit 345191
        """Return number of hugepages on given node or None if given node is not configured."""
Packit 345191
        if not os.path.isfile(self.path.format(node_id)):
Packit 345191
            return None
Packit 345191
        with open(self.path.format(node_id), "r") as f:
Packit 345191
            return int(f.read())
Packit 345191
Packit 345191
    def __set_nr_hugepages(self, node_id, nr_hugepages):
Packit 345191
        """Set hugepages on given node to given number. Return True on success, False otherwise."""
Packit 345191
        command = 'sh -c "echo {0} >> {1}"'.format(nr_hugepages, self.path.format(node_id))
Packit 345191
        output, retcode = self.cmd_helper.execute_cmd(command, sudo=True)
Packit 345191
        if retcode:
Packit 345191
            return False
Packit 345191
        return self.__get_nr_hugepages(node_id) is nr_hugepages
Packit 345191
Packit 345191
    def __init__(self, nr_hugepages_per_node):
Packit 345191
        """Save current hugepages setup and set hugepages per NUMA node."""
Packit 345191
        for node_id in itertools.count():
Packit 345191
            nr_hugepages = self.__get_nr_hugepages(node_id)
Packit 345191
            if nr_hugepages is None:
Packit 345191
                break
Packit 345191
            self.restore_values.append(nr_hugepages)
Packit 345191
            retcode = self.__set_nr_hugepages(node_id, nr_hugepages_per_node)
Packit 345191
            if not retcode:
Packit 345191
               self.__restore()
Packit 345191
            assert retcode, "Error: Could not set the requested amount of hugepages."
Packit 345191
Packit 345191
    def __del__(self):
Packit 345191
        """Call __restore() function."""
Packit 345191
        self.__restore()