[ECOS] Possible fix for interrupt latency problems on Arm

Mike mjs2@ovus.co.uk
Thu Aug 3 15:37:00 GMT 2006


Nick Garnett wrote:
> That change is not a good idea. It can introduce race conditions into
> the system. I think you have been lucky so far.
>
> Although interrupt_end() is entered with interrupts disabled, they
> will be enabled to call DSRs, that's what
> hal_interrupt_stack_call_pending_DSRs does. Interrupts will also be
> re-enabled if a context switch is made. So interrupts will get turned
> back on within a few microseconds of completing the ISR
Hi Nick,

Thanks for getting involved on this one! Prior to my mod, I was indeed 
seeing interrupts being re-enabled in 
hal_interrupt_stack_call_pending_DSRs. However, my problem was that this 
call was being made some time after the interrupt, and resulted in me 
seeing interrupts being disabled for up to 1.3ms, which was simply no good!

I had hoped that the copious use of HAL_DISABLE_INTERRUPTS() in the 
functions called by interrupt_end() would have prevented any race 
conditions. As far as I could determine the only impact of my mod would 
be on the size of interrupt stack needed.

The reason I was hopeful that this was a good mod is that other 
architectures do appear to re-enable ints before the interrupt_end() call.
For example the sparc code does:


    ! First restore the processor interrupt level to that interrupted
    ! (otherwise a task-switch runs at the current PIL) on the assumption
    ! that the ISR dealt with the interrupt source per se, so it is safe
    ! to unmask it, effectively:
    or    %l0, 0x0e0, %l7        ! original PSR and ET (+S,PS)
    wr    %l7, %psr        ! and enable!
    <omitted some code here>

    ! then call interrupt_end( isr_retcode, &intr_object, &regsave )
    ! to unlock the scheduler and do any rescheduling that~s needed.
    ! argument 0 (isr_retcode) is already in place in %o0
    sethi    %hi(hal_interrupt_objects), %l7
    or    %l7, %lo(hal_interrupt_objects), %l7
    ld    [ %l7 + %l3 ], %o1
    add    %sp, 24 * 4, %o2    ! saved regset (maybe tiny)

    .extern interrupt_end
    call    interrupt_end


Likewise for the 68k:


        /*   The  interrupt_end  routine  will   call  the   DSRs  and   
do */
        /* rescheduling when it  decrements the  scheduler lock  from 1  
to */
        /* zero.  In this case, we  do not want  to have interrupts  
masked */
        /* while the DSRs run.   Restore the  interrupt mask  to the  
value */
        /* prior  to  this  interrupt.    Do  not  completely  unmask   
all */
        /* interrupts because this interrupt may be a nested interrupt.  
We */
        /* do not want to lower  the interrupt mask  on the lower  
priority */
        /* 
interrupt.                                                       */

        move.w  (4*3)+int_pres_regs_sz+2(%sp),%d2
        move.w  %d2,%sr

        /*   If the interrupt mask was not previously zero, we want to 
make */
        /* sure that the DSRs to not run and no preemption occurs.  Add 
the */
        /* value of the previous interrupt mask to the scheduler lock.   
If */
        /* the previous mask was  zero, the scheduler  lock will remain  
at */
        /* one and the interrupt  end function will  decrement it to  
zero. */
        /* Otherwise, we want  to prevent the  interrupt end function  
from */
        /* unlocking the scheduler.  We do  this because there is a  
chance */
        /* that someone had  interrupts masked with  the scheduler lock  
at */
        /* zero.  If a  higher  priority  interrupt  occurs,  we  could  
be */
        /* running DSRs and doing preemption with the interrupts 
masked!    */

        and.l   #0x0700,%d2
        lsr.l   #8,%d2
        add.l   %d2,cyg_scheduler_sched_lock

        .extern interrupt_end               /*   Call the  
interrupt_end  C */
        jbsr    interrupt_end               /* routine.  This routine 
might */
                                            /* preempt    the     
currently */
                                            /* running 
thread.              */


Mike





-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss



More information about the Ecos-discuss mailing list