linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Nigel Cunningham <ncunningham@linuxmail.org>
To: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Suspend 2 merge: 38/51: Page directory support.
Date: Thu, 25 Nov 2004 00:00:57 +1100	[thread overview]
Message-ID: <1101298736.5805.345.camel@desktop.cunninghams> (raw)
In-Reply-To: <1101292194.5805.180.camel@desktop.cunninghams>

A pageset is a group of pages that are saved as part of the image.
Suspend uses two pagesets: pageset2 contains the LRU pages and pageset1
contains all other pages saved. A pagedir is the original name for
pagesets. I use it more to refer to the metadata for the pageset.

Note that all of our metadata is actually stored in extents (I called
them ranges before I knew what an extent was). The struct pbe2 is an
abstraction of this data, roughly equivalent to the pbes that swsusp
uses (hence the name) and the *pbe* functions at the top of this file.

Here we also have the code for making our atomic copy when suspending,
allocating and freeing the metadata and working to ensure the copy of
pagedir1 loaded at resume time doesn't get overwritten by itself
('collide') as we restore the kernel.

diff -ruN 828-pagedir-old/kernel/power/pagedir.c 828-pagedir-new/kernel/power/pagedir.c
--- 828-pagedir-old/kernel/power/pagedir.c	1970-01-01 10:00:00.000000000 +1000
+++ 828-pagedir-new/kernel/power/pagedir.c	2004-11-17 19:05:47.000000000 +1100
@@ -0,0 +1,532 @@
+/*
+ * kernel/power/pagedir.c
+ *
+ * Copyright (C) 1998-2001 Gabor Kuti <seasons@fornax.hu>
+ * Copyright (C) 1998,2001,2002 Pavel Machek <pavel@suse.cz>
+ * Copyright (C) 2002-2003 Florent Chabaud <fchabaud@free.fr>
+ * Copyright (C) 2002-2004 Nigel Cunningham <ncunningham@linuxmail.org>
+ *
+ * This file is released under the GPLv2.
+ *
+ * Routines for handling pagesets.
+ * Note that pbes aren't actually stored as such. They're stored as
+ * ranges (extents is the term, I'm told).
+ */
+
+#define SUSPEND_PAGEDIR_C
+#include <linux/suspend.h>
+#include <linux/highmem.h>
+#include <linux/module.h>
+
+extern struct pagedir pagedir1, pagedir2, pagedir_resume;
+
+#include "suspend.h"
+#include "pageflags.h"
+
+/* setup_pbe_variable
+ *
+ * Description:	Set up one variable in a page backup entry from the range list.
+ * Arguments:	unsigned long:		The variable which will contain the 
+ * 					value.
+ * 		struct range**:		Address of the pointer to the current
+ * 					range.
+ * 		struct rangechain*:	Address of the rangechain we are 
+ * 					traversing.
+ */
+static inline void setup_pbe_variable(unsigned long * variable, struct range ** currentrange,
+		struct rangechain * chain)
+{
+	*currentrange = chain->first;
+	if (chain->first)
+		*variable = chain->first->minimum;
+	else
+		*variable = 0;
+}
+
+/* get_first_pbe
+ *
+ * Description:	Get the first page backup entry for a pagedir.
+ * Arguments:	struct pbe2 *:	Address of the page backup entry we're 
+ * 				populating.
+ * 		struct pagedir: Pagedir providing the data.
+ */
+void get_first_pbe(struct pbe2 * pbe, struct pagedir * pagedir)
+{
+	unsigned long currentorig, currentaddress;
+
+	pbe->pagedir = pagedir;
+
+	/* Get raw initial values */
+	setup_pbe_variable((unsigned long *) &pbe->origaddress, 
+			&pbe->currentorigrange, &pagedir->origranges);
+	setup_pbe_variable((unsigned long *) &pbe->address,
+			&pbe->currentdestrange, &pagedir->destranges);
+
+	/* Convert to range values */
+	currentorig = (unsigned long) pbe->origaddress;
+	currentaddress = (unsigned long) pbe->address;
+
+	pbe->origaddress = mem_map + currentorig;
+	pbe->address = mem_map + currentaddress;
+
+	if ((currentaddress < 0) || (currentaddress > max_mapnr))
+		panic("Argh! Destination range value %ld is invalid!",
+				currentaddress);
+}
+
+/* get_next_pbe
+ *
+ * Description:	Get the next page backup entry in a pagedir.
+ * Arguments:	struct pbe2 *:	Address of the pbe we're updating.
+ */
+void get_next_pbe(struct pbe2 * pbe)
+{
+	unsigned long currentorig, currentaddress;
+
+	/* Convert to range values */
+	currentorig = (pbe->origaddress - mem_map);
+	currentaddress = (pbe->address - mem_map);
+
+	/* Update values */
+	GET_RANGE_NEXT(pbe->currentorigrange, currentorig);
+	GET_RANGE_NEXT(pbe->currentdestrange, currentaddress);
+	
+	pbe->origaddress = mem_map + currentorig;
+	pbe->address = mem_map + currentaddress;
+}
+
+/*
+ * --------------------------------------------------------------------------------------
+ *
+ * 	Local Page Flags routines.
+ *
+ * 	Rather than using the rare and precious flags in struct page, we allocate
+ * 	our own bitmaps dynamically.
+ * 
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/* copy_pageset1
+ *
+ * Description:	Make the atomic copy of pageset1. We can't use copy_page (as we
+ * 		once did) because we can't be sure what side effects it has. On
+ * 		my old Duron, with 3DNOW, kernel_fpu_begin increments preempt
+ * 		count, making our preempt count at resume time 4 instead of 3.
+ * 		
+ * 		We don't want to call kmap_atomic unconditionally because it has
+ * 		the side effect of incrementing the preempt count, which will
+ * 		leave it one too high post resume (the page containing the
+ * 		preempt count will be copied after its incremented. This is
+ * 		essentially the same problem.
+ */
+
+void copy_pageset1(void)
+{
+	int i = 0;
+	struct pbe2 pbe;
+
+	get_first_pbe(&pbe, &pagedir1);
+
+	for (i = 0; i < pageset1_size; i++) {
+		int loop;
+		unsigned long * origpage;
+		unsigned long * copypage = page_address(pbe.address);
+
+	       	if (PageHighMem(pbe.origaddress))
+			origpage = kmap_atomic(pbe.origaddress, KM_USER1);
+		else
+			origpage = page_address(pbe.origaddress);
+
+		for (loop=0; loop < (PAGE_SIZE / sizeof(unsigned long)); loop++)
+			*(copypage + loop) = *(origpage + loop);
+	       	if (PageHighMem(pbe.origaddress))
+			kunmap_atomic(origpage, KM_USER1);
+
+		get_next_pbe(&pbe);
+	}
+}
+
+#ifdef CONFIG_DEBUG_PAGEALLOC
+void suspend_map_atomic_copy_pages(void)
+{
+	int i = 0;
+	struct pbe2 pbe;
+
+	get_first_pbe(&pbe, &pagedir1);
+
+	for (i = 0; i < pageset1_size; i++) {
+		int orig_was_mapped = 1, copy_was_mapped = 1;
+
+	       	if (!PageHighMem(pbe.origaddress)) {
+			orig_was_mapped = suspend_map_kernel_page(pbe.origaddress, 1);
+			if (!orig_was_mapped)
+				SetPageUnmap(pbe.origaddress);
+		}
+		copy_was_mapped = suspend_map_kernel_page(pbe.address, 1);
+		if (!copy_was_mapped)
+			SetPageUnmap(pbe.address);
+
+		get_next_pbe(&pbe);
+	}
+}
+
+void suspend_unmap_atomic_copy_pages(void)
+{
+	int i;
+	for (i = 0; i < max_mapnr; i++)
+		if (PageUnmap(mem_map + i))
+			suspend_map_kernel_page(mem_map + i, 0);
+}
+#endif
+
+/* free_pagedir
+ *
+ * Description:	Free a previously allocated pagedir.
+ * Arguments:	struct pagedir *:	Pointer to the pagedir being freed.
+ */
+void free_pagedir(struct pagedir * p)
+{
+	PRINTFREEMEM("at start of free_pagedir");
+
+	if (p->allocdranges.first) {
+		/* Free allocated pages */
+		struct range * rangepointer;
+		unsigned long pagenumber;
+		range_for_each(&p->allocdranges, rangepointer, pagenumber) {
+			ClearPageNosave(mem_map+pagenumber);
+			free_page((unsigned long) page_address(mem_map+pagenumber));
+		}
+	}
+
+	suspend_store_free_mem(SUSPEND_FREE_EXTRA_PD1, 1);
+
+	/* For pagedir 2, destranges == origranges */
+	if (p->pagedir_num == 2)
+		p->destranges.first = NULL;
+	
+	put_range_chain(&p->origranges);
+	put_range_chain(&p->destranges);
+	put_range_chain(&p->allocdranges);
+
+	PRINTFREEMEM("at end of free_pagedir");
+	suspend_message(SUSPEND_PAGESETS, SUSPEND_MEDIUM, 0,
+			"Pageset size was %d.\n", p->pageset_size);
+	p->pageset_size = 0;
+}
+
+/* PageInPagedir
+ *
+ * Description:	Determine whether a page is in a pagedir.
+ * Arguments:	struct pagedir *	The pagedir to search.
+ * 		struct page *		The page to look for.
+ * Result:	int			Bitmap of state:
+ * 					Bit 0: Source page
+ * 					Bit 1: Dest page
+ * 					Bit 2: Allocated
+ * 					(Should only result in 0, 1, 2 or 6).
+ */
+
+int PageInPagedir(struct pagedir * p, struct page * page)
+{
+	int page_sought = page_to_pfn(page);
+	int result = 0;
+
+	if (p->origranges.first) {
+		struct range * rangepointer;
+		unsigned long pagenumber;
+		range_for_each(&p->origranges, rangepointer, pagenumber) {
+			if (pagenumber == page_sought)
+				result |=  1;
+			if (pagenumber >= page_sought)
+				break;
+		}
+	}
+
+	if (p->destranges.first) {
+		/* Free allocated pages */
+		struct range * rangepointer;
+		unsigned long pagenumber;
+		range_for_each(&p->destranges, rangepointer, pagenumber) {
+			if (pagenumber == page_sought)
+				result |= 2;
+			if (pagenumber >= page_sought)
+				break;
+		}
+	}
+
+	if (p->allocdranges.first) {
+		/* Free allocated pages */
+		struct range * rangepointer;
+		unsigned long pagenumber;
+		range_for_each(&p->allocdranges, rangepointer, pagenumber) {
+			if (pagenumber == page_sought)
+				result |= 4;
+			if (pagenumber >= page_sought)
+				break;
+		}
+	}
+
+	return result;
+}
+
+/* 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 allocate_extra_pagedir_memory(struct pagedir * p, int pageset_size,
+		int alloc_from)
+{
+	int num_to_alloc = pageset_size - alloc_from - p->allocdranges.size;
+	int j, order;
+
+	prepare_status(0, 0, "Preparing page directory.");
+
+	PRINTFREEMEM("at start of allocate_extra_pagedir_memory");
+
+	if (num_to_alloc < 1)
+		num_to_alloc = 0;
+
+	if (num_to_alloc) {
+		int num_added = 0, numnosaveallocated=0;
+		int origallocd = alloc_from + p->allocdranges.size;
+	
+		PRINTFREEMEM("prior to attempt");
+
+		order = generic_fls(num_to_alloc);
+		if (order >= MAX_ORDER)
+			order = MAX_ORDER - 1;
+
+		while (num_added < num_to_alloc) {
+			struct page * newpage;
+			unsigned long virt;
+			
+			while ((1 << order) > (num_to_alloc - num_added))
+				order--;
+
+			virt = get_grabbed_pages(order);
+			while ((!virt) && (order > 0)) {
+				order--;
+				virt = get_grabbed_pages(order);
+			}
+
+			if (!virt) {
+				p->pageset_size += num_added;
+				suspend_message(SUSPEND_PAGESETS, SUSPEND_VERBOSE, 1,
+					"   Allocated (extra) memory for pages"
+					" from %d-%d (%d pages).\n",
+					origallocd + 1, pageset_size, 
+					pageset_size - origallocd);
+				printk("Couldn't get enough yet."
+						" %d pages short.\n",
+						num_to_alloc - num_added);
+				PRINTFREEMEM("at abort of "
+					"allocate_extra_pagedir_memory");
+				suspend_store_free_mem(SUSPEND_FREE_EXTRA_PD1, 0);
+				return 1;
+			}
+
+			newpage = virt_to_page(virt);
+			suspend_store_free_mem(SUSPEND_FREE_EXTRA_PD1, 0);
+			for (j = 0; j < (1 << order); j++) {
+				SetPageNosave(newpage + j);
+				/* Pages will be freed one at a time. */
+				set_page_count(newpage + j, 1);
+				add_to_range_chain(&p->allocdranges, newpage - mem_map + j);
+				numnosaveallocated++;
+			}
+			suspend_store_free_mem(SUSPEND_FREE_RANGE_PAGES, 0);
+			num_added+= (1 << order);
+		}
+		suspend_message(SUSPEND_PAGESETS, SUSPEND_VERBOSE, 1,
+			"   Allocated (extra) memory for pages "
+			"from %d-%d (%d pages).\n",
+			origallocd + 1, pageset_size, 
+			pageset_size - origallocd);
+	}
+
+	p->pageset_size = pageset_size;
+
+	suspend_store_free_mem(SUSPEND_FREE_EXTRA_PD1, 0);
+	PRINTFREEMEM("at end of allocate_extra_pagedir_memory");
+	return 0;
+}
+
+/* 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.
+ */
+
+void mark_pages_for_pageset2(void)
+{
+	int i, numpageset2 = 0;
+	struct zone * zone;
+	unsigned long flags;
+
+	if (max_mapnr != num_physpages) {
+		abort_suspend("mapnr is not expected");
+		return;
+	}
+	
+	clear_map(pageset2_map);
+
+	/* 
+	 * 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!).
+	 */
+	
+	/* Add LRU pages */
+	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);
+	}
+
+
+	/* Ensure range pages are not Pageset2 */
+	if (num_range_pages) {
+		if (get_rangepages_list())
+			return;
+
+		for (i = 1; i <= num_range_pages; i++) {
+			struct page * page;
+			page = virt_to_page(get_rangepages_list_entry(i));
+			// Must be assigned by the time recalc stats is called
+			if (PagePageset2(page)) {
+				suspend_message(SUSPEND_PAGESETS, SUSPEND_ERROR, 1,
+					"Pagedir[%d] was marked as pageset2 -"
+					" unmarking.\n", i);
+				ClearPagePageset2(page);
+				numpageset2--;
+			}
+		}
+	}
+
+	/* Finally, ensure that Slab pages are not Pageset2. */
+
+	for (i = 0; i < max_mapnr; i++) {
+		if (PageSlab(mem_map+i)) {
+			if (TestAndClearPagePageset2(mem_map+i)) {
+				//suspend_message(SUSPEND_PAGESETS, SUSPEND_ERROR, 1,
+				printk(
+					"Found page %d is slab page "
+						"but marked pageset 2.\n", i);
+				numpageset2--;
+			}
+		}
+	}
+}
+
+/* warmup_collision_cache
+ *
+ * Description:	Mark the pages which are used by the original kernel.
+ */
+void warmup_collision_cache(void) {
+	int i;
+	struct range * rangepointer = NULL;
+	unsigned long pagenumber;
+	
+	/* Allocatemap doesn't get deallocated because it's forgotten when we
+	 * copy PageDir1 back. It doesn't matter if it collides because it is
+	 * not used during the copy back itself.
+	 */
+	allocate_local_pageflags(&in_use_map, 0);
+	suspend_message(SUSPEND_IO, SUSPEND_VERBOSE, 1, "Setting up pagedir cache...");
+	for (i = 0; i < max_mapnr; i++)
+		ClearPageInUse(mem_map+i);
+
+	range_for_each(&pagedir_resume.origranges, rangepointer, pagenumber)
+		SetPageInUse(mem_map+pagenumber);
+}
+
+/* get_pageset1_load_addresses
+ * 
+ * Description: We check here that pagedir & pages it points to won't collide
+ * 		with pages where we're going to restore from the loaded pages
+ * 		later.
+ * Returns:	Zero on success, one if couldn't find enough pages (shouldn't
+ * 		happen).
+ */
+
+int get_pageset1_load_addresses(void)
+{
+	int i, nrdone = 0, result = 0;
+	void **eaten_memory = NULL, **this;
+	struct page * pageaddr = NULL;
+
+	/*
+	 * Because we're trying to make this work when we're saving as much
+	 * memory as possible we need to remember the pages we reject here
+	 * and then free them when we're done.
+	 */
+	
+	for(i=0; i < pagedir_resume.pageset_size; i++) {
+		while ((this = (void *) get_zeroed_page(GFP_ATOMIC))) {
+			memset(this, 0, PAGE_SIZE);
+			pageaddr = virt_to_page(this);
+			if (!PageInUse(pageaddr)) {
+				break;
+			}
+			*this = eaten_memory;
+			eaten_memory = this;
+		}
+		if (!this) {
+			abort_suspend("Error: Ran out of memory seeking locations for reloading data.");
+			result = 1;
+			break;
+		}
+		add_to_range_chain(&pagedir_resume.destranges, pageaddr - mem_map);
+		nrdone++;
+	}
+
+	/* Free unwanted memory */
+	while(eaten_memory) {
+		this = eaten_memory;
+		eaten_memory = *eaten_memory;
+		free_page((unsigned long) this);
+	}
+	
+	return result;
+}
+
+/* set_chain_names
+ *
+ * Description:	Set the chain names for a pagedir. (For debugging).
+ * Arguments:	struct pagedir: The pagedir on which we want to set the names.
+ */
+
+void set_chain_names(struct pagedir * p)
+{
+	p->origranges.name = "original addresses";
+	p->destranges.name =  "destination addresses";
+	p->allocdranges.name = "allocated addresses";
+}
+
+EXPORT_SYMBOL(get_first_pbe);
+EXPORT_SYMBOL(get_next_pbe);



  parent reply	other threads:[~2004-11-24 17:14 UTC|newest]

