From: Cliff Wickman <[email protected]>

- get_mm_sparsemem(): reduce the number of entries in the mem_map[] by
  recording only those sections which actually exist in memory
- shorten the executions of __exclude_unnecessary_pages() by passing it only
  the pfn's of the current cyclic area

- for testing: add option -a to use cyclic mode when plenty of memory is
  available for noncyclic mode
  (assumes patch  makedumpfile: use non-cyclic when possible)

- cosmetic: in cyclic mode count the number of cycles and report the cycle
  number as the scan-and-copy cycles progress
- cosmetic: let the prints of unnecessary page scans stop at their current
  position, i.e. at the end of the current cyclic region

makes a progress history like

Begin page counting phase.
Scan cycle 1
Excluding free pages               : [100 %] 
Excluding unnecessary pages        : [ 45 %] 
Scan cycle 2
Excluding free pages               : [ 87 %] 
Excluding unnecessary pages        : [ 87 %] 
Scan cycle 3
Excluding free pages               : [100 %] 
Excluding unnecessary pages        : [ 99 %] 
Scan cycle 4

Scan-and-copy cycle 1/3
Excluding free pages               : [ 45 %] 
Excluding unnecessary pages        : [ 45 %] 
Copying data                       : [ 44 %] 
Scan-and-copy cycle 2/3
Excluding free pages               : [ 87 %] 
Excluding unnecessary pages        : [ 87 %] 
Copying data                       : [ 86 %] 
Scan-and-copy cycle 3/3
Excluding free pages               : [100 %] 
Excluding unnecessary pages        : [ 99 %] 
Copying data                       : [100 %] 
Saving core complete


Diffed against makedumpfile-1.5.4
Signed-off-by: Cliff Wickman <[email protected]>
---
 makedumpfile.c |  127 +++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 98 insertions(+), 29 deletions(-)

Index: makedumpfile-1.5.4/makedumpfile.c
===================================================================
--- makedumpfile-1.5.4.orig/makedumpfile.c
+++ makedumpfile-1.5.4/makedumpfile.c
@@ -50,6 +50,8 @@ unsigned long long pfn_hwpoison;
 unsigned long long num_dumped;
 
 int retcd = FAILED;    /* return code */
+int aflag = 0;
+int total_cycles = 0;
 
 #define INITIALIZE_LONG_TABLE(table, value) \
 do { \
@@ -2651,7 +2653,7 @@ sparse_decode_mem_map(unsigned long code
 int
 get_mm_sparsemem(void)
 {
-       unsigned int section_nr, mem_section_size, num_section;
+       unsigned int section_nr, valid_section_nr, mem_section_size, 
num_section;
        unsigned long long pfn_start, pfn_end;
        unsigned long section, mem_map;
        unsigned long *mem_sec = NULL;
@@ -2686,17 +2688,26 @@ get_mm_sparsemem(void)
                    strerror(errno));
                goto out;
        }
+       valid_section_nr = 0;
        for (section_nr = 0; section_nr < num_section; section_nr++) {
                section = nr_to_section(section_nr, mem_sec);
                mem_map = section_mem_map_addr(section);
                mem_map = sparse_decode_mem_map(mem_map, section_nr);
-               if (!is_kvaddr(mem_map))
-                       mem_map = NOT_MEMMAP_ADDR;
-               pfn_start = section_nr * PAGES_PER_SECTION();
-               pfn_end   = pfn_start + PAGES_PER_SECTION();
-               if (info->max_mapnr < pfn_end)
-                       pfn_end = info->max_mapnr;
-               dump_mem_map(pfn_start, pfn_end, mem_map, section_nr);
+               if (is_kvaddr(mem_map)) {
+                       pfn_start = section_nr * PAGES_PER_SECTION();
+                       pfn_end   = pfn_start + PAGES_PER_SECTION();
+                       if (info->max_mapnr < pfn_end)
+                               pfn_end = info->max_mapnr;
+                       dump_mem_map(pfn_start, pfn_end, mem_map, 
valid_section_nr);
+                       valid_section_nr++;
+               }
+       }
+       info->num_mem_map = valid_section_nr;
+       if (valid_section_nr < num_section) {
+               if (realloc(mem_sec, mem_section_size) != mem_sec) {
+                       ERRMSG("mem_sec realloc failed\n");
+                       exit(1);
+               };
        }
        ret = TRUE;
 out:
@@ -3642,10 +3653,15 @@ reset_bitmap_of_free_pages(unsigned long
                                        retcd = ANALYSIS_FAILED;
                                        return FALSE;
                                }
-                               for (i = 0; i < (1<<order); i++) {
-                                       pfn = start_pfn + i;
-                                       if 
(clear_bit_on_2nd_bitmap_for_kernel(pfn))
-                                               found_free_pages++;
+
+                               if (!info->flag_cyclic ||
+                                   ((start_pfn >= info->cyclic_start_pfn) &&
+                                    (start_pfn < info->cyclic_end_pfn))) {
+                                       for (i = 0; i < (1<<order); i++) {
+                                               pfn = start_pfn + i;
+                                               if 
(clear_bit_on_2nd_bitmap_for_kernel(pfn))
+                                                       found_free_pages++;
+                                       }
                                }
 
                                previous = curr;
@@ -4519,6 +4535,10 @@ int
 exclude_unnecessary_pages_cyclic(void)
 {
        unsigned int mm;
+       unsigned long pfn_start;
+       unsigned long pfn_end;
+       unsigned long mem_map;
+       long offset;
        struct mem_map_data *mmd;
        struct timeval tv_start;
 
@@ -4527,9 +4547,12 @@ exclude_unnecessary_pages_cyclic(void)
         */
        copy_bitmap_cyclic();
 
-       if ((info->dump_level & DL_EXCLUDE_FREE) && !info->page_is_buddy)
+       if ((info->dump_level & DL_EXCLUDE_FREE) && !info->page_is_buddy) {
                if (!exclude_free_page())
                        return FALSE;
+               else
+                       PROGRESS_MSG("\n");
+       }
 
        /*
         * Exclude cache pages, cache private pages, user data pages,
@@ -4549,21 +4572,37 @@ exclude_unnecessary_pages_cyclic(void)
 
                        mmd = &info->mem_map_data[mm];
 
+                       // NOT_MEMMAP_ADDR generally not used
                        if (mmd->mem_map == NOT_MEMMAP_ADDR)
                                continue;
 
                        if (mmd->pfn_end >= info->cyclic_start_pfn &&
                            mmd->pfn_start <= info->cyclic_end_pfn) {
-                               if (!__exclude_unnecessary_pages(mmd->mem_map,
-                                                                
mmd->pfn_start, mmd->pfn_end))
+                               offset = 0;
+                               pfn_start = mmd->pfn_start;
+                               pfn_end = mmd->pfn_end;
+                               mem_map = mmd->mem_map;
+                               if (info->cyclic_end_pfn < pfn_end) {
+                                       pfn_end = info->cyclic_end_pfn;
+                               }
+                               if (info->cyclic_start_pfn > pfn_start) {
+                                       offset = info->cyclic_start_pfn -
+                                               pfn_start;
+                                       mem_map = mmd->mem_map +
+                                                       (SIZE(page) * offset);
+                                       pfn_start = info->cyclic_start_pfn;
+                               }
+
+                               if (!__exclude_unnecessary_pages(mem_map,
+                                                       pfn_start, pfn_end))
                                        return FALSE;
                        }
                }
 
                /*
-                * print [100 %]
+                * let progress stop at the print ending position
                 */
-               print_progress(PROGRESS_UNN_PAGES, info->num_mem_map, 
info->num_mem_map);
+               PROGRESS_MSG("\n");
                print_execution_time(PROGRESS_UNN_PAGES, &tv_start);
        }
 
@@ -4571,7 +4610,7 @@ exclude_unnecessary_pages_cyclic(void)
 }
 
 int
-update_cyclic_region(unsigned long long pfn)
+update_cyclic_region(unsigned long long pfn, int *didscan)
 {
        if (is_cyclic_region(pfn))
                return TRUE;
@@ -4588,6 +4627,8 @@ update_cyclic_region(unsigned long long 
        if (!exclude_unnecessary_pages_cyclic())
                return FALSE;
 
+       if (didscan)
+               (*didscan)++;
        return TRUE;
 }
 
@@ -4651,14 +4692,17 @@ create_2nd_bitmap(void)
                        ERRMSG("Can't exclude unnecessary pages.\n");
                        return FALSE;
                }
+               PROGRESS_MSG("\n");
        }
 
        /*
         * Exclude free pages.
         */
-       if ((info->dump_level & DL_EXCLUDE_FREE) && !info->page_is_buddy)
+       if ((info->dump_level & DL_EXCLUDE_FREE) && !info->page_is_buddy) {
                if (!exclude_free_page())
                        return FALSE;
+               PROGRESS_MSG("\n");
+       }
 
        /*
         * Exclude Xen user domain.
@@ -5262,15 +5306,26 @@ get_num_dumpable(void)
 unsigned long long
 get_num_dumpable_cyclic(void)
 {
+       int cycle = 0;
+       int lastcycle = 0;
+       int newcycle = 1;
        unsigned long long pfn, num_dumpable=0;
 
+       PROGRESS_MSG("Begin page counting phase.\n");
        for (pfn = 0; pfn < info->max_mapnr; pfn++) {
-               if (!update_cyclic_region(pfn))
+               if (newcycle)
+                       PROGRESS_MSG("Scan cycle %d\n", cycle + 1);
+               newcycle = 0;
+               lastcycle = cycle;
+               if (!update_cyclic_region(pfn, &cycle))
                        return FALSE;
+               if (cycle > lastcycle)
+                       newcycle++;
 
                if (is_dumpable_cyclic(info->partial_bitmap2, pfn))
                        num_dumpable++;
        }
+       total_cycles = cycle;
 
        return num_dumpable;
 }
@@ -5566,7 +5621,7 @@ get_loads_dumpfile_cyclic(void)
                         * Update target region and bitmap
                         */
                        if (!is_cyclic_region(pfn)) {
-                               if (!update_cyclic_region(pfn))
+                               if (!update_cyclic_region(pfn, 0))
                                        return FALSE;
                        }
 
@@ -5635,7 +5690,7 @@ write_elf_pages_cyclic(struct cache_data
 
        info->cyclic_start_pfn = 0;
        info->cyclic_end_pfn = 0;
-       if (!update_cyclic_region(0))
+       if (!update_cyclic_region(0, 0))
                return FALSE;
 
        if (!(phnum = get_phnum_memory()))
@@ -5673,7 +5728,7 @@ write_elf_pages_cyclic(struct cache_data
                        /*
                         * Update target region and partial bitmap if necessary.
                         */
-                       if (!update_cyclic_region(pfn))
+                       if (!update_cyclic_region(pfn, 0))
                                return FALSE;
 
                        if (!is_dumpable_cyclic(info->partial_bitmap2, pfn)) {
@@ -6499,6 +6554,7 @@ out:
 int
 write_kdump_pages_and_bitmap_cyclic(struct cache_data *cd_header, struct 
cache_data *cd_page)
 {
+       int cycle_number = 1;
        struct page_desc pd_zero;
        off_t offset_data=0;
        struct disk_dump_header *dh = info->dump_header;
@@ -6544,7 +6600,10 @@ write_kdump_pages_and_bitmap_cyclic(stru
                if (is_cyclic_region(pfn))
                        continue;
 
-               if (!update_cyclic_region(pfn))
+               PROGRESS_MSG("\nScan-and-copy cycle %d/%d\n",
+                       cycle_number, total_cycles);
+               cycle_number++;
+               if (!update_cyclic_region(pfn, 0))
                         return FALSE;
 
                if (!write_kdump_pages_cyclic(cd_header, cd_page, &pd_zero, 
&offset_data))
@@ -7673,12 +7732,19 @@ create_dumpfile(void)
        print_vtop();
 
        if (plenty_of_memory()) {
-               if (info->flag_cyclic == TRUE)
-                       MSG("Plenty of memory; using non-cyclic mode.\n");
-               info->flag_cyclic = FALSE;
+               if (info->flag_cyclic == TRUE) {
+                       if (aflag)
+                               PROGRESS_MSG(
+                            "Plenty of memory; could use non-cyclic mode.\n");
+                       else {
+                               PROGRESS_MSG(
+                               "Plenty of memory; using non-cyclic mode.\n");
+                               info->flag_cyclic = FALSE;
+                       }
+               }
        } else {
                if (info->flag_cyclic == TRUE)
-                       MSG("Restricted memory; staying in cyclic mode.\n");
+                       PROGRESS_MSG("Restricted memory; staying in cyclic 
mode.\n");
        }
 
        num_retry = 0;
@@ -8623,9 +8689,12 @@ main(int argc, char *argv[])
        
        info->block_order = DEFAULT_ORDER;
        message_level = DEFAULT_MSG_LEVEL;
-       while ((opt = getopt_long(argc, argv, "b:cDd:EFfg:hi:lMpRrsvXx:", 
longopts,
+       while ((opt = getopt_long(argc, argv, "ab:cDd:EFfg:hi:lMpRrsvXx:", 
longopts,
            NULL)) != -1) {
                switch (opt) {
+               case 'a':
+                       aflag = 1; // force cyclic mode
+                       break;
                case 'b':
                        info->block_order = atoi(optarg);
                        break;

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

Reply via email to