ntb_test.sh 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  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. REMOTE_HOST=
  16. LIST_DEVS=FALSE
  17. DEBUGFS=${DEBUGFS-/sys/kernel/debug}
  18. PERF_RUN_ORDER=32
  19. MAX_MW_SIZE=0
  20. RUN_DMA_TESTS=
  21. DONT_CLEANUP=
  22. MW_SIZE=65536
  23. function show_help()
  24. {
  25. echo "Usage: $0 [OPTIONS] LOCAL_DEV REMOTE_DEV"
  26. echo "Run tests on a pair of NTB endpoints."
  27. echo
  28. echo "If the NTB device loops back to the same host then,"
  29. echo "just specifying the two PCI ids on the command line is"
  30. echo "sufficient. Otherwise, if the NTB link spans two hosts"
  31. echo "use the -r option to specify the hostname for the remote"
  32. echo "device. SSH will then be used to test the remote side."
  33. echo "An SSH key between the root users of the host would then"
  34. echo "be highly recommended."
  35. echo
  36. echo "Options:"
  37. echo " -C don't cleanup ntb modules on exit"
  38. echo " -d run dma tests"
  39. echo " -h show this help message"
  40. echo " -l list available local and remote PCI ids"
  41. echo " -r REMOTE_HOST specify the remote's hostname to connect"
  42. echo " to for the test (using ssh)"
  43. echo " -p NUM ntb_perf run order (default: $PERF_RUN_ORDER)"
  44. echo " -w max_mw_size maxmium memory window size"
  45. echo
  46. }
  47. function parse_args()
  48. {
  49. OPTIND=0
  50. while getopts "Cdhlm:r:p:w:" opt; do
  51. case "$opt" in
  52. C) DONT_CLEANUP=1 ;;
  53. d) RUN_DMA_TESTS=1 ;;
  54. h) show_help; exit 0 ;;
  55. l) LIST_DEVS=TRUE ;;
  56. m) MW_SIZE=${OPTARG} ;;
  57. r) REMOTE_HOST=${OPTARG} ;;
  58. p) PERF_RUN_ORDER=${OPTARG} ;;
  59. w) MAX_MW_SIZE=${OPTARG} ;;
  60. \?)
  61. echo "Invalid option: -$OPTARG" >&2
  62. exit 1
  63. ;;
  64. esac
  65. done
  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. set -e
  77. function _modprobe()
  78. {
  79. modprobe "$@"
  80. }
  81. function split_remote()
  82. {
  83. VPATH=$1
  84. REMOTE=
  85. if [[ "$VPATH" == *":/"* ]]; then
  86. REMOTE=${VPATH%%:*}
  87. VPATH=${VPATH#*:}
  88. fi
  89. }
  90. function read_file()
  91. {
  92. split_remote $1
  93. if [[ "$REMOTE" != "" ]]; then
  94. ssh "$REMOTE" cat "$VPATH"
  95. else
  96. cat "$VPATH"
  97. fi
  98. }
  99. function write_file()
  100. {
  101. split_remote $2
  102. VALUE=$1
  103. if [[ "$REMOTE" != "" ]]; then
  104. ssh "$REMOTE" "echo \"$VALUE\" > \"$VPATH\""
  105. else
  106. echo "$VALUE" > "$VPATH"
  107. fi
  108. }
  109. function link_test()
  110. {
  111. LOC=$1
  112. REM=$2
  113. EXP=0
  114. echo "Running link tests on: $(basename $LOC) / $(basename $REM)"
  115. if ! write_file "N" "$LOC/link" 2> /dev/null; then
  116. echo " Unsupported"
  117. return
  118. fi
  119. write_file "N" "$LOC/link_event"
  120. if [[ $(read_file "$REM/link") != "N" ]]; then
  121. echo "Expected remote link to be down in $REM/link" >&2
  122. exit -1
  123. fi
  124. write_file "Y" "$LOC/link"
  125. write_file "Y" "$LOC/link_event"
  126. echo " Passed"
  127. }
  128. function doorbell_test()
  129. {
  130. LOC=$1
  131. REM=$2
  132. EXP=0
  133. echo "Running db tests on: $(basename $LOC) / $(basename $REM)"
  134. write_file "c 0xFFFFFFFF" "$REM/db"
  135. for ((i=1; i <= 8; i++)); do
  136. let DB=$(read_file "$REM/db") || true
  137. if [[ "$DB" != "$EXP" ]]; then
  138. echo "Doorbell doesn't match expected value $EXP " \
  139. "in $REM/db" >&2
  140. exit -1
  141. fi
  142. let "MASK=1 << ($i-1)" || true
  143. let "EXP=$EXP | $MASK" || true
  144. write_file "s $MASK" "$LOC/peer_db"
  145. done
  146. echo " Passed"
  147. }
  148. function read_spad()
  149. {
  150. VPATH=$1
  151. IDX=$2
  152. ROW=($(read_file "$VPATH" | grep -e "^$IDX"))
  153. let VAL=${ROW[1]} || true
  154. echo $VAL
  155. }
  156. function scratchpad_test()
  157. {
  158. LOC=$1
  159. REM=$2
  160. CNT=$(read_file "$LOC/spad" | wc -l)
  161. echo "Running spad tests on: $(basename $LOC) / $(basename $REM)"
  162. for ((i = 0; i < $CNT; i++)); do
  163. VAL=$RANDOM
  164. write_file "$i $VAL" "$LOC/peer_spad"
  165. RVAL=$(read_spad "$REM/spad" $i)
  166. if [[ "$VAL" != "$RVAL" ]]; then
  167. echo "Scratchpad doesn't match expected value $VAL " \
  168. "in $REM/spad, got $RVAL" >&2
  169. exit -1
  170. fi
  171. done
  172. echo " Passed"
  173. }
  174. function write_mw()
  175. {
  176. split_remote $2
  177. if [[ "$REMOTE" != "" ]]; then
  178. ssh "$REMOTE" \
  179. dd if=/dev/urandom "of=$VPATH" 2> /dev/null || true
  180. else
  181. dd if=/dev/urandom "of=$VPATH" 2> /dev/null || true
  182. fi
  183. }
  184. function mw_test()
  185. {
  186. IDX=$1
  187. LOC=$2
  188. REM=$3
  189. echo "Running $IDX tests on: $(basename $LOC) / $(basename $REM)"
  190. write_mw "$LOC/$IDX"
  191. split_remote "$LOC/$IDX"
  192. if [[ "$REMOTE" == "" ]]; then
  193. A=$VPATH
  194. else
  195. A=/tmp/ntb_test.$$.A
  196. ssh "$REMOTE" cat "$VPATH" > "$A"
  197. fi
  198. split_remote "$REM/peer_$IDX"
  199. if [[ "$REMOTE" == "" ]]; then
  200. B=$VPATH
  201. else
  202. B=/tmp/ntb_test.$$.B
  203. ssh "$REMOTE" cat "$VPATH" > "$B"
  204. fi
  205. cmp -n $MW_SIZE "$A" "$B"
  206. if [[ $? != 0 ]]; then
  207. echo "Memory window $MW did not match!" >&2
  208. fi
  209. if [[ "$A" == "/tmp/*" ]]; then
  210. rm "$A"
  211. fi
  212. if [[ "$B" == "/tmp/*" ]]; then
  213. rm "$B"
  214. fi
  215. echo " Passed"
  216. }
  217. function pingpong_test()
  218. {
  219. LOC=$1
  220. REM=$2
  221. echo "Running ping pong tests on: $(basename $LOC) / $(basename $REM)"
  222. LOC_START=$(read_file $LOC/count)
  223. REM_START=$(read_file $REM/count)
  224. sleep 7
  225. LOC_END=$(read_file $LOC/count)
  226. REM_END=$(read_file $REM/count)
  227. if [[ $LOC_START == $LOC_END ]] || [[ $REM_START == $REM_END ]]; then
  228. echo "Ping pong counter not incrementing!" >&2
  229. exit 1
  230. fi
  231. echo " Passed"
  232. }
  233. function perf_test()
  234. {
  235. USE_DMA=$1
  236. if [[ $USE_DMA == "1" ]]; then
  237. WITH="with"
  238. else
  239. WITH="without"
  240. fi
  241. _modprobe ntb_perf run_order=$PERF_RUN_ORDER \
  242. max_mw_size=$MAX_MW_SIZE use_dma=$USE_DMA
  243. echo "Running local perf test $WITH DMA"
  244. write_file "" $LOCAL_PERF/run
  245. echo -n " "
  246. read_file $LOCAL_PERF/run
  247. echo " Passed"
  248. echo "Running remote perf test $WITH DMA"
  249. write_file "" $REMOTE_PERF/run
  250. echo -n " "
  251. read_file $LOCAL_PERF/run
  252. echo " Passed"
  253. _modprobe -r ntb_perf
  254. }
  255. function ntb_tool_tests()
  256. {
  257. LOCAL_TOOL=$DEBUGFS/ntb_tool/$LOCAL_DEV
  258. REMOTE_TOOL=$REMOTE_HOST:$DEBUGFS/ntb_tool/$REMOTE_DEV
  259. echo "Starting ntb_tool tests..."
  260. _modprobe ntb_tool
  261. write_file Y $LOCAL_TOOL/link_event
  262. write_file Y $REMOTE_TOOL/link_event
  263. link_test $LOCAL_TOOL $REMOTE_TOOL
  264. link_test $REMOTE_TOOL $LOCAL_TOOL
  265. for PEER_TRANS in $(ls $LOCAL_TOOL/peer_trans*); do
  266. PT=$(basename $PEER_TRANS)
  267. write_file $MW_SIZE $LOCAL_TOOL/$PT
  268. write_file $MW_SIZE $REMOTE_TOOL/$PT
  269. done
  270. doorbell_test $LOCAL_TOOL $REMOTE_TOOL
  271. doorbell_test $REMOTE_TOOL $LOCAL_TOOL
  272. scratchpad_test $LOCAL_TOOL $REMOTE_TOOL
  273. scratchpad_test $REMOTE_TOOL $LOCAL_TOOL
  274. for MW in $(ls $LOCAL_TOOL/mw*); do
  275. MW=$(basename $MW)
  276. mw_test $MW $LOCAL_TOOL $REMOTE_TOOL
  277. mw_test $MW $REMOTE_TOOL $LOCAL_TOOL
  278. done
  279. _modprobe -r ntb_tool
  280. }
  281. function ntb_pingpong_tests()
  282. {
  283. LOCAL_PP=$DEBUGFS/ntb_pingpong/$LOCAL_DEV
  284. REMOTE_PP=$REMOTE_HOST:$DEBUGFS/ntb_pingpong/$REMOTE_DEV
  285. echo "Starting ntb_pingpong tests..."
  286. _modprobe ntb_pingpong
  287. pingpong_test $LOCAL_PP $REMOTE_PP
  288. _modprobe -r ntb_pingpong
  289. }
  290. function ntb_perf_tests()
  291. {
  292. LOCAL_PERF=$DEBUGFS/ntb_perf/$LOCAL_DEV
  293. REMOTE_PERF=$REMOTE_HOST:$DEBUGFS/ntb_perf/$REMOTE_DEV
  294. echo "Starting ntb_perf tests..."
  295. perf_test 0
  296. if [[ $RUN_DMA_TESTS ]]; then
  297. perf_test 1
  298. fi
  299. }
  300. function cleanup()
  301. {
  302. set +e
  303. _modprobe -r ntb_tool 2> /dev/null
  304. _modprobe -r ntb_perf 2> /dev/null
  305. _modprobe -r ntb_pingpong 2> /dev/null
  306. _modprobe -r ntb_transport 2> /dev/null
  307. set -e
  308. }
  309. cleanup
  310. if ! [[ $$DONT_CLEANUP ]]; then
  311. trap cleanup EXIT
  312. fi
  313. if [ "$(id -u)" != "0" ]; then
  314. echo "This script must be run as root" 1>&2
  315. exit 1
  316. fi
  317. if [[ "$LIST_DEVS" == TRUE ]]; then
  318. echo "Local Devices:"
  319. ls -1 /sys/bus/ntb/devices
  320. echo
  321. if [[ "$REMOTE_HOST" != "" ]]; then
  322. echo "Remote Devices:"
  323. ssh $REMOTE_HOST ls -1 /sys/bus/ntb/devices
  324. fi
  325. exit 0
  326. fi
  327. if [[ "$LOCAL_DEV" == $"" ]] || [[ "$REMOTE_DEV" == $"" ]]; then
  328. show_help
  329. exit 1
  330. fi
  331. ntb_tool_tests
  332. echo
  333. ntb_pingpong_tests
  334. echo
  335. ntb_perf_tests
  336. echo