diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index 61b463dee9078879a0bbb373c5dbeec6daddf439..adf53610dba51beba7220ef3d4a716eaa6ed0ae6 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 18864d81b0c0e95c76f73207416c654b126bd9c9..4d1309bff4b4236eacdab079f1ad8ce03da722ef 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 a11385f7004cebbe8051344755a01c15e586ba4e..4ef59773d83f713ad9b3a7cd67f2ad5a8da50373 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); } } - -