Skip to content

Commit c1d24eb

Browse files
committed
test: Import dlpar test scripts
1 parent ce260df commit c1d24eb

File tree

2 files changed

+214
-0
lines changed

2 files changed

+214
-0
lines changed

scripts/test/dlpar

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
import sys
5+
from glob import glob
6+
from subprocess import run
7+
from random import randint
8+
9+
10+
def main(args):
11+
print('Kernel version: ', end=None)
12+
run(['uname', '-a'], check=True)
13+
14+
rc = True
15+
rc &= memory_dlpar()
16+
rc &= cpu_dlpar()
17+
18+
if rc:
19+
print('Finished test OK')
20+
21+
return rc
22+
23+
24+
def memory_dlpar():
25+
print('========================================')
26+
print(' Memory')
27+
print('========================================')
28+
run(['free'])
29+
30+
print('Offlining memory ...')
31+
if not dlpar_write('memory remove count 100'):
32+
print('Error: failed removing memory')
33+
return False
34+
35+
run(['free'])
36+
print('-> Onlining memory ...')
37+
if not dlpar_write('memory add count 100'):
38+
print('Error: failed adding memory')
39+
return False
40+
41+
print('Offlining until failure ...')
42+
i = 0
43+
while True:
44+
if not dlpar_write('memory remove count 10'):
45+
break
46+
47+
i += 1
48+
49+
print(f'Removed {i*10} LMBs before failure')
50+
51+
print(f'Onlining {i} x 10 LMBs')
52+
while i > 0:
53+
if not dlpar_write('memory add count 10'):
54+
print('Error onlining LMBs?')
55+
56+
i -= 1
57+
58+
return True
59+
60+
61+
def cpu_dlpar():
62+
print('========================================')
63+
print(' CPUs')
64+
print('========================================')
65+
66+
nproc = int(run(['nproc'], capture_output=True, check=True).stdout)
67+
print(f'nproc before: {nproc}')
68+
69+
# FIXME detect this for P9 LPAR
70+
threads_per_core = 8
71+
# Offline all but 1 core
72+
num_cores = int((nproc / threads_per_core) - 1)
73+
74+
drcs = lookup_drcs(num_cores, nproc, threads_per_core)
75+
if not drcs:
76+
return False
77+
78+
for i in range(0, 11):
79+
expected = nproc - (num_cores * threads_per_core)
80+
if not cpu_dlpar_once(num_cores, nproc, expected, drcs):
81+
return False
82+
83+
num_cores = randint(1, 7)
84+
85+
if i == 0:
86+
print('Doing loop to stress refcounting ...')
87+
88+
return True
89+
90+
91+
def cpu_dlpar_once(num_cores, nproc_before, expected, drcs):
92+
def repair():
93+
print("Trying to re-online cores ...")
94+
for drc in drcs:
95+
dlpar_write(f'cpu add index 0x{drc:x}')
96+
97+
print(f'Removing {num_cores} cores ...')
98+
for i in range(0, num_cores):
99+
drc = drcs[i]
100+
if not dlpar_write(f'cpu remove index 0x{drc:x}'):
101+
print(f'Error: failed DLPAR removing {i}th core with drc 0x{drc:x}')
102+
repair()
103+
return False
104+
105+
nproc_after = int(run(['nproc'], capture_output=True, check=True).stdout)
106+
print(f'nproc after offline: {nproc_after}')
107+
108+
if nproc_after != expected:
109+
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
110+
print(f' Error: nproc != {expected} after offlining?!')
111+
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
112+
repair()
113+
return False
114+
115+
print(f'Onlining {num_cores} cores ...')
116+
117+
for i in range(0, num_cores):
118+
drc = drcs[i]
119+
if not dlpar_write(f'cpu add index 0x{drc:x}'):
120+
print(f'Error: failed DLPAR adding {i}th core with drc 0x{drc:x}, continuing')
121+
122+
nproc_after = int(run(['nproc'], capture_output=True, check=True).stdout)
123+
print(f'nproc after online: {nproc_after}')
124+
125+
if nproc_after != nproc_before:
126+
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
127+
print(f' Error: nproc != {nproc_before} after onlining?!')
128+
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
129+
return False
130+
131+
return True
132+
133+
134+
def lookup_drcs(num_cores, nproc, threads_per_core):
135+
# Skip core 0, it sometimes fails removal
136+
i = threads_per_core
137+
drcs = []
138+
while len(drcs) < num_cores and i < nproc:
139+
path = f'/proc/device-tree/cpus/*@{i:x}/ibm,my-drc-index'
140+
141+
i += threads_per_core
142+
143+
matches = glob(path)
144+
if not len(matches):
145+
continue
146+
147+
path = matches[0]
148+
p = run(f'od -A none -t x1 {path}'.split(), capture_output=True, check=True)
149+
drc = p.stdout.decode('utf-8').strip()
150+
drc = drc.replace(' ', '')
151+
drc = int(drc, 16)
152+
drcs.append(drc)
153+
154+
if len(drcs) != num_cores:
155+
print(f'Error: unable to find enough DRCs? Got {len(drcs)}')
156+
return None
157+
158+
return drcs
159+
160+
161+
def dlpar_write(s, warn=True):
162+
try:
163+
f = open('/sys/kernel/dlpar', 'w')
164+
f.write(s)
165+
f.close()
166+
except Exception as e:
167+
print(f"DLAPR write of '{s}' failed with '{e}'")
168+
return False
169+
else:
170+
return True
171+
172+
173+
sys.exit(0 if main(sys.argv[1:]) else 1)

scripts/test/remote-dlpar

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/bin/bash
2+
3+
set -o pipefail
4+
5+
hostname=$1
6+
7+
if [[ $hostname != *@* ]]; then
8+
hostname="root@$hostname"
9+
fi
10+
11+
script_base=$(realpath $(dirname $0))
12+
13+
DEST_DIR=/var/tmp/ngci
14+
timeout -v 1m rsync -azL --rsync-path="mkdir -p $DEST_DIR && rsync" \
15+
"$script_base/dlpar" "$hostname:$DEST_DIR/"
16+
17+
if [[ $? -ne 0 ]]; then
18+
echo "Failed rsyncing test to $hostname!" >&2
19+
exit 1
20+
fi
21+
22+
timeout -v -k 30s 1h ssh $hostname <<EOF | tee test.log
23+
set -$-
24+
echo -n "-> Running on: "
25+
uname -a
26+
echo 'ngci: dlpar test starting' > /dev/kmsg
27+
cd /var/tmp/ngci/
28+
./dlpar
29+
echo 'ngci: dlpar test finishing' > /dev/kmsg
30+
echo "-> Finished OK"
31+
EOF
32+
33+
rc=$?
34+
35+
if [[ $rc -eq 0 ]]; then
36+
echo "OK"
37+
else
38+
echo "Error: Something failed!"
39+
fi
40+
41+
exit $rc

0 commit comments

Comments
 (0)