[linux-audio-user] APIC

Clemens Ladisch clemens at ladisch.de
Tue Jan 20 05:05:27 EST 2004


Yesterday, I wrote:
> Mark Knecht wrote:
> >    Also, the first link says 'For APICs, when two interrupts are present
> > when interrupts are enabled, the one with the highest interrupt vector
> > number will be taken first' and 'So, the last PCI interrupt source in the
> > MPS table will be the highest priority'.
> >
> >    However the second link says 'The local APIC unit will handle interrupts
> > depending on vector, with lowest being highest priority. Here is a sample
> > table with NR being the IRQ e.g. 0 = 31;'
> >
> >    For me this wording seems contradictory,
>
> I think the first is simply wrong

I've looked into the Intel documentation, and it turns out I thought
wrong, i.e., the first quoted link is right.  (But it was for an older
Linux version which assigned vector numbers consecutively.)

Section 8.3.3 of the "IA-32 Intel(R) Architecture Software Developer's
Manual, Volume 3: System Programming Guide" says:

| For interrupts that are delivered to the processor through the local
| APIC, each interrupt has an implied priority based on its vector
| number. The local APIC uses this priority to determine when to
| service the interrupt relative to the other activities of the
| processor, including the servicing of other interrupts.
|
| For interrupts vectors in the range of 16 to 255, the interrupt
| priority is determined using the following relationship:
|
| priority = vector / 16
|
| Here the quotient is rounded down to the nearest integer value to
| determine the priority, with 1 being the lowest priority and 15 is
| the highest.  Because vectors 0 through 31 are reserved for
| dedicated uses by the IA-32 architecture, the priorities of user
| defined interrupts range from 2 to 15.
|
| Each interrupt priority level (sometimes interpreted by software as
| an interrupt priority class) encompasses 16 vectors.  Prioritizing
| interrupts within a priority level is determined by the vector
| number.  The higher the vector number, the higher the priority
| within that priority level.  In determining the priority of a vector
| and ranking of vectors within a priority group, the vector number is
| often divided into two parts, with the high 4 bits of the vector
| indicating its priority and the low 4 bit indicating its ranking
| within the priority group.

So, if Intel's explanation is correct, higher vector numbers have
higer priority.

> The table shown by Zwane is output into the system log when booting.

For example, on my P4P800, dmesg says:

.... IRQ redirection table:
 NR Log Phy Mask Trig IRR Pol Stat Dest Deli Vect:
 00 000 00  1    0    0   0   0    0    0    00
 01 003 03  0    0    0   0   0    1    1    39
 02 003 03  0    0    0   0   0    1    1    31
 03 003 03  0    0    0   0   0    1    1    41
 04 003 03  0    0    0   0   0    1    1    49
 05 003 03  0    0    0   0   0    1    1    51
 06 003 03  0    0    0   0   0    1    1    59
 07 003 03  0    0    0   0   0    1    1    61
 08 003 03  0    0    0   0   0    1    1    69
 09 003 03  0    1    0   0   0    1    1    71
 0a 003 03  0    0    0   0   0    1    1    79
 0b 003 03  0    0    0   0   0    1    1    81
 0c 003 03  0    0    0   0   0    1    1    89
 0d 003 03  0    0    0   0   0    1    1    91
 0e 003 03  0    0    0   0   0    1    1    99
 0f 003 03  0    0    0   0   0    1    1    A1
 10 003 03  1    1    0   1   0    1    1    B9
 11 003 03  1    1    0   1   0    1    1    B1
 12 003 03  1    1    0   1   0    1    1    A9
 13 003 03  1    1    0   1   0    1    1    C1
 14 003 03  1    1    0   1   0    1    1    D1
 15 003 03  1    1    0   1   0    1    1    D9
 16 003 03  1    1    0   1   0    1    1    E1
 17 003 03  1    1    0   1   0    1    1    C9

So, interrupt 22 (0x16) has the highest priority (vector 0xE1),
followed by interrupts 21 and 20, etc.  (On the P4P800, these
interrupts are assigned to the onboard 3C940 and PCI slots 5 and 4,
respectively.)

It would be possible to assign a different vector number to a specific
interrupt by patching the assign_irq_vector function in
arch/i386/kernel/io_apic.c


> >    One other piece of interesting information was that you can supposedly
> > control the ordering of the interrupt table using some kernel type software.
> > This would be quite cool since you could then insert your sound card
> > anywhere into the list and give it the very best servicing that your machine
> > can provide.
>
> The "Task Priority Register" register mentioned there lets you assign
> a priority to each CPU, so that an interrupt can interrupt the
> lowest-priority task in a multi-CPU system.

This explanation is slightly wrong, too.  The processor priority isn't
determined by the TPR but by the PPR (Processor Priority Register),
which is computed as follows:
| [T]he processor priority is set to either to the highest priority
| pending interrupt [...] or to the current task priority, whichever
| is higher.

The TPR is used to suppress interrupts which have a lower priority
than the current task priority.


Regards,
Clemens





More information about the Linux-audio-user mailing list