From 02147f488d52b9f84547f884af0192e5bf9a5b69 Mon Sep 17 00:00:00 2001
From: Peter Cai <peter.cai@uwaterloo.ca>
Date: Mon, 13 Feb 2023 14:30:55 -0500
Subject: [PATCH] Check in IRQ utility script

---
 irq.sh | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 185 insertions(+)
 create mode 100755 irq.sh

diff --git a/irq.sh b/irq.sh
new file mode 100755
index 0000000..f7e4a4b
--- /dev/null
+++ b/irq.sh
@@ -0,0 +1,185 @@
+#!/usr/bin/env bash
+
+function error() {
+	echo $*
+	exit 1
+}
+
+cfgfile=$HOME/.irq.sh.config
+cntfile=$HOME/.irq.sh.count
+
+# use tilly01 as default...
+if ! [ -f $cfgfile ]; then
+	cat > $cfgfile <<EOF
+mod: mlx4
+nic: eno3d1
+EOF
+	echo -n "async irq:" >> $cfgfile
+	echo -n " 69" >> $cfgfile
+	echo >> $cfgfile
+	echo -n "rxirq:" >> $cfgfile
+	for ((i=104;i<112;i++)); do echo -n " $i" >> $cfgfile; done
+	for ((i=120;i<128;i++)); do echo -n " $i" >> $cfgfile; done
+	for ((i=112;i<120;i++)); do echo -n " $i" >> $cfgfile; done
+	for ((i=128;i<136;i++)); do echo -n " $i" >> $cfgfile; done
+	echo >> $cfgfile
+	echo -n "txirq:" >> $cfgfile
+  for i in 70 71; do echo -n " $i" >> $cfgfile; done
+	for ((i=74;i<80;i++)); do echo -n " $i" >> $cfgfile; done
+	for ((i=88;i<96;i++)); do echo -n " $i" >> $cfgfile; done
+	for ((i=80;i<88;i++)); do echo -n " $i" >> $cfgfile; done
+	for ((i=96;i<104;i++)); do echo -n " $i" >> $cfgfile; done
+	echo >> $cfgfile
+fi
+
+if [ "$1" = "print" ]; then
+	mod=$(fgrep "mod:" $cfgfile|cut -f2 -d' ')
+	[ -z "$mod" ] && error cannot find kernel name in $cfgfile
+	fgrep $mod /proc/interrupts|awk '{print $1, $NF}'
+	exit 0
+fi
+
+nic=$(fgrep "nic:" $cfgfile|cut -f2 -d' ')
+[ -z "$nic" ] && error cannot find nic in $cfgfile
+
+rxirq=($(fgrep rxirq: $cfgfile|cut -f2 -d:))
+txirq=($(fgrep txirq: $cfgfile|cut -f2 -d:))
+rxcnt=${#rxirq[@]}
+txcnt=${#txirq[@]}
+rqcnt=$(ethtool -l $nic|fgrep RX:|tail -1|awk '{print $2}')
+tqcnt=$(ethtool -l $nic|fgrep TX:|tail -1|awk '{print $2}')
+
+allirq=("${rxirq[@]}" "${txirq[@]}")
+allcnt=${#allirq[@]}
+
+idx=0
+for ((i=0;i<$rxcnt;i++)); do
+	irqtype[$idx]="RX"
+	idx=$(expr $idx + 1)
+done
+for ((i=0;i<$txcnt;i++)); do
+  irqtype[$idx]="TX"
+	idx=$(expr $idx + 1)
+done
+
+if [ "$1" = "-a" ]; then
+	shift
+	all=1
+else
+	all=0
+fi
+
+if [ "$1" = "set" ]; then
+	shift
+	if [ "$1" = "rx" ]; then 
+		shift
+		maxidx=$rxcnt
+	else
+		maxidx=$allcnt
+	fi
+	[ $# -lt 1 ] && error "usage $0 set <low> [<high>]"
+	[ $# -lt 2 ] && num=1 || num=$(expr 1 + $2 - $1)
+	for ((idx=0;idx<$maxidx;idx++)); do
+		irq=${allirq[$idx]}
+		cpu=$(expr $1 + $idx % $num)
+		sudo -s sh -c "echo $cpu > /proc/irq/$irq/smp_affinity_list"
+#		echo $cpu | sudo tee /proc/irq/$irq/smp_affinity_list > /dev/null
+	done
+	exit 0
+fi
+
+[ -f $cntfile ] || touch $cntfile
+
+idx=0
+[ "$1" = "clear" ] || for x in $(fgrep irqs: $cntfile|cut -f2 -d:); do
+	irqcntprev[$idx]=$x
+	idx=$(expr $idx + 1)
+done
+for ((;idx<$allcnt;idx++)); do
+	irqcntprev[$idx]=0
+done
+
+idx=0
+[ "$1" = "clear" ] || for x in $(fgrep pkts: $cntfile|cut -f2 -d:); do
+	pktcntprev[$idx]=$x
+	idx=$(expr $idx + 1)
+done
+for ((;idx<$allcnt;idx++)); do
+	pktcntprev[$idx]=0
+done
+
+[ "$1" = "clear" ] && {
+	rxdropsprev=0
+	txdropsprev=0
+} || {
+	fgrep -q rxdrops: $cntfile && {
+		rxdropsprev=$(fgrep rxdrops: $cntfile|cut -f2 -d:)
+	} || {
+		rxdropsprev=0
+	}
+	fgrep -q txdrops: $cntfile && {
+		txdropsprev=$(fgrep txdrops: $cntfile|cut -f2 -d:)
+	} || {
+		txdropsprev=0
+	}
+}
+
+echo -n "irqs:" > $cntfile
+irqline=($(fgrep intr /proc/stat|cut -f3- -d' '))
+for ((idx=0;idx<$allcnt;idx++)); do
+	x=${irqline[${allirq[$idx]}]}
+	echo -n " $x" >> $cntfile
+	irqcntnow[$idx]=$x
+done
+echo >> $cntfile
+
+echo -n "pkts:" >> $cntfile
+idx=0
+for x in $(ethtool -S $nic|fgrep packet|fgrep rx|fgrep -v rx_|cut -f2 -d:); do
+	echo -n " $x" >> $cntfile
+	pktcntnow[$idx]=$x
+  idx=$(expr $idx + 1)
+done
+for ((;idx<$rxcnt;idx++)); do
+	echo -n " 0" >> $cntfile
+	pktcntnow[$idx]=0
+done
+for x in $(ethtool -S $nic|fgrep packet|fgrep tx|fgrep -v tx_|cut -f2 -d:); do
+	echo -n " $x" >> $cntfile
+	pktcntnow[$idx]=$x
+  idx=$(expr $idx + 1)
+done
+for ((;idx<$allcnt;idx++)); do
+	echo -n " 0" >> $cntfile
+	pktcntnow[$idx]=0
+done
+echo >> $cntfile
+
+rxdropsnow=$(ethtool -S $nic|fgrep rx_dropped:|cut -f2 -d:)
+txdropsnow=$(ethtool -S $nic|fgrep tx_dropped:|cut -f2 -d:)
+echo "rxdrops: $rxdropsnow" >> $cntfile
+echo "txdrops: $txdropsnow" >> $cntfile
+rxdrops=$(expr $rxdropsnow - $rxdropsprev)
+txdrops=$(expr $txdropsnow - $txdropsprev)
+
+irqsum=0
+pktsum=0
+printf "%5s    %10s %10s %5s name\n" num irqs pkts cpus
+for ((idx=0;idx<$allcnt;idx++)); do
+	irqs[$idx]=$(expr ${irqcntnow[$idx]} - ${irqcntprev[$idx]})
+	pkts[$idx]=$(expr ${pktcntnow[$idx]} - ${pktcntprev[$idx]})
+	irqsum=$(expr $irqsum + ${irqs[$idx]})
+	pktsum=$(expr $pktsum + ${pkts[$idx]})
+done
+for ((idx=0;idx<$allcnt;idx++)); do
+	irq=${allirq[$idx]}
+	cpus=$(cat /proc/irq/$irq/smp_affinity_list)
+	name=$(fgrep " $irq:" /proc/interrupts|awk '{print $NF}')
+	if [ $all -gt 0 ] || [ ${irqs[$idx]} -gt 0 -o ${pkts[$idx]} -gt 0 ]; then
+		printf "%5d %2s %10d %10d %5s %s\n" $irq ${irqtype[$idx]} ${irqs[$idx]} ${pkts[$idx]} $cpus $name
+	fi
+done|sort -g -k1
+printf "total    %10d %10d\n" $irqsum $pktsum
+[ $rxdrops -gt 0 ] && printf "drops RX %10d\n" $rxdrops
+[ $txdrops -gt 0 ] && printf "drops TX %10d\n" $txdrops
+exit 0
-- 
GitLab