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