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

[Xen-changelog] [xen-unstable] tmem: Fix domain lifecycle synchronisation.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1276205992 -3600
# Node ID 04e81a65d27ef09654cd731735fc6a4ebc6314d4
# Parent  39657b16806826f88947b9882884374f3ed15c30
tmem: Fix domain lifecycle synchronisation.

Obtaining a domain reference count is neither necessary nor
sufficient. Instead we simply check whether a domain is already dying
when it first becomes a client of tmem. If it is not then we will
correctly clean up later via tmem_destroy() called from domain_kill().

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/common/tmem.c          |   18 ++++++++++++------
 xen/common/tmem_xen.c      |    2 +-
 xen/include/xen/tmem_xen.h |   27 +++++++++++++++------------
 3 files changed, 28 insertions(+), 19 deletions(-)

diff -r 39657b168068 -r 04e81a65d27e xen/common/tmem.c
--- a/xen/common/tmem.c Thu Jun 10 22:12:36 2010 +0100
+++ b/xen/common/tmem.c Thu Jun 10 22:39:52 2010 +0100
@@ -1170,17 +1170,19 @@ static client_t *client_create(cli_id_t 
     if ( client == NULL )
     {
         printk("failed... out of memory\n");
-        return NULL;
+        goto fail;
     }
     memset(client,0,sizeof(client_t));
     if ( (client->tmh = tmh_client_init(cli_id)) == NULL )
     {
         printk("failed... can't allocate host-dependent part of client\n");
-        if ( client )
-            tmh_free_infra(client);
-        return NULL;
-    }
-    tmh_set_client_from_id(client, client->tmh, cli_id);
+        goto fail;
+    }
+    if ( !tmh_set_client_from_id(client, client->tmh, cli_id) )
+    {
+        printk("failed... can't set client\n");
+        goto fail;
+    }
     client->cli_id = cli_id;
 #ifdef __i386__
     client->compress = 0;
@@ -1202,6 +1204,10 @@ static client_t *client_create(cli_id_t 
     client->succ_eph_gets = 0; client->succ_pers_gets = 0;
     printk("ok\n");
     return client;
+
+ fail:
+    tmh_free_infra(client);
+    return NULL;
 }
 
 static void client_free(client_t *client)
diff -r 39657b168068 -r 04e81a65d27e xen/common/tmem_xen.c
--- a/xen/common/tmem_xen.c     Thu Jun 10 22:12:36 2010 +0100
+++ b/xen/common/tmem_xen.c     Thu Jun 10 22:39:52 2010 +0100
@@ -339,10 +339,10 @@ EXPORT tmh_client_t *tmh_client_init(cli
 
 EXPORT void tmh_client_destroy(tmh_client_t *tmh)
 {
+    ASSERT(tmh->domain->is_dying);
 #ifndef __i386__
     xmem_pool_destroy(tmh->persistent_pool);
 #endif
-    put_domain(tmh->domain);
     tmh->domain = NULL;
 }
 
diff -r 39657b168068 -r 04e81a65d27e xen/include/xen/tmem_xen.h
--- a/xen/include/xen/tmem_xen.h        Thu Jun 10 22:12:36 2010 +0100
+++ b/xen/include/xen/tmem_xen.h        Thu Jun 10 22:39:52 2010 +0100
@@ -302,9 +302,6 @@ extern tmh_client_t *tmh_client_init(cli
 extern tmh_client_t *tmh_client_init(cli_id_t);
 extern void tmh_client_destroy(tmh_client_t *);
 
-/* we don't need to take a reference to the domain here as we hold
- * one for the entire life of the client, so use rcu_lock_domain_by_id
- * variant instead of get_domain_by_id() */
 static inline struct client *tmh_client_from_cli_id(cli_id_t cli_id)
 {
     struct client *c;
@@ -333,15 +330,21 @@ static inline tmh_cli_ptr_t *tmh_get_cli
     return current->domain;
 }
 
-static inline void tmh_set_client_from_id(struct client *client,
-                                          tmh_client_t *tmh, cli_id_t cli_id)
-{
-    /* here we DO want to take/hold a reference to the domain as
-     * this routine should be called exactly once when the client is created;
-     * the matching put_domain is in tmh_client_destroy */
-    struct domain *d = get_domain_by_id(cli_id);
-    d->tmem = client;
-    tmh->domain = d;
+static inline bool_t tmh_set_client_from_id(
+    struct client *client, tmh_client_t *tmh, cli_id_t cli_id)
+{
+    struct domain *d = rcu_lock_domain_by_id(cli_id);
+    bool_t rc = 0;
+    if ( d == NULL )
+        return 0;
+    if ( !d->is_dying )
+    {
+        d->tmem = client;
+        tmh->domain = d;
+        rc = 1;
+    }
+    rcu_unlock_domain(d);
+    return rc;
 }
 
 static inline bool_t tmh_current_is_privileged(void)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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