From 3d1cf683f37a6f75e9db2ce1f11ec93159b77663 Mon Sep 17 00:00:00 2001 From: mucor Date: Thu, 24 Jun 2021 11:34:58 +0800 Subject: [PATCH] feat: add clear cache cmd to /proc/fs_cache write "clear pathcahe" to clear pathcaches and vnodes write "clear pagecache" to clear pagecaches write "clear all" to clear both pathcaches and pagechaches the cache in use will not be cleared close: #I3XLPH Signed-off-by: mucor --- fs/proc/os_adapt/fs_cache_proc.c | 71 ++++++++++++++++++++-------- fs/vfs/include/vnode.h | 1 + fs/vfs/operation/fs_file_mapping.c | 5 ++ fs/vfs/vnode.c | 23 +++++++++ kernel/base/include/los_vm_filemap.h | 1 + 5 files changed, 80 insertions(+), 21 deletions(-) diff --git a/fs/proc/os_adapt/fs_cache_proc.c b/fs/proc/os_adapt/fs_cache_proc.c index b026704b..146f447c 100644 --- a/fs/proc/os_adapt/fs_cache_proc.c +++ b/fs/proc/os_adapt/fs_cache_proc.c @@ -35,6 +35,11 @@ #include "los_vm_filemap.h" #ifdef LOSCFG_DEBUG_VERSION + +#define CLEAR_ALL_CACHE "clear all" +#define CLEAR_PATH_CACHE "clear pathcache" +#define CLEAR_PAGE_CACHE "clear pagecache" + static char* VnodeTypeToStr(enum VnodeType type) { switch (type) { case VNODE_TYPE_UNKNOWN: @@ -93,40 +98,39 @@ static int PathCacheListProcess(struct SeqBuf *buf) return count; } -static void PageCacheEntryProcess(struct SeqBuf *buf, struct page_mapping *mapping) +static int PageCacheEntryProcess(struct SeqBuf *buf, struct page_mapping *mapping) { + int total = 0; LosFilePage *fpage = NULL; if (mapping == NULL) { LosBufPrintf(buf, "null]\n"); - return; + return total; } LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) { LosBufPrintf(buf, "%d,", fpage->pgoff); + total++; } LosBufPrintf(buf, "]\n"); - return; + return total; } -static void PageCacheMapProcess(struct SeqBuf *buf) +static int PageCacheMapProcess(struct SeqBuf *buf) { - struct filelist *flist = &tg_filelist; - struct file *filep = NULL; - - (void)sem_wait(&flist->fl_sem); - for (int i = 3; i < CONFIG_NFILE_DESCRIPTORS; i++) { - if (!get_bit(i)) { - continue; - } - filep = &flist->fl_files[i]; - if (filep == NULL) { - continue; - } - LosBufPrintf(buf, "[%d]%s:[", i, filep->f_path); - PageCacheEntryProcess(buf, filep->f_mapping); + struct file_map *mapList = GetFileMappingList(); + char *name = NULL; + struct file_map *curMap = NULL; + int total = 0; + + (VOID)LOS_MuxLock(&mapList->lock, LOS_WAIT_FOREVER); + LOS_DL_LIST_FOR_EACH_ENTRY(curMap, &mapList->head, struct file_map, head) { + name = curMap->rename ? curMap->rename: curMap->owner; + LosBufPrintf(buf, "%s:[", name); + total += PageCacheEntryProcess(buf, &curMap->mapping); } - (void)sem_post(&flist->fl_sem); + (VOID)LOS_MuxUnlock(&mapList->lock); + return total; } static int FsCacheInfoFill(struct SeqBuf *buf, void *arg) @@ -140,6 +144,7 @@ static int FsCacheInfoFill(struct SeqBuf *buf, void *arg) int pathCacheTotalTry = 0; int pathCacheTotalHit = 0; + int pageCacheTotal = 0; int pageCacheTotalTry = 0; int pageCacheTotalHit = 0; @@ -159,19 +164,43 @@ static int FsCacheInfoFill(struct SeqBuf *buf, void *arg) pathCacheTotal = PathCacheListProcess(buf); LosBufPrintf(buf, "\n=================================================================\n"); - PageCacheMapProcess(buf); + pageCacheTotal = PageCacheMapProcess(buf); + LosBufPrintf(buf, "\n=================================================================\n"); LosBufPrintf(buf, "PathCache Total:%d Try:%d Hit:%d\n", pathCacheTotal, pathCacheTotalTry, pathCacheTotalHit); LosBufPrintf(buf, "Vnode Total:%d Free:%d Virtual:%d Active:%d\n", vnodeTotal, vnodeFree, vnodeVirtual, vnodeActive); - LosBufPrintf(buf, "PageCache Try:%d Hit:%d\n", pageCacheTotalTry, pageCacheTotalHit); + LosBufPrintf(buf, "PageCache total:%d Try:%d Hit:%d\n", pageCacheTotal, pageCacheTotalTry, pageCacheTotalHit); VnodeDrop(); return 0; } +static int FsCacheClear(struct ProcFile *pf, const char *buffer, size_t buflen, loff_t *ppos) +{ + if (buffer == NULL || buflen < sizeof(CLEAR_ALL_CACHE)) { + return -EINVAL; + } + int vnodeCount = 0; + int pageCount = 0; + + if (!strcmp(buffer, CLEAR_ALL_CACHE)) { + vnodeCount = VnodeClearCache(); + pageCount = OsTryShrinkMemory(VM_FILEMAP_MAX_SCAN); + } else if (!strcmp(buffer, CLEAR_PAGE_CACHE)) { + pageCount = OsTryShrinkMemory(VM_FILEMAP_MAX_SCAN); + } else if (!strcmp(buffer, CLEAR_PATH_CACHE)) { + vnodeCount = VnodeClearCache(); + } else { + return -EINVAL; + } + + PRINTK("%d vnodes and related pathcaches cleared\n%d pages cleared\n", vnodeCount, pageCount); + return buflen; +} static const struct ProcFileOperations FS_CACHE_PROC_FOPS = { .read = FsCacheInfoFill, + .write = FsCacheClear, }; void ProcFsCacheInit(void) diff --git a/fs/vfs/include/vnode.h b/fs/vfs/include/vnode.h index ba13e8b9..c56fbffb 100644 --- a/fs/vfs/include/vnode.h +++ b/fs/vfs/include/vnode.h @@ -179,5 +179,6 @@ int VfsVnodePermissionCheck(const struct Vnode *node, int accMode); LIST_HEAD* GetVnodeFreeList(void); LIST_HEAD* GetVnodeActiveList(void); LIST_HEAD* GetVnodeVirtualList(void); +int VnodeClearCache(void); #endif /* !_VNODE_H_ */ diff --git a/fs/vfs/operation/fs_file_mapping.c b/fs/vfs/operation/fs_file_mapping.c index 8ea8e7c7..b143df41 100644 --- a/fs/vfs/operation/fs_file_mapping.c +++ b/fs/vfs/operation/fs_file_mapping.c @@ -293,4 +293,9 @@ out: (void)sem_post(&f_list->fl_sem); return ret; } + +struct file_map* GetFileMappingList() +{ + return &g_file_mapping; +} #endif diff --git a/fs/vfs/vnode.c b/fs/vfs/vnode.c index 95bf120b..56c2ec18 100644 --- a/fs/vfs/vnode.c +++ b/fs/vfs/vnode.c @@ -640,3 +640,26 @@ LIST_HEAD* GetVnodeActiveList() { return &g_vnodeActiveList; } + +int VnodeClearCache() +{ + struct Vnode *item = NULL; + struct Vnode *nextItem = NULL; + int count = 0; + + VnodeHold(); + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_vnodeActiveList, struct Vnode, actFreeEntry) { + if ((item->useCount > 0) || + (item->flag & VNODE_FLAG_MOUNT_ORIGIN) || + (item->flag & VNODE_FLAG_MOUNT_NEW)) { + continue; + } + + if (VnodeFree(item) == LOS_OK) { + count++; + } + } + VnodeDrop(); + + return count; +} diff --git a/kernel/base/include/los_vm_filemap.h b/kernel/base/include/los_vm_filemap.h index 17120118..9d8ec5fb 100644 --- a/kernel/base/include/los_vm_filemap.h +++ b/kernel/base/include/los_vm_filemap.h @@ -208,6 +208,7 @@ typedef struct ProcessCB LosProcessCB; VOID OsVmmFileRegionFree(struct file *filep, LosProcessCB *processCB); #ifdef LOSCFG_DEBUG_VERSION VOID ResetPageCacheHitInfo(int *try, int *hit); +struct file_map* GetFileMappingList(void); #endif #ifdef __cplusplus #if __cplusplus -- GitLab