diff options
author | Balbir Singh <balbir@linux.vnet.ibm.com> | 2008-02-07 03:14:02 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-07 11:42:19 -0500 |
commit | e1a1cd590e3fcb0d2e230128daf2337ea55387dc (patch) | |
tree | eb660ab340c657a1eb595b2d4d8e8b62783bf6fb /include/linux | |
parent | bed7161a519a2faef53e1bce1b47595e297c1d14 (diff) |
Memory controller: make charging gfp mask aware
Nick Piggin pointed out that swap cache and page cache addition routines
could be called from non GFP_KERNEL contexts. This patch makes the
charging routine aware of the gfp context. Charging might fail if the
cgroup is over it's limit, in which case a suitable error is returned.
This patch was tested on a Powerpc box. I am still looking at being able
to test the path, through which allocations happen in non GFP_KERNEL
contexts.
[kamezawa.hiroyu@jp.fujitsu.com: problem with ZONE_MOVABLE]
Signed-off-by: Balbir Singh <balbir@linux.vnet.ibm.com>
Cc: Pavel Emelianov <xemul@openvz.org>
Cc: Paul Menage <menage@google.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Cc: Kirill Korotaev <dev@sw.ru>
Cc: Herbert Poetzl <herbert@13thfloor.at>
Cc: David Rientjes <rientjes@google.com>
Cc: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/memcontrol.h | 12 | ||||
-rw-r--r-- | include/linux/swap.h | 3 |
2 files changed, 10 insertions, 5 deletions
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 9d0a830423b6..cc0ad7191acd 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h | |||
@@ -32,7 +32,8 @@ extern void mm_free_cgroup(struct mm_struct *mm); | |||
32 | extern void page_assign_page_cgroup(struct page *page, | 32 | extern void page_assign_page_cgroup(struct page *page, |
33 | struct page_cgroup *pc); | 33 | struct page_cgroup *pc); |
34 | extern struct page_cgroup *page_get_page_cgroup(struct page *page); | 34 | extern struct page_cgroup *page_get_page_cgroup(struct page *page); |
35 | extern int mem_cgroup_charge(struct page *page, struct mm_struct *mm); | 35 | extern int mem_cgroup_charge(struct page *page, struct mm_struct *mm, |
36 | gfp_t gfp_mask); | ||
36 | extern void mem_cgroup_uncharge(struct page_cgroup *pc); | 37 | extern void mem_cgroup_uncharge(struct page_cgroup *pc); |
37 | extern void mem_cgroup_move_lists(struct page_cgroup *pc, bool active); | 38 | extern void mem_cgroup_move_lists(struct page_cgroup *pc, bool active); |
38 | extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, | 39 | extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, |
@@ -42,7 +43,8 @@ extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, | |||
42 | struct mem_cgroup *mem_cont, | 43 | struct mem_cgroup *mem_cont, |
43 | int active); | 44 | int active); |
44 | extern void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask); | 45 | extern void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask); |
45 | extern int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm); | 46 | extern int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm, |
47 | gfp_t gfp_mask); | ||
46 | extern struct mem_cgroup *mm_cgroup(struct mm_struct *mm); | 48 | extern struct mem_cgroup *mm_cgroup(struct mm_struct *mm); |
47 | 49 | ||
48 | static inline void mem_cgroup_uncharge_page(struct page *page) | 50 | static inline void mem_cgroup_uncharge_page(struct page *page) |
@@ -70,7 +72,8 @@ static inline struct page_cgroup *page_get_page_cgroup(struct page *page) | |||
70 | return NULL; | 72 | return NULL; |
71 | } | 73 | } |
72 | 74 | ||
73 | static inline int mem_cgroup_charge(struct page *page, struct mm_struct *mm) | 75 | static inline int mem_cgroup_charge(struct page *page, struct mm_struct *mm, |
76 | gfp_t gfp_mask) | ||
74 | { | 77 | { |
75 | return 0; | 78 | return 0; |
76 | } | 79 | } |
@@ -89,7 +92,8 @@ static inline void mem_cgroup_move_lists(struct page_cgroup *pc, | |||
89 | } | 92 | } |
90 | 93 | ||
91 | static inline int mem_cgroup_cache_charge(struct page *page, | 94 | static inline int mem_cgroup_cache_charge(struct page *page, |
92 | struct mm_struct *mm) | 95 | struct mm_struct *mm, |
96 | gfp_t gfp_mask) | ||
93 | { | 97 | { |
94 | return 0; | 98 | return 0; |
95 | } | 99 | } |
diff --git a/include/linux/swap.h b/include/linux/swap.h index 4d91bc0e0fd5..3ca5c4bd6d3f 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h | |||
@@ -183,7 +183,8 @@ extern void swap_setup(void); | |||
183 | /* linux/mm/vmscan.c */ | 183 | /* linux/mm/vmscan.c */ |
184 | extern unsigned long try_to_free_pages(struct zone **zones, int order, | 184 | extern unsigned long try_to_free_pages(struct zone **zones, int order, |
185 | gfp_t gfp_mask); | 185 | gfp_t gfp_mask); |
186 | extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem); | 186 | extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem, |
187 | gfp_t gfp_mask); | ||
187 | extern int __isolate_lru_page(struct page *page, int mode); | 188 | extern int __isolate_lru_page(struct page *page, int mode); |
188 | extern unsigned long shrink_all_memory(unsigned long nr_pages); | 189 | extern unsigned long shrink_all_memory(unsigned long nr_pages); |
189 | extern int vm_swappiness; | 190 | extern int vm_swappiness; |