mirror of
https://github.com/qosmio/nss-packages.git
synced 2025-12-17 00:33:40 +00:00
Reworked flawed smp_affinity logic. It was assumed that all 'nss_*' IRQs needed to be equally balanced across all CPUs. However, what ends up happening most of the time is messing with scheduling, thrashing, missed cache and high context switching. For each core: 1. nss_empty_buf_sos 2. nss_empty_buf_queue 3. nss_queue0 The IRQs should be kept on the same CPU. Doing so allows NSS cores to properly feed and empty the queues. Signed-off-by: Sean Khan <datapronix@protonmail.com>
136 lines
3.7 KiB
Bash
136 lines
3.7 KiB
Bash
#!/bin/sh /etc/rc.common
|
|
# vim: set syn=bash
|
|
# shellcheck disable=2155,3010,3019,3043,3057,3060
|
|
|
|
START=94
|
|
PROG="qca-nss-drv"
|
|
|
|
log_msg() {
|
|
|
|
local irq_name="$1" affinity="$2" occurrence="$3" irq="$4"
|
|
|
|
msg="$(printf "Pinning IRQ($irq) %-24s to CPU ${affinity}\n" "$irq_name")"
|
|
|
|
[[ $irq_name =~ "nss" ]] && msg="$msg (NSS Core $((occurrence - 1)))"
|
|
|
|
logger -t "$PROG" "$msg"
|
|
}
|
|
|
|
######################################################################
|
|
### Takes a comma, space separated, or range list of CPU numbers and
|
|
## returns a bitmask of CPUs.
|
|
## cpus_to_bitmask "0,1,2,3" -> f
|
|
## cpus_to_bitmask "0 1 2 3" -> f
|
|
## cpus_to_bitmask "0-3" -> f
|
|
## cpus_to_bitmask "3" -> 8
|
|
#######################################################################
|
|
|
|
cpus_to_bitmask() {
|
|
|
|
local bitmask=0
|
|
# shellcheck disable=2048
|
|
for range in ${*//,/ }; do
|
|
start="${range%-*}"
|
|
end="${range#*-}"
|
|
if [ -z "$end" ]; then
|
|
bitmask="$((bitmask | 1 << start))"
|
|
else
|
|
bitmask="$((bitmask | (2 ** (end - start + 1) - 1) << start))"
|
|
fi
|
|
done
|
|
printf '%x' $bitmask
|
|
}
|
|
|
|
######################################################################
|
|
### Takes a bitmask of CPUs and returns a space separated list of
|
|
## CPU numbers.
|
|
## bitmask_to_cpus f -> 0 1 2 3
|
|
######################################################################
|
|
|
|
bitmask_to_cpus() {
|
|
|
|
[ "${1:0:2}" != "0x" ] && set -- "0x$1"
|
|
local bitmask="$(printf '%d' "$1")"
|
|
|
|
local cpus=""
|
|
for i in $(seq 0 63); do
|
|
if [ $((bitmask & 1)) -ne 0 ]; then
|
|
cpus="$cpus $i"
|
|
fi
|
|
bitmask=$((bitmask >> 1))
|
|
done
|
|
echo "${cpus# }"
|
|
}
|
|
|
|
######################################################################
|
|
### Sets the affinity of the IRQs with the given name to the given CPU.
|
|
## first argument: IRQ name ("nss_queue0")
|
|
## second argument: CPU number
|
|
## third argument: occurrence of the IRQ name
|
|
## since NSS core 0/1 share the same IRQ names
|
|
## set_affinity "nss_queue0" 1 1
|
|
|
|
set_affinity() {
|
|
|
|
local irq_name="$1" affinity="$2" occurrence="${3:-1}" bitmask
|
|
|
|
awk -v irq_name="$irq_name" -v occurrence="$occurrence" '
|
|
BEGIN{count=0}
|
|
$NF==irq_name {
|
|
if(++count==occurrence){
|
|
sub(/:$/,"",$1)
|
|
print $1
|
|
}
|
|
}' /proc/interrupts | while read -r irq; do
|
|
$enable_log && {
|
|
log_msg "$irq_name" "$affinity" "$occurrence" "$irq"
|
|
}
|
|
bitmask=$(cpus_to_bitmask "$affinity") && echo "$bitmask" > /proc/irq/"$irq"/smp_affinity
|
|
done
|
|
}
|
|
|
|
enable_rps() {
|
|
|
|
# NSS Core 0 : 4 nss queues to each core
|
|
set_affinity "nss_queue0" 0-3 1
|
|
set_affinity "nss_queue1" 1 1
|
|
set_affinity "nss_queue2" 2 1
|
|
set_affinity "nss_queue3" 3 1
|
|
|
|
# NSS Core 1 : 1 nss queue to 3rd core
|
|
set_affinity "nss_queue0" 3 2
|
|
|
|
# NSS Core 0 : 2 nss sos/queues to last core
|
|
set_affinity "nss_empty_buf_sos" 0-3 1
|
|
set_affinity "nss_empty_buf_queue" 0-3 1
|
|
|
|
# NSS Core 1 : 1 nss sos to last core
|
|
set_affinity "nss_empty_buf_sos" 3 2
|
|
|
|
# USB 3.0 : pin to 3rd core
|
|
set_affinity "xhci-hcd:usb1" 1,3 1
|
|
|
|
# TCL Completion, REO Dest, ERR, Exception and h2rxdma
|
|
# are offloaded, so balance remaining IRQs accordingly.
|
|
# PPDU IRQ : pin to 2nd and 3rd core
|
|
set_affinity 'ppdu-end-interrupts-mac1' 1 1
|
|
set_affinity 'ppdu-end-interrupts-mac3' 2 1
|
|
|
|
set_affinity 'ath10k_pci' 0-3 1
|
|
|
|
# Enable NSS RPS
|
|
sysctl -w dev.nss.rps.enable=1 >/dev/null 2>&1
|
|
}
|
|
|
|
start() {
|
|
|
|
local enable_rps
|
|
|
|
config_load nss
|
|
config_get enable_rps "general" enable_rps 1
|
|
config_get_bool enable_log "general" enable_log 1
|
|
|
|
[ "$enable_log" -eq 1 ] && enable_log=true || enable_log=false
|
|
[ "$enable_rps" -eq 1 ] && enable_rps
|
|
}
|