[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] More PV save/restore fixes.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1172671989 0 # Node ID 1ec0d322402eaa5b85691f8b4df704fe39d14263 # Parent 0f0ac445bf82e4dca6d3b22d646e0bf278bd3757 More PV save/restore fixes. Related changesets: 14148:b67c253d1cdb4f502dec2 13519:b4a8000e76db6b4b27341 These three changesets must be applied as a set! Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c | 23 ++++++++-- linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h | 1 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c | 39 +++++++++++------ tools/python/xen/xend/XendCheckpoint.py | 10 ++-- tools/xenstore/xenstored_domain.c | 15 ++++-- 5 files changed, 62 insertions(+), 26 deletions(-) diff -r 0f0ac445bf82 -r 1ec0d322402e linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Wed Feb 28 13:22:20 2007 +0000 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Wed Feb 28 14:13:09 2007 +0000 @@ -137,12 +137,15 @@ int xb_write(const void *data, unsigned return 0; } +int xb_data_to_read(void) +{ + struct xenstore_domain_interface *intf = xen_store_interface; + return (intf->rsp_cons != intf->rsp_prod); +} + int xb_wait_for_data_to_read(void) { - struct xenstore_domain_interface *intf = xen_store_interface; - return wait_event_interruptible( - xb_waitq, - intf->rsp_cons != intf->rsp_prod); + return wait_event_interruptible(xb_waitq, xb_data_to_read()); } int xb_read(void *data, unsigned len) @@ -197,7 +200,19 @@ int xb_read(void *data, unsigned len) /* Set up interrupt handler off store event channel. */ int xb_init_comms(void) { + struct xenstore_domain_interface *intf = xen_store_interface; int err; + + if (intf->req_prod != intf->req_cons) + printk(KERN_ERR "XENBUS request ring is not quiescent " + "(%08x:%08x)!\n", intf->req_cons, intf->req_prod); + + if (intf->rsp_prod != intf->rsp_cons) { + printk(KERN_WARNING "XENBUS response ring is not quiescent " + "(%08x:%08x): fixing up\n", + intf->rsp_cons, intf->rsp_prod); + intf->rsp_cons = intf->rsp_prod; + } if (xenbus_irq) unbind_from_irqhandler(xenbus_irq, &xb_waitq); diff -r 0f0ac445bf82 -r 1ec0d322402e linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h Wed Feb 28 13:22:20 2007 +0000 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h Wed Feb 28 14:13:09 2007 +0000 @@ -37,6 +37,7 @@ int xb_init_comms(void); /* Low level routines. */ int xb_write(const void *data, unsigned len); int xb_read(void *data, unsigned len); +int xb_data_to_read(void); int xb_wait_for_data_to_read(void); int xs_input_avail(void); extern struct xenstore_domain_interface *xen_store_interface; diff -r 0f0ac445bf82 -r 1ec0d322402e linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Wed Feb 28 13:22:20 2007 +0000 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Wed Feb 28 14:13:09 2007 +0000 @@ -80,6 +80,9 @@ struct xs_handle { /* One request at a time. */ struct mutex request_mutex; + /* Protect xenbus reader thread against save/restore. */ + struct mutex response_mutex; + /* Protect transactions against save/restore. */ struct rw_semaphore suspend_mutex; }; @@ -654,6 +657,7 @@ void xs_suspend(void) { down_write(&xs_state.suspend_mutex); mutex_lock(&xs_state.request_mutex); + mutex_lock(&xs_state.response_mutex); } void xs_resume(void) @@ -661,6 +665,7 @@ void xs_resume(void) struct xenbus_watch *watch; char token[sizeof(watch) * 2 + 1]; + mutex_unlock(&xs_state.response_mutex); mutex_unlock(&xs_state.request_mutex); /* No need for watches_lock: the suspend_mutex is sufficient. */ @@ -674,6 +679,7 @@ void xs_resume(void) void xs_suspend_cancel(void) { + mutex_unlock(&xs_state.response_mutex); mutex_unlock(&xs_state.request_mutex); up_write(&xs_state.suspend_mutex); } @@ -737,19 +743,27 @@ static int process_msg(void) char *body; int err; - err = xb_wait_for_data_to_read(); - if (err) - return err; + /* + * We must disallow save/restore while reading a xenstore message. + * A partial read across s/r leaves us out of sync with xenstored. + */ + for (;;) { + err = xb_wait_for_data_to_read(); + if (err) + return err; + mutex_lock(&xs_state.response_mutex); + if (xb_data_to_read()) + break; + /* We raced with save/restore: pending data 'disappeared'. */ + mutex_unlock(&xs_state.response_mutex); + } + msg = kmalloc(sizeof(*msg), GFP_KERNEL); - if (msg == NULL) - return -ENOMEM; - - /* - * We are now committed to reading an entire message. Partial reads - * across save/restore leave us out of sync with the xenstore daemon. - */ - down_read(&xs_state.suspend_mutex); + if (msg == NULL) { + err = -ENOMEM; + goto out; + } err = xb_read(&msg->hdr, sizeof(msg->hdr)); if (err) { @@ -803,7 +817,7 @@ static int process_msg(void) } out: - up_read(&xs_state.suspend_mutex); + mutex_unlock(&xs_state.response_mutex); return err; } @@ -833,6 +847,7 @@ int xs_init(void) init_waitqueue_head(&xs_state.reply_waitq); mutex_init(&xs_state.request_mutex); + mutex_init(&xs_state.response_mutex); init_rwsem(&xs_state.suspend_mutex); /* Initialize the shared memory rings to talk to xenstored */ diff -r 0f0ac445bf82 -r 1ec0d322402e tools/python/xen/xend/XendCheckpoint.py --- a/tools/python/xen/xend/XendCheckpoint.py Wed Feb 28 13:22:20 2007 +0000 +++ b/tools/python/xen/xend/XendCheckpoint.py Wed Feb 28 14:13:09 2007 +0000 @@ -230,11 +230,7 @@ def restore(xd, fd, dominfo = None, paus if not is_hvm and handler.console_mfn is None: raise XendError('Could not read console MFN') - dominfo.waitForDevices() # Wait for backends to set up - if not paused: - dominfo.unpause() - - # get qemu state and create a tmp file for dm restore + # get qemu state and create a tmp file for dm restore if is_hvm: qemu_signature = read_exact(fd, len(QEMU_SIGNATURE), "invalid device model signature read") @@ -257,6 +253,10 @@ def restore(xd, fd, dominfo = None, paus dominfo.completeRestore(handler.store_mfn, handler.console_mfn) + dominfo.waitForDevices() # Wait for backends to set up + if not paused: + dominfo.unpause() + return dominfo except: dominfo.destroy() diff -r 0f0ac445bf82 -r 1ec0d322402e tools/xenstore/xenstored_domain.c --- a/tools/xenstore/xenstored_domain.c Wed Feb 28 13:22:20 2007 +0000 +++ b/tools/xenstore/xenstored_domain.c Wed Feb 28 14:13:09 2007 +0000 @@ -298,6 +298,7 @@ void do_introduce(struct connection *con unsigned int domid; unsigned long mfn; evtchn_port_t port; + int rc; if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) { send_error(conn, EINVAL); @@ -341,17 +342,21 @@ void do_introduce(struct connection *con talloc_steal(domain->conn, domain); fire_watches(conn, "@introduceDomain", false); - } - else { - int rc; - + } else if (domain->mfn == mfn) { /* Use XS_INTRODUCE for recreating the xenbus event-channel. */ if (domain->port) xc_evtchn_unbind(xce_handle, domain->port); rc = xc_evtchn_bind_interdomain(xce_handle, domid, port); domain->port = (rc == -1) ? 0 : rc; domain->remote_port = port; - } + } else { + send_error(conn, EINVAL); + return; + } + + /* Rings must be quiesced. */ + domain->interface->req_cons = domain->interface->req_prod = 0; + domain->interface->rsp_cons = domain->interface->rsp_prod = 0; send_ack(conn, XS_INTRODUCE); } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |