From 4e7d5a3dd8799abdacda9c6b60051d346b6e7f0b Mon Sep 17 00:00:00 2001 From: zhilan Date: Tue, 11 Jul 2023 16:30:38 +0800 Subject: [PATCH 1/3] unity: podmem: sort cache size before generating file path --- .../unity/collector/plugin/podmem/memcg.cpp | 183 +++++++++++++++++- 1 file changed, 182 insertions(+), 1 deletion(-) diff --git a/source/tools/monitor/unity/collector/plugin/podmem/memcg.cpp b/source/tools/monitor/unity/collector/plugin/podmem/memcg.cpp index 7cb44cd9..20802b0d 100644 --- a/source/tools/monitor/unity/collector/plugin/podmem/memcg.cpp +++ b/source/tools/monitor/unity/collector/plugin/podmem/memcg.cpp @@ -44,6 +44,15 @@ struct file_info { int shmem; int del; }; +struct myComp2 +{ + bool operator()(const pair &a,const pair &b) + { + return a.second>b.second; + } +}; + +set ,myComp2> cachedset; map files; struct myComp { @@ -123,6 +132,177 @@ static int get_filename(unsigned long dentry, char *filename, int len) return 0; } +int get_top_dentry(unsigned long pfn, int top) +{ + unsigned long page = PFN_TO_PAGE(pfn); + map::iterator iter2; + struct member_attribute *att; + struct member_attribute *att2; + unsigned long map = 0; + unsigned long cached = 0; + unsigned long inode = 0; + unsigned long i_ino; + char* tables; + att = get_offset("page", "mapping"); + if (!att) { + return 0; + } + + kcore_readmem(page + att->offset, &map, sizeof(map)); + if (!is_kvaddr(map)) + return 0; + att = get_offset("address_space", "host"); + if (!att) { + return 0; + } + att2 = get_offset("address_space", "nrpages"); + if (!att2) { + return 0; + } + tables = (char*)malloc(att2->offset-att->offset + sizeof(cached)); + kcore_readmem(map + att->offset, tables, att2->offset-att->offset + sizeof(cached)); + inode = *((unsigned long*) tables); + cached = *((unsigned long*) (tables+att2->offset-att->offset)); + free(tables); + /* skip file cache < 100K */ + //printf("top:%d, cached size:%d, cached:%d\n",top, cachedset.size(), cached*4); + if (cachedset.size() >= top and (cached*4 < (--cachedset.end())->second)) + return 0; + + att = get_offset("inode", "i_ino"); + if (!att) { + return 0; + } + kcore_readmem(inode + att->offset, &i_ino, sizeof(i_ino)); + iter2 = files.find(i_ino); + if (iter2 != files.end()) { + return -1; + } + + cachedset.insert(pair(inode,cached*4)); + if (cachedset.size() > top) + cachedset.erase(--cachedset.end()); +} + +static int get_dentry_top() +{ + set, myComp2>::iterator iter; + unsigned long map = 0; + unsigned long inode = 0; + unsigned long i_ino; + unsigned long i_size; + unsigned long inode_dentry =0; + unsigned long dentry_first = 0; + unsigned long hdentry = 0; + unsigned long pdentry = 0; + unsigned long mount = 0; + char tmp[4096] = {0}; + char *end = tmp + 4095; + int buflen = 4095; + unsigned long cached; + int del = 0; + char filename[1024] = {0}; + struct file_info *info; + struct member_attribute *att; + for(iter=cachedset.begin();iter!=cachedset.end();iter++) + { + cached = iter->second; + inode = iter->first; + att = get_offset("inode", "i_ino"); + if (!att) { + return 0; + } + kcore_readmem(inode + att->offset, &i_ino, sizeof(i_ino)); + att = get_offset("inode", "i_size"); + if (!att) { + return 0; + } + kcore_readmem(inode + att->offset, &i_size, sizeof(i_size)); + + mount = inode2mount(inode); + att = get_offset("inode","i_dentry"); + if (!att) { + return 0; + } + kcore_readmem(inode + att->offset, &inode_dentry, sizeof(inode)); + if (!is_kvaddr(inode_dentry)) + continue; + att = get_offset("dentry", "d_alias"); + if (!att) { + att = get_offset("dentry", "d_u"); + if (!att) + return 0; + } + + dentry_first = inode_dentry - att->offset; + memset(filename, 0, 1024); + att = get_offset("dentry", "d_parent"); + if (!att) { + return 0; + } + kcore_readmem(dentry_first+att->offset, &pdentry, sizeof(pdentry)); + att = get_offset("dentry", "d_hash"); + if (!att) { + return 0; + } + kcore_readmem(dentry_first+att->offset + sizeof(void*), &hdentry, sizeof(hdentry)); + if ((dentry_first != pdentry) && !hdentry) + del = 1; + do { + unsigned long mount_parent = 0; + unsigned long mount_dentry = 0; + int len = 0; + int ret = 0; + + get_filename(dentry_first, filename, 1024); + len = strlen(filename); + if (len <=0 || ((len == 1) && (filename[0] == '/'))) + break; + + prepend(&end, &buflen, filename, strlen(filename), 0); + att = get_offset("mount", "mnt_parent"); + if (!att) { + return 0; + } + ret = kcore_readmem(mount + att->offset, &mount_parent , sizeof(mount_parent)); + if (ret != sizeof(mount_parent)) + break; + att = get_offset("mount", "mnt_mountpoint"); + if (!att) { + return 0; + } + kcore_readmem(mount+ att->offset, &mount_dentry, sizeof(mount_dentry)); + if (mount_parent == mount || mount_dentry==dentry_first) + break; + dentry_first = mount_dentry; + mount = mount_parent; + } while(true); + + if (buflen >= 4092) + continue; + info = (struct file_info *)malloc(sizeof(struct file_info)); + if (!info) { + printf("alloc file info error \n"); + continue; + } + memset(info, 0, sizeof(struct file_info)); + info->inode = i_ino; + //info->shmem = shmem; + info->cached = cached; + info->cgcached = 1; + info->active = 0; + info->dirty = 0; + info->inactive = 0; + info->del = del; + + info->size = i_size>>10; + strncpy(info->filename, end, sizeof(info->filename) - 2); + info->filename[sizeof(info->filename) -1] = '0'; + files[i_ino] = info; + } + return 0; +} + /* * pfn: page pfn * cinode: cgroup inode @@ -382,9 +562,10 @@ int scan_pageflags_nooutput(struct options *opt, char *res) shmem = !!(pageflag & (1 <top); + get_top_dentry(pfn, opt->top); } } + get_dentry_top(); output_file_cached_string(opt->top, res); return 0; } -- Gitee From eb5b79197f515f45c7429d52a924c1b98888603b Mon Sep 17 00:00:00 2001 From: zhilan Date: Wed, 12 Jul 2023 13:35:41 +0800 Subject: [PATCH 2/3] unity: podmem: clear cachedset and reset it --- source/tools/monitor/unity/collector/plugin/podmem/memcg.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/tools/monitor/unity/collector/plugin/podmem/memcg.cpp b/source/tools/monitor/unity/collector/plugin/podmem/memcg.cpp index 20802b0d..92fa5618 100644 --- a/source/tools/monitor/unity/collector/plugin/podmem/memcg.cpp +++ b/source/tools/monitor/unity/collector/plugin/podmem/memcg.cpp @@ -299,6 +299,7 @@ static int get_dentry_top() strncpy(info->filename, end, sizeof(info->filename) - 2); info->filename[sizeof(info->filename) -1] = '0'; files[i_ino] = info; + fileset.insert(i_ino); } return 0; } @@ -517,6 +518,7 @@ static int output_file_cached_string(unsigned int top, char *res) } files.clear(); fileset.clear(); + cachedset.clear(); return 0; } -- Gitee From 9bdf25f7e135e284726a4c9c87ac6f5de03cf8eb Mon Sep 17 00:00:00 2001 From: zhilan Date: Wed, 12 Jul 2023 16:38:30 +0800 Subject: [PATCH 3/3] unity: podmem: fix bugs in podmem --- .../unity/collector/plugin/podmem/memcg.cpp | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/source/tools/monitor/unity/collector/plugin/podmem/memcg.cpp b/source/tools/monitor/unity/collector/plugin/podmem/memcg.cpp index 92fa5618..bea1c24f 100644 --- a/source/tools/monitor/unity/collector/plugin/podmem/memcg.cpp +++ b/source/tools/monitor/unity/collector/plugin/podmem/memcg.cpp @@ -63,6 +63,7 @@ struct myComp }; set fileset; map inodes; +map history_inodes; extern struct member_attribute *get_offset(string struct_name, string member_name); static int prepend(char **buffer, int *buflen, const char *str, int namelen, int off) @@ -166,20 +167,11 @@ int get_top_dentry(unsigned long pfn, int top) free(tables); /* skip file cache < 100K */ //printf("top:%d, cached size:%d, cached:%d\n",top, cachedset.size(), cached*4); - if (cachedset.size() >= top and (cached*4 < (--cachedset.end())->second)) + if (history_inodes.find(inode) != history_inodes.end() or (cachedset.size() >= top and (cached*4 < (--cachedset.end())->second))) return 0; - att = get_offset("inode", "i_ino"); - if (!att) { - return 0; - } - kcore_readmem(inode + att->offset, &i_ino, sizeof(i_ino)); - iter2 = files.find(i_ino); - if (iter2 != files.end()) { - return -1; - } - cachedset.insert(pair(inode,cached*4)); + history_inodes[inode] = 1; if (cachedset.size() > top) cachedset.erase(--cachedset.end()); } @@ -196,16 +188,16 @@ static int get_dentry_top() unsigned long hdentry = 0; unsigned long pdentry = 0; unsigned long mount = 0; - char tmp[4096] = {0}; - char *end = tmp + 4095; - int buflen = 4095; unsigned long cached; int del = 0; - char filename[1024] = {0}; struct file_info *info; struct member_attribute *att; for(iter=cachedset.begin();iter!=cachedset.end();iter++) { + char tmp[4096] = {0}; + char *end = tmp + 4095; + int buflen = 4095; + char filename[1024] = {0}; cached = iter->second; inode = iter->first; att = get_offset("inode", "i_ino"); @@ -519,6 +511,7 @@ static int output_file_cached_string(unsigned int top, char *res) files.clear(); fileset.clear(); cachedset.clear(); + history_inodes.clear(); return 0; } -- Gitee