]> git.hungrycats.org Git - linux/commitdiff
[PATCH] swsusp: cleanup
authorPavel Machek <pavel@suse.cz>
Wed, 29 May 2002 03:00:18 +0000 (20:00 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Wed, 29 May 2002 03:00:18 +0000 (20:00 -0700)
 - use list_for_each in head_of_free_region
 - cleanups from 2.4
 - fix for usb
 - kill broken queueing

17 files changed:
Documentation/kernel-parameters.txt
arch/i386/kernel/acpi_wakeup.S
arch/i386/kernel/setup.c
drivers/acpi/acpi_system.c
drivers/block/floppy.c
drivers/block/loop.c
drivers/usb/core/hub.c
fs/buffer.c
fs/jbd/journal.c
fs/reiserfs/journal.c
include/asm-i386/suspend.h
include/linux/suspend.h
include/linux/tqueue.h
kernel/suspend.c
mm/page_alloc.c
mm/pdflush.c
mm/vmscan.c

index be8601c6164741399bd6c89ed6d4942b252e510c..a87aed2bb6ed41199ca8abedcdb5c49aaf855cbf 100644 (file)
@@ -45,6 +45,7 @@ restrictions referred to are that the relevant option is valid if:
        SERIAL  Serial support is enabled.
        SMP     The kernel is an SMP kernel.
        SOUND   Appropriate sound system support is enabled.
+       SWSUSP  Software suspension is enabled.
        V4L     Video For Linux support is enabled.
        VGA     The VGA console has been enabled.
        VT      Virtual terminal support is enabled.
@@ -392,6 +393,8 @@ running once the system is up.
                        initial RAM disk.
 
        nointroute      [IA-64]
+
+       noresume        [SWSUSP] Disables resume and restore original swap space.
  
        no-scroll       [VGA]
 
@@ -519,6 +522,8 @@ running once the system is up.
 
        reserve=        [KNL,BUGS] force the kernel to ignore some iomem area.
 
+       resume=         [SWSUSP] specify the partition device for software suspension.
+
        riscom8=        [HW,SERIAL]
 
        ro              [KNL] Mount root device read-only on boot.
index 92449354076b5bf9262aa659a8b36874742ddffb..bafff9b4f4cbb38682b14b67370ce4a6de32eeb1 100644 (file)
@@ -262,7 +262,6 @@ ENTRY(saved_esp)    .long   0
 
 ENTRY(saved_magic)     .long   0
 ENTRY(saved_magic2)    .long   0       
-ENTRY(saved_videomode) .long   0
 
 ALIGN
 # saved registers
index 0a3f51873d1049b4288a502331a76599ca2c60f5..ec1f85096d562e7f2bc15464739007825a4dd10e 100644 (file)
@@ -168,6 +168,8 @@ void __init visws_get_board_type_and_rev(void);
 static int disable_x86_serial_nr __initdata = 1;
 static int disable_x86_fxsr __initdata = 0;
 
+unsigned long saved_videomode;
+
 extern unsigned long saved_videomode;
 
 /*
@@ -684,10 +686,8 @@ void __init setup_arch(char **cmdline_p)
        drive_info = DRIVE_INFO;
        screen_info = SCREEN_INFO;
        apm_info.bios = APM_BIOS_INFO;
-#ifdef CONFIG_ACPI_SLEEP
        saved_videomode = VIDEO_MODE;
        printk("Video mode to be used for restore is %lx\n", saved_videomode);
-#endif
        if( SYS_DESC_TABLE.length != 0 ) {
                MCA_bus = SYS_DESC_TABLE.table[3] &0x2;
                machine_id = SYS_DESC_TABLE.table[0];
index 980796ace06e1c8f069c3fa18cd469901f3ab4c9..992426b45ddb8a0af893723821eb90deae5fc12b 100644 (file)
@@ -709,11 +709,9 @@ acpi_system_write_sleep (
        if (!system->states[state])
                return_VALUE(-ENODEV);
 
-       
 #ifdef CONFIG_SOFTWARE_SUSPEND
        if (state == 4) {
-               /* We are working from process context, that's why we may call it directly. */ 
-               do_software_suspend();
+               software_suspend();
                return_VALUE(count);
        }
 #endif
