xref: /spdk/scripts/qat_setup.sh (revision 515ec7e7c71bfc03a47f1591f994f05a41758ee9)
1#!/usr/bin/env bash
2#  SPDX-License-Identifier: BSD-3-Clause
3#  Copyright (C) 2018 Intel Corporation
4#  All rights reserved.
5#
6shopt -s nullglob
7set -e
8
9rootdir=$(readlink -f $(dirname $0))/..
10allowed_drivers=("igb_uio" "uio_pci_generic" "vfio_pci")
11
12reload_intel_qat() {
13	# We need to make sure the out-of-tree intel_qat driver, provided via autotest_setup.sh,
14	# is in use. Otherwise, some dependency modules loaded by qat_service may fail causing
15	# some disturbance later on during the tests - in particular, it's been seen that the
16	# adf_ctl was returning inconsistent data (wrong pci addresses), confusing the service
17	# into believing SR-IOV is not enabled.
18
19	# If this file doesn't exist, then either intel_qat is a kernel built-in or is not loaded.
20	# Nothing to do in such cases, qat_service will load the module for us.
21	[[ -e /sys/module/intel_qat/taint ]] || return 0
22
23	local t v
24	t=$(< /sys/module/intel_qat/taint)
25	v=$(< /sys/module/intel_qat/version)
26
27	# OE - out-of-tree, unsigned. By the very default, drivers built via vm_setup.sh are not
28	# signed.
29	[[ -z $t || $t != *"OE"* ]] || return 0
30
31	# Check the version of loaded module against the version of the same module as seen
32	# from .dep. perspective. if these are the same the most likely something is broken
33	# with the dependencies. We report a failure in such a case since reloading the module
34	# won't do any good anyway.
35
36	if [[ $(modinfo -F version intel_qat) == "$v" ]]; then
37		cat <<- WARN
38			Upstream intel_qat driver detected. Same version of the driver is seen
39			in modules dependencies: $v. This may mean QAT build didn't update
40			dependencies properly. QAT setup may fail, please, rebuild the QAT
41			driver.
42		WARN
43		return 0
44	fi
45
46	# Ok, intel_qat is an upstream module, replace it with the out-of-tree one.
47	echo "Reloading intel_qat module"
48
49	local h=(/sys/module/intel_qat/holders/*)
50	h=("${h[@]##*/}")
51
52	modprobe -r "${h[@]}" intel_qat
53	# qat_service does that too, but be vigilant
54	modprobe -a intel_qat "${h[@]}"
55}
56
57# Please note that this script is not intended to be comprehensive or production quality.
58# It supports configuring a single card (the Intel QAT 8970) for use with the SPDK
59
60bad_driver=true
61driver_to_bind=uio_pci_generic
62
63# try starting the qat service. If this doesn't work, just treat it as a warning for now.
64if ! service qat_service start; then
65	echo "failed to start the qat service. Something may be wrong with your 01.org driver."
66fi
67
68reload_intel_qat
69
70_qat_pci_bdfs=(
71	/sys/bus/pci/drivers/c6xx/0000*
72	/sys/bus/pci/drivers/dh895xcc/0000*
73	/sys/bus/pci/drivers/4xxx/0000*
74)
75
76qat_pci_bdfs=("${_qat_pci_bdfs[@]#*drivers/}")
77
78if [ ${#qat_pci_bdfs[@]} -eq 0 ]; then
79	echo "No QAT devices found. Exiting"
80	exit 1
81fi
82
83if [ -n "$1" ]; then
84	driver_to_bind=$1
85fi
86
87for driver in "${allowed_drivers[@]}"; do
88	if [ $driver == $driver_to_bind ]; then
89		bad_driver=false
90	fi
91done
92
93if $bad_driver; then
94	echo "Unrecognized driver. Please specify an accepted driver (listed below):"
95	echo "${allowed_drivers[@]}"
96	exit 1
97fi
98
99expected_num_vfs=0 set_num_vfs=0
100# configure virtual functions for the QAT cards.
101for qat_bdf in "${qat_pci_bdfs[@]}"; do
102	if [[ ! -e /sys/bus/pci/drivers/$qat_bdf/sriov_numvfs ]]; then
103		echo "(${qat_bdf##*/}) sriov_numvfs interface missing, is SR-IOV enabled?"
104		continue
105	fi
106	# Make sure autoprobe is disabled for the VFs so we don't have to race with the
107	# qat_*vf drivers while binding the devices.
108	echo "0" > "/sys/bus/pci/drivers/$qat_bdf/sriov_drivers_autoprobe"
109	num_vfs=$(< "/sys/bus/pci/drivers/$qat_bdf/sriov_totalvfs")
110	echo "$num_vfs" > /sys/bus/pci/drivers/$qat_bdf/sriov_numvfs
111	num_vfs_set=$(< "/sys/bus/pci/drivers/$qat_bdf/sriov_numvfs")
112	if ((num_vfs != num_vfs_set)); then
113		echo "Number of VFs set to $num_vfs_set, expected $num_vfs"
114	else
115		echo "${qat_bdf##*/} set to $num_vfs VFs"
116	fi
117	((expected_num_vfs += num_vfs))
118	((set_num_vfs += num_vfs_set))
119done
120
121# Build VF list out of qat_pci_bdfs[@] by slapping /virtfn* to the path to know if we got'em all.
122# shellcheck disable=SC2206 # <- intentional
123qat_vf_bdfs=(${_qat_pci_bdfs[@]/%//virtfn*})
124
125if ((expected_num_vfs != set_num_vfs || ${#qat_vf_bdfs[@]} != expected_num_vfs)); then
126	echo "Failed to prepare the VFs. Aborting" >&2
127	exit 1
128fi
129
130# Insert the dpdk uio kernel module.
131if [ $driver_to_bind == "igb_uio" ]; then
132	modprobe uio
133	if ! modprobe igb_uio; then
134		echo "Unable to insert the igb_uio kernel module. Aborting."
135		exit 1
136	fi
137elif [ "$driver_to_bind" == "uio_pci_generic" ]; then
138	modprobe uio
139	modprobe uio_pci_generic
140elif [ "$driver_to_bind" == "vfio_pci" ]; then
141	modprobe vfio
142	modprobe vfio_pci
143else
144	echo "Unsure how to work with driver $driver_to_bind. Please configure it in qat_setup.sh"
145	exit 1
146fi
147
148# Unbind old driver if necessary.
149for vf in "${qat_vf_bdfs[@]}"; do
150	vf=$(readlink -f "$vf")
151	if [[ -e $vf/driver ]]; then
152		old_driver=$(basename "$(readlink -f "$vf/driver")")
153		if [[ $old_driver != "$driver_to_bind" ]]; then
154			echo "unbinding driver $old_driver from qat VF at BDF ${vf##*/}"
155			echo "${vf##*/}" > "/sys/bus/pci/drivers/$old_driver/unbind"
156		fi
157	fi
158	# Bind new driver
159	if [ "$driver_to_bind" == "vfio_pci" ]; then
160		"$rootdir/dpdk/usertools/dpdk-devbind.py" -b vfio-pci $vf
161	else
162		echo "$driver_to_bind" > "$vf/driver_override"
163		echo "${vf##*/}" > /sys/bus/pci/drivers_probe
164	fi
165done
166
167echo "Properly configured the qat device with driver $driver_to_bind."
168