[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