提交 3d1cf683 编写于 作者: M mucor

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: Nmucor <mucorwang@gmail.com>
上级 ca40c797
......@@ -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)
......
......@@ -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_ */
......@@ -293,4 +293,9 @@ out:
(void)sem_post(&f_list->fl_sem);
return ret;
}
struct file_map* GetFileMappingList()
{
return &g_file_mapping;
}
#endif
......@@ -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;
}
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册