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; |
