Subject: Re: splserial() higher than splhigh()?
To: Allen Briggs <briggs@wasabisystems.com>
From: David Querbach <querbach@realtime.bc.ca>
List: tech-kern
Date: 01/31/2001 10:08:10
> The interrupts are disabled by the processor when the exception is taken,
> and are not re-enabled (for some reason, I thought that they were, but I
> don't see it now).
>
> > For the softint processing, you probably do want to have interrupts
> > re-enabled, but this code obviously doesn't do that. This would be
> > pretty straight-forward to do.
>
> ...except for the fact that if you have re-enabled interrupts prior
> to doing the softint processing, it's quite possible that another
> h/w interrupt has come in and been deferred at that point (which you
> may will miss due to the reentrancy check). You could put a loop here,
> but I don't think you really want that, either. So this isn't quite
> as straight-forward as I thought at first.
Thanks for that confirmation. Here's what I'm thinking of doing:
External interrupts are already masked in the MSR by hardware when
the exception is taken. The first level exception handler also
ensures proper interrupt stack nesting.
Find out which is the highest hardware priority active interrupt
source. Raise the IPL to the IPL of this interrupt, and mask all
interrupt sources with the same or lower IPL.
Enable external interrupts in the MSR.
Run the appropriate interrupt handler. While running the handler,
we may accept another higher-IPL interrupt if it occurs.
Disable external interrupts in the MSR.
Restore the IPL to what it was before we raised it. Unmask hardware
interrupt sources appropriately. Check for any pending software
interrupts:
For each software interrupt source (in order of priority),
if pending and not masked by IPL:
Raise the IPL to the level of this interrupt.
Enable external interrupts in the MSR.
Run the appropriate handler. We can be interrupted
by any higher IPL interrupt (hard or soft) while the
handler is running.
Disable external interrupts in the MSR
Loop over the software interrupts until no more are pending
and unmasked.
Return to the first level handler which will restore the stack. The
hardware will enable external interrupts as we leave the first-level
handler.
Similar but simpler code will be used for the decrementer interrupt. The
last half or so of the code above forms the splx() function, which is called
by the decrementer interrupt and throughout the kernel to restore the IPL
after a critical section.
Note that in this method, interrupts are deferred in hardware, rather than
in software. This should give lower latency. This method also allows
software interrupt handlers to pre-empt one another, according to their IPL.
> Sorry for any confusion.
Not at all. Thanks again for looking at the code and confirming my read of
it.
Regards,
David Querbach
Real-Time Systems Inc.