pkg://hwtools_0.2.orig.tar.gz:99395/
hwtools-0.2.orig/
irqtune/
src/irqtune.pod
downloads
=title I<IRQTUNE> -- A Linux x86 IRQ Priority Optimizer
=head1 I<IRQTUNE> -- A Linux x86 IRQ Priority Optimizer
I<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.
B<With>
I<irqtune>,
B<a 3X speedup of serial/modem throughput is possible.>
=head1 Where do I get I<irqtune>?
I<irqtune> is free software under the terms and conditions of the GNU Public
License. See the file COPYING, included in the distribution, for details.
=over 4
=item *
It's available via anonymous ftp from:
ftp://www.best.com/pub/cae/irqtune.tgz (gzipped tar archive)
=item *
The author is Craig Estey, (cae@best.com).
=item *
This FAQ file is available both in html and text versions included in the tar
file. This FAQ is also available online via http://www.best.com/~cae/irqtune
=back
=head1 How do I know if I need I<irqtune>?
B<You are running Linux on an x86 PC, other architectures to be implemented>
B<later--Sorry.>
B<You probably need>
I<irqtune>,
B<if you are experiencing any of the following:>
=over 4
=item *
SLIP/PPP transfers seem slow. For example, using a 28.8 (or better) modem,
the effective throughput is approximately 700 bytes/second instead of the
expected 2500 bytes/second.
=item *
A running SLIP/PPP dies at random times.
=item *
Serial connections are slow or drop data.
=item *
Netscape hangs mysteriously or stalls when trying to access a web page.
=item *
Equivalent programs under Windoze run much faster than under Linux.
=item *
Disk accesses seem to interfere with SLIP/PPP.
=item *
Interrupt handlers for specialized, time critical devices don't get control
when they need to.
=back
=head1 What is actually happening to cause these problems?
I<Note to Linux kernel programmers: Please forgive the simplifications.>
B<Q: What should the system be doing?>
Serial devices are what are termed I<fast-interrupt> devices:
They require frequent interrupts but the interrupt service executes quickly.
Such devices require high IRQ priority.
On the the other end of the scale is the timer interrupt.
The kernel has some laborous tasks that it must perform internally for an
interrupt service routine.
These are too time consuming to perform with interrupts locked off.
Linux defers them and processes them, in the I<bottom-half> or
I<soft-interrupt> section of the timer interrupt.
When the kernel is in the I<bottom-half> routine, interrupts are enabled. This
allows other interrupt routines to preempt the I<bottom-half> routine, allow
I<fast-interrupt> routines to run, and resume the I<bottom-half> routine.
B<Q: Sounds fine, so what is wrong?>
Unfortunately, this is what should happen--it doesn't.
What actually happens is this:
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!!!
Because of the way the interrupt controller is currently programmed
under Linux, when it is executing the I<bottom-half>,
B<preemptive interrupt processing does not occur>.
The system will continue to execute the
I<bottom-half> routine until completion. The serial interrupt will not be
allowed to preempt the I<bottom-half> when it needs to, causing some characters
to be delayed, or worse yet, dropped.
B<Q: But, why is this so--The bottom-half>
B<interrupt code does enable interrupts!?!?>
It enables interrupts in the CPU itself (via I<sti>),
B<not> the interrupt controller.
The CPU B<would> allow the preemptive interrupt, but the interrupt
controller will B<not> permit the interrupt to be shown to the CPU.
B<Q: Why won't the interrupt controller allow the CPU to see the interrupt?>
Because the I<bottom-half> routine is executing at IRQ priority 0--the highest
priority in the system. The serial interrupt is given priority 11, one
of the lowest. The interrupt controller will not allow a lower priority
device to preempt a higher priority device.
B<Q: So if we could make the serial interrupt a higher priority than the>
B<timer interrupt, would this solve the problem?>
Exactly! This is what I<irqtune> does. It allows you to change the IRQ
priority of devices so that the high priority interrupts occur when they
are supposed to.
=head1 How do I install I<irqtune>?
=SS1
=over 4
=item *
Unpack the tar file:
=over 4
=item *
B<gzip -d < irqtune.tgz | tar xvf ->
=item *
It will create a directory, B<irqtune> in
whatever is the current directory.
=back
=item *
B<cd ./irqtune>
=item *
B<make install>
=over 4
=item *
This will install the files:
=over 4
=item *
/sbin/irqtune
=item *
/sbin/irqtune_mod.o
=back
=back
=back
=SS0
=head1 How do I use I<irqtune>? Don't I have to rebuild my kernel?
No, you do B<not> have to rebuild your kernel. I<irqtune> uses I<insmod> and
I<rmmod> to dynamically load and unload a kernel module. But you are correct
in sensing that irqtune is a kernel patch.
B<Q: Ok, if it's a kernel patch, why not just issue a kernel patch like>
B<everybody else does (e.g. diff -u output)?>
I<irqtune> will work even if you don't have the kernel source loaded. It uses
I<insmod> to load the patch, invoke it, and then unload it. The IRQ priority
changes will last so long as the kernel is booted.
B<Q: How do I invoke it?>
I<irqtune> takes two arguments optional arguments:
=over 4
=item *
irqtune I<master> I<slave>
=back
The only caveat is that you must specify the full pathname, even
if I<irqtune> is placed in a directory that is in $PATH. This is required
because I<irqtune> uses argv[0] to locate its B<irqtune_mod.o> file.
The default is I<3 14> which will work for many standard configurations.
More on this later.
B<Q: Could I do this from my /etc/rc.d/rc.local file?>
Yes. Just add a B</sbin/irqtune> line to this file and you're
in business.
You may also issue another I<irqtune> command at any time.
B<Q: But aren't kernel patches dependent on the particular revision of the>
B<kernel? What if my kernel revision is different from the kernel revision>
B<that you built it on?>
I<irqtune> is 99.44% kernel revision independent. It is built
using ELF binaries, so your I<insmod> must understand them. But that's
really about it.
B<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 I<irqtune>. Just be sure
that B</usr/src/linux/include> is installed. Then, just type:
=SS1
=over 4
=item *
B<make clean>
=item *
B<make sbin>
=item *
B<make install>
=back
=SS0
and that should do the trick.
=head1 What about my non-standard hardware configuration?
I<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.
B<Q: How do I determine what my IRQ configuration is?>
Just type B<cat /proc/interrupts> and you'll get something like:
=for html <PRE>
0: 8578913 timer
1: 109547 keyboard
2: 0 + cascade
3: 86470 + serial
4: 197648 + serial
13: 1 math error
14: 93123 + Ux4F
</PRE>
Note that
B</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.
B<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 B<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:
=over 4
=item *
B</sbin/irqtune> I<3>
=back
This sets IRQ 3 to the highest priority.
In fact, before we invoked I<irqtune>, the IRQ number was also its priority:
=for html <PRE>
IRQ PRIOR
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
</PRE>
After this command, the IRQ priorities are now:
=for html <PRE>
IRQ PRIOR
0 5
1 6
2 7
3 0
4 1
5 2
6 3
7 4
</PRE>
B<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 I<master>
and a I<slave>. The I<slave> is I<cascaded> to the I<master> via its IRQ 2.
The I<master> controls IRQ's 0-7 and the I<slave> controls IRQ's 8-15.
You actually may select two high IRQ priorities, one for the I<master> and one
for the I<slave>. I<irqtune> defaults the I<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 I<master> IRQ's as M0-M7 and the I<slave> IRQ's
as S0-S7.
B<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:
=for html <PRE>
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<P>
</PRE>
In this case, you might want to use:
=over 4
=item *
B</sbin/irqtune> I<3 12>
=back
because you want your ethernet card to have a higher priority than the disk
controller. 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:
=for html <PRE>
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
</PRE>
B<Q: Suppose I also had a serial multiplexer card on IRQ 11?>
Once again, your configuration might look something like this:
=for html <PRE>
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<P>
</PRE>
This configuration is a bit tricky because now we've got a serial device on
the I<slave> controller. It would be much better to put all serial cards on
the I<master> controller. Things would stay much simpler.
In this case you would want to use:
=over 4
=item *
B</sbin/irqtune> I<2 11>
=back
The resulting priorities would be more complex and would result in something
like:
=for html <PRE>
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
</PRE>
The reason things would be better if all serial devices were on the I<master>
is that now you have serial devices at priorities 0, 8, and 9.
B<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.
=head1 How can I tell if I<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:
=SS1
=over 4
=item *
Hit many of your favorite web sites and note the transfer rates in
bytes/second.
=item *
FTP reports the transfer time of a file in bytes/second. Download (or upload)
a few files (300K or greater to smooth out the benchmark) and note the
transfer rates.
=back
=SS0
Repeat this using I<irqtune> and note the transfer times again.
I<NOTE: IRQTUNE just won't quit--if you want to test in the original mode>
I<again, reboot the system first.>
=head1 What about other remedies I've heard about?
B<Q: What about disabling Van Jacobsen header compression?>
This reduces the amount of I<bottom-half> processing the system has to do at
the expense of larger packets being sent.
B<Q: What about using "hdparm -u" to set the interrupt-unmask flag in hard>
B<disk driver?>
It suffers from the same problem as the I<bottom-half> routine.
The disk controller typically uses
IRQ 14 and 15. While the I<slave> interrupt controller would
probably allow preemption,
the I<master> (on IRQ 2) would not because the priority of all I<slave>
devices is higher than the serial IRQ priority.
B<Q: What about adjusting the MRU/MTU numbers?>
This will have less of an effect now. In fact, you normally reduced the MRU
to a minimum (296) to reduce the I<bottom-half> processing at the expense of
adding extra overhead bytes due to the reduced packet size. You may now
actually be able to increase the MRU to regain the efficiency.
I<Beware: Do this slowly as the optimal may not be 1500. The flip buffer>
I<in the serial/tty drivers is only 512 bytes.>
B<Q: What about going to newer kernel revisions?>
Although I<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 I<irqtune>'s effect. In fact, 2.0.X and
I<irqtune> actually complement one another.