# HG changeset patch
# User yamahata valinux.co.jp
# Date 1188381736 -32400
# Node ID 97c0b1a793162f39251183672b7b057386772aa8
# Parent a630c1ba002b8ecbafd50691c90ca96f3a45dc3e
Optimize xc_core.c implementation.
optimize out unnecessary map/unmap foreign domain page
by moving p2m/pfn talbe after pages array.
This patch doesn't change the xm dump-core format.
PATCHNAME: xc_core_c_optimize
Signed-off-by: Isaku Yamahata <yamahata valinux.co.jp>
diff -r a630c1ba002b -r 97c0b1a79316 tools/libxc/xc_core.c
--- a/tools/libxc/xc_core.c Tue Aug 28 13:11:51 2007 +0900
+++ b/tools/libxc/xc_core.c Wed Aug 29 19:02:16 2007 +0900
 -17,8
+17,8 
* | .xen_prstatus
|
* | .xen_ia64_mmapped_regs if ia64
|
* | .xen_shared_info if present
|
+ * | .xen_pages
|
* | .xen_p2m or .xen_pfn
|
- * | .xen_pages
|
*
+--------------------------------------------------------+
* |.note.Xen:note section
|
* | "Xen" is used as note name,
|
 -37,12
+37,12 
*
+--------------------------------------------------------+
* |.xen_shared_info if possible
|
*
+--------------------------------------------------------+
+ * |.xen_pages
|
+ * | page * nr_pages
|
+ *
+--------------------------------------------------------+
* |.xen_p2m or .xen_pfn
|
* | .xen_p2m: struct xen_dumpcore_p2m[nr_pages]
|
* | .xen_pfn: uint64_t[nr_pages]
|
- *
+--------------------------------------------------------+
- * |.xen_pages
|
- * | page * nr_pages
|
*
+--------------------------------------------------------+
* |.shstrtab: section header string table
|
*
+--------------------------------------------------------+
 -57,21
+57,6 
/* number of pages to write at a time */
#define DUMP_INCREMENT (4 * 1024)
-
-static int
-copy_from_domain_page(int xc_handle,
- uint32_t domid,
- unsigned long mfn,
- void *dst_page)
-{
- void *vaddr = xc_map_foreign_range(
- xc_handle, domid, PAGE_SIZE, PROT_READ, mfn);
- if ( vaddr == NULL )
- return -1;
- memcpy(dst_page, vaddr, PAGE_SIZE);
- munmap(vaddr, PAGE_SIZE);
- return 0;
-}
/* string table */
struct xc_core_strtab {
 -520,47
+505,6  xc_domain_dumpcore_via_callback(int xc_h
}
}
- /* create .xen_p2m or .xen_pfn */
- j = 0;
- for ( map_idx = 0; map_idx < nr_memory_map;
map_idx++ )
- {
- uint64_t pfn_start;
- uint64_t pfn_end;
-
- pfn_start = memory_map[map_idx].addr >>
PAGE_SHIFT;
- pfn_end = pfn_start + (memory_map[map_idx].size
>> PAGE_SHIFT);
- for ( i = pfn_start; i < pfn_end; i++ )
- {
- if ( !auto_translated_physmap )
- {
- if ( p2m[i] == INVALID_P2M_ENTRY )
- continue;
- p2m_array[j].pfn = i;
- p2m_array[j].gmfn = p2m[i];
- }
- else
- {
- /* try to map page to determin wheter it
has underlying page */
- void *vaddr =
xc_map_foreign_range(xc_handle, domid,
-
PAGE_SIZE, PROT_READ, i);
- if ( vaddr == NULL )
- continue;
- munmap(vaddr, PAGE_SIZE);
- pfn_array[j] = i;
- }
-
- j++;
- }
- }
- if ( j != nr_pages )
- {
- PERROR("j (%ld) != nr_pages (%ld)", j ,
nr_pages);
- /* When live dump-mode (-L option) is specified,
- * guest domain may change its mapping.
- */
- nr_pages = j;
- }
-
/* ehdr.e_shnum and ehdr.e_shstrndx aren't known here
yet. fill it later*/
xc_core_ehdr_init(&ehdr);
 -660,48
+604,12  xc_domain_dumpcore_via_callback(int xc_h
offset += filesz;
}
- /* p2m/pfn table */
- shdr = xc_core_shdr_get(sheaders);
- if ( shdr == NULL )
- {
- PERROR("Could not get section header for
.xen_{p2m, pfn} table");
- goto out;
- }
- if ( !auto_translated_physmap )
- {
- filesz = nr_pages * sizeof(p2m_array[0]);
- sts = xc_core_shdr_set(shdr, strtab,
XEN_DUMPCORE_SEC_P2M,
- SHT_PROGBITS,
- offset, filesz,
__alignof__(p2m_array[0]),
- sizeof(p2m_array[0]));
- if ( sts != 0 )
- goto out;
- }
- else
- {
- filesz = nr_pages * sizeof(pfn_array[0]);
- sts = xc_core_shdr_set(shdr, strtab,
XEN_DUMPCORE_SEC_PFN,
- SHT_PROGBITS,
- offset, filesz,
__alignof__(pfn_array[0]),
- sizeof(pfn_array[0]));
- if ( sts != 0 )
- goto out;
- }
- offset += filesz;
-
- /* pages */
- shdr = xc_core_shdr_get(sheaders);
- if ( shdr == NULL )
- {
- PERROR("could not get section headers for
.xen_pages");
- goto out;
- }
-
/*
- * pages are the last section to allocate section
headers
+ * pages and p2m/pfn are the last section to allocate
section headers
* so that we know the number of section headers here.
+ * 2 = pages section and p2m/pfn table section
*/
- fixup = sheaders->num * sizeof(*shdr);
+ fixup = (sheaders->num + 2) * sizeof(*shdr);
/* zeroth section should have zero offset */
for ( i = 1; i < sheaders->num; i++ )
sheaders->shdrs[i].sh_offset += fixup;
 -709,9
+617,43  xc_domain_dumpcore_via_callback(int xc_h
dummy_len = ROUNDUP(offset, PAGE_SHIFT) - offset; /*
padding length */
offset += dummy_len;
+ /* pages */
+ shdr = xc_core_shdr_get(sheaders);
+ if ( shdr == NULL )
+ {
+ PERROR("could not get section headers for
.xen_pages");
+ goto out;
+ }
filesz = nr_pages * PAGE_SIZE;
sts = xc_core_shdr_set(shdr, strtab,
XEN_DUMPCORE_SEC_PAGES, SHT_PROGBITS,
offset, filesz, PAGE_SIZE,
PAGE_SIZE);
+ if ( sts != 0 )
+ goto out;
+ offset += filesz;
+
+ /* p2m/pfn table */
+ shdr = xc_core_shdr_get(sheaders);
+ if ( shdr == NULL )
+ {
+ PERROR("Could not get section header for
.xen_{p2m, pfn} table");
+ goto out;
+ }
+ if ( !auto_translated_physmap )
+ {
+ filesz = nr_pages * sizeof(p2m_array[0]);
+ sts = xc_core_shdr_set(shdr, strtab,
XEN_DUMPCORE_SEC_P2M,
+ SHT_PROGBITS,
+ offset, filesz,
__alignof__(p2m_array[0]),
+ sizeof(p2m_array[0]));
+ }
+ else
+ {
+ filesz = nr_pages * sizeof(pfn_array[0]);
+ sts = xc_core_shdr_set(shdr, strtab,
XEN_DUMPCORE_SEC_PFN,
+ SHT_PROGBITS,
+ offset, filesz,
__alignof__(pfn_array[0]),
+ sizeof(pfn_array[0]));
+ }
if ( sts != 0 )
goto out;
offset += filesz;
 -736,7
+678,7  xc_domain_dumpcore_via_callback(int xc_h
/* elf note section: xen core header */
sts = elfnote_dump_none(args, dump_rtn);
- if ( sts != 0)
+ if ( sts != 0 )
goto out;
/* elf note section: xen core header */
 -772,16
+714,6  xc_domain_dumpcore_via_callback(int xc_h
if ( sts != 0 )
goto out;
- /* p2m/pfn table: .xen_p2m/.xen_pfn */
- if ( !auto_translated_physmap )
- sts = dump_rtn(args, (char *)p2m_array,
- sizeof(p2m_array[0]) * nr_pages);
- else
- sts = dump_rtn(args, (char *)pfn_array,
- sizeof(pfn_array[0]) * nr_pages);
- if ( sts != 0 )
- goto out;
-
/* Pad the output data to page alignment. */
memset(dummy, 0, PAGE_SIZE);
sts = dump_rtn(args, dummy, dummy_len);
 -789,24
+721,99  xc_domain_dumpcore_via_callback(int xc_h
goto out;
/* dump pages: .xen_pages */
- for ( dump_mem = dump_mem_start, i = 0; i <
nr_pages; i++ )
- {
- uint64_t gmfn;
- if ( !auto_translated_physmap )
- gmfn = p2m_array[i].gmfn;
- else
- gmfn = pfn_array[i];
-
- copy_from_domain_page(xc_handle, domid, gmfn,
dump_mem);
- dump_mem += PAGE_SIZE;
- if ( ((i + 1) % DUMP_INCREMENT == 0) || ((i + 1) ==
nr_pages) )
+ j = 0;
+ dump_mem = dump_mem_start;
+ for ( map_idx = 0; map_idx < nr_memory_map;
map_idx++ )
+ {
+ uint64_t pfn_start;
+ uint64_t pfn_end;
+
+ pfn_start = memory_map[map_idx].addr >>
PAGE_SHIFT;
+ pfn_end = pfn_start + (memory_map[map_idx].size
>> PAGE_SHIFT);
+ for ( i = pfn_start; i < pfn_end; i++ )
{
- sts = dump_rtn(args, dump_mem_start, dump_mem -
dump_mem_start);
+ uint64_t gmfn;
+ void *vaddr;
+
+ if ( j >= nr_pages )
+ {
+ /*
+ * When live dump-mode (-L option) is
specified,
+ * guest domain may increase memory.
+ */
+ IPRINTF("exceeded nr_pages (%ld)
losing pages", nr_pages);
+ goto copy_done;
+ }
+
+ if ( !auto_translated_physmap )
+ {
+ gmfn = p2m[i];
+ if ( gmfn == INVALID_P2M_ENTRY )
+ continue;
+
+ p2m_array[j].pfn = i;
+ p2m_array[j].gmfn = gmfn;
+ }
+ else
+ {
+ gmfn = i;
+ pfn_array[j] = i;
+ }
+
+ vaddr = xc_map_foreign_range(
+ xc_handle, domid, PAGE_SIZE, PROT_READ,
gmfn);
+ if ( vaddr == NULL )
+ continue;
+ memcpy(dump_mem, vaddr, PAGE_SIZE);
+ munmap(vaddr, PAGE_SIZE);
+ dump_mem += PAGE_SIZE;
+ if ( (j + 1) % DUMP_INCREMENT == 0 )
+ {
+ sts = dump_rtn(
+ args, dump_mem_start, dump_mem -
dump_mem_start);
+ if ( sts != 0 )
+ goto out;
+ dump_mem = dump_mem_start;
+ }
+
+ j++;
+ }
+ }
+
+copy_done:
+ sts = dump_rtn(args, dump_mem_start, dump_mem -
dump_mem_start);
+ if ( sts != 0 )
+ goto out;
+ if ( j < nr_pages )
+ {
+ /* When live dump-mode (-L option) is specified,
+ * guest domain may reduce memory. pad with zero
pages.
+ */
+ IPRINTF("j (%ld) != nr_pages (%ld)", j ,
nr_pages);
+ memset(dump_mem_start, 0, PAGE_SIZE);
+ for (; j < nr_pages; j++) {
+ sts = dump_rtn(args, dump_mem_start,
PAGE_SIZE);
if ( sts != 0 )
goto out;
- dump_mem = dump_mem_start;
- }
- }
+ if ( !auto_translated_physmap )
+ {
+ p2m_array[j].pfn = XC_CORE_INVALID_PFN;
+ p2m_array[j].gmfn = XC_CORE_INVALID_GMFN;
+ }
+ else
+ pfn_array[j] = XC_CORE_INVALID_PFN;
+ }
+ }
+
+ /* p2m/pfn table: .xen_p2m/.xen_pfn */
+ if ( !auto_translated_physmap )
+ sts = dump_rtn(
+ args, (char *)p2m_array, sizeof(p2m_array[0]) *
nr_pages);
+ else
+ sts = dump_rtn(
+ args, (char *)pfn_array, sizeof(pfn_array[0]) *
nr_pages);
+ if ( sts != 0 )
+ goto out;
/* elf section header string table: .shstrtab */
sts = dump_rtn(args, strtab->strings,
strtab->current);
 -816,6
+823,8  xc_domain_dumpcore_via_callback(int xc_h
sts = 0;
out:
+ if ( memory_map != NULL )
+ free(memory_map);
if ( p2m != NULL )
munmap(p2m, PAGE_SIZE * P2M_FL_ENTRIES);
if ( p2m_array != NULL )
diff -r a630c1ba002b -r 97c0b1a79316 tools/libxc/xc_core.h
--- a/tools/libxc/xc_core.h Tue Aug 28 13:11:51 2007 +0900
+++ b/tools/libxc/xc_core.h Wed Aug 29 19:02:16 2007 +0900
 -107,6
+107,8  struct xen_dumpcore_elfnote_format_versi
struct xen_dumpcore_elfnote_format_version_desc
format_version;
};
+#define XC_CORE_INVALID_PFN (~(uint64_t)0)
+#define XC_CORE_INVALID_GMFN (~(uint64_t)0)
struct xen_dumpcore_p2m {
uint64_t pfn;
uint64_t gmfn;
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel lists.xensource.com
http://list
s.xensource.com/xen-ia64-devel
|