[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 |