[rt-smart] testcase & improvements for memory management (#7099)

* [utest/mm] add testcase for create/init
format codes of create/init in components/mm

* [libcpu/aarch64] fix user stack check routine

* [kservice] export API for utest

* [utest/mm] testcase for aspace_map
format & modify the files under components/mm related with aspace_map

* [lwp/user_mm] add user_map_varea for mmap feature

* [mm] rename rt_mm_fault_try_fix to rt_aspace_fault_try_fix

* [utest/mm] testcase for synchronization

* [mm] modify unmap api to improve throughput

* [utest/mm] testcases for cache and varea map

* [format] remove extra space

* [utest/mm] fix testcase problem in header

* [lwp] extend map_user_varea with a flag

* [utest/mm] testcase for lwp_map_user_varea

* [libcpu/arm/cortex-a] fix kernel space layout

* [utest/mm] adjust for armv7 arch
This commit is contained in:
Shell
2023-03-30 08:25:15 +08:00
committed by GitHub
parent dc77d8fcb6
commit eec78d9f5d
38 changed files with 1887 additions and 240 deletions
+2
View File
@@ -117,6 +117,7 @@ rt_varea_t _aspace_bst_search_exceed(struct rt_aspace *aspace, void *start)
if (cmp < 0)
{
/* varae exceed start */
ptrdiff_t off = va_s - start;
if (off < min_off)
{
@@ -127,6 +128,7 @@ rt_varea_t _aspace_bst_search_exceed(struct rt_aspace *aspace, void *start)
}
else if (cmp > 0)
{
/* find the next huger varea */
node = node->avl_right;
}
else
+1 -1
View File
@@ -98,7 +98,7 @@ void *rt_ioremap_cached(void *paddr, size_t size)
void rt_iounmap(volatile void *vaddr)
{
rt_aspace_unmap(&rt_kernel_space, (void *)vaddr, 1);
rt_aspace_unmap(&rt_kernel_space, (void *)vaddr);
}
#else
+303 -147
View File
File diff suppressed because it is too large Load Diff
+33 -9
View File
@@ -90,7 +90,7 @@ typedef struct rt_mm_va_hint
typedef struct rt_mem_obj
{
void (*hint_free)(rt_mm_va_hint_t hint);
void (*on_page_fault)(struct rt_varea *varea, struct rt_mm_fault_msg *msg);
void (*on_page_fault)(struct rt_varea *varea, struct rt_aspace_fault_msg *msg);
/* do pre open bushiness like inc a ref */
void (*on_varea_open)(struct rt_varea *varea);
@@ -127,8 +127,7 @@ enum rt_mmu_cntl
rt_aspace_t rt_aspace_create(void *start, rt_size_t length, void *pgtbl);
rt_aspace_t rt_aspace_init(rt_aspace_t aspace, void *start, rt_size_t length,
void *pgtbl);
rt_err_t rt_aspace_init(rt_aspace_t aspace, void *start, rt_size_t length, void *pgtbl);
void rt_aspace_delete(rt_aspace_t aspace);
@@ -182,12 +181,11 @@ int rt_aspace_map_phy_static(rt_aspace_t aspace, rt_varea_t varea,
*
* @param aspace
* @param addr
* @param length
* @return int
*/
int rt_aspace_unmap(rt_aspace_t aspace, void *addr, rt_size_t length);
int rt_aspace_unmap(rt_aspace_t aspace, void *addr);
int mm_aspace_control(rt_aspace_t aspace, void *addr, enum rt_mmu_cntl cmd);
int rt_aspace_control(rt_aspace_t aspace, void *addr, enum rt_mmu_cntl cmd);
int rt_aspace_load_page(rt_aspace_t aspace, void *addr, rt_size_t npage);
@@ -198,11 +196,35 @@ int rt_aspace_traversal(rt_aspace_t aspace,
void rt_aspace_print_all(rt_aspace_t aspace);
void rt_varea_insert_page(rt_varea_t varea, void *page_addr);
/**
* @brief Map one page to varea
*
* @param varea target varea
* @param addr user address
* @param page the page frame to be mapped
* @return int
*/
int rt_varea_map_page(rt_varea_t varea, void *vaddr, void *page);
void rt_varea_free_pages(rt_varea_t varea);
/**
* @brief Map a range of physical address to varea
*
* @param varea target varea
* @param vaddr user address
* @param paddr physical address
* @param length map range
* @return int
*/
int rt_varea_map_range(rt_varea_t varea, void *vaddr, void *paddr, rt_size_t length);
void rt_varea_offload_page(rt_varea_t varea, void *vaddr, rt_size_t size);
/**
* @brief Insert page to page manager of varea
* The page will be freed by varea on uninstall automatically
*
* @param varea target varea
* @param page_addr the page frame to be added
*/
void rt_varea_pgmgr_insert(rt_varea_t varea, void *page_addr);
rt_ubase_t rt_kmem_pvoff(void);
@@ -212,4 +234,6 @@ int rt_kmem_map_phy(void *va, void *pa, rt_size_t length, rt_size_t attr);
void *rt_kmem_v2p(void *vaddr);
void rt_kmem_list(void);
#endif /* __MM_ASPACE_H__ */
+19 -29
View File
@@ -26,40 +26,28 @@
#define UNRECOVERABLE 0
#define RECOVERABLE 1
static int _fetch_page(rt_varea_t varea, struct rt_mm_fault_msg *msg)
static int _fetch_page(rt_varea_t varea, struct rt_aspace_fault_msg *msg)
{
int err = UNRECOVERABLE;
int err;
msg->response.status = MM_FAULT_STATUS_UNRECOVERABLE;
msg->response.vaddr = 0;
msg->response.size = 0;
if (varea->mem_obj && varea->mem_obj->on_page_fault)
{
varea->mem_obj->on_page_fault(varea, msg);
if (msg->response.status == MM_FAULT_STATUS_OK)
{
void *store = msg->response.vaddr;
rt_size_t store_sz = msg->response.size;
if (msg->vaddr + store_sz > varea->start + varea->size)
{
LOG_W("%s more size of buffer is provided than varea", __func__);
}
else
{
rt_hw_mmu_map(varea->aspace, msg->vaddr, store + PV_OFFSET,
store_sz, varea->attr);
rt_hw_tlb_invalidate_range(varea->aspace, msg->vaddr, store_sz,
ARCH_PAGE_SIZE);
err = RECOVERABLE;
}
}
err = _varea_map_with_msg(varea, msg);
err = (err == RT_EOK ? RECOVERABLE : UNRECOVERABLE);
}
return err;
}
static int _read_fault(rt_varea_t varea, void *pa, struct rt_mm_fault_msg *msg)
static int _read_fault(rt_varea_t varea, void *pa, struct rt_aspace_fault_msg *msg)
{
int err = UNRECOVERABLE;
if (msg->fault_type == MM_FAULT_TYPE_PAGE_FAULT)
{
RT_ASSERT(pa == ARCH_MAP_FAILED);
RT_ASSERT(!(varea->flag & MMF_PREFETCH));
err = _fetch_page(varea, msg);
}
else
@@ -69,12 +57,13 @@ static int _read_fault(rt_varea_t varea, void *pa, struct rt_mm_fault_msg *msg)
return err;
}
static int _write_fault(rt_varea_t varea, void *pa, struct rt_mm_fault_msg *msg)
static int _write_fault(rt_varea_t varea, void *pa, struct rt_aspace_fault_msg *msg)
{
int err = UNRECOVERABLE;
if (msg->fault_type == MM_FAULT_TYPE_PAGE_FAULT)
{
RT_ASSERT(pa == ARCH_MAP_FAILED);
RT_ASSERT(!(varea->flag & MMF_PREFETCH));
err = _fetch_page(varea, msg);
}
else if (msg->fault_type == MM_FAULT_TYPE_ACCESS_FAULT &&
@@ -88,33 +77,34 @@ static int _write_fault(rt_varea_t varea, void *pa, struct rt_mm_fault_msg *msg)
return err;
}
static int _exec_fault(rt_varea_t varea, void *pa, struct rt_mm_fault_msg *msg)
static int _exec_fault(rt_varea_t varea, void *pa, struct rt_aspace_fault_msg *msg)
{
int err = UNRECOVERABLE;
if (msg->fault_type == MM_FAULT_TYPE_PAGE_FAULT)
{
RT_ASSERT(pa == ARCH_MAP_FAILED);
RT_ASSERT(!(varea->flag & MMF_PREFETCH));
err = _fetch_page(varea, msg);
}
return err;
}
int rt_mm_fault_try_fix(struct rt_mm_fault_msg *msg)
int rt_aspace_fault_try_fix(struct rt_aspace_fault_msg *msg)
{
struct rt_lwp *lwp = lwp_self();
int err = UNRECOVERABLE;
uintptr_t va = (uintptr_t)msg->vaddr;
uintptr_t va = (uintptr_t)msg->fault_vaddr;
va &= ~ARCH_PAGE_MASK;
msg->vaddr = (void *)va;
msg->fault_vaddr = (void *)va;
if (lwp)
{
rt_aspace_t aspace = lwp->aspace;
rt_varea_t varea = _aspace_bst_search(aspace, msg->vaddr);
rt_varea_t varea = _aspace_bst_search(aspace, msg->fault_vaddr);
if (varea)
{
void *pa = rt_hw_mmu_v2p(aspace, msg->vaddr);
msg->off = (msg->vaddr - varea->start) >> ARCH_PAGE_SHIFT;
void *pa = rt_hw_mmu_v2p(aspace, msg->fault_vaddr);
msg->off = (msg->fault_vaddr - varea->start) >> ARCH_PAGE_SHIFT;
/* permission checked by fault op */
switch (msg->fault_op)
+8 -5
View File
@@ -14,8 +14,11 @@
#include <stddef.h>
#include <stdint.h>
#define MM_FAULT_STATUS_OK 0
#define MM_FAULT_STATUS_UNRECOVERABLE 1
/* fast path fault handler, a page frame on kernel space is returned */
#define MM_FAULT_STATUS_OK 0
/* customized fault handler, done by using rt_varea_map_* */
#define MM_FAULT_STATUS_OK_MAPPED 1
#define MM_FAULT_STATUS_UNRECOVERABLE 4
struct rt_mm_fault_res
{
@@ -39,17 +42,17 @@ enum rt_mm_fault_type
MM_FAULT_TYPE_GENERIC,
};
struct rt_mm_fault_msg
struct rt_aspace_fault_msg
{
enum rt_mm_fault_op fault_op;
enum rt_mm_fault_type fault_type;
rt_size_t off;
void *vaddr;
void *fault_vaddr;
struct rt_mm_fault_res response;
};
/* MMU base page fault handler, return 1 is */
int rt_mm_fault_try_fix(struct rt_mm_fault_msg *msg);
int rt_aspace_fault_try_fix(struct rt_aspace_fault_msg *msg);
#endif /* __MM_FAULT_H__ */
+3 -3
View File
@@ -82,9 +82,9 @@ enum mm_flag_cntl
*
* Direct use of flag is also acceptable: (MMF_MAP_FIXED | MMF_PREFETCH)
*/
#define MMF_CREATE(cntl, align) \
(align ? (MMF_SET_CNTL((mm_flag_t)0, (cntl) | MMF_REQUEST_ALIGN) | \
MMF_SET_ALIGN((mm_flag_t)0, align)) \
#define MMF_CREATE(cntl, align) \
((align) ? (MMF_SET_CNTL((mm_flag_t)0, (cntl) | MMF_REQUEST_ALIGN) | \
MMF_SET_ALIGN((mm_flag_t)0, (align))) \
: (MMF_SET_CNTL((mm_flag_t)0, (cntl) & ~MMF_REQUEST_ALIGN)))
#undef _DEF_FLAG
+3 -3
View File
@@ -17,13 +17,13 @@
#include "mm_private.h"
#include <mmu.h>
static void list_kernel_space(void)
static void list_kmem(void)
{
rt_aspace_print_all(&rt_kernel_space);
}
MSH_CMD_EXPORT(list_kernel_space, List varea in kernel space);
MSH_CMD_EXPORT(list_kmem, List varea in kernel virtual memory space);
void rt_kmem_list_varea(void) __attribute__((alias("list_kernel_space")));
void rt_kmem_list(void) __attribute__((alias("list_kmem")));
static rt_ubase_t rt_pv_offset;
+6 -6
View File
@@ -24,7 +24,7 @@ static const char *get_name(rt_varea_t varea)
return "dummy-mapper";
}
void rt_varea_insert_page(rt_varea_t varea, void *page_addr)
void rt_varea_pgmgr_insert(rt_varea_t varea, void *page_addr)
{
rt_page_t page = rt_page_addr2page(page_addr);
@@ -41,7 +41,7 @@ void rt_varea_insert_page(rt_varea_t varea, void *page_addr)
}
}
void rt_varea_free_pages(rt_varea_t varea)
void rt_varea_pgmgr_pop_all(rt_varea_t varea)
{
rt_page_t page = varea->frames;
@@ -54,7 +54,7 @@ void rt_varea_free_pages(rt_varea_t varea)
}
}
void rt_varea_offload_page(rt_varea_t varea, void *vaddr, rt_size_t size)
void rt_varea_pgmgr_pop(rt_varea_t varea, void *vaddr, rt_size_t size)
{
void *vend = vaddr + size;
while (vaddr != vend)
@@ -67,7 +67,7 @@ void rt_varea_offload_page(rt_varea_t varea, void *vaddr, rt_size_t size)
}
}
static void on_page_fault(struct rt_varea *varea, struct rt_mm_fault_msg *msg)
static void on_page_fault(struct rt_varea *varea, struct rt_aspace_fault_msg *msg)
{
void *page;
page = rt_pages_alloc(0);
@@ -82,7 +82,7 @@ static void on_page_fault(struct rt_varea *varea, struct rt_mm_fault_msg *msg)
msg->response.size = ARCH_PAGE_SIZE;
msg->response.vaddr = page;
rt_varea_insert_page(varea, page);
rt_varea_pgmgr_insert(varea, page);
}
static void on_varea_open(struct rt_varea *varea)
@@ -96,7 +96,7 @@ static void on_varea_close(struct rt_varea *varea)
static void on_page_offload(rt_varea_t varea, void *vaddr, rt_size_t size)
{
rt_varea_offload_page(varea, vaddr, size);
rt_varea_pgmgr_pop(varea, vaddr, size);
}
struct rt_mem_obj rt_mm_dummy_mapper = {
+3 -3
View File
@@ -59,13 +59,13 @@ static void hint_free(rt_mm_va_hint_t hint)
hint->prefer = rt_mpr_start;
}
static void on_page_fault(struct rt_varea *varea, struct rt_mm_fault_msg *msg)
static void on_page_fault(struct rt_varea *varea, struct rt_aspace_fault_msg *msg)
{
void *init_start = (void *)init_mpr_align_start;
void *init_end = (void *)init_mpr_align_end;
if (msg->vaddr < init_end && msg->vaddr >= init_start)
if (msg->fault_vaddr < init_end && msg->fault_vaddr >= init_start)
{
rt_size_t offset = msg->vaddr - init_start;
rt_size_t offset = msg->fault_vaddr - init_start;
msg->response.status = MM_FAULT_STATUS_OK;
msg->response.vaddr = init_mpr_cont_start + offset;
msg->response.size = ARCH_PAGE_SIZE;
+11 -6
View File
@@ -7,8 +7,8 @@
* Date Author Notes
* 2022-11-14 WangXiaoyao the first version
*/
#ifndef __MM_INTERN_H__
#define __MM_INTERN_H__
#ifndef __MM_PRIVATE_H__
#define __MM_PRIVATE_H__
#include "mm_aspace.h"
#include <rtdef.h>
@@ -44,7 +44,7 @@ struct _mm_range
rt_err_t _aspace_bst_init(struct rt_aspace *aspace);
/**
* @brief
* @brief Retrieve any varea if start in [varea->start, varea->end]
*
* @param aspace
* @param start
@@ -53,8 +53,7 @@ rt_err_t _aspace_bst_init(struct rt_aspace *aspace);
struct rt_varea *_aspace_bst_search(struct rt_aspace *aspace, void *start);
/**
* @brief Retrieve lowest varea satisfies
* ((varea->start >= start) || (varea->end >= start))
* @brief Retrieve lowest varea satisfies (varea->start >= start)
*
* @param aspace
* @param length
@@ -91,4 +90,10 @@ void _aspace_bst_insert(struct rt_aspace *aspace, struct rt_varea *varea);
*/
void _aspace_bst_remove(struct rt_aspace *aspace, struct rt_varea *varea);
#endif /* __MM_INTERN_H__ */
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 _varea_map_with_msg(rt_varea_t varea, struct rt_aspace_fault_msg *msg);
#endif /* __MM_PRIVATE_H__ */