From: Nigel Cunningham <nigel@suspend2.net>
To: linux-kernel@vger.kernel.org
Subject: [Suspend2][ 18/20] [Suspend2] Free up memory if necessary.
Date: Tue, 27 Jun 2006 08:35:48 +1000 [thread overview]
Message-ID: <20060626223547.4050.40672.stgit@nigel.suspend2.net> (raw)
In-Reply-To: <20060626223446.4050.9897.stgit@nigel.suspend2.net>
Seek to ensure memory constraints are met. If we need to free memory, we
thaw kernel space processes only, so that we won't deadlock with the swap
and filesystem code. We then call shrink_all_memory until the constraints
are met or we determine that we're not getting anywhere. We may also bail
immediately if the user has said they don't want any memory to be freed.
Kernel space is re-frozen before we exit.
Signed-off-by: Nigel Cunningham <nigel@suspend2.net>
kernel/power/prepare_image.c | 94 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 94 insertions(+), 0 deletions(-)
diff --git a/kernel/power/prepare_image.c b/kernel/power/prepare_image.c
index 054d0d4..893ba72 100644
--- a/kernel/power/prepare_image.c
+++ b/kernel/power/prepare_image.c
@@ -528,3 +528,97 @@ long ram_to_suspend(void)
MIN_FREE_RAM + suspend_memory_for_modules());
}
+/* eat_memory
+ *
+ * Try to free some memory, either to meet hard or soft constraints on the image
+ * characteristics.
+ *
+ * Hard constraints:
+ * - Pageset1 must be < half of memory;
+ * - We must have enough memory free at resume time to have pageset1
+ * be able to be loaded in pages that don't conflict with where it has to
+ * be restored.
+ * Soft constraints
+ * - User specificied image size limit.
+ */
+static int eat_memory(void)
+{
+ int amount_wanted = 0;
+ int free_flags = 0, did_eat_memory = 0;
+
+ /*
+ * Note that if we have enough storage space and enough free memory, we may
+ * exit without eating anything. We give up when the last 10 iterations ate
+ * no extra pages because we're not going to get much more anyway, but
+ * the few pages we get will take a lot of time.
+ *
+ * We freeze processes before beginning, and then unfreeze them if we
+ * need to eat memory until we think we have enough. If our attempts
+ * to freeze fail, we give up and abort.
+ */
+
+ /* -- Stage 1: Freeze Processes -- */
+
+
+ suspend_recalculate_image_contents(0);
+ amount_wanted = amount_needed(1);
+
+ switch (image_size_limit) {
+ case -1: /* Don't eat any memory */
+ if (amount_wanted > 0) {
+ set_result_state(SUSPEND_ABORTED);
+ set_result_state(SUSPEND_WOULD_EAT_MEMORY);
+ }
+ break;
+ case -2: /* Free caches only */
+ free_flags = GFP_NOIO | __GFP_HIGHMEM;
+ amount_wanted = 1 << 31; /* As much cache as we can get */
+ break;
+ default:
+ free_flags = GFP_ATOMIC | __GFP_HIGHMEM;
+ }
+
+ thaw_processes(FREEZER_KERNEL_THREADS);
+
+ /* -- Stage 2: Eat memory -- */
+
+ if (amount_wanted > 0 && !test_result_state(SUSPEND_ABORTED) &&
+ image_size_limit != -1) {
+
+ suspend_prepare_status(CLEAR_BAR, "Seeking to free %dMB of memory.", MB(amount_wanted));
+
+ shrink_all_memory(amount_wanted);
+ suspend_recalculate_image_contents(0);
+
+ did_eat_memory = 1;
+
+ suspend_cond_pause(0, NULL);
+ }
+
+ if (freeze_processes()) {
+ set_result_state(SUSPEND_FREEZING_FAILED);
+ set_result_state(SUSPEND_ABORTED);
+ }
+
+ if (did_eat_memory) {
+ unsigned long orig_state = get_suspend_state();
+ /* Freeze_processes will call sys_sync too */
+ restore_suspend_state(orig_state);
+ suspend_recalculate_image_contents(0);
+ }
+
+ /* Blank out image size display */
+ suspend_update_status(100, 100, NULL);
+
+ if (!test_result_state(SUSPEND_ABORTED) &&
+ (amount_needed(0) - extra_pd1_pages_allowance > 0)) {
+ printk("Unable to free sufficient memory to suspend. Still need %d pages.\n",
+ amount_needed(1));
+ display_stats(1, 1);
+ set_result_state(SUSPEND_ABORTED);
+ set_result_state(SUSPEND_UNABLE_TO_FREE_ENOUGH_MEMORY);
+ }
+
+ return 0;
+}
+
--
Nigel Cunningham nigel at suspend2 dot net
next prev parent reply other threads:[~2006-06-26 22:36 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-06-26 22:34 [Suspend2][ 00/20] Prepare image Nigel Cunningham
2006-06-26 22:34 ` [Suspend2][ 01/20] [Suspend2] Prepare_image.c header Nigel Cunningham
2006-06-26 22:34 ` [Suspend2][ 02/20] [Suspend2] Get number of pcp pages Nigel Cunningham
2006-06-26 22:34 ` [Suspend2][ 03/20] [Suspend2] Get the real number of free pages (incl. pcp) Nigel Cunningham
2006-06-26 22:35 ` [Suspend2][ 04/20] [Suspend2] Calculate pagedir1 growth allowance Nigel Cunningham
2006-06-26 22:35 ` [Suspend2][ 05/20] [Suspend2] Get the amount of storage needed for the image proper Nigel Cunningham
2006-06-26 22:35 ` [Suspend2][ 06/20] [Suspend2] Calculate header storage needed Nigel Cunningham
2006-06-26 22:35 ` [Suspend2][ 07/20] [Suspend2] Display image vital statistics Nigel Cunningham
2006-06-26 22:35 ` [Suspend2][ 08/20] [Suspend2] Generate free page bitmap Nigel Cunningham
2006-06-26 22:35 ` [Suspend2][ 09/20] [Suspend2] Get size of a free region Nigel Cunningham
2006-06-26 22:35 ` [Suspend2][ 10/20] [Suspend2] Count pages in image parts Nigel Cunningham
2006-06-26 22:35 ` [Suspend2][ 11/20] [Suspend2] Amount of memory still to be freed Nigel Cunningham
2006-06-26 22:35 ` [Suspend2][ 12/20] [Suspend2] Recalculate image contents Nigel Cunningham
2006-06-26 22:35 ` [Suspend2][ 13/20] [Suspend2] Try to refreeze processes Nigel Cunningham
2006-06-26 22:35 ` [Suspend2][ 14/20] [Suspend2] Update the image Nigel Cunningham
2006-06-26 22:35 ` [Suspend2][ 15/20] [Suspend2] Attempt to freeze processes Nigel Cunningham
2006-06-27 13:45 ` Pavel Machek
2006-06-27 23:38 ` Nigel Cunningham
2006-06-28 18:59 ` Hugh Dickins
2006-06-28 22:10 ` Nigel Cunningham
2006-06-26 22:35 ` [Suspend2][ 16/20] [Suspend2] Calculate storage needed for an image Nigel Cunningham
2006-06-26 22:35 ` [Suspend2][ 17/20] [Suspend2] Calculate the amount of free memory needed Nigel Cunningham
2006-06-26 22:35 ` Nigel Cunningham [this message]
2006-06-26 22:35 ` [Suspend2][ 19/20] [Suspend2] Prepare an image Nigel Cunningham
2006-06-26 22:35 ` [Suspend2][ 20/20] [Suspend2] Prepare image header file Nigel Cunningham
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060626223547.4050.40672.stgit@nigel.suspend2.net \
--to=nigel@suspend2.net \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox