fix: 进程退出前自己回收vmspace中的所有region
背景: 父进程fork一个子进程,调用waitpid等待子进程结束。 子进程dlopen一个文件a.so,并退出。当守护进程正在 1核回收子进程资源时,父进程在0核运行从waitpid返 回后,同时remove a.so概率失败。 Close #I4CKQC Signed-off-by: zhushengle <zhushengle@huawei.com> Change-Id: Ie7940e7c931ced10ee357cf9aa7c64355effed49
This commit is contained in:
parent
7d7cff4c51
commit
298ccea3fe
|
@ -342,6 +342,12 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
|
||||||
OsCurrProcessGet()->processID, processCB->processID);
|
OsCurrProcessGet()->processID, processCB->processID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LOSCFG_KERNEL_VM
|
||||||
|
if (OsProcessIsUserMode(processCB)) {
|
||||||
|
(VOID)OsVmSpaceRegionFree(processCB->vmSpace);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LOSCFG_FS_VFS
|
#ifdef LOSCFG_FS_VFS
|
||||||
if (OsProcessIsUserMode(processCB)) {
|
if (OsProcessIsUserMode(processCB)) {
|
||||||
delete_files(processCB->files);
|
delete_files(processCB->files);
|
||||||
|
@ -546,11 +552,11 @@ LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID)
|
||||||
/* Clear the bottom 4 bits of process status */
|
/* Clear the bottom 4 bits of process status */
|
||||||
OsInsertPCBToFreeList(processCB);
|
OsInsertPCBToFreeList(processCB);
|
||||||
}
|
}
|
||||||
SCHEDULER_UNLOCK(intSave);
|
|
||||||
#ifdef LOSCFG_KERNEL_VM
|
#ifdef LOSCFG_KERNEL_VM
|
||||||
|
SCHEDULER_UNLOCK(intSave);
|
||||||
(VOID)LOS_VmSpaceFree(space);
|
(VOID)LOS_VmSpaceFree(space);
|
||||||
#endif
|
|
||||||
SCHEDULER_LOCK(intSave);
|
SCHEDULER_LOCK(intSave);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SCHEDULER_UNLOCK(intSave);
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
|
|
@ -292,6 +292,8 @@ LosVmSpace *OsCreateUserVmSpace(VOID);
|
||||||
STATUS_T LOS_VmSpaceClone(LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace);
|
STATUS_T LOS_VmSpaceClone(LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace);
|
||||||
LosMux *OsGVmSpaceMuxGet(VOID);
|
LosMux *OsGVmSpaceMuxGet(VOID);
|
||||||
STATUS_T OsUnMMap(LosVmSpace *space, VADDR_T addr, size_t size);
|
STATUS_T OsUnMMap(LosVmSpace *space, VADDR_T addr, size_t size);
|
||||||
|
STATUS_T OsVmSpaceRegionFree(LosVmSpace *space);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* thread safety
|
* thread safety
|
||||||
* it is used to malloc continuous virtual memory, no sure for continuous physical memory.
|
* it is used to malloc continuous virtual memory, no sure for continuous physical memory.
|
||||||
|
|
|
@ -844,13 +844,47 @@ ERR_REGION_SPLIT:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATUS_T LOS_VmSpaceFree(LosVmSpace *space)
|
STATIC VOID OsVmSpaceAllRegionFree(LosVmSpace *space)
|
||||||
{
|
{
|
||||||
LosVmMapRegion *region = NULL;
|
|
||||||
LosRbNode *pstRbNode = NULL;
|
LosRbNode *pstRbNode = NULL;
|
||||||
LosRbNode *pstRbNodeNext = 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) {
|
if (space == NULL) {
|
||||||
return LOS_ERRNO_VM_INVALID_ARGS;
|
return LOS_ERRNO_VM_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
|
@ -862,19 +896,10 @@ STATUS_T LOS_VmSpaceFree(LosVmSpace *space)
|
||||||
|
|
||||||
/* pop it out of the global aspace list */
|
/* pop it out of the global aspace list */
|
||||||
(VOID)LOS_MuxAcquire(&space->regionMux);
|
(VOID)LOS_MuxAcquire(&space->regionMux);
|
||||||
|
|
||||||
LOS_ListDelete(&space->node);
|
LOS_ListDelete(&space->node);
|
||||||
/* free all of the regions */
|
|
||||||
RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext)
|
OsVmSpaceAllRegionFree(space);
|
||||||
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)
|
|
||||||
|
|
||||||
/* make sure the current thread does not map the aspace */
|
/* make sure the current thread does not map the aspace */
|
||||||
LosProcessCB *currentProcess = OsCurrProcessGet();
|
LosProcessCB *currentProcess = OsCurrProcessGet();
|
||||||
|
@ -1185,5 +1210,3 @@ VOID LOS_KernelFree(VOID *ptr)
|
||||||
(VOID)LOS_MemFree(OS_SYS_MEM_ADDR, ptr);
|
(VOID)LOS_MemFree(OS_SYS_MEM_ADDR, ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue