|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [UNIKRAFT PATCH 2/2] plat/linuxu: do not allocate IRQ handler entries dynamically
This commit applies the same strategy as previously done for the KVM
platform. We pre-allocate IRQ handlers statically. Their number can be
configured via a new config variable LINUXU_MAX_IRQ_HANDLER_ENTRIES.
Signed-off-by: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxx>
---
plat/linuxu/Config.uk | 4 +++
plat/linuxu/irq.c | 67 ++++++++++++++++++++++++++++++---------------------
2 files changed, 43 insertions(+), 28 deletions(-)
diff --git a/plat/linuxu/Config.uk b/plat/linuxu/Config.uk
index d8c86d8..0394f91 100644
--- a/plat/linuxu/Config.uk
+++ b/plat/linuxu/Config.uk
@@ -17,4 +17,8 @@ if (PLAT_LINUXU)
changed by using linuxu.heap_size as a command line argument.
For more
information refer to "Command line arguments in Unikraft"
sections in
the developers guide
+
+ config LINUXU_MAX_IRQ_HANDLER_ENTRIES
+ int "Maximum number of IRQ handlers per event"
+ default 8
endif
diff --git a/plat/linuxu/irq.c b/plat/linuxu/irq.c
index 961dcf9..c1de4d1 100644
--- a/plat/linuxu/irq.c
+++ b/plat/linuxu/irq.c
@@ -32,8 +32,7 @@
* THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
*/
#include <string.h>
-#include <uk/alloc.h>
-#include <uk/list.h>
+#include <errno.h>
#include <uk/plat/lcpu.h>
#include <uk/plat/irq.h>
#include <uk/assert.h>
@@ -41,24 +40,34 @@
#include <linuxu/signal.h>
#define IRQS_NUM 16
+#define HANDLER_RESERVED ((void *) 0x1)
/* IRQ handlers declarations */
struct irq_handler {
+ /* func() special values:
+ * NULL: free,
+ * HANDLER_RESERVED: reserved
+ */
irq_handler_func_t func;
void *arg;
struct uk_sigaction oldaction;
-
- UK_SLIST_ENTRY(struct irq_handler) entries;
};
-UK_SLIST_HEAD(irq_handler_head, struct irq_handler);
-static struct irq_handler_head irq_handlers[IRQS_NUM];
+static struct irq_handler irq_handlers[IRQS_NUM]
+ [CONFIG_LINUXU_MAX_IRQ_HANDLER_ENTRIES];
-static struct uk_alloc *allocator;
static k_sigset_t handled_signals_set;
static unsigned long irq_enabled;
+static inline struct irq_handler *allocate_handler(unsigned long irq)
+{
+ for (int i = 0; i < CONFIG_LINUXU_MAX_IRQ_HANDLER_ENTRIES; i++)
+ if (irq_handlers[irq][i].func == NULL)
+ return &irq_handlers[irq][i];
+ return NULL;
+}
+
void ukplat_lcpu_enable_irq(void)
{
int rc;
@@ -123,10 +132,16 @@ asm("__restorer:mov r7, #0x77\nsvc 0x0");
static void _irq_handle(int irq)
{
struct irq_handler *h;
+ int i;
UK_ASSERT(irq >= 0 && irq < IRQS_NUM);
- UK_SLIST_FOREACH(h, &irq_handlers[irq], entries) {
+ for (i = 0; i < CONFIG_LINUXU_MAX_IRQ_HANDLER_ENTRIES; i++) {
+ if (irq_handlers[irq][i].func == NULL)
+ break;
+ else if (irq_handlers[irq][i].func == HANDLER_RESERVED)
+ continue; /* reserved entry */
+ h = &irq_handlers[irq][i];
if (h->func(h->arg) == 1)
return;
}
@@ -151,11 +166,15 @@ int ukplat_irq_register(unsigned long irq,
irq_handler_func_t func, void *arg)
return -EINVAL;
/* New handler */
- h = uk_malloc(allocator, sizeof(struct irq_handler));
- if (!h)
- return -ENOMEM;
- h->func = func;
- h->arg = arg;
+ flags = ukplat_lcpu_save_irqf();
+ h = allocate_handler(irq);
+ if (!h) {
+ ukplat_lcpu_restore_irqf(flags);
+ return -EINVAL;
+ }
+
+ h->func = HANDLER_RESERVED; /* reserve */
+ ukplat_lcpu_restore_irqf(flags);
/* Register signal action */
memset(&action, 0, sizeof(action));
@@ -164,12 +183,14 @@ int ukplat_irq_register(unsigned long irq,
irq_handler_func_t func, void *arg)
action.k_sa_restorer = __restorer;
rc = sys_sigaction((int) irq, &action, &h->oldaction);
- if (rc != 0)
+ if (rc != 0) {
+ h->func = NULL; /* give back */
goto err;
+ }
- flags = ukplat_lcpu_save_irqf();
- UK_SLIST_INSERT_HEAD(&irq_handlers[irq], h, entries);
- ukplat_lcpu_restore_irqf(flags);
+ /* Enable the handler */
+ h->func = func;
+ h->arg = arg;
/* Unblock the signal */
k_sigemptyset(&set);
@@ -185,22 +206,12 @@ int ukplat_irq_register(unsigned long irq,
irq_handler_func_t func, void *arg)
return 0;
err:
- uk_free(allocator, h);
return -rc;
}
-int ukplat_irq_init(struct uk_alloc *a)
+int ukplat_irq_init(struct uk_alloc *a __unused)
{
UK_ASSERT(!irq_enabled);
- UK_ASSERT(!allocator);
-
- allocator = a;
-
- /* Clear list head */
- for (int i = 0; i < IRQS_NUM; i++)
- UK_SLIST_INIT(&irq_handlers[i]);
-
k_sigemptyset(&handled_signals_set);
-
return 0;
}
--
2.7.4
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |