Damien Zammit, le ven. 11 juil. 2025 06:56:30 +0000, a ecrit: > This avoids race condition with multiple devices raising interrupts > simultaneously on the same IRQ and causing mask to fail. > > TESTED: on SMP and UP+apic gnumach, boots to console and receives > a large file over rumpnet on debian hurd-i386.
Applied, thanks! > --- > i386/i386/irq.c | 49 ++++++++++++++++++++++++++++++++--------- > i386/i386/irq.h | 1 + > i386/i386at/model_dep.c | 1 + > 3 files changed, 40 insertions(+), 11 deletions(-) > > diff --git a/i386/i386/irq.c b/i386/i386/irq.c > index 91318f67..6268db18 100644 > --- a/i386/i386/irq.c > +++ b/i386/i386/irq.c > @@ -34,32 +34,59 @@ irq_eoi (struct irqdev *dev, int id) > #endif > } > > -static unsigned int ndisabled_irq[NINTR]; > +/* Each array elem fits in a cache line */ > +struct nested_irq { > + simple_lock_irq_data_t irq_lock; > + int32_t ndisabled; > + uint32_t unused[14]; > +} __attribute__((packed)) nested_irqs[NINTR]; > + > +void > +init_irqs (void) > +{ > + int i; > + > + for (i = 0; i < NINTR; i++) > + { > + simple_lock_init_irq(&nested_irqs[i].irq_lock); > + nested_irqs[i].ndisabled = 0; > + } > +} > > void > __disable_irq (irq_t irq_nr) > { > + spl_t s; > + struct nested_irq *nirq = &nested_irqs[irq_nr]; > + > assert (irq_nr < NINTR); > > - spl_t s = splhigh(); > - ndisabled_irq[irq_nr]++; > - assert (ndisabled_irq[irq_nr] > 0); > - if (ndisabled_irq[irq_nr] == 1) > + s = simple_lock_irq(&nirq->irq_lock); > + > + nirq->ndisabled++; > + assert (nirq->ndisabled > 0); > + if (nirq->ndisabled == 1) > mask_irq (irq_nr); > - splx(s); > + > + simple_unlock_irq(s, &nirq->irq_lock); > } > > void > __enable_irq (irq_t irq_nr) > { > + spl_t s; > + struct nested_irq *nirq = &nested_irqs[irq_nr]; > + > assert (irq_nr < NINTR); > > - spl_t s = splhigh(); > - assert (ndisabled_irq[irq_nr] > 0); > - ndisabled_irq[irq_nr]--; > - if (ndisabled_irq[irq_nr] == 0) > + s = simple_lock_irq(&nirq->irq_lock); > + > + assert (nirq->ndisabled > 0); > + nirq->ndisabled--; > + if (nirq->ndisabled == 0) > unmask_irq (irq_nr); > - splx(s); > + > + simple_unlock_irq(s, &nirq->irq_lock); > } > > struct irqdev irqtab = { > diff --git a/i386/i386/irq.h b/i386/i386/irq.h > index 72bbe57b..e1f41045 100644 > --- a/i386/i386/irq.h > +++ b/i386/i386/irq.h > @@ -23,6 +23,7 @@ > > typedef unsigned int irq_t; > > +void init_irqs (void); > void __enable_irq (irq_t irq); > void __disable_irq (irq_t irq); > > diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c > index 42dadeb8..afb4fadd 100644 > --- a/i386/i386at/model_dep.c > +++ b/i386/i386at/model_dep.c > @@ -176,6 +176,7 @@ void machine_init(void) > #if defined(APIC) > ioapic_configure(); > #endif > + init_irqs(); > clkstart(); > > /* > -- > 2.45.2 > > > -- Samuel AUTHOR FvwmM4 is the result of a random bit mutation on a hard disk, presumably a result of a cosmic-ray or some such thing. (extrait de la page de man de FvwmM4)