diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2006-09-26 02:32:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-26 11:48:59 -0400 |
commit | f6143aa60ed71e58578bc92cc64d98158a694d99 (patch) | |
tree | aa3ccc4327ecf950abb15800e3d008cde6dc26f3 /kernel/power | |
parent | f623f0db8e6aa86a37be86167e4ff478821a9f4f (diff) |
[PATCH] swsusp: Reorder memory-allocating functions
Move some functions in kernel/power/snapshot.c to a better place (in the
same file) and introduce free_image_page() (will be necessary in the
future).
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/power')
-rw-r--r-- | kernel/power/snapshot.c | 93 |
1 files changed, 53 insertions, 40 deletions
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 4afb7900002b..7ad0c0465524 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
@@ -156,6 +156,58 @@ static inline int save_highmem(void) {return 0;} | |||
156 | static inline int restore_highmem(void) {return 0;} | 156 | static inline int restore_highmem(void) {return 0;} |
157 | #endif | 157 | #endif |
158 | 158 | ||
159 | /** | ||
160 | * @safe_needed - on resume, for storing the PBE list and the image, | ||
161 | * we can only use memory pages that do not conflict with the pages | ||
162 | * used before suspend. | ||
163 | * | ||
164 | * The unsafe pages are marked with the PG_nosave_free flag | ||
165 | * and we count them using unsafe_pages | ||
166 | */ | ||
167 | |||
168 | static unsigned int unsafe_pages; | ||
169 | |||
170 | static void *alloc_image_page(gfp_t gfp_mask, int safe_needed) | ||
171 | { | ||
172 | void *res; | ||
173 | |||
174 | res = (void *)get_zeroed_page(gfp_mask); | ||
175 | if (safe_needed) | ||
176 | while (res && PageNosaveFree(virt_to_page(res))) { | ||
177 | /* The page is unsafe, mark it for swsusp_free() */ | ||
178 | SetPageNosave(virt_to_page(res)); | ||
179 | unsafe_pages++; | ||
180 | res = (void *)get_zeroed_page(gfp_mask); | ||
181 | } | ||
182 | if (res) { | ||
183 | SetPageNosave(virt_to_page(res)); | ||
184 | SetPageNosaveFree(virt_to_page(res)); | ||
185 | } | ||
186 | return res; | ||
187 | } | ||
188 | |||
189 | unsigned long get_safe_page(gfp_t gfp_mask) | ||
190 | { | ||
191 | return (unsigned long)alloc_image_page(gfp_mask, 1); | ||
192 | } | ||
193 | |||
194 | /** | ||
195 | * free_image_page - free page represented by @addr, allocated with | ||
196 | * alloc_image_page (page flags set by it must be cleared) | ||
197 | */ | ||
198 | |||
199 | static inline void free_image_page(void *addr, int clear_nosave_free) | ||
200 | { | ||
201 | ClearPageNosave(virt_to_page(addr)); | ||
202 | if (clear_nosave_free) | ||
203 | ClearPageNosaveFree(virt_to_page(addr)); | ||
204 | free_page((unsigned long)addr); | ||
205 | } | ||
206 | |||
207 | /** | ||
208 | * pfn_is_nosave - check if given pfn is in the 'nosave' section | ||
209 | */ | ||
210 | |||
159 | static inline int pfn_is_nosave(unsigned long pfn) | 211 | static inline int pfn_is_nosave(unsigned long pfn) |
160 | { | 212 | { |
161 | unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT; | 213 | unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT; |
@@ -245,7 +297,6 @@ static void copy_data_pages(struct pbe *pblist) | |||
245 | BUG_ON(pbe); | 297 | BUG_ON(pbe); |
246 | } | 298 | } |
247 | 299 | ||
248 | |||
249 | /** | 300 | /** |
250 | * free_pagedir - free pages allocated with alloc_pagedir() | 301 | * free_pagedir - free pages allocated with alloc_pagedir() |
251 | */ | 302 | */ |
@@ -256,10 +307,7 @@ static void free_pagedir(struct pbe *pblist, int clear_nosave_free) | |||
256 | 307 | ||
257 | while (pblist) { | 308 | while (pblist) { |
258 | pbe = (pblist + PB_PAGE_SKIP)->next; | 309 | pbe = (pblist + PB_PAGE_SKIP)->next; |
259 | ClearPageNosave(virt_to_page(pblist)); | 310 | free_image_page(pblist, clear_nosave_free); |
260 | if (clear_nosave_free) | ||
261 | ClearPageNosaveFree(virt_to_page(pblist)); | ||
262 | free_page((unsigned long)pblist); | ||
263 | pblist = pbe; | 311 | pblist = pbe; |
264 | } | 312 | } |
265 | } | 313 | } |
@@ -303,41 +351,6 @@ static inline void create_pbe_list(struct pbe *pblist, unsigned int nr_pages) | |||
303 | } | 351 | } |
304 | } | 352 | } |
305 | 353 | ||
306 | static unsigned int unsafe_pages; | ||
307 | |||
308 | /** | ||
309 | * @safe_needed - on resume, for storing the PBE list and the image, | ||
310 | * we can only use memory pages that do not conflict with the pages | ||
311 | * used before suspend. | ||
312 | * | ||
313 | * The unsafe pages are marked with the PG_nosave_free flag | ||
314 | * and we count them using unsafe_pages | ||
315 | */ | ||
316 | |||
317 | static void *alloc_image_page(gfp_t gfp_mask, int safe_needed) | ||
318 | { | ||
319 | void *res; | ||
320 | |||
321 | res = (void *)get_zeroed_page(gfp_mask); | ||
322 | if (safe_needed) | ||
323 | while (res && PageNosaveFree(virt_to_page(res))) { | ||
324 | /* The page is unsafe, mark it for swsusp_free() */ | ||
325 | SetPageNosave(virt_to_page(res)); | ||
326 | unsafe_pages++; | ||
327 | res = (void *)get_zeroed_page(gfp_mask); | ||
328 | } | ||
329 | if (res) { | ||
330 | SetPageNosave(virt_to_page(res)); | ||
331 | SetPageNosaveFree(virt_to_page(res)); | ||
332 | } | ||
333 | return res; | ||
334 | } | ||
335 | |||
336 | unsigned long get_safe_page(gfp_t gfp_mask) | ||
337 | { | ||
338 | return (unsigned long)alloc_image_page(gfp_mask, 1); | ||
339 | } | ||
340 | |||
341 | /** | 354 | /** |
342 | * alloc_pagedir - Allocate the page directory. | 355 | * alloc_pagedir - Allocate the page directory. |
343 | * | 356 | * |