]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/scripts/setup.sh
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / spdk / scripts / setup.sh
1 #!/usr/bin/env bash
2
3 set -e
4
5 rootdir=$(readlink -f $(dirname $0))/..
6
7 function linux_iter_pci {
8 # Argument is the class code
9 # TODO: More specifically match against only class codes in the grep
10 # step.
11 lspci -mm -n | grep $1 | tr -d '"' | awk -F " " '{print "0000:"$1}'
12 }
13
14 function linux_bind_driver() {
15 bdf="$1"
16 driver_name="$2"
17 old_driver_name="no driver"
18 ven_dev_id=$(lspci -n -s $bdf | cut -d' ' -f3 | sed 's/:/ /')
19
20 if [ -e "/sys/bus/pci/devices/$bdf/driver" ]; then
21 old_driver_name=$(basename $(readlink /sys/bus/pci/devices/$bdf/driver))
22
23 if [ "$driver_name" = "$old_driver_name" ]; then
24 return 0
25 fi
26
27 echo "$ven_dev_id" > "/sys/bus/pci/devices/$bdf/driver/remove_id" 2> /dev/null || true
28 echo "$bdf" > "/sys/bus/pci/devices/$bdf/driver/unbind"
29 fi
30
31 echo "$bdf ($ven_dev_id): $old_driver_name -> $driver_name"
32
33 echo "$ven_dev_id" > "/sys/bus/pci/drivers/$driver_name/new_id" 2> /dev/null || true
34 echo "$bdf" > "/sys/bus/pci/drivers/$driver_name/bind" 2> /dev/null || true
35
36 iommu_group=$(basename $(readlink -f /sys/bus/pci/devices/$bdf/iommu_group))
37 if [ -e "/dev/vfio/$iommu_group" ]; then
38 if [ "$username" != "" ]; then
39 chown "$username" "/dev/vfio/$iommu_group"
40 fi
41 fi
42 }
43
44 function linux_hugetlbfs_mount() {
45 mount | grep '^hugetlbfs ' | awk '{ print $3 }'
46 }
47
48 function configure_linux {
49 driver_name=vfio-pci
50 if [ -z "$(ls /sys/kernel/iommu_groups)" ]; then
51 # No IOMMU. Use uio.
52 driver_name=uio_pci_generic
53 fi
54
55 # NVMe
56 modprobe $driver_name || true
57 for bdf in $(linux_iter_pci 0108); do
58 linux_bind_driver "$bdf" "$driver_name"
59 done
60
61
62 # IOAT
63 TMP=`mktemp`
64 #collect all the device_id info of ioat devices.
65 grep "PCI_DEVICE_ID_INTEL_IOAT" $rootdir/include/spdk/pci_ids.h \
66 | awk -F"x" '{print $2}' > $TMP
67
68 for dev_id in `cat $TMP`; do
69 # Abuse linux_iter_pci by giving it a device ID instead of a class code
70 for bdf in $(linux_iter_pci $dev_id); do
71 linux_bind_driver "$bdf" "$driver_name"
72 done
73 done
74 rm $TMP
75
76 echo "1" > "/sys/bus/pci/rescan"
77
78 hugetlbfs_mount=$(linux_hugetlbfs_mount)
79
80 if [ -z "$hugetlbfs_mount" ]; then
81 hugetlbfs_mount=/mnt/huge
82 echo "Mounting hugetlbfs at $hugetlbfs_mount"
83 mkdir -p "$hugetlbfs_mount"
84 mount -t hugetlbfs nodev "$hugetlbfs_mount"
85 fi
86 echo "$NRHUGE" > /proc/sys/vm/nr_hugepages
87
88 if [ "$driver_name" = "vfio-pci" ]; then
89 if [ "$username" != "" ]; then
90 chown "$username" "$hugetlbfs_mount"
91 fi
92
93 MEMLOCK_AMNT=`ulimit -l`
94 if [ "$MEMLOCK_AMNT" != "unlimited" ] ; then
95 MEMLOCK_MB=$(( $MEMLOCK_AMNT / 1024 ))
96 echo ""
97 echo "Current user memlock limit: ${MEMLOCK_MB} MB"
98 echo ""
99 echo "This is the maximum amount of memory you will be"
100 echo "able to use with DPDK and VFIO if run as current user."
101 echo -n "To change this, please adjust limits.conf memlock "
102 echo "limit for current user."
103
104 if [ $MEMLOCK_AMNT -lt 65536 ] ; then
105 echo ""
106 echo "## WARNING: memlock limit is less than 64MB"
107 echo -n "## DPDK with VFIO may not be able to initialize "
108 echo "if run as current user."
109 fi
110 fi
111 fi
112 }
113
114 function reset_linux {
115 # NVMe
116 modprobe nvme || true
117 for bdf in $(linux_iter_pci 0108); do
118 linux_bind_driver "$bdf" nvme
119 done
120
121
122 # IOAT
123 TMP=`mktemp`
124 #collect all the device_id info of ioat devices.
125 grep "PCI_DEVICE_ID_INTEL_IOAT" $rootdir/include/spdk/pci_ids.h \
126 | awk -F"x" '{print $2}' > $TMP
127
128 modprobe ioatdma || true
129 for dev_id in `cat $TMP`; do
130 # Abuse linux_iter_pci by giving it a device ID instead of a class code
131 for bdf in $(linux_iter_pci $dev_id); do
132 linux_bind_driver "$bdf" ioatdma
133 done
134 done
135 rm $TMP
136
137 echo "1" > "/sys/bus/pci/rescan"
138
139 hugetlbfs_mount=$(linux_hugetlbfs_mount)
140 rm -f "$hugetlbfs_mount"/spdk*map_*
141 }
142
143 function status_linux {
144 echo "NVMe devices"
145
146 echo -e "BDF\t\tNuma Node\tDriver name\t\tDevice name"
147 for bdf in $(linux_iter_pci 0108); do
148 driver=`grep DRIVER /sys/bus/pci/devices/$bdf/uevent |awk -F"=" '{print $2}'`
149 node=`cat /sys/bus/pci/devices/$bdf/numa_node`;
150 if [ "$driver" = "nvme" ]; then
151 name="\t"`ls /sys/bus/pci/devices/$bdf/nvme`;
152 else
153 name="-";
154 fi
155 echo -e "$bdf\t$node\t\t$driver\t\t$name";
156 done
157
158 echo "I/OAT DMA"
159
160 #collect all the device_id info of ioat devices.
161 TMP=`grep "PCI_DEVICE_ID_INTEL_IOAT" $rootdir/include/spdk/pci_ids.h \
162 | awk -F"x" '{print $2}'`
163 echo -e "BDF\t\tNuma Node\tDriver Name"
164 for dev_id in $TMP; do
165 # Abuse linux_iter_pci by giving it a device ID instead of a class code
166 for bdf in $(linux_iter_pci $dev_id); do
167 driver=`grep DRIVER /sys/bus/pci/devices/$bdf/uevent |awk -F"=" '{print $2}'`
168 node=`cat /sys/bus/pci/devices/$bdf/numa_node`;
169 echo -e "$bdf\t$node\t\t$driver"
170 done
171 done
172 }
173
174 function configure_freebsd {
175 TMP=`mktemp`
176
177 # NVMe
178 GREP_STR="class=0x010802"
179
180 # IOAT
181 grep "PCI_DEVICE_ID_INTEL_IOAT" $rootdir/include/spdk/pci_ids.h \
182 | awk -F"x" '{print $2}' > $TMP
183 for dev_id in `cat $TMP`; do
184 GREP_STR="${GREP_STR}\|chip=0x${dev_id}8086"
185 done
186
187 AWK_PROG="{if (count > 0) printf \",\"; printf \"%s:%s:%s\",\$2,\$3,\$4; count++}"
188 echo $AWK_PROG > $TMP
189
190 BDFS=`pciconf -l | grep "${GREP_STR}" | awk -F: -f $TMP`
191
192 kldunload nic_uio.ko || true
193 kenv hw.nic_uio.bdfs=$BDFS
194 kldload nic_uio.ko
195 rm $TMP
196
197 kldunload contigmem.ko || true
198 kenv hw.contigmem.num_buffers=$((NRHUGE * 2 / 256))
199 kenv hw.contigmem.buffer_size=$((256 * 1024 * 1024))
200 kldload contigmem.ko
201 }
202
203 function reset_freebsd {
204 kldunload contigmem.ko || true
205 kldunload nic_uio.ko || true
206 }
207
208 : ${NRHUGE:=1024}
209
210 username=$1
211 mode=$2
212
213 if [ "$username" = "reset" -o "$username" = "config" -o "$username" = "status" ]; then
214 mode="$username"
215 username=""
216 fi
217
218 if [ "$mode" == "" ]; then
219 mode="config"
220 fi
221
222 if [ "$username" = "" ]; then
223 username="$SUDO_USER"
224 if [ "$username" = "" ]; then
225 username=`logname 2>/dev/null` || true
226 fi
227 fi
228
229 if [ `uname` = Linux ]; then
230 if [ "$mode" == "config" ]; then
231 configure_linux
232 elif [ "$mode" == "reset" ]; then
233 reset_linux
234 elif [ "$mode" == "status" ]; then
235 status_linux
236 fi
237 else
238 if [ "$mode" == "config" ]; then
239 configure_freebsd
240 elif [ "$mode" == "reset" ]; then
241 reset_freebsd
242 fi
243 fi