index 06c0764cd77ec317bdb3758f7c24fdd6209d4ff6..a746c87e9e20768c5d3681d5ab9bbe9cf4672f3e 100644 (file)
@@ -4220,14 +4220,15 @@ static int __init floppy_setup(char *str)
 
 static int have_no_fdc= -ENODEV;
 
-static struct device device_floppy;
+static struct device device_floppy = {
+       name:           "floppy",
+       bus_id:         "03?0",
+};
 
 int __init floppy_init(void)
 {
        int i,unit,drive;
 
-       strcpy(device_floppy.name, "floppy");
-       strcpy(device_floppy.bus_id, "03?0");
        register_sys_device(&device_floppy);
 
        raw_cmd = NULL;
index a63ddbe51761559a0fc539d025d79ebf2454e5f2..66df618d318b6f9f9b756192c0e5cab5a8b1d606 100644 (file)
@@ -577,7 +577,9 @@ static int loop_thread(void *data)
        daemonize();
 
        sprintf(current->comm, "loop%d", lo->lo_number);
-       current->flags |= PF_IOTHREAD;
+       current->flags |= PF_IOTHREAD;  /* loop can be used in an encrypted device
+                                          hence, it mustn't be stopped at all because it could
+                                          be indirectly used during suspension */
 
        spin_lock_irq(&current->sigmask_lock);
        sigfillset(&current->blocked);
index 654294e79d1241479108feb77bac25f501b122a2..6138dc4d44a58bd8f010db8a13a742b9fd609956 100644 (file)
@@ -25,6 +25,7 @@
 #endif
 #include <linux/usb.h>
 #include <linux/usbdevice_fs.h>
+#include <linux/suspend.h>
 
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
@@ -1064,6 +1065,8 @@ static int usb_hub_thread(void *__hub)
        /* Send me a signal to get me die (for debugging) */
        do {
                usb_hub_events();
+               if (current->flags & PF_FREEZE)
+                       refrigerator(PF_IOTHREAD);
                wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); 
        } while (!signal_pending(current));
 
index e4166036523e28332a78e95d22c6433cc38d5878..66ace03446ad786d947aa7177a0cc81a53f58454 100644 (file)
@@ -122,8 +122,6 @@ void unlock_buffer(struct buffer_head *bh)
        wake_up_buffer(bh);
 }
 
