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 Suspend-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/suspend-devel