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 <mucorwang@gmail.com>
This commit is contained in:
mucor 2021-06-24 11:34:58 +08:00
parent ca40c79761
commit 3d1cf683f3
5 changed files with 79 additions and 20 deletions

View File

@ -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;
struct file_map *mapList = GetFileMappingList();
char *name = NULL;
struct file_map *curMap = NULL;
int total = 0;
(void)sem_wait(&flist->fl_sem);
for (int i = 3; i < CONFIG_NFILE_DESCRIPTORS; i++) {
if (!get_bit(i)) {
continue;
(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);
}
filep = &flist->fl_files[i];
if (filep == NULL) {
continue;
}
LosBufPrintf(buf, "[%d]%s:[", i, filep->f_path);
PageCacheEntryProcess(buf, filep->f_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)

View File

@ -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_ */

View File

@ -293,4 +293,9 @@ out:
(void)sem_post(&f_list->fl_sem);
return ret;
}
struct file_map* GetFileMappingList()
{
return &g_file_mapping;
}
#endif

View File

@ -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;
}

View File

@ -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