[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
- [PATCH] user_intr: a lock to protect main_intr_queue,
Junling Ma <=