Thread overview: 241+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-11-24 12:56 Suspend 2 merge Nigel Cunningham
2004-11-24 12:56 ` Suspend2 merge: 1/51: Device trees Nigel Cunningham
2004-11-24 12:56 ` Suspend2 merge: 2/51: Find class by name Nigel Cunningham
2004-11-24 12:57 ` Suspend 2 merge: 3/51: e820 table support Nigel Cunningham
2004-11-25 16:53   ` Pavel Machek
2004-11-24 12:57 ` Suspend 2 merge: 4/51: Get module list Nigel Cunningham
2004-11-25 16:56   ` Pavel Machek
2004-11-25 21:25     ` Nigel Cunningham
2004-11-25 21:32       ` Pavel Machek
2004-11-24 12:57 ` Suspend 2 merge: 5/51: Workthread freezer support Nigel Cunningham
2004-11-25 16:57   ` Pavel Machek
2004-11-24 12:57 ` Suspend 2 merge: 7/51: Reboot handler hook Nigel Cunningham
2004-11-24 13:07   ` Christoph Hellwig
2004-11-24 20:19     ` Nigel Cunningham
2004-11-25  2:37       ` Nigel Cunningham
2004-11-24 12:57 ` Suspend 2 merge: 8/51: /proc/acpi/sleep hook Nigel Cunningham
2004-11-24 13:13   ` Christoph Hellwig
2004-11-24 12:57 ` Suspend 2 merge: 9/51: init/* changes Nigel Cunningham
2004-11-25 17:07   ` Pavel Machek
2004-11-25 21:36     ` Nigel Cunningham
2004-11-25 21:45       ` Pavel Machek
2004-11-25 21:51         ` Nigel Cunningham
2004-11-25 21:58           ` Pavel Machek
2004-11-25 22:03             ` Nigel Cunningham
2004-11-25 22:30               ` Pavel Machek
2004-11-27  2:14     ` Matthew Garrett
2004-11-27  7:22       ` Pavel Machek
2004-11-27  9:31         ` Herbert Xu
2004-11-27 13:21           ` Matthew Garrett
2004-11-27 16:20             ` Pavel Machek
2004-11-28 22:43             ` Nigel Cunningham
2004-11-24 12:57 ` Suspend 2 merge: 10/51: Exports for suspend built as modules Nigel Cunningham
2004-11-24 13:12   ` Christoph Hellwig
2004-11-24 21:52     ` Nigel Cunningham
2004-11-24 14:44   ` Ingo Molnar
2004-11-24 20:46     ` Nigel Cunningham
2004-11-25 18:07   ` Pavel Machek
2004-11-25 21:40     ` Nigel Cunningham
2004-11-25 21:50       ` Pavel Machek
2004-11-24 12:57 ` Suspend 2 merge: 11/51: Export vt functions Nigel Cunningham
2004-11-24 12:57 ` Suspend 2 merge:L 12/51: Disable OOM killer when suspending Nigel Cunningham
2004-11-25 18:12   ` Pavel Machek
2004-11-25 21:47     ` Nigel Cunningham
2004-11-25 21:54       ` Pavel Machek
2004-11-24 12:57 ` Suspend 2 merge: 13/51: Disable highmem tlb flush for copyback Nigel Cunningham
2004-11-25 18:13   ` Pavel Machek
2004-11-24 12:57 ` Suspend 2 merge: 14/51: Disable page alloc failure message when suspending Nigel Cunningham
2004-11-24 14:15   ` Christoph Hellwig
2004-11-24 20:46     ` Nigel Cunningham
2004-11-24 16:00   ` Dave Hansen
2004-11-24 21:06     ` Nigel Cunningham
2004-11-24 22:25       ` Dave Hansen
2004-11-25 18:15   ` Pavel Machek
2004-11-25 21:49     ` Nigel Cunningham
2004-11-25 21:56       ` Pavel Machek
2004-11-25 22:46         ` Nigel Cunningham
2004-11-25 23:22           ` Pavel Machek
2004-11-24 12:58 ` Suspend 2 merge: 15/51: Disable pdflush during suspend Nigel Cunningham
2004-11-24 12:58 ` Suspend 2 merge: 16/51: Disable cache reaping " Nigel Cunningham
2004-11-25 18:18   ` Pavel Machek
2004-11-25 22:00     ` Nigel Cunningham
2004-11-24 12:58 ` Suspend 2 merge: 17/51: Disable MCE checking " Nigel Cunningham
2004-11-25 18:19   ` Pavel Machek
2004-11-25 22:05     ` Nigel Cunningham
2004-11-25 22:31       ` Pavel Machek
2004-11-25 22:38         ` Nigel Cunningham
2004-11-25 22:45           ` Pavel Machek
2004-11-24 12:58 ` Suspend 2 merge: 18/51: Debug page_alloc support Nigel Cunningham
2004-11-24 16:02   ` Dave Hansen
2004-11-24 20:17     ` Nigel Cunningham
2004-11-24 22:26       ` Dave Hansen
2004-11-25 18:21   ` Pavel Machek
2004-11-25 22:06     ` Nigel Cunningham
2004-11-24 12:58 ` Suspend 2 merge: 19/51: Remove MTRR sysdev support Nigel Cunningham
2004-11-24 16:27   ` Zwane Mwaikambo
2004-11-24 20:17     ` Nigel Cunningham
2004-11-25 18:22   ` Pavel Machek
2004-11-28 22:34     ` Nigel Cunningham
2004-11-24 12:58 ` Suspend 2 merge: 20/51: Timer freezer (experimental) Nigel Cunningham
2004-11-24 12:58 ` Suspend 2 merge: 21/51: Refrigerator upgrade Nigel Cunningham
2004-11-25 18:33   ` Pavel Machek
2004-11-25 22:10     ` Nigel Cunningham
2004-11-25 22:36       ` Pavel Machek
2004-11-25 22:49         ` Nigel Cunningham
2004-11-25 23:25           ` Pavel Machek
2004-11-25 23:49             ` Nigel Cunningham
2004-11-26  0:05               ` Pavel Machek
2004-11-26  0:12                 ` Nigel Cunningham
2004-11-26  0:18                   ` Pavel Machek
2004-11-27 17:18                   ` Pavel Machek
2004-11-26 21:00       ` Christoph Hellwig
2004-11-24 12:58 ` Suspend 2 merge: 22/51: Suspend2 lowlevel code Nigel Cunningham
2004-11-24 16:42   ` Zwane Mwaikambo
2004-11-24 21:20     ` Nigel Cunningham
2004-11-24 21:55       ` Zwane Mwaikambo
2004-11-24 21:56         ` Nigel Cunningham
2004-11-25 18:39   ` Pavel Machek
2004-11-25 22:15     ` Nigel Cunningham
2004-11-25 22:38       ` Pavel Machek
2004-11-24 12:58 ` Suspend 2 merge: 23/51: PPC support Nigel Cunningham
2004-11-25 18:40   ` Pavel Machek
2004-11-25 22:15     ` Nigel Cunningham
2004-11-24 12:59 ` Suspend 2 merge: 24/51: Keyboard and serial console hooks Nigel Cunningham
2004-11-24 13:29   ` Christoph Hellwig
2004-11-24 18:47     ` Yaroslav Rastrigin
2004-11-24 21:38     ` Nigel Cunningham
2004-11-24 21:57     ` Jan Rychter
2004-11-24 23:02       ` Christoph Hellwig
2004-11-25  1:22         ` Jan Rychter
2004-11-25 10:08           ` Christoph Hellwig
2004-11-26 20:21         ` pb
2004-11-25 19:28     ` Pavel Machek
2004-11-28 22:34       ` Nigel Cunningham
2004-11-28 23:39         ` Pavel Machek
2004-11-29 22:15           ` Nigel Cunningham
2004-11-24 12:59 ` Suspend 2 merge: 25/51: Documentation Nigel Cunningham
2004-11-24 12:59 ` Suspend 2 merge: 26/51: Kconfig and makefile Nigel Cunningham
2004-11-24 16:34   ` Roman Zippel
2004-11-24 21:11     ` Nigel Cunningham
2004-11-24 21:46       ` Roman Zippel
2004-11-24 21:53         ` Nigel Cunningham
2004-11-25  2:37     ` Nigel Cunningham
2004-11-24 12:59 ` Suspend 2 merge: 27/51: Block I/O module Nigel Cunningham
2004-11-24 12:59 ` Suspend 2 merge: 28/51: Suspend memory pool hooks Nigel Cunningham
2004-11-25 19:34   ` Pavel Machek
2004-11-24 12:59 ` Suspend 2 merge: 29/51: Clear swapfile bdev in swapoff Nigel Cunningham
2004-11-24 12:59 ` Suspend 2 merge: 30/51: Enable slab alloc fallback to suspend memory pool Nigel Cunningham
2004-11-25 19:36   ` Pavel Machek
2004-11-24 12:59 ` Suspend 2 merge: 31/51: Export tlb flushing Nigel Cunningham
2004-11-24 15:32   ` Martin J. Bligh
2004-11-24 21:04     ` Nigel Cunningham
2004-11-24 12:59 ` Suspend 2 merge: 32/51: Make show task non-static Nigel Cunningham
2004-11-24 12:59 ` Suspend 2 merge: 33/51: More documentation Nigel Cunningham
2004-11-24 13:00 ` Suspend 2 merge: 34/51: Includes Nigel Cunningham
2004-11-24 13:25   ` Christoph Hellwig
2004-11-24 20:17     ` Nigel Cunningham
2004-11-24 23:19       ` Matthew Garrett
2004-11-25  2:43         ` Nigel Cunningham
2004-11-24 13:00 ` Suspend 2 merge: 35/51: Code always built in to the kernel Nigel Cunningham
2004-11-25 23:32   ` Pavel Machek
2004-11-25 23:57     ` Nigel Cunningham
2004-11-26  0:08       ` Pavel Machek
2004-11-26  0:17         ` Nigel Cunningham
2004-11-26  0:23           ` Pavel Machek
2004-11-27  2:19       ` Matthew Garrett
2004-11-28 22:39         ` Nigel Cunningham
2004-11-27  9:00       ` Jan Rychter
2004-11-27 17:22         ` Pavel Machek
2004-11-24 13:00 ` Suspend 2 merge: 36/51: Highlevel I/O routines Nigel Cunningham
2004-11-25 23:36   ` Pavel Machek
2004-11-27  1:39     ` Tomas Carnecky
2004-11-24 13:00 ` Suspend 2 merge: 37/51: Memory pool support Nigel Cunningham
2004-11-25 23:37   ` Pavel Machek
2004-11-24 13:00 ` Nigel Cunningham [this message]
2004-11-24 13:01 ` Suspend 2 merge: 39/51: Plugins support Nigel Cunningham
2004-11-24 13:01 ` Suspend 2 merge: 40/51: Prepare image Nigel Cunningham
2004-11-24 13:01 ` Suspend 2 merge: 41/51: Ranges (extents) Nigel Cunningham
2004-11-24 13:01 ` Suspend 2 merge: 42/51: Suspend.c Nigel Cunningham
2004-11-24 16:52   ` Zwane Mwaikambo
2004-11-24 21:23     ` Nigel Cunningham
2004-11-25 23:43   ` Pavel Machek
2004-11-24 13:01 ` Suspend 2 merge: 43/51: Utility functions Nigel Cunningham
2004-11-25 23:46   ` Pavel Machek
2004-11-26  0:04     ` Nigel Cunningham
2004-11-27 16:11       ` Dave Hansen
2004-11-28 21:36         ` Nigel Cunningham
2004-11-24 13:01 ` Suspend 2 merge: 44/51: Text UI plugin Nigel Cunningham
2004-11-24 13:02 ` Suspend 2 merge: 45/51: Bootsplash support Nigel Cunningham
2004-11-24 13:02 ` Suspend 2 merge: 46/51: LZF support Nigel Cunningham
2004-11-24 23:01   ` Bartlomiej Zolnierkiewicz
2004-11-25  2:38     ` Nigel Cunningham
2004-11-25  6:32       ` hugang
2004-11-25  6:52         ` Dmitry Torokhov
2004-11-25  7:07           ` hugang
2004-11-25 10:10           ` Christoph Hellwig
2004-11-24 13:02 ` Suspend 2 merge: 47/51: GZIP support Nigel Cunningham
2004-11-25 23:50   ` Pavel Machek
2004-11-24 13:02 ` Suspend 2 merge: 48/51: Swapwriter Nigel Cunningham
2004-11-25 23:55   ` Pavel Machek
2004-11-26  0:05     ` Nigel Cunningham
2004-11-24 13:02 ` Suspend 2 merge: 49/51: Checksumming Nigel Cunningham
2004-11-25 23:56   ` Pavel Machek
2004-11-26  0:00     ` Nigel Cunningham
2004-11-26  0:14       ` Pavel Machek
2004-11-29  9:55   ` Rob Landley
2004-11-30  0:24     ` Nigel Cunningham
2004-11-29 23:30       ` Rob Landley
2004-11-30  0:49         ` Nigel Cunningham
2004-11-30 13:07           ` Pavel Machek
2004-11-30 21:45             ` Nigel Cunningham
2004-11-30 13:02     ` Pavel Machek
2004-11-30 13:38       ` Matthew Garrett
2004-11-30 22:38         ` Pavel Machek
2004-12-02 21:31       ` Rob Landley
2004-11-24 13:02 ` Suspend 2 merge: 50/51: Device mapper support Nigel Cunningham
2004-11-25 23:58   ` Pavel Machek
2004-11-26  0:07     ` Nigel Cunningham
2004-12-02 20:40       ` Alasdair G Kergon
2004-12-02 21:04         ` Nigel Cunningham
2004-12-02 21:49           ` Alasdair G Kergon
2004-12-02 22:08             ` Nigel Cunningham
2004-12-03 17:47               ` Alasdair G Kergon
2004-12-03 19:57                 ` Nigel Cunningham
2004-12-03 20:12                   ` Alasdair G Kergon
2004-12-14  0:47                     ` Nigel Cunningham
2004-11-24 13:03 ` Suspend 2 merge: 51/51: Notes Nigel Cunningham
2004-11-26  0:01   ` Pavel Machek
2004-11-26  0:09     ` Nigel Cunningham
2004-11-26  0:24       ` Pavel Machek
2004-11-24 13:03 ` Suspend 2 merge: 6/51 Nigel Cunningham
2004-11-24 13:28 ` Suspend 2 merge Christoph Hellwig
2004-11-24 20:46   ` Nigel Cunningham
2004-11-25 19:20     ` Pavel Machek
2004-11-25 22:34       ` Nigel Cunningham
2004-11-25 23:22         ` Pavel Machek
2004-11-25 23:46           ` Nigel Cunningham
2004-11-26  0:39             ` Pavel Machek
2004-11-26  9:08               ` Nigel Cunningham
2004-11-26 12:38                 ` Pavel Machek
2004-11-26 15:54                   ` Christoph Hellwig
2004-11-26 22:36                     ` Pavel Machek
2004-11-28 22:35                   ` Nigel Cunningham
2004-11-28 23:55                     ` Pavel Machek
2004-11-29  3:20                       ` Nigel Cunningham
2004-11-29 13:03                         ` Pavel Machek
2004-11-30  0:24                           ` Nigel Cunningham
2004-11-30 10:19                             ` Pavel Machek
     [not found]               ` <20041126082109.GA842@hugang.soulinfo.com>
2004-11-26 13:25                 ` Pavel Machek
     [not found]               ` <20041126043203.GA2713@hugang.soulinfo.com>
2004-11-26  9:08                 ` Nigel Cunningham
2004-11-26 13:37                   ` Pavel Machek
2004-11-26 13:31                 ` Pavel Machek
2004-11-28 21:40               ` Nigel Cunningham
2004-11-29  9:34             ` Stefan Seyfried
2004-11-29 22:20               ` Nigel Cunningham
2004-11-29 22:34                 ` Pavel Machek
2004-11-30 12:16                 ` Stefan Seyfried
2004-11-30 21:16                   ` Nigel Cunningham
2004-11-30 22:20                     ` Pavel Machek
2004-12-01  9:27                       ` Nigel Cunningham
2004-12-01 10:08                         ` Pavel Machek
2004-12-01 20:39                           ` 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=1101298736.5805.345.camel@desktop.cunninghams \
    --to=ncunningham@linuxmail.org \
    --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;
as well as URLs for NNTP newsgroup(s).