summaryrefslogtreecommitdiff
path: root/device/intr.c
diff options
context:
space:
mode:
authorJustus Winter <justus@gnupg.org>2016-02-26 16:01:46 +0100
committerJustus Winter <justus@gnupg.org>2016-02-26 16:01:46 +0100
commit23ffabdd5b4e62340454884bf1e85c925bcf509b (patch)
tree8cb5e8e3cde933f0fe433ce8294e7c35acd956cc /device/intr.c
parent7debcbf8fb5b5b99e5a0b48ec6e9672455237938 (diff)
Fix infinite loop with cli if netdde is killed with pending irqs
Diffstat (limited to 'device/intr.c')
-rw-r--r--device/intr.c38
1 files 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);