diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2011-11-22 17:08:10 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2011-11-23 15:03:38 -0500 |
commit | bb58dd5d1ffad6c2d21c69698ba766dad4ae54e6 (patch) | |
tree | aedde5149df5e3eb8c217b90540222ee507d5e9e | |
parent | f10cdea68b70bd85706baed0decab59618f9c353 (diff) |
PM / Hibernate: Do not leak memory in error/test code paths
The hibernation core code forgets to release memory preallocated
for hibernation if there's an error in its early stages or if test
modes causing hibernation_snapshot() to return early are used. This
causes the system to be hardly usable, because the amount of
preallocated memory is usually huge. Fix this problem.
Reported-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
-rw-r--r-- | kernel/power/hibernate.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 196c01268eb..a6b0503574e 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c | |||
@@ -347,7 +347,7 @@ int hibernation_snapshot(int platform_mode) | |||
347 | 347 | ||
348 | error = freeze_kernel_threads(); | 348 | error = freeze_kernel_threads(); |
349 | if (error) | 349 | if (error) |
350 | goto Close; | 350 | goto Cleanup; |
351 | 351 | ||
352 | if (hibernation_test(TEST_FREEZER) || | 352 | if (hibernation_test(TEST_FREEZER) || |
353 | hibernation_testmode(HIBERNATION_TESTPROC)) { | 353 | hibernation_testmode(HIBERNATION_TESTPROC)) { |
@@ -357,12 +357,14 @@ int hibernation_snapshot(int platform_mode) | |||
357 | * successful freezer test. | 357 | * successful freezer test. |
358 | */ | 358 | */ |
359 | freezer_test_done = true; | 359 | freezer_test_done = true; |
360 | goto Close; | 360 | goto Cleanup; |
361 | } | 361 | } |
362 | 362 | ||
363 | error = dpm_prepare(PMSG_FREEZE); | 363 | error = dpm_prepare(PMSG_FREEZE); |
364 | if (error) | 364 | if (error) { |
365 | goto Complete_devices; | 365 | dpm_complete(msg); |
366 | goto Cleanup; | ||
367 | } | ||
366 | 368 | ||
367 | suspend_console(); | 369 | suspend_console(); |
368 | pm_restrict_gfp_mask(); | 370 | pm_restrict_gfp_mask(); |
@@ -391,8 +393,6 @@ int hibernation_snapshot(int platform_mode) | |||
391 | pm_restore_gfp_mask(); | 393 | pm_restore_gfp_mask(); |
392 | 394 | ||
393 | resume_console(); | 395 | resume_console(); |
394 | |||
395 | Complete_devices: | ||
396 | dpm_complete(msg); | 396 | dpm_complete(msg); |
397 | 397 | ||
398 | Close: | 398 | Close: |
@@ -402,6 +402,10 @@ int hibernation_snapshot(int platform_mode) | |||
402 | Recover_platform: | 402 | Recover_platform: |
403 | platform_recover(platform_mode); | 403 | platform_recover(platform_mode); |
404 | goto Resume_devices; | 404 | goto Resume_devices; |
405 | |||
406 | Cleanup: | ||
407 | swsusp_free(); | ||
408 | goto Close; | ||
405 | } | 409 | } |
406 | 410 | ||
407 | /** | 411 | /** |