aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ncpfs/mmap.c2
-rw-r--r--include/linux/memcontrol.h7
-rw-r--r--mm/filemap.c1
-rw-r--r--mm/memcontrol.c47
-rw-r--r--mm/memory.c2
-rw-r--r--mm/shmem.c11
6 files changed, 65 insertions, 5 deletions
diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c
index a7c07b44b100..e5d71b27a5b0 100644
--- a/fs/ncpfs/mmap.c
+++ b/fs/ncpfs/mmap.c
@@ -16,6 +16,7 @@
16#include <linux/mman.h> 16#include <linux/mman.h>
17#include <linux/string.h> 17#include <linux/string.h>
18#include <linux/fcntl.h> 18#include <linux/fcntl.h>
19#include <linux/memcontrol.h>
19 20
20#include <asm/uaccess.h> 21#include <asm/uaccess.h>
21#include <asm/system.h> 22#include <asm/system.h>
@@ -92,6 +93,7 @@ static int ncp_file_mmap_fault(struct vm_area_struct *area,
92 * -- wli 93 * -- wli
93 */ 94 */
94 count_vm_event(PGMAJFAULT); 95 count_vm_event(PGMAJFAULT);
96 mem_cgroup_count_vm_event(area->vm_mm, PGMAJFAULT);
95 return VM_FAULT_MAJOR; 97 return VM_FAULT_MAJOR;
96} 98}
97 99
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index ac1e5d20916a..9724a38ee69d 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -20,6 +20,8 @@
20#ifndef _LINUX_MEMCONTROL_H 20#ifndef _LINUX_MEMCONTROL_H
21#define _LINUX_MEMCONTROL_H 21#define _LINUX_MEMCONTROL_H
22#include <linux/cgroup.h> 22#include <linux/cgroup.h>
23#include <linux/vm_event_item.h>
24
23struct mem_cgroup; 25struct mem_cgroup;
24struct page_cgroup; 26struct page_cgroup;
25struct page; 27struct page;
@@ -149,6 +151,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
149 unsigned long *total_scanned); 151 unsigned long *total_scanned);
150u64 mem_cgroup_get_limit(struct mem_cgroup *mem); 152u64 mem_cgroup_get_limit(struct mem_cgroup *mem);
151 153
154void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx);
152#ifdef CONFIG_TRANSPARENT_HUGEPAGE 155#ifdef CONFIG_TRANSPARENT_HUGEPAGE
153void mem_cgroup_split_huge_fixup(struct page *head, struct page *tail); 156void mem_cgroup_split_huge_fixup(struct page *head, struct page *tail);
154#endif 157#endif
@@ -357,6 +360,10 @@ static inline void mem_cgroup_split_huge_fixup(struct page *head,
357{ 360{
358} 361}
359 362
363static inline
364void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx)
365{
366}
360#endif /* CONFIG_CGROUP_MEM_CONT */ 367#endif /* CONFIG_CGROUP_MEM_CONT */
361 368
362#if !defined(CONFIG_CGROUP_MEM_RES_CTLR) || !defined(CONFIG_DEBUG_VM) 369#if !defined(CONFIG_CGROUP_MEM_RES_CTLR) || !defined(CONFIG_DEBUG_VM)
diff --git a/mm/filemap.c b/mm/filemap.c
index 7455ccd8bda8..bcdc393b6580 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1661,6 +1661,7 @@ int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1661 /* No page in the page cache at all */ 1661 /* No page in the page cache at all */
1662 do_sync_mmap_readahead(vma, ra, file, offset); 1662 do_sync_mmap_readahead(vma, ra, file, offset);
1663 count_vm_event(PGMAJFAULT); 1663 count_vm_event(PGMAJFAULT);
1664 mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT);
1664 ret = VM_FAULT_MAJOR; 1665 ret = VM_FAULT_MAJOR;
1665retry_find: 1666retry_find:
1666 page = find_get_page(mapping, offset); 1667 page = find_get_page(mapping, offset);
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 4021fcd71b60..bd9052a5d3ad 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -94,6 +94,8 @@ enum mem_cgroup_events_index {
94 MEM_CGROUP_EVENTS_PGPGIN, /* # of pages paged in */ 94 MEM_CGROUP_EVENTS_PGPGIN, /* # of pages paged in */
95 MEM_CGROUP_EVENTS_PGPGOUT, /* # of pages paged out */ 95 MEM_CGROUP_EVENTS_PGPGOUT, /* # of pages paged out */
96 MEM_CGROUP_EVENTS_COUNT, /* # of pages paged in/out */ 96 MEM_CGROUP_EVENTS_COUNT, /* # of pages paged in/out */
97 MEM_CGROUP_EVENTS_PGFAULT, /* # of page-faults */
98 MEM_CGROUP_EVENTS_PGMAJFAULT, /* # of major page-faults */
97 MEM_CGROUP_EVENTS_NSTATS, 99 MEM_CGROUP_EVENTS_NSTATS,
98}; 100};
99/* 101/*
@@ -590,6 +592,16 @@ static void mem_cgroup_swap_statistics(struct mem_cgroup *mem,
590 this_cpu_add(mem->stat->count[MEM_CGROUP_STAT_SWAPOUT], val); 592 this_cpu_add(mem->stat->count[MEM_CGROUP_STAT_SWAPOUT], val);
591} 593}
592 594
595void mem_cgroup_pgfault(struct mem_cgroup *mem, int val)
596{
597 this_cpu_add(mem->stat->events[MEM_CGROUP_EVENTS_PGFAULT], val);
598}
599
600void mem_cgroup_pgmajfault(struct mem_cgroup *mem, int val)
601{
602 this_cpu_add(mem->stat->events[MEM_CGROUP_EVENTS_PGMAJFAULT], val);
603}
604
593static unsigned long mem_cgroup_read_events(struct mem_cgroup *mem, 605static unsigned long mem_cgroup_read_events(struct mem_cgroup *mem,
594 enum mem_cgroup_events_index idx) 606 enum mem_cgroup_events_index idx)
595{ 607{
@@ -827,6 +839,33 @@ static inline bool mem_cgroup_is_root(struct mem_cgroup *mem)
827 return (mem == root_mem_cgroup); 839 return (mem == root_mem_cgroup);
828} 840}
829 841
842void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx)
843{
844 struct mem_cgroup *mem;
845
846 if (!mm)
847 return;
848
849 rcu_read_lock();
850 mem = mem_cgroup_from_task(rcu_dereference(mm->owner));
851 if (unlikely(!mem))
852 goto out;
853
854 switch (idx) {
855 case PGMAJFAULT:
856 mem_cgroup_pgmajfault(mem, 1);
857 break;
858 case PGFAULT:
859 mem_cgroup_pgfault(mem, 1);
860 break;
861 default:
862 BUG();
863 }
864out:
865 rcu_read_unlock();
866}
867EXPORT_SYMBOL(mem_cgroup_count_vm_event);
868
830/* 869/*
831 * Following LRU functions are allowed to be used without PCG_LOCK. 870 * Following LRU functions are allowed to be used without PCG_LOCK.
832 * Operations are called by routine of global LRU independently from memcg. 871 * Operations are called by routine of global LRU independently from memcg.
@@ -3958,6 +3997,8 @@ enum {
3958 MCS_PGPGIN, 3997 MCS_PGPGIN,
3959 MCS_PGPGOUT, 3998 MCS_PGPGOUT,
3960 MCS_SWAP, 3999 MCS_SWAP,
4000 MCS_PGFAULT,
4001 MCS_PGMAJFAULT,
3961 MCS_INACTIVE_ANON, 4002 MCS_INACTIVE_ANON,
3962 MCS_ACTIVE_ANON, 4003 MCS_ACTIVE_ANON,
3963 MCS_INACTIVE_FILE, 4004 MCS_INACTIVE_FILE,
@@ -3980,6 +4021,8 @@ struct {
3980 {"pgpgin", "total_pgpgin"}, 4021 {"pgpgin", "total_pgpgin"},
3981 {"pgpgout", "total_pgpgout"}, 4022 {"pgpgout", "total_pgpgout"},
3982 {"swap", "total_swap"}, 4023 {"swap", "total_swap"},
4024 {"pgfault", "total_pgfault"},
4025 {"pgmajfault", "total_pgmajfault"},
3983 {"inactive_anon", "total_inactive_anon"}, 4026 {"inactive_anon", "total_inactive_anon"},
3984 {"active_anon", "total_active_anon"}, 4027 {"active_anon", "total_active_anon"},
3985 {"inactive_file", "total_inactive_file"}, 4028 {"inactive_file", "total_inactive_file"},
@@ -4008,6 +4051,10 @@ mem_cgroup_get_local_stat(struct mem_cgroup *mem, struct mcs_total_stat *s)
4008 val = mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_SWAPOUT); 4051 val = mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_SWAPOUT);
4009 s->stat[MCS_SWAP] += val * PAGE_SIZE; 4052 s->stat[MCS_SWAP] += val * PAGE_SIZE;
4010 } 4053 }
4054 val = mem_cgroup_read_events(mem, MEM_CGROUP_EVENTS_PGFAULT);
4055 s->stat[MCS_PGFAULT] += val;
4056 val = mem_cgroup_read_events(mem, MEM_CGROUP_EVENTS_PGMAJFAULT);
4057 s->stat[MCS_PGMAJFAULT] += val;
4011 4058
4012 /* per zone stat */ 4059 /* per zone stat */
4013 val = mem_cgroup_get_local_zonestat(mem, LRU_INACTIVE_ANON); 4060 val = mem_cgroup_get_local_zonestat(mem, LRU_INACTIVE_ANON);
diff --git a/mm/memory.c b/mm/memory.c
index fc24f7d788bd..6953d3926e01 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2874,6 +2874,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
2874 /* Had to read the page from swap area: Major fault */ 2874 /* Had to read the page from swap area: Major fault */
2875 ret = VM_FAULT_MAJOR; 2875 ret = VM_FAULT_MAJOR;
2876 count_vm_event(PGMAJFAULT); 2876 count_vm_event(PGMAJFAULT);
2877 mem_cgroup_count_vm_event(mm, PGMAJFAULT);
2877 } else if (PageHWPoison(page)) { 2878 } else if (PageHWPoison(page)) {
2878 /* 2879 /*
2879 * hwpoisoned dirty swapcache pages are kept for killing 2880 * hwpoisoned dirty swapcache pages are kept for killing
@@ -3413,6 +3414,7 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
3413 __set_current_state(TASK_RUNNING); 3414 __set_current_state(TASK_RUNNING);
3414 3415
3415 count_vm_event(PGFAULT); 3416 count_vm_event(PGFAULT);
3417 mem_cgroup_count_vm_event(mm, PGFAULT);
3416 3418
3417 /* do counter updates before entering really critical section. */ 3419 /* do counter updates before entering really critical section. */
3418 check_sync_rss_stat(current); 3420 check_sync_rss_stat(current);
diff --git a/mm/shmem.c b/mm/shmem.c
index 69edb45a9f28..1acfb2687bfa 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1305,12 +1305,10 @@ repeat:
1305 swappage = lookup_swap_cache(swap); 1305 swappage = lookup_swap_cache(swap);
1306 if (!swappage) { 1306 if (!swappage) {
1307 shmem_swp_unmap(entry); 1307 shmem_swp_unmap(entry);
1308 spin_unlock(&info->lock);
1308 /* here we actually do the io */ 1309 /* here we actually do the io */
1309 if (type && !(*type & VM_FAULT_MAJOR)) { 1310 if (type)
1310 __count_vm_event(PGMAJFAULT);
1311 *type |= VM_FAULT_MAJOR; 1311 *type |= VM_FAULT_MAJOR;
1312 }
1313 spin_unlock(&info->lock);
1314 swappage = shmem_swapin(swap, gfp, info, idx); 1312 swappage = shmem_swapin(swap, gfp, info, idx);
1315 if (!swappage) { 1313 if (!swappage) {
1316 spin_lock(&info->lock); 1314 spin_lock(&info->lock);
@@ -1549,7 +1547,10 @@ static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1549 error = shmem_getpage(inode, vmf->pgoff, &vmf->page, SGP_CACHE, &ret); 1547 error = shmem_getpage(inode, vmf->pgoff, &vmf->page, SGP_CACHE, &ret);
1550 if (error) 1548 if (error)
1551 return ((error == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS); 1549 return ((error == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS);
1552 1550 if (ret & VM_FAULT_MAJOR) {
1551 count_vm_event(PGMAJFAULT);
1552 mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT);
1553 }
1553 return ret | VM_FAULT_LOCKED; 1554 return ret | VM_FAULT_LOCKED;
1554} 1555}
1555 1556