Not all interrupts are triggers for the real-time tasks but all interrupts steal cycles from the real-time task. Threaded interrupt handlers allow a priority to be associated with the interrupt and for it to be scheduled at an appropriate time as shown in the following diagram:
If the interrupt handler code is run as a kernel thread there is no reason why it cannot be preempted by a user space thread of higher priority, and so the interrupt handler does not contribute towards scheduling latency of the user space thread. Threaded interrupt handlers have been a feature of mainline Linux since 2.6.30. You can request that an individual interrupt handler is threaded by registering it with request_threaded_irq()
in place of the normal request_irq()
. You can make threaded IRQs the default by configuring the kernel with CONFIG_IRQ_FORCED_THREADING=y
which makes all handlers into threads unless they have explicitly prevented this by setting the IRQF_NO_THREAD
flag. When you apply the PREEMPT_RT
patches, interrupts are, by default, configured as threads in this way. Here is an example of what you might see:
# ps -Leo pid,tid,class,rtprio,stat,comm,wchan | grep FF PID TID CLS RTPRIO STAT COMMAND WCHAN 3 3 FF 1 S ksoftirqd/0 smpboot_th 7 7 FF 99 S posixcputmr/0 posix_cpu_ 19 19 FF 50 S irq/28-edma irq_thread 20 20 FF 50 S irq/30-edma_err irq_thread 42 42 FF 50 S irq/91-rtc0 irq_thread 43 43 FF 50 S irq/92-rtc0 irq_thread 44 44 FF 50 S irq/80-mmc0 irq_thread 45 45 FF 50 S irq/150-mmc0 irq_thread 47 47 FF 50 S irq/44-mmc1 irq_thread 52 52 FF 50 S irq/86-44e0b000 irq_thread 59 59 FF 50 S irq/52-tilcdc irq_thread 65 65 FF 50 S irq/56-4a100000 irq_thread 66 66 FF 50 S irq/57-4a100000 irq_thread 67 67 FF 50 S irq/58-4a100000 irq_thread 68 68 FF 50 S irq/59-4a100000 irq_thread 76 76 FF 50 S irq/88-OMAP UAR irq_thread
In this case, a BeagleBone running linux-yocto-rt
, only the gp_timer
interrupt was not threaded. It is normal that the timer interrupt handler be run in-line.
Here is a suggested order of descending thread priorities:
posixcputmr
, should always have the highest priority.ksoftirqd
, which on RT kernels is responsible for running delayed interrupt routines and, prior to Linux 3.6, was responsible for running the network stack, the block I/O layer, and other things. You may need to experiment with different priority levels to get a balance.You can change the priorities using the chrt
command as part of the boot script, using a command like this:
# chrt -f -p 90 `pgrep irq/28-edma`
The pgrep
command is part of the procps
package.