[PATCH 2/2] Write out a whole part of the 1st bitmap before entering cyclic process

Atsushi Kumagai kumagai-atsushi at mxc.nes.nec.co.jp
Wed Oct 30 06:52:58 EDT 2013


(2013/10/24 15:52), HATAYAMA Daisuke wrote:
> Currently, 1st bitmap is created during cyclic process, but the
> information represented by the 1st bitmap, originally present memory,
> is still available from ELF program header table, so we don't need to
> keep the 1st bitmap even in cyclic process.
>
> Supported is a conversion from ELF to kdump-compressed format only,
> not from ELF to ELF.
>
> Signed-off-by: HATAYAMA Daisuke <d.hatayama at jp.fujitsu.com>
> ---
>   makedumpfile.c |  224 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
>   1 file changed, 202 insertions(+), 22 deletions(-)
>
> diff --git a/makedumpfile.c b/makedumpfile.c
> index 4b6c0ed..7440c97 100644
> --- a/makedumpfile.c
> +++ b/makedumpfile.c
> @@ -3055,7 +3055,8 @@ out:
>   				 * bufsize_cyclic is used to allocate 1st and 2nd bitmap,
>   				 * so it should be truncated to the half of free_memory.
>   				 */
> -				info->bufsize_cyclic = free_memory / 2;
> +				if (info->flag_elf_dumpfile)
> +					info->bufsize_cyclic = free_memory / 2;
>   			}
>   		}

I think here should be changed like below:

		if (info->flag_elf_dumpfile)
			info->bufsize_cyclic = free_memory / 2;
		else
			info->bufsize_cyclic = free_memory;


Thanks
Atsushi Kumagai

