Re: 2.6.21-rc5: swsusp: Not enough free memory

Rafael J. Wysocki
2007-04-02T21:15:12Z

On Monday, 2 April 2007 10:24, Jiri Slaby wrote:
> Rafael J. Wysocki napsal(a):
> >>> On Thursday, 29 March 2007 09:44, Jiri Slaby wrote:
> >>>> swsusp: critical section:
> >>>> swsusp: Need to copy 131380 pages
> >>>> swsusp: Not enough free memory
> >>>> Error -12 suspending
> >>>> Enabling non-boot CPUs ...
>
> > As a workaround, you can try to change the initial image size so that it's
> > smaller than a half of the RAM size. If that works, I'd like to send you a
> > debug patch, if you don't mind. :-)
>
> Yes, post it.

Appended. Please send me the dmesg output from after a failing suspend
(or in case it doesn't fail, from after the first one).

> # cat /sys/power/image_size
> 524288000
> # echo disk >/sys/power/state
> error
> # echo disk >/sys/power/state
> error
> # echo $((400*1024*1024)) > /sys/power/image_size
> # echo disk >/sys/power/state
> ok
> # dmesg|grep Memory:
> Memory: 1027160k/1048256k available (2559k kernel code, 20348k reserved,
> 1114k data, 188k init)
>
> I don't undestand it too much, but can't be shared video memory involved
> somehow?

No, I don't think so. There probably is a bug in swsusp_shrink_memory().

Greetings,
Rafael

---
---
kernel/power/snapshot.c | 2 +-
kernel/power/swsusp.c | 10 +++++++---
2 files changed, 8 insertions(+), 4 deletions(-)

Index: linux-2.6.21-rc5/kernel/power/snapshot.c
===================================================================
--- linux-2.6.21-rc5.orig/kernel/power/snapshot.c
+++ linux-2.6.21-rc5/kernel/power/snapshot.c
@@ -1093,7 +1093,7 @@ static int enough_free_mem(unsigned int
}

nr_pages += count_pages_for_highmem(nr_highmem);
- pr_debug("swsusp: Normal pages needed: %u + %u + %u, available pages: %u\n",
+ printk("swsusp: Normal pages needed: %u + %u + %u, available pages: %u\n",
nr_pages, PAGES_FOR_IO, meta, free);

return free > nr_pages + PAGES_FOR_IO + meta;
Index: linux-2.6.21-rc5/kernel/power/swsusp.c
===================================================================
--- linux-2.6.21-rc5.orig/kernel/power/swsusp.c
+++ linux-2.6.21-rc5/kernel/power/swsusp.c
@@ -227,22 +227,26 @@ int swsusp_shrink_memory(void)
size = count_data_pages() + PAGES_FOR_IO;
tmp = size;
size += highmem_size;
- for_each_zone (zone)
+ for_each_zone (zone) {
+ printk("Normal pages needed: %lu\n", tmp);
+ printk("Highmem pages needed: %lu\n", highmem_size);
if (populated_zone(zone)) {
+ tmp += snapshot_additional_pages(zone);
if (is_highmem(zone)) {
highmem_size -=
zone_page_state(zone, NR_FREE_PAGES);
} else {
tmp -= zone_page_state(zone, NR_FREE_PAGES);
tmp += zone->lowmem_reserve[ZONE_NORMAL];
- tmp += snapshot_additional_pages(zone);
}
}
+ }

if (highmem_size < 0)
highmem_size = 0;

tmp += highmem_size;
+ printk("Pages needed (total): %lu\n", tmp);
if (tmp > 0) {
tmp = __shrink_memory(tmp);
if (!tmp)
@@ -252,7 +256,7 @@ int swsusp_shrink_memory(void)
tmp = __shrink_memory(size - (image_size / PAGE_SIZE));
pages += tmp;
}
- printk("\b%c", p[i++%4]);
+ /*printk("\b%c", p[i++%4]);*/
} while (tmp > 0);
do_gettimeofday(&stop);
printk("\bdone (%lu pages freed)\n", pages);