diff options
-rw-r--r-- | fs/ncpfs/mmap.c | 2 | ||||
-rw-r--r-- | include/linux/memcontrol.h | 7 | ||||
-rw-r--r-- | mm/filemap.c | 1 | ||||
-rw-r--r-- | mm/memcontrol.c | 47 | ||||
-rw-r--r-- | mm/memory.c | 2 | ||||
-rw-r--r-- | mm/shmem.c | 11 |
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 | |||
23 | struct mem_cgroup; | 25 | struct mem_cgroup; |
24 | struct page_cgroup; | 26 | struct page_cgroup; |
25 | struct page; | 27 | struct 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); |
150 | u64 mem_cgroup_get_limit(struct mem_cgroup *mem); | 152 | u64 mem_cgroup_get_limit(struct mem_cgroup *mem); |
151 | 153 | ||
154 | void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx); | ||
152 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 155 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
153 | void mem_cgroup_split_huge_fixup(struct page *head, struct page *tail); | 156 | void 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 | ||
363 | static inline | ||
364 | void 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; |
1665 | retry_find: | 1666 | retry_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 | ||
595 | void mem_cgroup_pgfault(struct mem_cgroup *mem, int val) | ||
596 | { | ||
597 | this_cpu_add(mem->stat->events[MEM_CGROUP_EVENTS_PGFAULT], val); | ||
598 | } | ||
599 | |||
600 | void mem_cgroup_pgmajfault(struct mem_cgroup *mem, int val) | ||
601 | { | ||
602 | this_cpu_add(mem->stat->events[MEM_CGROUP_EVENTS_PGMAJFAULT], val); | ||
603 | } | ||
604 | |||
593 | static unsigned long mem_cgroup_read_events(struct mem_cgroup *mem, | 605 | static 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 | ||
842 | void 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 | } | ||
864 | out: | ||
865 | rcu_read_unlock(); | ||
866 | } | ||
867 | EXPORT_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 | ||