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