IRQTUNE -- A Linux x86 IRQ Priority Optimizer


IRQTUNE -- A Linux x86 IRQ Priority Optimizer

Copyright 1996 by Craig Estey.
This FAQ is revision 0.2
Last updated: Mon Aug 26 04:53:01 PDT 1996
See the Changes section at the bottom of this document.

irqtune changes the IRQ priority of devices to allow devices that require high priority and fast service (e.g. serial ports, modems) to have it.

With irqtune, a 3X speedup of serial/modem throughput is possible.


Where do I get irqtune?

irqtune is free software under the terms and conditions of the GNU Public License. See the file COPYING, included in the distribution, for details.


How do I know if I need irqtune?

You are running Linux on an x86 PC, other architectures to be implemented later--Sorry.

You probably need irqtune, if you are experiencing any of the following:


What is actually happening to cause these problems?

When the PC boots Linux, the timer is given, by default, the highest IRQ priority in the system (it's IRQ 0 and thus, priority 0). On a standard configuration, the serial ports are priority 11 and 12!!! This means that 10 other devices have higher priority.

Q: So what does IRQ priority do?

When multiple devices are in contention to interrupt the CPU, their priority decides which interrupts will occur in what order.

Q: When does this contention occur?

After an arbitrary period of having interrupts disabled (e.g after a cli), at the point where they're reenabled (sti). This can happen in several places:

Q: If there are multiple interrupts now pending,which one gets the service, the serial or some other?

In the default configuration, the serial ISR will usually lose as it's priority 11.


How does irqtune help this?

irqtune gives priority 0 to the whatever device you specify. If we specify a serial device, irqtune guarantees that the serial ISR gets control whenever a contention occurs.


Why does the serial interrupt service require the highest priority?

Q: Why does the serial device merit such special treatment?

Serial devices are somewhat unique. Even though they have one of the slowest data rates (relative to a disk), they are the largest consumer of interrupts and are extremely sensitive to interrupt latency (the time from when a device yanks the IRQ line until its ISR is executed).

Q: Could you give a concrete example of this?

Q: In this example, how would boosting serial IRQ priority help?


Doesn't this hurt the performance of other devices?

Not really. In actual practice, most devices don't even notice the difference. Most other devices (e.g. disks, tape, ethernet) are DMA devices. The DMA does most of the work, thus greatly reducing their need for interrupts. If the device allows a request queue, it may function autonomously on several requests, producing only one interrupt for the entire batch.

Furthermore, serial interrupt services are, themselves, very fast. They slam their data as quickly as possible and get out ASAP. No fancy calculations, just the minimum, mindless data transfer. Almost everything else is handled later, in the bottom-half with interrupts enabled. In fact, a serial ISR may have to re-interrupt it's own bottom-half several times.

Those devices that do experience some slight slowdown are more likely to have long interrupt disable windows themselves. Having several smaller cli/sti windows is much better than one large cli/sti window--It's just harder to program.

Q: But suppose I really want both fast serial and fast disk?

Ultimately, it's a bit of a compromise. Which is better:

When paying an ISP for Internet access in $$$/hour, it's an easy decision :-).


Isn't this IRQ priority thing a bit of a new idea?

No. It's actually an old idea. I've been doing device drivers since 1977 and Unix kernel work since 1981. I've personally written 8 serial drivers have used this many times commercially. Giving the serial device the highest priority is actually standard practice in many systems. With a 4Mhz CPU, these problems used to occur at 1200 baud :-)


How do I install irqtune?


How do I use irqtune? Don't I have to rebuild my kernel?

No, you do not have to rebuild your kernel. irqtune uses insmod and rmmod to dynamically load and unload a kernel module. But you are correct in sensing that irqtune is a kernel patch.

Q: Ok, if it's a kernel patch, why not just issue a kernel patch like everybody else does (e.g. diff -u output)?

irqtune will work even if you don't have the kernel source loaded. It uses insmod to load the patch, invoke it, and then unload it. The IRQ priority changes will last so long as the kernel is booted.

Q: How do I invoke it?

irqtune takes two arguments optional arguments:

The only caveat is that you must specify the full pathname, evenif irqtune is placed in a directory that is in $PATH. This is required because irqtune uses argv[0] to locate its irqtune_mod.o file.

The default is 3 14 which will work for many standard configurations. More on this later.

Q: Could I do this from my /etc/rc.d/rc.local file?

Yes. Just add a /sbin/irqtune line to this file and you're in business. You may also issue another irqtune command at any time.

Q: But aren't kernel patches dependent on the particular revision of the kernel? What if my kernel revision is different from the kernel revision that you built it on?

irqtune is 99.44% kernel revision independent. It is built using ELF binaries, so your insmod must understand them. Also, make sure that you have the correct insmod for your kernel. But that's really about it.

Q: But what if I don't have ELF binary support, how can I still do things?

Well, I'd recommend that you upgrade your kernel as ELF binaries are cool :-) But if you insist, you'll just have to recompile irqtune. Just be sure that /usr/src/linux/include is installed. The exact procedure for building a.out binaries can vary with compiler revision, so be sure to check your documentation on this (You may need to add a parameter or two).

That should do the trick. But, if it doesn't, look at revisionnumbers on insmod, gcc, ld, and the kernel for incompatibilities. Upgrade as necessary.


What about my non-standard hardware configuration?

irqtune defaults for a standard IRQ configuration. It assumes that the highest priority device should be on IRQ 3. This is normally the first serial port on standard configurations, which is what you want.

Q: How do I determine what my IRQ configuration is?

Just type cat /proc/interrupts and you'll get something like:

     0:  8578913   timer
     1:   109547   keyboard
     2:        0 + cascade
     3:    86470 + serial
     4:   197648 + serial
    13:        1   math error
    14:    93123 + Ux4F
Note that /proc/interrupts only reports on active devices. So to scope out the serial IRQ's ideally you'd have X Windows up with your serial mouse and be connected via PPP to the net.

Q: OK, I've got the output from /proc/interrupts, what do I do with it?

The leftmost number is the IRQ number. The rightmost column is the internal device name (not to be confused with /dev names). In the above case, the two serial ports are on IRQ 3 and IRQ 4. Just use the lower number, in this case 3:

This sets IRQ 3 to the highest priority. In fact, before we invoked irqtune, the IRQ number was also its priority:

    IRQ  PRIOR
     0     0
     1     1
     2     2
     3     3
     4     4
     5     5
     6     6
     7     7
After this command, the IRQ priorities are now:

    IRQ  PRIOR
     0     5
     1     6
     2     7
     3     0
     4     1
     5     2
     6     3
     7     4
Q: BTW, What's the cascade device I saw in the output of /proc/interrupts?

Glad you asked. There are actually two interrupt controllers, a master and a slave. The slave is cascaded to the master via its IRQ 2. The master controls IRQ's 0-7 and the slave controls IRQ's 8-15.

You actually may select two high IRQ priorities, one for the master and one for the slave. irqtune defaults the slave to IRQ 14, which is normally the disk controller.

Although the normal notation is to refer to IRQ's as 0-15, it may be easier to understand if we refer to the master IRQ's as M0-M7 and the slave IRQ's as S0-S7.

Q: But I've also got an Ethernet controller on IRQ 12. What about that?

In other words, your configuration might look something like this:

     0:  8578913   timer
     1:   109547   keyboard
     2:        0 + cascade
     3:    86470 + serial
     4:   197648 + serial
    12:    17968 + eth
    13:        1   math error
    14:    93123 + Ux4F

In this case, you might want to use:

because you want your ethernet card to have a higher priority than the diskcontroller. Actually if you did have this configuration, setting 3 14 (the default) would make the ethernet card, the lowest priority device in the system.

In our new notation IRQ 12 is S4, and the resulting priority would be:

    IRQ M/S  PRIOR
    0   M0     5
    1   M1     6
    2   M2     7
    3   M3     0
    4   M4     1
    5   M5     2
    6   M6     3
    7   M7     4
    8   S0     12
    9   S1     13
    10  S2     14
    11  S3     15
    12  S4     8
    13  S5     9
    14  S6     10
    15  S7     11
Q: Suppose I also had a serial multiplexer card on IRQ 11?

Once again, your configuration might look something like this:

     0:  8578913   timer
     1:   109547   keyboard
     2:        0 + cascade
     3:    86470 + serial
     4:   197648 + serial
    11:   197648 + sermux
    12:    17968 + eth
    13:        1   math error
    14:    93123 + Ux4F

This configuration is a bit tricky because now we've got a serial device on the slave controller. It would be much better to put all serial cards on the master controller. Things would stay much simpler.

In this case you would want to use:

The resulting priorities would be more complex and would result in somethinglike:

    IRQ M/S  PRIOR
    0   M0     13
    1   M1     14
    2   M2     0
    3   M3     8
    4   M4     9
    5   M5     10
    6   M6     11
    7   M7     12
    8   S0     5
    9   S1     6
    10  S2     7
    11  S3     0
    12  S4     1
    13  S5     2
    14  S6     3
    15  S7     4
The reason things would be better if all serial devices were on the master is that now you have serial devices at priorities 0, 8, and 9.

Q: So what's wrong with that?

Well, we boosted the priority of the serial multiplexer at the expense of the regular serial ports. The only way to allow all serial ports equally high priority is to group them on consecutive IRQ's and set the high priority for the lowest of those IRQ's.


How can I tell if irqtune actually did anything for me?

Well, first off, if PPP/SLIP was dying mysteriously, it will probably be more reliable.

Secondly, run without it and get a feel for the transfer rate:

Repeat this using irqtune and note the transfer times again. NOTE: IRQTUNE just won't quit--if you want to test in the original mode again, reboot the system first.


What if I still don't see any real improvement?

It's a matter of probability. Performance measurement is as much art as science.


What about other remedies I've heard about?

Q: What about disabling Van Jacobsen header compression?

This reduces the amount of bottom-half processing the system has to do at the expense of larger packets being sent.

Q: What about using ``hdparm -u'' to set the interrupt-unmask flag in hard disk driver?

It suffers from the same problem as the bottom-half routine. The disk controller typically uses IRQ 14 and 15. While the slave interrupt controller would probably allow preemption, the master (on IRQ 2) would not because the priority of all slave devices is higher than the serial IRQ priority.

Q: What about adjusting the MRU/MTU numbers?

This will have less of an effect now. In fact, we normally reduced the MRU to a minimum (296) to reduce the bottom-half processing and <flip-buffer> latency at the expense of adding extra overhead bytes due to the reduced packet size. We may now actually be able to increase the MRU to regain the efficiency.

Beware: Do this slowly as the optimal may not be 1500. The flip buffer in the serial/tty drivers is only 512 bytes.

Q: What about going to newer kernel revisions?

Although irqtune will work surprisingly well with just about any kernel revision, the low level IRQ handlers and device drivers have been vastly improved in the 2.0.X kernels. This will only improve irqtune's effect. In fact, 2.0.X and irqtune actually complement one another.


Didn't you give another explanation before, involving bottom-half routines?

Yes.

Many thanks to those that pointed this out.


Changes

FAQ 0.2 Changes: