From 1a8e06a365bebd238409eb8562c505e05438107f Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Tue, 4 Sep 2018 13:09:23 +0200 Subject: [PATCH] add interface providing the free list to the hypervisor (#101) Add an interface for sharing the free list with the hypervisor. This can be used to accelerate the cold migration of guests. --- arch/aarch64/mm/memory.c | 5 +++++ arch/x86_64/mm/memory.c | 5 +++++ caves | 2 +- drivers/net/uhyve-net.c | 6 +++--- include/hermit/memory.h | 5 +++++ include/hermit/stddef.h | 2 ++ include/hermit/vma.h | 1 + mm/vma.c | 16 +++++++++++++++- 8 files changed, 37 insertions(+), 5 deletions(-) diff --git a/arch/aarch64/mm/memory.c b/arch/aarch64/mm/memory.c index 9649d1643..a9c5d5a15 100644 --- a/arch/aarch64/mm/memory.c +++ b/arch/aarch64/mm/memory.c @@ -64,6 +64,11 @@ atomic_int64_t total_pages = ATOMIC_INIT(0); atomic_int64_t total_allocated_pages = ATOMIC_INIT(0); atomic_int64_t total_available_pages = ATOMIC_INIT(0); +free_list_t *get_free_list(void) +{ + return free_start; +} + size_t get_pages(size_t npages) { size_t i, ret = 0; diff --git a/arch/x86_64/mm/memory.c b/arch/x86_64/mm/memory.c index 0786057f9..9d997acc6 100644 --- a/arch/x86_64/mm/memory.c +++ b/arch/x86_64/mm/memory.c @@ -134,6 +134,11 @@ out: return ret; } +free_list_t *get_free_list(void) +{ + return free_start; +} + size_t get_pages(size_t npages) { return __get_pages(npages, PAGE_SIZE); diff --git a/caves b/caves index 9f19fde7b..1e1a23bc8 160000 --- a/caves +++ b/caves @@ -1 +1 @@ -Subproject commit 9f19fde7b78ea85d3f7ff06252316f75579df617 +Subproject commit 1e1a23bc82a71c5326b1cc0a76883ee2a52a7f3f diff --git a/drivers/net/uhyve-net.c b/drivers/net/uhyve-net.c index d77760eed..108789eb1 100755 --- a/drivers/net/uhyve-net.c +++ b/drivers/net/uhyve-net.c @@ -58,7 +58,7 @@ #include "uhyve-net.h" -#define UHYVE_IRQ 11 +#define UHYVE_IRQ_NET 11 static int8_t uhyve_net_init_ok = 0; static struct netif* mynetif = NULL; @@ -257,8 +257,8 @@ err_t uhyve_netif_init (struct netif* netif) LWIP_DEBUGF(NETIF_DEBUG, ("\n")); uhyve_netif->ethaddr = (struct eth_addr *)netif->hwaddr; - LOG_INFO("uhye_netif uses irq %d\n", UHYVE_IRQ); - irq_install_handler(32+UHYVE_IRQ, uhyve_irqhandler); + LOG_INFO("uhye_netif uses irq %d\n", UHYVE_IRQ_NET); + irq_install_handler(32+UHYVE_IRQ_NET, uhyve_irqhandler); /* * Initialize the snmp variables and counters inside the struct netif. diff --git a/include/hermit/memory.h b/include/hermit/memory.h index 7a3a828a5..cd0fd95e6 100644 --- a/include/hermit/memory.h +++ b/include/hermit/memory.h @@ -36,12 +36,17 @@ #ifndef __MEMORY_H__ #define __MEMORY_H__ +typedef struct free_list free_list_t; + /** @brief Initialize the memory subsystem */ int memory_init(void); /** @brief Request physical page frames */ size_t get_pages(size_t npages); +/** @brief Returns a pointer to the free_list */ +free_list_t *get_free_list(void); + /** @brief Get a single page * * Convenience function: uses get_pages(1); diff --git a/include/hermit/stddef.h b/include/hermit/stddef.h index 11166ed2b..4681baec0 100644 --- a/include/hermit/stddef.h +++ b/include/hermit/stddef.h @@ -74,6 +74,8 @@ extern size_t image_size; #define UHYVE_PORT_NETREAD 0x680 #define UHYVE_PORT_NETSTAT 0x700 +#define UHYVE_PORT_FREELIST 0x720 + /* Ports and data structures for uhyve command line arguments and envp * forwarding */ #define UHYVE_PORT_CMDSIZE 0x740 diff --git a/include/hermit/vma.h b/include/hermit/vma.h index 5e465112b..5d9a0d458 100644 --- a/include/hermit/vma.h +++ b/include/hermit/vma.h @@ -37,6 +37,7 @@ #define __VMA_H__ #include +#include #include #ifdef __cplusplus diff --git a/mm/vma.c b/mm/vma.c index fd388222c..ad0f84d37 100644 --- a/mm/vma.c +++ b/mm/vma.c @@ -32,7 +32,10 @@ #include #include #include +#include +#include +#define UHYVE_IRQ_FREELIST 12 /* * Note that linker symbols are not variables, they have no memory allocated for * maintaining a value, rather their address is their value. @@ -49,6 +52,13 @@ static vma_t vma_boot = { VMA_MIN, VMA_MIN, VMA_HEAP }; static vma_t* vma_list = &vma_boot; spinlock_irqsave_t hermit_mm_lock = SPINLOCK_IRQSAVE_INIT; +typedef struct free_list free_list_t; + +static void uhyve_irq_freelist_handler(struct state* s) +{ + outportl(UHYVE_PORT_FREELIST, (unsigned)virt_to_phys((size_t)get_free_list())); +} + int vma_init(void) { int ret; @@ -68,7 +78,11 @@ int vma_init(void) ret = vma_add(HEAP_START, HEAP_START+HEAP_SIZE, VMA_NO_ACCESS); if (BUILTIN_EXPECT(ret, 0)) goto out; - LOG_INFO("Reserve space for the heap: 0x%llx - 0x%llx\n", HEAP_START, HEAP_START+HEAP_SIZE-1); + LOG_INFO("Reserve space for the heap: 0x%llx - 0x%llx\n", HEAP_START, HEAP_START+HEAP_SIZE-1); + + // install IRQ handler for the migration interface + LOG_INFO("freelist channel uses irq %d\n", UHYVE_IRQ_FREELIST); + irq_install_handler(32+UHYVE_IRQ_FREELIST, uhyve_irq_freelist_handler); // we might move the architecture specific VMA regions to a // seperate function vma_arch_init()