Version 8 (modified by nettings, 14 years ago)
look up tasklet PIDs

IRQ Priorities How-To

Even with an rt-patched kernel, setting the scheduling priority of the IRQ handler on it's own is not enough to ensure proper operation. Since most of the actual work that has to be done to respond to an IRQ is done in a tasklet, one should also ensure that the priority of the softirq-tasklet processes is high enough. Otherwise tasklets are not executed in time. This has been experimentally verified.

All softirq-tasklets run SCHED_FIFO with a priority of 50 by default. To ensure glitch-free audio, it is important that those tasklets responsible for audio operation have a higher priority than the others.

Manual priority setting walk-through

You can adjust IRQ tasklet priorities manually (which is a good exercise to understand what is going on). Here's a typical laptop example:

Step one: Look up the relevant interrupts

To find out which IRQ lines handle which hardware, just ask the kernel:

nettings@hoppetosse:/local/ffado-svn/libffado> cat /proc/interrupts
           CPU0
  0:      89132   IO-APIC-edge      timer
  1:       1538   IO-APIC-edge      i8042
  8:          1   IO-APIC-edge      rtc0

The realtime clock (on IRQ 8) should have the highest priority. We are using 90 here.

  9:        274   IO-APIC-fasteoi   acpi
 12:      28208   IO-APIC-edge      i8042
 14:      20841   IO-APIC-edge      ata_piix
 15:          0   IO-APIC-edge      ata_piix
 16:      27747   IO-APIC-fasteoi   uhci_hcd:usb2, yenta, ohci1394, i915@pci:0000:00:02.0, eth0

Here's a tricky one. This example laptop uses a ffado device via a pc-card IEEE1934 adaptor. The module responsible for the cardbus slot is called "yenta" on IRQ 16. It must have the next highest priority, let's make it 88.

Next thing is the actual firewire module, called ohci1394. As you can see, it's sharing an interrupt with the yenta module (naturally). It will be set to 86.

You can also see that a USB hub sits on the same interrupt. So it's a bad idea to use the corresponding USB port for your external audio disk. Moreover, the wired network interface is sharing this busy interrupt line, too. If possible, bring down the network interface during important recording sessions.

 17:          0   IO-APIC-fasteoi   uhci_hcd:usb3, mmc0
 18:          0   IO-APIC-fasteoi   uhci_hcd:usb4
 19:       6501   IO-APIC-fasteoi   ehci_hcd:usb1, uhci_hcd:usb5

Here's a nice USB 2.0 hub on a little-used interrupt. An ideal place for our external recording disk. Let's up this to 84.

 21:         32   IO-APIC-fasteoi   ipw2200
...

The rest of the interrupts are not related to our audio chain.

Step two: find out which processes handle the IRQs

To get a list of all the kernel IRQ tasklets, you can (as root) do

hoppetosse:~ # ps -eLo pid,cls,rtprio,pri,nice,cmd | grep -i "irq"
    3  FF     49  89   - [sirq-high/0]
    4  FF     49  89   - [sirq-timer/0]
    5  FF     49  89   - [sirq-net-tx/0]
    6  FF     49  89   - [sirq-net-rx/0]
    7  FF     49  89   - [sirq-block/0]
    8  FF     49  89   - [sirq-tasklet/0]
    9  FF     49  89   - [sirq-sched/0]
   10  FF     49  89   - [sirq-hrtimer/0]
   11  FF     49  89   - [sirq-rcu/0]
   24  FF     50  90   - [irq/9-acpi]
   33  FF     50  90   - [irq/12-i8042]
   34  FF     50  90   - [irq/1-i8042]
   68  FF     50  90   - [irq/14-ata_piix]
   69  FF     50  90   - [irq/15-ata_piix]
  293  FF     50  90   - [irq/19-ehci_hcd]

This is the USB handler for our audio disk.

  429  FF     50  90   - [irq/16-uhci_hcd]
  436  FF     50  90   - [irq/17-uhci_hcd]
  441  FF     50  90   - [irq/18-uhci_hcd]
  442  FF     50  90   - [irq/19-uhci_hcd]
 1114  FF     50  90   - [irq/8-rtc0]
 1117  FF     50  90   - [irq/16-yenta]

Our pc-card module has the process ID 1117.

 1147  FF     50  90   - [irq/21-ipw2200]
 1169  FF     50  90   - [irq/17-mmc0]
 1220  FF     50  90   - [irq/23-Intel IC]
 1225  FF     50  90   - [irq/16-ohci1394]

The firewire card handler has PID 1225.

 1248  FF     50  90   - [irq/22-Intel IC]
 2440  FF     50  90   - [irq/16-i915@pci]
 2528  FF     50  90   - [irq/16-eth0]
 4461  TS      -  19   0 grep -i irq

NOTE: Çurrent low latency kernels enable per-device handlers (as opposed to per-interrupt as before). That means if two devices are sharing an interrupt (very common on notebooks), you can apply more fine-grained tweaks. rtirq has been updated to deal with this, so be sure to get the very latest version (scroll down a bit on that page). Still, you may encounter problems. Holler on the lists if you do.

  • Example rtirq config (/etc/sysconfig/rtirq)
    #!/bin/sh
    #
    # Copyright (c) 2004-2006 rncbc aka Rui Nuno Capela.
    # All rights reserved.
    #
    # /etc/sysconfig/rtirq
    #
    # Configuration for IRQ thread tunning,
    # for realtime-preempt enabled kernels.
    #
    
    # IRQ thread service names
    # (space separated list, from higher to lower priority).
    RTIRQ_NAME_LIST="rtc ohci1394 snd i8042"
    
    # Highest priority.
    RTIRQ_PRIO_HIGH=80
    
    # Priority decrease step.
    RTIRQ_PRIO_DECR=10
    
    # Whether to reset all IRQ threads to SCHED_OTHER.
    RTIRQ_RESET_ALL=1
    
    # On kernel configurations that support it,
    # which services should be NOT threaded
    # (space separated list).
    RTIRQ_NON_THREADED="rtc snd"
    
    # Process names which will be forced to the
    # highest realtime priority range (99-91)
    # (space separated list, from highest to lower priority).
    RTIRQ_HIGH_LIST="softirq-timer softirq-hrtimer softirq-tasklet"