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