[Devel] [PATCH RHEL8 COMMIT] mm: per-memcg negative dentries accounting
Konstantin Khorenko
khorenko at virtuozzo.com
Wed Jun 23 18:47:50 MSK 2021
The commit is pushed to "branch-rh8-4.18.0-240.1.1.vz8.5.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-240.1.1.vz8.5.48
------>
commit 24375477ca10dd08c0663b56dccd1383852cdd76
Author: Vasily Averin <vvs at virtuozzo.com>
Date: Wed Jun 23 14:07:06 2021 +0300
mm: per-memcg negative dentries accounting
This patch adds per-memcg negative dentries accounting
and makes them visible in userspace via memcg statistic
https://jira.sw.ru/browse/PSBM-104223
https://bugs.openvz.org/browse/OVZ-7225
Signed-off-by: Vasily Averin <vvs at virtuozzo.com>
(cherry-picked from vz7 commit ("8d980b969c46 per-memcg negative dentries
accounting"))
conflicts:
- mem_cgroup_from_kmem changed to mem_cgroup_from_obj
- memcg->stat changed to memcg->vmstats_percpu
https://jira.sw.ru/browse/PSBM-127858
Signed-off-by: Valeriy Vdovin <valeriy.vdovin at virtuozzo.com>
+++
mm: memory.stat format fix "negative dentries"
mFixes: 8d980b969c46d ("per-memcg negative dentries accounting")
https://jira.sw.ru/browse/PSBM-125735
Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn at virtuozzo.com>
(cherry-picked from c59eb09a181a666cdf9d6e71ead567ba1f4eda20)
https://jira.sw.ru/browse/PSBM-127858
Signed-off-by: Valeriy Vdovin <valeriy.vdovin at virtuozzo.com>
---
fs/dcache.c | 21 ++++++++++++++++-----
include/linux/memcontrol.h | 4 ++++
mm/memcontrol.c | 35 +++++++++++++++++++++++++++++++++++
3 files changed, 55 insertions(+), 5 deletions(-)
diff --git a/fs/dcache.c b/fs/dcache.c
index 44e3f102baab..dda99aaccaf5 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -30,6 +30,7 @@
#include <linux/bit_spinlock.h>
#include <linux/rculist_bl.h>
#include <linux/list_lru.h>
+#include <linux/memcontrol.h>
#include "internal.h"
#include "mount.h"
@@ -399,8 +400,10 @@ static void d_lru_add(struct dentry *dentry)
D_FLAG_VERIFY(dentry, 0);
dentry->d_flags |= DCACHE_LRU_LIST;
this_cpu_inc(nr_dentry_unused);
- if (d_is_negative(dentry))
+ if (d_is_negative(dentry)) {
this_cpu_inc(nr_dentry_negative);
+ memcg_neg_dentry_inc(dentry);
+ }
WARN_ON_ONCE(!list_lru_add(&dentry->d_sb->s_dentry_lru, &dentry->d_lru));
}
@@ -409,8 +412,10 @@ static void d_lru_del(struct dentry *dentry)
D_FLAG_VERIFY(dentry, DCACHE_LRU_LIST);
dentry->d_flags &= ~DCACHE_LRU_LIST;
this_cpu_dec(nr_dentry_unused);
- if (d_is_negative(dentry))
+ if (d_is_negative(dentry)) {
this_cpu_dec(nr_dentry_negative);
+ memcg_neg_dentry_dec(dentry);
+ }
WARN_ON_ONCE(!list_lru_del(&dentry->d_sb->s_dentry_lru, &dentry->d_lru));
}
@@ -441,8 +446,10 @@ static void d_lru_isolate(struct list_lru_one *lru, struct dentry *dentry)
D_FLAG_VERIFY(dentry, DCACHE_LRU_LIST);
dentry->d_flags &= ~DCACHE_LRU_LIST;
this_cpu_dec(nr_dentry_unused);
- if (d_is_negative(dentry))
+ if (d_is_negative(dentry)) {
this_cpu_dec(nr_dentry_negative);
+ memcg_neg_dentry_dec(dentry);
+ }
list_lru_isolate(lru, &dentry->d_lru);
}
@@ -451,8 +458,10 @@ static void d_lru_shrink_move(struct list_lru_one *lru, struct dentry *dentry,
{
D_FLAG_VERIFY(dentry, DCACHE_LRU_LIST);
dentry->d_flags |= DCACHE_SHRINK_LIST;
- if (d_is_negative(dentry))
+ if (d_is_negative(dentry)) {
this_cpu_dec(nr_dentry_negative);
+ memcg_neg_dentry_dec(dentry);
+ }
list_lru_isolate_move(lru, &dentry->d_lru, list);
}
@@ -1848,8 +1857,10 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode)
/*
* Decrement negative dentry count if it was in the LRU list.
*/
- if (dentry->d_flags & DCACHE_LRU_LIST)
+ if (dentry->d_flags & DCACHE_LRU_LIST) {
this_cpu_dec(nr_dentry_negative);
+ memcg_neg_dentry_dec(dentry);
+ }
hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry);
raw_write_seqcount_begin(&dentry->d_seq);
__d_set_inode_and_type(dentry, inode, add_flags);
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index c3dc019d2d20..0154df93ae68 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -109,6 +109,7 @@ struct RH_KABI_RENAME(mem_cgroup_stat_cpu, memcg_vmstats_percpu) {
unsigned long events[NR_VM_EVENT_ITEMS];
unsigned long nr_page_events;
unsigned long targets[MEM_CGROUP_NTARGETS];
+ unsigned long nr_dentry_neg;
};
struct mem_cgroup_reclaim_iter {
@@ -878,6 +879,9 @@ static inline void memcg_memory_event_mm(struct mm_struct *mm,
void mem_cgroup_split_huge_fixup(struct page *head);
#endif
+void memcg_neg_dentry_inc(struct dentry *dentry);
+void memcg_neg_dentry_dec(struct dentry *dentry);
+
void mem_cgroup_fill_meminfo(struct mem_cgroup *memcg, struct meminfo *mi);
void mem_cgroup_fill_vmstat(struct mem_cgroup *memcg, unsigned long *stats);
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 4958d2a6aad7..f78e3b669cde 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -995,6 +995,40 @@ struct mem_cgroup *get_mem_cgroup_from_page(struct page *page)
}
EXPORT_SYMBOL(get_mem_cgroup_from_page);
+static inline unsigned long
+mem_cgroup_read_nd(struct mem_cgroup *memcg)
+{
+ long val = 0;
+ int cpu;
+
+ /* Per-cpu values can be negative, use a signed accumulator */
+ for_each_possible_cpu(cpu)
+ val += per_cpu(memcg->vmstats_percpu->nr_dentry_neg, cpu);
+ /*
+ * Summing races with updates, so val may be negative. Avoid exposing
+ * transient negative values.
+ */
+ if (val < 0)
+ val = 0;
+ return val;
+}
+
+void memcg_neg_dentry_inc(struct dentry *dentry)
+{
+ struct mem_cgroup *memcg = mem_cgroup_from_obj(dentry);
+
+ if (memcg)
+ __this_cpu_inc(memcg->vmstats_percpu->nr_dentry_neg);
+}
+
+void memcg_neg_dentry_dec(struct dentry *dentry)
+{
+ struct mem_cgroup *memcg = mem_cgroup_from_obj(dentry);
+
+ if (memcg)
+ __this_cpu_dec(memcg->vmstats_percpu->nr_dentry_neg);
+}
+
/**
* If current->active_memcg is non-NULL, do not fallback to current->mm->memcg.
*/
@@ -4340,6 +4374,7 @@ static int memcg_stat_show(struct seq_file *m, void *v)
else
seq_printf(m, "oom %lu\n",
atomic_long_read(&memcg->memory_events[MEMCG_OOM]));
+ seq_printf(m, "negative_dentries %lu\n", mem_cgroup_read_nd(memcg));
for (i = 0; i < NR_LRU_LISTS; i++)
seq_printf(m, "%s %lu\n", lru_list_name(i),
More information about the Devel
mailing list