[RFC PATCH] patch for crash dump bitmap

Jingbai Ma jingbai.ma at hp.com
Thu Mar 7 09:07:54 EST 2013


Use the crash dump bitmap to speedup memory pages classification process.

Signed-off-by: Jingbai Ma <jingbai.ma at hp.com>
---
 makedumpfile.c |  122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 makedumpfile.h |   38 +++++++++++++++++
 2 files changed, 157 insertions(+), 3 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index acb1b21..f29b6a5 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -34,6 +34,10 @@ struct srcfile_table	srcfile_table;
 struct vm_table		vt = { 0 };
 struct DumpInfo		*info = NULL;
 
+struct crash_dump_bitmap_info	crash_dump_bitmap_info;
+
+const unsigned int CURRENT_BITMAP_INFO_VERSION = 1;
+
 char filename_stdout[] = FILENAME_STDOUT;
 
 /*
@@ -892,6 +896,7 @@ get_symbol_info(void)
 	SYMBOL_INIT(node_remap_start_vaddr, "node_remap_start_vaddr");
 	SYMBOL_INIT(node_remap_end_vaddr, "node_remap_end_vaddr");
 	SYMBOL_INIT(node_remap_start_pfn, "node_remap_start_pfn");
+	SYMBOL_INIT(crash_dump_bitmap_info, "crash_dump_bitmap_info");
 
 	if (SYMBOL(node_data) != NOT_FOUND_SYMBOL)
 		SYMBOL_ARRAY_TYPE_INIT(node_data, "node_data");
@@ -1704,6 +1709,8 @@ read_vmcoreinfo(void)
 	READ_SYMBOL("node_remap_end_vaddr", node_remap_end_vaddr);
 	READ_SYMBOL("node_remap_start_pfn", node_remap_start_pfn);
 
+	READ_SYMBOL("crash_dump_bitmap_info", crash_dump_bitmap_info);
+
 	READ_STRUCTURE_SIZE("page", page);
 	READ_STRUCTURE_SIZE("mem_section", mem_section);
 	READ_STRUCTURE_SIZE("pglist_data", pglist_data);
@@ -4423,6 +4430,74 @@ copy_bitmap(void)
 int
 create_2nd_bitmap(void)
 {
+	off_t offset_page;
+	char buf1[info->page_size], buf2[info->page_size];
+	int i;
+
+	if (info->flag_crash_dump_bitmap) {
+		offset_page = 0;
+		while (offset_page < (info->len_bitmap / 2)) {
+			if (lseek(info->bitmap1->fd, info->bitmap1->offset
+				+ offset_page, SEEK_SET) < 0) {
+				ERRMSG("Can't seek the bitmap(%s). %s\n",
+				    info->bitmap1->file_name, strerror(errno));
+				return FALSE;
+			}
+
+			if (read(info->bitmap1->fd, buf1, info->page_size)
+				!= info->page_size) {
+					ERRMSG("Can't read bitmap(%s). %s\n",
+					info->bitmap1->file_name,
+					strerror(errno));
+				return FALSE;
+			}
+
+			if (readmem(PADDR, crash_dump_bitmap_info.bitmap
+				+ offset_page, buf2, info->page_size)
+				!= info->page_size) {
+				ERRMSG("Can't read bitmap1! addr=%llx\n",
+					crash_dump_bitmap_info.bitmap
+					+ offset_page);
+				return FALSE;
+			}
+
+			if (crash_dump_bitmap_info.version
+				!= CURRENT_BITMAP_INFO_VERSION) {
+				ERRMSG("bitmap version! expected=%d, got=%d\n",
+					CURRENT_BITMAP_INFO_VERSION,
+					crash_dump_bitmap_info.version);
+				return FALSE;
+			}
+
+			for (i = 0; i < info->page_size; i++)
+				buf2[i] = buf1[i] & buf2[i];
+
+			if (lseek(info->bitmap2->fd, info->bitmap2->offset
+				+ offset_page, SEEK_SET) < 0) {
+				ERRMSG("Can't seek the bitmap(%s). %s\n",
+				    info->bitmap2->file_name, strerror(errno));
+				return FALSE;
+			}
+
+			if (write(info->bitmap2->fd, buf2, info->page_size)
+				!= info->page_size) {
+				ERRMSG("Can't write the bitmap(%s). %s\n",
+				    info->bitmap2->file_name, strerror(errno));
+				return FALSE;
+			}
+
+			offset_page += info->page_size;
+		}
+
+		pfn_cache = crash_dump_bitmap_info.cache_pages;
+		pfn_cache_private = crash_dump_bitmap_info.cache_private_pages;
+		pfn_user = crash_dump_bitmap_info.user_pages;
+		pfn_free = crash_dump_bitmap_info.free_pages;
+		pfn_hwpoison = crash_dump_bitmap_info.hwpoison_pages;
+
+		return TRUE;
+	}
+
 	/*
 	 * Copy 1st-bitmap to 2nd-bitmap.
 	 */
@@ -4587,6 +4662,46 @@ create_dump_bitmap(void)
 		if (!prepare_bitmap_buffer())
 			goto out;
 
