Messages in this thread | | | Date | Mon, 29 Jan 2007 11:00:11 -0800 | From | Auke Kok <> | Subject | Re: Possible regression: MSI vector leakage since 2.6.18-rc5ish (Unable to repeatedly allocate/free MSI interrupt) |
| |
Eric W. Biederman wrote: > Auke Kok <auke-jan.h.kok@intel.com> writes: > >> Hi, >> >> I've established a regression in the MSI vector/irq allocation routine for both >> i386 and x86_64. Our test labs repeatedly modprobe/rmmod the e1000 driver for >> serveral minutes which allocates msi vectors and frees them. These tests have >> been running fine until 2.6.19. [snip] >> I mostly suspect commit 7bd007e480672c99d8656c7b7b12ef0549432c37 at the >> moment. Perhaps Eric Biederman can help? > > Does this patch fix it for you? It looks like i386 vector allocate > did not have logic to look through the set of vectors more than once.
Yes. A few hundred cycles of loading/unloading snd_hda_intel with enable_msi=1 didn't break it on i386.
I sure hope this can get into 2.6.20!
Auke
> The code in this patch is a simplified version of what we have > on x86_64. > > Eric > > > diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c > index 2424cc9..6a3875f 100644 > --- a/arch/i386/kernel/io_apic.c > +++ b/arch/i386/kernel/io_apic.c > @@ -1227,26 +1227,32 @@ static u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 } > > static int __assign_irq_vector(int irq) > { > - static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; > - int vector; > + static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0; > + int vector, offset, i; > > BUG_ON((unsigned)irq >= NR_IRQ_VECTORS); > > if (irq_vector[irq] > 0) > return irq_vector[irq]; > > - current_vector += 8; > - if (current_vector == SYSCALL_VECTOR) > - current_vector += 8; > - > - if (current_vector >= FIRST_SYSTEM_VECTOR) { > - offset++; > - if (!(offset % 8)) > - return -ENOSPC; > - current_vector = FIRST_DEVICE_VECTOR + offset; > - } > - > vector = current_vector; > + offset = current_offset; > +next: > + vector += 8; > + if (vector >= FIRST_SYSTEM_VECTOR) { > + offset = (offset + 1) % 8; > + vector = FIRST_DEVICE_VECTOR + offset; > + } > + if (vector == current_vector) > + return -ENOSPC; > + if (vector == SYSCALL_VECTOR) > + goto next; > + for (i = 0; i < NR_IRQ_VECTORS; i++) > + if (irq_vector[i] == vector) > + goto next; > + > + current_vector = vector; > + current_offset = offset; > irq_vector[irq] = vector; > > return vector; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |