Commit d72fb463 authored by Pavel Machek's avatar Pavel Machek Committed by Linus Torvalds

[PATCH] swsusp: cleanup

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