From 7aa130c83c0a23f45a008233fa55f84ba828c12a Mon Sep 17 00:00:00 2001 From: geniusgogo <2041245+geniusgogo@users.noreply.github.com> Date: Tue, 5 Dec 2023 16:44:00 +0800 Subject: [PATCH] update mm. (#8334) --- components/mm/mm_aspace.c | 55 +++++++++++++++++++++++++++++++++++++++ components/mm/mm_aspace.h | 24 +++-------------- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/components/mm/mm_aspace.c b/components/mm/mm_aspace.c index df30b5460c..f29d660183 100644 --- a/components/mm/mm_aspace.c +++ b/components/mm/mm_aspace.c @@ -1068,6 +1068,61 @@ int rt_aspace_unmap_range(rt_aspace_t aspace, void *addr, size_t length) return error; } +void *rt_aspace_mremap_range(rt_aspace_t aspace, void *old_address, size_t old_size, + size_t new_size, int flags, void *new_address) +{ + void *ret = RT_NULL; + + if (!aspace) + { + LOG_I("%s: Invalid input", __func__); + } + else if (_not_in_range(old_address, old_size, aspace->start, aspace->size)) + { + LOG_I("%s: %lx not in range of aspace[%lx:%lx]", __func__, old_address, + aspace->start, (char *)aspace->start + aspace->size); + } + else if (!ALIGNED(old_address)) + { + LOG_I("%s(old_address=%p): Unaligned address", __func__, old_address); + } + else + { + /** + * Brief: re-arrange the address space to remove existing pages mapping + * in [unmap_start, unmap_start + unmap_len) + */ + old_size = RT_ALIGN(old_size, ARCH_PAGE_SIZE); + + WR_LOCK(aspace); + { + rt_varea_t existed; + struct _mm_range unmap_range; + + unmap_range.start = old_address; + unmap_range.end = old_address + old_size - 1; + + existed = _aspace_bst_search_overlap(aspace, unmap_range); + if (existed && existed->mem_obj && existed->mem_obj->on_varea_mremap) + { + ret = existed->mem_obj->on_varea_mremap(existed, new_size, flags, new_address); + } + } + WR_UNLOCK(aspace); + + if (ret) + { + int error = rt_aspace_unmap_range(aspace, old_address, old_size); + if (error != RT_EOK) + { + LOG_I("%s: unmap old failed, addr %p size %p", __func__, old_address, old_size); + } + } + } + + return ret; +} + static inline void *_lower(void *a, void *b) { return a < b ? a : b; diff --git a/components/mm/mm_aspace.h b/components/mm/mm_aspace.h index 08be2e2b21..b5356253b0 100644 --- a/components/mm/mm_aspace.h +++ b/components/mm/mm_aspace.h @@ -121,6 +121,8 @@ typedef struct rt_mem_obj void (*page_write)(struct rt_varea *varea, struct rt_aspace_io_msg *msg); const char *(*get_name)(rt_varea_t varea); + + void *(*on_varea_mremap)(struct rt_varea *varea, rt_size_t new_size, int flags, void *new_address); } *rt_mem_obj_t; extern struct rt_mem_obj rt_mm_dummy_mapper; @@ -226,26 +228,8 @@ int rt_aspace_unmap(rt_aspace_t aspace, void *addr); */ int rt_aspace_unmap_range(rt_aspace_t aspace, void *addr, size_t length); -/** - * @brief Remove pages of existed mappings in the range [addr, addr+length) - * Length is automatically rounded up to the next multiple of the page size. - * - * @param aspace target virtual address space - * @param addr the beginning of the range of pages to be unmapped - * @param length length of range in bytes - * @return int rt errno - */ -int rt_aspace_unmap_range(rt_aspace_t aspace, void *addr, size_t length); - -/** - * @brief Remove pages of existed mappings in the range [addr, addr+length) - * Length is automatically rounded up to the next multiple of the page size. - * - * @param aspace target virtual address space - * @param addr - * @return int - */ -int rt_aspace_unmap_range(rt_aspace_t aspace, void *addr, size_t length); +void *rt_aspace_mremap_range(rt_aspace_t aspace, void *old_address, size_t old_size, + size_t new_size, int flags, void *new_address); int rt_aspace_control(rt_aspace_t aspace, void *addr, enum rt_mmu_cntl cmd);