[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v9 09/11] x86/domctl: Don't pause the whole domain if only getting vcpu state
This patch is focused on moving the for loop to the caller so now we can save info for a single vcpu instance with the save_one handlers. Signed-off-by: Alexandru Isaila <aisaila@xxxxxxxxxxxxxxx> --- xen/arch/x86/hvm/save.c | 141 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 111 insertions(+), 30 deletions(-) diff --git a/xen/arch/x86/hvm/save.c b/xen/arch/x86/hvm/save.c index b674937..1b28e7f 100644 --- a/xen/arch/x86/hvm/save.c +++ b/xen/arch/x86/hvm/save.c @@ -138,9 +138,12 @@ size_t hvm_save_size(struct domain *d) int hvm_save_one(struct domain *d, unsigned int typecode, unsigned int instance, XEN_GUEST_HANDLE_64(uint8) handle, uint64_t *bufsz) { - int rv; + int rv = 0; hvm_domain_context_t ctxt = { }; const struct hvm_save_descriptor *desc; + bool is_single_instance = false; + uint32_t off = 0; + struct vcpu *v; if ( d->is_dying || typecode > HVM_SAVE_CODE_MAX || @@ -148,43 +151,94 @@ int hvm_save_one(struct domain *d, unsigned int typecode, unsigned int instance, !hvm_sr_handlers[typecode].save ) return -EINVAL; + if ( hvm_sr_handlers[typecode].kind == HVMSR_PER_VCPU && + instance < d->max_vcpus ) + is_single_instance = true; + ctxt.size = hvm_sr_handlers[typecode].size; - if ( hvm_sr_handlers[typecode].kind == HVMSR_PER_VCPU ) + if ( hvm_sr_handlers[typecode].kind == HVMSR_PER_VCPU && + instance == d->max_vcpus ) ctxt.size *= d->max_vcpus; ctxt.data = xmalloc_bytes(ctxt.size); if ( !ctxt.data ) return -ENOMEM; - if ( (rv = hvm_sr_handlers[typecode].save(d, &ctxt)) != 0 ) - printk(XENLOG_G_ERR "HVM%d save: failed to save type %"PRIu16" (%d)\n", - d->domain_id, typecode, rv); - else if ( rv = -ENOENT, ctxt.cur >= sizeof(*desc) ) + if ( is_single_instance ) + vcpu_pause(d->vcpu[instance]); + else + domain_pause(d); + + if ( is_single_instance ) { - uint32_t off; + if ( hvm_sr_handlers[typecode].save_one != NULL ) + rv = hvm_sr_handlers[typecode].save_one(d->vcpu[instance], + &ctxt); + else + rv = hvm_sr_handlers[typecode].save(d, &ctxt); - for ( off = 0; off <= (ctxt.cur - sizeof(*desc)); off += desc->length ) + if ( rv != 0 ) { - desc = (void *)(ctxt.data + off); - /* Move past header */ - off += sizeof(*desc); - if ( ctxt.cur < desc->length || - off > ctxt.cur - desc->length ) - break; - if ( instance == desc->instance ) - { - rv = 0; - if ( guest_handle_is_null(handle) ) - *bufsz = desc->length; - else if ( *bufsz < desc->length ) - rv = -ENOBUFS; - else if ( copy_to_guest(handle, ctxt.data + off, desc->length) ) - rv = -EFAULT; - else - *bufsz = desc->length; - break; - } + printk(XENLOG_G_ERR "HVM%d save: failed to save type %"PRIu16" (%d)\n", + d->domain_id, typecode, rv); + vcpu_unpause(d->vcpu[instance]); + } + else if ( ctxt.cur >= sizeof(*desc) ) + { + rv = -ENOENT; + desc = (void *)(ctxt.data); + /* Move past header */ + off = sizeof(*desc); + if ( ctxt.cur < desc->length || + off > ctxt.cur - desc->length ) + rv = -EFAULT; + rv = 0; + if ( guest_handle_is_null(handle) ) + *bufsz = desc->length; + else if ( *bufsz < desc->length ) + rv = -ENOBUFS; + else if ( copy_to_guest(handle, ctxt.data + off, desc->length) ) + rv = -EFAULT; + else + *bufsz = desc->length; + vcpu_unpause(d->vcpu[instance]); } } + else + { + for_each_vcpu ( d, v ) + { + if ( (rv = hvm_sr_handlers[typecode].save(d, &ctxt)) != 0 ) + { + printk(XENLOG_G_ERR "HVM%d save: failed to save type %"PRIu16" (%d)\n", + d->domain_id, typecode, rv); + } + else if ( ctxt.cur >= sizeof(*desc) ) + { + rv = -ENOENT; + desc = (void *)(ctxt.data + off); + /* Move past header */ + off += sizeof(*desc); + if ( ctxt.cur < desc->length || + off > ctxt.cur - desc->length ) + break; + if ( instance == desc->instance ) + { + rv = 0; + if ( guest_handle_is_null(handle) ) + *bufsz = desc->length; + else if ( *bufsz < desc->length ) + rv = -ENOBUFS; + else if ( copy_to_guest(handle, ctxt.data + off, desc->length) ) + rv = -EFAULT; + else + *bufsz = desc->length; + break; + } + off += desc->length; + } + } + domain_unpause(d); + } xfree(ctxt.data); return rv; @@ -196,7 +250,9 @@ int hvm_save(struct domain *d, hvm_domain_context_t *h) struct hvm_save_header hdr; struct hvm_save_end end; hvm_save_handler handler; - unsigned int i; + hvm_save_one_handler save_one_handler; + unsigned int i, rc; + struct vcpu *v = NULL; if ( d->is_dying ) return -EINVAL; @@ -224,11 +280,36 @@ int hvm_save(struct domain *d, hvm_domain_context_t *h) for ( i = 0; i <= HVM_SAVE_CODE_MAX; i++ ) { handler = hvm_sr_handlers[i].save; - if ( handler != NULL ) + save_one_handler = hvm_sr_handlers[i].save_one; + if ( save_one_handler != NULL ) { printk(XENLOG_G_INFO "HVM%d save: %s\n", d->domain_id, hvm_sr_handlers[i].name); - if ( handler(d, h) != 0 ) + for_each_vcpu ( d, v ) + { + rc = save_one_handler(v, h); + if( rc == CONTINUE ) + continue; + + if( rc != 0 ) + { + printk(XENLOG_G_ERR + "HVM%d save: failed to save type %"PRIu16"\n", + d->domain_id, i); + return -EFAULT; + } + } + } + else if ( handler != NULL ) + { + printk(XENLOG_G_INFO "HVM%d save: %s\n", + d->domain_id, hvm_sr_handlers[i].name); + + rc = handler(d, h); + if( rc == CONTINUE ) + continue; + + if( rc != 0 ) { printk(XENLOG_G_ERR "HVM%d save: failed to save type %"PRIu16"\n", -- 2.7.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |