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/10] 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
|