From 66998863586fbc2a43a6decb241e453a8e3bbff3 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 9 Jan 2014 13:45:20 +0100 Subject: [PATCH] changed vma_list order --- include/metalsvm/malloc.h | 6 +- include/metalsvm/vma.h | 5 +- mm/vma.c | 140 ++++++++++++++++++-------------------- 3 files changed, 73 insertions(+), 78 deletions(-) diff --git a/include/metalsvm/malloc.h b/include/metalsvm/malloc.h index 572f3411..feca4998 100644 --- a/include/metalsvm/malloc.h +++ b/include/metalsvm/malloc.h @@ -29,9 +29,9 @@ extern "C" { /// Binary exponent of maximal size for kmalloc() #define BUDDY_MAX 32 // 4 GB /// Binary exponent of minimal buddy size -#define BUDDY_MIN 4 // 16 Byte >= sizeof(buddy_prefix_t) -/// Binary exponent of the size which we allocate at least in one call to buddy_fill(); -#define BUDDY_ALLOC 17 // 128 KByte >= PAGE_SHIFT, TODO: add Huge Page support? +#define BUDDY_MIN 3 // 8 Byte >= sizeof(buddy_t) +/// Binary exponent of the size which we allocate with buddy_fill() +#define BUDDY_ALLOC 15 // 32 KByte >= PAGE_SIZE #define BUDDY_LISTS (BUDDY_MAX-BUDDY_MIN+1) #define BUDDY_MAGIC 0xBABE diff --git a/include/metalsvm/vma.h b/include/metalsvm/vma.h index e6bf8b77..2624d993 100644 --- a/include/metalsvm/vma.h +++ b/include/metalsvm/vma.h @@ -49,10 +49,9 @@ extern "C" { #define VMA_HEAP (VMA_READ|VMA_WRITE|VMA_CACHEABLE) // boundaries for VAS allocation -extern const void kernel_end; -//#define VMA_KERN_MIN (((size_t) &kernel_end + PAGE_SIZE) & PAGE_MASK) +#define VMA_KERN_MIN PAGE_SIZE // we skip the first page #define VMA_KERN_MAX KERNEL_SPACE -#define VMA_USER_MAX (1UL << 47) // TODO +#define VMA_USER_MAX PAGE_MAP_PGT struct vma; diff --git a/mm/vma.c b/mm/vma.c index a4e7622b..b77d49cb 100644 --- a/mm/vma.c +++ b/mm/vma.c @@ -30,7 +30,7 @@ * For bootstrapping we initialize the VMA list with one empty VMA * (start == end) and expand this VMA by calls to vma_alloc() */ -static vma_t vma_boot = { VMA_KERN_MAX, VMA_KERN_MAX, VMA_HEAP }; +static vma_t vma_boot = { VMA_KERN_MIN, VMA_KERN_MIN, VMA_HEAP }; static vma_t* vma_list = &vma_boot; static spinlock_t vma_lock = SPINLOCK_INIT; @@ -39,7 +39,6 @@ size_t vma_alloc(size_t size, uint32_t flags) task_t* task = per_core(current_task); spinlock_t* lock; vma_t** list; - size_t ret = 0; kprintf("vma_alloc(0x%lx, 0x%x)\n", size, flags); @@ -56,7 +55,7 @@ size_t vma_alloc(size_t size, uint32_t flags) lock = &task->vma_lock; } else { - base = 0; + base = VMA_KERN_MIN; limit = VMA_KERN_MAX; list = &vma_list; lock = &vma_lock; @@ -64,9 +63,9 @@ size_t vma_alloc(size_t size, uint32_t flags) spinlock_lock(lock); - // "last" fit search for free memory area - vma_t* pred = *list; // vma before current gap - vma_t* succ = NULL; // vma after current gap + // first fit search for free memory area + vma_t* pred = NULL; // vma before current gap + vma_t* succ = *list; // vma after current gap do { start = (pred) ? pred->end : base; end = (succ) ? succ->start : limit; @@ -74,8 +73,8 @@ size_t vma_alloc(size_t size, uint32_t flags) if (end > start && end - start > size) break; // we found a gap - succ = pred; - pred = (pred) ? pred->prev : NULL; + pred = succ; + succ = (succ) ? succ->next : NULL; } while (pred || succ); if (BUILTIN_EXPECT(end > limit || end < start || end - start < size, 0)) { @@ -83,35 +82,35 @@ size_t vma_alloc(size_t size, uint32_t flags) return 0; } - // resize existing vma - if (succ && succ->flags == flags) { - succ->start -= size; - ret = succ->start; - } - // insert new vma - else { - vma_t* new = kmalloc(sizeof(vma_t)); - if (BUILTIN_EXPECT(!new, 0)) - return 0; - new->start = end-size; - new->end = end; + if (pred && pred->flags == flags) { + pred->end = start+size; + } + else { + // insert new VMA + vma_t* new = kmalloc(sizeof(vma_t)); + if (BUILTIN_EXPECT(!new, 0)) { + spinlock_unlock(lock); + return 0; + } + + new->start = start; + new->end = start+size; new->flags = flags; new->next = succ; new->prev = pred; - if (pred) - pred->next = new; if (succ) succ->prev = new; + if (pred) + pred->next = new; else *list = new; - - ret = new->start; } spinlock_unlock(lock); - return ret; + + return start; } int vma_free(size_t start, size_t end) @@ -124,7 +123,7 @@ int vma_free(size_t start, size_t end) if (BUILTIN_EXPECT(start >= end, 0)) return -EINVAL; - if (end <= VMA_KERN_MAX) { + if (end < VMA_KERN_MAX) { lock = &vma_lock; list = &vma_list; } @@ -132,8 +131,6 @@ int vma_free(size_t start, size_t end) lock = &task->vma_lock; list = &task->vma_list; } - else - return -EINVAL; if (BUILTIN_EXPECT(!*list, 0)) return -EINVAL; @@ -144,7 +141,7 @@ int vma_free(size_t start, size_t end) vma = *list; while (vma) { if (start >= vma->start && end <= vma->end) break; - vma = vma->prev; + vma = vma->next; } if (BUILTIN_EXPECT(!vma, 0)) { @@ -173,13 +170,13 @@ int vma_free(size_t start, size_t end) return -ENOMEM; } - new->start = end; - vma->end = start; - new->end = vma->end; + vma->end = start; + new->start = end; + new->next = vma->next; - new->prev = vma; vma->next = new; + new->prev = vma; } spinlock_unlock(lock); @@ -211,48 +208,45 @@ int vma_add(size_t start, size_t end, uint32_t flags) lock = &vma_lock; // check if address is in kernelspace - if (BUILTIN_EXPECT(end > VMA_KERN_MAX, 0)) + if (BUILTIN_EXPECT(end >= VMA_KERN_MAX, 0)) return -EINVAL; } spinlock_lock(lock); // search gap - vma_t* pred = *list; - vma_t* succ = NULL; - while (pred) { + vma_t* pred = NULL; + vma_t* succ = *list; + do { if ((!pred || pred->end <= start) && (!succ || succ->start >= end)) break; - succ = pred; - pred = pred->prev; + pred = succ; + succ = succ->next; + } while (pred || succ); + + // TODO: check bounds + + // insert new VMA + vma_t* new = kmalloc(sizeof(vma_t)); + if (BUILTIN_EXPECT(!new, 0)) { + spinlock_unlock(lock); + return -ENOMEM; } - // resize existing vma - if (pred && pred->end == start && pred->flags == flags) - pred->end = end; - else if (succ && succ->start == end && succ->flags == flags) - succ->start = start; - // insert new vma - else { - vma_t* new = kmalloc(sizeof(vma_t)); - if (BUILTIN_EXPECT(!new, 0)) - return 0; + new->start = start; + new->end = end; + new->flags = flags; + new->next = succ; + new->prev = pred; - new->start = start; - new->end = end; - new->flags = flags; - new->next = succ; - new->prev = pred; - - if (pred) - pred->next = new; - if (succ) - succ->prev = new; - else - *list = new; - } + if (succ) + succ->prev = new; + if (pred) + pred->next = new; + else + *list = new; spinlock_unlock(lock); @@ -267,15 +261,15 @@ int copy_vma_list(task_t* task) spinlock_lock(&parent_task->vma_lock); spinlock_lock(&task->vma_lock); - int ret = 0; vma_t* last = NULL; vma_t* parent = parent_task->vma_list; while (parent) { vma_t *new = kmalloc(sizeof(vma_t)); if (BUILTIN_EXPECT(!new, 0)) { - ret = -ENOMEM; - goto out; + spinlock_unlock(&task->vma_lock); + spinlock_unlock(&parent_task->vma_lock); + return -ENOMEM; } new->start = parent->start; @@ -292,20 +286,22 @@ int copy_vma_list(task_t* task) parent = parent->next; } -out: - spinlock_unlock(&task->vma_lock); - spinlock_unlock(&parent_task->vma_lock); - return ret; + return 0; } int drop_vma_list() { task_t* task = per_core(current_task); + vma_t* vma; + + kprintf("drop_vma_list: task = %u\n", task->id); // TODO: remove spinlock_lock(&task->vma_lock); - while(task->vma_list) - pfree((void*) task->vma_list->start, task->vma_list->end - task->vma_list->start); + while (vma = task->vma_list) { + task->vma_list = vma->next; + kfree(vma); + } spinlock_unlock(&task->vma_lock); @@ -320,7 +316,7 @@ void vma_dump() (vma->flags & VMA_READ) ? 'r' : '-', (vma->flags & VMA_WRITE) ? 'w' : '-', (vma->flags & VMA_EXECUTE) ? 'x' : '-'); - vma = vma->prev; + vma = vma->next; } }