Re: [linux-audio-user] APIC

New Message Reply About this list Date view Thread view Subject view Author view Other groups

Subject: Re: [linux-audio-user] APIC
From: Clemens Ladisch (clemens_AT_ladisch.de)
Date: Tue Jan 20 2004 - 12:05:27 EET


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


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : Tue Jan 20 2004 - 12:06:52 EET