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