[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [UNIKRAFT PATCH 1/2] plat/kvm: do not allocate IRQ handler entries dynamically
IRQ handler entries are currently allocated dynamically. This has two undesired consequences: (1) this requires the dynamic memory allocator to be initialized when ukplat_irq_init() is called, which happens quite early, and (2) this makes the registering of IRQ handlers quite expensive. Pre-allocate IRQ handles statically. Their number can be configured via a new config variable KVM_MAX_IRQ_HANDLER_ENTRIES. Signed-off-by: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxx> --- plat/kvm/Config.uk | 5 +++++ plat/kvm/irq.c | 40 ++++++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/plat/kvm/Config.uk b/plat/kvm/Config.uk index 3372b6c..fe4d8cf 100644 --- a/plat/kvm/Config.uk +++ b/plat/kvm/Config.uk @@ -65,6 +65,11 @@ endif endmenu +config KVM_MAX_IRQ_HANDLER_ENTRIES + int "Maximum number of IRQ handlers per event" + default 8 + depends on (ARCH_X86_64) + config KVM_PCI bool "PCI Bus Driver" default y diff --git a/plat/kvm/irq.c b/plat/kvm/irq.c index 8f43aa6..1a8be10 100644 --- a/plat/kvm/irq.c +++ b/plat/kvm/irq.c @@ -27,7 +27,6 @@ #include <stdlib.h> #include <uk/alloc.h> -#include <uk/list.h> #include <uk/plat/lcpu.h> #include <uk/plat/common/cpu.h> #include <uk/plat/common/irq.h> @@ -37,17 +36,21 @@ #include <errno.h> #include <uk/bitops.h> -static struct uk_alloc *allocator; - struct irq_handler { irq_handler_func_t func; void *arg; - - UK_SLIST_ENTRY(struct irq_handler) entries; }; -UK_SLIST_HEAD(irq_handler_head, struct irq_handler); -static struct irq_handler_head irq_handlers[__MAX_IRQ]; +static struct irq_handler irq_handlers[__MAX_IRQ] + [CONFIG_KVM_MAX_IRQ_HANDLER_ENTRIES]; + +static inline struct irq_handler *allocate_handler(unsigned long irq) +{ + for (int i = 0; i < CONFIG_KVM_MAX_IRQ_HANDLER_ENTRIES; i++) + if (irq_handlers[irq][i].func == NULL) + return &irq_handlers[irq][i]; + return NULL; +} int ukplat_irq_register(unsigned long irq, irq_handler_func_t func, void *arg) { @@ -55,19 +58,17 @@ int ukplat_irq_register(unsigned long irq, irq_handler_func_t func, void *arg) unsigned long flags; UK_ASSERT(irq < __MAX_IRQ); - UK_ASSERT(allocator != NULL); - h = uk_malloc(allocator, sizeof(struct irq_handler)); + flags = ukplat_lcpu_save_irqf(); + h = allocate_handler(irq); if (!h) - return -ENOMEM; + UK_CRASH("Insufficient number of IRQ handler entries.\n"); h->func = func; - h->arg = arg; - - flags = ukplat_lcpu_save_irqf(); - UK_SLIST_INSERT_HEAD(&irq_handlers[irq], h, entries); ukplat_lcpu_restore_irqf(flags); + h->arg = arg; + intctrl_clear_irq(irq); return 0; } @@ -81,8 +82,12 @@ extern unsigned long sched_have_pending_events; void _ukplat_irq_handle(unsigned long irq) { struct irq_handler *h; + int i; - UK_SLIST_FOREACH(h, &irq_handlers[irq], entries) { + for (i = 0; i < CONFIG_KVM_MAX_IRQ_HANDLER_ENTRIES; i++) { + if (irq_handlers[irq][i].func == NULL) + break; + h = &irq_handlers[irq][i]; /* TODO define platform wise macro for timer IRQ number */ if (irq != 0) /* IRQ 0 is reserved for a timer, responsible to @@ -112,9 +117,8 @@ exit_ack: intctrl_ack_irq(irq); } -int ukplat_irq_init(struct uk_alloc *a) +int ukplat_irq_init(struct uk_alloc *a __unused) { - UK_ASSERT(allocator == NULL); - allocator = a; + /* Nothing for now */ return 0; } -- 2.7.4
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |