The size of cyclic buffer is set to DEFAULT_BUFSIZE_CYCLIC(1MB) when the size isn't specified. But 1MB is too small for large memory machine and the number of cycle will be so large. As a result, a lot of time will be spend for dump filtering. To resolve the issue above, I add calculate_cyclic_buffer_size() to calculate the buffer size as needed. Concretely, the logic is to choose the lesser value of the two below as the size of cyclic buffer: a. the size enough for storing the 1st/2nd bitmap for the whole of vmcore b. 80% of free memory (as safety limit) calculate_cyclic_buffer_size() uses max_mapnr, so it needs to be done after get_max_mapnr(). Signed-off-by: Atsushi Kumagai <kumagai-atsushi at mxc.nes.nec.co.jp> --- makedumpfile.c | 70 +++++++++++++++++++++++++++++++++++++++------------------- makedumpfile.h | 6 +---- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/makedumpfile.c b/makedumpfile.c index 73a466e..f784400 100644 --- a/makedumpfile.c +++ b/makedumpfile.c @@ -2573,29 +2573,6 @@ initial(void) } #endif - if (info->flag_cyclic) { - /* - * buffer size is specified as Kbyte - */ - if (info->bufsize_cyclic == 0) - info->bufsize_cyclic = DEFAULT_BUFSIZE_CYCLIC; - else - info->bufsize_cyclic <<= 10; - - /* - * Max buffer size is 100 MB - */ - if (info->bufsize_cyclic > (100 << 20)) { - MSG("Specified buffer size is too large, "); - MSG("The buffer size for the cyclic mode will be truncated to 100 MB.\n"); - info->bufsize_cyclic = (100 << 20); - } - info->pfn_cyclic = info->bufsize_cyclic * BITPERBYTE; - - DEBUG_MSG("\n"); - DEBUG_MSG("Buffer size for the cyclic mode: %ld\n", info->bufsize_cyclic); - } - if (info->flag_exclude_xen_dom) { if(info->flag_cyclic) { info->flag_cyclic = FALSE; @@ -2737,6 +2714,30 @@ out: if (!get_max_mapnr()) return FALSE; + if (info->flag_cyclic) { + /* + * buffer size is specified as Kbyte + */ + if (info->bufsize_cyclic == 0) { + if (!calculate_cyclic_buffer_size()) + return FALSE; + } else + info->bufsize_cyclic <<= 10; + + /* + * Max buffer size is 100 MB + */ + if (info->bufsize_cyclic > (100 << 20)) { + MSG("Specified buffer size is too large, "); + MSG("The buffer size for the cyclic mode will be truncated to 100 MB.\n"); + info->bufsize_cyclic = (100 << 20); + } + info->pfn_cyclic = info->bufsize_cyclic * BITPERBYTE; + + DEBUG_MSG("\n"); + DEBUG_MSG("Buffer size for the cyclic mode: %ld\n", info->bufsize_cyclic); + } + if (debug_info) { if (info->flag_sadump) (void) sadump_virt_phys_base(); @@ -8006,6 +8007,29 @@ out: return free_size; } + +/* + * Choose the lesser value of the two below as the size of cyclic buffer. + * - the size enough for storing the 1st/2nd bitmap for the whole of vmcore + * - 80% of free memory + */ +int +calculate_cyclic_buffer_size(void) { + unsigned long long free_size, needed_size; + + if (info->max_mapnr <= 0) { + ERRMSG("Invalid max_mapnr(%llu).\n", info->max_mapnr); + return FALSE; + } + + free_size = get_free_memory_size() * 0.8; + needed_size = (info->max_mapnr * 2) / BITPERBYTE; + + info->bufsize_cyclic = (free_size <= needed_size) ? free_size : needed_size; + + return TRUE; +} + static struct option longopts[] = { {"split", no_argument, NULL, 's'}, {"reassemble", no_argument, NULL, 'r'}, diff --git a/makedumpfile.h b/makedumpfile.h index c91b4e9..8ffef76 100644 --- a/makedumpfile.h +++ b/makedumpfile.h @@ -199,11 +199,6 @@ isAnon(unsigned long mapping) #define FILENAME_STDOUT "STDOUT" /* - * For cyclic processing - */ -#define DEFAULT_BUFSIZE_CYCLIC (1024 * 1024) - -/* * Minimam vmcore has 2 ProgramHeaderTables(PT_NOTE and PT_LOAD). */ #define MIN_ELF32_HEADER_SIZE \ @@ -1612,5 +1607,6 @@ unsigned long long get_num_dumpable_cyclic(void); int get_loads_dumpfile_cyclic(void); int initial_xen(void); unsigned long long get_free_memory_size(void); +int calculate_cyclic_buffer_size(void); #endif /* MAKEDUMPFILE_H */ -- 1.7.11