aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/tmem.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-11-24 14:37:59 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-11-24 14:37:59 +0000
commitc8ec7e22d614c89a2c1a1faa22681e84c39509cb (patch)
treebdde371072984002daea95df0576706c4713174d /xen/common/tmem.c
parent1a9b225d38b970df2dcd18a99cfcc12e559ad8ba (diff)
downloadxen-c8ec7e22d614c89a2c1a1faa22681e84c39509cb.tar.gz
xen-c8ec7e22d614c89a2c1a1faa22681e84c39509cb.tar.bz2
xen-c8ec7e22d614c89a2c1a1faa22681e84c39509cb.zip
tmem: Fix another race in tmem on domain destroy.
Signed-off-by: Dan Magenheimer <dan.magenheimer@oracle.com>
Diffstat (limited to 'xen/common/tmem.c')
-rw-r--r--xen/common/tmem.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/xen/common/tmem.c b/xen/common/tmem.c
index efc2f53649..af1537d3b5 100644
--- a/xen/common/tmem.c
+++ b/xen/common/tmem.c
@@ -149,6 +149,7 @@ typedef struct share_list sharelist_t;
struct tm_pool {
bool_t shared;
bool_t persistent;
+ bool_t is_dying;
int pageshift; /* 0 == 2**12 */
struct list_head pool_list; /* FIXME do we need this anymore? */
client_t *client;
@@ -724,6 +725,7 @@ static void pool_destroy_objs(pool_t *pool, bool_t selective, cli_id_t cli_id)
int i;
tmem_write_lock(&pool->pool_rwlock);
+ pool->is_dying = 1;
for (i = 0; i < OBJ_HASH_BUCKETS; i++)
{
node = rb_first(&pool->obj_rb_root[i]);
@@ -734,7 +736,8 @@ static void pool_destroy_objs(pool_t *pool, bool_t selective, cli_id_t cli_id)
node = rb_next(node);
ASSERT(obj->no_evict == 0);
if ( !selective )
- obj_destroy(obj,1);
+ /* FIXME: should be obj,1 but walking/erasing rbtree is racy */
+ obj_destroy(obj,0);
else if ( obj->last_client == cli_id )
obj_destroy(obj,0);
else
@@ -770,6 +773,7 @@ static pool_t * pool_alloc(void)
pool->found_gets = pool->gets = 0;
pool->flushs_found = pool->flushs = 0;
pool->flush_objs_found = pool->flush_objs = 0;
+ pool->is_dying = 0;
SET_SENTINEL(pool,POOL);
return pool;
}
@@ -1001,6 +1005,8 @@ static int tmem_evict(void)
{
obj = pgp->obj;
pool = obj->pool;
+ if ( pool->is_dying )
+ continue;
if ( tmh_lock_all && !obj->no_evict )
goto found;
if ( tmem_spin_trylock(&obj->obj_spinlock) )
@@ -1022,6 +1028,8 @@ static int tmem_evict(void)
{
obj = pgp->obj;
pool = obj->pool;
+ if ( pool->is_dying )
+ continue;
if ( tmh_lock_all && !obj->no_evict )
goto found;
if ( tmem_spin_trylock(&obj->obj_spinlock) )