From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40855) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vzj2t-0001LB-Vu for qemu-devel@nongnu.org; Sun, 05 Jan 2014 03:27:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Vzj2m-0002IX-Cl for qemu-devel@nongnu.org; Sun, 05 Jan 2014 03:26:55 -0500 Received: from fgwmail7.fujitsu.co.jp ([192.51.44.37]:38648) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vzj2l-0002II-Ov for qemu-devel@nongnu.org; Sun, 05 Jan 2014 03:26:48 -0500 Received: from fgwmail6.fujitsu.co.jp (fgwmail6.fujitsu.co.jp [192.51.44.36]) by fgwmail7.fujitsu.co.jp (Postfix) with ESMTP id DC24F1794849 for ; Sun, 5 Jan 2014 16:28:43 +0900 (JST) Received: from m3.gw.fujitsu.co.jp (unknown [10.0.50.73]) by fgwmail6.fujitsu.co.jp (Postfix) with ESMTP id 036BF3EE0D0 for ; Sun, 5 Jan 2014 16:28:43 +0900 (JST) Received: from smail (m3 [127.0.0.1]) by outgoing.m3.gw.fujitsu.co.jp (Postfix) with ESMTP id E7AD445DD77 for ; Sun, 5 Jan 2014 16:28:42 +0900 (JST) Received: from s3.gw.fujitsu.co.jp (s3.gw.nic.fujitsu.com [10.0.50.93]) by m3.gw.fujitsu.co.jp (Postfix) with ESMTP id D23CF45DEB5 for ; Sun, 5 Jan 2014 16:28:42 +0900 (JST) Received: from s3.gw.fujitsu.co.jp (localhost.localdomain [127.0.0.1]) by s3.gw.fujitsu.co.jp (Postfix) with ESMTP id C6374E08003 for ; Sun, 5 Jan 2014 16:28:42 +0900 (JST) Received: from s01.gw.fujitsu.co.jp (s01.gw.nic.fujitsu.com [133.161.11.16]) by s3.gw.fujitsu.co.jp (Postfix) with ESMTP id 7E645E08001 for ; Sun, 5 Jan 2014 16:28:42 +0900 (JST) Received: from s01.gw.fujitsu.co.jp (yt-mxio2.gw.nic.fujitsu.com [10.134.25.142]) by s01.gw.fujitsu.co.jp (Postfix) with ESMTP id 412ACD8108 for ; Sun, 5 Jan 2014 16:28:42 +0900 (JST) Received: from G08FNSTD100518.localdomain (unknown [10.167.226.68]) by s01.gw.fujitsu.co.jp (Postfix) with ESMTP id 973E38A010 for ; Sun, 5 Jan 2014 16:28:41 +0900 (JST) From: Qiao Nuohan Date: Sun, 5 Jan 2014 15:27:40 +0800 Message-Id: <1388906864-1083-8-git-send-email-qiaonuohan@cn.fujitsu.com> In-Reply-To: <1388906864-1083-1-git-send-email-qiaonuohan@cn.fujitsu.com> References: <1388906864-1083-1-git-send-email-qiaonuohan@cn.fujitsu.com> Subject: [Qemu-devel] [PATCH v6 07/11] dump: Add API to write dump_bitmap List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: stefanha@gmail.com, lcapitulino@redhat.com, afaerber@suse.de, eblake@redhat.com Cc: qemu-devel@nongnu.org, qiaonuohan@cn.fujitsu.com, kumagai-atsushi@mxc.nes.nec.co.jp, anderson@redhat.com, akong@redhat.com, lersek@redhat.com 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. 1st and 2nd dump_bitmap are same, because dump level is specified to 1 here. Signed-off-by: Qiao Nuohan --- dump.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++ include/sysemu/dump.h | 7 +++ 2 files changed, 123 insertions(+), 0 deletions(-) diff --git a/dump.c b/dump.c index e3623b9..1fae152 100644 --- a/dump.c +++ b/dump.c @@ -80,12 +80,14 @@ typedef struct DumpState { bool flag_flatten; uint32_t nr_cpus; size_t page_size; + uint32_t page_shift; uint64_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; uint32_t flag_compress; } DumpState; @@ -972,6 +974,120 @@ static int write_dump_header(DumpState *s) } } +/* set dump_bitmap sequencely. bitmap is not allowed to be rewritten. */ +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 bit needed to be set is not cached in buf, flush the data in buf + * to vmcore firstly. + * making new_offset be bigger than old_offset can also sync remained data + * into vmcore. + */ + 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 + + 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<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++; + } + } + + /* + * last_pfn > -1 means bitmap is set, then remained data in buf should be + * synchronized into vmcore + */ + if (last_pfn > -1) { + ret = set_dump_bitmap(last_pfn, last_pfn + PFN_BUFBITMAP, 0, + 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) { GuestPhysBlock *block; diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h index 9e47b4c..b5eaf8d 100644 --- a/include/sysemu/dump.h +++ b/include/sysemu/dump.h @@ -27,11 +27,18 @@ #define DUMP_DH_COMPRESSED_LZO (0x2) #define DUMP_DH_COMPRESSED_SNAPPY (0x4) +#define PAGE_SIZE (4096) #define KDUMP_SIGNATURE "KDUMP " #define SIG_LEN (sizeof(KDUMP_SIGNATURE) - 1) #define PHYS_BASE (0) #define DUMP_LEVEL (1) #define DISKDUMP_HEADER_BLOCKS (1) +#define BUFSIZE_BITMAP (PAGE_SIZE) +#define PFN_BUFBITMAP (CHAR_BIT * BUFSIZE_BITMAP) +#define ARCH_PFN_OFFSET (0) + +#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