From 298ccea3fedaccc651b38973f0455fa1ce12e516 Mon Sep 17 00:00:00 2001 From: zhushengle Date: Tue, 28 Sep 2021 15:57:37 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=BF=9B=E7=A8=8B=E9=80=80=E5=87=BA?= =?UTF-8?q?=E5=89=8D=E8=87=AA=E5=B7=B1=E5=9B=9E=E6=94=B6vmspace=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E6=89=80=E6=9C=89region?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景: 父进程fork一个子进程,调用waitpid等待子进程结束。 子进程dlopen一个文件a.so,并退出。当守护进程正在 1核回收子进程资源时,父进程在0核运行从waitpid返 回后,同时remove a.so概率失败。 Close #I4CKQC Signed-off-by: zhushengle Change-Id: Ie7940e7c931ced10ee357cf9aa7c64355effed49 --- kernel/base/core/los_process.c | 10 ++++-- kernel/base/include/los_vm_map.h | 2 ++ kernel/base/vm/los_vm_map.c | 57 ++++++++++++++++++++++---------- 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index 61b463de..adf53610 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -342,6 +342,12 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB) OsCurrProcessGet()->processID, processCB->processID); } +#ifdef LOSCFG_KERNEL_VM + if (OsProcessIsUserMode(processCB)) { + (VOID)OsVmSpaceRegionFree(processCB->vmSpace); + } +#endif + #ifdef LOSCFG_FS_VFS if (OsProcessIsUserMode(processCB)) { delete_files(processCB->files); @@ -546,11 +552,11 @@ LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID) /* Clear the bottom 4 bits of process status */ OsInsertPCBToFreeList(processCB); } - SCHEDULER_UNLOCK(intSave); #ifdef LOSCFG_KERNEL_VM + SCHEDULER_UNLOCK(intSave); (VOID)LOS_VmSpaceFree(space); -#endif SCHEDULER_LOCK(intSave); +#endif } SCHEDULER_UNLOCK(intSave); diff --git a/kernel/base/include/los_vm_map.h b/kernel/base/include/los_vm_map.h index 18864d81..4d1309bf 100644 --- a/kernel/base/include/los_vm_map.h +++ b/kernel/base/include/los_vm_map.h @@ -292,6 +292,8 @@ LosVmSpace *OsCreateUserVmSpace(VOID); STATUS_T LOS_VmSpaceClone(LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace); LosMux *OsGVmSpaceMuxGet(VOID); STATUS_T OsUnMMap(LosVmSpace *space, VADDR_T addr, size_t size); +STATUS_T OsVmSpaceRegionFree(LosVmSpace *space); + /** * thread safety * it is used to malloc continuous virtual memory, no sure for continuous physical memory. diff --git a/kernel/base/vm/los_vm_map.c b/kernel/base/vm/los_vm_map.c index a11385f7..4ef59773 100644 --- a/kernel/base/vm/los_vm_map.c +++ b/kernel/base/vm/los_vm_map.c @@ -844,13 +844,47 @@ ERR_REGION_SPLIT: return status; } -STATUS_T LOS_VmSpaceFree(LosVmSpace *space) +STATIC VOID OsVmSpaceAllRegionFree(LosVmSpace *space) { - LosVmMapRegion *region = NULL; LosRbNode *pstRbNode = NULL; LosRbNode *pstRbNodeNext = NULL; - STATUS_T ret; + /* free all of the regions */ + RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext) + LosVmMapRegion *region = (LosVmMapRegion *)pstRbNode; + if (region->range.size == 0) { + VM_ERR("space free, region: %#x flags: %#x, base:%#x, size: %#x", + region, region->regionFlags, region->range.base, region->range.size); + } + STATUS_T ret = LOS_RegionFree(space, region); + if (ret != LOS_OK) { + VM_ERR("free region error, space %p, region %p", space, region); + } + RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext) + + return; +} + +STATUS_T OsVmSpaceRegionFree(LosVmSpace *space) +{ + if (space == NULL) { + return LOS_ERRNO_VM_INVALID_ARGS; + } + + if (space == &g_kVmSpace) { + VM_ERR("try to free kernel aspace, not allowed"); + return LOS_OK; + } + + (VOID)LOS_MuxAcquire(&space->regionMux); + OsVmSpaceAllRegionFree(space); + (VOID)LOS_MuxRelease(&space->regionMux); + + return LOS_OK; +} + +STATUS_T LOS_VmSpaceFree(LosVmSpace *space) +{ if (space == NULL) { return LOS_ERRNO_VM_INVALID_ARGS; } @@ -862,19 +896,10 @@ STATUS_T LOS_VmSpaceFree(LosVmSpace *space) /* pop it out of the global aspace list */ (VOID)LOS_MuxAcquire(&space->regionMux); + LOS_ListDelete(&space->node); - /* free all of the regions */ - RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext) - region = (LosVmMapRegion *)pstRbNode; - if (region->range.size == 0) { - VM_ERR("space free, region: %#x flags: %#x, base:%#x, size: %#x", - region, region->regionFlags, region->range.base, region->range.size); - } - ret = LOS_RegionFree(space, region); - if (ret != LOS_OK) { - VM_ERR("free region error, space %p, region %p", space, region); - } - RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext) + + OsVmSpaceAllRegionFree(space); /* make sure the current thread does not map the aspace */ LosProcessCB *currentProcess = OsCurrProcessGet(); @@ -1185,5 +1210,3 @@ VOID LOS_KernelFree(VOID *ptr) (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, ptr); } } - - -- GitLab