]> git.proxmox.com Git - ceph.git/blob - ceph/src/dpdk/tools/dpdk-setup.sh
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / dpdk / tools / dpdk-setup.sh
1 #! /bin/bash
2
3 # BSD LICENSE
4 #
5 # Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
6 # All rights reserved.
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions
10 # are met:
11 #
12 # * Redistributions of source code must retain the above copyright
13 # notice, this list of conditions and the following disclaimer.
14 # * Redistributions in binary form must reproduce the above copyright
15 # notice, this list of conditions and the following disclaimer in
16 # the documentation and/or other materials provided with the
17 # distribution.
18 # * Neither the name of Intel Corporation nor the names of its
19 # contributors may be used to endorse or promote products derived
20 # from this software without specific prior written permission.
21 #
22 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34 #
35 # Run with "source /path/to/dpdk-setup.sh"
36 #
37
38 #
39 # Change to DPDK directory ( <this-script's-dir>/.. ), and export it as RTE_SDK
40 #
41 cd $(dirname ${BASH_SOURCE[0]})/..
42 export RTE_SDK=$PWD
43 echo "------------------------------------------------------------------------------"
44 echo " RTE_SDK exported as $RTE_SDK"
45 echo "------------------------------------------------------------------------------"
46
47 HUGEPGSZ=`cat /proc/meminfo | grep Hugepagesize | cut -d : -f 2 | tr -d ' '`
48
49 #
50 # Application EAL parameters for setting memory options (amount/channels/ranks).
51 #
52 EAL_PARAMS='-n 4'
53
54 #
55 # Sets QUIT variable so script will finish.
56 #
57 quit()
58 {
59 QUIT=$1
60 }
61
62 # Shortcut for quit.
63 q()
64 {
65 quit
66 }
67
68 #
69 # Sets up environmental variables for ICC.
70 #
71 setup_icc()
72 {
73 DEFAULT_PATH=/opt/intel/bin/iccvars.sh
74 param=$1
75 shpath=`which iccvars.sh 2> /dev/null`
76 if [ $? -eq 0 ] ; then
77 echo "Loading iccvars.sh from $shpath for $param"
78 source $shpath $param
79 elif [ -f $DEFAULT_PATH ] ; then
80 echo "Loading iccvars.sh from $DEFAULT_PATH for $param"
81 source $DEFAULT_PATH $param
82 else
83 echo "## ERROR: cannot find 'iccvars.sh' script to set up ICC."
84 echo "## To fix, please add the directory that contains"
85 echo "## iccvars.sh to your 'PATH' environment variable."
86 quit
87 fi
88 }
89
90 #
91 # Sets RTE_TARGET and does a "make install".
92 #
93 setup_target()
94 {
95 option=$1
96 export RTE_TARGET=${TARGETS[option]}
97
98 compiler=${RTE_TARGET##*-}
99 if [ "$compiler" == "icc" ] ; then
100 platform=${RTE_TARGET%%-*}
101 if [ "$platform" == "x86_64" ] ; then
102 setup_icc intel64
103 else
104 setup_icc ia32
105 fi
106 fi
107 if [ "$QUIT" == "0" ] ; then
108 make install T=${RTE_TARGET}
109 fi
110 echo "------------------------------------------------------------------------------"
111 echo " RTE_TARGET exported as $RTE_TARGET"
112 echo "------------------------------------------------------------------------------"
113 }
114
115 #
116 # Creates hugepage filesystem.
117 #
118 create_mnt_huge()
119 {
120 echo "Creating /mnt/huge and mounting as hugetlbfs"
121 sudo mkdir -p /mnt/huge
122
123 grep -s '/mnt/huge' /proc/mounts > /dev/null
124 if [ $? -ne 0 ] ; then
125 sudo mount -t hugetlbfs nodev /mnt/huge
126 fi
127 }
128
129 #
130 # Removes hugepage filesystem.
131 #
132 remove_mnt_huge()
133 {
134 echo "Unmounting /mnt/huge and removing directory"
135 grep -s '/mnt/huge' /proc/mounts > /dev/null
136 if [ $? -eq 0 ] ; then
137 sudo umount /mnt/huge
138 fi
139
140 if [ -d /mnt/huge ] ; then
141 sudo rm -R /mnt/huge
142 fi
143 }
144
145 #
146 # Unloads igb_uio.ko.
147 #
148 remove_igb_uio_module()
149 {
150 echo "Unloading any existing DPDK UIO module"
151 /sbin/lsmod | grep -s igb_uio > /dev/null
152 if [ $? -eq 0 ] ; then
153 sudo /sbin/rmmod igb_uio
154 fi
155 }
156
157 #
158 # Loads new igb_uio.ko (and uio module if needed).
159 #
160 load_igb_uio_module()
161 {
162 if [ ! -f $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko ];then
163 echo "## ERROR: Target does not have the DPDK UIO Kernel Module."
164 echo " To fix, please try to rebuild target."
165 return
166 fi
167
168 remove_igb_uio_module
169
170 /sbin/lsmod | grep -s uio > /dev/null
171 if [ $? -ne 0 ] ; then
172 modinfo uio > /dev/null
173 if [ $? -eq 0 ]; then
174 echo "Loading uio module"
175 sudo /sbin/modprobe uio
176 fi
177 fi
178
179 # UIO may be compiled into kernel, so it may not be an error if it can't
180 # be loaded.
181
182 echo "Loading DPDK UIO module"
183 sudo /sbin/insmod $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko
184 if [ $? -ne 0 ] ; then
185 echo "## ERROR: Could not load kmod/igb_uio.ko."
186 quit
187 fi
188 }
189
190 #
191 # Unloads VFIO modules.
192 #
193 remove_vfio_module()
194 {
195 echo "Unloading any existing VFIO module"
196 /sbin/lsmod | grep -s vfio > /dev/null
197 if [ $? -eq 0 ] ; then
198 sudo /sbin/rmmod vfio-pci
199 sudo /sbin/rmmod vfio_iommu_type1
200 sudo /sbin/rmmod vfio
201 fi
202 }
203
204 #
205 # Loads new vfio-pci (and vfio module if needed).
206 #
207 load_vfio_module()
208 {
209 remove_vfio_module
210
211 VFIO_PATH="kernel/drivers/vfio/pci/vfio-pci.ko"
212
213 echo "Loading VFIO module"
214 /sbin/lsmod | grep -s vfio_pci > /dev/null
215 if [ $? -ne 0 ] ; then
216 if [ -f /lib/modules/$(uname -r)/$VFIO_PATH ] ; then
217 sudo /sbin/modprobe vfio-pci
218 fi
219 fi
220
221 # make sure regular users can read /dev/vfio
222 echo "chmod /dev/vfio"
223 sudo chmod a+x /dev/vfio
224 if [ $? -ne 0 ] ; then
225 echo "FAIL"
226 quit
227 fi
228 echo "OK"
229
230 # check if /dev/vfio/vfio exists - that way we
231 # know we either loaded the module, or it was
232 # compiled into the kernel
233 if [ ! -e /dev/vfio/vfio ] ; then
234 echo "## ERROR: VFIO not found!"
235 fi
236 }
237
238 #
239 # Unloads the rte_kni.ko module.
240 #
241 remove_kni_module()
242 {
243 echo "Unloading any existing DPDK KNI module"
244 /sbin/lsmod | grep -s rte_kni > /dev/null
245 if [ $? -eq 0 ] ; then
246 sudo /sbin/rmmod rte_kni
247 fi
248 }
249
250 #
251 # Loads the rte_kni.ko module.
252 #
253 load_kni_module()
254 {
255 # Check that the KNI module is already built.
256 if [ ! -f $RTE_SDK/$RTE_TARGET/kmod/rte_kni.ko ];then
257 echo "## ERROR: Target does not have the DPDK KNI Module."
258 echo " To fix, please try to rebuild target."
259 return
260 fi
261
262 # Unload existing version if present.
263 remove_kni_module
264
265 # Now try load the KNI module.
266 echo "Loading DPDK KNI module"
267 sudo /sbin/insmod $RTE_SDK/$RTE_TARGET/kmod/rte_kni.ko
268 if [ $? -ne 0 ] ; then
269 echo "## ERROR: Could not load kmod/rte_kni.ko."
270 quit
271 fi
272 }
273
274 #
275 # Sets appropriate permissions on /dev/vfio/* files
276 #
277 set_vfio_permissions()
278 {
279 # make sure regular users can read /dev/vfio
280 echo "chmod /dev/vfio"
281 sudo chmod a+x /dev/vfio
282 if [ $? -ne 0 ] ; then
283 echo "FAIL"
284 quit
285 fi
286 echo "OK"
287
288 # make sure regular user can access everything inside /dev/vfio
289 echo "chmod /dev/vfio/*"
290 sudo chmod 0666 /dev/vfio/*
291 if [ $? -ne 0 ] ; then
292 echo "FAIL"
293 quit
294 fi
295 echo "OK"
296
297 # since permissions are only to be set when running as
298 # regular user, we only check ulimit here
299 #
300 # warn if regular user is only allowed
301 # to memlock <64M of memory
302 MEMLOCK_AMNT=`ulimit -l`
303
304 if [ "$MEMLOCK_AMNT" != "unlimited" ] ; then
305 MEMLOCK_MB=`expr $MEMLOCK_AMNT / 1024`
306 echo ""
307 echo "Current user memlock limit: ${MEMLOCK_MB} MB"
308 echo ""
309 echo "This is the maximum amount of memory you will be"
310 echo "able to use with DPDK and VFIO if run as current user."
311 echo -n "To change this, please adjust limits.conf memlock "
312 echo "limit for current user."
313
314 if [ $MEMLOCK_AMNT -lt 65536 ] ; then
315 echo ""
316 echo "## WARNING: memlock limit is less than 64MB"
317 echo -n "## DPDK with VFIO may not be able to initialize "
318 echo "if run as current user."
319 fi
320 fi
321 }
322
323 #
324 # Removes all reserved hugepages.
325 #
326 clear_huge_pages()
327 {
328 echo > .echo_tmp
329 for d in /sys/devices/system/node/node? ; do
330 echo "echo 0 > $d/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" >> .echo_tmp
331 done
332 echo "Removing currently reserved hugepages"
333 sudo sh .echo_tmp
334 rm -f .echo_tmp
335
336 remove_mnt_huge
337 }
338
339 #
340 # Creates hugepages.
341 #
342 set_non_numa_pages()
343 {
344 clear_huge_pages
345
346 echo ""
347 echo " Input the number of ${HUGEPGSZ} hugepages"
348 echo " Example: to have 128MB of hugepages available in a 2MB huge page system,"
349 echo " enter '64' to reserve 64 * 2MB pages"
350 echo -n "Number of pages: "
351 read Pages
352
353 echo "echo $Pages > /sys/kernel/mm/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" > .echo_tmp
354
355 echo "Reserving hugepages"
356 sudo sh .echo_tmp
357 rm -f .echo_tmp
358
359 create_mnt_huge
360 }
361
362 #
363 # Creates hugepages on specific NUMA nodes.
364 #
365 set_numa_pages()
366 {
367 clear_huge_pages
368
369 echo ""
370 echo " Input the number of ${HUGEPGSZ} hugepages for each node"
371 echo " Example: to have 128MB of hugepages available per node in a 2MB huge page system,"
372 echo " enter '64' to reserve 64 * 2MB pages on each node"
373
374 echo > .echo_tmp
375 for d in /sys/devices/system/node/node? ; do
376 node=$(basename $d)
377 echo -n "Number of pages for $node: "
378 read Pages
379 echo "echo $Pages > $d/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" >> .echo_tmp
380 done
381 echo "Reserving hugepages"
382 sudo sh .echo_tmp
383 rm -f .echo_tmp
384
385 create_mnt_huge
386 }
387
388 #
389 # Run unit test application.
390 #
391 run_test_app()
392 {
393 echo ""
394 echo " Enter hex bitmask of cores to execute test app on"
395 echo " Example: to execute app on cores 0 to 7, enter 0xff"
396 echo -n "bitmask: "
397 read Bitmask
398 echo "Launching app"
399 sudo ${RTE_TARGET}/app/test -c $Bitmask $EAL_PARAMS
400 }
401
402 #
403 # Run unit testpmd application.
404 #
405 run_testpmd_app()
406 {
407 echo ""
408 echo " Enter hex bitmask of cores to execute testpmd app on"
409 echo " Example: to execute app on cores 0 to 7, enter 0xff"
410 echo -n "bitmask: "
411 read Bitmask
412 echo "Launching app"
413 sudo ${RTE_TARGET}/app/testpmd -c $Bitmask $EAL_PARAMS -- -i
414 }
415
416 #
417 # Print hugepage information.
418 #
419 grep_meminfo()
420 {
421 grep -i huge /proc/meminfo
422 }
423
424 #
425 # Calls dpdk-devbind.py --status to show the devices and what they
426 # are all bound to, in terms of drivers.
427 #
428 show_devices()
429 {
430 if [ -d /sys/module/vfio_pci -o -d /sys/module/igb_uio ]; then
431 ${RTE_SDK}/tools/dpdk-devbind.py --status
432 else
433 echo "# Please load the 'igb_uio' or 'vfio-pci' kernel module before "
434 echo "# querying or adjusting device bindings"
435 fi
436 }
437
438 #
439 # Uses dpdk-devbind.py to move devices to work with vfio-pci
440 #
441 bind_devices_to_vfio()
442 {
443 if [ -d /sys/module/vfio_pci ]; then
444 ${RTE_SDK}/tools/dpdk-devbind.py --status
445 echo ""
446 echo -n "Enter PCI address of device to bind to VFIO driver: "
447 read PCI_PATH
448 sudo ${RTE_SDK}/tools/dpdk-devbind.py -b vfio-pci $PCI_PATH &&
449 echo "OK"
450 else
451 echo "# Please load the 'vfio-pci' kernel module before querying or "
452 echo "# adjusting device bindings"
453 fi
454 }
455
456 #
457 # Uses dpdk-devbind.py to move devices to work with igb_uio
458 #
459 bind_devices_to_igb_uio()
460 {
461 if [ -d /sys/module/igb_uio ]; then
462 ${RTE_SDK}/tools/dpdk-devbind.py --status
463 echo ""
464 echo -n "Enter PCI address of device to bind to IGB UIO driver: "
465 read PCI_PATH
466 sudo ${RTE_SDK}/tools/dpdk-devbind.py -b igb_uio $PCI_PATH && echo "OK"
467 else
468 echo "# Please load the 'igb_uio' kernel module before querying or "
469 echo "# adjusting device bindings"
470 fi
471 }
472
473 #
474 # Uses dpdk-devbind.py to move devices to work with kernel drivers again
475 #
476 unbind_devices()
477 {
478 ${RTE_SDK}/tools/dpdk-devbind.py --status
479 echo ""
480 echo -n "Enter PCI address of device to unbind: "
481 read PCI_PATH
482 echo ""
483 echo -n "Enter name of kernel driver to bind the device to: "
484 read DRV
485 sudo ${RTE_SDK}/tools/dpdk-devbind.py -b $DRV $PCI_PATH && echo "OK"
486 }
487
488 #
489 # Options for building a target. Note that this step MUST be first as it sets
490 # up TARGETS[] starting from 1, and this is accessed in setup_target using the
491 # user entered option.
492 #
493 step1_func()
494 {
495 TITLE="Select the DPDK environment to build"
496 CONFIG_NUM=1
497 for cfg in config/defconfig_* ; do
498 cfg=${cfg/config\/defconfig_/}
499 TEXT[$CONFIG_NUM]="$cfg"
500 TARGETS[$CONFIG_NUM]=$cfg
501 FUNC[$CONFIG_NUM]="setup_target"
502 let "CONFIG_NUM+=1"
503 done
504 }
505
506 #
507 # Options for setting up environment.
508 #
509 step2_func()
510 {
511 TITLE="Setup linuxapp environment"
512
513 TEXT[1]="Insert IGB UIO module"
514 FUNC[1]="load_igb_uio_module"
515
516 TEXT[2]="Insert VFIO module"
517 FUNC[2]="load_vfio_module"
518
519 TEXT[3]="Insert KNI module"
520 FUNC[3]="load_kni_module"
521
522 TEXT[4]="Setup hugepage mappings for non-NUMA systems"
523 FUNC[4]="set_non_numa_pages"
524
525 TEXT[5]="Setup hugepage mappings for NUMA systems"
526 FUNC[5]="set_numa_pages"
527
528 TEXT[6]="Display current Ethernet/Crypto device settings"
529 FUNC[6]="show_devices"
530
531 TEXT[7]="Bind Ethernet/Crypto device to IGB UIO module"
532 FUNC[7]="bind_devices_to_igb_uio"
533
534 TEXT[8]="Bind Ethernet/Crypto device to VFIO module"
535 FUNC[8]="bind_devices_to_vfio"
536
537 TEXT[9]="Setup VFIO permissions"
538 FUNC[9]="set_vfio_permissions"
539 }
540
541 #
542 # Options for running applications.
543 #
544 step3_func()
545 {
546 TITLE="Run test application for linuxapp environment"
547
548 TEXT[1]="Run test application (\$RTE_TARGET/app/test)"
549 FUNC[1]="run_test_app"
550
551 TEXT[2]="Run testpmd application in interactive mode (\$RTE_TARGET/app/testpmd)"
552 FUNC[2]="run_testpmd_app"
553 }
554
555 #
556 # Other options
557 #
558 step4_func()
559 {
560 TITLE="Other tools"
561
562 TEXT[1]="List hugepage info from /proc/meminfo"
563 FUNC[1]="grep_meminfo"
564
565 }
566
567 #
568 # Options for cleaning up the system
569 #
570 step5_func()
571 {
572 TITLE="Uninstall and system cleanup"
573
574 TEXT[1]="Unbind devices from IGB UIO or VFIO driver"
575 FUNC[1]="unbind_devices"
576
577 TEXT[2]="Remove IGB UIO module"
578 FUNC[2]="remove_igb_uio_module"
579
580 TEXT[3]="Remove VFIO module"
581 FUNC[3]="remove_vfio_module"
582
583 TEXT[4]="Remove KNI module"
584 FUNC[4]="remove_kni_module"
585
586 TEXT[5]="Remove hugepage mappings"
587 FUNC[5]="clear_huge_pages"
588 }
589
590 STEPS[1]="step1_func"
591 STEPS[2]="step2_func"
592 STEPS[3]="step3_func"
593 STEPS[4]="step4_func"
594 STEPS[5]="step5_func"
595
596 QUIT=0
597
598 while [ "$QUIT" == "0" ]; do
599 OPTION_NUM=1
600
601 for s in $(seq ${#STEPS[@]}) ; do
602 ${STEPS[s]}
603
604 echo "----------------------------------------------------------"
605 echo " Step $s: ${TITLE}"
606 echo "----------------------------------------------------------"
607
608 for i in $(seq ${#TEXT[@]}) ; do
609 echo "[$OPTION_NUM] ${TEXT[i]}"
610 OPTIONS[$OPTION_NUM]=${FUNC[i]}
611 let "OPTION_NUM+=1"
612 done
613
614 # Clear TEXT and FUNC arrays before next step
615 unset TEXT
616 unset FUNC
617
618 echo ""
619 done
620
621 echo "[$OPTION_NUM] Exit Script"
622 OPTIONS[$OPTION_NUM]="quit"
623 echo ""
624 echo -n "Option: "
625 read our_entry
626 echo ""
627 ${OPTIONS[our_entry]} ${our_entry}
628
629 if [ "$QUIT" == "0" ] ; then
630 echo
631 echo -n "Press enter to continue ..."; read
632 fi
633
634 done