+		if (info->flag_crash_dump_bitmap
+			&& (SYMBOL(crash_dump_bitmap_info)
+			!= NOT_FOUND_SYMBOL)) {
+			/* Read crash_dump_bitmap_info from old kernel */
+			readmem(VADDR, SYMBOL(crash_dump_bitmap_info),
+				&crash_dump_bitmap_info,
+				sizeof(struct crash_dump_bitmap_info));
+
+			if (!crash_dump_bitmap_info.bitmap_size
+				|| !crash_dump_bitmap_info.bitmap) {
+				ERRMSG("Can't get crash_dump bitmap info! ");
+				ERRMSG("Failback to legacy mode.\n");
+				ERRMSG("crash_dump_bitmap_info=0x%llx, ",
+					SYMBOL(crash_dump_bitmap_info));
+				ERRMSG("bitmap=0x%llx, ",
+					crash_dump_bitmap_info.bitmap);
+				ERRMSG("bitmap_size=%lld\n",
+					crash_dump_bitmap_info.bitmap_size);
+
+				info->flag_crash_dump_bitmap = FALSE;
+			} else {
+				MSG("crash_dump_bitmap: ");
+				MSG("crash_dump_bitmap_info=0x%llx, ",
+					SYMBOL(crash_dump_bitmap_info));
+				MSG("bitmap=0x%llx, ",
+					crash_dump_bitmap_info.bitmap);
+				MSG("bitmap_size=%lld, ",
+					crash_dump_bitmap_info.bitmap_size);
+				MSG("cache_pages=0x%lx, ",
+					crash_dump_bitmap_info.cache_pages);
+				MSG("cache_private_pages=0x%lx, ",
+					crash_dump_bitmap_info
+					.cache_private_pages);
+				MSG("user_pages=0x%lx, ",
+					crash_dump_bitmap_info.user_pages);
+				MSG("free_pages=0x%lx\n",
+					crash_dump_bitmap_info.free_pages);
+			}
+		}
+
 		if (!create_1st_bitmap())
 			goto out;
 
@@ -8454,7 +8569,8 @@ 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, "b:cDd:EFfg:hi:lMpqRrsvXx:",
+		longopts,
 	    NULL)) != -1) {
 		switch (opt) {
 		case 'b':
@@ -8518,6 +8634,10 @@ main(int argc, char *argv[])
 		case 'P':
 			info->xen_phys_start = strtoul(optarg, NULL, 0);
 			break;
+		case 'q':
+			info->flag_crash_dump_bitmap = TRUE;
+			info->flag_cyclic = FALSE;
+			break;
 		case 'R':
 			info->flag_rearrange = 1;
 			break;
diff --git a/makedumpfile.h b/makedumpfile.h
index 272273e..6404b16 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -41,6 +41,8 @@
 #include "dwarf_info.h"
 #include "diskdump_mod.h"
 #include "sadump_mod.h"
+#include "print_info.h"
+
 
 /*
  * Result of command
@@ -889,6 +891,7 @@ struct DumpInfo {
 	int		flag_refiltering;    /* refilter from kdump-compressed file */
 	int		flag_force;	     /* overwrite existing stuff */
 	int		flag_exclude_xen_dom;/* exclude Domain-U from xen-kdump */
+	int		flag_crash_dump_bitmap;/* crash dump bitmap */
 	int             flag_dmesg;          /* dump the dmesg log out of the vmcore file */
 	int		flag_nospace;	     /* the flag of "No space on device" error */
 	unsigned long	vaddr_for_vtop;      /* virtual address for debugging */
@@ -1153,6 +1156,11 @@ struct symbol_table {
 	unsigned long long	__per_cpu_load;
 	unsigned long long	cpu_online_mask;
 	unsigned long long	kexec_crash_image;
+
+	/*
+	 * for crash_dump_bitmap
+ 	 */
+	unsigned long long	crash_dump_bitmap_info;
 };
 
 struct size_table {
@@ -1381,6 +1389,20 @@ struct srcfile_table {
 	char	pud_t[LEN_SRCFILE];
 };
 
+/*
+ * for crash_dump_bitmap
+ */
+struct crash_dump_bitmap_info {
+	unsigned int version;
+	unsigned long long bitmap;
+	unsigned long long bitmap_size;
+	unsigned long cache_pages;
+	unsigned long cache_private_pages;
+	unsigned long user_pages;
+	unsigned long free_pages;
+	unsigned long hwpoison_pages;
+};
+
 extern struct symbol_table	symbol_table;
 extern struct size_table	size_table;
 extern struct offset_table	offset_table;
@@ -1541,8 +1563,20 @@ is_dumpable(struct dump_bitmap *bitmap, unsigned long long pfn)
 	off_t offset;
 	if (pfn == 0 || bitmap->no_block != pfn/PFN_BUFBITMAP) {
 		offset = bitmap->offset + BUFSIZE_BITMAP*(pfn/PFN_BUFBITMAP);
-		lseek(bitmap->fd, offset, SEEK_SET);
-		read(bitmap->fd, bitmap->buf, BUFSIZE_BITMAP);
+		if (lseek(bitmap->fd, offset, SEEK_SET) < 0) {
+			ERRMSG("Can't seek bitmap file %s:(%d), ",
+				bitmap->file_name, bitmap->fd);
+			ERRMSG("offset=%ld, error: %s\n",
+				offset, strerror(errno));
+		}
+
+		if (read(bitmap->fd, bitmap->buf, BUFSIZE_BITMAP) < 0) {
+			ERRMSG("Can't read bitmap file %s:(%d), ",
+				bitmap->file_name, bitmap->fd);
+			ERRMSG("offset=%ld, error: %s\n",
+				offset, strerror(errno));
+		}
+
 		if (pfn == 0)
 			bitmap->no_block = 0;
 		else




More information about the kexec mailing list