271 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			271 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|  | #!/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!" |