Linux 4.19.133
[linux/fpc-iii.git] / tools / testing / selftests / ntb / ntb_test.sh
blob17ca36403d04ca5e199d8202c10708ce71d5a3b4
1 #!/bin/bash
2 # Copyright (c) 2016 Microsemi. All Rights Reserved.
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.
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.
14 # Author: Logan Gunthorpe <logang@deltatee.com>
16 REMOTE_HOST=
17 LIST_DEVS=FALSE
19 DEBUGFS=${DEBUGFS-/sys/kernel/debug}
21 PERF_RUN_ORDER=32
22 MAX_MW_SIZE=0
23 RUN_DMA_TESTS=
24 DONT_CLEANUP=
25 MW_SIZE=65536
27 function show_help()
29 echo "Usage: $0 [OPTIONS] LOCAL_DEV REMOTE_DEV"
30 echo "Run tests on a pair of NTB endpoints."
31 echo
32 echo "If the NTB device loops back to the same host then,"
33 echo "just specifying the two PCI ids on the command line is"
34 echo "sufficient. Otherwise, if the NTB link spans two hosts"
35 echo "use the -r option to specify the hostname for the remote"
36 echo "device. SSH will then be used to test the remote side."
37 echo "An SSH key between the root users of the host would then"
38 echo "be highly recommended."
39 echo
40 echo "Options:"
41 echo " -C don't cleanup ntb modules on exit"
42 echo " -h show this help message"
43 echo " -l list available local and remote PCI ids"
44 echo " -r REMOTE_HOST specify the remote's hostname to connect"
45 echo " to for the test (using ssh)"
46 echo " -m MW_SIZE memory window size for ntb_tool"
47 echo " (default: $MW_SIZE)"
48 echo " -d run dma tests for ntb_perf"
49 echo " -p ORDER total data order for ntb_perf"
50 echo " (default: $PERF_RUN_ORDER)"
51 echo " -w MAX_MW_SIZE maxmium memory window size for ntb_perf"
52 echo
55 function parse_args()
57 OPTIND=0
58 while getopts "b:Cdhlm:r:p:w:" opt; do
59 case "$opt" in
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
72 esac
73 done
76 parse_args "$@"
77 shift $((OPTIND-1))
78 LOCAL_DEV=$1
79 shift
80 parse_args "$@"
81 shift $((OPTIND-1))
82 REMOTE_DEV=$1
83 shift
84 parse_args "$@"
86 set -e
88 function _modprobe()
90 modprobe "$@"
92 if [[ "$REMOTE_HOST" != "" ]]; then
93 ssh "$REMOTE_HOST" modprobe "$@"
97 function split_remote()
99 VPATH=$1
100 REMOTE=
102 if [[ "$VPATH" == *":/"* ]]; then
103 REMOTE=${VPATH%%:*}
104 VPATH=${VPATH#*:}
108 function read_file()
110 split_remote $1
111 if [[ "$REMOTE" != "" ]]; then
112 ssh "$REMOTE" cat "$VPATH"
113 else
114 cat "$VPATH"
118 function write_file()
120 split_remote $2
121 VALUE=$1
123 if [[ "$REMOTE" != "" ]]; then
124 ssh "$REMOTE" "echo \"$VALUE\" > \"$VPATH\""
125 else
126 echo "$VALUE" > "$VPATH"
130 function check_file()
132 split_remote $1
134 if [[ "$REMOTE" != "" ]]; then
135 ssh "$REMOTE" "[[ -e ${VPATH} ]]"
136 else
137 [[ -e ${VPATH} ]]
141 function subdirname()
143 echo $(basename $(dirname $1)) 2> /dev/null
146 function find_pidx()
148 PORT=$1
149 PPATH=$2
151 for ((i = 0; i < 64; i++)); do
152 PEER_DIR="$PPATH/peer$i"
154 check_file ${PEER_DIR} || break
156 PEER_PORT=$(read_file "${PEER_DIR}/port")
157 if [[ ${PORT} -eq $PEER_PORT ]]; then
158 echo $i
159 return 0
161 done
163 return 1
166 function port_test()
168 LOC=$1
169 REM=$2
171 echo "Running port tests on: $(basename $LOC) / $(basename $REM)"
173 LOCAL_PORT=$(read_file "$LOC/port")
174 REMOTE_PORT=$(read_file "$REM/port")
176 LOCAL_PIDX=$(find_pidx ${REMOTE_PORT} "$LOC")
177 REMOTE_PIDX=$(find_pidx ${LOCAL_PORT} "$REM")
179 echo "Local port ${LOCAL_PORT} with index ${REMOTE_PIDX} on remote host"
180 echo "Peer port ${REMOTE_PORT} with index ${LOCAL_PIDX} on local host"
182 echo " Passed"
185 function link_test()
187 LOC=$1
188 REM=$2
189 EXP=0
191 echo "Running link tests on: $(subdirname $LOC) / $(subdirname $REM)"
193 if ! write_file "N" "$LOC/../link" 2> /dev/null; then
194 echo " Unsupported"
195 return
198 write_file "N" "$LOC/link_event"
200 if [[ $(read_file "$REM/link") != "N" ]]; then
201 echo "Expected link to be down in $REM/link" >&2
202 exit -1
205 write_file "Y" "$LOC/../link"
207 echo " Passed"
210 function doorbell_test()
212 LOC=$1
213 REM=$2
214 EXP=0
216 echo "Running db tests on: $(basename $LOC) / $(basename $REM)"
218 DB_VALID_MASK=$(read_file "$LOC/db_valid_mask")
220 write_file "c $DB_VALID_MASK" "$REM/db"
222 for ((i = 0; i < 64; i++)); do
223 DB=$(read_file "$REM/db")
224 if [[ "$DB" -ne "$EXP" ]]; then
225 echo "Doorbell doesn't match expected value $EXP " \
226 "in $REM/db" >&2
227 exit -1
230 let "MASK = (1 << $i) & $DB_VALID_MASK" || true
231 let "EXP = $EXP | $MASK" || true
233 write_file "s $MASK" "$LOC/peer_db"
234 done
236 write_file "c $DB_VALID_MASK" "$REM/db_mask"
237 write_file $DB_VALID_MASK "$REM/db_event"
238 write_file "s $DB_VALID_MASK" "$REM/db_mask"
240 write_file "c $DB_VALID_MASK" "$REM/db"
242 echo " Passed"
245 function get_files_count()
247 NAME=$1
248 LOC=$2
250 split_remote $LOC
252 if [[ "$REMOTE" == "" ]]; then
253 echo $(ls -1 "$VPATH"/${NAME}* 2>/dev/null | wc -l)
254 else
255 echo $(ssh "$REMOTE" "ls -1 \"$VPATH\"/${NAME}* | \
256 wc -l" 2> /dev/null)
260 function scratchpad_test()
262 LOC=$1
263 REM=$2
265 echo "Running spad tests on: $(subdirname $LOC) / $(subdirname $REM)"
267 CNT=$(get_files_count "spad" "$LOC")
269 if [[ $CNT -eq 0 ]]; then
270 echo " Unsupported"
271 return
274 for ((i = 0; i < $CNT; i++)); do
275 VAL=$RANDOM
276 write_file "$VAL" "$LOC/spad$i"
277 RVAL=$(read_file "$REM/../spad$i")
279 if [[ "$VAL" -ne "$RVAL" ]]; then
280 echo "Scratchpad $i value $RVAL doesn't match $VAL" >&2
281 exit -1
283 done
285 echo " Passed"
288 function message_test()
290 LOC=$1
291 REM=$2
293 echo "Running msg tests on: $(subdirname $LOC) / $(subdirname $REM)"
295 CNT=$(get_files_count "msg" "$LOC")
297 if [[ $CNT -eq 0 ]]; then
298 echo " Unsupported"
299 return
302 MSG_OUTBITS_MASK=$(read_file "$LOC/../msg_inbits")
303 MSG_INBITS_MASK=$(read_file "$REM/../msg_inbits")
305 write_file "c $MSG_OUTBITS_MASK" "$LOC/../msg_sts"
306 write_file "c $MSG_INBITS_MASK" "$REM/../msg_sts"
308 for ((i = 0; i < $CNT; i++)); do
309 VAL=$RANDOM
310 write_file "$VAL" "$LOC/msg$i"
311 RVAL=$(read_file "$REM/../msg$i")
313 if [[ "$VAL" -ne "${RVAL%%<-*}" ]]; then
314 echo "Message $i value $RVAL doesn't match $VAL" >&2
315 exit -1
317 done
319 echo " Passed"
322 function get_number()
324 KEY=$1
326 sed -n "s/^\(${KEY}\)[ \t]*\(0x[0-9a-fA-F]*\)\(\[p\]\)\?$/\2/p"
329 function mw_alloc()
331 IDX=$1
332 LOC=$2
333 REM=$3
335 write_file $MW_SIZE "$LOC/mw_trans$IDX"
337 INB_MW=$(read_file "$LOC/mw_trans$IDX")
338 MW_ALIGNED_SIZE=$(echo "$INB_MW" | get_number "Window Size")
339 MW_DMA_ADDR=$(echo "$INB_MW" | get_number "DMA Address")
341 write_file "$MW_DMA_ADDR:$(($MW_ALIGNED_SIZE))" "$REM/peer_mw_trans$IDX"
343 if [[ $MW_SIZE -ne $MW_ALIGNED_SIZE ]]; then
344 echo "MW $IDX size aligned to $MW_ALIGNED_SIZE"
348 function write_mw()
350 split_remote $2
352 if [[ "$REMOTE" != "" ]]; then
353 ssh "$REMOTE" \
354 dd if=/dev/urandom "of=$VPATH" 2> /dev/null || true
355 else
356 dd if=/dev/urandom "of=$VPATH" 2> /dev/null || true
360 function mw_check()
362 IDX=$1
363 LOC=$2
364 REM=$3
366 write_mw "$LOC/mw$IDX"
368 split_remote "$LOC/mw$IDX"
369 if [[ "$REMOTE" == "" ]]; then
370 A=$VPATH
371 else
372 A=/tmp/ntb_test.$$.A
373 ssh "$REMOTE" cat "$VPATH" > "$A"
376 split_remote "$REM/peer_mw$IDX"
377 if [[ "$REMOTE" == "" ]]; then
378 B=$VPATH
379 else
380 B=/tmp/ntb_test.$$.B
381 ssh "$REMOTE" cat "$VPATH" > "$B"
384 cmp -n $MW_ALIGNED_SIZE "$A" "$B"
385 if [[ $? != 0 ]]; then
386 echo "Memory window $MW did not match!" >&2
389 if [[ "$A" == "/tmp/*" ]]; then
390 rm "$A"
393 if [[ "$B" == "/tmp/*" ]]; then
394 rm "$B"
398 function mw_free()
400 IDX=$1
401 LOC=$2
402 REM=$3
404 write_file "$MW_DMA_ADDR:0" "$REM/peer_mw_trans$IDX"
406 write_file 0 "$LOC/mw_trans$IDX"
409 function mw_test()
411 LOC=$1
412 REM=$2
414 CNT=$(get_files_count "mw_trans" "$LOC")
416 for ((i = 0; i < $CNT; i++)); do
417 echo "Running mw$i tests on: $(subdirname $LOC) / " \
418 "$(subdirname $REM)"
420 mw_alloc $i $LOC $REM
422 mw_check $i $LOC $REM
424 mw_free $i $LOC $REM
426 echo " Passed"
427 done
431 function pingpong_test()
433 LOC=$1
434 REM=$2
436 echo "Running ping pong tests on: $(basename $LOC) / $(basename $REM)"
438 LOC_START=$(read_file "$LOC/count")
439 REM_START=$(read_file "$REM/count")
441 sleep 7
443 LOC_END=$(read_file "$LOC/count")
444 REM_END=$(read_file "$REM/count")
446 if [[ $LOC_START == $LOC_END ]] || [[ $REM_START == $REM_END ]]; then
447 echo "Ping pong counter not incrementing!" >&2
448 exit 1
451 echo " Passed"
454 function perf_test()
456 USE_DMA=$1
458 if [[ $USE_DMA == "1" ]]; then
459 WITH="with"
460 else
461 WITH="without"
464 _modprobe ntb_perf total_order=$PERF_RUN_ORDER \
465 max_mw_size=$MAX_MW_SIZE use_dma=$USE_DMA
467 echo "Running local perf test $WITH DMA"
468 write_file "$LOCAL_PIDX" "$LOCAL_PERF/run"
469 echo -n " "
470 read_file "$LOCAL_PERF/run"
471 echo " Passed"
473 echo "Running remote perf test $WITH DMA"
474 write_file "$REMOTE_PIDX" "$REMOTE_PERF/run"
475 echo -n " "
476 read_file "$REMOTE_PERF/run"
477 echo " Passed"
479 _modprobe -r ntb_perf
482 function ntb_tool_tests()
484 LOCAL_TOOL="$DEBUGFS/ntb_tool/$LOCAL_DEV"
485 REMOTE_TOOL="$REMOTE_HOST:$DEBUGFS/ntb_tool/$REMOTE_DEV"
487 echo "Starting ntb_tool tests..."
489 _modprobe ntb_tool
491 port_test "$LOCAL_TOOL" "$REMOTE_TOOL"
493 LOCAL_PEER_TOOL="$LOCAL_TOOL/peer$LOCAL_PIDX"
494 REMOTE_PEER_TOOL="$REMOTE_TOOL/peer$REMOTE_PIDX"
496 link_test "$LOCAL_PEER_TOOL" "$REMOTE_PEER_TOOL"
497 link_test "$REMOTE_PEER_TOOL" "$LOCAL_PEER_TOOL"
499 #Ensure the link is up on both sides before continuing
500 write_file "Y" "$LOCAL_PEER_TOOL/link_event"
501 write_file "Y" "$REMOTE_PEER_TOOL/link_event"
503 doorbell_test "$LOCAL_TOOL" "$REMOTE_TOOL"
504 doorbell_test "$REMOTE_TOOL" "$LOCAL_TOOL"
506 scratchpad_test "$LOCAL_PEER_TOOL" "$REMOTE_PEER_TOOL"
507 scratchpad_test "$REMOTE_PEER_TOOL" "$LOCAL_PEER_TOOL"
509 message_test "$LOCAL_PEER_TOOL" "$REMOTE_PEER_TOOL"
510 message_test "$REMOTE_PEER_TOOL" "$LOCAL_PEER_TOOL"
512 mw_test "$LOCAL_PEER_TOOL" "$REMOTE_PEER_TOOL"
513 mw_test "$REMOTE_PEER_TOOL" "$LOCAL_PEER_TOOL"
515 _modprobe -r ntb_tool
518 function ntb_pingpong_tests()
520 LOCAL_PP="$DEBUGFS/ntb_pingpong/$LOCAL_DEV"
521 REMOTE_PP="$REMOTE_HOST:$DEBUGFS/ntb_pingpong/$REMOTE_DEV"
523 echo "Starting ntb_pingpong tests..."
525 _modprobe ntb_pingpong
527 pingpong_test $LOCAL_PP $REMOTE_PP
529 _modprobe -r ntb_pingpong
532 function ntb_perf_tests()
534 LOCAL_PERF="$DEBUGFS/ntb_perf/$LOCAL_DEV"
535 REMOTE_PERF="$REMOTE_HOST:$DEBUGFS/ntb_perf/$REMOTE_DEV"
537 echo "Starting ntb_perf tests..."
539 perf_test 0
541 if [[ $RUN_DMA_TESTS ]]; then
542 perf_test 1
546 function cleanup()
548 set +e
549 _modprobe -r ntb_tool 2> /dev/null
550 _modprobe -r ntb_perf 2> /dev/null
551 _modprobe -r ntb_pingpong 2> /dev/null
552 _modprobe -r ntb_transport 2> /dev/null
553 set -e
556 cleanup
558 if ! [[ $$DONT_CLEANUP ]]; then
559 trap cleanup EXIT
562 if [ "$(id -u)" != "0" ]; then
563 echo "This script must be run as root" 1>&2
564 exit 1
567 if [[ "$LIST_DEVS" == TRUE ]]; then
568 echo "Local Devices:"
569 ls -1 /sys/bus/ntb/devices
570 echo
572 if [[ "$REMOTE_HOST" != "" ]]; then
573 echo "Remote Devices:"
574 ssh $REMOTE_HOST ls -1 /sys/bus/ntb/devices
577 exit 0
580 if [[ "$LOCAL_DEV" == $"" ]] || [[ "$REMOTE_DEV" == $"" ]]; then
581 show_help
582 exit 1
585 ntb_tool_tests
586 echo
587 ntb_pingpong_tests
588 echo
589 ntb_perf_tests
590 echo