From defe460d44b639aa865ec3afc9c647f9a6093de0 Mon Sep 17 00:00:00 2001 From: coolsnowwolf Date: Wed, 1 Jul 2020 12:49:28 +0800 Subject: [PATCH] ipq40xx: import irq-balance script from presisco/openwrt-irq-balance --- target/linux/ipq40xx/Makefile | 2 +- .../base-files/etc/init.d/adjust_network | 205 +++++++++++++++++- .../ipq40xx/base-files/lib/adjust_network.sh | 86 -------- 3 files changed, 197 insertions(+), 96 deletions(-) delete mode 100644 target/linux/ipq40xx/base-files/lib/adjust_network.sh diff --git a/target/linux/ipq40xx/Makefile b/target/linux/ipq40xx/Makefile index e99d40f1f..d2696b771 100644 --- a/target/linux/ipq40xx/Makefile +++ b/target/linux/ipq40xx/Makefile @@ -20,6 +20,6 @@ DEFAULT_PACKAGES += \ kmod-ath10k wpad-openssl \ kmod-usb3 kmod-usb-dwc3 ath10k-firmware-qca4019 \ automount autosamba luci-app-ipsec-vpnd luci-app-unblockmusic luci-app-cpufreq luci-app-zerotier luci-app-xlnetacc \ - htop fdisk e2fsprogs + htop fdisk e2fsprogs ethtool $(eval $(call BuildTarget)) diff --git a/target/linux/ipq40xx/base-files/etc/init.d/adjust_network b/target/linux/ipq40xx/base-files/etc/init.d/adjust_network index 788b833ff..6089259e5 100755 --- a/target/linux/ipq40xx/base-files/etc/init.d/adjust_network +++ b/target/linux/ipq40xx/base-files/etc/init.d/adjust_network @@ -1,18 +1,205 @@ #!/bin/sh /etc/rc.common # Copyright (C) 2006-2011 OpenWrt.org -START=11 +START=99 STOP=98 -adjust_smp_affinity() { - test -f /lib/adjust_network.sh && { - . /lib/adjust_network.sh +rps_flow_cnt=4096 +core_count=$(grep -c processor /proc/cpuinfo) +rps_sock_flow_ent=`expr $core_count \* $rps_flow_cnt` +queue_cores="0 1 2" +queue_irq_cores="1 2" +wifi_core="3" +usb_core="0" - adjust_edma_smp_affinity - adjust_radio_smp_affinity - } +############### util functions ############### + +to_hex_list() { + local cores=$1 + local converted="" + for core in $(echo $cores | awk '{print}') + do + local hex="$(gen_hex_mask "$core")" + converted="$converted $hex" + done + echo `echo $converted | sed 's/^ *//'` } -boot() { - adjust_smp_affinity +gen_hex_mask() { + local cores=$1 + local mask=0 + for core in $(echo $cores | awk '{print}') + do + local bit="$((1 << $core))" + let "mask = mask + bit" + done + local hex="$(printf %x "$mask")" + echo "$hex" } + +val_at_index() { + local values=$1 + local idx=$2 + echo `echo $values | awk -v i=$idx '{print $i}'` +} + +size_of_list() { + local list=$1 + local spaces=`echo $list | grep -o ' ' | wc -l` + echo `expr $spaces + 1` +} + +set_core_mask() { + local file=$1 + local cores=$2 + local mask="$(gen_hex_mask "$cores")" + echo $mask > $file +} + +set_core_mask_round() { + local files=$1 + local cores=$2 + local step_size=$3 + [ ! -n "$3" ] && step_size=1 + + local core_count="$(size_of_list "$cores")" + local counter=0 + local idx=1 + local roof=`expr $core_count \* $step_size` + for file in $(echo $files | awk '{print}') + do + let "idx = counter / step_size + 1" + local core="$(val_at_index "$cores" $idx)" + set_core_mask $file $core + let "counter = counter + 1" + [ $counter -ge $roof ] && counter=0 + done +} + +############### assign network queues ############### + +set_interface_round() { + local interface=$1 + local cores=$2 + local step_size=$3 + [ ! -n "$3" ] && step_size=1 + + echo "using round mask for interface: $interface, step size: $step_size" + set_core_mask_round "$(ls /sys/class/net/$interface/queues/tx-*/xps_cpus)" "$cores" $step_size + set_core_mask_round "$(ls /sys/class/net/$interface/queues/rx-*/rps_cpus)" "$cores" $step_size + + for file in /sys/class/net/$interface/queues/rx-[0-9]*/rps_flow_cnt + do + echo $rps_flow_cnt > $file + done +} + +set_interface() { + local interface=$1 + local cores=$2 + + echo "using cores: $cores for interface: $interface" + + for file in /sys/class/net/$interface/queues/rx-[0-9]*/rps_cpus + do + set_core_mask $file "$cores" + echo $rps_flow_cnt > `dirname $file`/rps_flow_cnt + done + + for file in /sys/class/net/$interface/queues/tx-[0-9]*/xps_cpus + do + set_core_mask $file "$cores" + done +} + +set_interface_queues() { + echo "using cpu: $queue_cores for network queues" + for dev in /sys/class/net/eth* + do + [ -d "$dev" ] || continue + + local interface=`basename $dev` + + set_interface $interface "$queue_cores" + done + + for dev in /sys/class/net/wlan* + do + [ -d "$dev" ] || continue + + local interface=`basename $dev` + + set_interface $interface "$queue_cores" + done + + for dev in /sys/class/net/eth* + do + local eth=`basename $dev` + echo "enabling offload on $eth" + ethtool -K $eth rx-checksum on >/dev/null 2>&1 + ethtool -K $eth tx-checksum-ip-generic on >/dev/null 2>&1 || ( + ethtool -K $eth tx-checksum-ipv4 on >/dev/null 2>&1 + ethtool -K $eth tx-checksum-ipv6 on >/dev/null 2>&1) + ethtool -K $eth tx-scatter-gather on >/dev/null 2>&1 + ethtool -K $eth gso on >/dev/null 2>&1 + ethtool -K $eth gro on >/dev/null 2>&1 + ethtool -K $eth lro on >/dev/null 2>&1 + ethtool -K $eth tso on >/dev/null 2>&1 + ethtool -K $eth ufo on >/dev/null 2>&1 + done + + echo $rps_sock_flow_ent > /proc/sys/net/core/rps_sock_flow_entries + sysctl -w net.core.rps_sock_flow_entries=$rps_sock_flow_ent +} + +############### assign interrupts ############### +set_irq_cores() { + local mask="$(gen_hex_mask "$2")" + echo "set mask $mask for irq: $1" + echo $mask > "/proc/irq/$1/smp_affinity" +} + +set_irq_pattern() { + local name_pattern="$1" + local cores="$2" + + for irq in `grep "$name_pattern" /proc/interrupts | cut -d: -f1 | sed 's, *,,'` + do + set_irq_cores $irq "$cores" + done +} + +set_irq_interleave() { + local name_pattern=$1 + local cores=$2 + local step_size=$3 + + local files="" + for irq in `grep "$name_pattern" /proc/interrupts | cut -d: -f1 | sed 's, *,,'` + do + files="$files\ + /proc/irq/$irq/smp_affinity" + done + + set_core_mask_round "$files" "$cores" "$step_size" +} + +set_irqs() { + #dma + set_irq_pattern bam_dma "$usb_core" + + #ethernet + set_irq_interleave eth_tx "$queue_irq_cores" 4 + set_irq_interleave eth_rx "$queue_irq_cores" 1 + + #pcie + set_irq_pattern pcie "$wifi_core" + + #usb + set_irq_pattern usb "$usb_core" +} + +start() { + set_interface_queues + set_irqs +} \ No newline at end of file diff --git a/target/linux/ipq40xx/base-files/lib/adjust_network.sh b/target/linux/ipq40xx/base-files/lib/adjust_network.sh deleted file mode 100644 index 95ffedc04..000000000 --- a/target/linux/ipq40xx/base-files/lib/adjust_network.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/bin/sh -# this scripts is used for adjust cpu's choice of interrupts. -# - -################################################ -# Adjust smp_affinity of edma -# Globals: -# None -# Arguments: -# None -# Returns: -# None -# Remark: -# execute only once on start-up. -################################################ -adjust_edma_smp_affinity() { - grep -q edma_eth_ /proc/interrupts || return 0 - local nr=`cat /proc/cpuinfo | grep processor | wc -l` - local cpu=0 - local tx_irq_num - - for tx_num in `seq 0 1 15` ; do - cpu=`printf "%x" $((1<<((tx_num/4+3)%nr)))` - tx_irq_num=`grep -m1 edma_eth_tx$tx_num /proc/interrupts | cut -d ':' -f 1 | tail -n1 | tr -d ' '` - [ -n "$tx_irq_num" ] && echo $cpu > /proc/irq/$tx_irq_num/smp_affinity - done - - for rx_num in `seq 0 1 7` ; do - cpu=`printf "%x" $((1<<((rx_num/2)%nr)))` - rx_irq_num=`grep -m1 edma_eth_rx$rx_num /proc/interrupts | cut -d ':' -f 1 | tail -n1 | tr -d ' '` - [ -n "$rx_irq_num" ] && echo $cpu > /proc/irq/$rx_irq_num/smp_affinity - done -} - -################################################ -# Adjust smp_affinity of ath10k for 2G and 5G -# Globals: -# None -# Arguments: -# None -# Returns: -# None -# Remark: -# execute only once on start-up. -################################################ -adjust_radio_smp_affinity() { - local irqs="`grep -E 'ath10k' /proc/interrupts | cut -d ':' -f 1 | tr -d ' '`" - local nr=`cat /proc/cpuinfo | grep processor | wc -l` - local idx=2 - - for irq in $irqs; do - cpu=`printf "%x" $((1<<((idx)%nr)))` - echo $cpu > /proc/irq/$irq/smp_affinity - idx=$((idx+1)) - done -} - -################################################ -# Adjust queue of eth -# Globals: -# None -# Arguments: -# None -# Returns: -# None -# Remark: -# Each network reboot needs to be executed. -################################################ -adjust_eth_queue() { - local nr=`cat /proc/cpuinfo | grep processor | wc -l` - local cpu=`printf "%x" $(((1< $exps - echo 256 > `dirname $exps`/rps_flow_cnt - done - which ethtool >/dev/null 2>&1 && ethtool -K $eth gro off - done - - echo 1024 > /proc/sys/net/core/rps_sock_flow_entries -}