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