Fix swsusp with PREEMPT

Pavel Machek (pavel@ucw.cz)
Wed, 9 Jul 2003 23:38:21 +0200


Hi!

This fixes swsusp with CONFIG_PREEMPT and makes locking a bit more
obvious. Please apply,
Pavel

--- clean/kernel/suspend.c 2003-05-27 13:44:03.000000000 +0200
+++ linux/kernel/suspend.c 2003-07-09 23:30:12.000000000 +0200
@@ -692,7 +694,6 @@
printk(KERN_CRIT "%sCouldn't get enough free pages, on %d pages short\n",
name_suspend, nr_needed_pages-nr_free_pages());
root_swap = 0xFFFF;
- spin_unlock_irq(&suspend_pagedir_lock);
return 1;
}
si_swapinfo(&i); /* FIXME: si_swapinfo(&i) returns all swap devices information.
@@ -700,7 +701,6 @@
if (i.freeswap < nr_needed_pages) {
printk(KERN_CRIT "%sThere's not enough swap space available, on %ld pages short\n",
name_suspend, nr_needed_pages-i.freeswap);
- spin_unlock_irq(&suspend_pagedir_lock);
return 1;
}

@@ -710,7 +710,6 @@
/* Shouldn't happen */
printk(KERN_CRIT "%sCouldn't allocate enough pages\n",name_suspend);
panic("Really should not happen");
- spin_unlock_irq(&suspend_pagedir_lock);
return 1;
}
nr_copy_pages_check = nr_copy_pages;
@@ -724,12 +723,9 @@
* End of critical section. From now on, we can write to memory,
* but we should not touch disk. This specially means we must _not_
* touch swap space! Except we must write out our image of course.
- *
- * Following line enforces not writing to disk until we choose.
*/

printk( "critical section/: done (%d pages copied)\n", nr_copy_pages );
- spin_unlock_irq(&suspend_pagedir_lock);
return 0;
}

@@ -808,6 +804,24 @@
#endif
}

+/* do_magic() is implemented in arch/?/kernel/suspend_asm.S, and basically does:
+
+ if (!resume) {
+ do_magic_suspend_1();
+ save_processor_state();
+ SAVE_REGISTERS
+ do_magic_suspend_2();
+ return;
+ }
+ GO_TO_SWAPPER_PAGE_TABLES
+ do_magic_resume_1();
+ COPY_PAGES_BACK
+ RESTORE_REGISTERS
+ restore_processor_state();
+ do_magic_resume_2();
+
+ */
+
void do_magic_suspend_1(void)
{
mb();
@@ -818,8 +832,13 @@

void do_magic_suspend_2(void)
{
+ int is_problem;
read_swapfiles();
- if (!suspend_prepare_image()) { /* suspend_save_image realeses suspend_pagedir_lock */
+ is_problem = suspend_prepare_image();
+ spin_unlock_irq(&suspend_pagedir_lock);
+ if (!is_problem) {
+ kernel_fpu_end(); /* save_processor_state() does kernel_fpu_begin, and we need to revert it in order to pass in_atomic() checks */
+ BUG_ON(in_atomic());
suspend_save_image();
suspend_power_down(); /* FIXME: if suspend_power_down is commented out, console is lost after few suspends ?! */
}
@@ -1224,13 +1243,13 @@
orig_loglevel = console_loglevel;
console_loglevel = new_loglevel;

- if(!resume_file[0] && resume_status == RESUME_SPECIFIED) {
+ if (!resume_file[0] && resume_status == RESUME_SPECIFIED) {
printk( "suspension device unspecified\n" );
return;
}

printk( "resuming from %s\n", resume_file);
- if(read_suspend_image(resume_file, 0))
+ if (read_suspend_image(resume_file, 0))
goto read_failure;
do_magic(1);
panic("This never returns");

-- 
When do you have a heart between your knees?
[Johanka's followup: and *two* hearts?]
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/