From: Nigel Cunningham <nigel@suspend2.net>
To: linux-kernel@vger.kernel.org
Subject: [PATCH] [39/48] Suspend2 2.1.9.8 for 2.6.12: 615-poweroff.patch
Date: Wed, 6 Jul 2005 12:20:43 +1000 [thread overview]
Message-ID: <11206164431370@foobar.com> (raw)
In-Reply-To: <11206164393426@foobar.com>
diff -ruNp 616-prepare_image.patch-old/kernel/power/suspend2_core/prepare_image.c 616-prepare_image.patch-new/kernel/power/suspend2_core/prepare_image.c
--- 616-prepare_image.patch-old/kernel/power/suspend2_core/prepare_image.c 1970-01-01 10:00:00.000000000 +1000
+++ 616-prepare_image.patch-new/kernel/power/suspend2_core/prepare_image.c 2005-07-04 23:14:19.000000000 +1000
@@ -0,0 +1,585 @@
+/*
+ * kernel/power/prepare_image.c
+ *
+ * Copyright (C) 2003-2005 Nigel Cunningham <nigel@suspend.net>
+ *
+ * This file is released under the GPLv2.
+ *
+ * We need to eat memory until we can:
+ * 1. Perform the save without changing anything (RAM_NEEDED < max_mapnr)
+ * 2. Fit it all in available space (active_writer->available_space() >= STORAGE_NEEDED)
+ * 3. Reload the pagedir and pageset1 to places that don't collide with their
+ * final destinations, not knowing to what extent the resumed kernel will
+ * overlap with the one loaded at boot time. I think the resumed kernel should overlap
+ * completely, but I don't want to rely on this as it is an unproven assumption. We
+ * therefore assume there will be no overlap at all (worse case).
+ * 4. Meet the user's requested limit (if any) on the size of the image.
+ * The limit is in MB, so pages/256 (assuming 4K pages).
+ *
+ * (Final test in save_image doesn't use EATEN_ENOUGH_MEMORY)
+ */
+
+#include <linux/highmem.h>
+
+#include "suspend.h"
+#include "pageflags.h"
+#include "plugins.h"
+#include "suspend2_common.h"
+#include "io.h"
+#include "ui.h"
+#include "extent.h"
+#include "prepare_image.h"
+
+#define EATEN_ENOUGH_MEMORY() (amount_needed(1) < 1)
+static int arefrozen = 0, numnosave = 0;
+static int header_space_allocated = 0;
+static int storage_allocated = 0;
+static int storage_available = 0;
+
+static int num_pcp_pages(void)
+{
+ struct zone *zone;
+ int result = 0, i = 0;
+
+ /* PCP lists */
+ for_each_zone(zone) {
+ struct per_cpu_pageset *pset;
+ int cpu;
+
+ if (!zone->present_pages)
+ continue;
+
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ if (!cpu_possible(cpu))
+ continue;
+
+ pset = &zone->pageset[cpu];
+
+ for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) {
+ struct per_cpu_pages *pcp;
+
+ pcp = &pset->pcp[i];
+ result += pcp->count;
+ }
+ }
+ }
+ return result;
+}
+
+int real_nr_free_pages(void)
+{
+ return nr_free_pages() + num_pcp_pages();
+}
+
+/* generate_free_page_map
+ *
+ * Description: This routine generates a bitmap of free pages from the
+ * lists used by the memory manager. We then use the bitmap
+ * to quickly calculate which pages to save and in which
+ * pagesets.
+ */
+static void generate_free_page_map(void)
+{
+ int i, order, loop, cpu;
+ struct page * page;
+ unsigned long flags;
+ struct zone *zone;
+ struct per_cpu_pageset *pset;
+
+ for(i=0; i < max_mapnr; i++)
+ SetPageInUse(pfn_to_page(i));
+
+ for_each_zone(zone) {
+ if (!zone->present_pages)
+ continue;
+ spin_lock_irqsave(&zone->lock, flags);
+ for (order = MAX_ORDER - 1; order >= 0; --order) {
+ list_for_each_entry(page, &zone->free_area[order].free_list, lru)
+ for(loop=0; loop < (1 << order); loop++) {
+ ClearPageInUse(page+loop);
+ ClearPagePageset2(page+loop);
+ }
+ }
+
+
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ if (!cpu_possible(cpu))
+ continue;
+
+ pset = &zone->pageset[cpu];
+
+ for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) {
+ struct per_cpu_pages *pcp;
+ struct page * page;
+
+ pcp = &pset->pcp[i];
+ list_for_each_entry(page, &pcp->list, lru) {
+ ClearPageInUse(page);
+ ClearPagePageset2(page);
+ }
+ }
+ }
+
+ spin_unlock_irqrestore(&zone->lock, flags);
+ }
+}
+
+/* size_of_free_region
+ *
+ * Description: Return the number of pages that are free, beginning with and
+ * including this one.
+ */
+static int size_of_free_region(struct page * page)
+{
+ struct page * posn = page;
+
+ while (((page_to_pfn(posn)) < max_mapnr) && (!PageInUse(posn)))
+ posn++;
+ return (posn - page);
+}
+
+/* count_data_pages
+ *
+ * This routine generates our lists of pages to be stored in each
+ * pageset. Since we store the data using extents, and adding new
+ * extents might allocate a new extent page, this routine may well
+ * be called more than once.
+ */
+static struct pageset_sizes_result count_data_pages(void)
+{
+ int chunk_size, loop, numfree = 0;
+ int usepagedir2;
+ struct pageset_sizes_result result;
+
+ result.size1 = 0;
+ result.size1low = 0;
+ result.size2 = 0;
+ result.size2low = 0;
+
+ numnosave = 0;
+
+ clear_dyn_pageflags(pageset1_map);
+ clear_dyn_pageflags(pageset1_copy_map);
+
+ generate_free_page_map();
+
+ if (TEST_RESULT_STATE(SUSPEND_ABORTED))
+ return result;
+
+ if (max_mapnr != num_physpages) {
+ abort_suspend("Max_mapnr is not equal to num_physpages.");
+ return result;
+ }
+
+ /*
+ * Pages not to be saved are marked Nosave irrespective of being reserved
+ */
+ for (loop = 0; loop < max_mapnr; loop++) {
+ struct page * page = pfn_to_page(loop);
+ if (PageNosave(page)) {
+ numnosave++;
+ continue;
+ }
+
+ if (!PageReserved(page)) {
+ if ((chunk_size=size_of_free_region(page))!=0) {
+ numfree += chunk_size;
+ loop += chunk_size - 1;
+ continue;
+ }
+ } else {
+ if (PageHighMem(page)) {
+ /* HighMem pages may be marked Reserved. We ignore them. */
+ numnosave++;
+ continue;
+ }
+ };
+
+ usepagedir2 = PagePageset2(page);
+
+ if (usepagedir2) {
+ result.size2++;
+ if (!PageHighMem(page))
+ result.size2low++;
+ SetPagePageset1Copy(page);
+ } else {
+ result.size1++;
+ SetPagePageset1(page);
+ if (!PageHighMem(page))
+ result.size1low++;
+ }
+ }
+
+ suspend_message(SUSPEND_EAT_MEMORY, SUSPEND_MEDIUM, 0,
+ "Count data pages: Set1 (%d) + Set2 (%d) + Nosave (%d) + NumFree (%d) = %d.\n",
+ result.size1, result.size2, numnosave, numfree,
+ result.size1 + result.size2 + numnosave + numfree);
+ BITMAP_FOR_EACH_SET(allocd_pages_map, loop)
+ SetPagePageset1Copy(pfn_to_page(loop));
+ return result;
+}
+
+/* amount_needed
+ *
+ * Calculates the amount by which the image size needs to be reduced to meet
+ * our constraints.
+ */
+static int amount_needed(int use_image_size_limit)
+{
+
+ int max1 = max( (int) (RAM_TO_SUSPEND - real_nr_free_pages() -
+ nr_free_highpages()),
+ ((int) (STORAGE_NEEDED(1) -
+ storage_available)));
+ if (use_image_size_limit)
+ return max( max1,
+ (image_size_limit > 0) ?
+ ((int) (STORAGE_NEEDED(1) - (image_size_limit << 8))) : 0);
+ return max1;
+}
+
+/* display_stats
+ *
+ * Display the vital statistics.of the image.
+ */
+#ifdef CONFIG_PM_DEBUG
+static void display_stats(void)
+{
+ storage_allocated = active_writer->ops.writer.storage_allocated();
+ suspend_message(SUSPEND_EAT_MEMORY, SUSPEND_MEDIUM, 1,
+ "Free:%d(%d). Sets:%d(%d),%d(%d). Nosave:%d-%d=%d. Storage:%d/%d+%d=%d(%lu). Needed:%d|%d|%d.\n",
+
+ /* Free */
+ real_nr_free_pages(),
+ real_nr_free_pages() - nr_free_highpages(),
+
+ /* Sets */
+ pageset1_size, pageset1_sizelow,
+ pageset2_size, pageset2_sizelow,
+
+ /* Nosave */
+ numnosave, extra_pagedir_pages_allocated,
+ numnosave - extra_pagedir_pages_allocated,
+
+ /* Storage */
+ storage_allocated,
+ MAIN_STORAGE_NEEDED(1), HEADER_STORAGE_NEEDED,
+ STORAGE_NEEDED(1),
+ storage_available,
+
+ /* Needed */
+ RAM_TO_SUSPEND - real_nr_free_pages() - nr_free_highpages(),
+ STORAGE_NEEDED(1) - storage_available,
+ (image_size_limit > 0) ? (STORAGE_NEEDED(1) - (image_size_limit << 8)) : 0);
+}
+#else
+#define display_stats() do { } while(0)
+#endif
+
+/* suspend2_recalculate_stats
+ *
+ * Eaten is the number of pages which have been eaten.
+ * Pagedirincluded is the number of pages which have been allocated for the pagedir.
+ */
+struct pageset_sizes_result suspend2_recalculate_stats(void)
+{
+ struct pageset_sizes_result result;
+
+ suspend2_mark_pages_for_pageset2(); /* Need to call this before getting pageset1_size! */
+ result = count_data_pages();
+ pageset1_sizelow = result.size1low;
+ pageset2_sizelow = result.size2low;
+ pagedir1.lastpageset_size = pageset1_size = result.size1;
+ pagedir2.lastpageset_size = pageset2_size = result.size2;
+ storage_available = active_writer->ops.writer.storage_available();
+ return result;
+}
+
+/* update_image
+ *
+ * Allocate [more] memory and storage for the image.
+ */
+static int update_image(void)
+{
+ struct pageset_sizes_result result;
+ int result2, param_used;
+
+ result = suspend2_recalculate_stats();
+
+ /* Include allowance for growth in pagedir1 while writing pagedir 2 */
+ if (suspend2_allocate_extra_pagedir_memory(&pagedir1,
+ pageset1_size + EXTRA_PD1_PAGES_ALLOWANCE,
+ pageset2_sizelow)) {
+ suspend_message(SUSPEND_EAT_MEMORY, SUSPEND_LOW, 1,
+ "Still need to get more pages for pagedir 1.\n");
+ return 1;
+ }
+
+ thaw_processes(FREEZER_KERNEL_THREADS);
+
+ param_used = MAIN_STORAGE_NEEDED(1);
+ if ((result2 = active_writer->ops.writer.allocate_storage(param_used))) {
+ suspend_message(SUSPEND_EAT_MEMORY, SUSPEND_LOW, 1,
+ "Still need to get more storage space for the image proper.\n");
+ storage_allocated = active_writer->ops.writer.storage_allocated();
+ freeze_processes(1);
+ return 1;
+ }
+
+ param_used = HEADER_STORAGE_NEEDED;
+ if ((result2 = active_writer->ops.writer.allocate_header_space(HEADER_STORAGE_NEEDED))) {
+ suspend_message(SUSPEND_EAT_MEMORY, SUSPEND_LOW, 1,
+ "Still need to get more storage space for header.\n");
+ freeze_processes(1);
+ storage_allocated = active_writer->ops.writer.storage_allocated();
+ return 1;
+ }
+
+ header_space_allocated = HEADER_STORAGE_NEEDED;
+
+ /*
+ * Allocate remaining storage space, if possible, up to the
+ * maximum we know we'll need. It's okay to allocate the
+ * maximum if the writer is the swapwriter, but
+ * we don't want to grab all available space on an NFS share.
+ * We therefore ignore the expected compression ratio here,
+ * thereby trying to allocate the maximum image size we could
+ * need (assuming compression doesn't expand the image), but
+ * don't complain if we can't get the full amount we're after.
+ */
+
+ active_writer->ops.writer.allocate_storage(
+ min(storage_available,
+ MAIN_STORAGE_NEEDED(0) + 100));
+
+ storage_allocated = active_writer->ops.writer.storage_allocated();
+
+ freeze_processes(1);
+
+ suspend2_recalculate_stats();
+ display_stats();
+
+ suspend_message(SUSPEND_EAT_MEMORY, SUSPEND_LOW, 1,
+ "Amount still needed (%d) > 0:%d. Header: %d < %d: %d,"
+ " Storage allocd: %d < %d + %d: %d.\n",
+ amount_needed(0),
+ (amount_needed(0) > 0),
+ header_space_allocated, HEADER_STORAGE_NEEDED,
+ header_space_allocated < HEADER_STORAGE_NEEDED,
+ storage_allocated,
+ HEADER_STORAGE_NEEDED, MAIN_STORAGE_NEEDED(1),
+ storage_allocated <
+ (HEADER_STORAGE_NEEDED + MAIN_STORAGE_NEEDED(1)));
+
+ check_shift_keys(0, NULL);
+
+ return ((amount_needed(0) > 0) ||
+ header_space_allocated < HEADER_STORAGE_NEEDED ||
+ storage_allocated <
+ (HEADER_STORAGE_NEEDED + MAIN_STORAGE_NEEDED(1)));
+}
+
+/* --------------------------------------------------------------------------- */
+
+/* attempt_to_freeze
+ *
+ * Try to freeze processes.
+ */
+
+static int attempt_to_freeze(void)
+{
+ int result;
+
+ /* Stop processes before checking again */
+ thaw_processes(FREEZER_ALL_THREADS);
+ suspend2_prepare_status(1, 1, "Freezing processes");
+ result = freeze_processes(0);
+
+ if (result) {
+ SET_RESULT_STATE(SUSPEND_ABORTED);
+ SET_RESULT_STATE(SUSPEND_FREEZING_FAILED);
+ } else
+ arefrozen = 1;
+
+ return result;
+}
+
+/* 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 orig_memory_still_to_eat, last_amount_needed = 0, times_criteria_met = 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 ------------- */
+
+
+ suspend2_recalculate_stats();
+ display_stats();
+
+ orig_memory_still_to_eat = amount_needed(1);
+ last_amount_needed = orig_memory_still_to_eat;
+
+ switch (image_size_limit) {
+ case -1: /* Don't eat any memory */
+ if (orig_memory_still_to_eat) {
+ SET_RESULT_STATE(SUSPEND_ABORTED);
+ SET_RESULT_STATE(SUSPEND_WOULD_EAT_MEMORY);
+ }
+ break;
+ case -2: /* Free caches only */
+ free_flags = GFP_NOIO | __GFP_HIGHMEM;
+ break;
+ default:
+ free_flags = GFP_ATOMIC | __GFP_HIGHMEM;
+ }
+
+ /* ----------- Stage 2: Eat memory ------------- */
+
+ while (((!EATEN_ENOUGH_MEMORY()) || (image_size_limit == -2)) &&
+ (!TEST_RESULT_STATE(SUSPEND_ABORTED)) &&
+ (times_criteria_met < 10)) {
+ int amount_freed;
+ int amount_wanted = orig_memory_still_to_eat - amount_needed(1);
+
+ suspend2_prepare_status(0, 1, "Seeking to free %dMB of memory.", MB(amount_needed(1)));
+
+ if (amount_wanted < 1)
+ amount_wanted = 1; /* image_size_limit == -2 */
+
+ if (orig_memory_still_to_eat)
+ suspend2_update_status(orig_memory_still_to_eat - amount_needed(1),
+ orig_memory_still_to_eat,
+ " Image size %d ",
+ MB(STORAGE_NEEDED(1)));
+ else
+ suspend2_update_status(0, 1, "Image size %d ", MB(STORAGE_NEEDED(1)));
+
+ if ((last_amount_needed - amount_needed(1)) < 10)
+ times_criteria_met++;
+ else
+ times_criteria_met = 0;
+ last_amount_needed = amount_needed(1);
+ amount_freed = shrink_all_memory(last_amount_needed);
+ suspend2_recalculate_stats();
+ display_stats();
+
+ did_eat_memory = 1;
+
+ check_shift_keys(0, NULL);
+ }
+
+ if (did_eat_memory) {
+ unsigned long orig_state = get_suspend_state();
+ thaw_processes(FREEZER_KERNEL_THREADS);
+ /* Freeze_processes will call sys_sync too */
+ freeze_processes(1);
+ restore_suspend_state(orig_state);
+ suspend2_recalculate_stats();
+ display_stats();
+ }
+
+ /* Blank out image size display */
+ suspend2_update_status(100, 100, NULL);
+
+ if (!TEST_RESULT_STATE(SUSPEND_ABORTED)) {
+ /* Include image size limit when checking what to report */
+ if (amount_needed(1) > 0)
+ SET_RESULT_STATE(SUSPEND_UNABLE_TO_FREE_ENOUGH_MEMORY);
+
+ /* But don't include it when deciding whether to abort (soft limit) */
+ if ((amount_needed(0) > 0)) {
+ printk("Unable to free sufficient memory to suspend. Still need %d pages.\n",
+ amount_needed(1));
+ SET_RESULT_STATE(SUSPEND_ABORTED);
+ }
+
+ check_shift_keys(1, "Memory eating completed.");
+ }
+
+ return 0;
+}
+
+/* prepare_image
+ *
+ * Entry point to the whole image preparation section.
+ *
+ * We do four things:
+ * - Freeze processes;
+ * - Ensure image size constraints are met;
+ * - Complete all the preparation for saving the image,
+ * including allocation of storage. The only memory
+ * that should be needed when we're finished is that
+ * for actually storing the image (and we know how
+ * much is needed for that because the plugins tell
+ * us).
+ * - Make sure that all dirty buffers are written out.
+ */
+
+#define MAX_TRIES 4
+int suspend2_prepare_image(void)
+{
+ int result = 1, sizesought, tries = 0;
+
+ arefrozen = 0;
+
+ header_space_allocated = 0;
+
+ sizesought = 100 + memory_for_plugins();
+
+ if (attempt_to_freeze())
+ return 0;
+
+ storage_available = active_writer->ops.writer.storage_available();
+
+ if (!storage_available) {
+ printk(KERN_ERR "You need some storage available to be able to suspend.\n");
+ SET_RESULT_STATE(SUSPEND_ABORTED);
+ SET_RESULT_STATE(SUSPEND_NOSTORAGE_AVAILABLE);
+ return 0;
+ }
+
+ do {
+ suspend2_prepare_status(0, 1, "Preparing Image.");
+
+ if (eat_memory() || TEST_RESULT_STATE(SUSPEND_ABORTED))
+ break;
+
+ result = update_image();
+
+ check_shift_keys(0, NULL);
+
+ tries++;
+
+ } while ((result) && (tries < MAX_TRIES) && (!TEST_RESULT_STATE(SUSPEND_ABORTED)) &&
+ (!TEST_RESULT_STATE(SUSPEND_UNABLE_TO_FREE_ENOUGH_MEMORY)));
+
+ if (tries == MAX_TRIES)
+ abort_suspend("Unable to get sufficient storage for the image.\n");
+
+ check_shift_keys(1, "Image preparation complete.");
+
+ return !result;
+}
diff -ruNp 616-prepare_image.patch-old/kernel/power/suspend2_core/prepare_image.h 616-prepare_image.patch-new/kernel/power/suspend2_core/prepare_image.h
--- 616-prepare_image.patch-old/kernel/power/suspend2_core/prepare_image.h 1970-01-01 10:00:00.000000000 +1000
+++ 616-prepare_image.patch-new/kernel/power/suspend2_core/prepare_image.h 2005-07-04 23:14:19.000000000 +1000
@@ -0,0 +1,44 @@
+/*
+ * kernel/power/prepare_image.h
+ */
+
+extern int suspend2_prepare_image(void);
+extern struct pageset_sizes_result suspend2_recalculate_stats(void);
+extern int real_nr_free_pages(void);
+extern int image_size_limit;
+extern int pageset1_sizelow, pageset2_sizelow;
+
+struct pageset_sizes_result {
+ int size1; /* Can't be unsigned - breaks MAX function */
+ int size1low;
+ int size2;
+ int size2low;
+ int needmorespace;
+};
+
+#define MIN_FREE_RAM (max_low_pfn >> 7)
+
+#define EXTRA_PD1_PAGES_ALLOWANCE 100
+
+#define MAIN_STORAGE_NEEDED(USE_ECR) \
+ ((pageset1_size + pageset2_size + 100 + \
+ EXTRA_PD1_PAGES_ALLOWANCE) * \
+ (USE_ECR ? expected_compression_ratio() : 100) / 100)
+
+#define HEADER_BYTES_NEEDED \
+ ((extents_allocated * 2 * sizeof(unsigned long)) + \
+ sizeof(struct suspend_header) + \
+ sizeof(struct plugin_header) + \
+ (int) header_storage_for_plugins() + \
+ (PAGES_PER_BITMAP << PAGE_SHIFT) + \
+ num_plugins * \
+ (sizeof(struct plugin_header) + sizeof(int)))
+
+#define HEADER_STORAGE_NEEDED ((int) ((HEADER_BYTES_NEEDED + (int) PAGE_SIZE - 1) >> PAGE_SHIFT))
+
+#define STORAGE_NEEDED(USE_ECR) \
+ (MAIN_STORAGE_NEEDED(USE_ECR) + HEADER_STORAGE_NEEDED)
+
+#define RAM_TO_SUSPEND (1 + max((pageset1_size + EXTRA_PD1_PAGES_ALLOWANCE - pageset2_sizelow), 0) + \
+ MIN_FREE_RAM + memory_for_plugins())
+
next prev parent reply other threads:[~2005-07-06 3:36 UTC|newest]
Thread overview: 187+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-07-06 2:20 [0/48] Suspend2 2.1.9.8 for 2.6.12 Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [1/48] Suspend2 2.1.9.8 for 2.6.12: submit_intro Nigel Cunningham
2005-07-06 6:37 ` Pekka Enberg
2005-07-06 8:12 ` Pavel Machek
2005-07-06 2:20 ` [PATCH] [4/48] Suspend2 2.1.9.8 for 2.6.12: 302-init-hooks.patch Nigel Cunningham
2005-07-06 8:38 ` Shaohua Li
2005-07-06 8:35 ` Nigel Cunningham
2005-07-06 15:38 ` Bernard Blackham
2005-07-06 2:20 ` [PATCH] [3/48] Suspend2 2.1.9.8 for 2.6.12: 301-proc-acpi-sleep-activate-hook.patch Nigel Cunningham
2005-07-10 23:03 ` Christoph Hellwig
2005-07-12 6:45 ` Nigel Cunningham
[not found] ` <E1DsHMp-00062f-00@chiark.greenend.org.uk>
2005-07-12 10:07 ` Nigel Cunningham
2005-07-12 10:22 ` Matthew Garrett
2005-07-12 10:34 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [6/48] Suspend2 2.1.9.8 for 2.6.12: 351-syncthreads.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [5/48] Suspend2 2.1.9.8 for 2.6.12: 350-workthreads.patch Nigel Cunningham
2005-07-10 23:04 ` Christoph Hellwig
2005-07-12 6:40 ` Nigel Cunningham
2005-07-12 10:57 ` Pavel Machek
2005-07-12 11:07 ` Nigel Cunningham
2005-07-12 11:15 ` Pavel Machek
2005-07-12 11:25 ` Nigel Cunningham
2005-07-12 11:25 ` Pavel Machek
2005-07-12 11:45 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [2/48] Suspend2 2.1.9.8 for 2.6.12: 300-reboot-handler-hook.patch Nigel Cunningham
2005-07-06 10:08 ` Pekka Enberg
2005-07-06 10:18 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [11/48] Suspend2 2.1.9.8 for 2.6.12: 401-e820-table-support.patch Nigel Cunningham
2005-07-06 3:35 ` Zwane Mwaikambo
2005-07-06 3:44 ` Nigel Cunningham
2005-07-06 8:04 ` Pavel Machek
2005-07-06 13:29 ` Zwane Mwaikambo
2005-07-06 2:20 ` [PATCH] [13/48] Suspend2 2.1.9.8 for 2.6.12: 403-debug-pagealloc-support.patch Nigel Cunningham
2005-07-10 23:02 ` Christoph Hellwig
2005-07-12 6:48 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [10/48] Suspend2 2.1.9.8 for 2.6.12: 360-reset-kswapd-max-order-after-resume.patch Nigel Cunningham
2005-07-10 23:09 ` Christoph Hellwig
2005-07-12 9:05 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [9/48] Suspend2 2.1.9.8 for 2.6.12: 354-disable-mce-checking-during-suspend-avoid-smp-deadlock.patch Nigel Cunningham
2005-07-09 11:49 ` Pavel Machek
2005-07-09 12:02 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [14/48] Suspend2 2.1.9.8 for 2.6.12: 404-check-mounts-support.patch Nigel Cunningham
2005-07-06 8:15 ` Pavel Machek
2005-07-06 8:30 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [12/48] Suspend2 2.1.9.8 for 2.6.12: 402-mtrr-remove-sysdev.patch Nigel Cunningham
2005-07-10 23:07 ` Christoph Hellwig
2005-07-12 6:33 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [7/48] Suspend2 2.1.9.8 for 2.6.12: 352-disable-pdflush-during-suspend.patch Nigel Cunningham
2005-07-06 3:34 ` Zwane Mwaikambo
2005-07-06 3:43 ` Nigel Cunningham
2005-07-06 13:27 ` Zwane Mwaikambo
2005-07-06 8:08 ` Pavel Machek
2005-07-06 9:52 ` Russell King
2005-07-10 23:07 ` Christoph Hellwig
2005-07-06 2:20 ` [PATCH] [8/48] Suspend2 2.1.9.8 for 2.6.12: 353-disable-highmem-tlb-flush-for-copyback.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [23/48] Suspend2 2.1.9.8 for 2.6.12: 600-suspend-header.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [21/48] Suspend2 2.1.9.8 for 2.6.12: 550-documentation.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [15/48] Suspend2 2.1.9.8 for 2.6.12: 405-clear-swapfile-bdev-in-swapoff.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [20/48] Suspend2 2.1.9.8 for 2.6.12: 520-version-specific-x86_64.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [19/48] Suspend2 2.1.9.8 for 2.6.12: 510-version-specific-mac.patch Nigel Cunningham
2005-07-06 3:49 ` Nigel Cunningham
2005-07-06 5:30 ` hugang
2005-07-06 6:03 ` Nigel Cunningham
2005-07-06 3:53 ` Zwane Mwaikambo
2005-07-06 3:59 ` Nigel Cunningham
2005-07-06 13:40 ` Zwane Mwaikambo
2005-07-06 5:58 ` Pekka Enberg
2005-07-06 6:21 ` Nigel Cunningham
2005-07-06 10:04 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [16/48] Suspend2 2.1.9.8 for 2.6.12: 406-dynamic-pageflags.patch Nigel Cunningham
2005-07-06 7:46 ` Shaohua Li
2005-07-06 8:13 ` Nigel Cunningham
2005-07-06 8:30 ` Shaohua Li
2005-07-06 2:20 ` [PATCH] [18/48] Suspend2 2.1.9.8 for 2.6.12: 501-tlb-flushing-functions.patch Nigel Cunningham
2005-07-09 11:52 ` Pavel Machek
2005-07-06 2:20 ` [PATCH] [22/48] Suspend2 2.1.9.8 for 2.6.12: 560-Kconfig-and-Makefile-for-suspend2.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [17/48] Suspend2 2.1.9.8 for 2.6.12: 500-version-specific-i386.patch Nigel Cunningham
2005-07-06 3:43 ` YOSHIFUJI Hideaki / 吉藤英明
2005-07-06 2:20 ` [PATCH] [29/48] Suspend2 2.1.9.8 for 2.6.12: 606-all-settings.patch Nigel Cunningham
2005-07-10 18:03 ` Pavel Machek
2005-07-11 9:38 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [28/48] Suspend2 2.1.9.8 for 2.6.12: 605-kernel_power_suspend.patch Nigel Cunningham
2005-07-10 17:58 ` Pavel Machek
2005-07-12 8:39 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [24/48] Suspend2 2.1.9.8 for 2.6.12: 601-kernel_power_power-header.patch Nigel Cunningham
2005-07-06 3:42 ` Zwane Mwaikambo
2005-07-06 3:45 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [31/48] Suspend2 2.1.9.8 for 2.6.12: 608-compression.patch Nigel Cunningham
2005-07-09 11:55 ` Pavel Machek
2005-07-09 12:15 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [32/48] Suspend2 2.1.9.8 for 2.6.12: 609-driver-model.patch Nigel Cunningham
2005-07-06 10:10 ` Pekka Enberg
2005-07-06 12:05 ` Nigel Cunningham
2005-07-06 12:14 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [25/48] Suspend2 2.1.9.8 for 2.6.12: 602-smp.patch Nigel Cunningham
2005-07-06 12:03 ` Pekka Enberg
2005-07-06 13:21 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [27/48] Suspend2 2.1.9.8 for 2.6.12: 604-utility.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [26/48] Suspend2 2.1.9.8 for 2.6.12: 603-suspend2_common-headers.patch Nigel Cunningham
2005-07-06 10:22 ` Pekka Enberg
2005-07-06 11:41 ` Nigel Cunningham
2005-07-06 11:52 ` Pekka J Enberg
2005-07-06 11:58 ` [PATCH] [26/48] " Nigel Cunningham
2005-07-09 11:53 ` Pavel Machek
2005-07-06 2:20 ` [PATCH] [30/48] Suspend2 2.1.9.8 for 2.6.12: 607-atomic-copy.patch Nigel Cunningham
2005-07-10 18:01 ` Pavel Machek
2005-07-11 8:58 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [41/48] Suspend2 2.1.9.8 for 2.6.12: 617-proc.patch Nigel Cunningham
2005-07-06 10:03 ` Pekka Enberg
2005-07-06 2:20 ` [PATCH] [35/48] Suspend2 2.1.9.8 for 2.6.12: 611-io.patch Nigel Cunningham
2005-07-10 18:12 ` Pavel Machek
2005-07-12 8:38 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [36/48] Suspend2 2.1.9.8 for 2.6.12: 612-pagedir.patch Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [40/48] Suspend2 2.1.9.8 for 2.6.12: 616-prepare_image.patch Nigel Cunningham
2005-07-10 18:13 ` Pavel Machek
2005-07-12 8:34 ` Nigel Cunningham
2005-07-06 2:20 ` Nigel Cunningham [this message]
2005-07-10 18:18 ` [PATCH] [39/48] Suspend2 2.1.9.8 for 2.6.12: 615-poweroff.patch Pavel Machek
2005-07-12 8:31 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [38/48] Suspend2 2.1.9.8 for 2.6.12: 614-plugins.patch Nigel Cunningham
2005-07-10 18:08 ` Pavel Machek
2005-07-11 10:05 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [37/48] Suspend2 2.1.9.8 for 2.6.12: 613-pageflags.patch Nigel Cunningham
2005-07-06 12:01 ` Pekka Enberg
2005-07-07 9:30 ` Nigel Cunningham
2005-07-09 12:16 ` Pavel Machek
2005-07-09 12:32 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [33/48] Suspend2 2.1.9.8 for 2.6.12: 610-encryption.patch Nigel Cunningham
2005-07-10 18:15 ` Pavel Machek
2005-07-12 8:34 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [34/48] Suspend2 2.1.9.8 for 2.6.12: 610-extent.patch Nigel Cunningham
2005-07-06 10:14 ` Pekka Enberg
2005-07-06 2:20 ` [PATCH] [46/48] Suspend2 2.1.9.8 for 2.6.12: 622-swapwriter.patch Nigel Cunningham
2005-07-06 6:33 ` Pekka Enberg
2005-07-07 12:40 ` Nigel Cunningham
2005-07-07 13:05 ` Pekka J Enberg
2005-07-08 13:41 ` Nigel Cunningham
2005-07-07 13:32 ` [PATCH] [46/48] " Pekka Enberg
2005-07-07 21:16 ` Nigel Cunningham
2005-07-07 21:26 ` nickpiggin
2005-07-08 13:42 ` Nigel Cunningham
2005-07-08 5:49 ` Pekka J Enberg
2005-07-08 5:53 ` Pekka J Enberg
2005-07-06 2:20 ` [PATCH] [42/48] Suspend2 2.1.9.8 for 2.6.12: 618-core.patch Nigel Cunningham
2005-07-10 18:21 ` Pavel Machek
2005-07-12 6:59 ` Nigel Cunningham
2005-07-12 7:56 ` Pavel Machek
2005-07-06 2:20 ` [PATCH] [45/48] Suspend2 2.1.9.8 for 2.6.12: 621-swsusp-tidy.patch Nigel Cunningham
2005-07-06 9:55 ` Pekka Enberg
2005-07-06 2:20 ` [PATCH] [48/48] Suspend2 2.1.9.8 for 2.6.12: 624-filewriter.patch Nigel Cunningham
2005-07-06 10:07 ` Pekka Enberg
2005-07-06 10:13 ` Nigel Cunningham
2005-07-06 10:17 ` Pekka J Enberg
2005-07-09 12:10 ` [PATCH] [48/48] " Pavel Machek
2005-07-09 12:18 ` Nigel Cunningham
2005-07-10 23:14 ` Christoph Hellwig
2005-07-12 6:30 ` Nigel Cunningham
2005-07-06 2:20 ` [PATCH] [47/48] Suspend2 2.1.9.8 for 2.6.12: 623-generic-block-io.patch Nigel Cunningham
2005-07-10 18:24 ` Pavel Machek
2005-07-06 2:20 ` [PATCH] [43/48] Suspend2 2.1.9.8 for 2.6.12: 619-userspace-nofreeze.patch Nigel Cunningham
2005-07-06 6:18 ` Pekka Enberg
2005-07-10 23:15 ` Christoph Hellwig
2005-07-12 6:29 ` Nigel Cunningham
2005-07-12 14:21 ` Christoph Hellwig
2005-07-06 2:20 ` [PATCH] [44/48] Suspend2 2.1.9.8 for 2.6.12: 620-userui.patch Nigel Cunningham
2005-07-10 18:22 ` Pavel Machek
2005-07-12 6:58 ` Nigel Cunningham
2005-07-06 6:40 ` [0/48] Suspend2 2.1.9.8 for 2.6.12 Pekka Enberg
2005-07-07 12:19 ` Nigel Cunningham
2005-07-06 8:21 ` Pavel Machek
2005-07-06 8:22 ` Pavel Machek
2005-07-06 8:33 ` Nigel Cunningham
2005-07-07 0:27 ` Nigel Cunningham
2005-07-07 12:04 ` Matthew Garrett
2005-07-07 12:15 ` Nigel Cunningham
2005-07-07 12:49 ` Matthew Garrett
2005-07-07 12:56 ` Nigel Cunningham
2005-07-07 18:54 ` Rafael J. Wysocki
2005-07-07 21:21 ` Nigel Cunningham
2005-07-08 13:30 ` Stefan Seyfried
2005-07-08 22:27 ` Nigel Cunningham
2005-07-07 19:19 ` Pavel Machek
2005-07-10 23:06 ` Christoph Hellwig
2005-07-12 6:36 ` Nigel Cunningham
2005-07-12 6:41 ` Andrew Morton
2005-07-12 6:57 ` Nigel Cunningham
2005-07-12 10:25 ` 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=11206164431370@foobar.com \
--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