a2c38062068524d45a2195b301357b9cd956b0f2
[dpdk.git] / tools / setup.sh
1 #! /bin/bash
2
3 #   BSD LICENSE
4
5 #   Copyright(c) 2010-2013 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 #
36 # Run with "source /path/to/setup.sh"
37 #
38
39 #
40 # Change to DPDK directory ( <this-script's-dir>/.. ), and export it as RTE_SDK
41 #
42 cd $(dirname ${BASH_SOURCE[0]})/..
43 export RTE_SDK=$PWD
44 echo "------------------------------------------------------------------------------"
45 echo " RTE_SDK exported as $RTE_SDK"
46 echo "------------------------------------------------------------------------------"
47
48 #
49 # Application EAL parameters for setting memory options (amount/channels/ranks).
50 #
51 EAL_PARAMS='-n 4'
52
53 #
54 # Sets QUIT variable so script will finish.
55 #
56 quit()
57 {
58         QUIT=$1
59 }
60
61 #
62 # Sets up environmental variables for ICC.
63 #
64 setup_icc()
65 {
66         DEFAULT_PATH=/opt/intel/bin/iccvars.sh
67         param=$1
68         shpath=`which iccvars.sh 2> /dev/null`
69         if [ $? -eq 0 ] ; then
70                 echo "Loading iccvars.sh from $shpath for $param"
71                 source $shpath $param
72         elif [ -f $DEFAULT_PATH ] ; then
73                 echo "Loading iccvars.sh from $DEFAULT_PATH for $param"
74                 source $DEFAULT_PATH $param
75         else
76                 echo "## ERROR: cannot find 'iccvars.sh' script to set up ICC."
77                 echo "##     To fix, please add the directory that contains"
78                 echo "##     iccvars.sh  to your 'PATH' environment variable."
79                 quit
80         fi
81 }
82
83 #
84 # Sets RTE_TARGET and does a "make install".
85 #
86 setup_target()
87 {
88         option=$1
89         export RTE_TARGET=${TARGETS[option]}
90
91         compiler=${RTE_TARGET##*-}
92         if [ "$compiler" == "icc" ] ; then
93                 platform=${RTE_TARGET%%-*}
94                 if [ "$platform" == "x86_64" ] ; then
95                         setup_icc intel64
96                 else
97                         setup_icc ia32
98                 fi
99         fi
100         if [ "$QUIT" == "0" ] ; then
101                 make install T=${RTE_TARGET}
102         fi
103         echo "------------------------------------------------------------------------------"
104         echo " RTE_TARGET exported as $RTE_TARGET"
105         echo "------------------------------------------------------------------------------"
106 }
107
108 #
109 # Uninstall all targets.
110 #
111 uninstall_targets()
112 {
113         make uninstall
114 }
115
116 #
117 # Creates hugepage filesystem.
118 #
119 create_mnt_huge()
120 {
121         echo "Creating /mnt/huge and mounting as hugetlbfs"
122         sudo mkdir -p /mnt/huge
123
124         grep -s '/mnt/huge' /proc/mounts > /dev/null
125         if [ $? -ne 0 ] ; then
126                 sudo mount -t hugetlbfs nodev /mnt/huge
127         fi
128 }
129
130 #
131 # Removes hugepage filesystem.
132 #
133 remove_mnt_huge()
134 {
135         echo "Unmounting /mnt/huge and removing directory"
136         grep -s '/mnt/huge' /proc/mounts > /dev/null
137         if [ $? -eq 0 ] ; then
138                 sudo umount /mnt/huge
139         fi
140
141         if [ -d /mnt/huge ] ; then
142                 sudo rm -R /mnt/huge
143         fi
144 }
145
146 #
147 # Unloads igb_uio.ko.
148 #
149 remove_igb_uio_module()
150 {
151         echo "Unloading any existing DPDK UIO module"
152         /sbin/lsmod | grep -s igb_uio > /dev/null
153         if [ $? -eq 0 ] ; then
154                 sudo /sbin/rmmod igb_uio
155         fi
156 }
157
158 #
159 # Loads new igb_uio.ko (and uio module if needed).
160 #
161 load_igb_uio_module()
162 {
163         if [ ! -f $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko ];then
164                 echo "## ERROR: Target does not have the DPDK UIO Kernel Module."
165                 echo "       To fix, please try to rebuild target."
166                 return
167         fi
168
169         remove_igb_uio_module
170
171         /sbin/lsmod | grep -s uio > /dev/null
172         if [ $? -ne 0 ] ; then
173                 if [ -f /lib/modules/$(uname -r)/kernel/drivers/uio/uio.ko ] ; 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 the rte_kni.ko module.
192 #
193 remove_kni_module()
194 {
195         echo "Unloading any existing DPDK KNI module"
196         /sbin/lsmod | grep -s rte_kni > /dev/null
197         if [ $? -eq 0 ] ; then
198                 sudo /sbin/rmmod rte_kni
199         fi
200 }
201
202 #
203 # Loads the rte_kni.ko module.
204 #
205 load_kni_module()
206 {
207     # Check that the KNI module is already built.
208         if [ ! -f $RTE_SDK/$RTE_TARGET/kmod/rte_kni.ko ];then
209                 echo "## ERROR: Target does not have the DPDK KNI Module."
210                 echo "       To fix, please try to rebuild target."
211                 return
212         fi
213
214     # Unload existing version if present.
215         remove_kni_module
216
217     # Now try load the KNI module.
218         echo "Loading DPDK KNI module"
219         sudo /sbin/insmod $RTE_SDK/$RTE_TARGET/kmod/rte_kni.ko
220         if [ $? -ne 0 ] ; then
221                 echo "## ERROR: Could not load kmod/rte_kni.ko."
222                 quit
223         fi
224 }
225
226 #
227 # Removes all reserved hugepages.
228 #
229 clear_huge_pages()
230 {
231         echo > .echo_tmp
232         for d in /sys/devices/system/node/node? ; do
233                 echo "echo 0 > $d/hugepages/hugepages-2048kB/nr_hugepages" >> .echo_tmp
234         done
235         echo "Removing currently reserved hugepages"
236         sudo sh .echo_tmp
237         rm -f .echo_tmp
238
239         remove_mnt_huge
240 }
241
242 #
243 # Creates hugepages.
244 #
245 set_non_numa_pages()
246 {
247         clear_huge_pages
248
249         echo ""
250         echo "  Input the number of 2MB pages"
251         echo "  Example: to have 128MB of hugepages available, enter '64' to"
252         echo "  reserve 64 * 2MB pages"
253         echo -n "Number of pages: "
254         read Pages
255
256         echo "echo $Pages > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages" > .echo_tmp
257
258         echo "Reserving hugepages"
259         sudo sh .echo_tmp
260         rm -f .echo_tmp
261
262         create_mnt_huge
263 }
264
265 #
266 # Creates hugepages on specific NUMA nodes.
267 #
268 set_numa_pages()
269 {
270         clear_huge_pages
271
272         echo ""
273         echo "  Input the number of 2MB pages for each node"
274         echo "  Example: to have 128MB of hugepages available per node,"
275         echo "  enter '64' to reserve 64 * 2MB pages on each node"
276
277         echo > .echo_tmp
278         for d in /sys/devices/system/node/node? ; do
279                 node=$(basename $d)
280                 echo -n "Number of pages for $node: "
281                 read Pages
282                 echo "echo $Pages > $d/hugepages/hugepages-2048kB/nr_hugepages" >> .echo_tmp
283         done
284         echo "Reserving hugepages"
285         sudo sh .echo_tmp
286         rm -f .echo_tmp
287
288         create_mnt_huge
289 }
290
291 #
292 # Run unit test application.
293 #
294 run_test_app()
295 {
296         echo ""
297         echo "  Enter hex bitmask of cores to execute test app on"
298         echo "  Example: to execute app on cores 0 to 7, enter 0xff"
299         echo -n "bitmask: "
300         read Bitmask
301         echo "Launching app"
302         sudo ${RTE_TARGET}/app/test -c $Bitmask $EAL_PARAMS
303 }
304
305 #
306 # Run unit testpmd application.
307 #
308 run_testpmd_app()
309 {
310         echo ""
311         echo "  Enter hex bitmask of cores to execute testpmd app on"
312         echo "  Example: to execute app on cores 0 to 7, enter 0xff"
313         echo -n "bitmask: "
314         read Bitmask
315         echo "Launching app"
316         sudo ${RTE_TARGET}/app/testpmd -c $Bitmask $EAL_PARAMS -- -i
317 }
318
319 #
320 # Print hugepage information.
321 #
322 grep_meminfo()
323 {
324         grep -i huge /proc/meminfo
325 }
326
327 #
328 # Calls pci_unbind.py --status to show the NIC and what they
329 # are all bound to, in terms of drivers.
330 #
331 show_nics()
332 {
333         if  /sbin/lsmod  | grep -q igb_uio ; then 
334                 ${RTE_SDK}/tools/pci_unbind.py --status
335         else 
336                 echo "# Please load the 'igb_uio' kernel module before querying or "
337                 echo "# adjusting NIC device bindings"
338         fi
339 }
340
341 #
342 # Uses pci_unbind.py to move devices to work with igb_uio
343 #
344 bind_nics()
345 {
346         if  /sbin/lsmod  | grep -q igb_uio ; then 
347                 ${RTE_SDK}/tools/pci_unbind.py --status
348                 echo ""
349                 echo -n "Enter PCI address of device to bind to IGB UIO driver: "
350                 read PCI_PATH
351                 sudo ${RTE_SDK}/tools/pci_unbind.py -b igb_uio $PCI_PATH && echo "OK"
352         else 
353                 echo "# Please load the 'igb_uio' kernel module before querying or "
354                 echo "# adjusting NIC device bindings"
355         fi
356 }
357
358 #
359 # Uses pci_unbind.py to move devices to work with kernel drivers again
360 #
361 unbind_nics()
362 {
363         ${RTE_SDK}/tools/pci_unbind.py --status
364         echo ""
365         echo -n "Enter PCI address of device to bind to IGB UIO driver: "
366         read PCI_PATH
367         echo ""
368         echo -n "Enter name of kernel driver to bind the device to: "
369         read DRV
370         sudo ${RTE_SDK}/tools/pci_unbind.py -b $DRV $PCI_PATH && echo "OK"
371 }
372
373 #
374 # Options for building a target. Note that this step MUST be first as it sets
375 # up TARGETS[] starting from 1, and this is accessed in setup_target using the
376 # user entered option.
377 #
378 step1_func()
379 {
380         TITLE="Select the DPDK environment to build"
381         CONFIG_NUM=1
382         for cfg in config/defconfig_* ; do
383                 cfg=${cfg/config\/defconfig_/}
384                 TEXT[$CONFIG_NUM]="$cfg"
385                 TARGETS[$CONFIG_NUM]=$cfg
386                 FUNC[$CONFIG_NUM]="setup_target"
387                 let "CONFIG_NUM+=1"
388         done
389 }
390
391 #
392 # Options for setting up environment.
393 #
394 step2_func()
395 {
396         TITLE="Setup linuxapp environment"
397
398         TEXT[1]="Insert IGB UIO module"
399         FUNC[1]="load_igb_uio_module"
400
401         TEXT[2]="Insert KNI module"
402         FUNC[2]="load_kni_module"
403
404         TEXT[3]="Setup hugepage mappings for non-NUMA systems"
405         FUNC[3]="set_non_numa_pages"
406
407         TEXT[4]="Setup hugepage mappings for NUMA systems"
408         FUNC[4]="set_numa_pages"
409
410         TEXT[5]="Display current Ethernet device settings"
411         FUNC[5]="show_nics"
412
413         TEXT[6]="Bind Ethernet device to IGB UIO module"
414         FUNC[6]="bind_nics"
415 }
416
417 #
418 # Options for running applications.
419 #
420 step3_func()
421 {
422         TITLE="Run test application for linuxapp environment"
423
424         TEXT[1]="Run test application (\$RTE_TARGET/app/test)"
425         FUNC[1]="run_test_app"
426
427         TEXT[2]="Run testpmd application in interactive mode (\$RTE_TARGET/app/testpmd)"
428         FUNC[2]="run_testpmd_app"
429 }
430
431 #
432 # Other options
433 #
434 step4_func()
435 {
436         TITLE="Other tools"
437
438         TEXT[1]="List hugepage info from /proc/meminfo"
439         FUNC[1]="grep_meminfo"
440
441 }
442
443 #
444 # Options for cleaning up the system
445 #
446 step5_func()
447 {
448         TITLE="Uninstall and system cleanup"
449
450         TEXT[1]="Uninstall all targets"
451         FUNC[1]="uninstall_targets"
452
453         TEXT[2]="Unbind NICs from IGB UIO driver"
454         FUNC[2]="unbind_nics"
455
456         TEXT[3]="Remove IGB UIO module"
457         FUNC[3]="remove_igb_uio_module"
458
459         TEXT[4]="Remove KNI module"
460         FUNC[4]="remove_kni_module"
461
462         TEXT[5]="Remove hugepage mappings"
463         FUNC[5]="clear_huge_pages"
464 }
465
466 STEPS[1]="step1_func"
467 STEPS[2]="step2_func"
468 STEPS[3]="step3_func"
469 STEPS[4]="step4_func"
470 STEPS[5]="step5_func"
471
472 QUIT=0
473
474 while [ "$QUIT" == "0" ]; do
475         OPTION_NUM=1
476
477         for s in $(seq ${#STEPS[@]}) ; do
478                 ${STEPS[s]}
479
480                 echo "----------------------------------------------------------"
481                 echo " Step $s: ${TITLE}"
482                 echo "----------------------------------------------------------"
483
484                 for i in $(seq ${#TEXT[@]}) ; do
485                         echo "[$OPTION_NUM] ${TEXT[i]}"
486                         OPTIONS[$OPTION_NUM]=${FUNC[i]}
487                         let "OPTION_NUM+=1"
488                 done
489
490                 # Clear TEXT and FUNC arrays before next step
491                 unset TEXT
492                 unset FUNC
493
494                 echo ""
495         done
496
497         echo "[$OPTION_NUM] Exit Script"
498         OPTIONS[$OPTION_NUM]="quit"
499         echo ""
500         echo -n "Option: "
501         read our_entry
502         echo ""
503         ${OPTIONS[our_entry]} ${our_entry}
504         echo
505         echo -n "Press enter to continue ..."; read
506 done