[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 2/5] xc_core: Optimize xc_core.c



# HG changeset patch
# User yamahata@xxxxxxxxxxxxx
# 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@xxxxxxxxxxxxx>

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;

Attachment: 15764_97c0b1a79316_xc_core_c_optimize.patch
Description: Text Data

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.