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 <[email protected]>
---
 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

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

Reply via email to