[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v5 6/9] dump: Add API to write dump_bitmap
From: |
Qiao Nuohan |
Subject: |
[Qemu-devel] [PATCH v5 6/9] dump: Add API to write dump_bitmap |
Date: |
Tue, 9 Jul 2013 15:30:11 +0800 |
functions are used to write 1st and 2nd dump_bitmap of kdump-compressed format,
which is used to indicate whether the corresponded page is existed in vmcore.
Dump level 1 is chosen, so 1st and 2nd dump_bitmap are same.
Signed-off-by: Qiao Nuohan <address@hidden>
Reviewed-by: Zhang Xiaohe <address@hidden>
---
dump.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++
include/sysemu/dump.h | 5 ++
2 files changed, 141 insertions(+), 0 deletions(-)
diff --git a/dump.c b/dump.c
index cb2f866..40a5ea5 100644
--- a/dump.c
+++ b/dump.c
@@ -79,12 +79,14 @@ typedef struct DumpState {
bool flag_flatten;
uint32_t nr_cpus;
size_t page_size;
+ uint32_t page_shift;
size_t max_mapnr;
size_t len_dump_bitmap;
void *note_buf;
size_t note_buf_offset;
off_t offset_dump_bitmap;
off_t offset_page;
+ size_t num_dumpable;
} DumpState;
static int dump_cleanup(DumpState *s)
@@ -925,6 +927,140 @@ static int write_dump_header(DumpState *s)
}
}
+/* set dump_bitmap sequencely */
+static int set_dump_bitmap(int64_t last_pfn, int64_t pfn, uint32_t value,
+ void *buf, DumpState *s)
+{
+ off_t old_offset, new_offset;
+ off_t offset_bitmap1, offset_bitmap2;
+ uint32_t byte, bit;
+
+ /* should not set the previous place */
+ if (last_pfn > pfn) {
+ return -1;
+ }
+
+ /*
+ * if the block needed to be set is not same as the one cached in buf,
flush
+ * the cached buf to vmcore firstly
+ */
+ old_offset = BUFSIZE_BITMAP * (last_pfn / PFN_BUFBITMAP);
+ new_offset = BUFSIZE_BITMAP * (pfn / PFN_BUFBITMAP);
+
+ while (old_offset < new_offset) {
+ /* calculate the offset and write dump_bitmap */
+ offset_bitmap1 = s->offset_dump_bitmap + old_offset;
+ if (write_buffer(s->fd, s->flag_flatten, offset_bitmap1, buf,
+ BUFSIZE_BITMAP) < 0) {
+ return -1;
+ }
+
+ /* dump level 1 is chosen, so 1st and 2nd bitmap are same */
+ offset_bitmap2 = s->offset_dump_bitmap + s->len_dump_bitmap / 2 +
+ old_offset;
+ if (write_buffer(s->fd, s->flag_flatten, offset_bitmap2, buf,
+ BUFSIZE_BITMAP) < 0) {
+ return -1;
+ }
+
+ memset(buf, 0, BUFSIZE_BITMAP);
+ old_offset += BUFSIZE_BITMAP;
+ }
+
+ /* get the exact place of the bit in the buf, and set it */
+ byte = (pfn % PFN_BUFBITMAP) >> 3;
+ bit = (pfn % PFN_BUFBITMAP) & 7;
+ if (value) {
+ ((char *)buf)[byte] |= 1<<bit;
+ } else {
+ ((char *)buf)[byte] &= ~(1<<bit);
+ }
+
+ return 0;
+}
+
+/* write the remaining dump_bitmap in buf to s->fd */
+static int sync_dump_bitmap(int64_t last_pfn, void *buf, DumpState *s)
+{
+ off_t last_offset, offset_bitmap1, offset_bitmap2;
+
+ /* nothing is stored in buf */
+ if (last_pfn < 0) {
+ return 0;
+ }
+
+ last_offset = BUFSIZE_BITMAP * (last_pfn / PFN_BUFBITMAP);
+
+ /* calculate the offset and write dump_bitmap */
+ offset_bitmap1 = s->offset_dump_bitmap + last_offset;
+ if (write_buffer(s->fd, s->flag_flatten, offset_bitmap1, buf,
+ BUFSIZE_BITMAP) < 0) {
+ return -1;
+ }
+
+ offset_bitmap2 = s->offset_dump_bitmap + s->len_dump_bitmap / 2 +
+ last_offset;
+ if (write_buffer(s->fd, s->flag_flatten, offset_bitmap2, buf,
+ BUFSIZE_BITMAP) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int write_dump_bitmap(DumpState *s)
+{
+ int ret = 0;
+ int64_t pfn_start, pfn_end, pfn;
+ int64_t last_pfn;
+ void *dump_bitmap_buf;
+ size_t num_dumpable;
+ MemoryMapping *memory_mapping;
+
+ /* dump_bitmap_buf is used to store dump_bitmap temporarily */
+ dump_bitmap_buf = g_malloc0(BUFSIZE_BITMAP);
+
+ num_dumpable = 0;
+ last_pfn = -1;
+
+ /*
+ * exam memory page by page, and set the bit in dump_bitmap corresponded
+ * to the existing page
+ */
+ QTAILQ_FOREACH(memory_mapping, &s->list.head, next) {
+ pfn_start = paddr_to_pfn(memory_mapping->phys_addr, s->page_shift);
+ pfn_end = paddr_to_pfn(memory_mapping->phys_addr +
+ memory_mapping->length, s->page_shift);
+
+ for (pfn = pfn_start; pfn < pfn_end; pfn++) {
+ ret = set_dump_bitmap(last_pfn, pfn, 1, dump_bitmap_buf, s);
+ if (ret < 0) {
+ dump_error(s, "dump: failed to set dump_bitmap.\n");
+ ret = -1;
+ goto out;
+ }
+
+ last_pfn = pfn;
+ num_dumpable++;
+ }
+ }
+
+ ret = sync_dump_bitmap(last_pfn, dump_bitmap_buf, s);
+ if (ret < 0) {
+ dump_error(s, "dump: failed to sync dump_bitmap.\n");
+ ret = -1;
+ goto out;
+ }
+
+ /* number of dumpable pages that will be dumped later */
+ s->num_dumpable = num_dumpable;
+
+out:
+ g_free(dump_bitmap_buf);
+
+ return ret;
+}
+
static ram_addr_t get_start_block(DumpState *s)
{
RAMBlock *block;
diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
index 54ae4e5..e67927d 100644
--- a/include/sysemu/dump.h
+++ b/include/sysemu/dump.h
@@ -25,8 +25,13 @@
#define PHYS_BASE (0)
#define DUMP_LEVEL (1)
#define DISKDUMP_HEADER_BLOCKS (1)
+#define BUFSIZE_BITMAP (4096)
+#define PFN_BUFBITMAP (CHAR_BIT * BUFSIZE_BITMAP)
+#define ARCH_PFN_OFFSET (0)
#define divideup(x, y) (((x) + ((y) - 1)) / (y))
+#define paddr_to_pfn(X, page_shift) \
+ (((unsigned long long)(X) >> (page_shift)) - ARCH_PFN_OFFSET)
typedef struct ArchDumpInfo {
int d_machine; /* Architecture */
--
1.7.1
- [Qemu-devel] [PATCH v5 0/9] Make 'dump-guest-memory' dump in kdump-compressed format, Qiao Nuohan, 2013/07/09
- [Qemu-devel] [PATCH v5 1/9] dump: Add argument to write_elfxx_notes, Qiao Nuohan, 2013/07/09
- [Qemu-devel] [PATCH v5 2/9] dump: Add API to write header of flatten format, Qiao Nuohan, 2013/07/09
- [Qemu-devel] [PATCH v5 3/9] dump: Add API to write vmcore, Qiao Nuohan, 2013/07/09
- [Qemu-devel] [PATCH v5 7/9] dump: Add APIs to operate DataCache, Qiao Nuohan, 2013/07/09
- [Qemu-devel] [PATCH v5 4/9] dump: Add API to write elf notes to buffer, Qiao Nuohan, 2013/07/09
- [Qemu-devel] [PATCH v5 6/9] dump: Add API to write dump_bitmap,
Qiao Nuohan <=
- [Qemu-devel] [PATCH v5 9/9] dump: Make kdump-compressed format available for 'dump-guest-memory', Qiao Nuohan, 2013/07/09
- [Qemu-devel] [PATCH v5 8/9] dump: Add API to write dump pages, Qiao Nuohan, 2013/07/09
- [Qemu-devel] [PATCH v5 5/9] dump: add API to write dump header, Qiao Nuohan, 2013/07/09
- Re: [Qemu-devel] [PATCH v5 0/9] Make 'dump-guest-memory' dump in kdump-compressed format, Qiao Nuohan, 2013/07/09