[LAD] Playing dice with IRQ's

Jean-Baptiste Mestelan mestelan at gmail.com
Thu Dec 18 21:09:58 UTC 2008


2008/12/17 Jens M Andreasen <jens.andreasen at comhem.se>:
> I would like to automagically increase the priority of the IRQ
> associated with my soundcard - peek at "the dice" before placing my bet
> so to say - how do I do that?


Mr Rui Nuno Capela figured this out for you/us:
http://alsa.opensrc.org/Rtirq

Not sure why, but rtirq is hard to be found on the internet, these
days. The Gentoo-proaudio people have packaged it here:
http://download.tuxfamily.org/proaudio/distfiles/rtirq-20071012.tar.gz
Or see the main shell script below; the line you want goes like this:
grep irq /proc/asound/cards | tac | sed 's/.* irq \(.*\)/\1/'

Kind regards.

### ### ### ### ### ### ###
cat /etc/init.d/rtirq.sh

#!/bin/bash +x
#
# Copyright (c) 2004-2007 rncbc aka Rui Nuno Capela.
#
# /etc/init.d/rtirq
#
# Startup script for realtime-preempt enabled kernels.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 or later.
#
# chkconfig: 35 81 19
# description: Realtime IRQ thread tunning.
#
### BEGIN INIT INFO
# Provides:          rtirq
# Required-Start:    $syslog $local_fs
# Should-Start: $time alsa alsasound hotplug
# Required-Stop:     $syslog $local_fs
# Should-Stop: $time alsa alsasound hotplug
# Default-Start:     3 5
# Default-Stop:      0 1 2 6
# Short-Description: Realtime IRQ thread tunning.
# Description:       Change the realtime scheduling policy
#       and priority of relevant system driver IRQ handlers.
### END INIT INFO
#


# Won't work without those binaries.
for DIR in /sbin /usr/sbin /bin /usr/bin /usr/local/bin; do
       [ -z "${RTIRQ_CHRT}" -a -x ${DIR}/chrt ] && RTIRQ_CHRT=${DIR}/chrt
done

# Check for missing binaries (stale symlinks should not happen)
[ -n "${RTIRQ_CHRT}" -a -x ${RTIRQ_CHRT} ] || {
       echo "`basename $0`: chrt: not installed."
       [ "$1" = "stop" ] && exit 0 || exit 5
}

# Check for existence of needed config file and read it.
RTIRQ_CONFIG=/etc/conf.d/rtirq
[ -r ${RTIRQ_CONFIG} ] || RTIRQ_CONFIG=/etc/default/rtirq
[ -r ${RTIRQ_CONFIG} ] || RTIRQ_CONFIG=/etc/rtirq.conf
[ -r ${RTIRQ_CONFIG} ] || {
       echo "`basename $0`: ${RTIRQ_CONFIG}: not found."
       [ "${RTIRQ_ACTION}" = "stop" ] && exit 0 || exit 6
}

# Read configuration.
source ${RTIRQ_CONFIG}

# Colon delimited trail list of already assigned IRQ numbers,
# preventind lower priority override due to shared IRQs.
RTIRQ_TRAIL=":"

#
# Reset policy of all IRQ threads out there.
#
function rtirq_reset ()
{
       # Reset all softirq-timer/s from highest priority.
       rtirq_exec_high reset
       # PIDS=`ps -eo pid,class | egrep '(FF|RR)' | awk '{print $1}'`
       PIDS=`ps -eo pid,comm | grep IRQ | awk '{print $1}'`
       for PID in ${PIDS}
       do
               ${RTIRQ_CHRT} --pid --other 0 ${PID}
       done
}

