From: Troy H. <tro...@hp...> - 2005-02-10 22:19:24
|
I'm working on a major clean up of the lkcd kernel patch code in the 7.X.X development branch. I am planning on removing RLE compression, unless there is a strong objection not to. This means the 2 choices will be uncompressed or gzip. Lcrash will continue to work with older RLE compressed dumps, this only affects the lkcd kernel patch. I am also completely removing MEMDEV from the 7.X.X tree. Troy |
From: Jason U. <jas...@sg...> - 2005-02-11 10:47:21
|
On Thu, Feb 10, 2005 at 03:15:56PM -0700, Troy Heber wrote: > I'm working on a major clean up of the lkcd kernel patch code in the 7.X.X > development branch. I am planning on removing RLE compression, unless there > is a strong objection not to. This means the 2 choices will be uncompressed > or gzip. Lcrash will continue to work with older RLE compressed dumps, this > only affects the lkcd kernel patch. There are actually quite a few people using RLE compression for performance reasons (mostly on large systems, where we have so much memory that dump times are pushing the limits of practicality). The synchronous nature of dump I/O means the CPU time required to perform gzip compression can have a huge effect on total dump time, and using the cheaper RLE algorithm can yield a net win even though we have to write more physical blocks that way. SGI quantified this at one point and found gzip dumps were taking ~6.8 times as long as RLE dumps of comparable uncompressed size, even though the compressed dump was only about ~30% as big in the gzip case as in the RLE case. Those numbers are of course highly dependent on the ratio of CPU speed to disk speed and the compressibility of the data, but I don't think we were doing anything which could be considered an extreme corner case. Part of the problem is that the dump_gzip code uses a compression level of Z_BEST_COMPRESSION (the equivalent of gzip -9), which favors size over speed to an extreme well beyond the point of diminishing returns. It was found that by using a more moderate compression level, we could get a ~300% speed boost at the cost of a very modest (~15%) increase in dump size. That change never got pushed out to the LKCD project (I'll look into doing that and verify the results against the current codebase as soon as I get a chance), but even with a ~300% boost, gzip is still considerably slower than RLE. |
From: Troy H. <tro...@hp...> - 2005-02-11 14:08:50
|
On 02/11/05 02:46, Jason Uhlenkott wrote: > On Thu, Feb 10, 2005 at 03:15:56PM -0700, Troy Heber wrote: > SGI quantified this at one point and found gzip dumps were taking ~6.8 > times as long as RLE dumps of comparable uncompressed size. That's a good enough argument for me! The only reason to take it out was just a general clean up of unused components, it's obviously used. > I'll look into doing that and verify the results against the current > codebase as soon as I get a chance. Excellent. Troy |
From: Jason U. <jas...@sg...> - 2005-02-12 08:09:59
|
As promised, this gives a big speed boost (~300% on a typical SGI Altix) to gzip dumps, at only a marginal cost in dump size. It also removes an incorrect comment (we don't fall back to RLE in the indicated case). Index: linux/drivers/dump/dump_gzip.c =================================================================== --- linux.orig/drivers/dump/dump_gzip.c 2005-02-11 16:12:11.444284482 -0800 +++ linux/drivers/dump/dump_gzip.c 2005-02-11 16:32:28.535116151 -0800 @@ -48,8 +48,7 @@ */ return(0); } - if ((err = zlib_deflateInit(&dump_stream, Z_BEST_COMPRESSION)) != Z_OK) { - /* fall back to RLE compression */ + if ((err = zlib_deflateInit(&dump_stream, Z_BEST_SPEED)) != Z_OK) { printk("dump_compress_gzip(): zlib_deflateInit() " "failed (%d)!\n", err); return 0; |
From: Troy H. <tro...@hp...> - 2005-02-12 16:28:13
|
On 02/12/05 00:09, Jason Uhlenkott wrote: > As promised, this gives a big speed boost (~300% on a typical SGI > Altix) to gzip dumps, at only a marginal cost in dump size. I like it. I'll put it in the 6.X.X trunk as is. But for the 7.X.X tree what if we changed the dump flag for gzip from being 2 to being 21 - 29 where 1-9 was the level of compression. That way people could choose in the conf file what compression the wanted and we could default to 1. Ofcouse this will be a touch more work because we will have to change the ioctrl and dumputils to handle the extra info, but it seems like it would be good to push the choice to the users. What do you think? Troy |
From: Jason U. <jas...@sg...> - 2005-02-13 03:37:27
|
On Sat, Feb 12, 2005 at 09:24:36AM -0700, Troy Heber wrote: > On 02/12/05 00:09, Jason Uhlenkott wrote: > > As promised, this gives a big speed boost (~300% on a typical SGI > > Altix) to gzip dumps, at only a marginal cost in dump size. > > I like it. I'll put it in the 6.X.X trunk as is. But for the 7.X.X tree what > if we changed the dump flag for gzip from being 2 to being 21 - 29 where 1-9 > was the level of compression. That way people could choose in the conf file > what compression the wanted and we could default to 1. Ofcouse this will be a > touch more work because we will have to change the ioctrl and dumputils to > handle the extra info, but it seems like it would be good to push the choice > to the users. What do you think? Sure. Here's a stab at that. Index: linux/drivers/dump/dump_setup.c =================================================================== --- linux.orig/drivers/dump/dump_setup.c 2005-02-12 12:11:39.149392076 -0800 +++ linux/drivers/dump/dump_setup.c 2005-02-12 18:33:27.307611884 -0800 @@ -4,7 +4,7 @@ * Created by: Matt Robinson (ya...@so...) * Contributions from SGI, IBM, HP, MCL, and others. * - * Copyright (C) 1999 - 2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1999 - 2005 Silicon Graphics, Inc. All rights reserved. * Copyright (C) 2000 - 2002 TurboLinux, Inc. All rights reserved. * Copyright (C) 2001 - 2002 Matt D. Robinson. All rights reserved. * Copyright (C) 2002 Free Software Foundation, Inc. All rights reserved. @@ -61,12 +61,12 @@ * * dump_compress (used to be dump_compress_pages): * This is the flag which indicates which compression mechanism - * to use. This is a BITMASK, not an index (0,1,2,4,8,16,etc.). - * This is the current set of values: + * to use. This is the current set of values: * * 0: DUMP_COMPRESS_NONE -- Don't compress any pages. * 1: DUMP_COMPRESS_RLE -- This uses RLE compression. - * 2: DUMP_COMPRESS_GZIP -- This uses GZIP compression. + * 21-29: DUMP_COMPRESS_GZIP_[1-9] -- This uses GZIP compression + * (21 is fastest, 29 is smallest). * * dump_level: * The amount of effort the dump module should make to save @@ -147,12 +147,13 @@ /* Other global fields */ extern struct __dump_header dump_header; struct dump_dev *dump_dev = NULL; /* Active dump device */ -static int dump_compress = 0; +int dump_compress = 0; static u32 dump_compress_none(const u8 *old, u32 oldsize, u8 *new, u32 newsize, unsigned long loc); struct __dump_compress dump_none_compression = { - .compress_type = DUMP_COMPRESS_NONE, + .compress_type_min = DUMP_COMPRESS_NONE, + .compress_type_max = DUMP_COMPRESS_NONE, .compress_func = dump_compress_none, .compress_name = "none", }; @@ -379,21 +380,10 @@ * compression pointer if necessary. */ void -dump_unregister_compression(int compression_type) +dump_unregister_compression(struct __dump_compress *item) { - struct list_head *tmp; - struct __dump_compress *dc; - - /* let's make sure our list is valid */ - if (compression_type != DUMP_COMPRESS_NONE) { - list_for_each(tmp, &dump_compress_list) { - dc = list_entry(tmp, struct __dump_compress, list); - if (dc->compress_type == compression_type) { - list_del(&(dc->list)); - break; - } - } - } + if (item) + list_del(&item->list); } /* @@ -409,7 +399,8 @@ /* try to remove the compression item */ list_for_each(tmp, &dump_compress_list) { dc = list_entry(tmp, struct __dump_compress, list); - if (dc->compress_type == compression_type) { + if (compression_type >= dc->compress_type_min && + compression_type <= dc->compress_type_max) { dump_config.dumper->compress = dc; dump_compress = compression_type; pr_debug("Dump Compress %s\n", dc->compress_name); @@ -595,9 +586,7 @@ return dump_compress_init((int)arg); case DIOGDUMPCOMPRESS: /* get the dump_compress status */ - return put_user((long)(dump_config.dumper ? - dump_config.dumper->compress->compress_type : 0), - (long *)arg); + return put_user((long)dump_compress, (long *)arg); case DIOGDUMPOKAY: /* check if dump is configured */ return put_user((long)dump_okay, (long *)arg); Index: linux/include/linux/dump.h =================================================================== --- linux.orig/include/linux/dump.h 2005-02-12 12:11:39.181618892 -0800 +++ linux/include/linux/dump.h 2005-02-12 18:06:09.881817903 -0800 @@ -2,7 +2,7 @@ * Kernel header file for Linux crash dumps. * * Created by: Matt Robinson (ya...@sg...) - * Copyright 1999 - 2002 Silicon Graphics, Inc. All rights reserved. + * Copyright 1999 - 2005 Silicon Graphics, Inc. All rights reserved. * * vmdump.h to dump.h by: Matt D. Robinson (ya...@so...) * Copyright 2001 - 2002 Matt D. Robinson. All rights reserved. @@ -111,9 +111,18 @@ /* dump compression options -- add as necessary */ -#define DUMP_COMPRESS_NONE 0x0 /* don't compress this dump */ -#define DUMP_COMPRESS_RLE 0x1 /* use RLE compression */ -#define DUMP_COMPRESS_GZIP 0x2 /* use GZIP compression */ +#define DUMP_COMPRESS_NONE 0 /* don't compress this dump */ +#define DUMP_COMPRESS_RLE 1 /* use RLE compression */ +/* #define DUMP_COMPRESS_GZIP 2 (was used by older dumps; don't reuse) */ +#define DUMP_COMPRESS_GZIP_1 21 /* use GZIP level 1 (fastest) */ +#define DUMP_COMPRESS_GZIP_2 22 /* use GZIP level 2 */ +#define DUMP_COMPRESS_GZIP_3 23 /* use GZIP level 3 */ +#define DUMP_COMPRESS_GZIP_4 24 /* use GZIP level 4 */ +#define DUMP_COMPRESS_GZIP_5 25 /* use GZIP level 5 */ +#define DUMP_COMPRESS_GZIP_6 26 /* use GZIP level 6 */ +#define DUMP_COMPRESS_GZIP_7 27 /* use GZIP level 7 */ +#define DUMP_COMPRESS_GZIP_8 28 /* use GZIP level 8 */ +#define DUMP_COMPRESS_GZIP_9 29 /* use GZIP level 9 (smallest) */ /* dump flags - any dump-type specific flags -- add as necessary */ #define DUMP_FLAGS_NONE 0x0 /* no flags are set for this dump */ @@ -307,7 +316,8 @@ struct list_head list; /* the type of compression to use (DUMP_COMPRESS_XXX) */ - int compress_type; + int compress_type_min; + int compress_type_max; const char *compress_name; /* the compression function to call */ @@ -316,7 +326,8 @@ /* functions for dump compression registration */ extern void dump_register_compression(struct __dump_compress *); -extern void dump_unregister_compression(int); +extern void dump_unregister_compression(struct __dump_compress *); +extern int dump_compress; /* * Structure dump_mbank[]: Index: linux/drivers/dump/dump_gzip.c =================================================================== --- linux.orig/drivers/dump/dump_gzip.c 2005-02-12 12:11:38.203095563 -0800 +++ linux/drivers/dump/dump_gzip.c 2005-02-12 17:26:15.910881408 -0800 @@ -39,6 +39,7 @@ struct page *pg = (struct page *)loc; unsigned long paddr = page_to_pfn(pg) << PAGE_SHIFT; static int warning = 0; + int gzip_level = dump_compress - DUMP_COMPRESS_GZIP_1 + 1; dump_stream.workspace = deflate_workspace; if ((paddr == workspace_paddr[0]) || (paddr == workspace_paddr[1])) { @@ -48,8 +49,7 @@ */ return(0); } - if ((err = zlib_deflateInit(&dump_stream, Z_BEST_COMPRESSION)) != Z_OK) { - /* fall back to RLE compression */ + if ((err = zlib_deflateInit(&dump_stream, gzip_level)) != Z_OK) { printk("dump_compress_gzip(): zlib_deflateInit() " "failed (%d)!\n", err); return 0; @@ -100,7 +100,8 @@ /* setup the gzip compression functionality */ static struct __dump_compress dump_gzip_compression = { - .compress_type = DUMP_COMPRESS_GZIP, + .compress_type_min = DUMP_COMPRESS_GZIP_1, + .compress_type_max = DUMP_COMPRESS_GZIP_9, .compress_func = dump_compress_gzip, .compress_name = "GZIP", }; @@ -162,7 +163,7 @@ safety_buffer = NULL; } - dump_unregister_compression(DUMP_COMPRESS_GZIP); + dump_unregister_compression(&dump_gzip_compression); } /* module initialization */ Index: linux/drivers/dump/dump_rle.c =================================================================== --- linux.orig/drivers/dump/dump_rle.c 2005-02-12 12:11:38.296846301 -0800 +++ linux/drivers/dump/dump_rle.c 2005-02-12 16:12:02.454093668 -0800 @@ -141,7 +141,8 @@ /* setup the rle compression functionality */ static struct __dump_compress dump_rle_compression = { - .compress_type = DUMP_COMPRESS_RLE, + .compress_type_min = DUMP_COMPRESS_RLE, + .compress_type_max = DUMP_COMPRESS_RLE, .compress_func = dump_compress_rle, .compress_name = "RLE", }; @@ -164,7 +165,7 @@ static void __exit dump_compress_rle_cleanup(void) { - dump_unregister_compression(DUMP_COMPRESS_RLE); + dump_unregister_compression(&dump_rle_compression); } /* module initialization */ Index: linux/drivers/dump/dump_fmt.c =================================================================== --- linux.orig/drivers/dump/dump_fmt.c 2005-02-12 12:11:38.192353291 -0800 +++ linux/drivers/dump/dump_fmt.c 2005-02-12 16:15:41.479242989 -0800 @@ -123,8 +123,7 @@ dump_header.dh_page_size = PAGE_SIZE; dump_header.dh_dump_level = dump_config.level; dump_header.dh_current_task = (unsigned long) current; - dump_header.dh_dump_compress = dump_config.dumper->compress-> - compress_type; + dump_header.dh_dump_compress = dump_compress; dump_header.dh_dump_flags = dump_config.flags; dump_header.dh_dump_device = dump_config.dumper->dev->device_id; dump_header.dh_dump_buffer_size = DUMP_BUFFER_SIZE; Index: lkcd/7.X.X/lkcdutils/lib/libklib/include/kl_dump.h =================================================================== --- lkcd.orig/7.X.X/lkcdutils/lib/libklib/include/kl_dump.h 2004-12-21 15:26:21.000000000 -0800 +++ lkcd/7.X.X/lkcdutils/lib/libklib/include/kl_dump.h 2005-02-12 18:09:08.939852666 -0800 @@ -79,9 +79,18 @@ #define KL_DUMP_LEVEL_ALL 0x10 /* dump all memory RAM and firmware */ /* dump compression options -- add as necessary */ -#define KL_DUMP_COMPRESS_NONE 0x0 /* don't compress this dump */ -#define KL_DUMP_COMPRESS_RLE 0x1 /* use RLE compression */ -#define KL_DUMP_COMPRESS_GZIP 0x2 /* use GZIP compression */ +#define KL_DUMP_COMPRESS_NONE 0 /* don't compress this dump */ +#define KL_DUMP_COMPRESS_RLE 1 /* use RLE compression */ +#define KL_DUMP_COMPRESS_GZIP 2 /* use GZIP (used by older dumps) */ +#define KL_DUMP_COMPRESS_GZIP_1 21 /* use GZIP level 1 (fastest) */ +#define KL_DUMP_COMPRESS_GZIP_2 22 /* use GZIP level 2 */ +#define KL_DUMP_COMPRESS_GZIP_3 23 /* use GZIP level 3 */ +#define KL_DUMP_COMPRESS_GZIP_4 24 /* use GZIP level 4 */ +#define KL_DUMP_COMPRESS_GZIP_5 25 /* use GZIP level 5 */ +#define KL_DUMP_COMPRESS_GZIP_6 26 /* use GZIP level 6 */ +#define KL_DUMP_COMPRESS_GZIP_7 27 /* use GZIP level 7 */ +#define KL_DUMP_COMPRESS_GZIP_8 28 /* use GZIP level 8 */ +#define KL_DUMP_COMPRESS_GZIP_9 29 /* use GZIP level 9 (smallest) */ /* dump flags - any dump-type specific flags -- add as necessary */ #define KL_DUMP_FLAGS_NONE 0x0 /* no flags are set for this dump */ Index: lkcd/7.X.X/lkcdutils/dumputils/etc.dumputils.conf =================================================================== --- lkcd.orig/7.X.X/lkcdutils/dumputils/etc.dumputils.conf 2004-12-21 15:26:17.000000000 -0800 +++ lkcd/7.X.X/lkcdutils/dumputils/etc.dumputils.conf 2005-02-12 18:50:37.692551105 -0800 @@ -69,9 +69,17 @@ # also other compression modules coming (such as GZIP). The values for # DUMP_COMPRESS are currently: # -# DUMP_COMPRESS_NONE(0): Don't compress this dump. -# DUMP_COMPRESS_RLE(1): Use RLE compression. -# DUMP_COMPRESS_GZIP(2): Use GZIP compression. +# DUMP_COMPRESS_NONE(0): Don't compress this dump. +# DUMP_COMPRESS_RLE(1): Use RLE compression. +# DUMP_COMPRESS_GZIP_1(21): Use GZIP compression, level 1 (fastest). +# DUMP_COMPRESS_GZIP_2(22): Use GZIP compression, level 2. +# DUMP_COMPRESS_GZIP_3(23): Use GZIP compression, level 3. +# DUMP_COMPRESS_GZIP_4(24): Use GZIP compression, level 4. +# DUMP_COMPRESS_GZIP_5(25): Use GZIP compression, level 5. +# DUMP_COMPRESS_GZIP_6(26): Use GZIP compression, level 6. +# DUMP_COMPRESS_GZIP_7(27): Use GZIP compression, level 7. +# DUMP_COMPRESS_GZIP_8(28): Use GZIP compression, level 8. +# DUMP_COMPRESS_GZIP_9(29): Use GZIP compression, level 9 (smallest). # --------------------------------------------------------------------------- # For 2.4 Kernel based systems: # @@ -117,5 +125,5 @@ DUMPDIR=/var/log/dump DUMP_SAVE=1 DUMP_LEVEL=8 -DUMP_COMPRESS=2 +DUMP_COMPRESS=21 PANIC_TIMEOUT=5 Index: lkcd/7.X.X/lkcdutils/lib/libklib/kl_cmp.c =================================================================== --- lkcd.orig/7.X.X/lkcdutils/lib/libklib/kl_cmp.c 2004-12-21 15:26:20.000000000 -0800 +++ lkcd/7.X.X/lkcdutils/lib/libklib/kl_cmp.c 2005-02-12 18:13:31.309076564 -0800 @@ -528,6 +528,15 @@ break; case KL_DUMP_COMPRESS_GZIP: + case KL_DUMP_COMPRESS_GZIP_1: + case KL_DUMP_COMPRESS_GZIP_2: + case KL_DUMP_COMPRESS_GZIP_3: + case KL_DUMP_COMPRESS_GZIP_4: + case KL_DUMP_COMPRESS_GZIP_5: + case KL_DUMP_COMPRESS_GZIP_6: + case KL_DUMP_COMPRESS_GZIP_7: + case KL_DUMP_COMPRESS_GZIP_8: + case KL_DUMP_COMPRESS_GZIP_9: if (!__cmpuncompress_page_gzip( (unsigned char*)compr_page, (unsigned char*)uncompr_page, |
From: Troy H. <tro...@hp...> - 2005-02-14 14:38:41
|
On 02/12/05 19:37, Jason Uhlenkott wrote: > Sure. Here's a stab at that. Wow that was quick! Just did a quick scan and it looks great. Thanks! Troy |
From: Troy H. <tro...@hp...> - 2005-02-14 15:43:10
|
On 02/12/05 00:09, Jason Uhlenkott wrote: > - if ((err = zlib_deflateInit(&dump_stream, Z_BEST_COMPRESSION)) != Z_OK) { > - /* fall back to RLE compression */ > + if ((err = zlib_deflateInit(&dump_stream, Z_BEST_SPEED)) != Z_OK) { Checked in to the 6.X.X trees. Troy |
From: philippe b. <phi...@wa...> - 2005-02-12 09:31:47
|
Hi All, Can't we make the assumption that such gigantic physmem are MP as well, then devoting some gziping some proc while 1 proc handle the polling io? Just curious. Phi |
From: Jason U. <jas...@sg...> - 2005-02-13 03:37:40
|
On Sat, Feb 12, 2005 at 10:31:45AM +0100, philippe benard wrote: > Hi All, > > Can't we make the assumption that such gigantic physmem are MP as well, > then devoting some gziping some proc while 1 proc handle the polling io? As Keith pointed out, that's problematic on ia64 at least. It might be possible to have the dumping cpu itself do some useful work while waiting for I/O, though. We'd just need the compression code to register a function somewhere that we can call from the loop after we fire off a request while we wait for it to complete. |