fix: MMU竞态问题修复
背景:同一个进程的多个线程读写同一个PTE时,由于PTE无保护,存在竞态问题。 方案:新增spinlock保护PTE,包括大锁跟小锁。大锁:一个进程只有一个spinlock锁,多个线程 读写PTE时竞争一把锁,锁的内存占用小,但系统性能降低;小锁:每个页表持有一把spinlock, 由于锁是page结构体的一个字段,内存消耗较大,但是相对大锁性能较优。系统默认使用大锁,用 户可根据具体需要配置使用大锁还是小锁。 close #I2WARC Signed-off-by: Haryslee <lihao189@huawei.com> Change-Id: I5612eeac1f65507160035eae16af61f285182eda
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
|
||||
#include "los_typedef.h"
|
||||
#include "los_arch_mmu.h"
|
||||
#include "los_mux.h"
|
||||
#include "los_rbtree.h"
|
||||
#include "los_vm_syscall.h"
|
||||
#include "los_vm_zone.h"
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "los_bitmap.h"
|
||||
#include "los_list.h"
|
||||
#include "los_atomic.h"
|
||||
#include "los_spinlock.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
@@ -51,6 +52,9 @@ typedef struct VmPage {
|
||||
UINT8 order; /**< vm page in which order list */
|
||||
UINT8 segID; /**< the segment id of vm page */
|
||||
UINT16 nPages; /**< the vm page is used for kernel heap */
|
||||
#ifdef LOSCFG_PAGE_TABLE_FINE_LOCK
|
||||
SPIN_LOCK_S lock; /**< lock for page table entry */
|
||||
#endif
|
||||
} LosVmPage;
|
||||
|
||||
extern LosVmPage *g_vmPageArray;
|
||||
|
||||
@@ -102,6 +102,7 @@ LosVmPage *OsVmVaddrToPage(VOID *ptr);
|
||||
VOID OsPhysSharePageCopy(PADDR_T oldPaddr, PADDR_T *newPaddr, LosVmPage *newPage);
|
||||
VOID OsVmPhysPagesFreeContiguous(LosVmPage *page, size_t nPages);
|
||||
LosVmPage *OsVmPhysToPage(paddr_t pa, UINT8 segID);
|
||||
LosVmPage *OsVmPaddrToPage(paddr_t paddr);
|
||||
|
||||
LosVmPage *LOS_PhysPageAlloc(VOID);
|
||||
VOID LOS_PhysPageFree(LosVmPage *page);
|
||||
@@ -110,6 +111,7 @@ size_t LOS_PhysPagesFree(LOS_DL_LIST *list);
|
||||
VOID *LOS_PhysPagesAllocContiguous(size_t nPages);
|
||||
VOID LOS_PhysPagesFreeContiguous(VOID *ptr, size_t nPages);
|
||||
VADDR_T *LOS_PaddrToKVaddr(PADDR_T paddr);
|
||||
PADDR_T OsKVaddrToPaddr(VADDR_T kvaddr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
|
||||
@@ -50,6 +50,9 @@ STATIC VOID OsVmPageInit(LosVmPage *page, paddr_t pa, UINT8 segID)
|
||||
page->segID = segID;
|
||||
page->order = VM_LIST_ORDER_MAX;
|
||||
page->nPages = 0;
|
||||
#ifdef LOSCFG_PAGE_TABLE_FINE_LOCK
|
||||
LOS_SpinInit(&page->lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsVmPageOrderListInit(LosVmPage *page, size_t nPages)
|
||||
|
||||
@@ -220,6 +220,20 @@ LosVmPage *OsVmPhysToPage(paddr_t pa, UINT8 segID)
|
||||
return (seg->pageBase + (offset >> PAGE_SHIFT));
|
||||
}
|
||||
|
||||
LosVmPage *OsVmPaddrToPage(paddr_t paddr)
|
||||
{
|
||||
INT32 segID;
|
||||
LosVmPage *vmPage = NULL;
|
||||
|
||||
for (segID = 0; segID < g_vmPhysSegNum; segID++) {
|
||||
vmPage = OsVmPhysToPage(paddr, segID);
|
||||
if (vmPage != NULL) {
|
||||
return vmPage;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VOID *OsVmPageToVaddr(LosVmPage *page)
|
||||
{
|
||||
VADDR_T vaddr;
|
||||
@@ -444,11 +458,23 @@ VOID LOS_PhysPagesFreeContiguous(VOID *ptr, size_t nPages)
|
||||
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
|
||||
}
|
||||
|
||||
PADDR_T OsKVaddrToPaddr(VADDR_T kvaddr)
|
||||
{
|
||||
if (kvaddr == 0) {
|
||||
return 0;
|
||||
}
|
||||
return (kvaddr - KERNEL_ASPACE_BASE + SYS_MEM_BASE);
|
||||
}
|
||||
|
||||
VADDR_T *LOS_PaddrToKVaddr(PADDR_T paddr)
|
||||
{
|
||||
struct VmPhysSeg *seg = NULL;
|
||||
UINT32 segID;
|
||||
|
||||
if (paddr == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (segID = 0; segID < g_vmPhysSegNum; segID++) {
|
||||
seg = &g_vmPhysSeg[segID];
|
||||
if ((paddr >= seg->start) && (paddr < (seg->start + seg->size))) {
|
||||
|
||||
Reference in New Issue
Block a user