1. no isr is required for the lapic. (and the old code was wrong anyway). don't do it. this saves ~100 cycles/clock interrupt. we're now down to ~980 from 1380 just a few days ago. 2. properly account for rdts in ioapics. panic if the count is off. don't call ioapicintrdisable for msi interrupts. Reference: /n/atom/patch/applied/lapicnoisr Date: Fri Jan 3 03:59:51 CET 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/nix/k10/lapic.c Fri Jan 3 03:57:51 2014 +++ /sys/src/nix/k10/lapic.c Fri Jan 3 03:57:51 2014 @@ -108,16 +108,6 @@ return vecno; } -int -lapicisr(int vecno) -{ - int isr; - - isr = lapicrget(Is + (vecno/32)*16); - - return isr & (1<<(vecno%32)); -} - static char* lapicprint(char *p, char *e, Lapic *a, int i) { --- /sys/src/nix/k10/apic.h Fri Jan 3 03:57:51 2014 +++ /sys/src/nix/k10/apic.h Fri Jan 3 03:57:51 2014 @@ -84,6 +84,8 @@ int gsitoapicid(int, uint*); void ioapicdump(void); Apic* ioapicinit(int, int, uintmem); +int ioapicintrdisable(int); +int ioapicintrenable(Vctl*); void ioapicintrinit(int, int, int, int, int, u32int); Apic* ioapiclookup(uint); void ioapiconline(void); @@ -91,7 +93,6 @@ int lapiceoi(int); void lapicinit(int, uintmem, int); void lapicipi(int); -int lapicisr(int); Apic* lapiclookup(uint); int lapiconline(void); void lapicpri(int); --- /sys/src/nix/k10/trap.c Fri Jan 3 03:57:51 2014 +++ /sys/src/nix/k10/trap.c Fri Jan 3 03:57:51 2014 @@ -101,7 +101,6 @@ intrdisable(void* vector) { Vctl *v, *x, **ll; - extern int ioapicintrdisable(int); ilock(&vctllock); v = vector; @@ -116,7 +115,10 @@ v->mask(v, 1); v->f(nil, v->a); *ll = v->next; - ioapicintrdisable(v->vno); /* BOTCH: this is wrong for non-ioapic interrupts shoid msi disable*/ + if(strcmp(v->type, "ioapic") == 0) + ioapicintrdisable(v->vno); + else + iprint("intrdisable: not disabling %s type %s\n", v->name, v->type); iunlock(&vctllock); free(v); --- /sys/src/nix/k10/ioapic.c Fri Jan 3 03:57:51 2014 +++ /sys/src/nix/k10/ioapic.c Fri Jan 3 03:57:51 2014 @@ -421,6 +421,8 @@ /* Set delivery mode (lo) and destination field (hi) */ *hi = mach->apicno<<24; *lo |= v->vno|Pm|MTf; + if(*lo & Lm) + *lo |= MTlp; return 0; } @@ -444,18 +446,14 @@ lo = IPlow | TMedge; ioapicphysdd(v, &hi, &lo); - if(lo & Lm) - lo |= MTlp; - msivec = (u64int)hi<<32 | lo; if(pcimsienable(p, msivec) == -1) return -1; - v->isr = lapicisr; v->eoi = lapiceoi; v->type = "msi"; v->mask = msimask; - DBG("msiirq: %T: enabling %.16llux %s irq %d vno %d\n", p->tbdf, msivec, v->name, v->irq, v->vno); + DBG("msiirq: %T: enabling %.16llux %s vno %d\n", p->tbdf, msivec, v->name, v->vno); return v->vno; } @@ -470,6 +468,7 @@ int ioapicintrenable(Vctl* v) { + Pcidev *p; Rbus *rbus; Rdt *rdt; u32int hi, lo; @@ -496,19 +495,13 @@ } } else if((bustype = BUSTYPE(v->tbdf)) == BusPCI){ - /* - * PCI. - * Make a devno from BUSDNO(tbdf) and pcidev->intp. - */ - Pcidev *pcidev; - busno = BUSBNO(v->tbdf); - if((pcidev = pcimatchtbdf(v->tbdf)) == nil) - panic("no PCI dev for tbdf %T", v->tbdf); - if(intrenablemsi(v, pcidev) != -1) + if((p = pcimatchtbdf(v->tbdf)) == nil) + panic("ioapic: no pci dev for tbdf %T", v->tbdf); + if(intrenablemsi(v, p) != -1) return v->vno; - disablemsi(v, pcidev); - if((devno = pcicfgr8(pcidev, PciINTP)) == 0) + disablemsi(v, p); + if((devno = pcicfgr8(p, PciINTP)) == 0) panic("no INTP for tbdf %T", v->tbdf); devno = BUSDNO(v->tbdf)<<2|(devno-1); DBG("ioapicintrenable: tbdf %T busno %d devno %d\n", @@ -551,10 +544,10 @@ * the whole IOAPIC to initialise the RDT entry * rather than putting a Lock in each entry. */ - lock(rdt->apic); DBG("%T: %ld/%d/%d (%d)\n", v->tbdf, rdt->apic - xioapic, rbus->devno, rdt->intin, devno); - rdt->enabled++; + lock(rdt->apic); + ainc(&rdt->enabled); lo = (rdt->lo & ~Im); ioapicphysdd(v, &hi, &lo); @@ -569,7 +562,6 @@ DBG("busno %d devno %d hi %#.8ux lo %#.8ux vecno %d\n", busno, devno, hi, lo, v->vno); - v->isr = lapicisr; v->eoi = lapiceoi; v->type = "ioapic"; @@ -581,26 +573,13 @@ { Rdt *rdt; - /* - * FOV. Oh dear. This isn't very good. - * Fortunately rdtvecno[vecno] is static - * once assigned. - * Must do better. - * - * What about any pending interrupts? - */ - if(vecno < 0 || vecno > MaxVectorAPIC){ - panic("ioapicintrdisable: vecno %d out of range", vecno); - return -1; - } if((rdt = rdtvecno[vecno]) == nil){ panic("ioapicintrdisable: vecno %d has no rdt", vecno); return -1; } lock(rdt->apic); - rdt->enabled--; - if(rdt->enabled == 0) + if(adec(&rdt->enabled) == 0) rtblput(rdt->apic, rdt->intin, 0, rdt->lo); unlock(rdt->apic);