[Devel] [PATCH RHEL7 COMMIT] ms/memcg: add page_cgroup_ino helper

Konstantin Khorenko khorenko at odin.com
Mon May 18 21:23:31 PDT 2015


The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.1
------>
commit 77c59afe2b55a1dd631c3b8a6d3763eff8d09941
Author: Vladimir Davydov <vdavydov at parallels.com>
Date:   Tue May 19 08:23:31 2015 +0400

    ms/memcg: add page_cgroup_ino helper
    
    Patchset description: idle memory tracking
    
    This patch set backports
    
      https://lkml.org/lkml/2015/5/12/449
    
    which is required by vcmmd.
    
    It is not yet clear if the original patch set will be accepted upstream
    as is, there still may be changes. However, I hope the user API will be
    preserved. If it is not, we will have to fix this in our kernel too.
    
    https://jira.sw.ru/browse/PSBM-32460
    
    Vladimir Davydov (3):
      memcg: add page_cgroup_ino helper
      proc: add kpagecgroup file
      proc: add kpageidle file
    
    ===================================================
    This patch description:
    
    Hwpoison allows to filter pages by memory cgroup ino. To ahieve that, it
    calls try_get_mem_cgroup_from_page(), then mem_cgroup_css(), and finally
    extracts the inode number from the cgroup returned. This looks bulky.
    Since in the next patch I need to get the ino of the memory cgroup a
    page is charged to too, in this patch I introduce the page_cgroup_ino()
    helper.
    
    Note that page_cgroup_ino() only considers those pages that are charged
    to mem_cgroup->res (i.e. page_cgroup->mem_cgroup != NULL), and for
    others it returns 0, while try_get_mem_cgroup_page(), used by hwpoison
    before, may extract the cgroup from a swapcache readahead page too.
    Ignoring swapcache readahead pages allows to call page_cgroup_ino() on
    unlocked pages, which is nice. Hwpoison users will hardly see any
    difference.
    
    Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
---
 include/linux/memcontrol.h |  3 +++
 mm/hwpoison-inject.c       |  3 ---
 mm/memcontrol.c            | 22 ++++++++++++++++++++++
 mm/memory-failure.c        | 18 +-----------------
 4 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 675b4c5..5507be5 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -200,6 +200,9 @@ void mem_cgroup_split_huge_fixup(struct page *head);
 bool mem_cgroup_bad_page_check(struct page *page);
 void mem_cgroup_print_bad_page(struct page *page);
 #endif
+
+unsigned long page_cgroup_ino(struct page *page);
+
 #else /* CONFIG_MEMCG */
 struct mem_cgroup;
 
diff --git a/mm/hwpoison-inject.c b/mm/hwpoison-inject.c
index 3a61efc..bd580f8 100644
--- a/mm/hwpoison-inject.c
+++ b/mm/hwpoison-inject.c
@@ -44,12 +44,9 @@ static int hwpoison_inject(void *data, u64 val)
 	/*
 	 * do a racy check with elevated page count, to make sure PG_hwpoison
 	 * will only be set for the targeted owner (or on a free page).
-	 * We temporarily take page lock for try_get_mem_cgroup_from_page().
 	 * memory_failure() will redo the check reliably inside page lock.
 	 */
-	lock_page(hpage);
 	err = hwpoison_filter(hpage);
-	unlock_page(hpage);
 	if (err)
 		return 0;
 
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index e772a06..9dda309 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2877,6 +2877,28 @@ struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page)
 	return memcg;
 }
 
+/**
+ * page_cgroup_ino - return inode number of page's memcg
+ * @page: the page
+ *
+ * Look up the memory cgroup @page is charged to and return its inode number.
+ * It is safe to call this function without taking a reference to the page.
+ */
+unsigned long page_cgroup_ino(struct page *page)
+{
+	struct mem_cgroup *memcg;
+	struct page_cgroup *pc;
+	unsigned long ino = 0;
+
+	pc = lookup_page_cgroup(page);
+	lock_page_cgroup(pc);
+	memcg = pc->mem_cgroup;
+	if (PageCgroupUsed(pc) && memcg)
+		ino = memcg->css.cgroup->dentry->d_inode->i_ino;
+	unlock_page_cgroup(pc);
+	return ino;
+}
+
 static void __mem_cgroup_commit_charge(struct mem_cgroup *memcg,
 				       struct page *page,
 				       unsigned int nr_pages,
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 06f8d308..b3b1a2d 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -133,26 +133,10 @@ u64 hwpoison_filter_memcg;
 EXPORT_SYMBOL_GPL(hwpoison_filter_memcg);
 static int hwpoison_filter_task(struct page *p)
 {
-	struct mem_cgroup *mem;
-	struct cgroup_subsys_state *css;
-	unsigned long ino;
-
 	if (!hwpoison_filter_memcg)
 		return 0;
 
-	mem = try_get_mem_cgroup_from_page(p);
-	if (!mem)
-		return -EINVAL;
-
-	css = mem_cgroup_css(mem);
-	/* root_mem_cgroup has NULL dentries */
-	if (!css->cgroup->dentry)
-		return -EINVAL;
-
-	ino = css->cgroup->dentry->d_inode->i_ino;
-	css_put(css);
-
-	if (ino != hwpoison_filter_memcg)
+	if (page_cgroup_ino(p) != hwpoison_filter_memcg)
 		return -EINVAL;
 
 	return 0;



More information about the Devel mailing list