-DECLARE_TASK_QUEUE(tq_bdflush);
-
 /*
  * Block until a buffer comes unlocked.  This doesn't stop it
  * from becoming locked again - you have to lock it yourself
index 4897c69f8d38dc59ea04977cd3ed017602b75df8..f20e9f4e8c35d23accdc9b44588b4a7abe7de6c6 100644 (file)
@@ -226,7 +226,6 @@ int kjournald(void *arg)
                        journal->j_commit_interval / HZ);
        list_add(&journal->j_all_journals, &all_journals);
 
-       current->flags |= PF_KERNTHREAD;
        /* And now, wait forever for commit wakeup events. */
        while (1) {
                if (journal->j_flags & JFS_UNMOUNT)
index e495970481bc768fa594b7ecf64a618dfbfaa632..a5a6eae9c08b0ad2fa09668cd7271e89e72e3049 100644 (file)
@@ -1888,7 +1888,6 @@ static int reiserfs_journal_commit_thread(void *nullp) {
   spin_unlock_irq(&current->sigmask_lock);
 
   sprintf(current->comm, "kreiserfsd") ;
-  current->flags |= PF_KERNTHREAD;
   lock_kernel() ;
   while(1) {
 
index 16fcd5af6c65c9505dd036831b4fed1b45b1968d..203e10e23cb7b4dcbe061d026a786988d536b6a3 100644 (file)
@@ -1,13 +1,8 @@
-#ifndef __ASM_I386_SUSPEND_H
-#define __ASM_I386_SUSPEND_H
-#endif
-
 /*
  * Copyright 2001-2002 Pavel Machek <pavel@suse.cz>
  * Based on code
  * Copyright 2001 Patrick Mochel <mochel@osdl.org>
  */
-#if defined(SUSPEND_C) || defined(ACPI_C)
 #include <asm/desc.h>
 #include <asm/i387.h>
 
@@ -225,7 +220,6 @@ static inline void restore_processor_context (void)
        do_fpu_end();
 }
 
-#endif
 #ifdef SUSPEND_C
 /* Local variables for do_magic */
 static int loop __nosavedata = 0;
index 3ede8ad272707d85ec17cd0dd2c90ab56855e04e..fa09ebfc582eb68884e0117fa7fc5ef667dcf026 100644 (file)
@@ -1,7 +1,9 @@
 #ifndef _LINUX_SWSUSP_H
 #define _LINUX_SWSUSP_H
 
+#if defined(SUSPEND_C) || defined(ACPI_C)
 #include <asm/suspend.h>
+#endif
 #include <linux/swap.h>
 #include <linux/notifier.h>
 #include <linux/config.h>
index a325ce1792c52667070f2a685a6fbd4751a5f5d6..3d30470272295c806d1ae39c0d5dd85ae76d2360 100644 (file)
@@ -66,7 +66,7 @@ typedef struct list_head task_queue;
 #define DECLARE_TASK_QUEUE(q)  LIST_HEAD(q)
 #define TQ_ACTIVE(q)           (!list_empty(&q))
 
-extern task_queue tq_timer, tq_immediate, tq_bdflush;
+extern task_queue tq_timer, tq_immediate;
 
 /*
  * To implement your own list of active bottom halfs, use the following
index ad527e5addd85da3385b60d2939b1de4bd7ad628..565daab071436ccaf36f349130d096c8d7c2079d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/kernel/swsusp.c
+ * linux/kernel/suspend.c
  *
  * This file is to realize architecture-independent
  * machine suspend feature using pretty near only high-level routines
  * For TODOs,FIXMEs also look in Documentation/swsusp.txt
  */
 
-/*
- * TODO:
- *
- * - we should launch a kernel_thread to process suspend request, cleaning up
- * bdflush from this task. (check apm.c for something similar).
- */
-
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/swapctl.h>
@@ -65,6 +58,7 @@
 #include <linux/swap.h>
 #include <linux/pm.h>
 #include <linux/device.h>
+#include <linux/buffer_head.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -78,7 +72,7 @@ unsigned char software_suspend_enabled = 0;
    we probably do not take enough locks for switching consoles, etc,
    so bad things might happen.
 */
-#ifndef CONFIG_VT
+#if !defined(CONFIG_VT) || !defined(CONFIG_VT_CONSOLE)
 #undef SUSPEND_CONSOLE
 #endif
 
@@ -152,7 +146,7 @@ static const char *name_resume = "Resume Machine: ";
 #define        DEBUG_DEFAULT   1
 #undef DEBUG_PROCESS
 #undef DEBUG_SLOW
-#define TEST_SWSUSP 0          /* Set to 1 to reboot instead of halt machine after suspension */
+#define TEST_SWSUSP 1          /* Set to 1 to reboot instead of halt machine after suspension */
 
 #ifdef DEBUG_DEFAULT
 #define PRINTD(func, f, a...)  \
@@ -775,7 +769,10 @@ void suspend_power_down(void)
                machine_restart(NULL);
        else
 #endif
+       {
+               device_shutdown();
                machine_power_off();
+       }
 
        printk(KERN_EMERG "%sProbably not capable for powerdown. System halted.\n", name_suspend);
        machine_halt();
@@ -783,9 +780,6 @@ void suspend_power_down(void)
        /* NOTREACHED */
 }
 
-/* forward decl */
-void do_software_suspend(void);
-
 /*
  * Magic happens here
  */
@@ -822,7 +816,6 @@ static void do_magic_resume_2(void)
 #ifdef SUSPEND_CONSOLE
        update_screen(fg_console);      /* Hmm, is this the problem? */
 #endif
-       suspend_tq.routine = (void *)do_software_suspend;
 }
 
 static void do_magic_suspend_1(void)
