Re: [PATCH]: Compress hibernation image with LZO (in-kernel)

From: Bojan Smojver
Date: Mon Aug 02 2010 - 21:59:19 EST


On Mon, 2010-08-02 at 11:43 +1000, Bojan Smojver wrote:
> OK, get it. Will rework.

What I did today was:

1. Introduced a global variable in swap.c called swsusp_lzo_buffers. It
was declared in kernel/power/power.h as:
---------------------
extern void *swsusp_lzo_buffers;
---------------------

2. Allocation in save_image() then went like this:
---------------------
swsusp_lzo_buffers = vmalloc(LZO_WRK_SIZE + LZO_UNC_SIZE + LZO_OVH_SIZE)
;
if (!swsusp_lzo_buffers) {
printk(KERN_ERR "PM: Failed to allocate LZO buffers\n");
free_page((unsigned long)page);
return -ENOMEM;
}

wrk = swsusp_lzo_buffers;
buf = swsusp_lzo_buffers + LZO_WRK_SIZE;
---------------------

3. Deallocation in save_image() had (this is after everything has been
written to disk):
---------------------
vfree(swsusp_lzo_buffers);
swsusp_lzo_buffers = NULL;
---------------------

4. swsusp_free() had (note memset(), which would crash the kernel if
this was already freed, but pointer not NULL):
---------------------
printk (KERN_ERR "In swsusp_free().\n");
if (swsusp_lzo_buffers) {
printk (KERN_ERR "Freeing vmalloc() buffers.\n");
memset(swsusp_lzo_buffers, 0, 80 * PAGE_SIZE);
vfree(swsusp_lzo_buffers);
}
---------------------

>From all this, I only got "In swsusp_free()" printed on resume. So, it
seems that save_image() does indeed free those vmalloc()-ed buffers and
they are not saved in the image.

I even put this in hibernate.c:
---------------------
/* Restore control flow magically appears here */
restore_processor_state();
if (!in_suspend)
platform_leave(platform_mode);

printk(KERN_ERR "Resumed, checking swsusp_lzo_buffers.\n");
if (swsusp_lzo_buffers) {
printk (KERN_ERR "Setting vmalloc() buffers.\n");
memset(swsusp_lzo_buffers, 0, 80 * PAGE_SIZE);
}
---------------------

This printed just "Resumed, checking swsusp_lzo_buffers.", meaning it
was already set to NULL.

Any further comments on this? Nigel, what do you reckon?

PS. I also enhanced the patch to use overlapping compression in order to
save memory. Looks like that's causing it to be slower on compression
(we go down from 130 - 150 MB/s to around 105 - 110 MB/s), but still
over 3 times faster than regular swsusp code. Decompression remains
roughly the same around 100+ MB/s (this is double the speed of current
swsusp code). I will post this a bit later on.

--
Bojan


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/