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 | |
| 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')
| -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 | * |