@@ -851,7 +844,6 @@ static void do_magic_suspend_2(void)
        drivers_resume(RESUME_PHASE1);
        spin_unlock_irq(&suspend_pagedir_lock);
        mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME);
-       suspend_tq.routine = (void *)do_software_suspend;
        printk(KERN_WARNING "%sLeaving do_magic_suspend_2...\n", name_suspend); 
 }
 
@@ -859,43 +851,38 @@ static void do_magic_suspend_2(void)
 #include <asm/suspend.h>
 
 /*
- * This function is triggered using process bdflush. We try to swap out as
- * much as we can then make a copy of the occupied pages in memory so we can
- * make a copy of kernel state atomically, the I/O needed by saving won't
- * bother us anymore.
+ * We try to swap out as much as we can then make a copy of the
+ * occupied pages in memory so we can make a copy of kernel state
+ * atomically, the I/O needed by saving won't bother us anymore. 
  */
 void do_software_suspend(void)
 {
        arch_prepare_suspend();
-       if (!prepare_suspend_console()) {
-               if (!prepare_suspend_processes()) {
-                       free_some_memory();
-
-                       /* No need to invalidate any vfsmnt list -- they will be valid after resume, anyway.
-                        *
-                        * We sync here -- so you have consistent filesystem state when things go wrong.
-                        * -- so that noone writes to disk after we do atomic copy of data.
-                        */
-                       PRINTS("Syncing disks before copy\n");
-                       do_suspend_sync();
-                       if(drivers_suspend()==0)
-                               do_magic(0);                    /* This function returns after machine woken up from resume */
-                       PRINTR("Restarting processes...\n");
-                       thaw_processes();
-               }
+       if (prepare_suspend_console())
+               printk( "Can't allocate a console... proceeding\n");
+       if (!prepare_suspend_processes()) {
+               free_some_memory();
+               
+               /* No need to invalidate any vfsmnt list -- they will be valid after resume, anyway.
+                *
+                * We sync here -- so you have consistent filesystem state when things go wrong.
+                * -- so that noone writes to disk after we do atomic copy of data.
+                */
+               PRINTS("Syncing disks before copy\n");
+               do_suspend_sync();
+               if(drivers_suspend()==0)
+                       do_magic(0);                    /* This function returns after machine woken up from resume */
+               PRINTR("Restarting processes...\n");
+               thaw_processes();
        }
        software_suspend_enabled = 1;
        MDELAY(1000);
        restore_console ();
 }
 
-struct tq_struct suspend_tq =
-       { routine: (void *)(void *)do_software_suspend, 
-         data: 0 };
-
 /*
- * This is the trigger function, we must queue ourself since we
- * can be called from interrupt && bdflush context is needed
+ * This is main interface to the outside world. It needs to be
+ * called from process context.
  */
 void software_suspend(void)
 {
@@ -903,8 +890,8 @@ void software_suspend(void)
                return;
 
        software_suspend_enabled = 0;
-       queue_task(&suspend_tq, &tq_bdflush);
-       wakeup_bdflush();
+       BUG_ON(in_interrupt());
+       do_software_suspend();
 }
 
 /* More restore stuff */
@@ -1123,6 +1110,7 @@ static int resume_try_to_read(const char * specialfile, int noresume)
        pagedir_order = get_bitmask_order(nr_pgdir_pages);
 
        error = -ENOMEM;
+       free_page((unsigned long) cur);
        pagedir_nosave = (suspend_pagedir_t *)__get_free_pages(GFP_ATOMIC, pagedir_order);
        if(!pagedir_nosave)
                goto resume_read_error;
index fb05fef5d8dc3e8451e3947505f49fef698e8fe8..d36941ae24517427cdbcbefe2ab9d17164847ddc 100644 (file)
@@ -247,42 +247,26 @@ static struct page * rmqueue(zone_t *zone, unsigned int order)
 }
 
 #ifdef CONFIG_SOFTWARE_SUSPEND
