summaryrefslogtreecommitdiff
path: root/debian/patches/700010-Fix-infinite-loop-with-cli-if-netdde-is-killed-with-.patch
blob: cbf3b0208c71ba31c2a4765c34608af09418317e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
From 23ffabdd5b4e62340454884bf1e85c925bcf509b Mon Sep 17 00:00:00 2001
From: Justus Winter <justus@gnupg.org>
Date: Fri, 26 Feb 2016 16:01:46 +0100
Subject: [PATCH gnumach 10/15] Fix infinite loop with cli if netdde is killed
 with pending irqs

---
 device/intr.c | 38 +++++++++++++++++---------------------
 1 file changed, 17 insertions(+), 21 deletions(-)

diff --git a/device/intr.c b/device/intr.c
index a061d5e..39408ea 100644
--- a/device/intr.c
+++ b/device/intr.c
@@ -28,8 +28,6 @@ struct intr_entry
 typedef struct intr_entry *intr_entry_t;
 
 static queue_head_t intr_queue;
-/* The total number of unprocessed interrupts. */
-static int tot_num_intr;
 
 /* This function can only be used in the interrupt handler. */
 boolean_t
@@ -37,7 +35,6 @@ queue_intr (struct intr_entry *e)
 {
   cli ();
   e->interrupts++;
-  tot_num_intr++;
   sti ();
 
   thread_wakeup ((event_t) &intr_thread);
@@ -251,24 +248,23 @@ intr_thread ()
       assert_wait ((event_t) &intr_thread, FALSE);
       cli ();
 
-      while (tot_num_intr)
-	queue_iterate (&intr_queue, e, struct intr_entry *, chain)
-	  if (e->interrupts)
-	    {
-	      line = e->line;
-	      dest = e->dest;
-	      e->interrupts--;
-	      tot_num_intr--;
-
-	      sti ();
-	      deliver_intr (line, dest);
-	      cli ();
-
-	      /* We cannot assume that e still exists at this point
-		 because we released the lock.  Hence we restart the
-		 iteration.  */
-	      break;
-	    }
+    restart:
+      queue_iterate (&intr_queue, e, struct intr_entry *, chain)
+	if (e->interrupts)
+	  {
+	    line = e->line;
+	    dest = e->dest;
+	    e->interrupts--;
+
+	    sti ();
+	    deliver_intr (line, dest);
+	    cli ();
+
+	    /* We cannot assume that e still exists at this point
+	       because we released the lock.  Hence we restart the
+	       iteration.  */
+	    goto restart;
+	  }
 
       sti ();
       thread_block (thread_no_continuation);
-- 
2.1.4