From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 529 invoked by alias); 3 Aug 2006 15:37:54 -0000 Received: (qmail 514 invoked by uid 22791); 3 Aug 2006 15:37:52 -0000 X-Spam-Check-By: sourceware.org Received: from mta3.th.hotchilli.net (HELO mta3.th.hotchilli.net) (62.89.140.53) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 03 Aug 2006 15:37:47 +0000 Received: from [192.168.1.106] (static-195-248-102-183.adsl.hotchilli.net [195.248.102.183]) by mta3.th.hotchilli.net (Postfix) with ESMTP id BB2762445BE; Thu, 3 Aug 2006 16:37:44 +0100 (BST) Message-ID: <44D2184C.6080801@ovus.co.uk> Date: Thu, 03 Aug 2006 15:37:00 -0000 From: Mike User-Agent: Thunderbird 1.5.0.5 (Windows/20060719) MIME-Version: 1.0 To: eCos Discussion CC: Nick Garnett References: <44B7850A.4050508@ovus.co.uk> <44CDBFC1.1050909@televic.com> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Mailing-List: contact ecos-discuss-help@ecos.sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: ecos-discuss-owner@ecos.sourceware.org Subject: Re: [ECOS] Possible fix for interrupt latency problems on Arm X-SW-Source: 2006-08/txt/msg00032.txt.bz2 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! ! then call interrupt_end( isr_retcode, &intr_object, ®save ) ! 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