Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1#!/bin/bash
2# Copyright (c) 2016 Microsemi. All Rights Reserved.
3#
4# This program is free software; you can redistribute it and/or
5# modify it under the terms of the GNU General Public License as
6# published by the Free Software Foundation; either version 2 of
7# the License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it would be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# Author: Logan Gunthorpe <logang@deltatee.com>
15
16REMOTE_HOST=
17LIST_DEVS=FALSE
18
19DEBUGFS=${DEBUGFS-/sys/kernel/debug}
20
21DB_BITMASK=0x7FFF
22PERF_RUN_ORDER=32
23MAX_MW_SIZE=0
24RUN_DMA_TESTS=
25DONT_CLEANUP=
26MW_SIZE=65536
27
28function show_help()
29{
30 echo "Usage: $0 [OPTIONS] LOCAL_DEV REMOTE_DEV"
31 echo "Run tests on a pair of NTB endpoints."
32 echo
33 echo "If the NTB device loops back to the same host then,"
34 echo "just specifying the two PCI ids on the command line is"
35 echo "sufficient. Otherwise, if the NTB link spans two hosts"
36 echo "use the -r option to specify the hostname for the remote"
37 echo "device. SSH will then be used to test the remote side."
38 echo "An SSH key between the root users of the host would then"
39 echo "be highly recommended."
40 echo
41 echo "Options:"
42 echo " -b BITMASK doorbell clear bitmask for ntb_tool"
43 echo " -C don't cleanup ntb modules on exit"
44 echo " -d run dma tests"
45 echo " -h show this help message"
46 echo " -l list available local and remote PCI ids"
47 echo " -r REMOTE_HOST specify the remote's hostname to connect"
48 echo " to for the test (using ssh)"
49 echo " -p NUM ntb_perf run order (default: $PERF_RUN_ORDER)"
50 echo " -w max_mw_size maxmium memory window size"
51 echo
52}
53
54function parse_args()
55{
56 OPTIND=0
57 while getopts "b:Cdhlm:r:p:w:" opt; do
58 case "$opt" in
59 b) DB_BITMASK=${OPTARG} ;;
60 C) DONT_CLEANUP=1 ;;
61 d) RUN_DMA_TESTS=1 ;;
62 h) show_help; exit 0 ;;
63 l) LIST_DEVS=TRUE ;;
64 m) MW_SIZE=${OPTARG} ;;
65 r) REMOTE_HOST=${OPTARG} ;;
66 p) PERF_RUN_ORDER=${OPTARG} ;;
67 w) MAX_MW_SIZE=${OPTARG} ;;
68 \?)
69 echo "Invalid option: -$OPTARG" >&2
70 exit 1
71 ;;
72 esac
73 done
74}
75
76parse_args "$@"
77shift $((OPTIND-1))
78LOCAL_DEV=$1
79shift
80parse_args "$@"
81shift $((OPTIND-1))
82REMOTE_DEV=$1
83shift
84parse_args "$@"
85
86set -e
87
88function _modprobe()
89{
90 modprobe "$@"
91
92 if [[ "$REMOTE_HOST" != "" ]]; then
93 ssh "$REMOTE_HOST" modprobe "$@"
94 fi
95}
96
97function split_remote()
98{
99 VPATH=$1
100 REMOTE=
101
102 if [[ "$VPATH" == *":/"* ]]; then
103 REMOTE=${VPATH%%:*}
104 VPATH=${VPATH#*:}
105 fi
106}
107
108function read_file()
109{
110 split_remote $1
111 if [[ "$REMOTE" != "" ]]; then
112 ssh "$REMOTE" cat "$VPATH"
113 else
114 cat "$VPATH"
115 fi
116}
117
118function write_file()
119{
120 split_remote $2
121 VALUE=$1
122
123 if [[ "$REMOTE" != "" ]]; then
124 ssh "$REMOTE" "echo \"$VALUE\" > \"$VPATH\""
125 else
126 echo "$VALUE" > "$VPATH"
127 fi
128}
129
130function link_test()
131{
132 LOC=$1
133 REM=$2
134 EXP=0
135
136 echo "Running link tests on: $(basename $LOC) / $(basename $REM)"
137
138 if ! write_file "N" "$LOC/link" 2> /dev/null; then
139 echo " Unsupported"
140 return
141 fi
142
143 write_file "N" "$LOC/link_event"
144
145 if [[ $(read_file "$REM/link") != "N" ]]; then
146 echo "Expected remote link to be down in $REM/link" >&2
147 exit -1
148 fi
149
150 write_file "Y" "$LOC/link"
151 write_file "Y" "$LOC/link_event"
152
153 echo " Passed"
154}
155
156function doorbell_test()
157{
158 LOC=$1
159 REM=$2
160 EXP=0
161
162 echo "Running db tests on: $(basename $LOC) / $(basename $REM)"
163
164 write_file "c $DB_BITMASK" "$REM/db"
165
166 for ((i=1; i <= 8; i++)); do
167 let DB=$(read_file "$REM/db") || true
168 if [[ "$DB" != "$EXP" ]]; then
169 echo "Doorbell doesn't match expected value $EXP " \
170 "in $REM/db" >&2
171 exit -1
172 fi
173
174 let "MASK=1 << ($i-1)" || true
175 let "EXP=$EXP | $MASK" || true
176 write_file "s $MASK" "$LOC/peer_db"
177 done
178
179 echo " Passed"
180}
181
182function read_spad()
183{
184 VPATH=$1
185 IDX=$2
186
187 ROW=($(read_file "$VPATH" | grep -e "^$IDX"))
188 let VAL=${ROW[1]} || true
189 echo $VAL
190}
191
192function scratchpad_test()
193{
194 LOC=$1
195 REM=$2
196 CNT=$(read_file "$LOC/spad" | wc -l)
197
198 echo "Running spad tests on: $(basename $LOC) / $(basename $REM)"
199
200 for ((i = 0; i < $CNT; i++)); do
201 VAL=$RANDOM
202 write_file "$i $VAL" "$LOC/peer_spad"
203 RVAL=$(read_spad "$REM/spad" $i)
204
205 if [[ "$VAL" != "$RVAL" ]]; then
206 echo "Scratchpad doesn't match expected value $VAL " \
207 "in $REM/spad, got $RVAL" >&2
208 exit -1
209 fi
210
211 done
212
213 echo " Passed"
214}
215
216function write_mw()
217{
218 split_remote $2
219
220 if [[ "$REMOTE" != "" ]]; then
221 ssh "$REMOTE" \
222 dd if=/dev/urandom "of=$VPATH" 2> /dev/null || true
223 else
224 dd if=/dev/urandom "of=$VPATH" 2> /dev/null || true
225 fi
226}
227
228function mw_test()
229{
230 IDX=$1
231 LOC=$2
232 REM=$3
233
234 echo "Running $IDX tests on: $(basename $LOC) / $(basename $REM)"
235
236 write_mw "$LOC/$IDX"
237
238 split_remote "$LOC/$IDX"
239 if [[ "$REMOTE" == "" ]]; then
240 A=$VPATH
241 else
242 A=/tmp/ntb_test.$$.A
243 ssh "$REMOTE" cat "$VPATH" > "$A"
244 fi
245
246 split_remote "$REM/peer_$IDX"
247 if [[ "$REMOTE" == "" ]]; then
248 B=$VPATH
249 else
250 B=/tmp/ntb_test.$$.B
251 ssh "$REMOTE" cat "$VPATH" > "$B"
252 fi
253
254 cmp -n $MW_SIZE "$A" "$B"
255 if [[ $? != 0 ]]; then
256 echo "Memory window $MW did not match!" >&2
257 fi
258
259 if [[ "$A" == "/tmp/*" ]]; then
260 rm "$A"
261 fi
262
263 if [[ "$B" == "/tmp/*" ]]; then
264 rm "$B"
265 fi
266
267 echo " Passed"
268}
269
270function pingpong_test()
271{
272 LOC=$1
273 REM=$2
274
275 echo "Running ping pong tests on: $(basename $LOC) / $(basename $REM)"
276
277 LOC_START=$(read_file $LOC/count)
278 REM_START=$(read_file $REM/count)
279
280 sleep 7
281
282 LOC_END=$(read_file $LOC/count)
283 REM_END=$(read_file $REM/count)
284
285 if [[ $LOC_START == $LOC_END ]] || [[ $REM_START == $REM_END ]]; then
286 echo "Ping pong counter not incrementing!" >&2
287 exit 1
288 fi
289
290 echo " Passed"
291}
292
293function perf_test()
294{
295 USE_DMA=$1
296
297 if [[ $USE_DMA == "1" ]]; then
298 WITH="with"
299 else
300 WITH="without"
301 fi
302
303 _modprobe ntb_perf run_order=$PERF_RUN_ORDER \
304 max_mw_size=$MAX_MW_SIZE use_dma=$USE_DMA
305
306 echo "Running local perf test $WITH DMA"
307 write_file "" $LOCAL_PERF/run
308 echo -n " "
309 read_file $LOCAL_PERF/run
310 echo " Passed"
311
312 echo "Running remote perf test $WITH DMA"
313 write_file "" $REMOTE_PERF/run
314 echo -n " "
315 read_file $REMOTE_PERF/run
316 echo " Passed"
317
318 _modprobe -r ntb_perf
319}
320
321function ntb_tool_tests()
322{
323 LOCAL_TOOL=$DEBUGFS/ntb_tool/$LOCAL_DEV
324 REMOTE_TOOL=$REMOTE_HOST:$DEBUGFS/ntb_tool/$REMOTE_DEV
325
326 echo "Starting ntb_tool tests..."
327
328 _modprobe ntb_tool
329
330 write_file Y $LOCAL_TOOL/link_event
331 write_file Y $REMOTE_TOOL/link_event
332
333 link_test $LOCAL_TOOL $REMOTE_TOOL
334 link_test $REMOTE_TOOL $LOCAL_TOOL
335
336 for PEER_TRANS in $(ls $LOCAL_TOOL/peer_trans*); do
337 PT=$(basename $PEER_TRANS)
338 write_file $MW_SIZE $LOCAL_TOOL/$PT
339 write_file $MW_SIZE $REMOTE_TOOL/$PT
340 done
341
342 doorbell_test $LOCAL_TOOL $REMOTE_TOOL
343 doorbell_test $REMOTE_TOOL $LOCAL_TOOL
344 scratchpad_test $LOCAL_TOOL $REMOTE_TOOL
345 scratchpad_test $REMOTE_TOOL $LOCAL_TOOL
346
347 for MW in $(ls $LOCAL_TOOL/mw*); do
348 MW=$(basename $MW)
349
350 mw_test $MW $LOCAL_TOOL $REMOTE_TOOL
351 mw_test $MW $REMOTE_TOOL $LOCAL_TOOL
352 done
353
354 _modprobe -r ntb_tool
355}
356
357function ntb_pingpong_tests()
358{
359 LOCAL_PP=$DEBUGFS/ntb_pingpong/$LOCAL_DEV
360 REMOTE_PP=$REMOTE_HOST:$DEBUGFS/ntb_pingpong/$REMOTE_DEV
361
362 echo "Starting ntb_pingpong tests..."
363
364 _modprobe ntb_pingpong
365
366 pingpong_test $LOCAL_PP $REMOTE_PP
367
368 _modprobe -r ntb_pingpong
369}
370
371function ntb_perf_tests()
372{
373 LOCAL_PERF=$DEBUGFS/ntb_perf/$LOCAL_DEV
374 REMOTE_PERF=$REMOTE_HOST:$DEBUGFS/ntb_perf/$REMOTE_DEV
375
376 echo "Starting ntb_perf tests..."
377
378 perf_test 0
379
380 if [[ $RUN_DMA_TESTS ]]; then
381 perf_test 1
382 fi
383}
384
385function cleanup()
386{
387 set +e
388 _modprobe -r ntb_tool 2> /dev/null
389 _modprobe -r ntb_perf 2> /dev/null
390 _modprobe -r ntb_pingpong 2> /dev/null
391 _modprobe -r ntb_transport 2> /dev/null
392 set -e
393}
394
395cleanup
396
397if ! [[ $$DONT_CLEANUP ]]; then
398 trap cleanup EXIT
399fi
400
401if [ "$(id -u)" != "0" ]; then
402 echo "This script must be run as root" 1>&2
403 exit 1
404fi
405
406if [[ "$LIST_DEVS" == TRUE ]]; then
407 echo "Local Devices:"
408 ls -1 /sys/bus/ntb/devices
409 echo
410
411 if [[ "$REMOTE_HOST" != "" ]]; then
412 echo "Remote Devices:"
413 ssh $REMOTE_HOST ls -1 /sys/bus/ntb/devices
414 fi
415
416 exit 0
417fi
418
419if [[ "$LOCAL_DEV" == $"" ]] || [[ "$REMOTE_DEV" == $"" ]]; then
420 show_help
421 exit 1
422fi
423
424ntb_tool_tests
425echo
426ntb_pingpong_tests
427echo
428ntb_perf_tests
429echo