mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Nigel Cunningham <nigel@suspend2.net>
To: linux-kernel@vger.kernel.org
Subject: [Suspend2][ 3/9] [Suspend2] Allocate extra memory for the atomic copy.
Date: Tue, 27 Jun 2006 08:34:23 +1000	[thread overview]
Message-ID: <20060626223421.3963.39587.stgit@nigel.suspend2.net> (raw)
In-Reply-To: <20060626223412.3963.1484.stgit@nigel.suspend2.net>

Allocate extra memory needed for an atomic copy when the page cache is too
small to store it.

Signed-off-by: Nigel Cunningham <nigel@suspend2.net>

 kernel/power/pagedir.c |   75 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 75 insertions(+), 0 deletions(-)

diff --git a/kernel/power/pagedir.c b/kernel/power/pagedir.c
index 9c26990..76da2e5 100644
--- a/kernel/power/pagedir.c
+++ b/kernel/power/pagedir.c
@@ -54,3 +54,78 @@ void suspend_free_extra_pagedir_memory(v
 	extra_pagedir_pages_allocated = 0;
 }
 
+/* suspend_allocate_extra_pagedir_memory
+ *
+ * Description:	Allocate memory for making the atomic copy of pagedir1 in the
+ * 		case where it is bigger than pagedir2.
+ * Arguments:	struct pagedir *: 	The pagedir for which we should 
+ * 					allocate memory.
+ * 		int:			Size of pageset 1.
+ * 		int:			Size of pageset 2.
+ * Result:	int. Zero on success. One if unable to allocate enough memory.
+ */
+int suspend_allocate_extra_pagedir_memory(struct pagedir *p, int pageset_size,
+		int alloc_from)
+{
+	int num_to_alloc = pageset_size - alloc_from - extra_pagedir_pages_allocated;
+	int j, order, num_added = 0;
+
+	if (num_to_alloc < 1)
+		num_to_alloc = 0;
+
+	if (num_to_alloc) {
+		order = fls(num_to_alloc);
+		if (order >= MAX_ORDER)
+			order = MAX_ORDER - 1;
+
+		while (num_added < num_to_alloc) {
+			struct page *newpage;
+			unsigned long virt;
+			struct extras *extras_entry;
+			
+			while ((1 << order) > (num_to_alloc - num_added))
+				order--;
+
+			virt = __get_free_pages(GFP_ATOMIC | __GFP_NOWARN, order);
+			while ((!virt) && (order > 0)) {
+				order--;
+				virt = __get_free_pages(GFP_ATOMIC | __GFP_NOWARN, order);
+			}
+
+			if (!virt) {
+				p->pageset_size += num_added;
+				extra_pagedir_pages_allocated += num_added;
+				return 1;
+			}
+
+			newpage = virt_to_page(virt);
+
+			extras_entry = (struct extras *) kmalloc(sizeof(struct extras), GFP_ATOMIC);
+
+			if (!extras_entry) {
+				__free_pages(newpage, order);
+				extra_pagedir_pages_allocated += num_added;
+				return 1;
+			}
+
+			extras_entry->page = newpage;
+			extras_entry->order = order;
+			extras_entry->next = NULL;
+
+			if (extras_list)
+				extras_entry->next = extras_list;
+
+			extras_list = extras_entry;
+
+			for (j = 0; j < (1 << order); j++) {
+				SetPageNosave(newpage + j);
+				SetPagePageset1Copy(newpage + j);
+			}
+			num_added+= (1 << order);
+		}
+	}
+
+	extra_pagedir_pages_allocated += num_added;
+	return 0;
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

  parent reply	other threads:[~2006-06-26 22:34 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-06-26 22:34 [Suspend2][ 0/9] Pagedir specific routines Nigel Cunningham
2006-06-26 22:34 ` [Suspend2][ 1/9] [Suspend2] Pagedir.c header Nigel Cunningham
2006-06-26 22:34 ` [Suspend2][ 2/9] [Suspend2] Free extra memory allocated for the atomic copy Nigel Cunningham
2006-06-26 22:34 ` Nigel Cunningham [this message]
2006-06-26 22:34 ` [Suspend2][ 4/9] [Suspend2] Mark a task as pageset 1 Nigel Cunningham
2006-06-26 22:34 ` [Suspend2][ 5/9] [Suspend2] Mark pages for pageset 2 Nigel Cunningham
2006-06-26 22:34 ` [Suspend2][ 6/9] [Suspend2] Get nonconflicting page Nigel Cunningham
2006-06-26 22:34 ` [Suspend2][ 7/9] [Suspend2] Relocate a piece of memory if required Nigel Cunningham
2006-06-26 22:34 ` [Suspend2][ 8/9] [Suspend2] Get pageset1 load addresses Nigel Cunningham
2006-06-26 22:34 ` [Suspend2][ 9/9] [Suspend2] Header file for pagedir functions 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=20060626223421.3963.39587.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

all inboxes | Powered by JetHome®