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)

Reply via email to