diff --git a/comparecfg.sh b/comparecfg.sh new file mode 100755 index 0000000..55d8e32 --- /dev/null +++ b/comparecfg.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +showall=0 + +if [ $# -gt 0 ]; then + if [ $1 == "-a" ]; then + showall=1 + fi +fi + +chkcfg() { + + cfg=${1}; shift; + if [ ! -f ${cfg} ]; then + "cannot open ${cfg}" + return + fi + + echo + echo "===> Comparing ${cfg}" + echo + + for i in `cat ${cfg} | grep '=' | grep '\.' | sed 's/^#//' | cut -f1 -d=`; do + desc=`sysctl -nd ${i} 2>/dev/null` + cmdresult=0 + curval=`sysctl -n ${i} 2>/dev/null` + cmdresult=$? + cfgval=`grep ${i}= ${cfg} | tail -n1 | cut -f2 -d= | sed 's/\"//g'` + + if [ X${curval} != X${cfgval} ] || [ ${showall} -eq 1 ]; then + + if [ ${cmdresult} -ne 0 ]; then + curval="** sysctl returned error**" + fi + + + echo " Name: ${i}" + echo " Desc: ${desc}" + echo " Current: ${curval}" + echo " Config: ${cfgval}" + echo + fi + done +} + +chkcfg "/etc/sysctl.conf" +chkcfg "/boot/loader.conf" + diff --git a/cpuflags b/cpuflags new file mode 100755 index 0000000..ecf7d47 --- /dev/null +++ b/cpuflags @@ -0,0 +1,33 @@ +#!/bin/sh + +COMPILERS="clang gcc gcc45 gcc46 gcc47 gcc48 gcc49 gcc5 gcc6" + +check_compilers() +{ + echo "Looking for available C compilers..." + for C in ${COMPILERS} + do + P=`which ${C} 2>&1` + RES=$? + if [ $RES -eq 0 ]; then + echo " - Found ${C} at ${P}" + check_flags ${P} + echo + fi + done +} + +check_flags() +{ + C=$1; shift; + printf " Compiler flags:\t" + if `echo ${C} | grep -q clang$` + then + ${C} -march=native -E -v - < /dev/null 2>&1 | grep cc1 | grep -o -E '\-target-cpu ([a-zA-Z0-9=\-]+)' + else + ${C} -march=native -E -v - < /dev/null 2>&1 | grep cc1 | grep -o -E '\-march[=]*[a-zA-Z0-9]+' + fi +} + + +check_compilers diff --git a/getlockprof b/getlockprof new file mode 100755 index 0000000..729c266 --- /dev/null +++ b/getlockprof @@ -0,0 +1,40 @@ +#!/bin/sh + +# +# You need to make sure kernel profiling in enabled by adding +# following line to kernel configuartion and rebuilding the kernel +# and modules: +# +# options LOCK_PROFILING +# + +OUTFILE=`mktemp -t kernlock` + +if [ $# -lt 1 ]; then + echo "Syntax: $0 [ wait_seconds ]" + exit 1 +fi + +WAITTIME=${1} + +get_prof() +{ + sysctl -q debug.lock.prof.reset=1 + sysctl -q debug.lock.prof.enable=1 + echo "Profiling lock information for ${WAITTIME} seconds..." + sleep ${WAITTIME} + sysctl -q debug.lock.prof.enable=0 + sysctl debug.lock.prof.stats > ${OUTFILE} +} + +show_prof() +{ + { + head -2 ${OUTFILE} + cat ${OUTFILE} | sort -rn -k4 + } | ${PAGER} +} + +get_prof +show_prof +echo "Raw output save to ${OUTFILE}" diff --git a/getpmc.sh b/getpmc.sh new file mode 100755 index 0000000..0e821de --- /dev/null +++ b/getpmc.sh @@ -0,0 +1,43 @@ +#!/bin/sh +# +check_hwpmc() { + +# should fail if hwpmc is not availble + +} + +KERNDIR="/boot/kernel" + +# +# main +# +check_hwpmc + +if [ $# -lt 1 ]; then + echo "No event-spec given. Assuming CPU_CLK_UNHALTED_CORE..." + EVENT="CPU_CLK_UNHALTED_CORE" +else + EVENT=${1} +fi + +if [ $# -lt 2 ]; then + echo "No sleep time specified. Assuming 10 seconds..." + SLEEP="10" +else + SLEEP=${2} +fi + +echo "Instrumenting for ${SLEEP} seconds..." +pmcstat -S ${EVENT} -O ${EVENT}.pmc sleep ${SLEEP} +echo "Extracting stack trace..." +pmcstat -R ${EVENT}.pmc -z100 -G ${EVENT}.stacks.txt +echo "Annotating..." +pmcannotate -k ${KERNDIR} ${EVENT}.pmc ${KERNDIR}/kernel > ${EVENT}.annotated.txt +echo "Extracting gprof(1) profile data..." +pmcstat -R ${EVENT}.pmc -g +gprof -K ${KERNDIR}/kernel ${EVENT}/kernel.gmon > ${EVENT}.gprof-kernel.txt + +if [ -d ${EVENT} ]; then + echo "Cleaning up..." + rm -r ${EVENT} +fi diff --git a/ixirq.sh b/ixirq.sh new file mode 100755 index 0000000..95f0c57 --- /dev/null +++ b/ixirq.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# +# WARNING: Binding IRQs to a core will put system at risk of instability +# even after unbinding, and will require a reboot +# +basedir=`dirname $0` +binding="ix0:0:16 ix0:1:17 ix0:2:18 ix0:3:19 ix0:4:20 ix0:5:21 ix0:6:22 ix0:7:23 ix1:0:24 ix1:1:25 ix1:2:26 ix1:3:27 ix1:4:28 ix1:5:29 ix1:6:30 ix1:7:31" +release=0 + +# if "-r" is given as parameter, threads affinity will be unbound + +if [ $# -gt 0 ]; then + if [ $1 = "-r" ]; then + release=1 + fi +fi + + +for l in ${binding}; do + if [ -n "$l" ]; then + iface=`echo $l | cut -f 1 -d ":"` + queue=`echo $l | cut -f 2 -d ":"` + cpu=`echo $l | cut -f 3 -d ":"` + irq=`vmstat -i | grep "${iface}:que ${queue}" | cut -f 1 -d ":" | sed "s/irq//g"` + if [ $release -gt 0 ]; then + echo "Binding ${iface} queue #${queue} (irq ${irq}) -> CPU${cpu}" + cpuset -l $cpu -x $irq + else + echo "Unbinding ${iface} queue #${queue} (irq ${irq}) -> CPU${cpu}" + cpuset -l all -x $irq + fi + fi +done + diff --git a/ixque.sh b/ixque.sh new file mode 100755 index 0000000..aff971f --- /dev/null +++ b/ixque.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +# +# Bind interface queues to different cpu cores to reduce +# context switching and cpu cache misses +# + +# start from this core +cpu=0 +interfaces="ix0 ix1" +release=0 + +# if "-r" is given as parameter, threads affinity will be unbound + +if [ $# -gt 0 ]; then + if [ $1 = "-r" ]; then + release=1 + fi +fi + + +basedir=`dirname $0` +for int in ${interfaces}; do + for t in `procstat -ak | grep "${int} que" | awk '{print $2}'`; do + if [ -n "$t" ]; then + if [ $release -gt 0 ]; then + echo "Unbinding ${int} kernel queue (thread #${t})" + cpuset -l all -t $t + else + echo "Binding ${int} kernel queue (thread #${t}) -> CPU${cpu}" + cpu=`expr $cpu + 1` + cpuset -l $cpu -t $t + fi + fi + done +done + diff --git a/mbuf_autotune.sh b/mbuf_autotune.sh new file mode 100755 index 0000000..1c75d5f --- /dev/null +++ b/mbuf_autotune.sh @@ -0,0 +1,65 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Babak Farrokhi. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# +# Suggest optimum value for kern.ipc.* +# based on /sys/kern/kern_mbuf.c +# + +MCLBYTES=2048 +MSIZE=256 +PHYSMEM=`sysctl -n hw.physmem` +PAGE_SIZE=`sysctl -n hw.pagesize` +VM_KMEM_SIZE=`sysctl -n vm.kmem_size` +REALMEM=${VM_KMEM_SIZE} +MAXMBUFMEM=`expr $REALMEM / 4 \* 3` +MJUMPAGESIZE=$PAGE_SIZE +MJUM9BYTES=`expr 9 \* 1024` +MJUM16BYTES=`expr 16 \* 1024` + +NMBCLUSTERS=`expr $MAXMBUFMEM / $MCLBYTES / 4` +NMBJUMBOP=`expr $MAXMBUFMEM / $MJUMPAGESIZE / 4` +NMBJUMBO9=`expr $MAXMBUFMEM / $MJUM9BYTES / 6` +NMBJUMBO16=`expr $MAXMBUFMEM / $MJUM16BYTES / 6` + +echo "Suggested settings:" +echo "kern.ipc.maxmbufmem=$MAXMBUFMEM" +echo "kern.ipc.nmbclusters=$NMBCLUSTERS" +echo "kern.ipc.nmbjumbop=$NMBJUMBOP" +echo "kern.ipc.nmbjumbo9=$NMBJUMBO9" +echo "kern.ipc.nmbjumbo16=$NMBJUMBO16" + +NMBUFS=`sysctl -n kern.ipc.nmbufs` +NMMAX1=`expr $NMBCLUSTERS + $NMBJUMBOP + $NMBJUMBO9 + $NMBJUMBO16` +NMMAX2=`expr $MAXMBUFMEM / $MSIZE / 5` +if [ $NMMAX1 -gt $NMMAX2 ]; then + NMBUFS=$NMMAX1 +else + NMBUFX=$NMMAX2 +fi +echo "kern.ipc.nmbufs=$NMBUFS" diff --git a/munin-plugin-deploy.sh b/munin-plugin-deploy.sh new file mode 100755 index 0000000..56353a7 --- /dev/null +++ b/munin-plugin-deploy.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +MUNIN_LIBDIR="/usr/local/share/munin" +PLUGIN_PATH=${MUNIN_LIBDIR}/plugins +INSTALL_PATH=/usr/local/etc/munin/plugins +export MUNIN_LIBDIR + +# cleanup installed plugins +find ${INSTALL_PATH} -type l -delete + +# install plugins +for p in `find ${PLUGIN_PATH} -type f -perm +u+x`; do + pname=`basename $p` + if echo ${pname} | grep -q _$; then # plugin name ends with underline + params=`${p} suggest` || ( echo "failed to collect suggestion from ${pname} plugin"; exit 1) + for x in ${params}; do + ln -vs ${p} ${INSTALL_PATH}/${pname}${x} + done + else # not a wildcard plugin + ln -vs ${p} ${INSTALL_PATH}/${pname} + fi +done diff --git a/nullroute b/nullroute new file mode 100755 index 0000000..01a8b08 --- /dev/null +++ b/nullroute @@ -0,0 +1,114 @@ +#!/bin/sh +# +# Copyright (c) 2015 Babak Farrokhi. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# this script nullroutes a give CIDR +# +# + +ROUTE="/sbin/route" +NETSTAT="/usr/bin/netstat" +GREP="/usr/bin/grep" +AWK="/usr/bin/awk" +CFG="/usr/local/etc/nullroute.conf" + +nullroute() { + local ADDR=${1}; shift; + + ${ROUTE} add -net ${ADDR} 127.0.0.1 -blackhole +} + +delroute() { + local ADDR=${1}; shift; + + ${ROUTE} delete ${ADDR} +} + +showroute() { + ${NETSTAT} -rn | ${GREP} "SB " | ${AWK} '{print $1}' +} + +loadroutes() { + if [ ! -f ${CFG} ]; then + echo "Cannot open ${CFG}" + exit 1 + fi + + for R in `cat ${CFG} | ${GREP} -E -v '^[[:space:]]*$'`; do + nullroute ${R} + done +} + +saveroutes() { + showroute > ${CFG} && echo "configuration saved to ${CFG}" +} + +flush() { + for R in `${NETSTAT} -rn | ${GREP} "SB " | ${AWK} '{print $1}'`; do + delroute ${R} + done +} + +help() { + echo "$0 [ add | del | show | load | save | flush ]" +} + +if [ $# -lt 1 ]; then + help + exit 1 +fi + +case ${1} in + add) + if [ x${2} == x ]; then + help + exit 1 + fi + nullroute ${2} + ;; + del) + if [ x${2} == x ]; then + help + exit 1 + fi + delroute ${2} + ;; + show) + showroute + ;; + load) + loadroutes + ;; + save) + saveroutes + ;; + flush) + flush + ;; + *) + help + ;; +esac + diff --git a/splitgateway b/splitgateway new file mode 100755 index 0000000..d7a7dbc --- /dev/null +++ b/splitgateway @@ -0,0 +1,37 @@ +#!/bin/sh +# +# Split default route into 8 smaller routes to avoid +# lock contention during route lookup +# +# If a default router is not specified, it will be +# taken from rc.conf. +# + +ROUTECMD="/sbin/route -q " +ROUTES="0.0.0.0/3 32.0.0.0/3 64.0.0.0/3 96.0.0.0/3 128.0.0.0/3 160.0.0.0/3 192.0.0.0/3 224.0.0.0/3" + +if [ $# -lt 1 ]; then + echo "syntax: $0 [start|stop]" + exit 1 +fi + +case $1 in + start) + GW=`sysrc -n defaultrouter` + echo "splitgateway: Assuming ${GW} from rc.conf..." + + for R in ${ROUTES}; do + ${ROUTECMD} add -net ${R} ${GW} + done + ;; + stop) + for R in ${ROUTES}; do + ${ROUTECMD} delete -net ${R} + done + ;; +esac + + +# no need to remove default route since it will never be matched +#${ROUTECMD} delete default + diff --git a/tuning b/tuning new file mode 100755 index 0000000..b54ade7 --- /dev/null +++ b/tuning @@ -0,0 +1,270 @@ +#!/bin/sh + +# Strict script +set -e +set -u + +# Global variables +HOST=false +ROUTER=false + +# Get options passed by user +getoption () { + if [ $# -ge 1 ]; then + FIRST_OPTION="$1" + else + usage + exit 1 + fi + case "$FIRST_OPTION" in + host) + HOST=true + ;; + router) + ROUTER=true + ;; + help) + usage + exit 0 + ;; + esac +} + +usage () { + # Display usage + echo "Usage: $0 option" + echo " option can be:" + echo " -host: tuning tips for end-host" + echo " -router: tuning tips for router" + echo " -help: display this help" +} + +sysctl_atleast () { + # Check the sysctl parameter is at least configured to the value + # $1: sysctl parameter + # $2: recommended value + if [ `sysctl -n $1` -lt $2 ]; then + echo "$1=\"$2\"" + fi +} + +sysctl_equal () { + # Check the sysctl parameter match (equal) the value + # $1: sysctl parameter + # $2: recommended value + if [ `sysctl -n $1` -ne $2 ]; then + echo "$1=\"$2\"" + fi +} + +if_have_cap () { + # Check if the interface have capabilities and if it's enabled return true (0) + # $1: if + # $2: capability + ifconfig -m $1 | egrep -q "capabilities.*$2" && return 0 || return 1 +} + +if_is_cap_enabled () { + # Check if the interface capability is enabled: return true + # $1: if + # $2: capability + ifconfig -m $1 | egrep -q "options.*$2" && return 0 || return 1 +} + +tune () { + # Major function that call the others + # RO values need to be put in /boot/loader.conf.local + # RW values need to be put in /etc/sysctl.conf + echo "#==> Start of /boot/loader.conf.local" + echo "#TO DO All these values doesn't works here and need to be put in /etc/sysctl.conf" + net_nic + ($ROUTER) && net_forward + ($ROUTER) && net_inet + ($ROUTER) && cpu_ht + net_netisr + # Autombuf tunning avoid the need fo checking them + # net_mbuf + echo "#<== End of /boot/loader.conf.local" + net_netstat + echo "#==> To be added to /etc/rc.conf" + #Need to replace this part by a list of modules (ichsmb coretemp aesni watchdog?) + if grep -q 'Feature.*AESNI' /var/run/dmesg.boot ; then + #CPU support, check if not allready loaded + if ! kldstat -n aesni 2>&1 | grep -q aesni; then + echo "#CPU has AESNI feature, you should load the modules" + echo 'kld_list="cryptodev aesni"' + fi + fi + for NIC in `ifconfig -l "ether"`; do + #skip loopback interfaces + echo $NIC | egrep -q "lo[[:digit:]]" && continue + # Check only interface with vlan configured on them + if egrep -q "ifconfig_vlan.*${NIC}" /etc/rc.conf; then + if if_have_cap ${NIC} VLAN_HWFILTER; then + if ! if_is_cap_enabled ${NIC} VLAN_HWFILTER; then + echo "${NIC} configured with vlan and support VLAN_HWFILTER" + echo " => add the vlanhwfilter option to ifconfig_${NIC} in /etc/rc.conf" + fi + fi # if_have_cap + fi # rc.conf + # Router should not have LRO/TSO4/TSO6 enabled + if ($ROUTER); then + for CAP in LRO TSO4 TSO6; do + if_is_cap_enabled ${NIC} ${CAP} && \ + echo "A router MUST NOT have ${CAP} enabled on forwarding NIC" + done + fi + # Check for virtualized + if (${VM_DETECTED}); then + if if_have_cap ${NIC} POLLING; then + if ! if_is_cap_enabled ${NIC} POLLING; then + # http://lists.freebsd.org/pipermail/freebsd-net/2013-May/035626.html + echo "In VM, ${NIC} can have better behavior if POLLING was enabled" + echo " => Enable polling in /etc/rc.conf.misc" + fi + fi + # need disable hardware assisted features (need to found reference about this tip) + for CAP in RXCSUM TXCSUM TSO4 TSO6; do + if_is_cap_enabled ${NIC} ${CAP} && \ + echo "${NIC} have ${CAP} enabled: Disable it in a VM" + done # end for CAP + fi + done + +} + +cpu_ht () { + # Check if HyperThreading is enabled + grep -q "^FreeBSD/SMP.*SMT" /var/run/dmesg.boot && echo "You should disable HyperThreading" +} + +net_nic () { + # NIC drivers tuning + # em tuning + if ifconfig -l "ether" | egrep -q 'em[[:digit:]]'; then + # Need to check if there are not 82542 or 82543 (support 256 max) + for VALUE in hw.em.txd hw.em.rxd; do + sysctl_equal ${VALUE} 2048 + done + # Disabling limit of rx frame + #sysctl_atleast hw.em.rx_process_limit 500 + sysctl_equal hw.em.rx_process_limit -1 + # Increasing interrupt delay is bad for a router because it add latency + # http://www.intel.com/design/network/applnots/ap450.htm + if ! ($ROUTER); then + for VALUE in hw.em.rx_abs_int_delay hw.em.tx_abs_int_delay; do + sysctl_equal ${VALUE} 1024 + done + for VALUE in hw.em.rx_int_delay hw.em.tx_int_delay; do + sysctl_equal ${VALUE} 512 + done + fi + fi + # igb tuning + if ifconfig -l "ether" | egrep -q 'igb[[:digit:]]'; then + for VALUE in hw.igb.txd hw.igb.rxd; do + sysctl_equal ${VALUE} 2048 + done + # http://wiki.freebsd.org/NetworkPerformanceTuning + sysctl_atleast hw.igb.max_interrupt_rate 32000 + # Need mbuf be increased if rx_process limit increased? + #sysctl_atleast hw.igb.rx_process_limit 500 + # Disabling limit of rx frame + sysctl_equal hw.igb.rx_process_limit -1 + # Default kern.ipc.nmbclusters is too small for multiple igb card and multicore + # Need to add a test [ `sysctl -n hw.ncpu` -gt 1 ] and arch (i386 don't like too much) + [ `sysctl -n hw.ncpu` -ge 4 ] && sysctl_atleast kern.ipc.nmbclusters 262144 + fi + # ixgbe tuning + if ifconfig -l "ether" | egrep -q 'ix[[:digit:]]'; then + # source: README in drivers source + # When using the ixgbe driver with RSS autoconfigured based on the number of + # cores (the default setting) and that number is larger than 4, increase the + # memory resources allocated for the mbuf pool as follows: + # Warning: Where to put this valuedepends if drivers is a module or in kernel + if [ `sysctl -n hw.ncpu` -ge 4 ]; then + #loader.conf ? + sysctl_atleast kern.ipc.nmbclusters 262144 + #sysctl.conf ? + sysctl_atleast kern.ipc.nmbjumbop 262144 + fi + fi + # General + # default value of send interface queue length + # If em or igb were tunned, need to change this too + # http://lists.freebsd.org/pipermail/freebsd-net/2012-July/032712.html + sysctl_atleast net.link.ifqmaxlen 10240 + + # cxgbe (Chelsio) tuning + if ifconfig -l "ether" | egrep -q 'cxl[[:digit:]]'; then + # source: http://bsdrp.net/documentation/examples/forwarding_performance_lab_of_a_hp_proliant_dl360p_gen8_with_10-gigabit_with_10-gigabit_chelsio_t540-cr + # If ncpu=8 and drivers is using 8 queue (default), should reduce the NIC queue to 4 + if [ `sysctl -n hw.ncpu` -eq 8 ]; then + [ `sysctl -n dev.cxl.0.nrxq` -eq 8 ] && echo 'echo hw.cxgbe.nrxq10g="4" >> /boot/loader.conf.local' + [ `sysctl -n dev.cxl.0.ntxq` -eq 8 ] && echo 'echo hw.cxgbe.ntxq10g="4" >> /boot/loader.conf.local' + fi + fi +} + +net_netstat () { + # Analysing netstat -m output and provide advice regarding the result + echo "TODO: netstat" +} + +net_forward () { + # http://wiki.freebsd.org/NetworkPerformanceTuning + sysctl_equal net.inet.ip.forwarding 1 + if [ `sysrc -n ipsec_enable` == "YES" ]; then + sysctl_equal net.inet.ip.fastforwarding 0 + echo "IPSec configuration detected" + echo "Check if your hardware support one of these crypto accelerator modules:" + echo " aesni(4), glxsb(4), hifn(4), ipsec(4), padlock(4), safe(4) or ubsec(4)" + fi +} + +net_inet () { + # http://wiki.freebsd.org/NetworkPerformanceTuning + for VALUE in net.inet.raw.maxdgram net.inet.raw.recvspace; do + sysctl_atleast ${VALUE} 16384 + done + for VALUE in net.inet.ip.redirect; do + sysctl_equal ${VALUE} 0 + done +} + +net_netisr () { + # http://wiki.freebsd.org/NetworkPerformanceTuning + sysctl_atleast net.route.netisr_maxqlen 2048 +} + +net_mbuf () { + # kern.ipc.nmbclusters must be increased if multiple igb (man igb) + # Need to calculate (regarding RAM size) this value + # Does vm.kmem_size should be upgraded too ? + # igb loads 8 rings, each of 1024 per NIC + sysctl_atleast kern.ipc.nmbclusters 262144 + echo "On the following output, with all your NIC already configured" + echo " check the current and total" + netstat -m | grep "mbuf clusters in use" +} + + + +timecounter () { + # Are the timecounter tuning usefull ? + TIMECOUTER_CHOICE=`sysctl -n sysctl kern.timecounter.choice` + if echo "${TIMECOUTER_CHOICE}" | grep -q "HPET" ; then + sysctl -n kern.timecounter.hardware | grep -q HPET || \ + echo "sysctl kern.timecounter.hardware=HPET" + fi +} +################### +## Main function ## +################### + +getoption $* +#system_inventory +# Look for VM environnement +sysctl -n kern.vm_guest | grep -q -v "none" && VM_DETECTED=true || VM_DETECTED=false +tune +echo "Done!"