|
Packit Service |
96f515 |
#! /usr/libexec/platform-python
|
|
Packit |
b131a5 |
|
|
Packit Service |
e2dccc |
from __future__ import print_function
|
|
Packit Service |
46f680 |
from __future__ import division
|
|
Packit Service |
e2dccc |
|
|
Packit |
2d622a |
import subprocess
|
|
Packit |
2d622a |
import types
|
|
Packit |
2d622a |
import os
|
|
Packit |
2d622a |
import sys
|
|
Packit |
2d622a |
import getopt
|
|
Packit |
2d622a |
import resource
|
|
Packit |
2d622a |
import errno
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# The superset of wordsizes that should be tested (default 32, 64)
|
|
Packit |
2d622a |
wordsizes = set()
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# The super set of page sizes that should be tested. Defaults to all supported
|
|
Packit |
2d622a |
# huge page sizes with an active mount and at least one huge page allocated
|
|
Packit |
2d622a |
pagesizes = set()
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Each page size may have a subset of valid wordsizes
|
|
Packit |
2d622a |
# This is a dictionary (indexed by page size) of sets
|
|
Packit |
2d622a |
wordsizes_by_pagesize = {}
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# The linkhuge tests may only be valid on a subset of word sizes
|
|
Packit |
2d622a |
# This set contains the wordsizes valid for linkhuge tests
|
|
Packit |
2d622a |
linkhuge_wordsizes = set()
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# A list of all discovered mountpoints that may be used by libhugetlbfs for
|
|
Packit |
2d622a |
# this run of tests. This is used for cleaning up left-over share files.
|
|
Packit |
2d622a |
mounts = []
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Results matrix: This 3-D dictionary is indexed as follows:
|
|
Packit |
2d622a |
# [type] - Test results fall into one of the 'result_types' categories
|
|
Packit |
2d622a |
# [pagesize] - a page size from the set 'pagesizes'
|
|
Packit |
2d622a |
# [bits] - a word size from the set 'wordsizes'
|
|
Packit |
2d622a |
# The indexed value is the number of tests matching the above traits
|
|
Packit |
2d622a |
R = {}
|
|
Packit |
2d622a |
result_types = ("total", "pass", "config", "fail", "xfail", "xpass",
|
|
Packit |
2d622a |
"signal", "strange", "skip", "nofile")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def bash(cmd):
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Run 'cmd' in the shell and return the exit code and output.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
|
|
Packit |
2d622a |
try:
|
|
Packit |
2d622a |
rc = p.wait()
|
|
Packit |
2d622a |
except KeyboardInterrupt:
|
|
Packit |
2d622a |
# Abort and mark this a strange test result
|
|
Packit |
2d622a |
return (127, "")
|
|
Packit Service |
c35f72 |
out = p.stdout.read().decode().strip()
|
|
Packit |
2d622a |
return (rc, out)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def snapshot_pool_state():
|
|
Packit |
2d622a |
l = []
|
|
Packit |
2d622a |
for d in os.listdir("/sys/kernel/mm/hugepages"):
|
|
Packit |
2d622a |
substate = [(f, int(open("/sys/kernel/mm/hugepages/%s/%s" % (d, f)).read()))
|
|
Packit |
2d622a |
for f in os.listdir("/sys/kernel/mm/hugepages/%s" % d)]
|
|
Packit |
2d622a |
l.append((d, tuple(substate)))
|
|
Packit |
2d622a |
return tuple(l)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def run_test_prog(bits, pagesize, cmd, **env):
|
|
Packit |
2d622a |
if paranoid_pool_check:
|
|
Packit |
2d622a |
beforepool = snapshot_pool_state()
|
|
Packit Service |
e2dccc |
print("Pool state: %s" % str(beforepool))
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
local_env = os.environ.copy()
|
|
Packit |
2d622a |
local_env.update(env)
|
|
Packit |
2d622a |
local_env["PATH"] = "./obj%d:../obj%d:%s" \
|
|
Packit |
2d622a |
% (bits, bits, local_env.get("PATH", ""))
|
|
Packit |
2d622a |
local_env["LD_LIBRARY_PATH"] = "../obj%d:obj%d:%s" \
|
|
Packit |
2d622a |
% (bits, bits, local_env.get("LD_LIBRARY_PATH", ""))
|
|
Packit |
2d622a |
local_env["HUGETLB_DEFAULT_PAGE_SIZE"] = repr(pagesize)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
try:
|
|
Packit |
2d622a |
p = subprocess.Popen(cmd, env=local_env, stdout=subprocess.PIPE)
|
|
Packit |
2d622a |
rc = p.wait()
|
|
Packit |
2d622a |
except KeyboardInterrupt:
|
|
Packit |
2d622a |
# Abort and mark this a strange test result
|
|
Packit |
2d622a |
return (None, "")
|
|
Packit |
2d622a |
except OSError as e:
|
|
Packit |
2d622a |
return (-e.errno, "")
|
|
Packit Service |
c35f72 |
out = p.stdout.read().decode().strip()
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
if paranoid_pool_check:
|
|
Packit |
2d622a |
afterpool = snapshot_pool_state()
|
|
Packit |
2d622a |
if afterpool != beforepool:
|
|
Packit Service |
e2dccc |
print("Hugepage pool state not preserved!", file=sys.stderr)
|
|
Packit Service |
e2dccc |
print("BEFORE: %s" % str(beforepool), file=sys.stderr)
|
|
Packit Service |
e2dccc |
print("AFTER: %s" % str(afterpool), file=sys.stderr)
|
|
Packit |
2d622a |
sys.exit(98)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
return (rc, out)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def setup_env(override, defaults):
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Set up the environment for running commands in the shell.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
# All items in override are unconditionally set or unset
|
|
Packit |
2d622a |
for (var, val) in override.items():
|
|
Packit |
2d622a |
if val == None:
|
|
Packit |
2d622a |
if var in os.environ:
|
|
Packit |
2d622a |
del os.environ[var]
|
|
Packit |
2d622a |
else:
|
|
Packit |
2d622a |
os.environ[var] = val
|
|
Packit |
2d622a |
# If not already set, these variables are given default values
|
|
Packit |
2d622a |
for (var, val) in defaults.items():
|
|
Packit |
2d622a |
if var not in os.environ or os.environ[var] == "":
|
|
Packit |
2d622a |
os.environ[var] = val
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def init_results():
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Define the structure of the results matrix and initialize all results to 0.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
global R
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
for t in result_types:
|
|
Packit |
2d622a |
R[t] = {}
|
|
Packit |
2d622a |
for p in pagesizes:
|
|
Packit |
2d622a |
R[t][p] = {}
|
|
Packit |
2d622a |
for bits in (32, 64):
|
|
Packit |
2d622a |
R[t][p][bits] = 0
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def pretty_page_size(size):
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Convert a page size to a formatted string
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
Given a page size in bytes, return a string that expresses the size in
|
|
Packit |
2d622a |
a sensible unit (K, M, or G).
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
factor = 0
|
|
Packit |
2d622a |
while size > 1024:
|
|
Packit |
2d622a |
factor += 1
|
|
Packit |
2d622a |
size /= 1024
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
if factor == 0: return "%iB" % size
|
|
Packit |
2d622a |
elif factor == 1: return "%iK" % size
|
|
Packit |
2d622a |
elif factor == 2: return "%iM" % size
|
|
Packit |
2d622a |
elif factor == 3: return "%iG" % size
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def print_per_size(title, values):
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Print one line of test results
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
Print the results of a given result type on one line. The results for all
|
|
Packit |
2d622a |
page sizes and word sizes are written in a table format.
|
|
Packit |
2d622a |
"""
|
|
Packit Service |
e2dccc |
print("*%20s: " % title, end=" ")
|
|
Packit |
2d622a |
for sz in pagesizes:
|
|
Packit Service |
e2dccc |
print("%4s %4s " % (values[sz][32], values[sz][64]), end="")
|
|
Packit Service |
e2dccc |
print()
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def results_summary():
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Display a summary of the test results
|
|
Packit |
2d622a |
"""
|
|
Packit Service |
e2dccc |
print("********** TEST SUMMARY")
|
|
Packit Service |
e2dccc |
print("*%21s" % "", end=" ")
|
|
Packit Service |
e2dccc |
for p in pagesizes:
|
|
Packit Service |
e2dccc |
print("%-13s " % pretty_page_size(p), end="")
|
|
Packit Service |
e2dccc |
print()
|
|
Packit Service |
e2dccc |
print("*%21s" % "", end=" ")
|
|
Packit Service |
e2dccc |
for p in pagesizes:
|
|
Packit Service |
e2dccc |
print("32-bit 64-bit ", end="")
|
|
Packit Service |
e2dccc |
print()
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
print_per_size("Total testcases", R["total"])
|
|
Packit |
2d622a |
print_per_size("Skipped", R["skip"])
|
|
Packit |
2d622a |
print_per_size("PASS", R["pass"])
|
|
Packit |
2d622a |
print_per_size("FAIL", R["fail"])
|
|
Packit |
2d622a |
print_per_size("Killed by signal", R["signal"])
|
|
Packit |
2d622a |
print_per_size("Bad configuration", R["config"])
|
|
Packit |
2d622a |
print_per_size("Expected FAIL", R["xfail"])
|
|
Packit |
2d622a |
print_per_size("Unexpected PASS", R["xpass"])
|
|
Packit |
2d622a |
print_per_size("Test not present", R["nofile"])
|
|
Packit |
2d622a |
print_per_size("Strange test result", R["strange"])
|
|
Packit Service |
e2dccc |
print("**********")
|
|
Packit |
2d622a |
|
|
Packit Service |
95a5c0 |
def free_hpages(size=None):
|
|
Packit |
2d622a |
"""
|
|
Packit Service |
95a5c0 |
Return the number of free huge pages for a given size. If size is not
|
|
Packit Service |
95a5c0 |
passed, use the default huge page size.
|
|
Packit |
2d622a |
|
|
Packit Service |
95a5c0 |
Parse /sys/kernel/mm/hugepages/hugepages-<size-in-kB>/free_hugepages to
|
|
Packit Service |
95a5c0 |
obtain the number of free huge pages for the given page size.
|
|
Packit |
2d622a |
"""
|
|
Packit Service |
95a5c0 |
if size == None: size = system_default_hpage_size
|
|
Packit Service |
95a5c0 |
size_kb = size / 1024
|
|
Packit Service |
95a5c0 |
cmd = "cat /sys/kernel/mm/hugepages/hugepages-%dkB/free_hugepages" % size_kb
|
|
Packit Service |
95a5c0 |
(rc, out) = bash(cmd)
|
|
Packit |
2d622a |
return (rc, int(out))
|
|
Packit |
2d622a |
|
|
Packit Service |
95a5c0 |
def total_hpages(size=None):
|
|
Packit |
2d622a |
"""
|
|
Packit Service |
95a5c0 |
Return the total number of huge pages in the pool for a given size. If
|
|
Packit Service |
95a5c0 |
size is not passed, use the default huge page size.
|
|
Packit |
2d622a |
|
|
Packit Service |
95a5c0 |
Parse /sys/kernel/mm/hugepages/hugepages-<size-in-kB>/nr_hugepages to
|
|
Packit Service |
95a5c0 |
obtain the number of huge pages for the given page size.
|
|
Packit |
2d622a |
"""
|
|
Packit Service |
95a5c0 |
if size == None: size = system_default_hpage_size
|
|
Packit Service |
95a5c0 |
size_kb = size / 1024
|
|
Packit Service |
95a5c0 |
cmd = "cat /sys/kernel/mm/hugepages/hugepages-%dkB/nr_hugepages" % size_kb
|
|
Packit Service |
95a5c0 |
(rc, out) = bash(cmd)
|
|
Packit |
2d622a |
return (rc, int(out))
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def hpage_size():
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Return the size of the default huge page size in bytes.
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
Parse /proc/meminfo to obtain the default huge page size. This number is
|
|
Packit |
2d622a |
reported in Kb so multiply it by 1024 to convert it to bytes.
|
|
Packit |
2d622a |
XXX: This function is not multi-size aware yet.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
(rc, out) = bash("grep 'Hugepagesize:' /proc/meminfo | awk '{print $2}'")
|
|
Packit |
2d622a |
if out == "": out = 0
|
|
Packit |
2d622a |
out = int(out) * 1024
|
|
Packit |
2d622a |
return (rc, out)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def clear_hpages():
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Remove stale hugetlbfs files after sharing tests.
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
Traverse the mount points that are in use during testing to find left-over
|
|
Packit |
2d622a |
files that were created by the elflink sharing tests. These are not
|
|
Packit |
2d622a |
cleaned up automatically and must be removed to free up the huge pages.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
for mount in mounts:
|
|
Packit Service |
aea7d5 |
dir = mount + "/elflink-uid-" + repr(os.getuid())
|
|
Packit |
2d622a |
for root, dirs, files in os.walk(dir, topdown=False):
|
|
Packit |
2d622a |
for name in files:
|
|
Packit |
2d622a |
os.remove(os.path.join(root, name))
|
|
Packit |
2d622a |
for name in dirs:
|
|
Packit |
2d622a |
os.rmdir(os.path.join(root, name))
|
|
Packit |
2d622a |
try:
|
|
Packit |
2d622a |
os.rmdir(dir)
|
|
Packit |
2d622a |
except OSError:
|
|
Packit |
2d622a |
pass
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def get_pagesizes():
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Get a list of configured huge page sizes.
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
Use libhugetlbfs' hugeadm utility to get a list of page sizes that have
|
|
Packit |
2d622a |
active mount points and at least one huge page allocated to the pool.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
sizes = set()
|
|
Packit |
2d622a |
out = ""
|
|
Packit Service |
d8de40 |
(rc, out) = bash("hugeadm --page-sizes")
|
|
Packit Service |
c35f72 |
if rc != 0 or out == "":
|
|
Packit Service |
c35f72 |
return sizes
|
|
Packit |
2d622a |
|
|
Packit Service |
c35f72 |
for size in out.split("\n"):
|
|
Packit Service |
c35f72 |
sizes.add(int(size))
|
|
Packit |
2d622a |
return sizes
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def get_wordsizes():
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Checks for obj32 and obj64 subdirs to determine valid word sizes.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
sizes = set()
|
|
Packit |
2d622a |
if os.path.isdir("./obj32"): sizes.add(32)
|
|
Packit |
2d622a |
if os.path.isdir("./obj64"): sizes.add(64)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
return sizes
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def check_hugetlbfs_path():
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Check each combination of page size and word size for validity.
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
Some word sizes may not be valid for all page sizes. For example, a 16G
|
|
Packit |
2d622a |
page is too large to be used in a 32 bit process. Use a helper program to
|
|
Packit |
2d622a |
weed out invalid combinations and print informational messages as required.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
global wordsizes, pagesizes, mounts, wordsizes_by_pagesize
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
for p in pagesizes:
|
|
Packit |
2d622a |
okbits = []
|
|
Packit |
2d622a |
for b in wordsizes:
|
|
Packit |
2d622a |
(rc, out) = run_test_prog(b, p, "get_hugetlbfs_path")
|
|
Packit |
2d622a |
if rc == 0:
|
|
Packit |
2d622a |
okbits.append(b)
|
|
Packit |
2d622a |
mounts.append(out)
|
|
Packit |
2d622a |
if len(okbits) == 0:
|
|
Packit Service |
e2dccc |
print("run_tests.py: No mountpoints available for page size %s" %
|
|
Packit Service |
e2dccc |
pretty_page_size(p))
|
|
Packit |
2d622a |
wordsizes_by_pagesize[p] = set()
|
|
Packit |
2d622a |
continue
|
|
Packit |
2d622a |
for b in wordsizes - set(okbits):
|
|
Packit Service |
e2dccc |
print("run_tests.py: The %i bit word size is not compatible with " \
|
|
Packit Service |
e2dccc |
"%s pages" % (b, pretty_page_size(p)))
|
|
Packit |
2d622a |
wordsizes_by_pagesize[p] = set(okbits)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def check_linkhuge_tests():
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Check if the linkhuge tests are safe to run on this system.
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
Newer versions of binutils (>= 2.18) are known to be incompatible with the
|
|
Packit |
2d622a |
linkhuge tests and running them may cause unreliable behavior. Determine
|
|
Packit |
2d622a |
which word sizes can be tested with linkhuge. The others will be skipped.
|
|
Packit |
2d622a |
NOTE: The linhuge_rw tests are always safe to run and will not be skipped.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
okbits = set()
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
for bits in wordsizes:
|
|
Packit |
2d622a |
script = open('obj%d/dummy.ldscript' % bits, 'r').read()
|
|
Packit |
2d622a |
if script.count('SPECIAL') == 0:
|
|
Packit |
2d622a |
okbits.add(bits)
|
|
Packit |
2d622a |
return okbits
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def print_cmd(pagesize, bits, cmd, env):
|
|
Packit |
2d622a |
if env:
|
|
Packit Service |
e2dccc |
print(' '.join(['%s=%s' % (k, v) for k, v in env.items()]), end=" ")
|
|
Packit Service |
31fd4d |
if not isinstance(cmd, str):
|
|
Packit |
2d622a |
cmd = ' '.join(cmd)
|
|
Packit Service |
e2dccc |
print("%s (%s: %i):\t" % (cmd, pretty_page_size(pagesize), bits), end="")
|
|
Packit |
2d622a |
sys.stdout.flush()
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def run_test(pagesize, bits, cmd, **env):
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Execute a test, print the output and log the result
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
Run a test using the specified page size and word size. The parameter
|
|
Packit |
2d622a |
'pre' may contain additional environment settings and will be prepended to
|
|
Packit |
2d622a |
cmd. A line showing info about the test is printed and after completion
|
|
Packit |
2d622a |
the test output is printed. The result is recorded in the result matrix.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
global R
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
objdir = "obj%i" % bits
|
|
Packit |
2d622a |
if not os.path.isdir(objdir):
|
|
Packit |
2d622a |
return
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
print_cmd(pagesize, bits, cmd, env)
|
|
Packit |
2d622a |
(rc, out) = run_test_prog(bits, pagesize, cmd, **env)
|
|
Packit Service |
e2dccc |
print(out)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
R["total"][pagesize][bits] += 1
|
|
Packit |
2d622a |
if rc == 0: R["pass"][pagesize][bits] += 1
|
|
Packit |
2d622a |
elif rc == 1: R["config"][pagesize][bits] += 1
|
|
Packit |
2d622a |
elif rc == 2: R["fail"][pagesize][bits] += 1
|
|
Packit |
2d622a |
elif rc == 3: R["xfail"][pagesize][bits] += 1
|
|
Packit |
2d622a |
elif rc == 4: R["xpass"][pagesize][bits] += 1
|
|
Packit |
2d622a |
elif rc == -errno.ENOENT:
|
|
Packit |
2d622a |
R["nofile"][pagesize][bits] += 1
|
|
Packit |
2d622a |
elif rc < 0: R["signal"][pagesize][bits] += 1
|
|
Packit |
2d622a |
else: R["strange"][pagesize][bits] += 1
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def skip_test(pagesize, bits, cmd, **env):
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Skip a test, print test information, and log that it was skipped.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
global tot_tests, tot_skip
|
|
Packit |
2d622a |
R["total"][pagesize][bits] += 1
|
|
Packit |
2d622a |
R["skip"][pagesize][bits] += 1
|
|
Packit |
2d622a |
print_cmd(pagesize, bits, cmd, env)
|
|
Packit Service |
e2dccc |
print("SKIPPED")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def do_test(cmd, bits=None, **env):
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Run a test case, testing each page size and each indicated word size.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
if bits == None: bits = wordsizes
|
|
Packit |
2d622a |
for p in pagesizes:
|
|
Packit |
2d622a |
for b in (set(bits) & wordsizes_by_pagesize[p]):
|
|
Packit |
2d622a |
run_test(p, b, cmd, **env)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def do_test_with_rlimit(rtype, limit, cmd, bits=None, **env):
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Run a test case with a temporarily altered resource limit.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
oldlimit = resource.getrlimit(rtype)
|
|
Packit |
2d622a |
resource.setrlimit(rtype, (limit, limit))
|
|
Packit |
2d622a |
do_test(cmd, bits, **env)
|
|
Packit |
2d622a |
resource.setrlimit(rtype, oldlimit)
|
|
Packit |
2d622a |
|
|
Packit Service |
d5fae0 |
def do_test_with_pagesize(pagesize, cmd, bits=None, **env):
|
|
Packit Service |
d5fae0 |
"""
|
|
Packit Service |
d5fae0 |
Run a test case, testing with a specified huge page size and
|
|
Packit Service |
d5fae0 |
each indicated word size.
|
|
Packit Service |
d5fae0 |
"""
|
|
Packit Service |
d5fae0 |
if bits == None:
|
|
Packit Service |
d5fae0 |
bits = wordsizes
|
|
Packit Service |
d5fae0 |
for b in (set(bits) & wordsizes_by_pagesize[pagesize]):
|
|
Packit Service |
d5fae0 |
run_test(pagesize, b, cmd, **env)
|
|
Packit Service |
d5fae0 |
|
|
Packit |
2d622a |
def do_elflink_test(cmd, **env):
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Run an elflink test case, skipping known-bad configurations.
|
|
Packit |
2d622a |
"""
|
|
Packit Service |
32f346 |
for b in wordsizes_by_pagesize[system_default_hpage_size]:
|
|
Packit Service |
32f346 |
if b in linkhuge_wordsizes:
|
|
Packit Service |
32f346 |
run_test(system_default_hpage_size, b, cmd, **env)
|
|
Packit Service |
32f346 |
else:
|
|
Packit Service |
32f346 |
skip_test(system_default_hpage_size, b, cmd, **env)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def elflink_test(cmd, **env):
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Run an elflink test case with different configuration combinations.
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
Test various combinations of: preloading libhugetlbfs, B vs. BDT link
|
|
Packit |
2d622a |
modes, minimal copying on or off, and disabling segment remapping.
|
|
Packit |
2d622a |
"""
|
|
Packit Service |
32f346 |
do_test_with_pagesize(system_default_hpage_size, cmd, **env)
|
|
Packit |
2d622a |
# Test we don't blow up if not linked for hugepage
|
|
Packit Service |
32f346 |
do_test_with_pagesize(system_default_hpage_size, cmd,
|
|
Packit Service |
32f346 |
LD_PRELOAD="libhugetlbfs.so", **env)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Only run custom ldscript tests when -l option is set
|
|
Packit |
2d622a |
if not custom_ldscripts:
|
|
Packit |
2d622a |
return
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
do_elflink_test("xB." + cmd, **env)
|
|
Packit |
2d622a |
do_elflink_test("xBDT." + cmd, **env)
|
|
Packit |
2d622a |
# Test we don't blow up if HUGETLB_MINIMAL_COPY is diabled
|
|
Packit |
2d622a |
do_elflink_test("xB." + cmd, HUGETLB_MINIMAL_COPY="no", **env)
|
|
Packit |
2d622a |
do_elflink_test("xBDT." + cmd, HUGETLB_MINIMAL_COPY="no", **env)
|
|
Packit |
2d622a |
# Test that HUGETLB_ELFMAP=no inhibits remapping as intended
|
|
Packit |
2d622a |
do_elflink_test("xB." + cmd, HUGETLB_ELFMAP="no", **env)
|
|
Packit |
2d622a |
do_elflink_test("xBDT." + cmd, HUGETLB_ELFMAP="no", **env)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def elflink_rw_test(cmd, **env):
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Run the elflink_rw test with different configuration combinations.
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
Test various combinations of: remapping modes and minimal copy on or off.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
# Basic tests: None, Read-only, Write-only, Read-Write, exlicit disable
|
|
Packit Service |
32f346 |
do_test_with_pagesize(system_default_hpage_size, cmd, **env)
|
|
Packit Service |
32f346 |
do_test_with_pagesize(system_default_hpage_size, cmd,
|
|
Packit Service |
32f346 |
HUGETLB_ELFMAP="R", **env)
|
|
Packit Service |
32f346 |
do_test_with_pagesize(system_default_hpage_size, cmd,
|
|
Packit Service |
32f346 |
HUGETLB_ELFMAP="W", **env)
|
|
Packit Service |
32f346 |
do_test_with_pagesize(system_default_hpage_size, cmd,
|
|
Packit Service |
32f346 |
HUGETLB_ELFMAP="RW", **env)
|
|
Packit Service |
32f346 |
do_test_with_pagesize(system_default_hpage_size, cmd,
|
|
Packit Service |
32f346 |
HUGETLB_ELFMAP="no", **env)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Test we don't blow up if HUGETLB_MINIMAL_COPY is disabled
|
|
Packit Service |
32f346 |
do_test_with_pagesize(system_default_hpage_size, cmd,
|
|
Packit Service |
32f346 |
HUGETLB_MINIMAL_COPY="no", HUGETLB_ELFMAP="R", **env)
|
|
Packit Service |
32f346 |
do_test_with_pagesize(system_default_hpage_size, cmd,
|
|
Packit Service |
32f346 |
HUGETLB_MINIMAL_COPY="no", HUGETLB_ELFMAP="W", **env)
|
|
Packit Service |
32f346 |
do_test_with_pagesize(system_default_hpage_size, cmd,
|
|
Packit Service |
32f346 |
HUGETLB_MINIMAL_COPY="no", HUGETLB_ELFMAP="RW", **env)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def elfshare_test(cmd, **env):
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Test segment sharing with multiple configuration variations.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
# Run each elfshare test invocation independently - clean up the
|
|
Packit |
2d622a |
# sharefiles before and after in the first set of runs, but leave
|
|
Packit |
2d622a |
# them there in the second:
|
|
Packit |
2d622a |
clear_hpages()
|
|
Packit |
2d622a |
do_elflink_test("xB." + cmd, HUGETLB_SHARE="1", **env)
|
|
Packit |
2d622a |
clear_hpages()
|
|
Packit |
2d622a |
do_elflink_test("xBDT." + cmd, HUGETLB_SHARE="1", **env)
|
|
Packit |
2d622a |
clear_hpages()
|
|
Packit |
2d622a |
do_elflink_test("xB." + cmd, HUGETLB_SHARE="1", **env)
|
|
Packit |
2d622a |
do_elflink_test("xBDT." + cmd, HUGETLB_SHARE="1", **env)
|
|
Packit |
2d622a |
clear_hpages()
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def elflink_and_share_test(cmd, **env):
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Run the ordinary linkhuge tests with sharing enabled
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
# Run each elflink test pair independently - clean up the sharefiles
|
|
Packit |
2d622a |
# before and after each pair
|
|
Packit |
2d622a |
clear_hpages()
|
|
Packit |
2d622a |
for link_str in ("xB.", "xBDT."):
|
|
Packit |
2d622a |
for i in range(2):
|
|
Packit |
2d622a |
do_elflink_test(link_str + cmd, HUGETLB_SHARE=repr(i), **env)
|
|
Packit |
2d622a |
clear_hpages()
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def elflink_rw_and_share_test(cmd, **env):
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Run the ordinary linkhuge_rw tests with sharing enabled
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
clear_hpages()
|
|
Packit |
2d622a |
for mode in ("R", "W", "RW"):
|
|
Packit |
2d622a |
for i in range(2):
|
|
Packit Service |
32f346 |
do_test_with_pagesize(system_default_hpage_size, cmd,
|
|
Packit Service |
32f346 |
HUGETLB_ELFMAP=mode, HUGETLB_SHARE=repr(i),
|
|
Packit Service |
32f346 |
**env)
|
|
Packit |
2d622a |
clear_hpages()
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def setup_shm_sysctl(limit):
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Adjust the kernel shared memory limits to accomodate a desired size.
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
The original values are returned in a dictionary that can be passed to
|
|
Packit |
2d622a |
restore_shm_sysctl() to restore the system state.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
if os.getuid() != 0: return {}
|
|
Packit |
2d622a |
sysctls = {}
|
|
Packit |
2d622a |
files = [ "/proc/sys/kernel/shmmax", "/proc/sys/kernel/shmall"]
|
|
Packit |
2d622a |
for f in files:
|
|
Packit |
2d622a |
fh = open(f, "r")
|
|
Packit |
2d622a |
sysctls[f] = fh.read()
|
|
Packit |
2d622a |
fh.close()
|
|
Packit |
2d622a |
fh = open(f, "w")
|
|
Packit Service |
aea7d5 |
fh.write(repr(limit))
|
|
Packit |
2d622a |
fh.close()
|
|
Packit Service |
e2dccc |
print("set shmmax limit to %s" % limit)
|
|
Packit |
2d622a |
return sysctls
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def restore_shm_sysctl(sysctls):
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Restore the sysctls named in 'sysctls' to the given values.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
if os.getuid() != 0: return
|
|
Packit |
2d622a |
for (file, val) in sysctls.items():
|
|
Packit |
2d622a |
fh = open(file, "w")
|
|
Packit |
2d622a |
fh.write(val)
|
|
Packit |
2d622a |
fh.close()
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def do_shm_test(cmd, limit=None, bits=None, **env):
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Run a test case with temporarily expanded SysV shm limits, testing
|
|
Packit |
2d622a |
each indicated word size.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
if bits == None:
|
|
Packit |
2d622a |
bits = wordsizes
|
|
Packit |
2d622a |
if limit != None:
|
|
Packit |
2d622a |
tmp = setup_shm_sysctl(limit)
|
|
Packit |
2d622a |
for b in bits:
|
|
Packit |
2d622a |
run_test(system_default_hpage_size, b, cmd, **env)
|
|
Packit |
2d622a |
if limit != None:
|
|
Packit |
2d622a |
restore_shm_sysctl(tmp)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def functional_tests():
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Run the set of functional tests.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
global linkhuge_wordsizes
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Kernel background tests not requiring hugepage support
|
|
Packit |
2d622a |
do_test("zero_filesize_segment")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Library background tests not requiring hugepage support
|
|
Packit |
2d622a |
do_test("test_root")
|
|
Packit |
2d622a |
do_test("meminfo_nohuge")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Library tests requiring kernel hugepage support
|
|
Packit |
2d622a |
do_test("gethugepagesize")
|
|
Packit |
2d622a |
do_test("gethugepagesizes")
|
|
Packit |
2d622a |
do_test("empty_mounts", HUGETLB_VERBOSE="1")
|
|
Packit |
2d622a |
do_test("large_mounts", HUGETLB_VERBOSE="1")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Tests requiring an active and usable hugepage mount
|
|
Packit |
2d622a |
do_test("find_path")
|
|
Packit |
2d622a |
do_test("unlinked_fd")
|
|
Packit |
2d622a |
do_test("readback")
|
|
Packit |
2d622a |
do_test("truncate")
|
|
Packit |
2d622a |
do_test("shared")
|
|
Packit |
2d622a |
do_test("mprotect")
|
|
Packit |
2d622a |
do_test_with_rlimit(resource.RLIMIT_MEMLOCK, -1, "mlock")
|
|
Packit |
2d622a |
do_test("misalign")
|
|
Packit |
2d622a |
do_test("fallocate_basic.sh")
|
|
Packit |
2d622a |
do_test("fallocate_align.sh")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Specific kernel bug tests
|
|
Packit |
2d622a |
do_test("ptrace-write-hugepage")
|
|
Packit |
2d622a |
do_test("icache-hygiene")
|
|
Packit |
2d622a |
do_test("slbpacaflush")
|
|
Packit |
2d622a |
do_test("straddle_4GB_static", bits=(64,))
|
|
Packit |
2d622a |
do_test("huge_at_4GB_normal_below_static", bits=(64,))
|
|
Packit |
2d622a |
do_test("huge_below_4GB_normal_above_static", bits=(64,))
|
|
Packit |
2d622a |
do_test("map_high_truncate_2")
|
|
Packit |
2d622a |
do_test("misaligned_offset")
|
|
Packit |
2d622a |
do_test("truncate_above_4GB")
|
|
Packit |
2d622a |
do_test("brk_near_huge")
|
|
Packit |
2d622a |
do_test("task-size-overrun")
|
|
Packit |
2d622a |
do_test_with_rlimit(resource.RLIMIT_STACK, -1, "stack_grow_into_huge")
|
|
Packit |
2d622a |
do_test("corrupt-by-cow-opt")
|
|
Packit |
2d622a |
do_test("noresv-preserve-resv-page")
|
|
Packit |
2d622a |
do_test("noresv-regarded-as-resv")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
if dangerous == 1:
|
|
Packit |
2d622a |
do_test("readahead_reserve")
|
|
Packit |
2d622a |
do_test("madvise_reserve")
|
|
Packit |
2d622a |
do_test("fadvise_reserve")
|
|
Packit |
2d622a |
do_test("mremap-expand-slice-collision")
|
|
Packit |
2d622a |
do_test("mremap-fixed-normal-near-huge")
|
|
Packit |
2d622a |
do_test("mremap-fixed-huge-near-normal")
|
|
Packit |
2d622a |
else:
|
|
Packit |
2d622a |
do_test("readahead_reserve.sh")
|
|
Packit |
2d622a |
do_test("madvise_reserve.sh")
|
|
Packit |
2d622a |
do_test("fadvise_reserve.sh")
|
|
Packit |
2d622a |
do_test("mremap-expand-slice-collision.sh")
|
|
Packit |
2d622a |
do_test("mremap-fixed-normal-near-huge.sh")
|
|
Packit |
2d622a |
do_test("mremap-fixed-huge-near-normal.sh")
|
|
Packit Service |
a44172 |
do_shm_test("shm-perms", 1024*1024*1024)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Tests requiring an active mount and hugepage COW
|
|
Packit |
2d622a |
do_test("private")
|
|
Packit |
2d622a |
do_test("fork-cow")
|
|
Packit |
2d622a |
do_test("direct")
|
|
Packit Service |
d5fae0 |
do_test_with_pagesize(system_default_hpage_size, "malloc")
|
|
Packit Service |
d5fae0 |
do_test_with_pagesize(system_default_hpage_size, "malloc",
|
|
Packit Service |
d5fae0 |
LD_PRELOAD="libhugetlbfs.so",
|
|
Packit Service |
d5fae0 |
HUGETLB_MORECORE="yes")
|
|
Packit Service |
d5fae0 |
do_test_with_pagesize(system_default_hpage_size, "malloc",
|
|
Packit Service |
d5fae0 |
LD_PRELOAD="libhugetlbfs.so",
|
|
Packit Service |
d5fae0 |
HUGETLB_MORECORE="yes",
|
|
Packit Service |
d5fae0 |
HUGETLB_RESTRICT_EXE="unknown:none")
|
|
Packit Service |
d5fae0 |
do_test_with_pagesize(system_default_hpage_size, "malloc",
|
|
Packit Service |
d5fae0 |
LD_PRELOAD="libhugetlbfs.so",
|
|
Packit Service |
d5fae0 |
HUGETLB_MORECORE="yes",
|
|
Packit Service |
d5fae0 |
HUGETLB_RESTRICT_EXE="unknown:malloc")
|
|
Packit Service |
d5fae0 |
do_test_with_pagesize(system_default_hpage_size, "malloc_manysmall")
|
|
Packit Service |
d5fae0 |
do_test_with_pagesize(system_default_hpage_size, "malloc_manysmall",
|
|
Packit Service |
d5fae0 |
LD_PRELOAD="libhugetlbfs.so",
|
|
Packit Service |
d5fae0 |
HUGETLB_MORECORE="yes")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# After upstream commit: (glibc-2.25.90-688-gd5c3fafc43) glibc has a
|
|
Packit |
2d622a |
# new per-thread caching mechanism that will NOT allow heapshrink test to
|
|
Packit |
2d622a |
# successfully measure if heap has shrunk or not due to the fact that
|
|
Packit |
2d622a |
# heap won't have its sized reduced right away.
|
|
Packit |
2d622a |
#
|
|
Packit |
2d622a |
# In order to disable it, you need to have the tunable GLIBC in place.
|
|
Packit |
2d622a |
# Unfortunately, it requires to be set before program is loaded, as an
|
|
Packit |
2d622a |
# environment variable, since we can't re-initialize malloc() from the
|
|
Packit |
2d622a |
# program context (not even with a constructor function), and the tunable
|
|
Packit |
2d622a |
# is only evaluated during malloc() initialization.
|
|
Packit |
2d622a |
|
|
Packit Service |
d5fae0 |
do_test_with_pagesize(system_default_hpage_size, "heapshrink",
|
|
Packit Service |
d5fae0 |
GLIBC_TUNABLES="glibc.malloc.tcache_count=0")
|
|
Packit Service |
d5fae0 |
do_test_with_pagesize(system_default_hpage_size, "heapshrink",
|
|
Packit Service |
d5fae0 |
GLIBC_TUNABLES="glibc.malloc.tcache_count=0",
|
|
Packit Service |
d5fae0 |
LD_PRELOAD="libheapshrink.so")
|
|
Packit Service |
d5fae0 |
do_test_with_pagesize(system_default_hpage_size, "heapshrink",
|
|
Packit Service |
d5fae0 |
GLIBC_TUNABLES="glibc.malloc.tcache_count=0",
|
|
Packit Service |
d5fae0 |
LD_PRELOAD="libhugetlbfs.so",
|
|
Packit Service |
d5fae0 |
HUGETLB_MORECORE="yes")
|
|
Packit Service |
d5fae0 |
do_test_with_pagesize(system_default_hpage_size, "heapshrink",
|
|
Packit Service |
d5fae0 |
GLIBC_TUNABLES="glibc.malloc.tcache_count=0",
|
|
Packit Service |
d5fae0 |
LD_PRELOAD="libhugetlbfs.so libheapshrink.so",
|
|
Packit Service |
d5fae0 |
HUGETLB_MORECORE="yes")
|
|
Packit Service |
d5fae0 |
do_test_with_pagesize(system_default_hpage_size, "heapshrink",
|
|
Packit Service |
d5fae0 |
GLIBC_TUNABLES="glibc.malloc.tcache_count=0",
|
|
Packit Service |
d5fae0 |
LD_PRELOAD="libheapshrink.so",
|
|
Packit Service |
d5fae0 |
HUGETLB_MORECORE="yes",
|
|
Packit Service |
d5fae0 |
HUGETLB_MORECORE_SHRINK="yes")
|
|
Packit Service |
d5fae0 |
do_test_with_pagesize(system_default_hpage_size, "heapshrink",
|
|
Packit Service |
d5fae0 |
GLIBC_TUNABLES="glibc.malloc.tcache_count=0",
|
|
Packit Service |
d5fae0 |
LD_PRELOAD="libhugetlbfs.so libheapshrink.so",
|
|
Packit Service |
d5fae0 |
HUGETLB_MORECORE="yes",
|
|
Packit Service |
d5fae0 |
HUGETLB_MORECORE_SHRINK="yes")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
do_test("heap-overflow", HUGETLB_VERBOSE="1", HUGETLB_MORECORE="yes")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Run the remapping tests' up-front checks
|
|
Packit |
2d622a |
linkhuge_wordsizes = check_linkhuge_tests()
|
|
Packit |
2d622a |
# Original elflink tests
|
|
Packit |
2d622a |
elflink_test("linkhuge_nofd", HUGETLB_VERBOSE="0")
|
|
Packit |
2d622a |
elflink_test("linkhuge")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Only run custom ldscript tests when -l option is set
|
|
Packit |
2d622a |
if custom_ldscripts:
|
|
Packit |
2d622a |
# Original elflink sharing tests
|
|
Packit |
2d622a |
elfshare_test("linkshare")
|
|
Packit |
2d622a |
elflink_and_share_test("linkhuge")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# elflink_rw tests
|
|
Packit |
2d622a |
elflink_rw_test("linkhuge_rw")
|
|
Packit |
2d622a |
# elflink_rw sharing tests
|
|
Packit |
2d622a |
elflink_rw_and_share_test("linkhuge_rw")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Accounting bug tests
|
|
Packit |
2d622a |
# reset free hpages because sharing will have held some
|
|
Packit |
2d622a |
# alternatively, use
|
|
Packit |
2d622a |
do_test("chunk-overcommit")
|
|
Packit |
2d622a |
do_test(("alloc-instantiate-race", "shared"))
|
|
Packit |
2d622a |
do_test(("alloc-instantiate-race", "private"))
|
|
Packit |
2d622a |
do_test("truncate_reserve_wraparound")
|
|
Packit |
2d622a |
do_test("truncate_sigbus_versus_oom")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Test direct allocation API
|
|
Packit |
2d622a |
do_test("get_huge_pages")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Test overriding of shmget()
|
|
Packit |
2d622a |
do_shm_test("shmoverride_linked")
|
|
Packit |
2d622a |
do_shm_test("shmoverride_linked", HUGETLB_SHM="yes")
|
|
Packit |
2d622a |
do_shm_test("shmoverride_linked_static")
|
|
Packit |
2d622a |
do_shm_test("shmoverride_linked_static", HUGETLB_SHM="yes")
|
|
Packit |
2d622a |
do_shm_test("shmoverride_unlinked", LD_PRELOAD="libhugetlbfs.so")
|
|
Packit |
2d622a |
do_shm_test("shmoverride_unlinked", LD_PRELOAD="libhugetlbfs.so", HUGETLB_SHM="yes")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Test hugetlbfs filesystem quota accounting
|
|
Packit |
2d622a |
do_test("quota.sh")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Test accounting of HugePages_{Total|Free|Resv|Surp}
|
|
Packit |
2d622a |
# Alters the size of the hugepage pool so should probably be run last
|
|
Packit |
2d622a |
do_test("counters.sh")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def stress_tests():
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
Run the set of stress tests.
|
|
Packit |
2d622a |
"""
|
|
Packit |
2d622a |
iterations = 10 # Number of iterations for looping tests
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Don't update NRPAGES every time like above because we want to catch the
|
|
Packit |
2d622a |
# failures that happen when the kernel doesn't release all of the huge pages
|
|
Packit |
2d622a |
# after a stress test terminates
|
|
Packit Service |
608474 |
nr_pages = {p: free_hpages(p)[1] for p in pagesizes}
|
|
Packit |
2d622a |
|
|
Packit Service |
608474 |
for p in pagesizes:
|
|
Packit Service |
608474 |
cmd = ("mmap-gettest", repr(iterations), repr(nr_pages[p]))
|
|
Packit Service |
608474 |
do_test_with_pagesize(p, cmd)
|
|
Packit |
2d622a |
|
|
Packit Service |
608474 |
for p in pagesizes:
|
|
Packit Service |
608474 |
# mmap-cow needs a hugepage for each thread plus one extra
|
|
Packit Service |
608474 |
cmd = ("mmap-cow", repr(nr_pages[p]-1), repr(nr_pages[p]))
|
|
Packit Service |
608474 |
do_test_with_pagesize(p, cmd)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
(rc, tot_pages) = total_hpages()
|
|
Packit Service |
608474 |
nr_pages = nr_pages[system_default_hpage_size]
|
|
Packit |
2d622a |
limit = system_default_hpage_size * tot_pages
|
|
Packit |
2d622a |
threads = 10 # Number of threads for shm-fork
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
# Run shm-fork once using half available hugepages, then once using all
|
|
Packit |
2d622a |
# This is to catch off-by-ones or races in the kernel allocated that
|
|
Packit |
2d622a |
# can make allocating all hugepages a problem
|
|
Packit |
2d622a |
if nr_pages > 1:
|
|
Packit Service |
46f680 |
do_shm_test(("shm-fork", repr(threads), repr(nr_pages // 2)), limit)
|
|
Packit |
2d622a |
do_shm_test(("shm-fork", repr(threads), repr(nr_pages)), limit)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
do_shm_test(("shm-getraw", repr(nr_pages), "/dev/full"), limit)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
do_test("fallocate_stress.sh")
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def print_help():
|
|
Packit Service |
e2dccc |
print("Usage: %s [options]" % sys.argv[0])
|
|
Packit Service |
e2dccc |
print("Options:")
|
|
Packit Service |
e2dccc |
print(" -v \t Verbose output.")
|
|
Packit Service |
e2dccc |
print(" -V \t Highly verbose output.")
|
|
Packit Service |
e2dccc |
print(" -f \t Force all tests.")
|
|
Packit Service |
e2dccc |
print(" -t <set> Run test set, allowed are func and stress.")
|
|
Packit Service |
e2dccc |
print(" -b <wordsize> Define wordsizes to be used. ")
|
|
Packit Service |
e2dccc |
print(" -p <pagesize> Define the page sizes to be used.")
|
|
Packit Service |
e2dccc |
print(" -c \t Do a paranoid pool check.")
|
|
Packit Service |
e2dccc |
print(" -l \t Use custom ld scripts.")
|
|
Packit Service |
e2dccc |
print(" -h \t This help.")
|
|
Packit |
2d622a |
sys.exit(0)
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
def main():
|
|
Packit |
2d622a |
global wordsizes, pagesizes, dangerous, paranoid_pool_check, system_default_hpage_size
|
|
Packit |
2d622a |
global custom_ldscripts
|
|
Packit |
2d622a |
testsets = set()
|
|
Packit |
2d622a |
env_override = {"QUIET_TEST": "1", "HUGETLBFS_MOUNTS": "",
|
|
Packit |
2d622a |
"HUGETLB_ELFMAP": None, "HUGETLB_MORECORE": None}
|
|
Packit |
2d622a |
env_defaults = {"HUGETLB_VERBOSE": "0"}
|
|
Packit |
2d622a |
dangerous = 0
|
|
Packit |
2d622a |
paranoid_pool_check = False
|
|
Packit |
2d622a |
custom_ldscripts = False
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
try:
|
|
Packit |
2d622a |
opts, args = getopt.getopt(sys.argv[1:], "vVft:b:p:c:lh")
|
|
Packit Service |
fd4cdd |
except getopt.GetoptError as err:
|
|
Packit Service |
e2dccc |
print(str(err))
|
|
Packit |
2d622a |
sys.exit(1)
|
|
Packit |
2d622a |
for opt, arg in opts:
|
|
Packit |
2d622a |
if opt == "-v":
|
|
Packit |
2d622a |
env_override["QUIET_TEST"] = None
|
|
Packit |
2d622a |
env_defaults["HUGETLB_VERBOSE"] = "2"
|
|
Packit |
2d622a |
elif opt == "-V":
|
|
Packit |
2d622a |
env_defaults["HUGETLB_VERBOSE"] = "99"
|
|
Packit |
2d622a |
elif opt == "-f":
|
|
Packit |
2d622a |
dangerous = 1
|
|
Packit |
2d622a |
elif opt == "-t":
|
|
Packit |
2d622a |
for t in arg.split(): testsets.add(t)
|
|
Packit |
2d622a |
elif opt == "-b":
|
|
Packit |
2d622a |
for b in arg.split(): wordsizes.add(int(b))
|
|
Packit |
2d622a |
elif opt == "-p":
|
|
Packit |
2d622a |
for p in arg.split(): pagesizes.add(int(p))
|
|
Packit |
2d622a |
elif opt == '-c':
|
|
Packit |
2d622a |
paranoid_pool_check = True
|
|
Packit |
2d622a |
elif opt == '-l':
|
|
Packit |
2d622a |
custom_ldscripts = True
|
|
Packit |
2d622a |
elif opt == '-h':
|
|
Packit |
2d622a |
print_help()
|
|
Packit |
2d622a |
else:
|
|
Packit |
2d622a |
assert False, "unhandled option"
|
|
Packit |
2d622a |
if len(testsets) == 0: testsets = set(["func", "stress"])
|
|
Packit |
2d622a |
if len(wordsizes) == 0: wordsizes = get_wordsizes()
|
|
Packit |
2d622a |
if len(pagesizes) == 0: pagesizes = get_pagesizes()
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
if len(pagesizes) == 0:
|
|
Packit Service |
e2dccc |
print("Unable to find available page sizes, are you sure hugetlbfs")
|
|
Packit Service |
e2dccc |
print("is mounted and there are available huge pages?")
|
|
Packit |
2d622a |
return 1
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
setup_env(env_override, env_defaults)
|
|
Packit |
2d622a |
init_results()
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
(rc, system_default_hpage_size) = hpage_size()
|
|
Packit |
2d622a |
if rc != 0:
|
|
Packit Service |
e2dccc |
print("Unable to find system default hugepage size.")
|
|
Packit Service |
e2dccc |
print("Is hugepage supported included in this kernel?")
|
|
Packit |
2d622a |
return 1
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
check_hugetlbfs_path()
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
if "func" in testsets: functional_tests()
|
|
Packit |
2d622a |
if "stress" in testsets: stress_tests()
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
results_summary()
|
|
Packit |
2d622a |
|
|
Packit |
2d622a |
if __name__ == "__main__":
|
|
Packit |
2d622a |
main()
|