[RFC PATCH v2 2/10] Prepare partial bitmap for cyclic processing.
Atsushi Kumagai
kumagai-atsushi at mxc.nes.nec.co.jp
Thu Jun 28 22:17:00 EDT 2012
cyclic processing uses partial bitmap instead of temporary bitmap file.
partial bitmap is saved in memory only for each cycle.
This patch introduce partial bitmap and extend some accessor functions
to manage partial bitmap.
Signed-off-by: Atsushi Kumagai <kumagai-atsushi at mxc.nes.nec.co.jp>
---
makedumpfile.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++------
makedumpfile.h | 23 +++++++++++++
2 files changed, 113 insertions(+), 9 deletions(-)
diff --git a/makedumpfile.c b/makedumpfile.c
index 87bd680..9e77913 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -165,6 +165,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);
unsigned long
pfn_to_pos(unsigned long long pfn)
{
@@ -2719,6 +2720,12 @@ initialize_bitmap(struct dump_bitmap *bitmap)
}
void
+initialize_bitmap_cyclic(char *bitmap)
+{
+ memset(bitmap, 0, BUFSIZE_CYCLIC);
+}
+
+void
initialize_1st_bitmap(struct dump_bitmap *bitmap)
{
initialize_bitmap(bitmap);
@@ -2782,6 +2789,27 @@ set_bitmap(struct dump_bitmap *bitmap, unsigned long long pfn,
}
int
+set_bitmap_cyclic(char *bitmap, unsigned long long pfn, int val)
+{
+ int byte, bit;
+
+ if (pfn < info->cyclic_start_pfn || info->cyclic_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;
+ if (val)
+ bitmap[byte] |= 1<<bit;
+ else
+ bitmap[byte] &= ~(1<<bit);
+
+ return TRUE;
+}
+
+int
sync_bitmap(struct dump_bitmap *bitmap)
{
off_t offset;
@@ -2823,19 +2851,31 @@ sync_2nd_bitmap(void)
int
set_bit_on_1st_bitmap(unsigned long long pfn)
{
- return set_bitmap(info->bitmap1, pfn, 1);
+ if (info->flag_cyclic) {
+ return set_bitmap_cyclic(info->partial_bitmap1, pfn, 1);
+ } else {
+ return set_bitmap(info->bitmap1, pfn, 1);
+ }
}
int
clear_bit_on_1st_bitmap(unsigned long long pfn)
{
- return set_bitmap(info->bitmap1, pfn, 0);
+ if (info->flag_cyclic) {
+ return set_bitmap_cyclic(info->partial_bitmap1, pfn, 0);
+ } else {
+ return set_bitmap(info->bitmap1, pfn, 0);
+ }
}
int
clear_bit_on_2nd_bitmap(unsigned long long pfn)
{
- return set_bitmap(info->bitmap2, pfn, 0);
+ if (info->flag_cyclic) {
+ return set_bitmap_cyclic(info->partial_bitmap2, pfn, 0);
+ } else {
+ return set_bitmap(info->bitmap2, pfn, 0);
+ }
}
int
@@ -3914,6 +3954,38 @@ prepare_bitmap_buffer(void)
return TRUE;
}
+int
+prepare_bitmap_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_bitmap1 = (char *)malloc(BUFSIZE_CYCLIC)) == NULL) {
+ ERRMSG("Can't allocate memory for the 1st-bitmap. %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+ if ((info->partial_bitmap2 = (char *)malloc(BUFSIZE_CYCLIC)) == NULL) {
+ ERRMSG("Can't allocate memory for the 2nd-bitmap. %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+ initialize_bitmap_cyclic(info->partial_bitmap1);
+ initialize_bitmap_cyclic(info->partial_bitmap2);
+
+ return TRUE;
+}
+
void
free_bitmap_buffer(void)
{
@@ -3934,14 +4006,19 @@ create_dump_bitmap(void)
{
int ret = FALSE;
- if (!prepare_bitmap_buffer())
- goto out;
+ if (info->flag_cyclic) {
+ if (!prepare_bitmap_buffer_cyclic())
+ goto out;
+ } else {
+ if (!prepare_bitmap_buffer())
+ goto out;
- if (!create_1st_bitmap())
- goto out;
+ if (!create_1st_bitmap())
+ goto out;
- if (!create_2nd_bitmap())
- goto out;
+ if (!create_2nd_bitmap())
+ goto out;
+ }
ret = TRUE;
out:
@@ -7203,6 +7280,10 @@ out:
free(info->splitting_info);
if (info->p2m_mfn_frame_list != NULL)
free(info->p2m_mfn_frame_list);
+ if (info->partial_bitmap1 != NULL)
+ free(info->partial_bitmap1);
+ if (info->partial_bitmap2 != NULL)
+ free(info->partial_bitmap2);
free(info);
}
free_elf_info();
diff --git a/makedumpfile.h b/makedumpfile.h
index 287e055..bf5dd43 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -173,6 +173,12 @@ isAnon(unsigned long mapping)
#define FILENAME_STDOUT "STDOUT"
/*
+ * For cyclic processing
+ */
+#define BUFSIZE_CYCLIC (1024 * 1024)
+#define PFN_CYCLIC (BUFSIZE_CYCLIC * BITPERBYTE)
+
+/*
* Minimam vmcore has 2 ProgramHeaderTables(PT_NOTE and PT_LOAD).
*/
#define MIN_ELF32_HEADER_SIZE \
@@ -926,6 +932,14 @@ struct DumpInfo {
unsigned long long split_end_pfn;
/*
+ * for cyclic processing
+ */
+ char *partial_bitmap1;
+ char *partial_bitmap2;
+ unsigned long long cyclic_start_pfn;
+ unsigned long long cyclic_end_pfn;
+
+ /*
* sadump info:
*/
int flag_sadump_diskset;
@@ -1395,6 +1409,15 @@ is_dumpable(struct dump_bitmap *bitmap, unsigned long long pfn)
}
static inline int
+is_dumpable_cyclic(char *bitmap, unsigned long long pfn)
+{
+ if (pfn < info->cyclic_start_pfn || info->cyclic_end_pfn <= pfn)
+ return FALSE;
+ else
+ return is_on(bitmap, pfn - info->cyclic_start_pfn);
+}
+
+static inline int
is_zero_page(unsigned char *buf, long page_size)
{
size_t i;
--
1.7.9.2
More information about the kexec
mailing list