List Info

Thread: xc_core: Optimize xc_core.c




xc_core: Optimize xc_core.c
user name
2007-08-29 06:28:51
# HG changeset patch
# User yamahatavalinux.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 <yamahatavalinux.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-devellists.xensource.com
http://list
s.xensource.com/xen-ia64-devel
  
[1]

about | contact  Other archives ( Real Estate discussion Medical topics )