[PATCH v2 19/20] mm/mshare: get memcg from current->mm instead of mshare mm

Anthony Yznaga posted 20 patches 10 months, 1 week ago
There is a newer version of this series
[PATCH v2 19/20] mm/mshare: get memcg from current->mm instead of mshare mm
Posted by Anthony Yznaga 10 months, 1 week ago
Because handle_mm_fault() may operate on a vma from an mshare host mm,
the mm passed to cgroup functions count_memcg_event_mm() and
get_mem_cgroup_from_mm() may be an mshare host mm. These functions find
a memcg by dereferencing mm->owner which is set when an mm is allocated.
Since the task that created an mshare file may exit before the file is
deleted, use current->mm instead to find the memcg to update or charge
to.
This may not be the right solution but is hopefully a good starting
point. If charging should always go to a single memcg associated with
the mshare file, perhaps active_memcg could be used.

Signed-off-by: Anthony Yznaga <anthony.yznaga@oracle.com>
---
 include/linux/memcontrol.h | 3 +++
 mm/memcontrol.c            | 3 ++-
 mm/mshare.c                | 3 +++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 53364526d877..0d7a8787c876 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -983,6 +983,9 @@ static inline void count_memcg_events_mm(struct mm_struct *mm,
 	if (mem_cgroup_disabled())
 		return;
 
+	if (test_bit(MMF_MSHARE, &mm->flags))
+		mm = current->mm;
+
 	rcu_read_lock();
 	memcg = mem_cgroup_from_task(rcu_dereference(mm->owner));
 	if (likely(memcg))
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index c96c1f2b9cf5..42465e523caa 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -945,7 +945,8 @@ struct mem_cgroup *get_mem_cgroup_from_mm(struct mm_struct *mm)
 		mm = current->mm;
 		if (unlikely(!mm))
 			return root_mem_cgroup;
-	}
+	} else if (test_bit(MMF_MSHARE, &mm->flags))
+		mm = current->mm;
 
 	rcu_read_lock();
 	do {
diff --git a/mm/mshare.c b/mm/mshare.c
index 0a75bd3928fc..276fb825cc9a 100644
--- a/mm/mshare.c
+++ b/mm/mshare.c
@@ -432,6 +432,9 @@ msharefs_fill_mm(struct inode *inode)
 	if (ret)
 		goto err_free;
 
+#ifdef CONFIG_MEMCG
+	mm->owner = NULL;
+#endif
 	return 0;
 
 err_free:
-- 
2.43.5