1#!/usr/bin/env bash 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright (C) 2023 Intel Corporation. All rights reserved. 4# 5 6testdir=$(readlink -f "$(dirname "$0")") 7rootdir=$(readlink -f "$testdir/../../../") 8 9set -- "--transport=tcp" "$@" 10 11source "$rootdir/test/common/autotest_common.sh" 12source "$rootdir/test/nvmf/common.sh" 13 14nqn=nqn.2016-06.io.spdk:cnode1 15bperfsock=/var/tmp/bperf.sock 16runtime=2 17 18bperf_rpc() { "$rootdir/scripts/rpc.py" -s "$bperfsock" "$@"; } 19bperf_py() { "$rootdir/examples/bdev/bdevperf/bdevperf.py" -s "$bperfsock" "$@"; } 20 21cleanup() { 22 [[ -n "$bperfpid" ]] && killprocess $bperfpid || : 23 nvmftestfini 24} 25 26get_transient_errcount() { 27 bperf_rpc bdev_get_iostat -b "$1" \ 28 | jq -r '.bdevs[0] 29 | .driver_specific 30 | .nvme_error 31 | .status_code 32 | .command_transient_transport_error' 33} 34 35get_accel_stats() { 36 bperf_rpc accel_get_stats \ 37 | jq -rc '.operations[] 38 | select(.opcode=="crc32c") 39 | "\(.module_name) \(.executed)"' 40} 41 42common_target_config() { 43 rpc_cmd <<- CONFIG 44 framework_start_init 45 bdev_null_create null0 100 4096 46 nvmf_create_transport $NVMF_TRANSPORT_OPTS --in-capsule-data-size 4096 47 nvmf_create_subsystem $nqn -a 48 nvmf_subsystem_add_ns $nqn null0 49 nvmf_subsystem_add_listener -t tcp -a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT $nqn 50 CONFIG 51} 52 53run_bperf_err() { 54 local rw bs qd 55 56 rw=$1 bs=$2 qd=$3 57 "$rootdir/build/examples/bdevperf" -m 2 -r "$bperfsock" -w $rw -o $bs -t $runtime -q $qd -z & 58 bperfpid=$! 59 60 waitforlisten "$bperfpid" "$bperfsock" 61 bperf_rpc bdev_nvme_set_options --nvme-error-stat --bdev-retry-count -1 62 # Make sure error injection is disabled when the controller is being attached 63 rpc_cmd accel_error_inject_error -o crc32c -t disable 64 bperf_rpc bdev_nvme_attach_controller --ddgst -t tcp -a "$NVMF_FIRST_TARGET_IP" \ 65 -s "$NVMF_PORT" -f ipv4 -n "$nqn" -b nvme0 66 # Inject digest errors 67 rpc_cmd accel_error_inject_error -o crc32c -t corrupt -i $((qd * 2)) 68 69 bperf_py "perform_tests" 70 # Make sure that the digest errors were actually caught 71 (($(get_transient_errcount nvme0n1) > 0)) 72 73 killprocess $bperfpid 74} 75 76run_bperf() { 77 local rw bs qd 78 local acc_module acc_executed exp_module 79 80 rw=$1 bs=$2 qd=$3 81 "$rootdir/build/examples/bdevperf" -m 2 -r "$bperfsock" -w $rw -o $bs -t $runtime -q $qd -z --wait-for-rpc & 82 bperfpid=$! 83 waitforlisten "$bperfpid" "$bperfsock" 84 85 [[ $SPDK_TEST_ACCEL_DSA -eq 1 ]] && bperf_rpc dsa_scan_accel_module 86 bperf_rpc framework_start_init 87 88 bperf_rpc bdev_nvme_attach_controller --ddgst -t tcp -a "$NVMF_FIRST_TARGET_IP" \ 89 -s "$NVMF_PORT" -f ipv4 -n "$nqn" -b nvme0 90 91 bperf_py "perform_tests" 92 read -r acc_module acc_executed < <(get_accel_stats) 93 [[ $SPDK_TEST_ACCEL_DSA -eq 1 ]] && exp_module="dsa" || exp_module="software" 94 ((acc_executed > 0)) 95 [[ "$acc_module" == "$exp_module" ]] 96 97 killprocess $bperfpid 98} 99 100run_digest_error() { 101 nvmfappstart --wait-for-rpc 102 103 rpc_cmd accel_assign_opc -o crc32c -m error 104 common_target_config 105 106 # Test the reads - the host should detect digest errors and retry the requests until successful. 107 run_bperf_err randread 4096 128 108 run_bperf_err randread $((128 * 1024)) 16 109 110 # Test the writes - the target should detect digest errors, complete the commands with a transient 111 # transport error and the host should retry them until successful. Test both small writes fitting 112 # within a CapsuleCmd as well as large ones requiring H2CData PDUs. 113 run_bperf_err randwrite 4096 128 114 run_bperf_err randwrite $((128 * 1024)) 16 115 killprocess $nvmfpid 116} 117 118run_digest() { 119 nvmfappstart --wait-for-rpc 120 common_target_config 121 122 run_bperf randread 4096 128 123 run_bperf randread $((128 * 1024)) 16 124 run_bperf randwrite 4096 128 125 run_bperf randwrite $((128 * 1024)) 16 126 killprocess $nvmfpid 127} 128 129# This test only makes sense for the TCP transport 130[[ "$TEST_TRANSPORT" != "tcp" ]] && exit 1 131 132nvmftestinit 133 134trap cleanup SIGINT SIGTERM EXIT 135run_test "nvmf_digest_clean" run_digest 136run_test "nvmf_digest_error" run_digest_error 137 138trap - SIGINT SIGTERM EXIT 139nvmftestfini 140