[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v2 18/18] argo: unmap rings on suspend; signal ring-owners on resume



The hypervisor data structures for the argo rings are populated with mfns
which cannot be assumed to map to the same guest frame numbers across entry
to and exit from host power state S4 (hibernate to disk).

Tear down all the rings during suspend to stop argo operations from
performing any further writes into the registered set of mfns for the rings.

In order to support guests reestablishing their registered rings on resume,
signal each guest that has a registered ring so that the guest may
re-register each ring with the current mappings for its guest frame numbers.

Signed-off-by: Christopher Clark <christopher.clark6@xxxxxxxxxxxxxx>
---
Changes since v1:

v1. feedback #15 Jan: make i unsigned
v1. self: fix indentation and blank lines
v1. feedback #25 Jan: add rationale to commit message

re: v1 feedback #25 Jan: soft-reset is now not a problem for the resume logic
in this commit since handling of soft reset was added to an earlier commit in
this version 2 series.

 xen/common/argo.c      | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++
 xen/common/domain.c    |  9 +++++++
 xen/include/xen/argo.h |  2 ++
 3 files changed, 83 insertions(+)

diff --git a/xen/common/argo.c b/xen/common/argo.c
index 921aaf3..624ed8a 100644
--- a/xen/common/argo.c
+++ b/xen/common/argo.c
@@ -1076,6 +1076,16 @@ static void argo_ring_remove_mfns(const struct domain *d,
 }
 
 static void
+argo_ring_reset(struct domain *d, struct argo_ring_info *ring_info)
+{
+    ASSERT(rw_is_write_locked(&d->argo->lock));
+
+    argo_ring_remove_mfns(d, ring_info);
+    ring_info->len = 0;
+    ring_info->tx_ptr = 0;
+}
+
+static void
 argo_ring_remove_info(struct domain *d, struct argo_ring_info *ring_info)
 {
     ASSERT(rw_is_write_locked(&d->argo->lock));
@@ -2222,3 +2232,65 @@ argo_soft_reset(struct domain *d)
 
     write_unlock(&argo_lock);
 }
+
+void
+argo_shutdown_for_suspend(struct domain *d)
+{
+    unsigned int i;
+
+    if ( !d )
+        return;
+
+    if ( get_domain(d) )
+    {
+        read_lock(&argo_lock);
+
+        if ( d->argo )
+        {
+            write_lock(&d->argo->lock);
+
+            for ( i = 0; i < ARGO_HTABLE_SIZE; i++ )
+            {
+                struct hlist_node *node, *next;
+                struct argo_ring_info *ring_info;
+
+                hlist_for_each_entry_safe(ring_info, node,
+                                          next, &d->argo->ring_hash[i], node)
+                    argo_ring_reset(d, ring_info);
+            }
+
+            write_unlock(&d->argo->lock);
+        }
+
+        read_unlock(&argo_lock);
+
+        put_domain(d);
+    }
+}
+
+void
+argo_resume(struct domain *d)
+{
+    bool send_wakeup;
+
+    if ( !d )
+        return;
+
+    if ( !get_domain(d) )
+        return;
+
+    read_lock(&argo_lock);
+
+    read_lock(&d->argo->lock);
+
+    send_wakeup = ( d->argo->ring_count > 0 );
+
+    read_unlock(&d->argo->lock);
+
+    if ( send_wakeup )
+        argo_signal_domain(d);
+
+    read_unlock(&argo_lock);
+
+    put_domain(d);
+}
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 601c663..e194a42 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -89,6 +89,11 @@ static void __domain_finalise_shutdown(struct domain *d)
         if ( !v->paused_for_shutdown )
             return;
 
+#ifdef CONFIG_ARGO
+    if ( d->shutdown_code == SHUTDOWN_suspend )
+        argo_shutdown_for_suspend(d);
+#endif
+
     d->is_shut_down = 1;
     if ( (d->shutdown_code == SHUTDOWN_suspend) && d->suspend_evtchn )
         evtchn_send(d, d->suspend_evtchn);
@@ -857,6 +862,10 @@ void domain_resume(struct domain *d)
     spin_unlock(&d->shutdown_lock);
 
     domain_unpause(d);
+
+#ifdef CONFIG_ARGO
+    argo_resume(d);
+#endif
 }
 
 int vcpu_start_shutdown_deferral(struct vcpu *v)
diff --git a/xen/include/xen/argo.h b/xen/include/xen/argo.h
index 29d32a9..e3dc19b 100644
--- a/xen/include/xen/argo.h
+++ b/xen/include/xen/argo.h
@@ -18,6 +18,8 @@
 
 int argo_init(struct domain *d);
 void argo_destroy(struct domain *d);
+void argo_shutdown_for_suspend(struct domain *d);
+void argo_resume(struct domain *d);
 void argo_soft_reset(struct domain *d);
 
 #endif
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.