bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] user_intr: a lock to protect main_intr_queue


From: Junling Ma
Subject: [PATCH] user_intr: a lock to protect main_intr_queue
Date: Sun, 2 Aug 2020 21:04:24 -0700

1. The queue manipulated by two threads, the registration server and the 
intr_thread, so we need a lock to protect it.
2. To initialize the lock, we introduce a irq_init function in 
i386/i386/irq.[ch] and call it in device/device_init.c

---
 device/device_init.c |  3 ++-
 device/intr.c        | 26 ++++++++++++++++++++------
 device/intr.h        |  6 ++++--
 i386/i386/irq.c      | 16 ++++++++++++----
 i386/i386/irq.h      |  2 ++
 5 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/device/device_init.c b/device/device_init.c
index 794186ee..4e5109ff 100644
--- a/device/device_init.c
+++ b/device/device_init.c
@@ -41,7 +41,7 @@
 #include <device/ds_routines.h>
 #include <device/net_io.h>
 #include <device/chario.h>
-
+#include <machine/irq.h>
 
 ipc_port_t     master_device_port;
 
@@ -60,6 +60,7 @@ device_service_create(void)
        net_io_init();
        device_pager_init();
        chario_init();
+       irq_init();
 
        (void) kernel_thread(kernel_task, io_done_thread, 0);
        (void) kernel_thread(kernel_task, net_thread, 0);
diff --git a/device/intr.c b/device/intr.c
index fbb9f495..705dc1c6 100644
--- a/device/intr.c
+++ b/device/intr.c
@@ -23,18 +23,31 @@
 
 #ifndef MACH_XEN
 
-queue_head_t main_intr_queue;
+extern struct irqdev irqtab;
+#define main_intr_queue irqtab.intr_queue
 static boolean_t deliver_intr (int id, ipc_port_t dst_port);
 
+#define PROTECT(lock, critical_section) \
+{\
+  simple_lock(&lock);\
+  critical_section;\
+  simple_unlock(&lock);\
+}
+
 static user_intr_t *
 search_intr (struct irqdev *dev, ipc_port_t dst_port)
 {
   user_intr_t *e;
-  queue_iterate (dev->intr_queue, e, user_intr_t *, chain)
+  simple_lock(&dev->lock);
+  queue_iterate (&dev->intr_queue, e, user_intr_t *, chain)
     {
       if (e->dst_port == dst_port)
-       return e;
+        {
+          simple_unlock(&dev->lock);
+          return e;
+        }
     }
+  simple_unlock(&dev->lock);
   return NULL;
 }
 
@@ -64,7 +77,7 @@ irq_acknowledge (ipc_port_t receive_port)
   if (irqtab.irqdev_ack)
     (*(irqtab.irqdev_ack)) (&irqtab, e->id);
 
-  __enable_irq (irqtab.irq[e->id]);
+  PROTECT(irqtab.lock, __enable_irq (irqtab.irq[e->id]));
 
   return D_SUCCESS;
 }
@@ -139,7 +152,7 @@ insert_intr_entry (struct irqdev *dev, int id, ipc_port_t 
dst_port)
   new->interrupts = 0;
   new->n_unacked = 0;
 
-  queue_enter (dev->intr_queue, new, user_intr_t *, chain);
+  PROTECT(dev->lock, queue_enter (&dev->intr_queue, new, user_intr_t *, 
chain));
 out:
   splx (s);
   if (free)
@@ -153,7 +166,6 @@ intr_thread (void)
   user_intr_t *e;
   int id;
   ipc_port_t dst_port;
-  queue_init (&main_intr_queue);
 
   for (;;)
     {
@@ -163,6 +175,7 @@ intr_thread (void)
       spl_t s = splhigh ();
 
       /* Check for aborted processes */
+      simple_lock(&irqtab.lock);
       queue_iterate (&main_intr_queue, e, user_intr_t *, chain)
        {
          if ((!e->dst_port || e->dst_port->ip_references == 1) && e->n_unacked)
@@ -231,6 +244,7 @@ intr_thread (void)
              s = splhigh ();
            }
        }
+      simple_unlock(&irqtab.lock);
       splx (s);
       thread_block (NULL);
     }
diff --git a/device/intr.h b/device/intr.h
index cd3e0bce..54ddb331 100644
--- a/device/intr.h
+++ b/device/intr.h
@@ -42,14 +42,14 @@ struct irqdev {
   char *name;
   void (*irqdev_ack)(struct irqdev *dev, int id);
 
-  queue_head_t *intr_queue;
+  queue_head_t intr_queue;
+  decl_simple_lock_data(, lock);/* a lock to protect the intr_queue */
   int tot_num_intr; /* Total number of unprocessed interrupts */
 
   /* Machine dependent */
   irq_t irq[NINTR];
 };
 
-extern queue_head_t main_intr_queue;
 extern int install_user_intr_handler (struct irqdev *dev, int id, unsigned 
long flags, user_intr_t *e);
 extern int deliver_user_intr (struct irqdev *dev, int id, user_intr_t *e);
 extern user_intr_t *insert_intr_entry (struct irqdev *dev, int id, ipc_port_t 
receive_port);
@@ -57,6 +57,8 @@ extern user_intr_t *insert_intr_entry (struct irqdev *dev, 
int id, ipc_port_t re
 void intr_thread (void);
 kern_return_t irq_acknowledge (ipc_port_t receive_port);
 
+void irq_init(void);
+
 #endif /* MACH_XEN */
 
 #endif
diff --git a/i386/i386/irq.c b/i386/i386/irq.c
index 35681191..4ef1c43f 100644
--- a/i386/i386/irq.c
+++ b/i386/i386/irq.c
@@ -60,8 +60,16 @@ __enable_irq (irq_t irq_nr)
   splx(s);
 }
 
-struct irqdev irqtab = {
-  "irq", irq_eoi, &main_intr_queue, 0,
-  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
-};
+struct irqdev irqtab;
+
+void irq_init()
+{  
+  irqtab.name = "irq";
+  irqtab.irqdev_ack = irq_eoi;
+  queue_init (&irqtab.intr_queue);
+  simple_lock_init(&irqtab.lock);
+  irqtab.tot_num_intr = 0;
+  for (int i = 0; i < NINTR; ++i)
+    irqtab.irq[i] = i;
+}
 
diff --git a/i386/i386/irq.h b/i386/i386/irq.h
index d48a8e92..1ca105ef 100644
--- a/i386/i386/irq.h
+++ b/i386/i386/irq.h
@@ -22,6 +22,8 @@ typedef unsigned int irq_t;
 void __enable_irq (irq_t irq);
 void __disable_irq (irq_t irq);
 
+void irq_init();
+
 extern struct irqdev irqtab;
 
 #endif
-- 
2.28.0.rc1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]