-int is_head_of_free_region(struct page *p)
+int is_head_of_free_region(struct page *page)
 {
-       pg_data_t *pgdat = pgdat_list;
-       unsigned type;
-       unsigned long flags;
-
-       for (type=0;type < MAX_NR_ZONES; type++) {
-               zone_t *zone = pgdat->node_zones + type;
-               int order = MAX_ORDER - 1;
-               free_area_t *area;
-               struct list_head *head, *curr;
-               spin_lock_irqsave(&zone->lock, flags);  /* Should not matter as we need quiescent system for suspend anyway, but... */
-
-               do {
-                       area = zone->free_area + order;
-                       head = &area->free_list;
-                       curr = head;
+        zone_t *zone = page_zone(page);
+        unsigned long flags;
+       int order;
+       list_t *curr;
 
-                       for(;;) {
-                               if(!curr) {
-//                                     printk("FIXME: this should not happen but it does!!!");
-                                       break;
-                               }
-                               if(p != memlist_entry(curr, struct page, list)) {
-                                       curr = memlist_next(curr);
-                                       if (curr == head)
-                                               break;
-                                       continue;
-                               }
+       /*
+        * Should not matter as we need quiescent system for
+        * suspend anyway, but...
+        */
+       spin_lock_irqsave(&zone->lock, flags);
+       for (order = MAX_ORDER - 1; order >= 0; --order)
+               list_for_each(curr, &zone->free_area[order].free_list)
+                       if (page == list_entry(curr, struct page, list)) {
+                               spin_unlock_irqrestore(&zone->lock, flags);
                                return 1 << order;
                        }
-               } while(order--);
-               spin_unlock_irqrestore(&zone->lock, flags);
-
-       }
-       return 0;
+       spin_unlock_irqrestore(&zone->lock, flags);
+        return 0;
 }
 #endif /* CONFIG_SOFTWARE_SUSPEND */
 
index 632327dfb61d9bccb6eeded6e001b11d7cff1ea3..16aa09b697fdca8537e8db73bcac792c75e2e948 100644 (file)
@@ -91,7 +91,7 @@ static int __pdflush(struct pdflush_work *my_work)
        recalc_sigpending();
        spin_unlock_irq(&current->sigmask_lock);
 
-       current->flags |= PF_FLUSHER | PF_KERNTHREAD;
+       current->flags |= PF_FLUSHER;
        my_work->fn = NULL;
        my_work->who = current;
 
@@ -106,11 +106,8 @@ static int __pdflush(struct pdflush_work *my_work)
                set_current_state(TASK_INTERRUPTIBLE);
                spin_unlock_irq(&pdflush_lock);
 
-#ifdef CONFIG_SOFTWARE_SUSPEND
-               run_task_queue(&tq_bdflush);
                if (current->flags & PF_FREEZE)
                        refrigerator(PF_IOTHREAD);
-#endif
                schedule();
 
                if (my_work->fn)
index 212778f09668276519b49d7c9d1366fd7de3e58a..167413089968cdd88ca3412ea18a36243254d1e8 100644 (file)
@@ -791,7 +791,7 @@ int kswapd(void *unused)
         * us from recursively trying to free more memory as we're
         * trying to free the first piece of memory in the first place).
         */
-       tsk->flags |= PF_MEMALLOC | PF_KERNTHREAD;
+       tsk->flags |= PF_MEMALLOC;
 
        /*
         * Kswapd main loop.