[Xenomai-core] [patch, RFC] detect unhandled interrupts

2006-08-29 Thread Dmitry Adamushko

Hello,

Jan has rised this question initially and I was struggling last week to get his request eventually done :)

The main idea is to prevent system lockups when the cross domain IRQ
sharing isn't properly used (there were a number of reports recently).

So here is an initial patch as well as some related critics (yep, I critisize my own patch).

I tend to think now :

1) unhandled is not necessary indeed (do we need chasing spurious
interrupts the way Linux does it? i.e. it disables the line only after
a number of consequently unhandled interrupts  SOME_LIMIT);

2) XN_ISR_NONE -- should _not_ imply that the line gets re-enabled.

XN_ISR_HANDLED -- implies it, that's ok.

But XN_ISR_NONE (all ISRs in case of a shared RT line) should really mean something strange happens and it can be :

o either a spurious interrupt;

o something is sitting on the same line in the linux
domain. ISR should have returned XN_ISR_PROPAGATE in this case.


That said, if we are not interested in chasing spurious interrupts
the linux way, then this patch could be highly simplified to just
adding the following check in all nucleus ISR handlers.

+ if (unlikely(s == XN_ISR_NONE)) {
+
xnlogerr(xnintr_check_status: %d of unhandled consequent interrupts. 
+
Disabling the IRQ line #%d\n,
+
XNINTR_MAX_UNHANDLED, irq);
+ s |= XN_ISR_NOENABLE;
+ }

I tend to think this would be nicer?

-- Best regards,Dmitry Adamushko
___
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core


[Xenomai-core] Re: [patch, RFC] detect unhandled interrupts

2006-08-29 Thread Dmitry Adamushko

-ENOATTACHMENT (also a common issue...)
now fixed.

Jan-- Best regards,Dmitry Adamushko
diff -upr xenomai-SVN/include/nucleus/intr.h xenomai/include/nucleus/intr.h
--- xenomai-SVN/include/nucleus/intr.h	2006-07-20 11:09:01.0 +0200
+++ xenomai/include/nucleus/intr.h	2006-08-29 21:20:19.0 +0200
@@ -43,6 +43,8 @@ typedef struct xnintr {
 
 #if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL) || defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
 struct xnintr *next; /* ! Next object in the IRQ-sharing chain. */
+#else
+unsigned unhandled;	/* ! Number of consequent unhandled interrupts */
 #endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL || CONFIG_XENO_OPT_SHIRQ_EDGE */
 
 xnisr_t isr;	/* ! Interrupt service routine. */
diff -upr xenomai-SVN/ksrc/nucleus/intr.c xenomai/ksrc/nucleus/intr.c
--- xenomai-SVN/ksrc/nucleus/intr.c	2006-07-20 12:35:40.0 +0200
+++ xenomai/ksrc/nucleus/intr.c	2006-08-29 21:52:49.0 +0200
@@ -159,6 +159,8 @@ int xnintr_init(xnintr_t *intr,
 	intr-flags = flags;
 #if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL) || defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
 	intr-next = NULL;
+#else
+	intr-unhandled = 0;
 #endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL || CONFIG_XENO_OPT_SHIRQ_EDGE */
 
 	return 0;
@@ -374,6 +376,7 @@ void xnintr_clock_handler(void)
 	xnintr_irq_handler(nkclock.irq, nkclock);
 }
 
+#define XNINTR_MAX_UNHANDLED	1000
 /*
  * Low-level interrupt handler dispatching the ISRs -- Called with
  * interrupts off.
@@ -393,6 +396,14 @@ static void xnintr_irq_handler(unsigned 
 	s = intr-isr(intr);
 	++intr-hits;
 
+	if (unlikely(s == XN_ISR_NONE  ++intr-unhandled == XNINTR_MAX_UNHANDLED)) {
+		xnlogerr(xnintr_check_status: %d of unhandled consequent interrupts. 
+			Disabling the IRQ line #%d\n,
+			XNINTR_MAX_UNHANDLED, irq);
+		s |= XN_ISR_NOENABLE;
+	} else
+		intr-unhandled = 0;
+
 	if (s  XN_ISR_PROPAGATE)
 		xnarch_chain_irq(irq);
 	else if (!(s  XN_ISR_NOENABLE))
@@ -422,6 +433,7 @@ static void xnintr_irq_handler(unsigned 
 typedef struct xnintr_shirq {
 
 	xnintr_t *handlers;
+	int unhandled;
 #ifdef CONFIG_SMP
 	atomic_counter_t active;
 #endif/* CONFIG_SMP */
@@ -482,12 +494,21 @@ static void xnintr_shirq_handler(unsigne
 	intr = shirq-handlers;
 
 	while (intr) {
-		s |= intr-isr(intr)  XN_ISR_BITMASK;
+		s |= intr-isr(intr);
 		++intr-hits;
 		intr = intr-next;
 	}
+
 	xnintr_shirq_unlock(shirq);
 
+	if (unlikely(s == XN_ISR_NONE  ++shirq-unhandled == XNINTR_MAX_UNHANDLED)) {
+		xnlogerr(xnintr_irq_handler: %d of unhandled consequent interrupts. 
+			Disabling the IRQ line #%d\n,
+			XNINTR_MAX_UNHANDLED, irq);
+		s |= XN_ISR_NOENABLE;
+	} else	
+		shirq-unhandled = 0;
+
 	if (s  XN_ISR_PROPAGATE)
 		xnarch_chain_irq(irq);
 	else if (!(s  XN_ISR_NOENABLE))
@@ -527,16 +548,15 @@ static void xnintr_edge_shirq_handler(un
 	intr = shirq-handlers;
 
 	while (intr != end) {
-		int ret, code, bits;
+		int ret, code;
 
 		ret = intr-isr(intr);
 		code = ret  ~XN_ISR_BITMASK;
-		bits = ret  XN_ISR_BITMASK;
+		s |= ret;
 
 		if (code == XN_ISR_HANDLED) {
 			++intr-hits;
 			end = NULL;
-			s |= bits;
 		} else if (code == XN_ISR_NONE  end == NULL)
 			end = intr;
 
@@ -554,6 +574,14 @@ static void xnintr_edge_shirq_handler(un
 		(xnintr_edge_shirq_handler() : failed to get the IRQ%d line free.\n,
 		 irq);
 
+	if (unlikely(s == XN_ISR_NONE  ++shirq-unhandled == XNINTR_MAX_UNHANDLED)) {
+		xnlogerr(xnintr_irq_handler: %d of unhandled consequent interrupts. 
+			Disabling the IRQ line #%d\n,
+			XNINTR_MAX_UNHANDLED, irq);
+		s |= XN_ISR_NOENABLE;
+	} else	
+		shirq-unhandled = 0;
+
 	if (s  XN_ISR_PROPAGATE)
 		xnarch_chain_irq(irq);
 	else if (!(s  XN_ISR_NOENABLE))
@@ -613,6 +641,7 @@ static int xnintr_shirq_attach(xnintr_t 
 handler = xnintr_edge_shirq_handler;
 #endif /* CONFIG_XENO_OPT_SHIRQ_EDGE */
 		}
+		shirq-unhandled = 0;
 
 		err = xnarch_hook_irq(intr-irq, handler, intr-iack, intr);
 		if (err)
___
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core