#
# IRQ thread handler policy prioritizer, by IRQ number.
#
function rtirq_exec_num ()
{
       ACTION=$1
       NAME1=$2
       NAME2=$3
       PRI2=$4
       IRQ=$5
       # Check the services that are to be (un)threaded.
       if [ -n "`echo :${RTIRQ_NON_THREADED}: | sed 's/ /:/g' | grep
:${NAME1}:`" ]
       then
               PREPEND="`basename $0`: ${ACTION} [${NAME2}] irq=${IRQ}"
               for THREADED in /proc/irq/${IRQ}/*/threaded
               do
                       if [ -f "${THREADED}" ]
                       then
                               case ${ACTION} in
                               *start)
                                       echo "${PREPEND}: ${THREADED}: OFF."
                                       echo -n 0 > "${THREADED}"
                                       ;;
                               stop)
                                       echo "${PREPEND}: ${THREADED}: ON."
                                       echo -n 1 > "${THREADED}"
                                       ;;
                               esac
                       fi
               done
       fi
       # And now do the proper threading prioritization...
       if [ -z "`echo ${RTIRQ_TRAIL} | grep :${IRQ}:`" ]
       then
               PIDS=`ps -eo pid,comm | egrep "IRQ.${IRQ}\$" | awk '{print $1}'`
               for PID in ${PIDS}
               do
                       PREPEND="`basename $0`: ${ACTION} [${NAME2}]
irq=${IRQ} pid=${PID}"
                       case ${ACTION} in
                       *start)
                               PREPEND="${PREPEND} prio=${PRI2}"
                               if ${RTIRQ_CHRT} --pid --fifo ${PRI2} ${PID}
                               then
                                       echo "${PREPEND}: OK."
                               else
                                       echo "${PREPEND}: FAILED."
                               fi
                               ;;
                       stop)
                               if ${RTIRQ_CHRT} --pid --other 0 ${PID}
                               then
                                       echo "${PREPEND}: OK."
                               else
                                       echo "${PREPEND}: FAILED."
                               fi
                               ;;
                       status)
                               echo "${PREPEND}: " && ${RTIRQ_CHRT}
--pid --verbose ${PID}
                               ;;
                       *)
                               echo "${PREPEND}: ERROR."
                               ;;
                       esac
                       PRI2=$((${PRI2} - 1))
               done
               RTIRQ_TRAIL=":${IRQ}${RTIRQ_TRAIL}"
       fi
}

#
# IRQ thread handler policy prioritizer, by service name.
#
function rtirq_exec_name ()
{
       ACTION=$1
       NAME1=$2
       NAME2=$3
       PRI1=$4
       IRQS=`grep "${NAME2}" /proc/interrupts | awk -F: '{print $1}'`
       for IRQ in ${IRQS}
       do
               rtirq_exec_num ${ACTION} ${NAME1} ${NAME2} ${PRI1} ${IRQ}
               PRI1=$((${PRI1} - 1))
       done
}

#
# Generic process top prioritizer
#
function rtirq_exec_high ()
{
       ACTION=$1
       case ${ACTION} in
       *start)
               PRI1=99
               ;;
       *)
               PRI1=1
               ;;
       esac
       # Process all configured process names...
       for NAME in ${RTIRQ_HIGH_LIST}
       do
               PREPEND="`basename $0`: ${ACTION} [${NAME}]"
               PIDS=`ps -eo pid,comm | grep "${NAME}" | awk '{print $1}'`
               for PID in ${PIDS}
               do
                       if ${RTIRQ_CHRT} --pid --fifo ${PRI1} ${PID}
                       then
                               echo "${PREPEND} pid=${PID} prio=${PRI1}: OK."
                       else
                               echo "${PREPEND} pid=${PID}
prio=${PRI1}: FAILED."
                       fi
               done
               [ ${PRI1} -gt ${RTIRQ_PRIO_HIGH} ] && PRI1=$((${PRI1} - 1))
       done
}


#
# Main executive.
#
function rtirq_exec ()
{
       ACTION=$1
       # Check configured base priority.
       PRI0=${RTIRQ_PRIO_HIGH:-90}
       [ $((${PRI0})) -gt 95 ] && PRI0=95
       [ $((${PRI0})) -lt 55 ] && PRI0=55
       # Check configured priority decrease step.
       DECR=${RTIRQ_PRIO_DECR:-5}
       [ $((${DECR})) -gt 10 ] && DECR=10
       [ $((${DECR})) -lt  1 ] && DECR=1
       # (Re)set all softirq-timer/s to highest priority.
       rtirq_exec_high ${ACTION}
       # Process all configured service names...
       for NAME in ${RTIRQ_NAME_LIST}
       do
               case ${NAME} in
               snd)
                       PRI1=${PRI0}
                       IRQS=`grep irq /proc/asound/cards | tac | sed
's/.* irq \(.*\)/\1/'`
                       for IRQ in ${IRQS}
                       do
                               rtirq_exec_num ${ACTION} ${NAME}
${NAME} ${PRI1} ${IRQ}
                               PRI1=$((${PRI1} - 1))
                       done
                       ;;
               usb)
                       rtirq_exec_name ${ACTION} ${NAME} "ohci_hcd" ${PRI0}
                       rtirq_exec_name ${ACTION} ${NAME} "uhci_hcd" ${PRI0}
                       rtirq_exec_name ${ACTION} ${NAME} "ehci_hcd" ${PRI0}
                       ;;
               *)
                       rtirq_exec_name ${ACTION} ${NAME} ${NAME} ${PRI0}
                       ;;
               esac
               [ ${PRI0} -gt ${DECR} ] && PRI0=$((${PRI0} - ${DECR}))
       done
}


#
# Main procedure line.
#
case $1 in
*start)
       if [ "${RTIRQ_RESET_ALL}" = "yes" -o "${RTIRQ_RESET_ALL}" = "1" ]
       then
               rtirq_reset
       fi
       rtirq_exec start
       ;;
stop)
       if [ "${RTIRQ_RESET_ALL}" = "yes" -o "${RTIRQ_RESET_ALL}" = "1" ]
       then
               rtirq_reset
       #else
       #  rtirq_exec stop
       fi
       ;;
reset)
       if [ "${RTIRQ_RESET_ALL}" = "yes" -o "${RTIRQ_RESET_ALL}" = "1" ]
       then
               rtirq_reset
       else
               rtirq_exec stop
       fi
       ;;
status)
       echo
       #rtirq_exec status
       ps -eo pid,class,rtprio,ni,pri,pcpu,stat,comm --sort -rtprio \
               | egrep '(^[[:blank:]]*PID|IRQ|s(oft)?irq)' \
               | awk 'BEGIN {
                       while (getline IRQLine < "/proc/interrupts") {
                               split(IRQLine, IRQSplit, ":[[:blank:]|0-9]+");
                               if (match(IRQSplit[1],
"^[[:blank:]]*[0-9]+$")) {

gsub("[^[:blank:]]+PIC[^[:blank:]]*[[:blank:]]+" \

"|\\[[^\\]]+\\][^[:blank:]]*[[:blank:]]+",
                                               "", IRQSplit[2]);
                                       IRQTable[IRQSplit[1] + 0] = IRQSplit[2];
                               }
                       }
               } { if ($9 == "")
                       { print $0"\t"IRQTable[substr($8,5)]; }
                       else
                       { print $0"\t"IRQTable[$9]; } }'
       echo
       ;;
*)
       echo
       echo "  Usage: $0 {[re]start|stop|reset|status}"
       echo
       exit 1
       ;;
esac

exit 0



More information about the Linux-audio-dev mailing list