examples/l3fwd: improve grouping by destination port
[dpdk.git] / tools / 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/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 #
48 # Application EAL parameters for setting memory options (amount/channels/ranks).
49 #
50 EAL_PARAMS='-n 4'
51
52 #
53 # Sets QUIT variable so script will finish.
54 #
55 quit()
56 {
57         QUIT=$1
58 }
59
60 #
61 # Sets up environmental variables for ICC.
62 #
63 setup_icc()
64 {
65         DEFAULT_PATH=/opt/intel/bin/iccvars.sh
66         param=$1
67         shpath=`which iccvars.sh 2> /dev/null`
68         if [ $? -eq 0 ] ; then
69                 echo "Loading iccvars.sh from $shpath for $param"
70                 source $shpath $param
71         elif [ -f $DEFAULT_PATH ] ; then
72                 echo "Loading iccvars.sh from $DEFAULT_PATH for $param"
73                 source $DEFAULT_PATH $param
74         else
75                 echo "## ERROR: cannot find 'iccvars.sh' script to set up ICC."
76                 echo "##     To fix, please add the directory that contains"
77                 echo "##     iccvars.sh  to your 'PATH' environment variable."
78                 quit
79         fi
80 }
81
82 #
83 # Sets RTE_TARGET and does a "make install".
84 #
85 setup_target()
86 {
87         option=$1
88         export RTE_TARGET=${TARGETS[option]}
89
90         compiler=${RTE_TARGET##*-}
91         if [ "$compiler" == "icc" ] ; then
92                 platform=${RTE_TARGET%%-*}
93                 if [ "$platform" == "x86_64" ] ; then
94                         setup_icc intel64
95                 else
96                         setup_icc ia32
97                 fi
98         fi
99         if [ "$QUIT" == "0" ] ; then
100                 make install T=${RTE_TARGET}
101         fi
102         echo "------------------------------------------------------------------------------"
103         echo " RTE_TARGET exported as $RTE_TARGET"
104         echo "------------------------------------------------------------------------------"
105 }
106
107 #
108 # Uninstall all targets.
109 #
110 uninstall_targets()
111 {
112         make uninstall
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                 if [ -f /lib/modules/$(uname -r)/kernel/drivers/uio/uio.ko ] ; then
173                         echo "Loading uio module"
174                         sudo /sbin/modprobe uio
175                 fi
176         fi
177
178         # UIO may be compiled into kernel, so it may not be an error if it can't
179         # be loaded.
180
181         echo "Loading DPDK UIO module"
182         sudo /sbin/insmod $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko
183         if [ $? -ne 0 ] ; then
184                 echo "## ERROR: Could not load kmod/igb_uio.ko."
185                 quit
186         fi
187 }
188
189 #
190 # Unloads VFIO modules.
191 #
192 remove_vfio_module()
193 {
194         echo "Unloading any existing VFIO module"
195         /sbin/lsmod | grep -s vfio > /dev/null
196         if [ $? -eq 0 ] ; then
197                 sudo /sbin/rmmod vfio-pci
198                 sudo /sbin/rmmod vfio_iommu_type1
199                 sudo /sbin/rmmod vfio
200         fi
201 }
202
203 #
204 # Loads new vfio-pci (and vfio module if needed).
205 #
206 load_vfio_module()
207 {
208         remove_vfio_module
209
210         VFIO_PATH="kernel/drivers/vfio/pci/vfio-pci.ko"
211
212         echo "Loading VFIO module"
213         /sbin/lsmod | grep -s vfio_pci > /dev/null
214         if [ $? -ne 0 ] ; then
215                 if [ -f /lib/modules/$(uname -r)/$VFIO_PATH ] ; then
216                         sudo /sbin/modprobe vfio-pci
217                 fi
218         fi
219
220         # make sure regular users can read /dev/vfio
221         echo "chmod /dev/vfio"
222         sudo /usr/bin/chmod a+x /dev/vfio
223         if [ $? -ne 0 ] ; then
224                 echo "FAIL"
225                 quit
226         fi
227         echo "OK"
228
229         # check if /dev/vfio/vfio exists - that way we
230         # know we either loaded the module, or it was
231         # compiled into the kernel
232         if [ ! -e /dev/vfio/vfio ] ; then
233                 echo "## ERROR: VFIO not found!"
234         fi
235 }
236
237 #
238 # Unloads the rte_kni.ko module.
239 #
240 remove_kni_module()
241 {
242         echo "Unloading any existing DPDK KNI module"
243         /sbin/lsmod | grep -s rte_kni > /dev/null
244         if [ $? -eq 0 ] ; then
245                 sudo /sbin/rmmod rte_kni
246         fi
247 }
248
249 #
250 # Loads the rte_kni.ko module.
251 #
252 load_kni_module()
253 {
254     # Check that the KNI module is already built.
255         if [ ! -f $RTE_SDK/$RTE_TARGET/kmod/rte_kni.ko ];then
256                 echo "## ERROR: Target does not have the DPDK KNI Module."
257                 echo "       To fix, please try to rebuild target."
258                 return
259         fi
260
261     # Unload existing version if present.
262         remove_kni_module
263
264     # Now try load the KNI module.
265         echo "Loading DPDK KNI module"
266         sudo /sbin/insmod $RTE_SDK/$RTE_TARGET/kmod/rte_kni.ko
267         if [ $? -ne 0 ] ; then
268                 echo "## ERROR: Could not load kmod/rte_kni.ko."
269                 quit
270         fi
271 }
272
273 #
274 # Sets appropriate permissions on /dev/vfio/* files
275 #
276 set_vfio_permissions()
277 {
278         # make sure regular users can read /dev/vfio
279         echo "chmod /dev/vfio"
280         sudo /usr/bin/chmod a+x /dev/vfio
281         if [ $? -ne 0 ] ; then
282                 echo "FAIL"
283                 quit
284         fi
285         echo "OK"
286
287         # make sure regular user can access everything inside /dev/vfio
288         echo "chmod /dev/vfio/*"
289         sudo /usr/bin/chmod 0666 /dev/vfio/*
290         if [ $? -ne 0 ] ; then
291                 echo "FAIL"
292                 quit
293         fi
294         echo "OK"
295
296         # since permissions are only to be set when running as
297         # regular user, we only check ulimit here
298         #
299         # warn if regular user is only allowed
300         # to memlock <64M of memory
301         MEMLOCK_AMNT=`ulimit -l`
302
303         if [ "$MEMLOCK_AMNT" != "unlimited" ] ; then
304                 MEMLOCK_MB=`expr $MEMLOCK_AMNT / 1024`
305                 echo ""
306                 echo "Current user memlock limit: ${MEMLOCK_MB} MB"
307                 echo ""
308                 echo "This is the maximum amount of memory you will be"
309                 echo "able to use with DPDK and VFIO if run as current user."
310                 echo -n "To change this, please adjust limits.conf memlock "
311                 echo "limit for current user."
312
313                 if [ $MEMLOCK_AMNT -lt 65536 ] ; then
314                         echo ""
315                         echo "## WARNING: memlock limit is less than 64MB"
316                         echo -n "## DPDK with VFIO may not be able to initialize "
317                         echo "if run as current user."
318                 fi
319         fi
320 }
321
322 #
323 # Removes all reserved hugepages.
324 #
325 clear_huge_pages()
326 {
327         echo > .echo_tmp
328         for d in /sys/devices/system/node/node? ; do
329                 echo "echo 0 > $d/hugepages/hugepages-2048kB/nr_hugepages" >> .echo_tmp
330         done
331         echo "Removing currently reserved hugepages"
332         sudo sh .echo_tmp
333         rm -f .echo_tmp
334
335         remove_mnt_huge
336 }
337
338 #
339 # Creates hugepages.
340 #
341 set_non_numa_pages()
342 {
343         clear_huge_pages
344
345         echo ""
346         echo "  Input the number of 2MB pages"
347         echo "  Example: to have 128MB of hugepages available, enter '64' to"
348         echo "  reserve 64 * 2MB pages"
349         echo -n "Number of pages: "
350         read Pages
351
352         echo "echo $Pages > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages" > .echo_tmp
353
354         echo "Reserving hugepages"
355         sudo sh .echo_tmp
356         rm -f .echo_tmp
357
358         create_mnt_huge
359 }
360
361 #
362 # Creates hugepages on specific NUMA nodes.
363 #
364 set_numa_pages()
365 {
366         clear_huge_pages
367
368         echo ""
369         echo "  Input the number of 2MB pages for each node"
370         echo "  Example: to have 128MB of hugepages available per node,"
371         echo "  enter '64' to reserve 64 * 2MB pages on each node"
372
373         echo > .echo_tmp
374         for d in /sys/devices/system/node/node? ; do
375                 node=$(basename $d)
376                 echo -n "Number of pages for $node: "
377                 read Pages
378                 echo "echo $Pages > $d/hugepages/hugepages-2048kB/nr_hugepages" >> .echo_tmp
379         done
380         echo "Reserving hugepages"
381         sudo sh .echo_tmp
382         rm -f .echo_tmp
383
384         create_mnt_huge
385 }
386
387 #
388 # Run unit test application.
389 #
390 run_test_app()
391 {
392         echo ""
393         echo "  Enter hex bitmask of cores to execute test app on"
394         echo "  Example: to execute app on cores 0 to 7, enter 0xff"
395         echo -n "bitmask: "
396         read Bitmask
397         echo "Launching app"
398         sudo ${RTE_TARGET}/app/test -c $Bitmask $EAL_PARAMS
399 }
400
401 #
402 # Run unit testpmd application.
403 #
404 run_testpmd_app()
405 {
406         echo ""
407         echo "  Enter hex bitmask of cores to execute testpmd app on"
408         echo "  Example: to execute app on cores 0 to 7, enter 0xff"
409         echo -n "bitmask: "
410         read Bitmask
411         echo "Launching app"
412         sudo ${RTE_TARGET}/app/testpmd -c $Bitmask $EAL_PARAMS -- -i
413 }
414
415 #
416 # Print hugepage information.
417 #
418 grep_meminfo()
419 {
420         grep -i huge /proc/meminfo
421 }
422
423 #
424 # Calls dpdk_nic_bind.py --status to show the NIC and what they
425 # are all bound to, in terms of drivers.
426 #
427 show_nics()
428 {
429         if  /sbin/lsmod  | grep -q igb_uio ; then
430                 ${RTE_SDK}/tools/dpdk_nic_bind.py --status
431         else
432                 echo "# Please load the 'igb_uio' kernel module before querying or "
433                 echo "# adjusting NIC device bindings"
434         fi
435 }
436
437 #
438 # Uses dpdk_nic_bind.py to move devices to work with igb_uio
439 #
440 bind_nics_to_vfio()
441 {
442         if /sbin/lsmod  | grep -q vfio_pci ; then
443                 ${RTE_SDK}/tools/dpdk_nic_bind.py --status
444                 echo ""
445                 echo -n "Enter PCI address of device to bind to VFIO driver: "
446                 read PCI_PATH
447                 sudo ${RTE_SDK}/tools/dpdk_nic_bind.py -b vfio-pci $PCI_PATH &&
448                         echo "OK"
449         else
450                 echo "# Please load the 'vfio-pci' kernel module before querying or "
451                 echo "# adjusting NIC device bindings"
452         fi
453 }
454
455 #
456 # Uses dpdk_nic_bind.py to move devices to work with igb_uio
457 #
458 bind_nics_to_igb_uio()
459 {
460         if  /sbin/lsmod  | grep -q igb_uio ; then
461                 ${RTE_SDK}/tools/dpdk_nic_bind.py --status
462                 echo ""
463                 echo -n "Enter PCI address of device to bind to IGB UIO driver: "
464                 read PCI_PATH
465                 sudo ${RTE_SDK}/tools/dpdk_nic_bind.py -b igb_uio $PCI_PATH && echo "OK"
466         else
467                 echo "# Please load the 'igb_uio' kernel module before querying or "
468                 echo "# adjusting NIC device bindings"
469         fi
470 }
471
472 #
473 # Uses dpdk_nic_bind.py to move devices to work with kernel drivers again
474 #
475 unbind_nics()
476 {
477         ${RTE_SDK}/tools/dpdk_nic_bind.py --status
478         echo ""
479         echo -n "Enter PCI address of device to bind to IGB UIO driver: "
480         read PCI_PATH
481         echo ""
482         echo -n "Enter name of kernel driver to bind the device to: "
483         read DRV
484         sudo ${RTE_SDK}/tools/dpdk_nic_bind.py -b $DRV $PCI_PATH && echo "OK"
485 }
486
487 #
488 # Options for building a target. Note that this step MUST be first as it sets
489 # up TARGETS[] starting from 1, and this is accessed in setup_target using the
490 # user entered option.
491 #
492 step1_func()
493 {
494         TITLE="Select the DPDK environment to build"
495         CONFIG_NUM=1
496         for cfg in config/defconfig_* ; do
497                 cfg=${cfg/config\/defconfig_/}
498                 TEXT[$CONFIG_NUM]="$cfg"
499                 TARGETS[$CONFIG_NUM]=$cfg
500                 FUNC[$CONFIG_NUM]="setup_target"
501                 let "CONFIG_NUM+=1"
502         done
503 }
504
505 #
506 # Options for setting up environment.
507 #
508 step2_func()
509 {
510         TITLE="Setup linuxapp environment"
511
512         TEXT[1]="Insert IGB UIO module"
513         FUNC[1]="load_igb_uio_module"
514
515         TEXT[2]="Insert VFIO module"
516         FUNC[2]="load_vfio_module"
517
518         TEXT[3]="Insert KNI module"
519         FUNC[3]="load_kni_module"
520
521         TEXT[4]="Setup hugepage mappings for non-NUMA systems"
522         FUNC[4]="set_non_numa_pages"
523
524         TEXT[5]="Setup hugepage mappings for NUMA systems"
525         FUNC[5]="set_numa_pages"
526
527         TEXT[6]="Display current Ethernet device settings"
528         FUNC[6]="show_nics"
529
530         TEXT[7]="Bind Ethernet device to IGB UIO module"
531         FUNC[7]="bind_nics_to_igb_uio"
532
533         TEXT[8]="Bind Ethernet device to VFIO module"
534         FUNC[8]="bind_nics_to_vfio"
535
536         TEXT[9]="Setup VFIO permissions"
537         FUNC[9]="set_vfio_permissions"
538 }
539
540 #
541 # Options for running applications.
542 #
543 step3_func()
544 {
545         TITLE="Run test application for linuxapp environment"
546
547         TEXT[1]="Run test application (\$RTE_TARGET/app/test)"
548         FUNC[1]="run_test_app"
549
550         TEXT[2]="Run testpmd application in interactive mode (\$RTE_TARGET/app/testpmd)"
551         FUNC[2]="run_testpmd_app"
552 }
553
554 #
555 # Other options
556 #
557 step4_func()
558 {
559         TITLE="Other tools"
560
561         TEXT[1]="List hugepage info from /proc/meminfo"
562         FUNC[1]="grep_meminfo"
563
564 }
565
566 #
567 # Options for cleaning up the system
568 #
569 step5_func()
570 {
571         TITLE="Uninstall and system cleanup"
572
573         TEXT[1]="Uninstall all targets"
574         FUNC[1]="uninstall_targets"
575
576         TEXT[2]="Unbind NICs from IGB UIO driver"
577         FUNC[2]="unbind_nics"
578
579         TEXT[3]="Remove IGB UIO module"
580         FUNC[3]="remove_igb_uio_module"
581
582         TEXT[4]="Remove VFIO module"
583         FUNC[4]="remove_vfio_module"
584
585         TEXT[5]="Remove KNI module"
586         FUNC[5]="remove_kni_module"
587
588         TEXT[6]="Remove hugepage mappings"
589         FUNC[6]="clear_huge_pages"
590 }
591
592 STEPS[1]="step1_func"
593 STEPS[2]="step2_func"
594 STEPS[3]="step3_func"
595 STEPS[4]="step4_func"
596 STEPS[5]="step5_func"
597
598 QUIT=0
599
600 while [ "$QUIT" == "0" ]; do
601         OPTION_NUM=1
602
603         for s in $(seq ${#STEPS[@]}) ; do
604                 ${STEPS[s]}
605
606                 echo "----------------------------------------------------------"
607                 echo " Step $s: ${TITLE}"
608                 echo "----------------------------------------------------------"
609
610                 for i in $(seq ${#TEXT[@]}) ; do
611                         echo "[$OPTION_NUM] ${TEXT[i]}"
612                         OPTIONS[$OPTION_NUM]=${FUNC[i]}
613                         let "OPTION_NUM+=1"
614                 done
615
616                 # Clear TEXT and FUNC arrays before next step
617                 unset TEXT
618                 unset FUNC
619
620                 echo ""
621         done
622
623         echo "[$OPTION_NUM] Exit Script"
624         OPTIONS[$OPTION_NUM]="quit"
625         echo ""
626         echo -n "Option: "
627         read our_entry
628         echo ""
629         ${OPTIONS[our_entry]} ${our_entry}
630         echo
631         echo -n "Press enter to continue ..."; read
632 done