[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