diff options
| author | git-baoyou <[email protected]> | 2021-11-25 16:31:25 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-11-25 16:31:25 +0800 |
| commit | 5222f30832e1d1c366c692ba9eb7968c0420ebce (patch) | |
| tree | 4a91b51d2721132d7ffd722057999958182f790a /SOURCE | |
| parent | 1793502843cd8f3a5932fa602cdb9f4b3b390cbe (diff) | |
| parent | a5c8f452d5e97dd535a92a22ba52a3649bddb065 (diff) | |
Merge pull request #151 from w-simon/fix_5.10
memcg-stats: 输出mount点的路径,便于分析memcg的内存占用
Diffstat (limited to 'SOURCE')
| -rw-r--r-- | SOURCE/diagnose-tools/memcg_stats.cc | 6 | ||||
| -rw-r--r-- | SOURCE/module/mm/memcg_stats.c | 63 | ||||
| -rw-r--r-- | SOURCE/uapi/memcg_stats.h | 1 |
3 files changed, 68 insertions, 2 deletions
diff --git a/SOURCE/diagnose-tools/memcg_stats.cc b/SOURCE/diagnose-tools/memcg_stats.cc index 690e091..653572e 100644 --- a/SOURCE/diagnose-tools/memcg_stats.cc +++ b/SOURCE/diagnose-tools/memcg_stats.cc @@ -172,20 +172,22 @@ static int memcg_stats_extract(void *buf, unsigned int len, void *) break; detail = (struct diag_memcg_stats_detail *)buf; if (debug_mode) { - printf("memcg: %p inode: %p major: %u minor: %u ino: %lu pages: %u name: %s\n", + printf("memcg: %p inode: %p major: %u minor: %u ino: %lu pages: %u mnt: %s name: %s\n", (void *)detail->cg_addr, (void *)detail->key, MAJOR(detail->dev), MINOR(detail->dev), detail->ino, detail->pages, + detail->mnt_dir, detail->name); } else { - printf("major: %u minor: %u ino: %lu pages: %u name: %s\n", + printf("major: %u minor: %u ino: %lu pages: %u mnt: %s name: %s\n", MAJOR(detail->dev), MINOR(detail->dev), detail->ino, detail->pages, + detail->mnt_dir, detail->name); } break; diff --git a/SOURCE/module/mm/memcg_stats.c b/SOURCE/module/mm/memcg_stats.c index dc00824..17b5bf8 100644 --- a/SOURCE/module/mm/memcg_stats.c +++ b/SOURCE/module/mm/memcg_stats.c @@ -10,6 +10,7 @@ #include <linux/kallsyms.h> #include <linux/kernfs.h> #include <linux/version.h> +#include <linux/mount.h> #if KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE #include <linux/kernfs.h> #endif @@ -33,6 +34,8 @@ static struct pglist_data * (*orig_first_online_pgdat)(void) = NULL; static struct pglist_data * (*orig_next_online_pgdat)(struct pglist_data *pgdat) = NULL; +seqlock_t * orig_mount_lock = NULL; + static struct diag_variant_buffer memcg_stats_variant_buffer; static int memcg_stats_alloced = 0; @@ -114,6 +117,64 @@ static void inode_name(struct inode *ino, char *buf, unsigned int len) kfree(name); } +struct mount_diag { + struct hlist_node mnt_hash; + struct mount_diag *mnt_parent; + struct dentry *mnt_mountpoint; + struct vfsmount mnt; + union { + struct rcu_head mnt_rcu; + struct llist_node mnt_llist; + }; +#ifdef CONFIG_SMP + struct mnt_pcp __percpu *mnt_pcp; +#else + int mnt_count; + int mnt_writers; +#endif + struct list_head mnt_mounts; /* list of children, anchored here */ + struct list_head mnt_child; /* and going through their mnt_child */ + struct list_head mnt_instance; /* mount instance on sb->s_mounts */ +}; + +static void mnt_dir(struct inode *ino, char *buf, unsigned int len) +{ + struct mount_diag *mnt = NULL; + struct super_block *sb; + struct dentry *dentry; + char *name; + + buf[0] = '\0'; + if (!ino || !buf || !len) + goto out; + sb = ino->i_sb; + if (!sb) + goto out; + + write_seqlock(orig_mount_lock); + if (!list_empty(&sb->s_mounts)) + mnt = list_first_entry(&sb->s_mounts, struct mount_diag, + mnt_instance); + write_sequnlock(orig_mount_lock); + + if (!mnt) + goto out; + dentry = mnt->mnt_mountpoint; + if (!dentry) + goto out; + + name = __getname(); + if (!name) + goto out; + + __dentry_name(dentry, name); + strncpy(buf, name, len - 1); + kfree(name); + +out: + return; +} + static void diag_memcg_dump_variant_buffer(void * data, unsigned int len) { unsigned long flags; @@ -225,6 +286,7 @@ static void diag_memcg_build_inode_stats(struct mem_cgroup *memcg, stats->cg_addr = (unsigned long)memcg; stats->dev = inode->i_sb->s_dev; inode_name(inode, stats->name, MEMCG_NAME_LEN); + mnt_dir(inode, stats->mnt_dir, MEMCG_NAME_LEN); stats->pages = 1; radix_tree_insert(inode_stats_tree, (unsigned long)inode, stats); } else @@ -389,6 +451,7 @@ static int lookup_syms(void) LOOKUP_SYMS(page_mapping); LOOKUP_SYMS(first_online_pgdat); LOOKUP_SYMS(next_online_pgdat); + LOOKUP_SYMS(mount_lock); return 0; } diff --git a/SOURCE/uapi/memcg_stats.h b/SOURCE/uapi/memcg_stats.h index c2509d7..d22e0c7 100644 --- a/SOURCE/uapi/memcg_stats.h +++ b/SOURCE/uapi/memcg_stats.h @@ -51,6 +51,7 @@ struct diag_memcg_stats_detail { unsigned int dev; unsigned int pages; char name[MEMCG_NAME_LEN]; + char mnt_dir[MEMCG_NAME_LEN]; }; #endif /* UAPI_MEMCG_STATS_H */ |
