From fb78a71020a768d6615c8b10802f53bcc2c37c85 Mon Sep 17 00:00:00 2001 From: Shell Date: Wed, 25 Oct 2023 14:59:48 +0800 Subject: [smart] replace varea pgmgr and fixup of dfs mmap (#8184) Signed-off-by: shell Signed-off-by: Shell --- components/dfs/dfs_v2/src/dfs_file_mmap.c | 43 ++++----- components/lwp/lwp.h | 1 - components/lwp/lwp_syscall.c | 1 - components/lwp/lwp_user_mm.c | 120 ++----------------------- components/mm/mm_anon.c | 75 +++++++++++----- components/mm/mm_aspace.c | 12 ++- components/mm/mm_aspace.h | 1 - components/mm/mm_object.c | 143 ++++-------------------------- components/mm/mm_page.c | 1 - components/mm/mm_page.h | 1 - components/mm/mm_private.h | 2 - 11 files changed, 102 insertions(+), 298 deletions(-) (limited to 'components') diff --git a/components/dfs/dfs_v2/src/dfs_file_mmap.c b/components/dfs/dfs_v2/src/dfs_file_mmap.c index fe34593f4c..b7754f8909 100644 --- a/components/dfs/dfs_v2/src/dfs_file_mmap.c +++ b/components/dfs/dfs_v2/src/dfs_file_mmap.c @@ -35,10 +35,10 @@ static rt_mem_obj_t dfs_get_mem_obj(struct dfs_file *file); static void *dfs_mem_obj_get_file(rt_mem_obj_t mem_obj); -static rt_varea_t _dfs_map_user_varea_data(struct rt_lwp *lwp, void *map_vaddr, size_t map_size, size_t attr, mm_flag_t flags, off_t pgoffset, void *data) +static void *_do_mmap(struct rt_lwp *lwp, void *map_vaddr, size_t map_size, size_t attr, + mm_flag_t flags, off_t pgoffset, void *data, rt_err_t *code) { int ret = 0; - rt_varea_t varea; void *vaddr = map_vaddr; rt_mem_obj_t mem_obj = dfs_get_mem_obj(data); @@ -46,25 +46,21 @@ static rt_varea_t _dfs_map_user_varea_data(struct rt_lwp *lwp, void *map_vaddr, attr, flags, mem_obj, pgoffset); if (ret != RT_EOK) { - varea = RT_NULL; - } - else - { - varea = rt_aspace_query(lwp->aspace, vaddr); + vaddr = RT_NULL; + LOG_E("failed to map %lx with size %lx with errno %d", map_vaddr, + map_size, ret); } - if (ret != RT_EOK) + if (code) { - LOG_E("failed to map %lx with size %lx with errno %d", map_vaddr, - map_size, ret); + *code = ret; } - return varea; + return vaddr; } -static rt_varea_t dfs_map_user_varea_data(struct dfs_mmap2_args *mmap2, void *data) +static void *_map_data_to_uspace(struct dfs_mmap2_args *mmap2, void *data, rt_err_t *code) { - rt_varea_t varea = RT_NULL; size_t offset = 0; void *map_vaddr = mmap2->addr; size_t map_size = mmap2->length; @@ -82,10 +78,10 @@ static rt_varea_t dfs_map_user_varea_data(struct dfs_mmap2_args *mmap2, void *da k_flags = lwp_user_mm_flag_to_kernel(mmap2->flags); k_attr = lwp_user_mm_attr_to_kernel(mmap2->prot); - varea = _dfs_map_user_varea_data(lwp, map_vaddr, map_size, k_attr, k_flags, mmap2->pgoffset, data); + map_vaddr = _do_mmap(lwp, map_vaddr, map_size, k_attr, k_flags, mmap2->pgoffset, data, code); } - return varea; + return map_vaddr; } static void hint_free(rt_mm_va_hint_t hint) @@ -405,7 +401,8 @@ static void *dfs_mem_obj_get_file(rt_mem_obj_t mem_obj) int dfs_file_mmap(struct dfs_file *file, struct dfs_mmap2_args *mmap2) { - int ret = -EINVAL; + rt_err_t ret = -EINVAL; + void *map_vaddr; LOG_I("mmap2 args addr: %p length: 0x%x prot: %d flags: 0x%x pgoffset: 0x%x", mmap2->addr, mmap2->length, mmap2->prot, mmap2->flags, mmap2->pgoffset); @@ -414,19 +411,11 @@ int dfs_file_mmap(struct dfs_file *file, struct dfs_mmap2_args *mmap2) if (file->vnode->aspace) { /* create a va area in user space (lwp) */ - rt_varea_t varea = dfs_map_user_varea_data(mmap2, file); - if (varea) + map_vaddr = _map_data_to_uspace(mmap2, file, &ret); + if (map_vaddr) { - mmap2->ret = varea->start; - LOG_I("%s varea: %p", __func__, varea); - LOG_I("varea start: %p size: 0x%x offset: 0x%x attr: 0x%x flag: 0x%x", - varea->start, varea->size, varea->offset, varea->attr, varea->flag); + mmap2->ret = map_vaddr; LOG_I("file: %s%s", file->dentry->mnt->fullpath, file->dentry->pathname); - ret = RT_EOK; - } - else - { - ret = -ENOMEM; } } else diff --git a/components/lwp/lwp.h b/components/lwp/lwp.h index 56298a0385..2d1e381647 100644 --- a/components/lwp/lwp.h +++ b/components/lwp/lwp.h @@ -80,7 +80,6 @@ struct rt_lwp #ifdef ARCH_MM_MMU size_t end_heap; rt_aspace_t aspace; - struct rt_lwp_objs *lwp_obj; #else #ifdef ARCH_MM_MPU struct rt_mpu_info mpu_info; diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index 6bdb786355..daa4e00480 100644 --- a/components/lwp/lwp_syscall.c +++ b/components/lwp/lwp_syscall.c @@ -2780,7 +2780,6 @@ sysret_t sys_execve(const char *path, char *const argv[], char *const envp[]) #ifdef ARCH_MM_MMU _swap_lwp_data(lwp, new_lwp, struct rt_aspace *, aspace); - _swap_lwp_data(lwp, new_lwp, struct rt_lwp_objs *, lwp_obj); _swap_lwp_data(lwp, new_lwp, size_t, end_heap); #endif diff --git a/components/lwp/lwp_user_mm.c b/components/lwp/lwp_user_mm.c index eb8b59dd75..eb58c76f39 100644 --- a/components/lwp/lwp_user_mm.c +++ b/components/lwp/lwp_user_mm.c @@ -47,8 +47,6 @@ #define STACK_OBJ _null_object -static void _init_lwp_objs(struct rt_lwp_objs *lwp_objs, rt_aspace_t aspace); - static const char *_null_get_name(rt_varea_t varea) { return "null"; @@ -123,20 +121,15 @@ int lwp_user_space_init(struct rt_lwp *lwp, rt_bool_t is_fork) int err = -RT_ENOMEM; const size_t flags = MMF_MAP_PRIVATE; - lwp->lwp_obj = rt_malloc(sizeof(struct rt_lwp_objs)); - if (lwp->lwp_obj) + err = arch_user_space_init(lwp); + if (err == RT_EOK) { - err = arch_user_space_init(lwp); - if (err == RT_EOK) + if (!is_fork) { - _init_lwp_objs(lwp->lwp_obj, lwp->aspace); - if (!is_fork) - { - stk_addr = (void *)USER_STACK_VSTART; - err = rt_aspace_map(lwp->aspace, &stk_addr, - USER_STACK_VEND - USER_STACK_VSTART, - MMU_MAP_U_RWCB, flags, &STACK_OBJ, 0); - } + stk_addr = (void *)USER_STACK_VSTART; + err = rt_aspace_map(lwp->aspace, &stk_addr, + USER_STACK_VEND - USER_STACK_VSTART, + MMU_MAP_U_RWCB, flags, &STACK_OBJ, 0); } } @@ -167,107 +160,8 @@ void lwp_aspace_switch(struct rt_thread *thread) void lwp_unmap_user_space(struct rt_lwp *lwp) { arch_user_space_free(lwp); - rt_free(lwp->lwp_obj); -} - -static const char *_user_get_name(rt_varea_t varea) -{ - char *name; - if (varea->flag & MMF_TEXT) - { - name = "user.text"; - } - else - { - if (varea->start == (void *)USER_STACK_VSTART) - { - name = "user.stack"; - } - else if (varea->start >= (void *)USER_HEAP_VADDR && - varea->start < (void *)USER_HEAP_VEND) - { - name = "user.heap"; - } - else - { - name = "user.data"; - } - } - return name; -} - -#define NO_AUTO_FETCH 0x1 -#define VAREA_CAN_AUTO_FETCH(varea) (!((rt_ubase_t)((varea)->data) & NO_AUTO_FETCH)) - -static void _user_do_page_fault(struct rt_varea *varea, - struct rt_aspace_fault_msg *msg) -{ - struct rt_lwp_objs *lwp_objs; - lwp_objs = rt_container_of(varea->mem_obj, struct rt_lwp_objs, mem_obj); - - if (lwp_objs->source) - { - char *paddr = rt_hw_mmu_v2p(lwp_objs->source, msg->fault_vaddr); - if (paddr != ARCH_MAP_FAILED) - { - void *vaddr; - vaddr = paddr - PV_OFFSET; - - if (!(varea->flag & MMF_TEXT)) - { - void *cp = rt_pages_alloc_ext(0, PAGE_ANY_AVAILABLE); - if (cp) - { - memcpy(cp, vaddr, ARCH_PAGE_SIZE); - rt_varea_pgmgr_insert(varea, cp); - msg->response.status = MM_FAULT_STATUS_OK; - msg->response.vaddr = cp; - msg->response.size = ARCH_PAGE_SIZE; - } - else - { - LOG_W("%s: page alloc failed at %p", __func__, - varea->start); - } - } - else - { - rt_page_t page = rt_page_addr2page(vaddr); - page->ref_cnt += 1; - rt_varea_pgmgr_insert(varea, vaddr); - msg->response.status = MM_FAULT_STATUS_OK; - msg->response.vaddr = vaddr; - msg->response.size = ARCH_PAGE_SIZE; - } - } - else if (!(varea->flag & MMF_TEXT)) - { - /* if data segment not exist in source do a fallback */ - rt_mm_dummy_mapper.on_page_fault(varea, msg); - } - } - else if (VAREA_CAN_AUTO_FETCH(varea)) - { - /* if (!lwp_objs->source), no aspace as source data */ - rt_mm_dummy_mapper.on_page_fault(varea, msg); - } } -static void _init_lwp_objs(struct rt_lwp_objs *lwp_objs, rt_aspace_t aspace) -{ - if (lwp_objs) - { - /** - * @brief one lwp_obj represent an base layout of page based memory in user space - * This is useful on duplication. Where we only have a (lwp_objs and offset) to - * provide identical memory. This is implemented by lwp_objs->source. - */ - lwp_objs->source = NULL; - memcpy(&lwp_objs->mem_obj, &rt_mm_dummy_mapper, sizeof(struct rt_mem_obj)); - lwp_objs->mem_obj.get_name = _user_get_name; - lwp_objs->mem_obj.on_page_fault = _user_do_page_fault; - } -} static void *_lwp_map_user(struct rt_lwp *lwp, void *map_va, size_t map_size, int text) diff --git a/components/mm/mm_anon.c b/components/mm/mm_anon.c index e14300a08f..9cfe072bb1 100644 --- a/components/mm/mm_anon.c +++ b/components/mm/mm_anon.c @@ -127,6 +127,7 @@ static void _anon_varea_open(struct rt_varea *varea) static void _anon_varea_close(struct rt_varea *varea) { rt_aspace_anon_ref_dec(varea->mem_obj); + rt_mm_dummy_mapper.on_varea_close(varea); } static rt_err_t _anon_varea_expand(struct rt_varea *varea, void *new_vaddr, rt_size_t size) @@ -154,14 +155,14 @@ static rt_err_t _anon_varea_merge(struct rt_varea *merge_to, struct rt_varea *me rt_inline void _map_page_in_varea(rt_aspace_t asapce, rt_varea_t varea, struct rt_aspace_fault_msg *msg, char *fault_addr) { - if (rt_varea_map_page(varea, fault_addr, msg->response.vaddr) == RT_EOK) + char *page_va = msg->response.vaddr; + if (rt_varea_map_page(varea, fault_addr, page_va) == RT_EOK) { msg->response.status = MM_FAULT_STATUS_OK_MAPPED; + rt_varea_pgmgr_insert(varea, page_va); } else { - /* revoke the allocated page */ - rt_varea_pgmgr_pop(varea, msg->response.vaddr, ARCH_PAGE_SIZE); msg->response.status = MM_FAULT_STATUS_UNRECOVERABLE; LOG_W("%s: failed to map page into varea", __func__); } @@ -201,6 +202,7 @@ static void *_get_page_from_backup(rt_aspace_t backup, rt_base_t offset_in_mobj) { rc = msg.response.vaddr; } + rt_pages_free(msg.response.vaddr, 0); } } else @@ -221,28 +223,33 @@ static void *_get_page_from_backup(rt_aspace_t backup, rt_base_t offset_in_mobj) } /* get the backup page in kernel for the address in user space */ -static void _anon_page_fault(struct rt_varea *varea, struct rt_aspace_fault_msg *msg) +static void _fetch_page_for_varea(struct rt_varea *varea, struct rt_aspace_fault_msg *msg, rt_bool_t need_map) { void *paddr; char *frame_ka; - rt_aspace_t from_aspace = varea->aspace; + rt_aspace_t curr_aspace = varea->aspace; rt_aspace_t backup = _anon_obj_get_backup(varea->mem_obj); - RDWR_LOCK(from_aspace); + RDWR_LOCK(curr_aspace); /** * if the page is already mapped(this may caused by data race while other * thread success to take the lock and mapped the page before this), return okay */ - paddr = rt_hw_mmu_v2p(from_aspace, msg->fault_vaddr); + paddr = rt_hw_mmu_v2p(curr_aspace, msg->fault_vaddr); if (paddr == ARCH_MAP_FAILED) { - if (backup == from_aspace) + if (backup == curr_aspace) { rt_mm_dummy_mapper.on_page_fault(varea, msg); if (msg->response.status != MM_FAULT_STATUS_UNRECOVERABLE) { + /* if backup == curr_aspace, a page fetch always binding with a pte filling */ _map_page_in_varea(backup, varea, msg, msg->fault_vaddr); + if (msg->response.status != MM_FAULT_STATUS_UNRECOVERABLE) + { + rt_pages_free(msg->response.vaddr, 0); + } } } else @@ -252,7 +259,14 @@ static void _anon_page_fault(struct rt_varea *varea, struct rt_aspace_fault_msg { msg->response.vaddr = frame_ka; msg->response.size = ARCH_PAGE_SIZE; - _map_page_in_varea(from_aspace, varea, msg, msg->fault_vaddr); + if (!need_map) + { + msg->response.status = MM_FAULT_STATUS_OK; + } + else + { + _map_page_in_varea(curr_aspace, varea, msg, msg->fault_vaddr); + } } } } @@ -260,7 +274,12 @@ static void _anon_page_fault(struct rt_varea *varea, struct rt_aspace_fault_msg { msg->response.status = MM_FAULT_STATUS_OK_MAPPED; } - RDWR_UNLOCK(from_aspace); + RDWR_UNLOCK(curr_aspace); +} + +static void _anon_page_fault(struct rt_varea *varea, struct rt_aspace_fault_msg *msg) +{ + _fetch_page_for_varea(varea, msg, RT_TRUE); } static void read_by_mte(rt_aspace_t aspace, struct rt_aspace_io_msg *iomsg) @@ -271,9 +290,10 @@ static void read_by_mte(rt_aspace_t aspace, struct rt_aspace_io_msg *iomsg) static void _anon_page_read(struct rt_varea *varea, struct rt_aspace_io_msg *iomsg) { - rt_aspace_t from_aspace = varea->aspace; + rt_aspace_t curr_aspace = varea->aspace; + rt_aspace_t backup = _anon_obj_get_backup(varea->mem_obj); - if (rt_hw_mmu_v2p(from_aspace, iomsg->fault_vaddr) == ARCH_MAP_FAILED) + if (rt_hw_mmu_v2p(curr_aspace, iomsg->fault_vaddr) == ARCH_MAP_FAILED) { struct rt_aspace_fault_msg msg; msg.fault_op = MM_FAULT_OP_READ; @@ -282,15 +302,18 @@ static void _anon_page_read(struct rt_varea *varea, struct rt_aspace_io_msg *iom msg.off = iomsg->off; rt_mm_fault_res_init(&msg.response); - _anon_page_fault(varea, &msg); + _fetch_page_for_varea(varea, &msg, RT_FALSE); if (msg.response.status != MM_FAULT_STATUS_UNRECOVERABLE) { - read_by_mte(from_aspace, iomsg); + void *saved_fault_va = iomsg->fault_vaddr; + iomsg->fault_vaddr = (void *)(iomsg->off << MM_PAGE_SHIFT); + read_by_mte(backup, iomsg); + iomsg->fault_vaddr = saved_fault_va; } } else { - read_by_mte(from_aspace, iomsg); + read_by_mte(curr_aspace, iomsg); } } @@ -303,8 +326,14 @@ static void write_by_mte(rt_aspace_t aspace, struct rt_aspace_io_msg *iomsg) static void _anon_page_write(struct rt_varea *varea, struct rt_aspace_io_msg *iomsg) { rt_aspace_t from_aspace = varea->aspace; + rt_aspace_t backup = _anon_obj_get_backup(varea->mem_obj); - if (rt_hw_mmu_v2p(from_aspace, iomsg->fault_vaddr) == ARCH_MAP_FAILED) + if (from_aspace != backup) + { + /* varea in guest aspace cannot modify the page */ + iomsg->response.status = MM_FAULT_STATUS_UNRECOVERABLE; + } + else if (rt_hw_mmu_v2p(from_aspace, iomsg->fault_vaddr) == ARCH_MAP_FAILED) { struct rt_aspace_fault_msg msg; msg.fault_op = MM_FAULT_OP_WRITE; @@ -313,15 +342,20 @@ static void _anon_page_write(struct rt_varea *varea, struct rt_aspace_io_msg *io msg.off = iomsg->off; rt_mm_fault_res_init(&msg.response); - _anon_page_fault(varea, &msg); - if (msg.response.status != MM_FAULT_STATUS_UNRECOVERABLE) + _fetch_page_for_varea(varea, &msg, RT_TRUE); + if (msg.response.status == MM_FAULT_STATUS_OK_MAPPED) + { + write_by_mte(backup, iomsg); + } + else { - write_by_mte(from_aspace, iomsg); + /* mapping failed, report an error */ + iomsg->response.status = MM_FAULT_STATUS_UNRECOVERABLE; } } else { - write_by_mte(from_aspace, iomsg); + write_by_mte(backup, iomsg); } } @@ -413,6 +447,7 @@ static int _override_map(rt_varea_t varea, rt_aspace_t aspace, void *fault_vaddr RT_ASSERT(rt_hw_mmu_v2p(aspace, msg->fault_vaddr) == (page + PV_OFFSET)); rc = MM_FAULT_FIXABLE_TRUE; rt_varea_pgmgr_insert(map_varea, page); + rt_pages_free(page, 0); } else { diff --git a/components/mm/mm_aspace.c b/components/mm/mm_aspace.c index 42278e684f..76a50a67b1 100644 --- a/components/mm/mm_aspace.c +++ b/components/mm/mm_aspace.c @@ -495,7 +495,6 @@ static inline void _varea_post_install(rt_varea_t varea, rt_aspace_t aspace, varea->mem_obj = mem_obj; varea->flag = flags; varea->offset = offset; - varea->frames = NULL; if (varea->mem_obj && varea->mem_obj->on_varea_open) varea->mem_obj->on_varea_open(varea); @@ -565,11 +564,11 @@ void _varea_uninstall_locked(rt_varea_t varea) if (varea->mem_obj && varea->mem_obj->on_varea_close) varea->mem_obj->on_varea_close(varea); - - rt_hw_mmu_unmap(aspace, varea->start, varea->size); - rt_hw_tlb_invalidate_range(aspace, varea->start, varea->size, ARCH_PAGE_SIZE); - - rt_varea_pgmgr_pop_all(varea); + else + { + rt_hw_mmu_unmap(aspace, varea->start, varea->size); + rt_hw_tlb_invalidate_range(aspace, varea->start, varea->size, ARCH_PAGE_SIZE); + } _aspace_bst_remove(aspace, varea); } @@ -960,7 +959,6 @@ static rt_err_t _split_varea(rt_varea_t existed, char *ex_end, char *unmap_start subset->mem_obj = existed->mem_obj; subset->flag = existed->flag & ~MMF_STATIC_ALLOC; subset->offset = existed->offset + rela_offset; - subset->frames = NULL; error = existed->mem_obj->on_varea_split(existed, unmap_start, unmap_len, subset); if (error == RT_EOK) diff --git a/components/mm/mm_aspace.h b/components/mm/mm_aspace.h index 5748647903..08be2e2b21 100644 --- a/components/mm/mm_aspace.h +++ b/components/mm/mm_aspace.h @@ -76,7 +76,6 @@ typedef struct rt_varea struct _aspace_node node; - struct rt_page *frames; void *data; } *rt_varea_t; diff --git a/components/mm/mm_object.c b/components/mm/mm_object.c index f26b3173f5..fdd435b74e 100644 --- a/components/mm/mm_object.c +++ b/components/mm/mm_object.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2022, RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -7,6 +7,7 @@ * Date Author Notes * 2022-11-30 WangXiaoyao the first version * 2023-08-19 Shell Support varea modification handler + * 2023-10-13 Shell Replace the page management algorithm of pgmgr */ #define DBG_TAG "mm.object" @@ -30,79 +31,28 @@ static const char *get_name(rt_varea_t varea) return "dummy-mapper"; } -static rt_bool_t _varea_pgmgr_frame_is_member(rt_varea_t varea, rt_page_t frame) -{ - rt_page_t iter; - rt_bool_t rc = RT_FALSE; - - if (varea->frames) - { - iter = varea->frames; - do - { - if (iter == frame) - { - rc = RT_TRUE; - break; - } - iter = iter->next; - } while (iter); - } - - return rc; -} - void rt_varea_pgmgr_insert(rt_varea_t varea, void *page_addr) { - rt_page_t page = rt_page_addr2page(page_addr); - - if (varea->frames == NULL) - { - varea->frames = page; - page->pre = RT_NULL; - page->next = RT_NULL; - } - else - { - page->pre = RT_NULL; - varea->frames->pre = page; - page->next = varea->frames; - varea->frames = page; - } + /* each mapping of page frame in the varea is binding with a reference */ + rt_page_ref_inc(page_addr, 0); } +/* resource recycling of page frames */ void rt_varea_pgmgr_pop_all(rt_varea_t varea) { - rt_page_t page = varea->frames; + rt_aspace_t aspace = varea->aspace; + char *end_addr = varea->start + varea->size; + RT_ASSERT(!((long)end_addr & ARCH_PAGE_MASK)); - while (page) + for (char *iter = varea->start; iter != end_addr; iter += ARCH_PAGE_SIZE) { - rt_page_t next = page->next; - void *pg_va = rt_page_page2addr(page); - rt_pages_free(pg_va, 0); - page = next; - } - - varea->frames = RT_NULL; -} - -void rt_varea_pgmgr_pop(rt_varea_t varea, void *vaddr, rt_size_t size) -{ - void *vend = (char *)vaddr + size; - while (vaddr != vend) - { - rt_page_t page = rt_page_addr2page(vaddr); - if (_varea_pgmgr_frame_is_member(varea, page)) + void *page_pa = rt_hw_mmu_v2p(aspace, iter); + char *page_va = rt_kmem_p2v(page_pa); + if (page_pa != ARCH_MAP_FAILED && page_va) { - if (page->pre) - page->pre->next = page->next; - if (page->next) - page->next->pre = page->pre; - if (varea->frames == page) - varea->frames = page->next; - rt_pages_free(vaddr, 0); + rt_hw_mmu_unmap(aspace, iter, ARCH_PAGE_SIZE); + rt_pages_free(page_va, 0); } - vaddr = (char *)vaddr + ARCH_PAGE_SIZE; } } @@ -120,8 +70,6 @@ static void on_page_fault(struct rt_varea *varea, struct rt_aspace_fault_msg *ms msg->response.status = MM_FAULT_STATUS_OK; msg->response.size = ARCH_PAGE_SIZE; msg->response.vaddr = page; - - rt_varea_pgmgr_insert(varea, page); } static void on_varea_open(struct rt_varea *varea) @@ -131,6 +79,8 @@ static void on_varea_open(struct rt_varea *varea) static void on_varea_close(struct rt_varea *varea) { + /* unmap and dereference page frames in the varea region */ + rt_varea_pgmgr_pop_all(varea); } static rt_err_t on_varea_expand(struct rt_varea *varea, void *new_vaddr, rt_size_t size) @@ -153,7 +103,7 @@ static void _remove_pages(rt_varea_t varea, void *rm_start, void *rm_end) page_va -= PV_OFFSET; LOG_D("%s: free page %p", __func__, page_va); rt_varea_unmap_page(varea, rm_start); - rt_varea_pgmgr_pop(varea, page_va, ARCH_PAGE_SIZE); + rt_pages_free(page_va, 0); } rm_start += ARCH_PAGE_SIZE; } @@ -183,70 +133,15 @@ static rt_err_t on_varea_shrink(rt_varea_t varea, void *new_start, rt_size_t siz static rt_err_t on_varea_split(struct rt_varea *existed, void *unmap_start, rt_size_t unmap_len, struct rt_varea *subset) { - void *sub_start = subset->start; - void *sub_end = sub_start + subset->size; - void *page_va; - + /* remove the resource in the unmap region, and do nothing for the subset */ _remove_pages(existed, unmap_start, (char *)unmap_start + unmap_len); - RT_ASSERT(!((rt_ubase_t)sub_start & ARCH_PAGE_MASK)); - RT_ASSERT(!((rt_ubase_t)sub_end & ARCH_PAGE_MASK)); - while (sub_start != sub_end) - { - page_va = rt_hw_mmu_v2p(existed->aspace, sub_start); - - if (page_va != ARCH_MAP_FAILED) - { - rt_page_t frame; - page_va = rt_kmem_p2v(page_va); - if (page_va) - { - frame = rt_page_addr2page(page_va); - if (frame && _varea_pgmgr_frame_is_member(existed, frame)) - { - LOG_D("%s: free page %p", __func__, page_va); - rt_page_ref_inc(page_va, 0); - rt_varea_pgmgr_pop(existed, page_va, ARCH_PAGE_SIZE); - rt_varea_pgmgr_insert(subset, page_va); - } - } - } - sub_start += ARCH_PAGE_SIZE; - } - return RT_EOK; } static rt_err_t on_varea_merge(struct rt_varea *merge_to, struct rt_varea *merge_from) { - /* transport page */ - void *mr_start = merge_from->start; - void *mr_end = mr_start + merge_from->size; - void *page_va; - - RT_ASSERT(!((rt_ubase_t)mr_start & ARCH_PAGE_MASK)); - RT_ASSERT(!((rt_ubase_t)mr_end & ARCH_PAGE_MASK)); - while (mr_start != mr_end) - { - page_va = rt_hw_mmu_v2p(merge_from->aspace, mr_start); - if (page_va != ARCH_MAP_FAILED) - { - rt_page_t frame; - page_va = rt_kmem_p2v(page_va); - if (page_va) - { - frame = rt_page_addr2page(page_va); - if (frame && _varea_pgmgr_frame_is_member(merge_from, frame)) - { - LOG_D("%s: free page %p", __func__, page_va); - rt_page_ref_inc(page_va, 0); - rt_varea_pgmgr_pop(merge_from, page_va, ARCH_PAGE_SIZE); - rt_varea_pgmgr_insert(merge_to, page_va); - } - } - } - mr_start += ARCH_PAGE_SIZE; - } + /* do nothing for the migration */ return RT_EOK; } diff --git a/components/mm/mm_page.c b/components/mm/mm_page.c index 0ddb392b63..5c72127be7 100644 --- a/components/mm/mm_page.c +++ b/components/mm/mm_page.c @@ -134,7 +134,6 @@ static void _trace_alloc(rt_page_t page, void *caller, size_t size_bits) { if (enable) { - char *page_va = rt_page_page2addr(page); page->caller = caller; page->trace_size = size_bits; page->tl_prev = NULL; diff --git a/components/mm/mm_page.h b/components/mm/mm_page.h index e1557b923d..d02e16cb70 100644 --- a/components/mm/mm_page.h +++ b/components/mm/mm_page.h @@ -33,7 +33,6 @@ #define PAGE_ANY_AVAILABLE 0x1ul - #ifdef RT_DEBUGING_PAGE_LEAK #define DEBUG_FIELD struct { \ /* trace list */ \ diff --git a/components/mm/mm_private.h b/components/mm/mm_private.h index 3fd3b88f86..ac7a8987cb 100644 --- a/components/mm/mm_private.h +++ b/components/mm/mm_private.h @@ -105,8 +105,6 @@ void _aspace_bst_insert(struct rt_aspace *aspace, struct rt_varea *varea); */ void _aspace_bst_remove(struct rt_aspace *aspace, struct rt_varea *varea); -void rt_varea_pgmgr_pop(rt_varea_t varea, void *vaddr, rt_size_t size); - void rt_varea_pgmgr_pop_all(rt_varea_t varea); int rt_varea_fix_private_locked(rt_varea_t ex_varea, void *pa, -- cgit v1.3.1