#!/bin/bash
defaultmask=7
defaultisolirq=27
defaultisolmask=8
cpucores=`grep ^processor /proc/cpuinfo | wc -l`
if test $cpucores -gt 16
then
coremask=4294967295
elif test $cpucores -gt 8
then
coremask=65535
elif test $cpucores -gt 4
then
coremask=255
else
coremask=15
fi
eval `cat /proc/cmdline | tr ' ' '\n' | grep isolcpus`
if test "$isolcpus"
then
OLDIFS="$IFS"
IFS=,
isolmask=0
for i in $isolcpus
do
thismask=$((2 ** $i))
isolmask=$(($isolmask + $thismask))
done
IFS="$OLDIFS"
fi
if test "$isolmask"
then
decidefaultmask=$(($coremask ^ $isolmask))
defaultmask=`printf %x $decidefaultmask`
decidefaultisolmask=$isolmask
defaultisolmask=`printf %x $decidefaultisolmask`
fi
if test "$1" -a "$1" = --help
then
echo "Usage: `basename $0` <mask> <isolirq> <isolmask>"
echo "Function: Set SMP affinity mask of all IRQ threads to <mask>, except IRQs <isolirq> to <isolmask>"
echo " <mask> defaults to $defaultmask"
echo " <isolirq> defaults to $defaultisolirq"
echo " <isolmask> defaults to $defaultisolmask"
echo "Options: none"
exit 1
fi
strcmp() {
if test -z "$1" -o -z "$2"
then
echo false
else
str1="$1"
str2="$2"
strlen1=`echo -n "$str1" | wc -c`
strlen2=`echo -n "$str2" | wc -c`
if test $strlen1 -gt $strlen2
then
str1="`echo $str1 | cut -c1-$strlen2`"
elif test $strlen2 -gt $strlen1
then
str2="`echo $str2 | cut -c1-$strlen1`"
fi
test "$str1" = "$str2"
fi
}
pidof()
{
irqname="$1"
if test -z "$irqname"
then
echo
return
fi
cd /proc
for pid in [0-9]*
do
taskname="`cat $pid/comm 2>/dev/null`"
if test "$taskname"
then
if strcmp "$taskname" "$irqname"
then
echo $pid
break
fi
fi
done
cd - >/dev/null
}
if test "$1"
then
if echo $1 | grep -iq [^0-9a-f]
then
echo "First argument for default mask is expected to be a lower-case hexadecimal number, not $1"
exit 1
fi
mask=$1
else
mask=$defaultmask
fi
if test "$2"
then
if echo $2 | grep -q '[^0-9 ]'
then
echo "Second argument for isolated IRQs is expected to be a list of decimal numbers, not $2"
exit 1
fi
isolirq="$2"
else
isolirq="$defaultisolirq"
fi
if test "$3"
then
if echo $1 | grep -iq [^0-9a-f]
then
echo "Third argument for mask of isolated IRQs is expected to be a lower-case hexadecimal number, not $1"
exit 1
fi
isolmask=$3
else
isolmask=$defaultisolmask
fi
redcolor='\033[0;31m'
yellowcolor='\033[0;33m'
greencolor='\033[0;32m'
nocolor='\033[0m'
red() {
printf $redcolor$@$nocolor
}
yellow() {
printf $yellowcolor$@$nocolor
}
green() {
printf $greencolor$@$nocolor
}
NOT() {
echo `red NOT`
}
is() {
echo `green is`
}
can() {
echo `yellow can`
}
could() {
echo `yellow could`
}
cd /proc/irq
for irq in `ls -1d [0-9]* | sort -n`
do
irqshare=1
while true
do
namedir="`find $irq/* -type d -print0 | xargs -0 printf %s@ | cut -d@ -f$irqshare`"
if test "$namedir"
then
irqname=`basename "$namedir"`
taskname=`echo irq/$irq-$irqname`
pid=`pidof $taskname`
if test -z "$pid"
then
taskname=`echo $irq-$irqname`
pid=`pidof $taskname`
fi
if test "$pid"
then
realcore10=`ps -o psr $pid | sed 's/^ *//' | grep ^[0-9]`
realcoremask10=$((2 ** $realcore10))
affinity=`grep Cpus_allowed: ../$pid/status | cut -f2 | sed s/^0*//`
flags=`cat ../$pid/stat | sed 's/(.*)/comm/' | cut -d" " -f 9`
else
irqname=
fi
else
if test $irqshare -gt 1
then
break
fi
irqname=
fi
if echo $isolirq | tr " " "\n" | grep -q ^$irq$
then
thismask=$isolmask
else
thismask=$mask
fi
if test "$irqname"
then
if test $(($flags & 0x04000000)) != 0
then
echo -n Affinity mask of interrupt $irq $irqname can `NOT` be modified, since it has the PF_NO_SETAFFINITY flag set
if test $((0x$affinity - 0x$thismask)) = 0
then
if test $(($realcoremask10 & 0x$thismask)) != 0
then
echo ", but the affinity mask 0x$affinity of thread $irqname (PID $pid) fortunately `is` correct, and the thread is currently running on core $realcore10 which `is` ok"
else
echo ", but the affinity mask 0x$affinity of thread $irqname (PID $pid) fortunately `is` correct; however, the thread is currently running on core $realcore10 which is `NOT` ok"
fi
else
if test $(($realcoremask10 & 0x$thismask)) != 0
then
echo ", but although the affinity mask of thread $irqname (PID $pid) is 0x$affinity which is `NOT` ok, the thread is currently running on core $realcore10 which `is` ok"
else
echo ", and because the affinity mask of thread $irqname (PID $pid) unfortunately is 0x$affinity which is `NOT` ok, the thread is running on core $realcore10 which is `NOT` ok"
fi
fi
fi
fi
current_smp_affinity="`cat $irq/smp_affinity`"
if test $((0x$current_smp_affinity - 0x$thismask)) != 0
then
if ! echo $thismask >$irq/smp_affinity 2>/dev/null
then
echo -n Default SMP affinity mask of interrupt $irq $irqname is 0x$current_smp_affinity and could `NOT` be set to 0x$thismask
andorbut=but
else
echo -n Default SMP affinity mask of interrupt $irq $irqname was 0x$current_smp_affinity and `is` now corrected to 0x$thismask
andorbut=and
fi
else
echo -n Default SMP affinity mask of interrupt $irq $irqname `is` 0x$thismask and already correct
andorbut=and
fi
if test "$irqname"
then
if test $((0x$affinity - 0x$thismask)) = 0
then
if test $(($realcoremask10 & 0x$thismask)) != 0
then
echo ", $andorbut the affinity mask 0x$affinity of thread $irqname (PID $pid) fortunately `is` correct, and the thread is currently running on core $realcore10 which `is` ok"
else
echo ", $andorbut the affinity mask 0x$affinity of thread $irqname (PID $pid) fortunately `is` correct; however, the thread is currently running on core $realcore10 which is `NOT` ok"
fi
else
if taskset -p $thismask $pid >/dev/null 2>&1
then
echo -n ", $andorbut the affinity mask of thread $irqname (PID $pid) is 0x$affinity which is `NOT` ok, but successfully attempted to be modified to 0x$thismask"
realcore10=`ps -o psr $pid | sed 's/^ *//' | grep ^[0-9]`
realcoremask10=$((2 ** $realcore10))
affinity=`grep Cpus_allowed: ../$pid/status | cut -f2 | sed s/^0*//`
if test $((0x$affinity - 0x$thismask)) = 0
then
if test $(($realcoremask10 & 0x$thismask)) != 0
then
echo " and `is` now 0x$thismask, and the thread is currently running on core $realcore10 which `is` ok"
else
echo " and `is` now 0x$thismask, but the thread is currently running on core $realcore10 which is `NOT` ok"
fi
else
echo -n , but still is 0x$affinity which `is`
if test $((0x$affinity & 0x$thismask)) != 0
then
if test $(($realcoremask10 & 0x$thismask)) != 0
then
echo " potentially ok, and the thread is currently running on core $realcore10 which also `is` ok"
else
echo " potentially ok, but the thread is currently running on core $realcore10 which is `NOT` ok"
fi
else
if test $(($realcoremask10 & 0x$thismask)) != 0
then
echo " `NOT` ok, but the thread is currently running on core $realcore10 which `is` ok"
else
echo " `NOT` ok, and the thread is in fact currently running on core $realcore10 which is `NOT` ok"
fi
fi
fi
else
echo ", but the affinity mask of thread $irqname (PID $pid) is 0x$affinity which is `NOT` ok and could `NOT` be corrected"
fi
fi
else
echo
fi
irqshare=`expr $irqshare + 1`
done
done