1 #!/bin/bash 2 # SPDX-License-Identifier: GPL-2.0-or-later 3 # Copyright (c) 2016 Microsemi. All Rights Res 4 # 5 # Author: Logan Gunthorpe <logang@deltatee.com> 6 7 REMOTE_HOST= 8 LIST_DEVS=FALSE 9 10 DEBUGFS=${DEBUGFS-/sys/kernel/debug} 11 12 PERF_RUN_ORDER=32 13 MAX_MW_SIZE=0 14 RUN_DMA_TESTS= 15 DONT_CLEANUP= 16 MW_SIZE=65536 17 18 function show_help() 19 { 20 echo "Usage: $0 [OPTIONS] LOCAL_DEV RE 21 echo "Run tests on a pair of NTB endpo 22 echo 23 echo "If the NTB device loops back to 24 echo "just specifying the two PCI ids 25 echo "sufficient. Otherwise, if the NT 26 echo "use the -r option to specify the 27 echo "device. SSH will then be used to 28 echo "An SSH key between the root user 29 echo "be highly recommended." 30 echo 31 echo "Options:" 32 echo " -C don't cleanup 33 echo " -h show this help 34 echo " -l list available 35 echo " -r REMOTE_HOST specify the re 36 echo " to for the tes 37 echo " -m MW_SIZE memory window 38 echo " (default: $MW_ 39 echo " -d run dma tests 40 echo " -p ORDER total data ord 41 echo " (default: $PER 42 echo " -w MAX_MW_SIZE maxmium memory 43 echo 44 } 45 46 function parse_args() 47 { 48 OPTIND=0 49 while getopts "b:Cdhlm:r:p:w:" opt; do 50 case "$opt" in 51 C) DONT_CLEANUP=1 ;; 52 d) RUN_DMA_TESTS=1 ;; 53 h) show_help; exit 0 ;; 54 l) LIST_DEVS=TRUE ;; 55 m) MW_SIZE=${OPTARG} ;; 56 r) REMOTE_HOST=${OPTARG} ;; 57 p) PERF_RUN_ORDER=${OPTARG} ; 58 w) MAX_MW_SIZE=${OPTARG} ;; 59 \?) 60 echo "Invalid option: -$OP 61 exit 1 62 ;; 63 esac 64 done 65 } 66 67 parse_args "$@" 68 shift $((OPTIND-1)) 69 LOCAL_DEV=$1 70 shift 71 parse_args "$@" 72 shift $((OPTIND-1)) 73 REMOTE_DEV=$1 74 shift 75 parse_args "$@" 76 77 set -e 78 79 function _modprobe() 80 { 81 modprobe "$@" || return 1 82 83 if [[ "$REMOTE_HOST" != "" ]]; then 84 ssh "$REMOTE_HOST" modprobe "$ 85 fi 86 } 87 88 function split_remote() 89 { 90 VPATH=$1 91 REMOTE= 92 93 if [[ "$VPATH" == *":/"* ]]; then 94 REMOTE=${VPATH%%:*} 95 VPATH=${VPATH#*:} 96 fi 97 } 98 99 function read_file() 100 { 101 split_remote $1 102 if [[ "$REMOTE" != "" ]]; then 103 ssh "$REMOTE" cat "$VPATH" 104 else 105 cat "$VPATH" 106 fi 107 } 108 109 function write_file() 110 { 111 split_remote $2 112 VALUE=$1 113 114 if [[ "$REMOTE" != "" ]]; then 115 ssh "$REMOTE" "echo \"$VALUE\" 116 else 117 echo "$VALUE" > "$VPATH" 118 fi 119 } 120 121 function check_file() 122 { 123 split_remote $1 124 125 if [[ "$REMOTE" != "" ]]; then 126 ssh "$REMOTE" "[[ -e ${VPATH} 127 else 128 [[ -e ${VPATH} ]] 129 fi 130 } 131 132 function subdirname() 133 { 134 echo $(basename $(dirname $1)) 2> /dev 135 } 136 137 function find_pidx() 138 { 139 PORT=$1 140 PPATH=$2 141 142 for ((i = 0; i < 64; i++)); do 143 PEER_DIR="$PPATH/peer$i" 144 145 check_file ${PEER_DIR} || brea 146 147 PEER_PORT=$(read_file "${PEER_ 148 if [[ ${PORT} -eq $PEER_PORT ] 149 echo $i 150 return 0 151 fi 152 done 153 154 return 1 155 } 156 157 function port_test() 158 { 159 LOC=$1 160 REM=$2 161 162 echo "Running port tests on: $(basenam 163 164 LOCAL_PORT=$(read_file "$LOC/port") 165 REMOTE_PORT=$(read_file "$REM/port") 166 167 LOCAL_PIDX=$(find_pidx ${REMOTE_PORT} 168 REMOTE_PIDX=$(find_pidx ${LOCAL_PORT} 169 170 echo "Local port ${LOCAL_PORT} with in 171 echo "Peer port ${REMOTE_PORT} with in 172 173 echo " Passed" 174 } 175 176 function link_test() 177 { 178 LOC=$1 179 REM=$2 180 EXP=0 181 182 echo "Running link tests on: $(subdirn 183 184 if ! write_file "N" "$LOC/../link" 2> 185 echo " Unsupported" 186 return 187 fi 188 189 write_file "N" "$LOC/link_event" 190 191 if [[ $(read_file "$REM/link") != "N" 192 echo "Expected link to be down 193 exit -1 194 fi 195 196 write_file "Y" "$LOC/../link" 197 198 echo " Passed" 199 } 200 201 function doorbell_test() 202 { 203 LOC=$1 204 REM=$2 205 EXP=0 206 207 echo "Running db tests on: $(basename 208 209 DB_VALID_MASK=$(read_file "$LOC/db_val 210 211 write_file "c $DB_VALID_MASK" "$REM/db 212 213 for ((i = 0; i < 64; i++)); do 214 DB=$(read_file "$REM/db") 215 if [[ "$DB" -ne "$EXP" ]]; the 216 echo "Doorbell doesn't 217 "in $REM/db" >&2 218 exit -1 219 fi 220 221 let "MASK = (1 << $i) & $DB_VA 222 let "EXP = $EXP | $MASK" || tr 223 224 write_file "s $MASK" "$LOC/pee 225 done 226 227 write_file "c $DB_VALID_MASK" "$REM/db 228 write_file $DB_VALID_MASK "$REM/db_eve 229 write_file "s $DB_VALID_MASK" "$REM/db 230 231 write_file "c $DB_VALID_MASK" "$REM/db 232 233 echo " Passed" 234 } 235 236 function get_files_count() 237 { 238 NAME=$1 239 LOC=$2 240 241 split_remote $LOC 242 243 if [[ "$REMOTE" == "" ]]; then 244 echo $(ls -1 "$VPATH"/${NAME}* 245 else 246 echo $(ssh "$REMOTE" "ls -1 \" 247 wc -l" 2> /dev/null) 248 fi 249 } 250 251 function scratchpad_test() 252 { 253 LOC=$1 254 REM=$2 255 256 echo "Running spad tests on: $(subdirn 257 258 CNT=$(get_files_count "spad" "$LOC") 259 260 if [[ $CNT -eq 0 ]]; then 261 echo " Unsupported" 262 return 263 fi 264 265 for ((i = 0; i < $CNT; i++)); do 266 VAL=$RANDOM 267 write_file "$VAL" "$LOC/spad$i 268 RVAL=$(read_file "$REM/../spad 269 270 if [[ "$VAL" -ne "$RVAL" ]]; t 271 echo "Scratchpad $i va 272 exit -1 273 fi 274 done 275 276 echo " Passed" 277 } 278 279 function message_test() 280 { 281 LOC=$1 282 REM=$2 283 284 echo "Running msg tests on: $(subdirna 285 286 CNT=$(get_files_count "msg" "$LOC") 287 288 if [[ $CNT -eq 0 ]]; then 289 echo " Unsupported" 290 return 291 fi 292 293 MSG_OUTBITS_MASK=$(read_file "$LOC/../ 294 MSG_INBITS_MASK=$(read_file "$REM/../m 295 296 write_file "c $MSG_OUTBITS_MASK" "$LOC 297 write_file "c $MSG_INBITS_MASK" "$REM/ 298 299 for ((i = 0; i < $CNT; i++)); do 300 VAL=$RANDOM 301 write_file "$VAL" "$LOC/msg$i" 302 RVAL=$(read_file "$REM/../msg$ 303 304 if [[ "$VAL" -ne "${RVAL%%<-*} 305 echo "Message $i value 306 exit -1 307 fi 308 done 309 310 echo " Passed" 311 } 312 313 function get_number() 314 { 315 KEY=$1 316 317 sed -n "s/^\(${KEY}\)[ \t]*\(0x[0-9a-f 318 } 319 320 function mw_alloc() 321 { 322 IDX=$1 323 LOC=$2 324 REM=$3 325 326 write_file $MW_SIZE "$LOC/mw_trans$IDX 327 328 INB_MW=$(read_file "$LOC/mw_trans$IDX" 329 MW_ALIGNED_SIZE=$(echo "$INB_MW" | get 330 MW_DMA_ADDR=$(echo "$INB_MW" | get_num 331 332 write_file "$MW_DMA_ADDR:$(($MW_ALIGNE 333 334 if [[ $MW_SIZE -ne $MW_ALIGNED_SIZE ]] 335 echo "MW $IDX size aligned to 336 fi 337 } 338 339 function write_mw() 340 { 341 split_remote $2 342 343 if [[ "$REMOTE" != "" ]]; then 344 ssh "$REMOTE" \ 345 dd if=/dev/urandom "of 346 else 347 dd if=/dev/urandom "of=$VPATH" 348 fi 349 } 350 351 function mw_check() 352 { 353 IDX=$1 354 LOC=$2 355 REM=$3 356 357 write_mw "$LOC/mw$IDX" 358 359 split_remote "$LOC/mw$IDX" 360 if [[ "$REMOTE" == "" ]]; then 361 A=$VPATH 362 else 363 A=/tmp/ntb_test.$$.A 364 ssh "$REMOTE" cat "$VPATH" > " 365 fi 366 367 split_remote "$REM/peer_mw$IDX" 368 if [[ "$REMOTE" == "" ]]; then 369 B=$VPATH 370 else 371 B=/tmp/ntb_test.$$.B 372 ssh "$REMOTE" cat "$VPATH" > " 373 fi 374 375 cmp -n $MW_ALIGNED_SIZE "$A" "$B" 376 if [[ $? != 0 ]]; then 377 echo "Memory window $MW did no 378 fi 379 380 if [[ "$A" == "/tmp/*" ]]; then 381 rm "$A" 382 fi 383 384 if [[ "$B" == "/tmp/*" ]]; then 385 rm "$B" 386 fi 387 } 388 389 function mw_free() 390 { 391 IDX=$1 392 LOC=$2 393 REM=$3 394 395 write_file "$MW_DMA_ADDR:0" "$REM/peer 396 397 write_file 0 "$LOC/mw_trans$IDX" 398 } 399 400 function mw_test() 401 { 402 LOC=$1 403 REM=$2 404 405 CNT=$(get_files_count "mw_trans" "$LOC 406 407 for ((i = 0; i < $CNT; i++)); do 408 echo "Running mw$i tests on: $ 409 "$(subdirname $REM)" 410 411 mw_alloc $i $LOC $REM 412 413 mw_check $i $LOC $REM 414 415 mw_free $i $LOC $REM 416 417 echo " Passed" 418 done 419 420 } 421 422 function pingpong_test() 423 { 424 LOC=$1 425 REM=$2 426 427 echo "Running ping pong tests on: $(ba 428 429 LOC_START=$(read_file "$LOC/count") 430 REM_START=$(read_file "$REM/count") 431 432 sleep 7 433 434 LOC_END=$(read_file "$LOC/count") 435 REM_END=$(read_file "$REM/count") 436 437 if [[ $LOC_START == $LOC_END ]] || [[ 438 echo "Ping pong counter not in 439 exit 1 440 fi 441 442 echo " Passed" 443 } 444 445 function msi_test() 446 { 447 LOC=$1 448 REM=$2 449 450 write_file 1 $LOC/ready 451 452 echo "Running MSI interrupt tests on: 453 454 CNT=$(read_file "$LOC/count") 455 for ((i = 0; i < $CNT; i++)); do 456 START=$(read_file $REM/../irq$ 457 write_file $i $LOC/trigger 458 END=$(read_file $REM/../irq${i 459 460 if [[ $(($END - $START)) != 1 461 echo "MSI did not trig 462 exit 1 463 fi 464 done 465 466 echo " Passed" 467 } 468 469 function perf_test() 470 { 471 USE_DMA=$1 472 473 if [[ $USE_DMA == "1" ]]; then 474 WITH="with" 475 else 476 WITH="without" 477 fi 478 479 _modprobe ntb_perf total_order=$PERF_R 480 max_mw_size=$MAX_MW_SIZE use_d 481 482 echo "Running local perf test $WITH DM 483 write_file "$LOCAL_PIDX" "$LOCAL_PERF/ 484 echo -n " " 485 read_file "$LOCAL_PERF/run" 486 echo " Passed" 487 488 echo "Running remote perf test $WITH D 489 write_file "$REMOTE_PIDX" "$REMOTE_PER 490 echo -n " " 491 read_file "$REMOTE_PERF/run" 492 echo " Passed" 493 494 _modprobe -r ntb_perf 495 } 496 497 function ntb_tool_tests() 498 { 499 LOCAL_TOOL="$DEBUGFS/ntb_tool/$LOCAL_D 500 REMOTE_TOOL="$REMOTE_HOST:$DEBUGFS/ntb 501 502 echo "Starting ntb_tool tests..." 503 504 _modprobe ntb_tool 505 506 port_test "$LOCAL_TOOL" "$REMOTE_TOOL" 507 508 LOCAL_PEER_TOOL="$LOCAL_TOOL/peer$LOCA 509 REMOTE_PEER_TOOL="$REMOTE_TOOL/peer$RE 510 511 link_test "$LOCAL_PEER_TOOL" "$REMOTE_ 512 link_test "$REMOTE_PEER_TOOL" "$LOCAL_ 513 514 #Ensure the link is up on both sides b 515 write_file "Y" "$LOCAL_PEER_TOOL/link_ 516 write_file "Y" "$REMOTE_PEER_TOOL/link 517 518 doorbell_test "$LOCAL_TOOL" "$REMOTE_T 519 doorbell_test "$REMOTE_TOOL" "$LOCAL_T 520 521 scratchpad_test "$LOCAL_PEER_TOOL" "$R 522 scratchpad_test "$REMOTE_PEER_TOOL" "$ 523 524 message_test "$LOCAL_PEER_TOOL" "$REMO 525 message_test "$REMOTE_PEER_TOOL" "$LOC 526 527 mw_test "$LOCAL_PEER_TOOL" "$REMOTE_PE 528 mw_test "$REMOTE_PEER_TOOL" "$LOCAL_PE 529 530 _modprobe -r ntb_tool 531 } 532 533 function ntb_pingpong_tests() 534 { 535 LOCAL_PP="$DEBUGFS/ntb_pingpong/$LOCAL 536 REMOTE_PP="$REMOTE_HOST:$DEBUGFS/ntb_p 537 538 echo "Starting ntb_pingpong tests..." 539 540 _modprobe ntb_pingpong 541 542 pingpong_test $LOCAL_PP $REMOTE_PP 543 544 _modprobe -r ntb_pingpong 545 } 546 547 function ntb_msi_tests() 548 { 549 LOCAL_MSI="$DEBUGFS/ntb_msi_test/$LOCA 550 REMOTE_MSI="$REMOTE_HOST:$DEBUGFS/ntb_ 551 552 echo "Starting ntb_msi_test tests..." 553 554 if ! _modprobe ntb_msi_test 2> /dev/nu 555 echo " Not doing MSI tests se 556 return 557 fi 558 559 port_test $LOCAL_MSI $REMOTE_MSI 560 561 LOCAL_PEER="$LOCAL_MSI/peer$LOCAL_PIDX 562 REMOTE_PEER="$REMOTE_MSI/peer$REMOTE_P 563 564 msi_test $LOCAL_PEER $REMOTE_PEER 565 msi_test $REMOTE_PEER $LOCAL_PEER 566 567 _modprobe -r ntb_msi_test 568 } 569 570 function ntb_perf_tests() 571 { 572 LOCAL_PERF="$DEBUGFS/ntb_perf/$LOCAL_D 573 REMOTE_PERF="$REMOTE_HOST:$DEBUGFS/ntb 574 575 echo "Starting ntb_perf tests..." 576 577 perf_test 0 578 579 if [[ $RUN_DMA_TESTS ]]; then 580 perf_test 1 581 fi 582 } 583 584 function cleanup() 585 { 586 set +e 587 _modprobe -r ntb_tool 2> /dev/null 588 _modprobe -r ntb_perf 2> /dev/null 589 _modprobe -r ntb_pingpong 2> /dev/null 590 _modprobe -r ntb_transport 2> /dev/nul 591 _modprobe -r ntb_msi_test 2> /dev/null 592 set -e 593 } 594 595 cleanup 596 597 if ! [[ $$DONT_CLEANUP ]]; then 598 trap cleanup EXIT 599 fi 600 601 if [ "$(id -u)" != "0" ]; then 602 echo "This script must be run as root" 603 exit 1 604 fi 605 606 if [[ "$LIST_DEVS" == TRUE ]]; then 607 echo "Local Devices:" 608 ls -1 /sys/bus/ntb/devices 609 echo 610 611 if [[ "$REMOTE_HOST" != "" ]]; then 612 echo "Remote Devices:" 613 ssh $REMOTE_HOST ls -1 /sys/bu 614 fi 615 616 exit 0 617 fi 618 619 if [[ "$LOCAL_DEV" == $"" ]] || [[ "$REMOTE_DE 620 show_help 621 exit 1 622 fi 623 624 ntb_tool_tests 625 echo 626 ntb_pingpong_tests 627 echo 628 ntb_msi_tests 629 echo 630 ntb_perf_tests 631 echo
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.