>
> @@ -3328,6 +3329,33 @@ clear_bit_on_2nd_bitmap_for_kernel(unsigned long long pfn)
>   	return clear_bit_on_2nd_bitmap(pfn);
>   }
>
> +int
> +set_bit_on_2nd_bitmap(unsigned long long pfn)
> +{
> +	if (info->flag_cyclic) {
> +		return set_bitmap_cyclic(info->partial_bitmap2, pfn, 1);
> +	} else {
> +		return set_bitmap(info->bitmap2, pfn, 1);
> +	}
> +}
> +
> +int
> +set_bit_on_2nd_bitmap_for_kernel(unsigned long long pfn)
> +{
> +	unsigned long long maddr;
> +
> +	if (is_xen_memory()) {
> +		maddr = ptom_xen(pfn_to_paddr(pfn));
> +		if (maddr == NOT_PADDR) {
> +			ERRMSG("Can't convert a physical address(%llx) to machine address.\n",
> +			    pfn_to_paddr(pfn));
> +			return FALSE;
> +		}
> +		pfn = paddr_to_pfn(maddr);
> +	}
> +	return set_bit_on_2nd_bitmap(pfn);
> +}
> +
>   static inline int
>   is_in_segs(unsigned long long paddr)
>   {
> @@ -4418,6 +4446,53 @@ exclude_zero_pages(void)
>   	return TRUE;
>   }
>
> +static int
> +initialize_2nd_bitmap_cyclic(void)
> +{
> +	int i;
> +	unsigned long long pfn;
> +	unsigned long long phys_start, phys_end;
> +	unsigned long long pfn_start, pfn_end;
> +	unsigned long long pfn_start_roundup, pfn_end_round;
> +	unsigned long pfn_start_byte, pfn_end_byte;
> +
> +	/*
> +	 * At first, clear all the bits on the 2nd-bitmap.
> +	 */
> +	initialize_bitmap_cyclic(info->partial_bitmap2);
> +
> +	/*
> +	 * If page is on memory hole, set bit on the 2nd-bitmap.
> +	 */
> +	for (i = 0; get_pt_load(i, &phys_start, &phys_end, NULL, NULL); i++) {
> +		pfn_start = MAX(paddr_to_pfn(phys_start), info->cyclic_start_pfn);
> +		pfn_end = MIN(paddr_to_pfn(phys_end), info->cyclic_end_pfn);
> +
> +		if (pfn_start >= pfn_end)
> +			continue;
> +
> +		pfn_start_roundup = roundup(pfn_start, BITPERBYTE);
> +		pfn_end_round = round(pfn_end, BITPERBYTE);
> +
> +		for (pfn = pfn_start; pfn < pfn_start_roundup; ++pfn)
> +			if (!set_bit_on_2nd_bitmap_for_kernel(pfn))
> +				return FALSE;
> +
> +		pfn_start_byte = (pfn_start_roundup - info->cyclic_start_pfn) >> 3;
> +		pfn_end_byte = (pfn_end_round - info->cyclic_start_pfn) >> 3;
> +
> +		memset(info->partial_bitmap2 + pfn_start_byte,
> +		       0xff,
> +		       pfn_end_byte - pfn_start_byte);
> +
> +		for (pfn = pfn_end_round; pfn < pfn_end; ++pfn)
> +			if (!set_bit_on_2nd_bitmap_for_kernel(pfn))
> +				return FALSE;
> +	}
> +
> +	return TRUE;
> +}
> +
>   int
>   __exclude_unnecessary_pages(unsigned long mem_map,
>       unsigned long long pfn_start, unsigned long long pfn_end)
> @@ -4584,12 +4659,6 @@ exclude_unnecessary_pages(void)
>   	return TRUE;
>   }
>
> -void
> -copy_bitmap_cyclic(void)
> -{
> -	memcpy(info->partial_bitmap2, info->partial_bitmap1, info->bufsize_cyclic);
> -}
> -
>   int
>   exclude_unnecessary_pages_cyclic(void)
>   {
> @@ -4597,10 +4666,8 @@ exclude_unnecessary_pages_cyclic(void)
>   	struct mem_map_data *mmd;
>   	struct timeval tv_start;
>
> -	/*
> -	 * Copy 1st-bitmap to 2nd-bitmap.
> -	 */
> -	copy_bitmap_cyclic();
> +	if (!initialize_2nd_bitmap_cyclic())
> +		return FALSE;
>
>   	if ((info->dump_level & DL_EXCLUDE_FREE) && !info->page_is_buddy)
>   		if (!exclude_free_page())
> @@ -4657,7 +4724,7 @@ update_cyclic_region(unsigned long long pfn)
>   	if (info->cyclic_end_pfn > info->max_mapnr)
>   		info->cyclic_end_pfn = info->max_mapnr;
>
> -	if (!create_1st_bitmap_cyclic())
> +	if (info->flag_elf_dumpfile && !create_1st_bitmap_cyclic())
>   		return FALSE;
>
>   	if (!exclude_unnecessary_pages_cyclic())
> @@ -4841,19 +4908,71 @@ prepare_bitmap_buffer_cyclic(void)
>   	return TRUE;
>   }
>
> +int
> +prepare_bitmap1_buffer_cyclic(void)
> +{
> +	/*
> +	 * Prepare partial bitmap buffers for cyclic processing.
> +	 */
> +	if ((info->partial_bitmap1 = (char *)malloc(info->bufsize_cyclic)) == NULL) {
> +		ERRMSG("Can't allocate memory for the 1st bitmaps. %s\n",
> +		       strerror(errno));
> +		return FALSE;
> +	}
> +	initialize_bitmap_cyclic(info->partial_bitmap1);
> +
> +	return TRUE;
> +}
> +
> +int
> +prepare_bitmap2_buffer_cyclic(void)
> +{
> +	unsigned long tmp;
> +
> +	/*
> +	 * Create 2 bitmaps (1st-bitmap & 2nd-bitmap) on block_size
> +	 * boundary. The crash utility requires both of them to be
> +	 * aligned to block_size boundary.
> +	 */
> +	tmp = divideup(divideup(info->max_mapnr, BITPERBYTE), info->page_size);
> +	info->len_bitmap = tmp * info->page_size * 2;
> +
> +	/*
> +	 * Prepare partial bitmap buffers for cyclic processing.
> +	 */
> +	if ((info->partial_bitmap2 = (char *)malloc(info->bufsize_cyclic)) == NULL) {
> +		ERRMSG("Can't allocate memory for the 2nd bitmaps. %s\n",
> +		       strerror(errno));
> +		return FALSE;
> +	}
> +	initialize_bitmap_cyclic(info->partial_bitmap2);
> +
> +	return TRUE;
> +}
> +
>   void
> -free_bitmap_buffer(void)
> +free_bitmap1_buffer(void)
>   {
>   	if (info->bitmap1) {
>   		free(info->bitmap1);
>   		info->bitmap1 = NULL;
>   	}
> +}
> +
> +void
> +free_bitmap2_buffer(void)
> +{
>   	if (info->bitmap2) {
>   		free(info->bitmap2);
>   		info->bitmap2 = NULL;
>   	}
> +}
>
> -	return;
> +void
> +free_bitmap_buffer(void)
> +{
> +	free_bitmap1_buffer();
> +	free_bitmap2_buffer();
>   }
>
>   int
> @@ -4862,10 +4981,21 @@ create_dump_bitmap(void)
>   	int ret = FALSE;
>
>   	if (info->flag_cyclic) {
> -		if (!prepare_bitmap_buffer_cyclic())
> -			goto out;
>
> -		info->num_dumpable = get_num_dumpable_cyclic();
> +		if (info->flag_elf_dumpfile) {
> +			if (!prepare_bitmap_buffer_cyclic())
> +				goto out;
> +
> +			info->num_dumpable = get_num_dumpable_cyclic();
> +		} else {
> +			if (!prepare_bitmap2_buffer_cyclic())
> +				goto out;
> +
> +			info->num_dumpable = get_num_dumpable_cyclic();
> +
> +			free_bitmap2_buffer();
> +		}
> +
>   	} else {
>   		if (!prepare_bitmap_buffer())
>   			goto out;
> @@ -6564,7 +6694,7 @@ out:
>   }
>
>   int
> -write_kdump_bitmap_cyclic(void)
> +write_kdump_bitmap1_cyclic(void)
>   {
>   	off_t offset;
>           int increment;
> @@ -6576,10 +6706,30 @@ write_kdump_bitmap_cyclic(void)
>   		return FALSE;
>
>   	offset = info->offset_bitmap1;
> -	if (!write_buffer(info->fd_dumpfile, offset,
> +	if (!write_buffer(info->fd_dumpfile, offset + info->bufsize_cyclic *
> +			  (info->cyclic_start_pfn / info->pfn_cyclic),
>   			  info->partial_bitmap1, increment, info->name_dumpfile))
>   		goto out;
>
> +	ret = TRUE;
> +out:
> +	return ret;
> +}
> +
> +int
> +write_kdump_bitmap2_cyclic(void)
> +{
> +	off_t offset;
> +	int increment;
> +	int ret = FALSE;
> +
> +	increment = divideup(info->cyclic_end_pfn - info->cyclic_start_pfn,
> +			     BITPERBYTE);
> +
> +	if (info->flag_elf_dumpfile)
> +		return FALSE;
> +
> +	offset = info->offset_bitmap1;
>   	offset += info->len_bitmap / 2;
>   	if (!write_buffer(info->fd_dumpfile, offset,
>   			  info->partial_bitmap2, increment, info->name_dumpfile))
> @@ -6633,6 +6783,30 @@ write_kdump_pages_and_bitmap_cyclic(struct cache_data *cd_header, struct cache_d
>   	}
>
>   	/*
> +	 * Write the 1st bitmap
> +	 */
> +	if (!prepare_bitmap1_buffer_cyclic())
> +		return FALSE;
> +
> +	info->cyclic_start_pfn = 0;
> +	info->cyclic_end_pfn = 0;
> +	for (pfn = 0; pfn < info->max_mapnr; pfn++) {
> +		if (is_cyclic_region(pfn))
> +			continue;
> +		if (!update_cyclic_region(pfn))
> +			return FALSE;
> +		if (!create_1st_bitmap_cyclic())
> +			return FALSE;
> +		if (!write_kdump_bitmap1_cyclic())
> +			return FALSE;
> +	}
> +
> +	free_bitmap1_buffer();
> +
> +	if (!prepare_bitmap2_buffer_cyclic())
> +		return FALSE;
> +
> +	/*
>   	 * Write pages and bitmap cyclically.
>   	 */
>   	info->cyclic_start_pfn = 0;
> @@ -6647,7 +6821,7 @@ write_kdump_pages_and_bitmap_cyclic(struct cache_data *cd_header, struct cache_d
>   		if (!write_kdump_pages_cyclic(cd_header, cd_page, &pd_zero, &offset_data))
>   			return FALSE;
>
> -		if (!write_kdump_bitmap_cyclic())
> +		if (!write_kdump_bitmap2_cyclic())
>   			return FALSE;
>           }
>
> @@ -8681,8 +8855,14 @@ calculate_cyclic_buffer_size(void) {
>   	 * should be 40% of free memory to keep the size of cyclic buffer
>   	 * within 80% of free memory.
>   	 */
> -	free_size = get_free_memory_size() * 0.4;
> -	needed_size = (info->max_mapnr * 2) / BITPERBYTE;
> +	if (info->flag_elf_dumpfile) {
> +		free_size = get_free_memory_size() * 0.4;
> +		needed_size = (info->max_mapnr * 2) / BITPERBYTE;
> +	} else {
> +		free_size = get_free_memory_size() * 0.8;
> +		needed_size = info->max_mapnr / BITPERBYTE;
> +	}
> +
>   	/* if --split was specified cyclic buffer allocated per dump file */
>   	if (info->num_dumpfile > 1)
>   		needed_size /= info->num_dumpfile;
>
>
>





More information about the kexec mailing list