Per struct cycle and the relevant helper functions, it's simple to update cyclic region only. update_cyclic_region() is broken and not needed any more. cycle containing the cyclic region is passed down, and not global. Related clean up is also done in this patch. Signed-off-by: Baoquan He <bhe at redhat.com> --- makedumpfile.c | 471 +++++++++++++++++++++++++++------------------------------ makedumpfile.h | 14 +- sadump_info.c | 4 +- 3 files changed, 229 insertions(+), 260 deletions(-) diff --git a/makedumpfile.c b/makedumpfile.c index 01c6443..daef109 100644 --- a/makedumpfile.c +++ b/makedumpfile.c @@ -206,7 +206,7 @@ is_in_same_page(unsigned long vaddr1, unsigned long vaddr2) #define BITMAP_SECT_LEN 4096 static inline int is_dumpable(struct dump_bitmap *, unsigned long long); -static inline int is_dumpable_cyclic(char *bitmap, unsigned long long); +static inline int is_dumpable_cyclic(char *bitmap, unsigned long long, struct cycle *cycle); unsigned long pfn_to_pos(unsigned long long pfn) { @@ -3301,18 +3301,18 @@ set_bitmap(struct dump_bitmap *bitmap, unsigned long long pfn, } int -set_bitmap_cyclic(char *bitmap, unsigned long long pfn, int val) +set_bitmap_cyclic(char *bitmap, unsigned long long pfn, int val, struct cycle *cycle) { int byte, bit; - if (pfn < info->cyclic_start_pfn || info->cyclic_end_pfn <= pfn) - return FALSE; + if (pfn < cycle->start_pfn || cycle->end_pfn <= pfn) + return FALSE; /* * If val is 0, clear bit on the bitmap. */ - byte = (pfn - info->cyclic_start_pfn)>>3; - bit = (pfn - info->cyclic_start_pfn) & 7; + byte = (pfn - cycle->start_pfn)>>3; + bit = (pfn - cycle->start_pfn) & 7; if (val) bitmap[byte] |= 1<<bit; else @@ -3361,37 +3361,37 @@ sync_2nd_bitmap(void) } int -set_bit_on_1st_bitmap(unsigned long long pfn) +set_bit_on_1st_bitmap(unsigned long long pfn, struct cycle *cycle) { if (info->flag_cyclic) { - return set_bitmap_cyclic(info->partial_bitmap1, pfn, 1); + return set_bitmap_cyclic(info->partial_bitmap1, pfn, 1, cycle); } else { return set_bitmap(info->bitmap1, pfn, 1); } } int -clear_bit_on_1st_bitmap(unsigned long long pfn) +clear_bit_on_1st_bitmap(unsigned long long pfn, struct cycle *cycle) { if (info->flag_cyclic) { - return set_bitmap_cyclic(info->partial_bitmap1, pfn, 0); + return set_bitmap_cyclic(info->partial_bitmap1, pfn, 0, cycle); } else { return set_bitmap(info->bitmap1, pfn, 0); } } int -clear_bit_on_2nd_bitmap(unsigned long long pfn) +clear_bit_on_2nd_bitmap(unsigned long long pfn, struct cycle *cycle) { if (info->flag_cyclic) { - return set_bitmap_cyclic(info->partial_bitmap2, pfn, 0); + return set_bitmap_cyclic(info->partial_bitmap2, pfn, 0, cycle); } else { return set_bitmap(info->bitmap2, pfn, 0); } } int -clear_bit_on_2nd_bitmap_for_kernel(unsigned long long pfn) +clear_bit_on_2nd_bitmap_for_kernel(unsigned long long pfn, struct cycle *cycle) { unsigned long long maddr; @@ -3404,21 +3404,21 @@ clear_bit_on_2nd_bitmap_for_kernel(unsigned long long pfn) } pfn = paddr_to_pfn(maddr); } - return clear_bit_on_2nd_bitmap(pfn); + return clear_bit_on_2nd_bitmap(pfn, cycle); } int -set_bit_on_2nd_bitmap(unsigned long long pfn) +set_bit_on_2nd_bitmap(unsigned long long pfn, struct cycle *cycle) { if (info->flag_cyclic) { - return set_bitmap_cyclic(info->partial_bitmap2, pfn, 1); + return set_bitmap_cyclic(info->partial_bitmap2, pfn, 1, cycle); } else { return set_bitmap(info->bitmap2, pfn, 1); } } int -set_bit_on_2nd_bitmap_for_kernel(unsigned long long pfn) +set_bit_on_2nd_bitmap_for_kernel(unsigned long long pfn, struct cycle *cycle) { unsigned long long maddr; @@ -3431,7 +3431,7 @@ set_bit_on_2nd_bitmap_for_kernel(unsigned long long pfn) } pfn = paddr_to_pfn(maddr); } - return set_bit_on_2nd_bitmap(pfn); + return set_bit_on_2nd_bitmap(pfn, cycle); } static inline int @@ -3757,7 +3757,7 @@ page_to_pfn(unsigned long page) } int -reset_bitmap_of_free_pages(unsigned long node_zones) +reset_bitmap_of_free_pages(unsigned long node_zones, struct cycle *cycle) { int order, i, migrate_type, migrate_types; @@ -3803,7 +3803,7 @@ reset_bitmap_of_free_pages(unsigned long node_zones) } for (i = 0; i < (1<<order); i++) { pfn = start_pfn + i; - if (clear_bit_on_2nd_bitmap_for_kernel(pfn)) + if (clear_bit_on_2nd_bitmap_for_kernel(pfn, cycle)) found_free_pages++; } @@ -4098,7 +4098,7 @@ out: int -_exclude_free_page(void) +_exclude_free_page(struct cycle *cycle) { int i, nr_zones, num_nodes, node; unsigned long node_zones, zone, spanned_pages, pgdat; @@ -4139,7 +4139,7 @@ _exclude_free_page(void) } if (!spanned_pages) continue; - if (!reset_bitmap_of_free_pages(zone)) + if (!reset_bitmap_of_free_pages(zone, cycle)) return FALSE; } if (num_nodes < vt.numnodes) { @@ -4164,7 +4164,7 @@ _exclude_free_page(void) } int -exclude_free_page(void) +exclude_free_page(struct cycle *cycle) { /* * Check having necessary information. @@ -4199,7 +4199,7 @@ exclude_free_page(void) /* * Detect free pages and update 2nd-bitmap. */ - if (!_exclude_free_page()) + if (!_exclude_free_page(cycle)) return FALSE; return TRUE; @@ -4404,7 +4404,7 @@ create_1st_bitmap(void) pfn_end = paddr_to_pfn(phys_end); for (pfn = pfn_start; pfn < pfn_end; pfn++) { - set_bit_on_1st_bitmap(pfn); + set_bit_on_1st_bitmap(pfn, NULL); pfn_bitmap1++; } } @@ -4422,8 +4422,9 @@ create_1st_bitmap(void) return TRUE; } + int -create_1st_bitmap_cyclic() +create_1st_bitmap_cyclic(struct cycle *cycle) { int i; unsigned long long pfn, pfn_bitmap1; @@ -4443,8 +4444,8 @@ create_1st_bitmap_cyclic() */ pfn_bitmap1 = 0; 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); + pfn_start = MAX(paddr_to_pfn(phys_start), cycle->start_pfn); + pfn_end = MIN(paddr_to_pfn(phys_end), cycle->end_pfn); if (pfn_start >= pfn_end) continue; @@ -4453,12 +4454,12 @@ create_1st_bitmap_cyclic() pfn_end_round = round(pfn_end, BITPERBYTE); for (pfn = pfn_start; pfn < pfn_start_roundup; pfn++) { - if (set_bit_on_1st_bitmap(pfn)) + if (set_bit_on_1st_bitmap(pfn, cycle)) pfn_bitmap1++; } - pfn_start_byte = (pfn_start_roundup - info->cyclic_start_pfn) >> 3; - pfn_end_byte = (pfn_end_round - info->cyclic_start_pfn) >> 3; + pfn_start_byte = (pfn_start_roundup - cycle->start_pfn) >> 3; + pfn_end_byte = (pfn_end_round - cycle->start_pfn) >> 3; if (pfn_start_byte < pfn_end_byte) { memset(info->partial_bitmap1 + pfn_start_byte, @@ -4469,7 +4470,7 @@ create_1st_bitmap_cyclic() } for (pfn = pfn_end_round; pfn < pfn_end; pfn++) { - if (set_bit_on_1st_bitmap(pfn)) + if (set_bit_on_1st_bitmap(pfn, cycle)) pfn_bitmap1++; } } @@ -4518,7 +4519,7 @@ exclude_zero_pages(void) } } if (is_zero_page(buf, info->page_size)) { - if (clear_bit_on_2nd_bitmap(pfn)) + if (clear_bit_on_2nd_bitmap(pfn, NULL)) pfn_zero++; } } @@ -4533,7 +4534,7 @@ exclude_zero_pages(void) } static int -initialize_2nd_bitmap_cyclic(void) +initialize_2nd_bitmap_cyclic(struct cycle *cycle) { int i; unsigned long long pfn; @@ -4551,8 +4552,8 @@ initialize_2nd_bitmap_cyclic(void) * 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); + pfn_start = MAX(paddr_to_pfn(phys_start), cycle->start_pfn); + pfn_end = MIN(paddr_to_pfn(phys_end), cycle->end_pfn); if (pfn_start >= pfn_end) continue; @@ -4561,11 +4562,11 @@ initialize_2nd_bitmap_cyclic(void) 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)) + if (!set_bit_on_2nd_bitmap_for_kernel(pfn, cycle)) return FALSE; - pfn_start_byte = (pfn_start_roundup - info->cyclic_start_pfn) >> 3; - pfn_end_byte = (pfn_end_round - info->cyclic_start_pfn) >> 3; + pfn_start_byte = (pfn_start_roundup - cycle->start_pfn) >> 3; + pfn_end_byte = (pfn_end_round - cycle->start_pfn) >> 3; if (pfn_start_byte < pfn_end_byte) { memset(info->partial_bitmap2 + pfn_start_byte, @@ -4574,7 +4575,7 @@ initialize_2nd_bitmap_cyclic(void) } for (pfn = pfn_end_round; pfn < pfn_end; ++pfn) - if (!set_bit_on_2nd_bitmap_for_kernel(pfn)) + if (!set_bit_on_2nd_bitmap_for_kernel(pfn, cycle)) return FALSE; } @@ -4583,7 +4584,7 @@ initialize_2nd_bitmap_cyclic(void) int __exclude_unnecessary_pages(unsigned long mem_map, - unsigned long long pfn_start, unsigned long long pfn_end) + unsigned long long pfn_start, unsigned long long pfn_end, struct cycle *cycle) { unsigned long long pfn, pfn_mm, maddr; unsigned long long pfn_read_start, pfn_read_end, index_pg; @@ -4603,7 +4604,7 @@ __exclude_unnecessary_pages(unsigned long mem_map, /* * If this pfn doesn't belong to target region, skip this pfn. */ - if (info->flag_cyclic && !is_cyclic_region(pfn)) + if (info->flag_cyclic && !is_cyclic_region(pfn, cycle)) continue; /* @@ -4668,7 +4669,7 @@ __exclude_unnecessary_pages(unsigned long mem_map, * See check_cyclic_buffer_overrun() * for the detail. */ - if (clear_bit_on_2nd_bitmap_for_kernel(pfn + i)) + if (clear_bit_on_2nd_bitmap_for_kernel((pfn + i), cycle)) pfn_free++; } pfn += nr_pages - 1; @@ -4680,7 +4681,7 @@ __exclude_unnecessary_pages(unsigned long mem_map, else if ((info->dump_level & DL_EXCLUDE_CACHE) && (isLRU(flags) || isSwapCache(flags)) && !isPrivate(flags) && !isAnon(mapping)) { - if (clear_bit_on_2nd_bitmap_for_kernel(pfn)) + if (clear_bit_on_2nd_bitmap_for_kernel(pfn, cycle)) pfn_cache++; } /* @@ -4689,7 +4690,7 @@ __exclude_unnecessary_pages(unsigned long mem_map, else if ((info->dump_level & DL_EXCLUDE_CACHE_PRI) && (isLRU(flags) || isSwapCache(flags)) && !isAnon(mapping)) { - if (clear_bit_on_2nd_bitmap_for_kernel(pfn)) + if (clear_bit_on_2nd_bitmap_for_kernel(pfn, cycle)) pfn_cache_private++; } /* @@ -4697,14 +4698,14 @@ __exclude_unnecessary_pages(unsigned long mem_map, */ else if ((info->dump_level & DL_EXCLUDE_USER_DATA) && isAnon(mapping)) { - if (clear_bit_on_2nd_bitmap_for_kernel(pfn)) + if (clear_bit_on_2nd_bitmap_for_kernel(pfn, cycle)) pfn_user++; } /* * Exclude the hwpoison page. */ else if (isHWPOISON(flags)) { - if (clear_bit_on_2nd_bitmap_for_kernel(pfn)) + if (clear_bit_on_2nd_bitmap_for_kernel(pfn, cycle)) pfn_hwpoison++; } } @@ -4734,7 +4735,7 @@ exclude_unnecessary_pages(void) continue; if (!__exclude_unnecessary_pages(mmd->mem_map, - mmd->pfn_start, mmd->pfn_end)) + mmd->pfn_start, mmd->pfn_end, NULL)) return FALSE; } @@ -4748,17 +4749,17 @@ exclude_unnecessary_pages(void) } int -exclude_unnecessary_pages_cyclic(void) +exclude_unnecessary_pages_cyclic(struct cycle *cycle) { unsigned int mm; struct mem_map_data *mmd; struct timeval tv_start; - if (!initialize_2nd_bitmap_cyclic()) + if (!initialize_2nd_bitmap_cyclic(cycle)) return FALSE; if ((info->dump_level & DL_EXCLUDE_FREE) && !info->page_is_buddy) - if (!exclude_free_page()) + if (!exclude_free_page(cycle)) return FALSE; /* @@ -4782,10 +4783,10 @@ exclude_unnecessary_pages_cyclic(void) if (mmd->mem_map == NOT_MEMMAP_ADDR) continue; - if (mmd->pfn_end >= info->cyclic_start_pfn && - mmd->pfn_start <= info->cyclic_end_pfn) { + if (mmd->pfn_end >= cycle->start_pfn && + mmd->pfn_start <= cycle->end_pfn) { if (!__exclude_unnecessary_pages(mmd->mem_map, - mmd->pfn_start, mmd->pfn_end)) + mmd->pfn_start, mmd->pfn_end, cycle)) return FALSE; } } @@ -4801,27 +4802,6 @@ exclude_unnecessary_pages_cyclic(void) } int -update_cyclic_region(unsigned long long pfn) -{ - if (is_cyclic_region(pfn)) - return TRUE; - - info->cyclic_start_pfn = round(pfn, info->pfn_cyclic); - info->cyclic_end_pfn = info->cyclic_start_pfn + info->pfn_cyclic; - - if (info->cyclic_end_pfn > info->max_mapnr) - info->cyclic_end_pfn = info->max_mapnr; - - if (info->flag_elf_dumpfile && !create_1st_bitmap_cyclic()) - return FALSE; - - if (!exclude_unnecessary_pages_cyclic()) - return FALSE; - - return TRUE; -} - -int copy_bitmap(void) { off_t offset; @@ -4887,7 +4867,7 @@ create_2nd_bitmap(void) * Exclude free pages. */ if ((info->dump_level & DL_EXCLUDE_FREE) && !info->page_is_buddy) - if (!exclude_free_page()) + if (!exclude_free_page(NULL)) return FALSE; /* @@ -5576,13 +5556,16 @@ unsigned long long get_num_dumpable_cyclic(void) { unsigned long long pfn, num_dumpable=0; + struct cycle cycle = {0}; - for (pfn = 0; pfn < info->max_mapnr; pfn++) { - if (!update_cyclic_region(pfn)) + for_each_cycle(0, info->max_mapnr, &cycle) + { + if (!exclude_unnecessary_pages_cyclic(&cycle)) return FALSE; - if (is_dumpable_cyclic(info->partial_bitmap2, pfn)) - num_dumpable++; + for(pfn=cycle.start_pfn; pfn<cycle.end_pfn; pfn++) + if (is_dumpable_cyclic(info->partial_bitmap2, pfn, &cycle)) + num_dumpable++; } return num_dumpable; @@ -5841,16 +5824,7 @@ get_loads_dumpfile_cyclic(void) unsigned long long pfn, pfn_start, pfn_end, num_excluded; unsigned long frac_head, frac_tail; Elf64_Phdr load; - - /* - * Initialize target region and bitmap. - */ - info->cyclic_start_pfn = 0; - info->cyclic_end_pfn = info->pfn_cyclic; - if (!create_1st_bitmap_cyclic()) - return FALSE; - if (!exclude_unnecessary_pages_cyclic()) - return FALSE; + struct cycle cycle = {0}; if (!(phnum = get_phnum_memory())) return FALSE; @@ -5874,44 +5848,41 @@ get_loads_dumpfile_cyclic(void) if (frac_tail) pfn_end++; - for (pfn = pfn_start; pfn < pfn_end; pfn++) { - /* - * Update target region and bitmap - */ - if (!is_cyclic_region(pfn)) { - if (!update_cyclic_region(pfn)) - return FALSE; - } - - if (!is_dumpable_cyclic(info->partial_bitmap2, pfn)) { - num_excluded++; - continue; - } - - /* - * Exclude zero pages. - */ - if (info->dump_level & DL_EXCLUDE_ZERO) { - if (!read_pfn(pfn, buf)) - return FALSE; - if (is_zero_page(buf, page_size)) { + for_each_cycle(pfn_start, pfn_end, &cycle) { + if (!exclude_unnecessary_pages_cyclic(&cycle)) + return FALSE; + for (pfn = MAX(pfn_start, cycle.start_pfn); pfn < cycle.end_pfn; pfn++) { + if (!is_dumpable_cyclic(info->partial_bitmap2, pfn, &cycle)) { num_excluded++; continue; } - } - info->num_dumpable++; + /* + * Exclude zero pages. + */ + if (info->dump_level & DL_EXCLUDE_ZERO) { + if (!read_pfn(pfn, buf)) + return FALSE; + if (is_zero_page(buf, page_size)) { + num_excluded++; + continue; + } + } - /* - * If the number of the contiguous pages to be excluded - * is 256 or more, those pages are excluded really. - * And a new PT_LOAD segment is created. - */ - if (num_excluded >= PFN_EXCLUDED) { - num_new_load++; + info->num_dumpable++; + + /* + * If the number of the contiguous pages to be excluded + * is 256 or more, those pages are excluded really. + * And a new PT_LOAD segment is created. + */ + if (num_excluded >= PFN_EXCLUDED) { + num_new_load++; + } + num_excluded = 0; } - num_excluded = 0; } + } return num_new_load; } @@ -5929,6 +5900,7 @@ write_elf_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page) off_t off_seg_load, off_memory; Elf64_Phdr load; struct timeval tv_start; + struct cycle cycle = {0}; if (!info->flag_elf_dumpfile) return FALSE; @@ -5946,11 +5918,6 @@ write_elf_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page) pfn_user = pfn_free = pfn_hwpoison = 0; pfn_memhole = info->max_mapnr; - info->cyclic_start_pfn = 0; - info->cyclic_end_pfn = 0; - if (!update_cyclic_region(0)) - return FALSE; - if (!(phnum = get_phnum_memory())) return FALSE; @@ -5982,30 +5949,17 @@ write_elf_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page) if (frac_tail) pfn_end++; - for (pfn = pfn_start; pfn < pfn_end; pfn++) { + for_each_cycle(pfn_start, pfn_end, &cycle) { /* * Update target region and partial bitmap if necessary. */ - if (!update_cyclic_region(pfn)) + if (!create_1st_bitmap_cyclic(&cycle)) + return FALSE; + if (!exclude_unnecessary_pages_cyclic(&cycle)) return FALSE; - if (!is_dumpable_cyclic(info->partial_bitmap2, pfn)) { - num_excluded++; - if ((pfn == pfn_end - 1) && frac_tail) - memsz += frac_tail; - else - memsz += page_size; - continue; - } - - /* - * Exclude zero pages. - */ - if (info->dump_level & DL_EXCLUDE_ZERO) { - if (!read_pfn(pfn, buf)) - return FALSE; - if (is_zero_page(buf, page_size)) { - pfn_zero++; + for (pfn = MAX(pfn_start, cycle.start_pfn); pfn < cycle.end_pfn; pfn++) { + if (!is_dumpable_cyclic(info->partial_bitmap2, pfn, &cycle)) { num_excluded++; if ((pfn == pfn_end - 1) && frac_tail) memsz += frac_tail; @@ -6013,93 +5967,111 @@ write_elf_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page) memsz += page_size; continue; } - } - if ((num_dumped % per) == 0) - print_progress(PROGRESS_COPY, num_dumped, num_dumpable); + /* + * Exclude zero pages. + */ + if (info->dump_level & DL_EXCLUDE_ZERO) { + if (!read_pfn(pfn, buf)) + return FALSE; + if (is_zero_page(buf, page_size)) { + pfn_zero++; + num_excluded++; + if ((pfn == pfn_end - 1) && frac_tail) + memsz += frac_tail; + else + memsz += page_size; + continue; + } + } - num_dumped++; + if ((num_dumped % per) == 0) + print_progress(PROGRESS_COPY, num_dumped, num_dumpable); + + num_dumped++; - /* - * The dumpable pages are continuous. - */ - if (!num_excluded) { - if ((pfn == pfn_end - 1) && frac_tail) { - memsz += frac_tail; - filesz += frac_tail; - } else { - memsz += page_size; - filesz += page_size; - } - continue; /* - * If the number of the contiguous pages to be excluded - * is 255 or less, those pages are not excluded. + * The dumpable pages are continuous. */ - } else if (num_excluded < PFN_EXCLUDED) { - if ((pfn == pfn_end - 1) && frac_tail) { - memsz += frac_tail; - filesz += (page_size*num_excluded - + frac_tail); - }else { - memsz += page_size; - filesz += (page_size*num_excluded - + page_size); + if (!num_excluded) { + if ((pfn == pfn_end - 1) && frac_tail) { + memsz += frac_tail; + filesz += frac_tail; + } else { + memsz += page_size; + filesz += page_size; + } + continue; + /* + * If the number of the contiguous pages to be excluded + * is 255 or less, those pages are not excluded. + */ + } else if (num_excluded < PFN_EXCLUDED) { + if ((pfn == pfn_end - 1) && frac_tail) { + memsz += frac_tail; + filesz += (page_size*num_excluded + + frac_tail); + }else { + memsz += page_size; + filesz += (page_size*num_excluded + + page_size); + } + num_excluded = 0; + continue; } - num_excluded = 0; - continue; - } - /* - * If the number of the contiguous pages to be excluded - * is 256 or more, those pages are excluded really. - * And a new PT_LOAD segment is created. - */ - load.p_memsz = memsz; - load.p_filesz = filesz; - if (load.p_filesz) - load.p_offset = off_seg_load; - else /* - * If PT_LOAD segment does not have real data - * due to the all excluded pages, the file - * offset is not effective and it should be 0. + * If the number of the contiguous pages to be excluded + * is 256 or more, those pages are excluded really. + * And a new PT_LOAD segment is created. */ - load.p_offset = 0; - - /* - * Write a PT_LOAD header. - */ - if (!write_elf_phdr(cd_header, &load)) - return FALSE; + load.p_memsz = memsz; + load.p_filesz = filesz; + if (load.p_filesz) + load.p_offset = off_seg_load; + else + /* + * If PT_LOAD segment does not have real data + * due to the all excluded pages, the file + * offset is not effective and it should be 0. + */ + load.p_offset = 0; - /* - * Write a PT_LOAD segment. - */ - if (load.p_filesz) - if (!write_elf_load_segment(cd_page, paddr, - off_memory, load.p_filesz)) + /* + * Write a PT_LOAD header. + */ + if (!write_elf_phdr(cd_header, &load)) return FALSE; - load.p_paddr += load.p_memsz; + /* + * Write a PT_LOAD segment. + */ + if (load.p_filesz) + if (!write_elf_load_segment(cd_page, paddr, + off_memory, load.p_filesz)) + return FALSE; + + load.p_paddr += load.p_memsz; #ifdef __x86__ - /* - * FIXME: - * (x86) Fill PT_LOAD headers with appropriate - * virtual addresses. - */ - if (load.p_paddr < MAXMEM) - load.p_vaddr += load.p_memsz; + /* + * FIXME: + * (x86) Fill PT_LOAD headers with appropriate + * virtual addresses. + */ + if (load.p_paddr < MAXMEM) + load.p_vaddr += load.p_memsz; #else - load.p_vaddr += load.p_memsz; + load.p_vaddr += load.p_memsz; #endif /* x86 */ - paddr = load.p_paddr; - off_seg_load += load.p_filesz; + paddr = load.p_paddr; + off_seg_load += load.p_filesz; - num_excluded = 0; - memsz = page_size; - filesz = page_size; + num_excluded = 0; + memsz = page_size; + filesz = page_size; + } } + /* * Write the last PT_LOAD. */ @@ -6348,7 +6320,7 @@ out: int write_kdump_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page, - struct page_desc *pd_zero, off_t *offset_data) + struct page_desc *pd_zero, off_t *offset_data, struct cycle *cycle) { unsigned long long pfn, per; unsigned long long start_pfn, end_pfn; @@ -6406,8 +6378,8 @@ write_kdump_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_pag goto out; } - start_pfn = info->cyclic_start_pfn; - end_pfn = info->cyclic_end_pfn; + start_pfn = cycle->start_pfn; + end_pfn = cycle->end_pfn; if (info->flag_split) { if (start_pfn < info->split_start_pfn) @@ -6426,7 +6398,7 @@ write_kdump_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_pag /* * Check the excluded page. */ - if (!is_dumpable_cyclic(info->partial_bitmap2, pfn)) + if (!is_on(info->partial_bitmap2, pfn - cycle->start_pfn)) continue; num_dumped++; @@ -6788,20 +6760,20 @@ out: } int -write_kdump_bitmap1_cyclic(void) +write_kdump_bitmap1_cyclic(struct cycle *cycle) { off_t offset; int increment; int ret = FALSE; - increment = divideup(info->cyclic_end_pfn - info->cyclic_start_pfn, BITPERBYTE); + increment = divideup(cycle->end_pfn - cycle->start_pfn, BITPERBYTE); if (info->flag_elf_dumpfile) return FALSE; offset = info->offset_bitmap1; if (!write_buffer(info->fd_dumpfile, offset + info->bufsize_cyclic * - (info->cyclic_start_pfn / info->pfn_cyclic), + (cycle->start_pfn / info->pfn_cyclic), info->partial_bitmap1, increment, info->name_dumpfile)) goto out; @@ -6811,13 +6783,13 @@ out: } int -write_kdump_bitmap2_cyclic(void) +write_kdump_bitmap2_cyclic(struct cycle *cycle) { off_t offset; int increment; int ret = FALSE; - increment = divideup(info->cyclic_end_pfn - info->cyclic_start_pfn, + increment = divideup(cycle->end_pfn - cycle->start_pfn, BITPERBYTE); if (info->flag_elf_dumpfile) @@ -6844,7 +6816,6 @@ write_kdump_pages_and_bitmap_cyclic(struct cache_data *cd_header, struct cache_d off_t offset_data=0; struct disk_dump_header *dh = info->dump_header; unsigned char buf[info->page_size]; - unsigned long long pfn; struct timeval tv_start; /* @@ -6880,19 +6851,16 @@ write_kdump_pages_and_bitmap_cyclic(struct cache_data *cd_header, struct cache_d 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()) + struct cycle cycle = {0}; + for_each_cycle(0, info->max_mapnr, &cycle) + { + if (!create_1st_bitmap_cyclic(&cycle)) return FALSE; - if (!write_kdump_bitmap1_cyclic()) + if (!write_kdump_bitmap1_cyclic(&cycle)) return FALSE; } + free_bitmap1_buffer(); if (!prepare_bitmap2_buffer_cyclic()) @@ -6901,21 +6869,22 @@ write_kdump_pages_and_bitmap_cyclic(struct cache_data *cd_header, struct cache_d /* * Write pages and bitmap cyclically. */ - 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; + //cycle = {0, 0}; + memset(&cycle, 0, sizeof(struct cycle)); + for_each_cycle(0, info->max_mapnr, &cycle) + { + if (!exclude_unnecessary_pages_cyclic(&cycle)) + return FALSE; - if (!write_kdump_pages_cyclic(cd_header, cd_page, &pd_zero, &offset_data)) + if (!write_kdump_pages_cyclic(cd_header, cd_page, &pd_zero, + &offset_data, &cycle)) return FALSE; - if (!write_kdump_bitmap2_cyclic()) + if (!write_kdump_bitmap2_cyclic(&cycle)) return FALSE; - } + } + + gettimeofday(&tv_start, NULL); @@ -7527,7 +7496,7 @@ exclude_xen3_user_domain(void) size * num_pt_loads); if (!allocated_in_map(pfn)) { - clear_bit_on_2nd_bitmap(pfn); + clear_bit_on_2nd_bitmap(pfn, NULL); continue; } @@ -7535,7 +7504,7 @@ exclude_xen3_user_domain(void) if (!readmem(VADDR_XEN, page_info_addr + OFFSET(page_info.count_info), &count_info, sizeof(count_info))) { - clear_bit_on_2nd_bitmap(pfn); + clear_bit_on_2nd_bitmap(pfn, NULL); continue; /* page_info may not exist */ } if (!readmem(VADDR_XEN, @@ -7556,7 +7525,7 @@ exclude_xen3_user_domain(void) continue; if ((count_info & 0xffff) && is_select_domain(_domain)) continue; - clear_bit_on_2nd_bitmap(pfn); + clear_bit_on_2nd_bitmap(pfn, NULL); } } @@ -7594,7 +7563,7 @@ exclude_xen4_user_domain(void) if (!readmem(VADDR_XEN, page_info_addr + OFFSET(page_info.count_info), &count_info, sizeof(count_info))) { - clear_bit_on_2nd_bitmap(pfn); + clear_bit_on_2nd_bitmap(pfn, NULL); continue; /* page_info may not exist */ } @@ -7606,7 +7575,7 @@ exclude_xen4_user_domain(void) if (page_state_is(count_info, free) || page_state_is(count_info, offlined) || count_info & PGC_broken) { - clear_bit_on_2nd_bitmap(pfn); + clear_bit_on_2nd_bitmap(pfn, NULL); continue; } @@ -7632,7 +7601,7 @@ exclude_xen4_user_domain(void) continue; if (is_select_domain(_domain)) continue; - clear_bit_on_2nd_bitmap(pfn); + clear_bit_on_2nd_bitmap(pfn, NULL); } } diff --git a/makedumpfile.h b/makedumpfile.h index 4cf8102..38df2b3 100644 --- a/makedumpfile.h +++ b/makedumpfile.h @@ -1618,18 +1618,18 @@ is_dumpable(struct dump_bitmap *bitmap, unsigned long long pfn) } static inline int -is_dumpable_cyclic(char *bitmap, unsigned long long pfn) +is_dumpable_cyclic(char *bitmap, unsigned long long pfn, struct cycle *cycle) { - if (pfn < info->cyclic_start_pfn || info->cyclic_end_pfn <= pfn) + if (pfn < cycle->start_pfn || cycle->end_pfn <= pfn) return FALSE; else - return is_on(bitmap, pfn - info->cyclic_start_pfn); + return is_on(bitmap, pfn - cycle->start_pfn); } static inline int -is_cyclic_region(unsigned long long pfn) +is_cyclic_region(unsigned long long pfn, struct cycle *cycle) { - if (pfn < info->cyclic_start_pfn || info->cyclic_end_pfn <= pfn) + if (pfn < cycle->start_pfn || cycle->end_pfn <= pfn) return FALSE; else return TRUE; @@ -1647,8 +1647,8 @@ is_zero_page(unsigned char *buf, long page_size) } void write_vmcoreinfo_data(void); -int set_bit_on_1st_bitmap(unsigned long long pfn); -int clear_bit_on_1st_bitmap(unsigned long long pfn); +int set_bit_on_1st_bitmap(unsigned long long pfn, struct cycle *cycle); +int clear_bit_on_1st_bitmap(unsigned long long pfn, struct cycle *cycle); #ifdef __x86__ diff --git a/sadump_info.c b/sadump_info.c index 7822e82..f14ffc9 100644 --- a/sadump_info.c +++ b/sadump_info.c @@ -214,9 +214,9 @@ sadump_copy_1st_bitmap_from_memory(void) si->backup_src_start); if (is_dumpable(info->bitmap_memory, backup_src_pfn)) - set_bit_on_1st_bitmap(pfn); + set_bit_on_1st_bitmap(pfn, NULL); else - clear_bit_on_1st_bitmap(pfn); + clear_bit_on_1st_bitmap(pfn, NULL); } } -- 1.8.3.1