[Suspend2][ 5/9] [Suspend2] Mark pages for pageset 2.

From: Nigel Cunningham
Date: Mon Jun 26 2006 - 18:34:13 EST


Reset the contents of pageset 2: clear the map, mark LRU pages as being in,
then remove userspace helpers' pages.

Signed-off-by: Nigel Cunningham <nigel@xxxxxxxxxxxx>

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

diff --git a/kernel/power/pagedir.c b/kernel/power/pagedir.c
index b7fc3bc..c23ca58 100644
--- a/kernel/power/pagedir.c
+++ b/kernel/power/pagedir.c
@@ -178,3 +178,95 @@ void suspend_mark_task_as_pageset1(struc
up_read(&mm->mmap_sem);
}

+/* mark_pages_for_pageset2
+ *
+ * Description: Mark unshared pages in processes not needed for suspend as
+ * being able to be written out in a separate pagedir.
+ * HighMem pages are simply marked as pageset2. They won't be
+ * needed during suspend.
+ */
+
+struct attention_list {
+ struct task_struct *task;
+ struct attention_list *next;
+};
+
+void suspend_mark_pages_for_pageset2(void)
+{
+ struct zone *zone;
+ struct task_struct *p;
+ struct attention_list *attention_list = NULL, *last = NULL;
+ unsigned long flags;
+
+ BUG_ON(in_atomic() && !irqs_disabled());
+
+ clear_dyn_pageflags(pageset2_map);
+
+ if (test_action_state(SUSPEND_NO_PAGESET2))
+ return;
+
+ /*
+ * Note that we don't clear the map to begin with!
+ * This is because if we eat memory, we loose track
+ * of LRU pages that are still in use but taken off
+ * the LRU. If I can figure out how the VM keeps
+ * track of them, I might be able to tweak this a
+ * little further and decrease pageset one's size
+ * further.
+ *
+ * (Memory grabbing clears the pageset2 flag on
+ * pages that are really freed!).
+ */
+
+ for_each_zone(zone) {
+ spin_lock_irqsave(&zone->lru_lock, flags);
+ if (zone->nr_inactive) {
+ struct page *page;
+ list_for_each_entry(page, &zone->inactive_list, lru)
+ SetPagePageset2(page);
+ }
+ if (zone->nr_active) {
+ struct page *page;
+ list_for_each_entry(page, &zone->active_list, lru)
+ SetPagePageset2(page);
+ }
+ spin_unlock_irqrestore(&zone->lru_lock, flags);
+ }
+
+ BUG_ON(in_atomic() && !irqs_disabled());
+
+ /* Now we find all userspace process (with task->mm) marked PF_NOFREEZE
+ * and move them into pageset1.
+ */
+ read_lock(&tasklist_lock);
+ for_each_process(p)
+ if ((p->flags & PF_NOFREEZE) || p == current) {
+ struct attention_list *this = kmalloc(sizeof(struct attention_list), GFP_ATOMIC);
+ BUG_ON(!this);
+ this->task = p;
+ this->next = NULL;
+ if (attention_list) {
+ last->next = this;
+ last = this;
+ } else
+ attention_list = last = this;
+ }
+ read_unlock(&tasklist_lock);
+
+ BUG_ON(in_atomic() && !irqs_disabled());
+
+ /* Because the tasks in attention_list are ones related to suspending,
+ * we know that they won't go away under us.
+ */
+
+ while (attention_list) {
+ suspend_mark_task_as_pageset1(attention_list->task);
+ last = attention_list;
+ attention_list = attention_list->next;
+ kfree(last);
+ }
+
+ BUG_ON(in_atomic() && !irqs_disabled());
+
+}
+

--
Nigel Cunningham nigel at suspend2 dot net
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/