ia64/xen-unstable

changeset 1602:4d2fe50e4fc8

bitkeeper revision 1.1023.1.2 (40e03fb3Kn9LqtnC7_hTzWLj-CbQDg)

Merge.
author mjw@wray-m-3.hpl.hp.com
date Mon Jun 28 15:56:35 2004 +0000 (2004-06-28)
parents c5d25124f417
children 6ad69c5289fb
files tools/xc/lib/xc_linux_save.c
line diff
     1.1 --- a/tools/xc/lib/xc_linux_save.c	Mon Jun 28 15:54:03 2004 +0000
     1.2 +++ b/tools/xc/lib/xc_linux_save.c	Mon Jun 28 15:56:35 2004 +0000
     1.3 @@ -32,33 +32,30 @@
     1.4   * in the guest's pseudophysical map.
     1.5   * 0x80000000-3 mark the shared_info, and blk/net rings
     1.6   */
     1.7 -#define MFN_IS_IN_PSEUDOPHYS_MAP(_mfn) \
     1.8 -    (((_mfn) < (1024*1024)) && \
     1.9 -     ( ( (live_mfn_to_pfn_table[_mfn] < nr_pfns) && \
    1.10 -       (live_pfn_to_mfn_table[live_mfn_to_pfn_table[_mfn]] == (_mfn)) ) || \
    1.11 -\
    1.12 -       (live_mfn_to_pfn_table[_mfn] >= 0x80000000 && \
    1.13 - live_mfn_to_pfn_table[_mfn] <= 0x80000003 ) || \
    1.14 - live_pfn_to_mfn_table[live_mfn_to_pfn_table[_mfn]] == 0x80000004 )  )
    1.15 +#define MFN_IS_IN_PSEUDOPHYS_MAP(_mfn)                                    \
    1.16 +    (((_mfn) < (1024*1024)) &&                                            \
    1.17 +     (((live_mfn_to_pfn_table[_mfn] < nr_pfns) &&                         \
    1.18 +       (live_pfn_to_mfn_table[live_mfn_to_pfn_table[_mfn]] == (_mfn))) || \
    1.19 +      ((live_mfn_to_pfn_table[_mfn] >= 0x80000000) &&                     \
    1.20 +       (live_mfn_to_pfn_table[_mfn] <= 0x80000003)) ||                    \
    1.21 +      (live_pfn_to_mfn_table[live_mfn_to_pfn_table[_mfn]] == 0x80000004)))
    1.22       
    1.23  /* Returns TRUE if MFN is successfully converted to a PFN. */
    1.24 -#define translate_mfn_to_pfn(_pmfn)         \
    1.25 -({                                          \
    1.26 -    unsigned long mfn = *(_pmfn);           \
    1.27 -    int _res = 1;                           \
    1.28 -    if ( !MFN_IS_IN_PSEUDOPHYS_MAP(mfn) )   \
    1.29 -        _res = 0;                           \
    1.30 -    else                                    \
    1.31 -        *(_pmfn) = live_mfn_to_pfn_table[mfn];   \
    1.32 -    _res;                                   \
    1.33 +#define translate_mfn_to_pfn(_pmfn)            \
    1.34 +({                                             \
    1.35 +    unsigned long mfn = *(_pmfn);              \
    1.36 +    int _res = 1;                              \
    1.37 +    if ( !MFN_IS_IN_PSEUDOPHYS_MAP(mfn) )      \
    1.38 +        _res = 0;                              \
    1.39 +    else                                       \
    1.40 +        *(_pmfn) = live_mfn_to_pfn_table[mfn]; \
    1.41 +    _res;                                      \
    1.42  })
    1.43  
    1.44 -
    1.45 -/* test_bit */
    1.46  static inline int test_bit ( int nr, volatile void * addr)
    1.47  {
    1.48 -    return ( ((unsigned long*)addr)[nr/(sizeof(unsigned long)*8)] >> 
    1.49 -             (nr % (sizeof(unsigned long)*8) ) ) & 1;
    1.50 +    return (((unsigned long*)addr)[nr/(sizeof(unsigned long)*8)] >> 
    1.51 +            (nr % (sizeof(unsigned long)*8))) & 1;
    1.52  }
    1.53  
    1.54  static inline void clear_bit ( int nr, volatile void * addr)
    1.55 @@ -72,11 +69,8 @@ static inline void set_bit ( int nr, vol
    1.56      ((unsigned long*)addr)[nr/(sizeof(unsigned long)*8)] |= 
    1.57          (1 << (nr % (sizeof(unsigned long)*8) ) );
    1.58  }
    1.59 -/*
    1.60 - * hweightN: returns the hamming weight (i.e. the number
    1.61 - * of bits set) of a N-bit word
    1.62 - */
    1.63  
    1.64 +/* Returns the hamming weight (i.e. the number of bits set) in a N-bit word */
    1.65  static inline unsigned int hweight32(unsigned int w)
    1.66  {
    1.67      unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
    1.68 @@ -90,7 +84,7 @@ static inline int count_bits ( int nr, v
    1.69  {
    1.70      int i, count = 0;
    1.71      unsigned long *p = (unsigned long *)addr;
    1.72 -    /* we know the array is padded to unsigned long */
    1.73 +    /* We know that the array is padded to unsigned long. */
    1.74      for(i=0;i<nr/(sizeof(unsigned long)*8);i++,p++)
    1.75          count += hweight32( *p );
    1.76      return count;
    1.77 @@ -120,11 +114,7 @@ static inline int permute( int i, int nr
    1.78        LKJIHGF
    1.79        */
    1.80  
    1.81 -    do
    1.82 -    {
    1.83 -        i = ( ( i>>(order_nr-10))  | ( i<<10 ) ) &
    1.84 -            ((1<<order_nr)-1);
    1.85 -    }
    1.86 +    do { i = ((i>>(order_nr-10)) | ( i<<10 ) ) & ((1<<order_nr)-1); }
    1.87      while ( i >= nr ); /* this won't ever loop if nr is a power of 2 */
    1.88  
    1.89      return i;
    1.90 @@ -135,14 +125,22 @@ static long long tv_to_us( struct timeva
    1.91      return (new->tv_sec * 1000000) + new->tv_usec;
    1.92  }
    1.93  
    1.94 -static long long tvdelta( struct timeval *new, struct timeval *old )
    1.95 +static long long llgettimeofday()
    1.96 +{
    1.97 +    struct timeval now;
    1.98 +    gettimeofday(&now, NULL);
    1.99 +    return tv_to_us(&now);
   1.100 +}
   1.101 +
   1.102 +static long long tv_delta( struct timeval *new, struct timeval *old )
   1.103  {
   1.104      return ((new->tv_sec - old->tv_sec)*1000000 ) + 
   1.105          (new->tv_usec - old->tv_usec);
   1.106  }
   1.107  
   1.108 -static int track_cpu_usage( int xc_handle, u32 domid, int faults,
   1.109 -                            int pages_sent, int pages_dirtied, int print )
   1.110 +static int print_stats( int xc_handle, u32 domid, 
   1.111 +                        int pages_sent, xc_shadow_control_stats_t *stats,
   1.112 +                        int print )
   1.113  {
   1.114      static struct timeval wall_last;
   1.115      static long long      d0_cpu_last;
   1.116 @@ -153,33 +151,29 @@ static int track_cpu_usage( int xc_handl
   1.117      long long             d0_cpu_now, d0_cpu_delta;
   1.118      long long             d1_cpu_now, d1_cpu_delta;
   1.119  
   1.120 -
   1.121      gettimeofday(&wall_now, NULL);
   1.122  
   1.123      d0_cpu_now = xc_domain_get_cpu_usage( xc_handle, 0 )/1000;
   1.124      d1_cpu_now = xc_domain_get_cpu_usage( xc_handle, domid )/1000;
   1.125  
   1.126 -    if ( d0_cpu_now == -1 || d1_cpu_now == -1 ) 
   1.127 -    {
   1.128 +    if ( (d0_cpu_now == -1) || (d1_cpu_now == -1) ) 
   1.129          printf("ARRHHH!!\n");
   1.130 -    }
   1.131  
   1.132 -    wall_delta = tvdelta(&wall_now,&wall_last)/1000;
   1.133 +    wall_delta = tv_delta(&wall_now,&wall_last)/1000;
   1.134  
   1.135      if ( wall_delta == 0 ) wall_delta = 1;
   1.136  
   1.137      d0_cpu_delta  = (d0_cpu_now - d0_cpu_last)/1000;
   1.138      d1_cpu_delta  = (d1_cpu_now - d1_cpu_last)/1000;
   1.139  
   1.140 -    if(print)
   1.141 -        printf("delta %lldms, dom0 %d%%, target %d%%, "
   1.142 -               "sent %dMb/s, dirtied %dMb/s\n",
   1.143 +    if ( print )
   1.144 +        printf("delta %lldms, dom0 %d%%, target %d%%, sent %dMb/s, "
   1.145 +               "dirtied %dMb/s\n",
   1.146                 wall_delta, 
   1.147                 (int)((d0_cpu_delta*100)/wall_delta),
   1.148                 (int)((d1_cpu_delta*100)/wall_delta),
   1.149                 (int)((pages_sent*PAGE_SIZE*8)/(wall_delta*1000)),
   1.150 -               (int)((pages_dirtied*PAGE_SIZE*8)/(wall_delta*1000))
   1.151 -            );
   1.152 +               (int)((stats->dirty_count*PAGE_SIZE*8)/(wall_delta*1000)));
   1.153  
   1.154      d0_cpu_last  = d0_cpu_now;
   1.155      d1_cpu_last  = d1_cpu_now;
   1.156 @@ -203,6 +197,41 @@ static int write_vmconfig(XcIOContext *i
   1.157      return err;
   1.158  }
   1.159  
   1.160 +static int analysis_phase( int xc_handle, u32 domid, 
   1.161 +                           int nr_pfns, unsigned long *arr )
   1.162 +{
   1.163 +    long long start, now;
   1.164 +    xc_shadow_control_stats_t stats;
   1.165 +
   1.166 +    start = llgettimeofday();
   1.167 +
   1.168 +    while ( 0 )
   1.169 +    {
   1.170 +        int i;
   1.171 +
   1.172 +        xc_shadow_control( xc_handle, domid, 
   1.173 +                           DOM0_SHADOW_CONTROL_OP_CLEAN2,
   1.174 +                           arr, nr_pfns, NULL);
   1.175 +        printf("#Flush\n");
   1.176 +        for ( i = 0; i < 100; i++ )
   1.177 +        {     
   1.178 +            usleep(10000);     
   1.179 +            now = llgettimeofday();
   1.180 +            xc_shadow_control( xc_handle, domid, 
   1.181 +                               DOM0_SHADOW_CONTROL_OP_PEEK,
   1.182 +                               NULL, 0, &stats);
   1.183 +
   1.184 +            printf("now= %lld faults= %ld dirty= %ld dirty_net= %ld "
   1.185 +                   "dirty_block= %ld\n", 
   1.186 +                   ((now-start)+500)/1000, 
   1.187 +                   stats.fault_count, stats.dirty_count,
   1.188 +                   stats.dirty_net_count, stats.dirty_block_count);
   1.189 +        }
   1.190 +    }
   1.191 +
   1.192 +    return -1;
   1.193 +}
   1.194 +
   1.195  int xc_linux_save(int xc_handle, XcIOContext *ioctxt)
   1.196  {
   1.197      dom0_op_t op;
   1.198 @@ -212,7 +241,6 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.199      int live = (ioctxt->flags & XCFLAGS_LIVE);
   1.200      int debug = (ioctxt->flags & XCFLAGS_DEBUG);
   1.201      int sent_last_iter, skip_this_iter;
   1.202 -    unsigned long dirtied_this_iter, faults_this_iter;
   1.203  
   1.204      /* Important tuning parameters */
   1.205      int max_iters  = 29; /* limit us to 30 times round loop */
   1.206 @@ -263,6 +291,8 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.207         - to skip this iteration because already dirty;
   1.208         - to fixup by sending at the end if not already resent; */
   1.209      unsigned long *to_send, *to_skip, *to_fix;
   1.210 +    
   1.211 +    xc_shadow_control_stats_t stats;
   1.212  
   1.213      int needed_to_fix = 0;
   1.214      int total_sent    = 0;
   1.215 @@ -278,6 +308,11 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.216          goto out;
   1.217      }
   1.218  
   1.219 +    if ( xc_domain_getfullinfo( xc_handle, domid, &op, &ctxt) )
   1.220 +    {
   1.221 +        PERROR("Could not get full domain info");
   1.222 +        goto out;
   1.223 +    }
   1.224      memcpy(name, op.u.getdomaininfo.name, sizeof(name));
   1.225      shared_info_frame = op.u.getdomaininfo.shared_info_frame;
   1.226  
   1.227 @@ -329,7 +364,7 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.228              pgd[HYPERVISOR_VIRT_START>>L2_PAGETABLE_SHIFT]>>PAGE_SHIFT;
   1.229  
   1.230          live_mfn_to_pfn_table = 
   1.231 -            mfn_mapper_map_single(xc_handle, DOMID_SELF, 
   1.232 +            mfn_mapper_map_single(xc_handle, ~0UL, 
   1.233                                    PAGE_SIZE*1024, PROT_READ, 
   1.234                                    mfn_to_pfn_table_start_mfn );
   1.235      }
   1.236 @@ -364,7 +399,7 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.237      if( live ){ 
   1.238          if ( xc_shadow_control( xc_handle, domid, 
   1.239                                  DOM0_SHADOW_CONTROL_OP_ENABLE_LOGDIRTY,
   1.240 -                                NULL, 0, NULL, NULL ) < 0 ){
   1.241 +                                NULL, 0, NULL ) < 0 )
   1.242              xcio_error(ioctxt, "Couldn't enable shadow mode");
   1.243              goto out;
   1.244          }
   1.245 @@ -375,11 +410,14 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.246          }
   1.247  
   1.248          last_iter = 0;
   1.249 -        sent_last_iter = 1<<20; /* 4GB's worth of pages */
   1.250 +        sent_last_iter = 1<<20; /* 4GB of pages */
   1.251      } else{
   1.252          last_iter = 1;
   1.253      }
   1.254  
   1.255 +    /* calculate the power of 2 order of nr_pfns, e.g.
   1.256 +       15->4 16->4 17->5 */
   1.257 +    for( i=nr_pfns-1, order_nr=0; i ; i>>=1, order_nr++ );
   1.258  
   1.259      /* Setup to_send bitmap */
   1.260      {
   1.261 @@ -410,11 +448,7 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.262  
   1.263      }
   1.264  
   1.265 -    /* calculate the power of 2 order of nr_pfns, e.g.
   1.266 -       15->4 16->4 17->5 */
   1.267 -    for( i=nr_pfns-1, order_nr=0; i ; i>>=1, order_nr++ );
   1.268 -
   1.269 -    printf("nr_pfns=%lu order_nr=%d\n",nr_pfns, order_nr);
   1.270 +    analysis_phase( xc_handle, domid, nr_pfns, to_skip );
   1.271  
   1.272      /* We want zeroed memory so use calloc rather than malloc. */
   1.273      pfn_type = calloc(BATCH_SIZE, sizeof(unsigned long));
   1.274 @@ -468,7 +502,7 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.275          goto out;
   1.276      }
   1.277  
   1.278 -    track_cpu_usage(xc_handle, domid, 0, 0, 0, 0 );
   1.279 +    print_stats( xc_handle, domid, 0, &stats, 0 );
   1.280  
   1.281      /* Now write out each data page, canonicalising page tables as we go... */
   1.282      
   1.283 @@ -497,7 +531,7 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.284              if ( !last_iter && 
   1.285                   xc_shadow_control(xc_handle, domid, 
   1.286                                     DOM0_SHADOW_CONTROL_OP_PEEK,
   1.287 -                                   to_skip, nr_pfns, NULL, NULL) != nr_pfns ){
   1.288 +                                   to_skip, nr_pfns, NULL) != nr_pfns ) {
   1.289                  xcio_error(ioctxt, "Error peeking shadow bitmap");
   1.290                  goto out;
   1.291              }
   1.292 @@ -506,24 +540,27 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.293              /* load pfn_type[] with the mfn of all the pages we're doing in
   1.294                 this batch. */
   1.295  
   1.296 -            for( batch = 0; batch < BATCH_SIZE && N < nr_pfns ; N++ ){
   1.297 +            for ( batch = 0; batch < BATCH_SIZE && N < nr_pfns ; N++ )
   1.298 +            {
   1.299                  int n = permute(N, nr_pfns, order_nr );
   1.300  
   1.301 -                if(0 && debug)
   1.302 -                    fprintf(stderr,"%d pfn= %08lx mfn= %08lx %d   "
   1.303 -                            "[mfn]= %08lx\n",
   1.304 -                            iter, (unsigned long)n, live_pfn_to_mfn_table[n],
   1.305 +                if ( 0 && debug )
   1.306 +                    fprintf(stderr,"%d pfn= %08lx mfn= %08lx %d  "
   1.307 +                            " [mfn]= %08lx\n",
   1.308 +                            iter, n, live_pfn_to_mfn_table[n],
   1.309                              test_bit(n,to_send),
   1.310 -                            live_mfn_to_pfn_table[
   1.311 -                                live_pfn_to_mfn_table[n]&0xFFFFF]);
   1.312 +                            live_mfn_to_pfn_table[live_pfn_to_mfn_table[n]&
   1.313 +                                                 0xFFFFF]);
   1.314  
   1.315 -                if (!last_iter && test_bit(n, to_send) && test_bit(n, to_skip)){
   1.316 +                if ( !last_iter && 
   1.317 +                     test_bit(n, to_send) && 
   1.318 +                     test_bit(n, to_skip) )
   1.319                      skip_this_iter++; /* stats keeping */
   1.320                  }
   1.321  
   1.322 -                if (! ( (test_bit(n, to_send) && !test_bit(n, to_skip)) ||
   1.323 -                        (test_bit(n, to_send) && last_iter) ||
   1.324 -                        (test_bit(n, to_fix)  && last_iter) )   ){
   1.325 +                if ( !((test_bit(n, to_send) && !test_bit(n, to_skip)) ||
   1.326 +                       (test_bit(n, to_send) && last_iter) ||
   1.327 +                       (test_bit(n, to_fix)  && last_iter)) )
   1.328                      continue;
   1.329                  }
   1.330  
   1.331 @@ -543,29 +580,29 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.332  
   1.333                      set_bit( n, to_fix );
   1.334                      if( iter>1 )
   1.335 -                        DDPRINTF("Urk! netbuf race: iter %d, pfn %lx."
   1.336 -                                 " mfn %lx\n",
   1.337 +                        DDPRINTF("netbuf race: iter %d, pfn %lx. mfn %lx\n",
   1.338                                   iter,n,pfn_type[batch]);
   1.339                      continue;
   1.340                  }
   1.341  
   1.342 -                if ( last_iter && test_bit(n, to_fix) && 
   1.343 -                     !test_bit(n, to_send) ){
   1.344 +                if ( last_iter && 
   1.345 +                     test_bit(n, to_fix) && 
   1.346 +                     !test_bit(n, to_send) )
   1.347 +                {
   1.348                      needed_to_fix++;
   1.349                      DPRINTF("Fix! iter %d, pfn %lx. mfn %lx\n",
   1.350                              iter,n,pfn_type[batch]);
   1.351                  }
   1.352  
   1.353 -                clear_bit( n, to_fix ); 
   1.354 +                clear_bit(n, to_fix); 
   1.355  
   1.356                  batch++;
   1.357              }
   1.358       
   1.359 -            DDPRINTF("batch %d:%d (n=%d)\n",iter,batch,n);
   1.360 +            DDPRINTF("batch %d:%d (n=%d)\n", iter, batch, n);
   1.361  
   1.362 -            if ( batch == 0 ){
   1.363 -                goto skip; /* very unlikely */
   1.364 -            }
   1.365 +            if ( batch == 0 )
   1.366 +                goto skip; /* vanishingly unlikely... */
   1.367        
   1.368              if ( (region_base = mfn_mapper_map_batch(xc_handle, domid, 
   1.369                                                       PROT_READ,
   1.370 @@ -586,23 +623,19 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.371                      continue;
   1.372                  }
   1.373    
   1.374 -                if ( 0 && debug ){
   1.375 -                    fprintf(stderr,"%d pfn= %08lx mfn= %08lx "
   1.376 -                            "[mfn]= %08lx sum= %08lx\n",
   1.377 +                if ( 0 && debug )
   1.378 +                    fprintf(stderr, "%d pfn= %08lx mfn= %08lx [mfn]= %08lx"
   1.379 +                            " sum= %08lx\n",
   1.380                              iter, 
   1.381                              (pfn_type[j] & LTAB_MASK) | pfn_batch[j],
   1.382                              pfn_type[j],
   1.383                              live_mfn_to_pfn_table[pfn_type[j]&(~LTAB_MASK)],
   1.384 -                            csum_page(region_base + (PAGE_SIZE*j))
   1.385 -                        );
   1.386 -                }
   1.387 +                            csum_page(region_base + (PAGE_SIZE*j)));
   1.388  
   1.389                  /* canonicalise mfn->pfn */
   1.390 -                pfn_type[j] = (pfn_type[j] & LTAB_MASK) |
   1.391 -                    pfn_batch[j];
   1.392 +                pfn_type[j] = (pfn_type[j] & LTAB_MASK) | pfn_batch[j];
   1.393              }
   1.394  
   1.395 -     
   1.396              if ( xcio_write(ioctxt, &batch, sizeof(int) ) ){
   1.397                  xcio_error(ioctxt, "Error when writing to state file (2)");
   1.398                  goto out;
   1.399 @@ -616,7 +649,6 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.400              /* entering this loop, pfn_type is now in pfns (Not mfns) */
   1.401              for( j = 0; j < batch; j++ ){
   1.402                  /* write out pages in batch */
   1.403 -  
   1.404                  if( (pfn_type[j] & LTAB_MASK) == XTAB){
   1.405                      DDPRINTF("SKIP BOGUS page %i mfn %08lx\n",j,pfn_type[j]);
   1.406                      continue;
   1.407 @@ -624,17 +656,18 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.408    
   1.409                  if ( ((pfn_type[j] & LTAB_MASK) == L1TAB) || 
   1.410                       ((pfn_type[j] & LTAB_MASK) == L2TAB) ){
   1.411 -      
   1.412                      memcpy(page, region_base + (PAGE_SIZE*j), PAGE_SIZE);
   1.413        
   1.414                      for ( k = 0; 
   1.415                            k < (((pfn_type[j] & LTAB_MASK) == L2TAB) ? 
   1.416 -                               (HYPERVISOR_VIRT_START >> L2_PAGETABLE_SHIFT) : 
   1.417 +                               (HYPERVISOR_VIRT_START >> L2_PAGETABLE_SHIFT) :
   1.418                                 1024); 
   1.419                            k++ ){
   1.420                          unsigned long pfn;
   1.421  
   1.422 -                        if ( !(page[k] & _PAGE_PRESENT) ) continue;
   1.423 +                        if ( !(page[k] & _PAGE_PRESENT) )
   1.424 +                            continue;
   1.425 +                        
   1.426                          mfn = page[k] >> PAGE_SHIFT;      
   1.427                          pfn = live_mfn_to_pfn_table[mfn];
   1.428  
   1.429 @@ -647,11 +680,22 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.430                                     page[k], mfn, live_mfn_to_pfn_table[mfn],
   1.431                                     (live_mfn_to_pfn_table[mfn]<nr_pfns)? 
   1.432                                     live_pfn_to_mfn_table[
   1.433 -                                       live_mfn_to_pfn_table[mfn]]:0xdeadbeef);
   1.434 -                            pfn = 0; /* be suspicious, very suspicious */
   1.435 +                                       live_mfn_to_pfn_table[mfn]] : 
   1.436 +                                   0xdeadbeef);
   1.437 +
   1.438 +                            pfn = 0; /* be suspicious */
   1.439                          }
   1.440 +
   1.441                          page[k] &= PAGE_SIZE - 1;
   1.442                          page[k] |= pfn << PAGE_SHIFT;
   1.443 +   
   1.444 +#if 0
   1.445 +                        printf("L%d i=%d pfn=%d mfn=%d k=%d pte=%08lx "
   1.446 +                               "xpfn=%d\n",
   1.447 +                               pfn_type[j]>>28,
   1.448 +                               j,i,mfn,k,page[k],page[k]>>PAGE_SHIFT);
   1.449 +#endif     
   1.450 +   
   1.451                      } /* end of page table rewrite for loop */
   1.452        
   1.453                      if ( xcio_write(ioctxt, page, PAGE_SIZE) ){
   1.454 @@ -682,8 +726,9 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.455          xcio_info(ioctxt, "\r %d: sent %d, skipped %d, ", 
   1.456                         iter, sent_this_iter, skip_this_iter );
   1.457  
   1.458 -        if ( last_iter ){
   1.459 -            track_cpu_usage( xc_handle, domid, 0, sent_this_iter, 0, 1);
   1.460 +        if ( last_iter ) {
   1.461 +            print_stats( xc_handle, domid, sent_this_iter, &stats, 1);
   1.462 +
   1.463              xcio_info(ioctxt, "Total pages sent= %d (%.2fx)\n", 
   1.464                             total_sent, ((float)total_sent)/nr_pfns );
   1.465              xcio_info(ioctxt, "(of which %d were fixups)\n", needed_to_fix  );
   1.466 @@ -691,7 +736,7 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.467  
   1.468          if (last_iter && debug){
   1.469              int minusone = -1;
   1.470 -            memset( to_send, 0xff, nr_pfns/8 );
   1.471 +            memset( to_send, 0xff, (nr_pfns+8)/8 );
   1.472              debug = 0;
   1.473              printf("Entering debug resend-all mode\n");
   1.474      
   1.475 @@ -707,21 +752,23 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.476  
   1.477          if ( last_iter ) break;
   1.478  
   1.479 -        if ( live ) {
   1.480 -            if ( (iter >= max_iters) || 
   1.481 -                 (sent_this_iter+skip_this_iter < 50) || 
   1.482 -                 (total_sent > nr_pfns*max_factor) )
   1.483 +        if ( live )
   1.484 +        {
   1.485 +            if ( 
   1.486 +                /* ( sent_this_iter > (sent_last_iter * 0.95) ) || */
   1.487 +                (iter >= max_iters) || 
   1.488 +                (sent_this_iter+skip_this_iter < 50) || 
   1.489 +                (total_sent > nr_pfns*max_factor) )
   1.490              {
   1.491                  DPRINTF("Start last iteration\n");
   1.492                  last_iter = 1;
   1.493  
   1.494 -                xc_domain_pause(xc_handle, domid);
   1.495 +                xc_domain_pause( xc_handle, domid );
   1.496              } 
   1.497  
   1.498              if ( xc_shadow_control( xc_handle, domid, 
   1.499                                      DOM0_SHADOW_CONTROL_OP_CLEAN2,
   1.500 -                                    to_send, nr_pfns, &faults_this_iter,
   1.501 -                                    &dirtied_this_iter) != nr_pfns ) 
   1.502 +                                    to_send, nr_pfns, &stats ) != nr_pfns ) 
   1.503              {
   1.504                  xcio_error(ioctxt, "Error flushing shadow PT");
   1.505                  goto out;
   1.506 @@ -729,12 +776,11 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.507  
   1.508              sent_last_iter = sent_this_iter;
   1.509  
   1.510 -            /* dirtied_this_iter = count_bits( nr_pfns, to_send ); */
   1.511 -            track_cpu_usage( xc_handle, domid, faults_this_iter,
   1.512 -                             sent_this_iter, dirtied_this_iter, 1);
   1.513 +            print_stats( xc_handle, domid, sent_this_iter, &stats, 1);
   1.514       
   1.515          }
   1.516  
   1.517 +
   1.518      } /* end of while 1 */
   1.519  
   1.520      DPRINTF("All memory is saved\n");
   1.521 @@ -750,13 +796,9 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.522      }
   1.523  
   1.524      /* Get the final execution context */
   1.525 -    op.cmd = DOM0_GETDOMAININFO;
   1.526 -    op.u.getdomaininfo.domain = (domid_t)domid;
   1.527 -    op.u.getdomaininfo.ctxt = &ctxt;
   1.528 -    if ( (do_dom0_op(xc_handle, &op) < 0) || 
   1.529 -         ((u32)op.u.getdomaininfo.domain != domid) )
   1.530 +    if ( xc_domain_getfullinfo( xc_handle, domid, &op, &ctxt) )
   1.531      {
   1.532 -        xcio_perror(ioctxt, "Could not get info on domain");
   1.533 +        xcio_perror(ioctxt, "Could not get full domain info");
   1.534          goto out;
   1.535      }
   1.536  
   1.537 @@ -779,7 +821,7 @@ int xc_linux_save(int xc_handle, XcIOCon
   1.538          xcio_error(ioctxt, "PT base is not in range of pseudophys map");
   1.539          goto out;
   1.540      }
   1.541 -    ctxt.pt_base = live_mfn_to_pfn_table[ctxt.pt_base >> PAGE_SHIFT] << 
   1.542 +    ctxt.pt_base = live_mfn_to_pfn_table[ctxt.pt_base >> PAGE_SHIFT] <<
   1.543          PAGE_SHIFT;
   1.544  
   1.545      if ( xcio_write(ioctxt, &ctxt,       sizeof(ctxt)) ||