From: Jack Lange Date: Wed, 4 Jul 2012 23:06:01 +0000 (-0400) Subject: memory leak fixes X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=5ce19b21aac351221fe41e95e717127bfec0c467;p=palacios.git memory leak fixes --- diff --git a/linux_module/iface-console.c b/linux_module/iface-console.c index a11c50e..067cefc 100644 --- a/linux_module/iface-console.c +++ b/linux_module/iface-console.c @@ -414,6 +414,11 @@ static void palacios_tty_close(void * console) { struct palacios_console * cons = (struct palacios_console *) console; cons->open = 0; + + remove_guest_ctrl(cons->guest, V3_VM_CONSOLE_CONNECT); + deinit_queue(cons->queue); + + kfree(cons); } diff --git a/linux_module/util-queue.c b/linux_module/util-queue.c index f7f6146..e9379bf 100644 --- a/linux_module/util-queue.c +++ b/linux_module/util-queue.c @@ -16,6 +16,12 @@ void init_queue(struct gen_queue * queue, unsigned int max_entries) { spin_lock_init(&(queue->lock)); } +void deinit_queue(struct gen_queue * queue) { + while (dequeue(queue)) { + ERROR("Freeing non-empty queue. PROBABLE MEMORY LEAK DETECTED\n"); + } +} + struct gen_queue * create_queue(unsigned int max_entries) { struct gen_queue * tmp_queue = palacios_alloc(sizeof(struct gen_queue)); if (!tmp_queue) { diff --git a/linux_module/util-queue.h b/linux_module/util-queue.h index d4c8ddd..2a60d9a 100644 --- a/linux_module/util-queue.h +++ b/linux_module/util-queue.h @@ -7,12 +7,14 @@ #define __PALACIOS_QUEUE_H__ +#include "palacios.h" #include #include + struct queue_entry { void * entry; struct list_head node; @@ -29,6 +31,8 @@ struct gen_queue { struct gen_queue * create_queue(unsigned int max_entries); void init_queue(struct gen_queue * queue, unsigned int max_entries); +void deinit_queue(struct gen_queue * queue); + int enqueue(struct gen_queue * queue, void * entry); void * dequeue(struct gen_queue * queue); diff --git a/linux_module/vm.c b/linux_module/vm.c index b14cff4..624cc39 100644 --- a/linux_module/vm.c +++ b/linux_module/vm.c @@ -93,6 +93,8 @@ int add_guest_ctrl(struct v3_guest * guest, unsigned int cmd, } + + static struct vm_ctrl * get_ctrl(struct v3_guest * guest, unsigned int cmd) { struct rb_node * n = guest->vm_ctrls.rb_node; struct vm_ctrl * ctrl = NULL; @@ -112,6 +114,36 @@ static struct vm_ctrl * get_ctrl(struct v3_guest * guest, unsigned int cmd) { return NULL; } +int remove_guest_ctrl(struct v3_guest * guest, unsigned int cmd) { + struct vm_ctrl * ctrl = get_ctrl(guest, cmd); + + if (ctrl == NULL) { + INFO("Could not find control (%d) to remove\n", cmd); + return -1; + } + + rb_erase(&(ctrl->tree_node), &(guest->vm_ctrls)); + + kfree(ctrl); + + return 0; +} + +static void free_guest_ctrls(struct v3_guest * guest) { + struct rb_node * node = rb_first(&(guest->vm_ctrls)); + struct vm_ctrl * ctrl = NULL; + struct rb_node * tmp_node = NULL; + + while (node) { + ctrl = rb_entry(node, struct vm_ctrl, tree_node); + tmp_node = node; + node = rb_next(node); + + WARNING("Cleaning up guest ctrl that was not removed explicitly (%d)\n", ctrl->cmd); + + kfree(ctrl); + } +} @@ -408,6 +440,9 @@ int free_palacios_vm(struct v3_guest * guest) { cdev_del(&(guest->cdev)); + free_guest_ctrls(guest); + + vfree(guest->img); palacios_free(guest); diff --git a/linux_module/vm.h b/linux_module/vm.h index 53af2af..fbf1713 100644 --- a/linux_module/vm.h +++ b/linux_module/vm.h @@ -18,6 +18,8 @@ int add_guest_ctrl(struct v3_guest * guest, unsigned int cmd, void * priv_data), void * priv_data); +int remove_guest_ctrl(struct v3_guest * guest, unsigned int cmd); + #endif diff --git a/palacios/include/palacios/vmm_queue.h b/palacios/include/palacios/vmm_queue.h index 811f19d..6135ab0 100644 --- a/palacios/include/palacios/vmm_queue.h +++ b/palacios/include/palacios/vmm_queue.h @@ -45,6 +45,7 @@ struct v3_queue { struct v3_queue * v3_create_queue(); void v3_init_queue(struct v3_queue * queue); +void v3_deinit_queue(struct v3_queue * queue); void v3_enqueue(struct v3_queue * queue, addr_t entry); addr_t v3_dequeue(struct v3_queue * queue); diff --git a/palacios/src/palacios/vmm_bitmap.c b/palacios/src/palacios/vmm_bitmap.c index ff7a7a7..a94d557 100644 --- a/palacios/src/palacios/vmm_bitmap.c +++ b/palacios/src/palacios/vmm_bitmap.c @@ -41,6 +41,7 @@ int v3_bitmap_init(struct v3_bitmap * bitmap, int num_bits) { void v3_bitmap_deinit(struct v3_bitmap * bitmap) { + v3_lock_deinit(&(bitmap->lock)); V3_Free(bitmap->bits); } diff --git a/palacios/src/palacios/vmm_queue.c b/palacios/src/palacios/vmm_queue.c index 28d41ac..5414ce9 100644 --- a/palacios/src/palacios/vmm_queue.c +++ b/palacios/src/palacios/vmm_queue.c @@ -19,6 +19,9 @@ #include + + + void v3_init_queue(struct v3_queue * queue) { queue->num_entries = 0; INIT_LIST_HEAD(&(queue->entries)); @@ -37,6 +40,17 @@ struct v3_queue * v3_create_queue() { return tmp_queue; } +void v3_deinit_queue(struct v3_queue * queue) { + while (v3_dequeue(queue)) { + PrintError("ERROR: Freeing non-empty queue. PROBABLE MEMORY LEAK DETECTED\n"); + } + + v3_lock_deinit(&(queue->lock)); +} + + + + void v3_enqueue(struct v3_queue * queue, addr_t entry) { struct v3_queue_entry * q_entry = V3_Malloc(sizeof(struct v3_queue_entry)); unsigned int flags = 0; diff --git a/palacios/src/vnet/vnet_core.c b/palacios/src/vnet/vnet_core.c index 3e4dee3..c8ce677 100644 --- a/palacios/src/vnet/vnet_core.c +++ b/palacios/src/vnet/vnet_core.c @@ -919,7 +919,10 @@ int v3_init_vnet() { } -void v3_deinit_vnet(){ +void v3_deinit_vnet() { + + v3_deinit_queue(vnet_state.poll_devs); + Vnet_Free(vnet_state.poll_devs); PrintDebug("Stopping flush thread\n"); // This will pause until the flush thread is gone