EOI Seem To Be "Accepted" Randomly

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
fifo
Posts: 7
Joined: Wed May 30, 2012 4:37 pm

EOI Seem To Be "Accepted" Randomly

Post by fifo »

I am getting inconsistent results acknowledging IPI by writing to EOI.

At startup, I clean the APIC as much as I can and check IRR and ISR are "empty".

run1: send 1000 IPI from one core to the other at 1 IPI per ms rate. All IPIs are logged properly on the other core.

run2: I send one IPI from one core to the other, the ISR write EOI and displays IRR and ISR: IRR is "empty" while ISR shows my vector still present.

I send a second IPI, it appears in IRR and of course nothing happens.

In a nut shell, EOI seem to be "accepted" randomly.

Additional info:
- runs on Nehalem 2 CPU, in 64 bits mode
- No other IRQs or IPIs are triggered (each vector has a specific count)
- LAPIC memory is Uncached (MTRR and page descriptor)

How can I investigate this case ?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: EOI Seem To Be "Accepted" Randomly

Post by Brendan »

Hi,

Sounds like a bug (e.g. possibly a "forgot to put "volatile" in the right place/s" bug).

Could you post the code for the ISR, etc?


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
fifo
Posts: 7
Joined: Wed May 30, 2012 4:37 pm

Re: EOI Seem To Be "Accepted" Randomly

Post by fifo »

EDIT: If I add a 32000 pause instructions after writing to EOI register, it works well..

The ISR just "prints" on the serial port and account for the number of invocations.

code template for ISRs:

Code: Select all

void __##name##Gate(void) \
{ \
    asm volatile("\n\t" \
	"nop\n\t" \
	"nop\n\t" \
	"nop\n\t" \
	"nop\n\t" \
	"nop\n\t" \
	"nop\n\t" \
	"nop\n\t" \
	"nop\n\t" \
	"nop\n\t" \
	"nop\n\t" \
	"nop\n\t" \
	"nop\n\t" \
	"cli\n\t" \
	"movq %%r15, %%gs:8+128\n\t" \
	"movq %%r14, %%gs:8+120\n\t" \
	"movq %%r13, %%gs:8+112\n\t" \
	"movq %%r12, %%gs:8+104\n\t" \
	"movq %%r11, %%gs:8+96\n\t" \
	"movq %%r10, %%gs:8+88\n\t" \
	"movq %%r9,  %%gs:8+80\n\t" \
	"movq %%r8,  %%gs:8+72\n\t" \
	"movq %%rbp, %%gs:8+56\n\t" \
	"movq %%rdi, %%gs:8+48\n\t" \
	"movq %%rsi, %%gs:8+40\n\t" \
	"movq %%rdx, %%gs:8+32\n\t" \
	"movq %%rcx, %%gs:8+24\n\t" \
	"movq %%rbx, %%gs:8+16\n\t" \
	"movq %%rax, %%gs:8+8\n\t" \
	"movq 0(%%rsp),%%rax\n\tmovq %%rax, %%gs:8+0\n\t" \
	"movq 16(%%rsp),%%rax\n\tmovq %%rax, %%gs:8+136\n\t" \
	"movq 24(%%rsp),%%rax\n\tmovq %%rax, %%gs:8+64\n\t" \
	"movq %%rsp, %%rdi\n\t" \
	"call %P1\n\t" \
	"call %P0\n\t" \
	"movq %%gs:8+64,%%rax\n\tmov %%rax, 24(%%rsp)\n\t" \
	"movq %%gs:8+136,%%rax\n\tmov %%rax, 16(%%rsp)\n\t" \
	"movq %%gs:8+0,%%rax\n\tmov %%rax, 0(%%rsp)\n\t" \
	"movq %%gs:8+128, %%r15\n\t" \
	"movq %%gs:8+120, %%r14\n\t" \
	"movq %%gs:8+112, %%r13\n\t" \
	"movq %%gs:8+104, %%r12\n\t" \
	"movq %%gs:8+96, %%r11\n\t" \
	"movq %%gs:8+88, %%r10\n\t" \
	"movq %%gs:8+80, %%r9\n\t" \
	"movq %%gs:8+72, %%r8\n\t" \
	"movq %%gs:8+56, %%rbp\n\t" \
	"movq %%gs:8+48, %%rdi\n\t" \
	"movq %%gs:8+40, %%rsi\n\t" \
	"movq %%gs:8+32, %%rdx\n\t" \
	"movq %%gs:8+24, %%rcx\n\t" \
	"movq %%gs:8+16, %%rbx\n\t" \
	"movq %%gs:8+8, %%rax\n\t" \
	"iretq\n\t" \
	:\
	: "i"(name), "i" (Lapic_signalEOI) \
	); \
} \

Code: Select all

void Lapic_signalEOI(void) 
{
    int i;
    Lapic_write(APIC_EOI, 0);
    Processor_sfence();
    for(i=0; i<32000; i++)
        Processor_pause();
}
I have tried to move arround the call to write to EOI without succcess.
fifo
Posts: 7
Joined: Wed May 30, 2012 4:37 pm

Re: EOI Seem To Be "Accepted" Randomly

Post by fifo »

You were right about the volatile: now it works with:

Code: Select all

inline void Lapic_write(u32 offset, u32 value) 
{
    u32* volatile apicReg;
    apicReg= ((u32* volatile)(apicAddress+offset));
    *apicReg=value;
}
It's been a long time I did not bow.... but I have to do it now ;-)

Well done!!!
Post Reply