]> xenbits.xensource.com Git - people/dwmw2/xen.git/commitdiff
libxc: Support save/restore of up to 4096 VCPUs (increase from 64 VCPUs).
authorKeir Fraser <keir@xen.org>
Wed, 22 Aug 2012 21:20:42 +0000 (22:20 +0100)
committerKeir Fraser <keir@xen.org>
Wed, 22 Aug 2012 21:20:42 +0000 (22:20 +0100)
Signed-off-by: Keir Fraser <keir@xen.org>
tools/libxc/xc_domain_restore.c
tools/libxc/xc_domain_save.c
tools/libxc/xg_save_restore.h

index 3fe2b1237364463f01d34ec5124ded4384334c1a..b4c0b10aaa4799f8a56ecf1463b1a5e87e150a3d 100644 (file)
@@ -462,7 +462,7 @@ static int dump_qemu(xc_interface *xch, uint32_t dom, struct tailbuf_hvm *buf)
 
 static int buffer_tail_hvm(xc_interface *xch, struct restore_ctx *ctx,
                            struct tailbuf_hvm *buf, int fd,
-                           unsigned int max_vcpu_id, uint64_t vcpumap,
+                           unsigned int max_vcpu_id, uint64_t *vcpumap,
                            int ext_vcpucontext,
                            int vcpuextstate, uint32_t vcpuextstate_size)
 {
@@ -530,7 +530,7 @@ static int buffer_tail_hvm(xc_interface *xch, struct restore_ctx *ctx,
 
 static int buffer_tail_pv(xc_interface *xch, struct restore_ctx *ctx,
                           struct tailbuf_pv *buf, int fd,
-                          unsigned int max_vcpu_id, uint64_t vcpumap,
+                          unsigned int max_vcpu_id, uint64_t *vcpumap,
                           int ext_vcpucontext,
                           int vcpuextstate,
                           uint32_t vcpuextstate_size)
@@ -563,8 +563,8 @@ static int buffer_tail_pv(xc_interface *xch, struct restore_ctx *ctx,
     /* VCPU contexts */
     buf->vcpucount = 0;
     for (i = 0; i <= max_vcpu_id; i++) {
-        // DPRINTF("vcpumap: %llx, cpu: %d, bit: %llu\n", vcpumap, i, (vcpumap % (1ULL << i)));
-        if ( (!(vcpumap & (1ULL << i))) )
+        // DPRINTF("vcpumap: %llx, cpu: %d, bit: %llu\n", vcpumap[i/64], i, (vcpumap[i/64] & (1ULL << (i%64))));
+        if ( (!(vcpumap[i/64] & (1ULL << (i%64)))) )
             continue;
         buf->vcpucount++;
     }
@@ -614,7 +614,7 @@ static int buffer_tail_pv(xc_interface *xch, struct restore_ctx *ctx,
 
 static int buffer_tail(xc_interface *xch, struct restore_ctx *ctx,
                        tailbuf_t *buf, int fd, unsigned int max_vcpu_id,
-                       uint64_t vcpumap, int ext_vcpucontext,
+                       uint64_t *vcpumap, int ext_vcpucontext,
                        int vcpuextstate, uint32_t vcpuextstate_size)
 {
     if ( buf->ishvm )
@@ -680,7 +680,7 @@ typedef struct {
 
     int new_ctxt_format;
     int max_vcpu_id;
-    uint64_t vcpumap;
+    uint64_t vcpumap[XC_SR_MAX_VCPUS/64];
     uint64_t identpt;
     uint64_t paging_ring_pfn;
     uint64_t access_ring_pfn;
@@ -745,12 +745,12 @@ static int pagebuf_get_one(xc_interface *xch, struct restore_ctx *ctx,
     case XC_SAVE_ID_VCPU_INFO:
         buf->new_ctxt_format = 1;
         if ( RDEXACT(fd, &buf->max_vcpu_id, sizeof(buf->max_vcpu_id)) ||
-             buf->max_vcpu_id >= 64 || RDEXACT(fd, &buf->vcpumap,
-                                               sizeof(uint64_t)) ) {
+             buf->max_vcpu_id >= XC_SR_MAX_VCPUS ||
+             RDEXACT(fd, buf->vcpumap, vcpumap_sz(buf->max_vcpu_id)) ) {
             PERROR("Error when reading max_vcpu_id");
             return -1;
         }
-        // DPRINTF("Max VCPU ID: %d, vcpumap: %llx\n", buf->max_vcpu_id, buf->vcpumap);
+        // DPRINTF("Max VCPU ID: %d, vcpumap: %llx\n", buf->max_vcpu_id, buf->vcpumap[0]);
         return pagebuf_get_one(xch, ctx, buf, fd, dom);
 
     case XC_SAVE_ID_HVM_IDENT_PT:
@@ -1366,7 +1366,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
     struct mmuext_op pin[MAX_PIN_BATCH];
     unsigned int nr_pins;
 
-    uint64_t vcpumap = 1ULL;
+    uint64_t vcpumap[XC_SR_MAX_VCPUS/64] = { 1ULL };
     unsigned int max_vcpu_id = 0;
     int new_ctxt_format = 0;
 
@@ -1517,8 +1517,8 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
         if ( j == 0 ) {
             /* catch vcpu updates */
             if (pagebuf.new_ctxt_format) {
-                vcpumap = pagebuf.vcpumap;
                 max_vcpu_id = pagebuf.max_vcpu_id;
+                memcpy(vcpumap, pagebuf.vcpumap, vcpumap_sz(max_vcpu_id));
             }
             /* should this be deferred? does it change? */
             if ( pagebuf.identpt )
@@ -1880,7 +1880,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
     vcpup = tailbuf.u.pv.vcpubuf;
     for ( i = 0; i <= max_vcpu_id; i++ )
     {
-        if ( !(vcpumap & (1ULL << i)) )
+        if ( !(vcpumap[i/64] & (1ULL << (i%64))) )
             continue;
 
         memcpy(ctxt, vcpup, ((dinfo->guest_width == 8) ? sizeof(ctxt->x64)
index c359649edb31c32d3f82a5d5fd686053dd08ac4d..57d5347363038ea2d983d967564a1bed0e19177b 100644 (file)
@@ -855,7 +855,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
     unsigned long needed_to_fix = 0;
     unsigned long total_sent    = 0;
 
-    uint64_t vcpumap = 1ULL;
+    uint64_t vcpumap[XC_SR_MAX_VCPUS/64] = { 1ULL };
 
     /* HVM: a buffer for holding HVM context */
     uint32_t hvm_buf_size = 0;
@@ -1581,13 +1581,13 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
     }
 
     {
-        struct {
+        struct chunk {
             int id;
             int max_vcpu_id;
-            uint64_t vcpumap;
+            uint64_t vcpumap[XC_SR_MAX_VCPUS/64];
         } chunk = { XC_SAVE_ID_VCPU_INFO, info.max_vcpu_id };
 
-        if ( info.max_vcpu_id >= 64 )
+        if ( info.max_vcpu_id >= XC_SR_MAX_VCPUS )
         {
             ERROR("Too many VCPUS in guest!");
             goto out;
@@ -1598,11 +1598,12 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
             xc_vcpuinfo_t vinfo;
             if ( (xc_vcpu_getinfo(xch, dom, i, &vinfo) == 0) &&
                  vinfo.online )
-                vcpumap |= 1ULL << i;
+                vcpumap[i/64] |= 1ULL << (i%64);
         }
 
-        chunk.vcpumap = vcpumap;
-        if ( wrexact(io_fd, &chunk, sizeof(chunk)) )
+        memcpy(chunk.vcpumap, vcpumap, vcpumap_sz(info.max_vcpu_id));
+        if ( wrexact(io_fd, &chunk, offsetof(struct chunk, vcpumap)
+                     + vcpumap_sz(info.max_vcpu_id)) )
         {
             PERROR("Error when writing to state file");
             goto out;
@@ -1878,7 +1879,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
 
     for ( i = 0; i <= info.max_vcpu_id; i++ )
     {
-        if ( !(vcpumap & (1ULL << i)) )
+        if ( !(vcpumap[i/64] & (1ULL << (i%64))) )
             continue;
 
         if ( (i != 0) && xc_vcpu_getcontext(xch, dom, i, &ctxt) )
index 04e7892698a002f65c90149df0e75910f781c9a2..3edb088925b977a01ddd82215373483b9491ae6b 100644 (file)
 /* When pinning page tables at the end of restore, we also use batching. */
 #define MAX_PIN_BATCH  1024
 
+/* Maximum #VCPUs currently supported for save/restore. */
+#define XC_SR_MAX_VCPUS 4096
+#define vcpumap_sz(max_id) (((max_id)/64+1)*sizeof(uint64_t))
 
 
 /*