修复内存管理问题
This commit is contained in:
6
.vscode/launch.json
vendored
6
.vscode/launch.json
vendored
@@ -46,9 +46,9 @@
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
// "miDebuggerPath": "/opt/homebrew/bin/arm-none-eabi-gdb",
|
||||
// "miDebuggerPath": "/home/zhangzheng/gcc-arm-10.3-2021.07-aarch64-aarch64-none-elf/bin/aarch64-none-elf-gdb",
|
||||
"miDebuggerPath": "/home/mkrtos-smart/toolchains/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/aarch64-none-elf-gdb",
|
||||
"miDebuggerServerAddress": "127.0.0.1:33333",
|
||||
"miDebuggerPath": "/home/zhangzheng/gcc-arm-10.3-2021.07-aarch64-aarch64-none-elf/bin/aarch64-none-elf-gdb",
|
||||
// "miDebuggerPath": "/home/mkrtos-smart/toolchains/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/aarch64-none-elf-gdb",
|
||||
"miDebuggerServerAddress": "127.0.0.1:3333",
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <util.h>
|
||||
#include <vma.h>
|
||||
|
||||
#define VMA_DEBUG 0
|
||||
|
||||
static slab_t *vma_slab;
|
||||
static int vma_idl_tree_insert_cmp_handler(const void *key, const void *data);
|
||||
/**
|
||||
@@ -29,7 +31,8 @@ static vma_t *vma_alloc(void)
|
||||
{
|
||||
vma_t *pvma = slab_alloc(vma_slab);
|
||||
|
||||
if (!pvma) {
|
||||
if (!pvma)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
memset(pvma, 0, sizeof(*pvma));
|
||||
@@ -44,7 +47,8 @@ static mln_rbtree_node_t *vma_node_create(mln_rbtree_t *r_tree, vma_addr_t addr,
|
||||
mln_rbtree_node_t *node = NULL;
|
||||
vma_t *data_vma = vma_alloc();
|
||||
|
||||
if (data_vma == NULL) {
|
||||
if (data_vma == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -54,7 +58,8 @@ static mln_rbtree_node_t *vma_node_create(mln_rbtree_t *r_tree, vma_addr_t addr,
|
||||
|
||||
node = mln_rbtree_node_new(r_tree, data_vma);
|
||||
|
||||
if (mln_rbtree_null(node, r_tree)) {
|
||||
if (mln_rbtree_null(node, r_tree))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -83,7 +88,8 @@ int task_vma_init(task_vma_t *vma)
|
||||
|
||||
void task_vma_rbtree_print(mln_rbtree_t *t, mln_rbtree_node_t *root)
|
||||
{
|
||||
if (root == &(t->nil)) {
|
||||
if (root == &(t->nil))
|
||||
{
|
||||
return;
|
||||
}
|
||||
vma_t *data = mln_rbtree_node_data_get(root);
|
||||
@@ -100,14 +106,16 @@ static mln_rbtree_node_t *task_vma_tree_find(mln_rbtree_t *tree, rbtree_cmp cmp,
|
||||
|
||||
tree->cmp = cmp;
|
||||
rn = mln_rbtree_search(tree, &data);
|
||||
if (mln_rbtree_null(rn, tree)) {
|
||||
if (mln_rbtree_null(rn, tree))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return rn;
|
||||
}
|
||||
|
||||
typedef struct vma_idl_tree_insert_params {
|
||||
typedef struct vma_idl_tree_insert_params
|
||||
{
|
||||
vaddr_t addr;
|
||||
size_t size;
|
||||
} vma_idl_tree_insert_params_t;
|
||||
@@ -122,12 +130,17 @@ static int vma_idl_tree_insert_cmp_handler(const void *key, const void *data)
|
||||
vma_t *key_p = (vma_t *)key;
|
||||
vma_t *data_p = (vma_t *)data;
|
||||
|
||||
if (vma_addr_get_addr(key_p->vaddr) + key_p->size <= vma_addr_get_addr(data_p->vaddr)) {
|
||||
if (vma_addr_get_addr(key_p->vaddr) + key_p->size <= vma_addr_get_addr(data_p->vaddr))
|
||||
{
|
||||
return -1;
|
||||
} else if (vma_addr_get_addr(key_p->vaddr) >= vma_addr_get_addr(data_p->vaddr) &&
|
||||
(vma_addr_get_addr(key_p->vaddr) + key_p->size) <= vma_addr_get_addr(data_p->vaddr) + data_p->size) {
|
||||
}
|
||||
else if (vma_addr_get_addr(key_p->vaddr) >= vma_addr_get_addr(data_p->vaddr) &&
|
||||
(vma_addr_get_addr(key_p->vaddr) + key_p->size) <= vma_addr_get_addr(data_p->vaddr) + data_p->size)
|
||||
{
|
||||
return 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -142,12 +155,17 @@ static int vma_idl_tree_wrap_cmp_handler(const void *key, const void *data)
|
||||
vma_idl_tree_insert_params_t *key_p = (vma_idl_tree_insert_params_t *)key;
|
||||
vma_t *data_p = (vma_t *)data;
|
||||
|
||||
if (key_p->addr + key_p->size <= vma_addr_get_addr(data_p->vaddr)) {
|
||||
if (key_p->addr + key_p->size <= vma_addr_get_addr(data_p->vaddr))
|
||||
{
|
||||
return -1;
|
||||
} else if (key_p->addr >= vma_addr_get_addr(data_p->vaddr) &&
|
||||
(key_p->addr + key_p->size) <= vma_addr_get_addr(data_p->vaddr) + data_p->size) {
|
||||
}
|
||||
else if (key_p->addr >= vma_addr_get_addr(data_p->vaddr) &&
|
||||
(key_p->addr + key_p->size) <= vma_addr_get_addr(data_p->vaddr) + data_p->size)
|
||||
{
|
||||
return 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -162,16 +180,22 @@ static int vma_idl_tree_alloc_cmp_handler(const void *key, const void *data)
|
||||
vma_idl_tree_insert_params_t *key_p = (vma_idl_tree_insert_params_t *)key;
|
||||
vma_t *data_p = (vma_t *)data;
|
||||
|
||||
if (key_p->addr + key_p->size <= vma_addr_get_addr(data_p->vaddr)) {
|
||||
if (key_p->addr + key_p->size <= vma_addr_get_addr(data_p->vaddr))
|
||||
{
|
||||
return -1;
|
||||
} else if (key_p->addr >= vma_addr_get_addr(data_p->vaddr) &&
|
||||
(key_p->addr + key_p->size) <= vma_addr_get_addr(data_p->vaddr) + data_p->size) {
|
||||
}
|
||||
else if (key_p->addr >= vma_addr_get_addr(data_p->vaddr) &&
|
||||
(key_p->addr + key_p->size) <= vma_addr_get_addr(data_p->vaddr) + data_p->size)
|
||||
{
|
||||
return 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
typedef struct vma_idl_tree_iter_params {
|
||||
typedef struct vma_idl_tree_iter_params
|
||||
{
|
||||
// vaddr_t addr;
|
||||
size_t size;
|
||||
|
||||
@@ -189,8 +213,10 @@ static int rbtree_iterate_idle_tree_find(mln_rbtree_node_t *node, void *udata)
|
||||
vma_idl_tree_iter_params_t *param = udata;
|
||||
vma_t *node_data = mln_rbtree_node_data_get(node);
|
||||
|
||||
if (!(vma_node_get_used(node_data))) {
|
||||
if (node_data->size >= param->size) {
|
||||
if (!(vma_node_get_used(node_data)))
|
||||
{
|
||||
if (node_data->size >= param->size)
|
||||
{
|
||||
param->ret_node = node;
|
||||
return -1;
|
||||
}
|
||||
@@ -213,7 +239,8 @@ static mln_rbtree_node_t *task_vma_idle_tree_find(task_vma_t *task_vma, size_t s
|
||||
int ret;
|
||||
|
||||
ret = mln_rbtree_iterate(&task_vma->idle_tree, rbtree_iterate_idle_tree_find, ¶m);
|
||||
if (ret >= 0) {
|
||||
if (ret >= 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return param.ret_node;
|
||||
@@ -240,9 +267,12 @@ static int task_vma_node_split(mln_rbtree_t *r_tree, mln_rbtree_node_t *node, va
|
||||
addr + size <= vma_addr_get_addr(data->vaddr) + data->size);
|
||||
//!< 检查地址在合理的范围之内
|
||||
|
||||
if (addr == vma_addr_get_addr(data->vaddr) && size == data->size) {
|
||||
if (addr == vma_addr_get_addr(data->vaddr) && size == data->size)
|
||||
{
|
||||
/*大小正好相等,则什么都不用做*/
|
||||
} else if (addr == vma_addr_get_addr(data->vaddr)) {
|
||||
}
|
||||
else if (addr == vma_addr_get_addr(data->vaddr))
|
||||
{
|
||||
//!< 左对齐
|
||||
mln_rbtree_node_t *r_node;
|
||||
|
||||
@@ -250,13 +280,16 @@ static int task_vma_node_split(mln_rbtree_t *r_tree, mln_rbtree_node_t *node, va
|
||||
vma_addr_create(data->vaddr.prot, data->vaddr.flags,
|
||||
vma_addr_get_addr(data->vaddr) + size),
|
||||
data->size - size, 0);
|
||||
if (r_node == NULL) {
|
||||
if (r_node == NULL)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto err_ret;
|
||||
}
|
||||
r_tree->cmp = vma_idl_tree_insert_cmp_handler;
|
||||
mln_rbtree_insert(r_tree, r_node);
|
||||
} else if (addr + size == vma_addr_get_addr(data->vaddr) + data->size) {
|
||||
}
|
||||
else if (addr + size == vma_addr_get_addr(data->vaddr) + data->size)
|
||||
{
|
||||
//!< 右对齐
|
||||
mln_rbtree_node_t *r_node;
|
||||
|
||||
@@ -264,13 +297,16 @@ static int task_vma_node_split(mln_rbtree_t *r_tree, mln_rbtree_node_t *node, va
|
||||
vma_addr_create(data->vaddr.prot, data->vaddr.flags,
|
||||
vma_addr_get_addr(data->vaddr)),
|
||||
data->size - size, 0);
|
||||
if (r_node == NULL) {
|
||||
if (r_node == NULL)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto err_ret;
|
||||
}
|
||||
r_tree->cmp = vma_idl_tree_insert_cmp_handler;
|
||||
mln_rbtree_insert(r_tree, r_node);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// 在中间分割成两个
|
||||
mln_rbtree_node_t *r_node;
|
||||
|
||||
@@ -278,7 +314,8 @@ static int task_vma_node_split(mln_rbtree_t *r_tree, mln_rbtree_node_t *node, va
|
||||
vma_addr_create(data->vaddr.prot, data->vaddr.flags,
|
||||
vma_addr_get_addr(data->vaddr)),
|
||||
addr - vma_addr_get_addr(data->vaddr), 0);
|
||||
if (r_node == NULL) {
|
||||
if (r_node == NULL)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto err_ret;
|
||||
}
|
||||
@@ -289,7 +326,8 @@ static int task_vma_node_split(mln_rbtree_t *r_tree, mln_rbtree_node_t *node, va
|
||||
vma_addr_create(data->vaddr.prot, data->vaddr.flags,
|
||||
addr + size),
|
||||
vma_addr_get_addr(data->vaddr) + data->size - (addr + size), 0);
|
||||
if (l_node == NULL) {
|
||||
if (l_node == NULL)
|
||||
{
|
||||
vma_node_free(r_tree, r_node);
|
||||
ret = -ENOMEM;
|
||||
goto err_ret;
|
||||
@@ -318,7 +356,8 @@ mword_t task_vma_lock(task_vma_t *task_vma)
|
||||
task = container_of(container_of(task_vma, mm_space_t, mem_vma), task_t, mm_space);
|
||||
|
||||
ret = spinlock_lock(&task->kobj.lock);
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
@@ -338,7 +377,8 @@ mword_t task_vma_lock_two(task_vma_t *task_vma_0, task_vma_t *task_vma_1, mword_
|
||||
assert(status1);
|
||||
|
||||
status = task_vma_lock(task_vma_0);
|
||||
if (status < 0) {
|
||||
if (status < 0)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
*status0 = status;
|
||||
@@ -366,25 +406,32 @@ int task_vma_alloc(task_vma_t *task_vma, vma_addr_t vaddr, size_t size,
|
||||
mword_t lock_status;
|
||||
vaddr_t alloc_addr;
|
||||
|
||||
if ((size & (PAGE_SIZE - 1)) != 0) {
|
||||
if ((size & (PAGE_SIZE - 1)) != 0)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
lock_status = task_vma_lock(task_vma);
|
||||
if (lock_status < 0) {
|
||||
if (lock_status < 0)
|
||||
{
|
||||
return lock_status;
|
||||
}
|
||||
#if VMA_DEBUG
|
||||
printk("alloc pre:\n");
|
||||
task_vma_rbtree_print(&task_vma->idle_tree, mln_rbtree_root(&task_vma->idle_tree));
|
||||
|
||||
if (vma_addr_get_addr(vaddr) == 0) {
|
||||
#endif
|
||||
if (vma_addr_get_addr(vaddr) == 0)
|
||||
{
|
||||
node = task_vma_idle_tree_find(task_vma, size);
|
||||
if (!node) {
|
||||
if (!node)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
node_data = mln_rbtree_node_data_get(node);
|
||||
alloc_addr = vma_addr_get_addr(node_data->vaddr);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
alloc_addr = vma_addr_get_addr(vaddr);
|
||||
|
||||
task_vma->idle_tree.cmp = vma_idl_tree_alloc_cmp_handler;
|
||||
@@ -394,11 +441,13 @@ int task_vma_alloc(task_vma_t *task_vma, vma_addr_t vaddr, size_t size,
|
||||
.size = size,
|
||||
.addr = alloc_addr,
|
||||
}); //!< 查找是否存在
|
||||
if (mln_rbtree_null(node, &task_vma->idle_tree)) {
|
||||
if (mln_rbtree_null(node, &task_vma->idle_tree))
|
||||
{
|
||||
ret = -ENOENT;
|
||||
goto end;
|
||||
}
|
||||
if (vma_node_get_used(mln_rbtree_node_data_get(node))) {
|
||||
if (vma_node_get_used(mln_rbtree_node_data_get(node)))
|
||||
{
|
||||
ret = -EEXIST;
|
||||
goto end;
|
||||
}
|
||||
@@ -407,7 +456,8 @@ int task_vma_alloc(task_vma_t *task_vma, vma_addr_t vaddr, size_t size,
|
||||
|
||||
ret = task_vma_node_split(&task_vma->idle_tree, node,
|
||||
alloc_addr, size);
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
//!< 设置当前节点是使用节点,设置属性等,并插入到树中
|
||||
@@ -418,12 +468,15 @@ int task_vma_alloc(task_vma_t *task_vma, vma_addr_t vaddr, size_t size,
|
||||
task_vma->idle_tree.cmp = vma_idl_tree_insert_cmp_handler;
|
||||
mln_rbtree_insert(&task_vma->idle_tree, node);
|
||||
|
||||
if (ret_vaddr) {
|
||||
if (ret_vaddr)
|
||||
{
|
||||
//!< 设置分配后的地址
|
||||
*ret_vaddr = alloc_addr;
|
||||
}
|
||||
printk("alloc:[0x%x 0x%x] size:0x%x\n", alloc_addr, alloc_addr + size - 1, size);
|
||||
#if VMA_DEBUG
|
||||
task_vma_rbtree_print(&task_vma->idle_tree, mln_rbtree_root(&task_vma->idle_tree));
|
||||
#endif
|
||||
ret = 0;
|
||||
end:
|
||||
task_vma_unlock(task_vma, lock_status);
|
||||
@@ -441,16 +494,22 @@ static int vma_idl_tree_eq_cmp_handler(const void *key, const void *data)
|
||||
vma_idl_tree_insert_params_t *key_p = (vma_idl_tree_insert_params_t *)key;
|
||||
vma_t *data_p = (vma_t *)data;
|
||||
|
||||
if (key_p->addr + key_p->size <= vma_addr_get_addr(data_p->vaddr)) {
|
||||
if (key_p->addr + key_p->size <= vma_addr_get_addr(data_p->vaddr))
|
||||
{
|
||||
return -1;
|
||||
} else if (key_p->addr == vma_addr_get_addr(data_p->vaddr) &&
|
||||
(key_p->addr + key_p->size) == vma_addr_get_addr(data_p->vaddr) + data_p->size) {
|
||||
}
|
||||
else if (key_p->addr == vma_addr_get_addr(data_p->vaddr) &&
|
||||
(key_p->addr + key_p->size) == vma_addr_get_addr(data_p->vaddr) + data_p->size)
|
||||
{
|
||||
return 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
typedef struct vma_idl_tree_iter_grant_params {
|
||||
typedef struct vma_idl_tree_iter_grant_params
|
||||
{
|
||||
vaddr_t addr;
|
||||
vaddr_t dst_addr;
|
||||
size_t size;
|
||||
@@ -476,7 +535,8 @@ static int rbtree_iterate_tree_grant(mln_rbtree_node_t *node, void *udata)
|
||||
// printk("[grant][0x%lx 0x%lx] [0x%lx:0x%lx]\n", vma_addr_get_addr(node_data->vaddr), vma_addr_get_addr(node_data->vaddr) + node_data->size,
|
||||
// param->addr, param->size);
|
||||
if (vma_addr_get_addr(node_data->vaddr) >= param->addr &&
|
||||
vma_addr_get_addr(node_data->vaddr) + node_data->size <= param->addr + param->size) {
|
||||
vma_addr_get_addr(node_data->vaddr) + node_data->size <= param->addr + param->size)
|
||||
{
|
||||
mm_space_t *src_mm_space = container_of(param->src_mm_vma, mm_space_t, mem_vma);
|
||||
mm_space_t *dst_mm_space = container_of(param->dst_mm_vma, mm_space_t, mem_vma);
|
||||
|
||||
@@ -494,7 +554,8 @@ static int rbtree_iterate_tree_grant(mln_rbtree_node_t *node, void *udata)
|
||||
(addr_t)vma_node_get_paddr(node_data), PAGE_SHIFT, 1,
|
||||
vpage_attrs_to_page_attrs(vma_addr_get_prot(node_data->vaddr)));
|
||||
|
||||
if (ret >= 0) {
|
||||
if (ret >= 0)
|
||||
{
|
||||
param->grant_size += PAGE_SIZE;
|
||||
}
|
||||
// printk("vaddr:0x%x grant vaddr:0x%x 0x%x\n", vma_addr_get_addr(node_data->vaddr), dst_addr, PAGE_SIZE);
|
||||
@@ -521,7 +582,8 @@ int task_vma_grant(task_vma_t *src_task_vma, task_vma_t *dst_task_vma, vaddr_t s
|
||||
{
|
||||
assert(src_task_vma);
|
||||
assert(dst_task_vma);
|
||||
if ((size & (PAGE_SIZE - 1)) != 0) {
|
||||
if ((size & (PAGE_SIZE - 1)) != 0)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
mword_t lock_status;
|
||||
@@ -530,7 +592,8 @@ int task_vma_grant(task_vma_t *src_task_vma, task_vma_t *dst_task_vma, vaddr_t s
|
||||
int ret = -EINVAL;
|
||||
|
||||
lock_status = task_vma_lock_two(src_task_vma, dst_task_vma, &lock_status0, &lock_status1);
|
||||
if (lock_status < 0) {
|
||||
if (lock_status < 0)
|
||||
{
|
||||
return lock_status;
|
||||
}
|
||||
mln_rbtree_node_t *src_node;
|
||||
@@ -544,11 +607,13 @@ int task_vma_grant(task_vma_t *src_task_vma, task_vma_t *dst_task_vma, vaddr_t s
|
||||
.size = size,
|
||||
.addr = src_addr,
|
||||
}); //!< 查找是否存在
|
||||
if (mln_rbtree_null(src_node, &src_task_vma->idle_tree)) {
|
||||
if (mln_rbtree_null(src_node, &src_task_vma->idle_tree))
|
||||
{
|
||||
ret = -ENOENT;
|
||||
goto end;
|
||||
}
|
||||
if (!vma_node_get_used(mln_rbtree_node_data_get(src_node))) {
|
||||
if (!vma_node_get_used(mln_rbtree_node_data_get(src_node)))
|
||||
{
|
||||
ret = -ENOENT;
|
||||
goto end;
|
||||
}
|
||||
@@ -560,18 +625,23 @@ int task_vma_grant(task_vma_t *src_task_vma, task_vma_t *dst_task_vma, vaddr_t s
|
||||
.size = size,
|
||||
.addr = dst_addr,
|
||||
}); //!< 查找是否存在
|
||||
if (mln_rbtree_null(dst_node, &dst_task_vma->idle_tree)) {
|
||||
if (mln_rbtree_null(dst_node, &dst_task_vma->idle_tree))
|
||||
{
|
||||
ret = -EEXIST;
|
||||
goto end;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
vma_t *dst_node_dat = mln_rbtree_node_data_get(dst_node);
|
||||
|
||||
if (vma_node_get_used(dst_node_dat)) {
|
||||
if (vma_node_get_used(dst_node_dat))
|
||||
{
|
||||
ret = -EEXIST;
|
||||
goto end;
|
||||
}
|
||||
ret = task_vma_node_split(&dst_task_vma->idle_tree, dst_node, dst_addr, size);
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
vma_node_free(&dst_task_vma->idle_tree, dst_node);
|
||||
@@ -597,13 +667,50 @@ int task_vma_grant(task_vma_t *src_task_vma, task_vma_t *dst_task_vma, vaddr_t s
|
||||
dst_addr);
|
||||
mln_rbtree_insert(&dst_task_vma->idle_tree, src_node);
|
||||
ret = params.grant_size;
|
||||
#if VMA_DEBUG
|
||||
printk("grant:\n");
|
||||
task_vma_rbtree_print(&dst_task_vma->idle_tree, mln_rbtree_root(&dst_task_vma->idle_tree));
|
||||
#endif
|
||||
end:
|
||||
task_vma_unlock_two(src_task_vma, dst_task_vma, lock_status0, lock_status1);
|
||||
return ret;
|
||||
}
|
||||
static int rbtree_cmp_merge_r(const void *key, const void *data)
|
||||
{
|
||||
vma_idl_tree_insert_params_t *key_p = (vma_idl_tree_insert_params_t *)key;
|
||||
vma_t *data_p = (vma_t *)data;
|
||||
|
||||
if (key_p->addr == vma_addr_get_addr(data_p->vaddr) + data_p->size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (key_p->addr + key_p->size < vma_addr_get_addr(data_p->vaddr))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
static int rbtree_cmp_merge_l(const void *key, const void *data)
|
||||
{
|
||||
vma_idl_tree_insert_params_t *key_p = (vma_idl_tree_insert_params_t *)key;
|
||||
vma_t *data_p = (vma_t *)data;
|
||||
|
||||
if (key_p->addr == vma_addr_get_addr(data_p->vaddr))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (key_p->addr < vma_addr_get_addr(data_p->vaddr))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief 合并节点TODO:合并时属性不一致也不能合并
|
||||
*
|
||||
@@ -622,12 +729,28 @@ static int vma_node_merge(mln_rbtree_t *r_tree, mln_rbtree_node_t *node)
|
||||
vma_t *l_datanode;
|
||||
vma_t *data_node;
|
||||
|
||||
rnode = node->right;
|
||||
lnode = node->left;
|
||||
// rnode = node->right;
|
||||
// lnode = node->left;
|
||||
data_node = mln_rbtree_node_data_get(node);
|
||||
|
||||
r_tree->cmp = rbtree_cmp_merge_r;
|
||||
lnode = mln_rbtree_search(
|
||||
r_tree,
|
||||
&(vma_idl_tree_insert_params_t){
|
||||
.size = data_node->size,
|
||||
.addr = vma_addr_get_addr(data_node->vaddr),
|
||||
}); //!< 查找是否存在
|
||||
|
||||
r_tree->cmp = rbtree_cmp_merge_l;
|
||||
rnode = mln_rbtree_search(
|
||||
r_tree,
|
||||
&(vma_idl_tree_insert_params_t){
|
||||
.size = 0,
|
||||
.addr = vma_addr_get_addr(data_node->vaddr) + data_node->size,
|
||||
}); //!< 查找是否存在
|
||||
|
||||
r_tree->cmp = vma_idl_tree_insert_cmp_handler;
|
||||
|
||||
data_node = mln_rbtree_node_data_get(node);
|
||||
vma_node_set_unused(data_node);
|
||||
|
||||
int l_dmerge = !!mln_rbtree_null(lnode, r_tree) || ((!mln_rbtree_null(lnode, r_tree)) && (vma_node_get_used(((vma_t *)mln_rbtree_node_data_get(lnode))) !=
|
||||
@@ -642,11 +765,14 @@ static int vma_node_merge(mln_rbtree_t *r_tree, mln_rbtree_node_t *node)
|
||||
vma_addr_get_prot(data_node->vaddr)) ||
|
||||
(vma_addr_get_flags(((vma_t *)mln_rbtree_node_data_get(rnode))->vaddr) !=
|
||||
vma_addr_get_flags(data_node->vaddr)))));
|
||||
if (l_dmerge && r_dmerge) {
|
||||
if (l_dmerge && r_dmerge)
|
||||
{
|
||||
// 左右都是空的
|
||||
vma_node_set_unused(data_node);
|
||||
return 0;
|
||||
} else if (l_dmerge && !r_dmerge) { // 左边是空的
|
||||
}
|
||||
else if (l_dmerge && !r_dmerge)
|
||||
{ // 左边是空的
|
||||
mln_rbtree_delete(r_tree, node);
|
||||
|
||||
r_datanode = mln_rbtree_node_data_get(rnode);
|
||||
@@ -656,7 +782,9 @@ static int vma_node_merge(mln_rbtree_t *r_tree, mln_rbtree_node_t *node)
|
||||
vma_node_free(r_tree, rnode);
|
||||
|
||||
mln_rbtree_insert(r_tree, node);
|
||||
} else if (!l_dmerge && r_dmerge) { // 右边是空的
|
||||
}
|
||||
else if (!l_dmerge && r_dmerge)
|
||||
{ // 右边是空的
|
||||
mln_rbtree_delete(r_tree, node);
|
||||
|
||||
l_datanode = mln_rbtree_node_data_get(lnode);
|
||||
@@ -665,7 +793,9 @@ static int vma_node_merge(mln_rbtree_t *r_tree, mln_rbtree_node_t *node)
|
||||
l_datanode->size += data_node->size;
|
||||
mln_rbtree_insert(r_tree, lnode);
|
||||
vma_node_free(r_tree, node);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mln_rbtree_delete(r_tree, node);
|
||||
r_datanode = mln_rbtree_node_data_get(rnode);
|
||||
l_datanode = mln_rbtree_node_data_get(lnode);
|
||||
@@ -682,7 +812,8 @@ static int vma_node_merge(mln_rbtree_t *r_tree, mln_rbtree_node_t *node)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
typedef struct vma_idl_tree_iter_del_params {
|
||||
typedef struct vma_idl_tree_iter_del_params
|
||||
{
|
||||
vaddr_t addr;
|
||||
size_t size;
|
||||
mln_rbtree_t *r_tree;
|
||||
@@ -701,7 +832,8 @@ static int rbtree_iterate_alloc_tree_del(mln_rbtree_node_t *node, void *udata)
|
||||
vma_t *node_data = mln_rbtree_node_data_get(node);
|
||||
|
||||
if (vma_addr_get_addr(node_data->vaddr) >= param->addr &&
|
||||
vma_addr_get_addr(node_data->vaddr) + node_data->size <= param->addr + param->size) {
|
||||
vma_addr_get_addr(node_data->vaddr) + node_data->size <= param->addr + param->size)
|
||||
{
|
||||
// 解除映射
|
||||
unmap_mm(mm_space_get_pdir(param->mm_space),
|
||||
vma_addr_get_addr(node_data->vaddr), PAGE_SHIFT, 1);
|
||||
@@ -730,13 +862,19 @@ int task_vma_free(task_vma_t *task_vma, vaddr_t addr, size_t size)
|
||||
mword_t lock_status;
|
||||
|
||||
assert(task_vma);
|
||||
if ((size & (PAGE_SIZE - 1)) != 0) {
|
||||
if ((size & (PAGE_SIZE - 1)) != 0)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
lock_status = task_vma_lock(task_vma);
|
||||
if (lock_status < 0) {
|
||||
if (lock_status < 0)
|
||||
{
|
||||
return lock_status;
|
||||
}
|
||||
#if VMA_DEBUG
|
||||
printk("free pre:\n");
|
||||
task_vma_rbtree_print(&task_vma->idle_tree, mln_rbtree_root(&task_vma->idle_tree));
|
||||
#endif
|
||||
task_vma->idle_tree.cmp = vma_idl_tree_eq_cmp_handler;
|
||||
find_node = mln_rbtree_search(
|
||||
&task_vma->idle_tree,
|
||||
@@ -744,12 +882,13 @@ int task_vma_free(task_vma_t *task_vma, vaddr_t addr, size_t size)
|
||||
.size = size,
|
||||
.addr = addr,
|
||||
}); //!< 查找是否存在
|
||||
if (mln_rbtree_null(find_node, &task_vma->idle_tree)) {
|
||||
if (mln_rbtree_null(find_node, &task_vma->idle_tree))
|
||||
{
|
||||
ret = -ENOENT;
|
||||
goto end;
|
||||
}
|
||||
node_data = mln_rbtree_node_data_get(find_node);
|
||||
if (!(node_data->flags & VMA_USED_NODE)) //!< 必须被分配的
|
||||
if (!vma_node_get_used(node_data)) //!< 必须被分配的
|
||||
{
|
||||
ret = -ENOENT;
|
||||
goto end;
|
||||
@@ -764,8 +903,10 @@ int task_vma_free(task_vma_t *task_vma, vaddr_t addr, size_t size)
|
||||
mln_rbtree_iterate(&task_vma->alloc_tree, rbtree_iterate_alloc_tree_del, ¶m);
|
||||
vma_node_merge(&task_vma->idle_tree, find_node);
|
||||
ret = 0;
|
||||
#if VMA_DEBUG
|
||||
printk("free:\n");
|
||||
task_vma_rbtree_print(&task_vma->idle_tree, mln_rbtree_root(&task_vma->idle_tree));
|
||||
#endif
|
||||
end:
|
||||
task_vma_unlock(task_vma, lock_status);
|
||||
return ret;
|
||||
@@ -791,7 +932,8 @@ int task_vma_page_fault(task_vma_t *task_vma, vaddr_t addr)
|
||||
|
||||
assert(task_vma);
|
||||
lock_status = task_vma_lock(task_vma);
|
||||
if (lock_status < 0) {
|
||||
if (lock_status < 0)
|
||||
{
|
||||
return lock_status;
|
||||
}
|
||||
// printk("page fault:0x%x.\n", addr);
|
||||
@@ -804,7 +946,8 @@ int task_vma_page_fault(task_vma_t *task_vma, vaddr_t addr)
|
||||
.size = PAGE_SIZE,
|
||||
.addr = addr,
|
||||
}); //!< 查找是否存在
|
||||
if (mln_rbtree_null(find_node, &task_vma->idle_tree)) {
|
||||
if (mln_rbtree_null(find_node, &task_vma->idle_tree))
|
||||
{
|
||||
ret = -ENOENT;
|
||||
goto end;
|
||||
}
|
||||
@@ -815,18 +958,25 @@ int task_vma_page_fault(task_vma_t *task_vma, vaddr_t addr)
|
||||
goto end;
|
||||
}
|
||||
// 2.申请物理内存
|
||||
if (vma_addr_get_flags(node_data->vaddr) & VMA_ADDR_RESV) {
|
||||
if (!vma_node_get_paddr(node_data)) {
|
||||
if (vma_addr_get_flags(node_data->vaddr) & VMA_ADDR_RESV)
|
||||
{
|
||||
if (!vma_node_get_paddr(node_data))
|
||||
{
|
||||
mem = NULL;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mem = (void *)(addr - vma_addr_get_addr(node_data->vaddr) +
|
||||
vma_node_get_paddr(node_data));
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mem = buddy_alloc(buddy_get_alloter(), PAGE_SIZE);
|
||||
memset(mem, 0, PAGE_SIZE);
|
||||
}
|
||||
if (!mem) {
|
||||
if (!mem)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
@@ -837,8 +987,10 @@ int task_vma_page_fault(task_vma_t *task_vma, vaddr_t addr)
|
||||
vma_addr_create(vma_addr_get_prot(node_data->vaddr),
|
||||
vma_addr_get_flags(node_data->vaddr), addr),
|
||||
PAGE_SIZE, (paddr_t)mem);
|
||||
if (alloc_node == NULL) {
|
||||
if (!(vma_addr_get_flags(node_data->vaddr) & VMA_ADDR_RESV)) {
|
||||
if (alloc_node == NULL)
|
||||
{
|
||||
if (!(vma_addr_get_flags(node_data->vaddr) & VMA_ADDR_RESV))
|
||||
{
|
||||
buddy_free(buddy_get_alloter(), mem);
|
||||
}
|
||||
ret = -ENOMEM;
|
||||
@@ -848,7 +1000,8 @@ int task_vma_page_fault(task_vma_t *task_vma, vaddr_t addr)
|
||||
ret = map_mm(mm_space_get_pdir(&task->mm_space), addr,
|
||||
(addr_t)mem, PAGE_SHIFT, 1,
|
||||
vpage_attrs_to_page_attrs(vma_addr_get_prot(node_data->vaddr)));
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
{
|
||||
vma_node_free(&task_vma->alloc_tree, alloc_node);
|
||||
ret = -ENOMEM;
|
||||
goto end;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# export TOOLCHAIN=/home/zhangzheng/gcc-arm-10.3-2021.07-aarch64-aarch64-none-elf/bin/
|
||||
# export TOOLCHAIN_LIB=/home/zhangzheng/gcc-arm-10.3-2021.07-aarch64-aarch64-none-elf/lib/gcc/aarch64-none-elf/10.3.1
|
||||
export TOOLCHAIN=/home/mkrtos-smart/toolchains/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/
|
||||
export TOOLCHAIN_LIB=/home/mkrtos-smart/toolchains/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/lib/gcc/aarch64-none-elf/10.3.1
|
||||
export TOOLCHAIN=/home/zhangzheng/gcc-arm-10.3-2021.07-aarch64-aarch64-none-elf/bin/
|
||||
export TOOLCHAIN_LIB=/home/zhangzheng/gcc-arm-10.3-2021.07-aarch64-aarch64-none-elf/lib/gcc/aarch64-none-elf/10.3.1
|
||||
# export TOOLCHAIN=/home/mkrtos-smart/toolchains/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/
|
||||
# export TOOLCHAIN_LIB=/home/mkrtos-smart/toolchains/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/lib/gcc/aarch64-none-elf/10.3.1
|
||||
|
||||
export BOARD=aarch64_qemu
|
||||
export CROSS_COMPILE_NAME=aarch64-none-elf-
|
||||
|
||||
Reference in New Issue
Block a user