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 scan_dsa 78 local acc_module acc_executed exp_module 79 80 rw=$1 bs=$2 qd=$3 scan_dsa=$4 81 82 "$rootdir/build/examples/bdevperf" -m 2 -r "$bperfsock" -w $rw -o $bs -t $runtime -q $qd -z --wait-for-rpc & 83 bperfpid=$! 84 waitforlisten "$bperfpid" "$bperfsock" 85 86 $scan_dsa && bperf_rpc dsa_scan_accel_module 87 bperf_rpc framework_start_init 88 89 bperf_rpc bdev_nvme_attach_controller --ddgst -t tcp -a "$NVMF_FIRST_TARGET_IP" \ 90 -s "$NVMF_PORT" -f ipv4 -n "$nqn" -b nvme0 91 92 bperf_py "perform_tests" 93 read -r acc_module acc_executed < <(get_accel_stats) 94 $scan_dsa && exp_module="dsa" || exp_module="software" 95 ((acc_executed > 0)) 96 [[ "$acc_module" == "$exp_module" ]] 97 98 killprocess $bperfpid 99} 100 101run_digest_error() { 102 nvmfappstart --wait-for-rpc 103 104 rpc_cmd accel_assign_opc -o crc32c -m error 105 common_target_config 106 107 # Test the reads - the host should detect digest errors and retry the requests until successful. 108 run_bperf_err randread 4096 128 109 run_bperf_err randread $((128 * 1024)) 16 110 111 # Test the writes - the target should detect digest errors, complete the commands with a transient 112 # transport error and the host should retry them until successful. Test both small writes fitting 113 # within a CapsuleCmd as well as large ones requiring H2CData PDUs. 114 run_bperf_err randwrite 4096 128 115 run_bperf_err randwrite $((128 * 1024)) 16 116 killprocess $nvmfpid 117} 118 119run_digest() { 120 local dsa_initiator 121 [[ "$1" == "dsa_initiator" ]] && dsa_initiator=true || dsa_initiator=false 122 123 tgt_params=("--wait-for-rpc") 124 nvmfappstart "${tgt_params[@]}" 125 [[ "$1" == "dsa_target" ]] && rpc_cmd dsa_scan_accel_module 126 common_target_config 127 128 run_bperf randread 4096 128 $dsa_initiator 129 run_bperf randread $((128 * 1024)) 16 $dsa_initiator 130 run_bperf randwrite 4096 128 $dsa_initiator 131 run_bperf randwrite $((128 * 1024)) 16 $dsa_initiator 132 killprocess $nvmfpid 133} 134 135# This test only makes sense for the TCP transport 136[[ "$TEST_TRANSPORT" != "tcp" ]] && exit 1 137 138nvmftestinit 139 140trap cleanup SIGINT SIGTERM EXIT 141if [[ $SPDK_TEST_ACCEL_DSA -eq 1 ]]; then 142 run_test "nvmf_digest_dsa_initiator" run_digest dsa_initiator 143 run_test "nvmf_digest_dsa_target" run_digest dsa_target 144else 145 run_test "nvmf_digest_clean" run_digest 146fi 147run_test "nvmf_digest_error" run_digest_error 148 149trap - SIGINT SIGTERM EXIT 150nvmftestfini 151