changed vma_list order
This commit is contained in:
parent
ab67350783
commit
6699886358
3 changed files with 73 additions and 78 deletions
|
@ -29,9 +29,9 @@ extern "C" {
|
||||||
/// Binary exponent of maximal size for kmalloc()
|
/// Binary exponent of maximal size for kmalloc()
|
||||||
#define BUDDY_MAX 32 // 4 GB
|
#define BUDDY_MAX 32 // 4 GB
|
||||||
/// Binary exponent of minimal buddy size
|
/// Binary exponent of minimal buddy size
|
||||||
#define BUDDY_MIN 4 // 16 Byte >= sizeof(buddy_prefix_t)
|
#define BUDDY_MIN 3 // 8 Byte >= sizeof(buddy_t)
|
||||||
/// Binary exponent of the size which we allocate at least in one call to buddy_fill();
|
/// Binary exponent of the size which we allocate with buddy_fill()
|
||||||
#define BUDDY_ALLOC 17 // 128 KByte >= PAGE_SHIFT, TODO: add Huge Page support?
|
#define BUDDY_ALLOC 15 // 32 KByte >= PAGE_SIZE
|
||||||
|
|
||||||
#define BUDDY_LISTS (BUDDY_MAX-BUDDY_MIN+1)
|
#define BUDDY_LISTS (BUDDY_MAX-BUDDY_MIN+1)
|
||||||
#define BUDDY_MAGIC 0xBABE
|
#define BUDDY_MAGIC 0xBABE
|
||||||
|
|
|
@ -49,10 +49,9 @@ extern "C" {
|
||||||
#define VMA_HEAP (VMA_READ|VMA_WRITE|VMA_CACHEABLE)
|
#define VMA_HEAP (VMA_READ|VMA_WRITE|VMA_CACHEABLE)
|
||||||
|
|
||||||
// boundaries for VAS allocation
|
// boundaries for VAS allocation
|
||||||
extern const void kernel_end;
|
#define VMA_KERN_MIN PAGE_SIZE // we skip the first page
|
||||||
//#define VMA_KERN_MIN (((size_t) &kernel_end + PAGE_SIZE) & PAGE_MASK)
|
|
||||||
#define VMA_KERN_MAX KERNEL_SPACE
|
#define VMA_KERN_MAX KERNEL_SPACE
|
||||||
#define VMA_USER_MAX (1UL << 47) // TODO
|
#define VMA_USER_MAX PAGE_MAP_PGT
|
||||||
|
|
||||||
struct vma;
|
struct vma;
|
||||||
|
|
||||||
|
|
120
mm/vma.c
120
mm/vma.c
|
@ -30,7 +30,7 @@
|
||||||
* For bootstrapping we initialize the VMA list with one empty VMA
|
* For bootstrapping we initialize the VMA list with one empty VMA
|
||||||
* (start == end) and expand this VMA by calls to vma_alloc()
|
* (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 vma_t* vma_list = &vma_boot;
|
||||||
static spinlock_t vma_lock = SPINLOCK_INIT;
|
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);
|
task_t* task = per_core(current_task);
|
||||||
spinlock_t* lock;
|
spinlock_t* lock;
|
||||||
vma_t** list;
|
vma_t** list;
|
||||||
size_t ret = 0;
|
|
||||||
|
|
||||||
kprintf("vma_alloc(0x%lx, 0x%x)\n", size, flags);
|
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;
|
lock = &task->vma_lock;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
base = 0;
|
base = VMA_KERN_MIN;
|
||||||
limit = VMA_KERN_MAX;
|
limit = VMA_KERN_MAX;
|
||||||
list = &vma_list;
|
list = &vma_list;
|
||||||
lock = &vma_lock;
|
lock = &vma_lock;
|
||||||
|
@ -64,9 +63,9 @@ size_t vma_alloc(size_t size, uint32_t flags)
|
||||||
|
|
||||||
spinlock_lock(lock);
|
spinlock_lock(lock);
|
||||||
|
|
||||||
// "last" fit search for free memory area
|
// first fit search for free memory area
|
||||||
vma_t* pred = *list; // vma before current gap
|
vma_t* pred = NULL; // vma before current gap
|
||||||
vma_t* succ = NULL; // vma after current gap
|
vma_t* succ = *list; // vma after current gap
|
||||||
do {
|
do {
|
||||||
start = (pred) ? pred->end : base;
|
start = (pred) ? pred->end : base;
|
||||||
end = (succ) ? succ->start : limit;
|
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)
|
if (end > start && end - start > size)
|
||||||
break; // we found a gap
|
break; // we found a gap
|
||||||
|
|
||||||
succ = pred;
|
pred = succ;
|
||||||
pred = (pred) ? pred->prev : NULL;
|
succ = (succ) ? succ->next : NULL;
|
||||||
} while (pred || succ);
|
} while (pred || succ);
|
||||||
|
|
||||||
if (BUILTIN_EXPECT(end > limit || end < start || end - start < size, 0)) {
|
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;
|
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;
|
if (pred && pred->flags == flags) {
|
||||||
new->end = end;
|
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->flags = flags;
|
||||||
new->next = succ;
|
new->next = succ;
|
||||||
new->prev = pred;
|
new->prev = pred;
|
||||||
|
|
||||||
if (pred)
|
|
||||||
pred->next = new;
|
|
||||||
if (succ)
|
if (succ)
|
||||||
succ->prev = new;
|
succ->prev = new;
|
||||||
|
if (pred)
|
||||||
|
pred->next = new;
|
||||||
else
|
else
|
||||||
*list = new;
|
*list = new;
|
||||||
|
|
||||||
ret = new->start;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spinlock_unlock(lock);
|
spinlock_unlock(lock);
|
||||||
return ret;
|
|
||||||
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vma_free(size_t start, size_t end)
|
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))
|
if (BUILTIN_EXPECT(start >= end, 0))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (end <= VMA_KERN_MAX) {
|
if (end < VMA_KERN_MAX) {
|
||||||
lock = &vma_lock;
|
lock = &vma_lock;
|
||||||
list = &vma_list;
|
list = &vma_list;
|
||||||
}
|
}
|
||||||
|
@ -132,8 +131,6 @@ int vma_free(size_t start, size_t end)
|
||||||
lock = &task->vma_lock;
|
lock = &task->vma_lock;
|
||||||
list = &task->vma_list;
|
list = &task->vma_list;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (BUILTIN_EXPECT(!*list, 0))
|
if (BUILTIN_EXPECT(!*list, 0))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -144,7 +141,7 @@ int vma_free(size_t start, size_t end)
|
||||||
vma = *list;
|
vma = *list;
|
||||||
while (vma) {
|
while (vma) {
|
||||||
if (start >= vma->start && end <= vma->end) break;
|
if (start >= vma->start && end <= vma->end) break;
|
||||||
vma = vma->prev;
|
vma = vma->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BUILTIN_EXPECT(!vma, 0)) {
|
if (BUILTIN_EXPECT(!vma, 0)) {
|
||||||
|
@ -173,13 +170,13 @@ int vma_free(size_t start, size_t end)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
new->start = end;
|
|
||||||
vma->end = start;
|
|
||||||
|
|
||||||
new->end = vma->end;
|
new->end = vma->end;
|
||||||
|
vma->end = start;
|
||||||
|
new->start = end;
|
||||||
|
|
||||||
new->next = vma->next;
|
new->next = vma->next;
|
||||||
new->prev = vma;
|
|
||||||
vma->next = new;
|
vma->next = new;
|
||||||
|
new->prev = vma;
|
||||||
}
|
}
|
||||||
|
|
||||||
spinlock_unlock(lock);
|
spinlock_unlock(lock);
|
||||||
|
@ -211,34 +208,32 @@ int vma_add(size_t start, size_t end, uint32_t flags)
|
||||||
lock = &vma_lock;
|
lock = &vma_lock;
|
||||||
|
|
||||||
// check if address is in kernelspace
|
// check if address is in kernelspace
|
||||||
if (BUILTIN_EXPECT(end > VMA_KERN_MAX, 0))
|
if (BUILTIN_EXPECT(end >= VMA_KERN_MAX, 0))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
spinlock_lock(lock);
|
spinlock_lock(lock);
|
||||||
|
|
||||||
// search gap
|
// search gap
|
||||||
vma_t* pred = *list;
|
vma_t* pred = NULL;
|
||||||
vma_t* succ = NULL;
|
vma_t* succ = *list;
|
||||||
while (pred) {
|
do {
|
||||||
if ((!pred || pred->end <= start) &&
|
if ((!pred || pred->end <= start) &&
|
||||||
(!succ || succ->start >= end))
|
(!succ || succ->start >= end))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
succ = pred;
|
pred = succ;
|
||||||
pred = pred->prev;
|
succ = succ->next;
|
||||||
}
|
} while (pred || succ);
|
||||||
|
|
||||||
// resize existing vma
|
// TODO: check bounds
|
||||||
if (pred && pred->end == start && pred->flags == flags)
|
|
||||||
pred->end = end;
|
// insert new VMA
|
||||||
else if (succ && succ->start == end && succ->flags == flags)
|
|
||||||
succ->start = start;
|
|
||||||
// insert new vma
|
|
||||||
else {
|
|
||||||
vma_t* new = kmalloc(sizeof(vma_t));
|
vma_t* new = kmalloc(sizeof(vma_t));
|
||||||
if (BUILTIN_EXPECT(!new, 0))
|
if (BUILTIN_EXPECT(!new, 0)) {
|
||||||
return 0;
|
spinlock_unlock(lock);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
new->start = start;
|
new->start = start;
|
||||||
new->end = end;
|
new->end = end;
|
||||||
|
@ -246,13 +241,12 @@ int vma_add(size_t start, size_t end, uint32_t flags)
|
||||||
new->next = succ;
|
new->next = succ;
|
||||||
new->prev = pred;
|
new->prev = pred;
|
||||||
|
|
||||||
if (pred)
|
|
||||||
pred->next = new;
|
|
||||||
if (succ)
|
if (succ)
|
||||||
succ->prev = new;
|
succ->prev = new;
|
||||||
|
if (pred)
|
||||||
|
pred->next = new;
|
||||||
else
|
else
|
||||||
*list = new;
|
*list = new;
|
||||||
}
|
|
||||||
|
|
||||||
spinlock_unlock(lock);
|
spinlock_unlock(lock);
|
||||||
|
|
||||||
|
@ -267,15 +261,15 @@ int copy_vma_list(task_t* task)
|
||||||
spinlock_lock(&parent_task->vma_lock);
|
spinlock_lock(&parent_task->vma_lock);
|
||||||
spinlock_lock(&task->vma_lock);
|
spinlock_lock(&task->vma_lock);
|
||||||
|
|
||||||
int ret = 0;
|
|
||||||
vma_t* last = NULL;
|
vma_t* last = NULL;
|
||||||
vma_t* parent = parent_task->vma_list;
|
vma_t* parent = parent_task->vma_list;
|
||||||
|
|
||||||
while (parent) {
|
while (parent) {
|
||||||
vma_t *new = kmalloc(sizeof(vma_t));
|
vma_t *new = kmalloc(sizeof(vma_t));
|
||||||
if (BUILTIN_EXPECT(!new, 0)) {
|
if (BUILTIN_EXPECT(!new, 0)) {
|
||||||
ret = -ENOMEM;
|
spinlock_unlock(&task->vma_lock);
|
||||||
goto out;
|
spinlock_unlock(&parent_task->vma_lock);
|
||||||
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
new->start = parent->start;
|
new->start = parent->start;
|
||||||
|
@ -292,20 +286,22 @@ int copy_vma_list(task_t* task)
|
||||||
parent = parent->next;
|
parent = parent->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
return 0;
|
||||||
spinlock_unlock(&task->vma_lock);
|
|
||||||
spinlock_unlock(&parent_task->vma_lock);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int drop_vma_list()
|
int drop_vma_list()
|
||||||
{
|
{
|
||||||
task_t* task = per_core(current_task);
|
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);
|
spinlock_lock(&task->vma_lock);
|
||||||
|
|
||||||
while(task->vma_list)
|
while (vma = task->vma_list) {
|
||||||
pfree((void*) task->vma_list->start, task->vma_list->end - task->vma_list->start);
|
task->vma_list = vma->next;
|
||||||
|
kfree(vma);
|
||||||
|
}
|
||||||
|
|
||||||
spinlock_unlock(&task->vma_lock);
|
spinlock_unlock(&task->vma_lock);
|
||||||
|
|
||||||
|
@ -320,7 +316,7 @@ void vma_dump()
|
||||||
(vma->flags & VMA_READ) ? 'r' : '-',
|
(vma->flags & VMA_READ) ? 'r' : '-',
|
||||||
(vma->flags & VMA_WRITE) ? 'w' : '-',
|
(vma->flags & VMA_WRITE) ? 'w' : '-',
|
||||||
(vma->flags & VMA_EXECUTE) ? 'x' : '-');
|
(vma->flags & VMA_EXECUTE) ? 'x' : '-');
|
||||||
vma = vma->prev;
|
vma = vma->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue