On Saturday 04 August 2007, Alon Bar-Lev wrote:
>
> Hello Rafael,
>
> This is *UNTESTED* suggestion for switching into lzo without the memcpy.
> Please see if I missed something as I the code combination of global
> variables,
> local memory pool and unrelated sizes is difficult to understand/maintain.
>
> Basically, I've modify the init_swap_writer() so that it is the only function
> knowing the size of the swap_map_handle needs. When you call it with
> NULL you get the number of bytes it needs.
>
> I also don't fully understand why the encryption and compression/write blocks
> are related in size.... And why you remove the encryption block from mem_size.
>
> Alon.
OK.
I did got this wrong.
Here is another attempt.
Apart of making init_swap_writer(), init_swap_reader() be responsible of the
memory
size required, I've moved buffer_size, max_block_size from global scope to the
handler structure
as it is related and not used without it.
Also I think that:
buffer_size = BUFFER_PAGES * page_size;
Should be:
buffer_size = BUFFER_PAGES * max_block_size;
As compression adds its header...
But I still don't understand the encryption stuff...
It seems that key_data points to the same location
as handle->encrypt_buffer.
Did I get this wrong?
Why mem_size is decremented?
For now, I allocated it its own space.
There is a big fact that I am missing... why use only one mem_pool?
You can malloc as much as you wish at initialization directly into
the pointers... I just don't understand what may go wrong if you do this...
I will be happy to understand why you decided to allocate one block and split
it.
Alon.
---
diff -urNp suspend.org/Makefile suspend.compress1/Makefile
--- suspend.org/Makefile 2007-07-29 21:30:27.000000000 +0300
+++ suspend.compress1/Makefile 2007-08-04 14:47:14.000000000 +0300
@@ -41,7 +41,7 @@ endif
ifdef CONFIG_COMPRESS
CC_FLAGS += -DCONFIG_COMPRESS
-SWSUSP_LD_FLAGS += -llzf
+SWSUSP_LD_FLAGS += -llzo2
endif
ifdef CONFIG_ENCRYPT
diff -urNp suspend.org/resume.c suspend.compress1/resume.c
--- suspend.org/resume.c 2007-05-13 20:53:13.000000000 +0300
+++ suspend.compress1/resume.c 2007-08-04 14:47:51.000000000 +0300
@@ -26,9 +26,7 @@
#include <string.h>
#include <errno.h>
#ifdef CONFIG_COMPRESS
-#include <lzf.h>
-#else
-#define lzf_decompress(a, b, c, d) 0
+#include <lzo/lzo1x.h>
#endif
#include "swsusp.h"
@@ -133,7 +131,7 @@ static struct config_par parameters[PARA
};
static unsigned int page_size;
-static unsigned int buffer_size;
+static unsigned int workpool_size;
static void *mem_pool;
/**
@@ -178,6 +176,7 @@ struct swap_map_handle {
unsigned int k;
int fd;
struct md5_ctx ctx;
+ unsigned int buffer_size;
#ifdef CONFIG_ENCRYPT
char *decrypt_buffer;
gcry_cipher_hd_t cipher_handle;
@@ -196,7 +195,7 @@ static int fill_buffer(struct swap_map_h
void *dst = handle->read_buffer;
int error;
- int read_ahead_areas = READ_AHEAD_SIZE/buffer_size;
+ int read_ahead_areas = READ_AHEAD_SIZE/handle->buffer_size;
int advise_first, advise_last, i;
if (!handle->k) {
@@ -223,7 +222,7 @@ static int fill_buffer(struct swap_map_h
}
handle->area_size = handle->areas[handle->k].size;
- if (handle->area_size > buffer_size)
+ if (handle->area_size > handle->buffer_size)
return -ENOMEM;
#ifdef CONFIG_ENCRYPT
if (decrypt)
@@ -243,19 +242,48 @@ static int fill_buffer(struct swap_map_h
static int init_swap_reader(struct swap_map_handle *handle, int fd, loff_t
start, void *buf)
{
+ unsigned int buffer_size;
+ unsigned int max_block_size;
+ char *p = (char *)buf;
int error;
- if (!start || !buf)
+ if (handle != NULL && buf == NULL)
return -EINVAL;
- handle->areas = buf;
- handle->areas_per_page = (page_size - sizeof(loff_t)) /
- sizeof(struct swap_area);
- handle->next_swap = (loff_t *)(handle->areas + handle->areas_per_page);
- handle->page_buffer = (char *)buf + page_size;
- handle->read_buffer = handle->page_buffer + page_size;
+
+ /* This MUST NOT be less than page_size */
+ max_block_size = page_size;
+#ifdef CONFIG_COMPRESS
+ max_block_size += sizeof(short);
+#endif
+ buffer_size = BUFFER_PAGES * max_block_size;
+
+ if (handle != NULL) {
+ handle->areas = (struct swap_area *)p;
+ handle->areas_per_page = (page_size - sizeof(loff_t)) /
+ sizeof(struct swap_area);
+ handle->next_swap = (loff_t *)(handle->areas +
handle->areas_per_page);
+ }
+ p += page_size;
+ if (handle != NULL)
+ handle->page_buffer = p;
+ p += page_size;
+ if (handle != NULL)
+ handle->read_buffer = p;
+ p += buffer_size;
#ifdef CONFIG_ENCRYPT
- handle->decrypt_buffer = handle->read_buffer + buffer_size;
+ if (handle != NULL)
+ handle->decrypt_buffer = p;
+ p += buffer_size;
#endif
+
+ if (handle == NULL)
+ return p-(char *)buf;
+
+ if (!start)
+ return -EINVAL;
+
+ handle->buffer_size = buffer_size;
+
error = read_area(fd, handle->areas, start, page_size);
if (error)
return error;
@@ -276,21 +304,28 @@ static int restore(struct swap_map_handl
void *buf = handle->page_buffer;
block = (struct buf_block *)(handle->read_buffer + disp);
+#ifdef CONFIG_COMPRESS
if (decompress) {
unsigned short cnt = block->size;
if (cnt == page_size) {
memcpy(buf, block->data, page_size);
} else if (cnt < page_size) {
- cnt = lzf_decompress(block->data, cnt, buf, page_size);
- if (cnt != page_size)
+ lzo_uint result_len = page_size;
+
+ if (
+ lzo1x_decompress_safe((lzo_bytep)block->data,
cnt, buf, &result_len, NULL) != LZO_E_OK ||
+ result_len != page_size
+ ) {
return -ENODATA;
+ }
} else {
return -EINVAL;
}
block->size += sizeof(short);
return block->size;
}
+#endif
memcpy(buf, block, page_size);
return page_size;
}
@@ -566,7 +601,7 @@ static int read_image(int dev, int fd, s
static unsigned char orig_checksum[16], checksum[16];
int ret, error = 0;
struct swsusp_info *header = mem_pool;
- char *buffer = (char *)mem_pool + page_size;
+ char *buffer = (char *)mem_pool + workpool_size;
unsigned int nr_pages;
unsigned int size = sizeof(struct swsusp_header);
unsigned int shift = (resume_offset + 1) * page_size - size;
@@ -589,6 +624,10 @@ static int read_image(int dev, int fd, s
printf("resume: Compressed image\n");
#ifdef CONFIG_COMPRESS
decompress = 1;
+ if (lzo_init() != LZO_E_OK) {
+ fprintf(stderr, "suspend: Could not initialize
compress\n");
+ error = -ENOPKG;
+ }
#else
fprintf(stderr,"resume: Compression not supported\n");
error = -EINVAL;
@@ -818,13 +857,12 @@ int main(int argc, char *argv[])
splash_param = SPL_RESUME;
page_size = getpagesize();
- buffer_size = BUFFER_PAGES * page_size;
+ workpool_size = page_size;
+
+ mem_size = workpool_size + init_swap_reader (NULL, 0, 0, NULL);
#ifdef CONFIG_ENCRYPT
printf("resume: libgcrypt version: %s\n", gcry_check_version(NULL));
gcry_control(GCRYCTL_INIT_SECMEM, page_size, 0);
- mem_size = 3 * page_size + 2 * buffer_size;
-#else
- mem_size = 3 * page_size + buffer_size;
#endif
mem_pool = malloc(mem_size);
if (!mem_pool) {
diff -urNp suspend.org/suspend.c suspend.compress1/suspend.c
--- suspend.org/suspend.c 2007-07-29 21:30:27.000000000 +0300
+++ suspend.compress1/suspend.c 2007-08-04 14:47:04.000000000 +0300
@@ -33,9 +33,7 @@
#include <signal.h>
#include <termios.h>
#ifdef CONFIG_COMPRESS
-#include <lzf.h>
-#else
-#define lzf_compress(a, b, c, d) 0
+#include <lzo/lzo1x.h>
#endif
#include "swsusp.h"
@@ -61,10 +59,11 @@ static int suspend_loglevel = SUSPEND_LO
static char compute_checksum;
#ifdef CONFIG_COMPRESS
static char compress;
+static lzo_byte compress_work_buffer[LZO1X_1_MEM_COMPRESS];
#else
#define compress 0
#endif
-static unsigned long compr_diff;
+static unsigned long compr_diff = 0;
#ifdef CONFIG_ENCRYPT
static char encrypt;
static char use_RSA;
@@ -170,9 +169,8 @@ static struct config_par parameters[PARA
};
static unsigned int page_size;
-/* This MUST NOT be less than page_size */
-static unsigned int max_block_size;
-static unsigned int buffer_size;
+/* This is for misc operations */
+static unsigned int workpool_size;
static void *mem_pool;
#ifdef CONFIG_ENCRYPT
struct key_data *key_data;
@@ -263,26 +261,68 @@ struct swap_map_handle {
unsigned int k;
int dev, fd;
struct md5_ctx ctx;
+ unsigned int buffer_size;
+ unsigned int max_block_size;
#ifdef CONFIG_ENCRYPT
unsigned char *encrypt_buffer;
#endif
};
+/*
+ * If handle and buf are NULL, returns required memory size
+ */
static int
init_swap_writer(struct swap_map_handle *handle, int dev, int fd, void *buf)
{
- if (!buf)
+ unsigned int buffer_size;
+ unsigned int max_block_size;
+ char *p = (char *)buf;
+
+ if (handle != NULL && buf == NULL)
return -EINVAL;
- handle->areas = buf;
- handle->areas_per_page = (page_size - sizeof(loff_t)) /
- sizeof(struct swap_area);
- handle->next_swap = (loff_t *)(handle->areas + handle->areas_per_page);
- handle->page_buffer = (char *)buf + page_size;
- handle->write_buffer = handle->page_buffer + page_size;
+
+ /* This MUST NOT be less than page_size */
+ max_block_size = page_size;
+#ifdef CONFIG_COMPRESS
+ max_block_size += sizeof(short);
+#endif
+
+ buffer_size = BUFFER_PAGES * max_block_size;
+
+ if (handle != NULL) {
+ handle->areas = (struct swap_area *)p;
+ handle->areas_per_page = (page_size - sizeof(loff_t)) /
+ sizeof(struct swap_area);
+ handle->next_swap = (loff_t *)(handle->areas +
handle->areas_per_page);
+ }
+ p += page_size;
+ if (handle != NULL)
+ handle->page_buffer = p;
+ p += page_size;
+ if (handle != NULL)
+ handle->write_buffer = p;
+ p += buffer_size;
+#ifdef CONFIG_COMPRESS
+ /*
+ * This leaves room for safeguard of lzo
+ * uncompressable block
+ * operations, as we use block size
+ * of page_size, we should have this
+ * amount at the end of the buffer.
+ */
+ p += page_size/16+64+3;
+#endif
#ifdef CONFIG_ENCRYPT
- handle->encrypt_buffer = (unsigned char *)(handle->write_buffer +
- buffer_size);
+ if (handle != NULL)
+ handle->encrypt_buffer = (unsigned char *)p;
+ p += buffer_size;
#endif
+ if (handle == NULL)
+ return p-(char *)buf;
+
+ handle->buffer_size = buffer_size;
+ handle->max_block_size = max_block_size;
+
memset(handle->areas, 0, page_size);
handle->cur_swap = get_swap_page(dev);
if (!handle->cur_swap)
@@ -306,12 +346,15 @@ static int prepare(struct swap_map_handl
void *buf = handle->page_buffer;
block = (struct buf_block *)(handle->write_buffer + disp);
+#ifdef CONFIG_COMPRESS
if (compress) {
- unsigned short cnt;
+ lzo_uint cnt = 0;
- cnt = lzf_compress(buf, page_size,
- block->data, page_size - sizeof(short));
- if (!cnt) {
+ /* NOTICE: Assuming block->data large enough as lzo does not
check for limits */
+ if (
+ lzo1x_1_compress(buf, page_size,
(lzo_bytep)block->data, &cnt, compress_work_buffer) != LZO_E_OK ||
+ cnt >= page_size - sizeof(short)
+ ) {
memcpy(block->data, buf, page_size);
cnt = page_size;
} else {
@@ -322,6 +365,7 @@ static int prepare(struct swap_map_handl
cnt += sizeof(short);
return cnt;
}
+#endif
memcpy(block, buf, page_size);
return page_size;
}
@@ -381,8 +425,8 @@ static int swap_write_page(struct swap_m
return try_get_more_swap(handle);
}
- if (handle->cur_alloc + max_block_size <= buffer_size) {
- if (handle->cur_area.size + max_block_size <=
handle->cur_alloc) {
+ if (handle->cur_alloc + handle->max_block_size <= handle->buffer_size) {
+ if (handle->cur_area.size + handle->max_block_size <=
handle->cur_alloc) {
handle->cur_area.size += prepare(handle,
handle->cur_area.size);
return 0;
}
@@ -596,17 +640,15 @@ int write_image(int snapshot_fd, int res
return -ENOSPC;
}
error = init_swap_writer(&handle, snapshot_fd, resume_fd,
- (char *)mem_pool + page_size);
+ (char *)mem_pool + workpool_size);
if (!error) {
header->map_start = handle.cur_swap;
header->image_flags = 0;
- max_block_size = page_size;
if (compute_checksum)
header->image_flags |= IMAGE_CHECKSUM;
if (compress) {
header->image_flags |= IMAGE_COMPRESSED;
- max_block_size += sizeof(short);
}
#ifdef CONFIG_ENCRYPT
@@ -1294,6 +1336,9 @@ int main(int argc, char *argv[])
int orig_loglevel, orig_swappiness, ret;
struct rlimit rlim;
static char chroot_path[MAX_STR_LEN];
+#ifdef CONFIG_ENCRYPT
+ int encrypt_buffer_size;
+#endif
/* Make sure the 0, 1, 2 descriptors are open before opening the
* snapshot and resume devices
@@ -1346,13 +1391,24 @@ int main(int argc, char *argv[])
shutdown_method = SHUTDOWN_METHOD_REBOOT;
}
+#ifdef CONFIG_COMPRESS
+ if (compress) {
+ if (lzo_init() != LZO_E_OK) {
+ fprintf(stderr, "suspend: Could not initialize
compress\n");
+ return ENOPKG;
+ }
+ }
+#endif
+
page_size = getpagesize();
- buffer_size = BUFFER_PAGES * page_size;
+ workpool_size = page_size;
- mem_size = 3 * page_size + buffer_size;
+ mem_size = workpool_size + init_swap_writer (NULL, 0, 0, NULL);
#ifdef CONFIG_ENCRYPT
+ /* Am I missing something, or this can be sizeof (struct key_data)? */
+ encrypt_buffer_size = BUFFER_PAGES * page_size;
if (encrypt)
- mem_size += buffer_size;
+ mem_size += encrypt_buffer_size;
#endif
mem_pool = malloc(mem_size);
if (!mem_pool) {
@@ -1374,7 +1430,7 @@ int main(int argc, char *argv[])
}
}
if (encrypt) {
- mem_size -= buffer_size;
+ mem_size -= encrypt_buffer_size;
key_data = (struct key_data *)((char *)mem_pool + mem_size);
generate_key();
}
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Suspend-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/suspend-devel