Port-amd64 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[PATCH] Warn on unhandled interrupts



Hi,

while chasing a spurious interrupt bug I realised that the kernel
doesn't warn about unhandled interrupts on amd64. In fact, it ignores
the return value of the interrupt handlers completely. I wrote the patch
below so that the kernel will complain when an interrupt goes
unhandled. The warning is rate limited to once every 5 seconds and it
will only complain at most 10 times for any given slot.

Be aware that I haven't done much x86-64 assembly programming and so
there could be some issues with the vector.S patch. For example, I've no
idea if the kernel expects a particular alignment for the stack.

The patch is also available from,
http://www.netbsd.org/~mjf/patches/amd64-spurious-interrupt.patch

Comments?


Index: src/sys/arch/amd64/amd64/machdep.c
===================================================================
--- src.orig/sys/arch/amd64/amd64/machdep.c     2010-05-28 16:37:38.000000000 
+0100
+++ src/sys/arch/amd64/amd64/machdep.c  2010-05-29 00:15:42.796764916 +0100
@@ -1800,3 +1800,25 @@
 {
        return memseg_baseaddr(l, seg, ldtp, len, NULL);
 }
+
+static struct timeval lasttime;
+static struct timeval intervaltime = { 5, 0 }; /* interval time is 5 seconds */
+
+static unsigned long long intr_count[MAX_INTR_SOURCES];
+static int warn_count[MAX_INTR_SOURCES];
+
+void unhandled_intr(int slot)
+{
+       intr_count[slot]++;
+
+       if (ratecheck(&lasttime, &intervaltime)) {
+               if (warn_count[slot] == 10) {
+                       warn_count[slot]++;     /* So we don't warn again. */
+                       printf("Warned about unhandled interrupt 10 times. Shutting up now.\n");
+               } else if (warn_count[slot] < 10) {
+                       warn_count[slot]++;
+                       printf("Unhandled interrupt! slot #%d, count %llu\n",
+                           slot, intr_count[slot]);
+               }
+       }
+}
Index: src/sys/arch/amd64/amd64/vector.S
===================================================================
--- src.orig/sys/arch/amd64/amd64/vector.S      2010-05-28 16:38:55.000000000 
+0100
+++ src/sys/arch/amd64/amd64/vector.S   2010-05-28 23:34:38.069712108 +0100
@@ -682,6 +682,7 @@
        sti                                                             ;\
        incl    CPUVAR(IDEPTH)                                          ;\
        movq    IS_HANDLERS(%r14),%rbx                                  ;\
+       pushq   $0                      /* push 'handled' */            ;\
 6:                                                                     \
        movl    IH_LEVEL(%rbx),%r12d                                    ;\
        cmpl    %r13d,%r12d                                             ;\
@@ -691,9 +692,15 @@
        movl    %r12d,CPUVAR(ILEVEL)                                    ;\
        call    *IH_FUN(%rbx)           /* call it */                   ;\
        movq    IH_NEXT(%rbx),%rbx      /* next handler in chain */     ;\
+       addl    %eax,(%rsp)                                             ;\
        testq   %rbx,%rbx                                               ;\
        jnz     6b                                                      ;\
+       cmpl    $0,(%rsp)               /* was the intr handled? */     ;\
+       jne     5f                                                      ;\
+       movl    $num,%edi                                               ;\
+       call    _C_LABEL(unhandled_intr)                                ;\
 5:                                                                     \
+       addq    $8,%rsp                 /* pop 'handled' */             ;\
        cli                                                             ;\
        unmask(num)                     /* unmask it in hardware */     ;\
        late_ack(num)                                                   ;\
Index: src/sys/arch/amd64/include/intr.h
===================================================================
--- src.orig/sys/arch/amd64/include/intr.h      2010-05-29 09:25:59.000000000 
+0100
+++ src/sys/arch/amd64/include/intr.h   2010-05-29 09:26:26.332451320 +0100
@@ -1,3 +1,5 @@
 /*     $NetBSD: intr.h,v 1.1 2003/04/26 18:39:42 fvdl Exp $    */
 
 #include <x86/intr.h>
+
+extern void unhandled_intr(int);


Home | Main Index | Thread Index | Old Index