From owner-freebsd-hackers Tue Oct 1 11:30:39 1996 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id LAA08143 for hackers-outgoing; Tue, 1 Oct 1996 11:30:39 -0700 (PDT) Received: from pat.idt.unit.no (pat.idt.unit.no [129.241.103.5]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id LAA07788 for ; Tue, 1 Oct 1996 11:23:01 -0700 (PDT) Received: from idt.unit.no (hyll.idt.unit.no [129.241.200.3]) by pat.idt.unit.no (8.7.5/8.7.3) with ESMTP id UAA17515 for ; Tue, 1 Oct 1996 20:22:39 +0200 (MET DST) Message-Id: <199610011822.UAA17515@pat.idt.unit.no> To: freebsd-hackers@freebsd.org Subject: Interrupt lossage in FreeBSD-current. Mime-Version: 1.0 X-Mailer: Mew version 1.03 on Emacs 19.31.1 Content-Type: Text/Plain; charset=us-ascii Date: Tue, 01 Oct 1996 20:22:39 +0200 From: Tor Egge Sender: owner-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk I've written a device driver for an ISA card that has the potential of generating interrupts as fast as the machine is able to handle them. It is not a common situation, but it may happens for short periods at a time (e.g. 0.3 seconds). One problem though, is that this may cause a high interrupt latency (0.3 seconds), with the net effect that one RTC interrupt is lost. Profiling and CPU time accountings stops working. In an attempt to avoid losing an RTC interrupt, I've recently added some code to the interrupt handler in the device driver to check for a pending timer interrupt and a repeatedly pending RTC interrupt. If such an interrupt is pending, the restart of the device is performed in a timeout routine called by softclock instead of in the interrupt handler, causing all pending hardware interrupts to be processed. This seems to work, and prohibit the loss of RTC interrupts, but I found no good method of checking for pending/blocked interrupts: ((imen & 1) || (inb(IO_ICU1) & 1)) and ((imen & 256) || (inb(IO_ICU2) & 1)) are not what I would consider easily readable code to check for pending IRQ0 and IRQ8. A macro as e.g.: #define INTRBLOCKED(i) ((imen & (1<<(i))) || (inb((i)>=8?IO_ICU2:IO_ICU1)&(1<<((i)&7)))) can cause the code to be more readable, but may also add some overhead unless the compiler manages to reduce it to the variants shown earlier. Maybe a better way is to rewrite the fastintr handler, to enable the ICUs before calling the interrupt handler? Then the interrupt handler could enable interrupts, disable interrupts, and just check the imen variable instead of polling the interrupt controller. Then a macro for the check would be trivial, e.g.: #define INTRBLOCKED(i) (imen & (1<<(i))) I cannot immediately see any reasons not to reenable the ICUs before calling the interrupt handler from the fast interrupt vector code in vector.s, since interrupts are disabled by default when the interrupt handler is called. Any good suggestions? - Tor Egge