xref: /spdk/test/nvmf/host/digest.sh (revision 91fcde065a5883d85ca1034a9a1b254e1eadbcad)
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