OSDN Git Service

mm: memcontrol: fix missed end-writeback page accounting
[uclinux-h8/linux.git] / mm / rmap.c
index 116a505..f574046 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1042,15 +1042,16 @@ void page_add_new_anon_rmap(struct page *page,
  */
 void page_add_file_rmap(struct page *page)
 {
-       bool locked;
+       struct mem_cgroup *memcg;
        unsigned long flags;
+       bool locked;
 
-       mem_cgroup_begin_update_page_stat(page, &locked, &flags);
+       memcg = mem_cgroup_begin_page_stat(page, &locked, &flags);
        if (atomic_inc_and_test(&page->_mapcount)) {
                __inc_zone_page_state(page, NR_FILE_MAPPED);
-               mem_cgroup_inc_page_stat(page, MEM_CGROUP_STAT_FILE_MAPPED);
+               mem_cgroup_inc_page_stat(memcg, MEM_CGROUP_STAT_FILE_MAPPED);
        }
-       mem_cgroup_end_update_page_stat(page, &locked, &flags);
+       mem_cgroup_end_page_stat(memcg, locked, flags);
 }
 
 /**
@@ -1061,9 +1062,10 @@ void page_add_file_rmap(struct page *page)
  */
 void page_remove_rmap(struct page *page)
 {
+       struct mem_cgroup *uninitialized_var(memcg);
        bool anon = PageAnon(page);
-       bool locked;
        unsigned long flags;
+       bool locked;
 
        /*
         * The anon case has no mem_cgroup page_stat to update; but may
@@ -1071,7 +1073,7 @@ void page_remove_rmap(struct page *page)
         * we hold the lock against page_stat move: so avoid it on anon.
         */
        if (!anon)
-               mem_cgroup_begin_update_page_stat(page, &locked, &flags);
+               memcg = mem_cgroup_begin_page_stat(page, &locked, &flags);
 
        /* page still mapped by someone else? */
        if (!atomic_add_negative(-1, &page->_mapcount))
@@ -1096,8 +1098,7 @@ void page_remove_rmap(struct page *page)
                                -hpage_nr_pages(page));
        } else {
                __dec_zone_page_state(page, NR_FILE_MAPPED);
-               mem_cgroup_dec_page_stat(page, MEM_CGROUP_STAT_FILE_MAPPED);
-               mem_cgroup_end_update_page_stat(page, &locked, &flags);
+               mem_cgroup_dec_page_stat(memcg, MEM_CGROUP_STAT_FILE_MAPPED);
        }
        if (unlikely(PageMlocked(page)))
                clear_page_mlock(page);
@@ -1110,10 +1111,9 @@ void page_remove_rmap(struct page *page)
         * Leaving it set also helps swapoff to reinstate ptes
         * faster for those pages still in swapcache.
         */
-       return;
 out:
        if (!anon)
-               mem_cgroup_end_update_page_stat(page, &locked, &flags);
+               mem_cgroup_end_page_stat(memcg, locked, flags);
 }
 
 /*