# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1258194779 0
# Node ID bec27eb6f72cfb3fcecd8eb3060869fa301a62df
# Parent 412a8c7d3721090ca54bc963b97e7892ae4f38c7
tmem: fix domain shutdown problem/race
Tmem fails to put_domain so a dying domain never gets
properly shut down. Also, fix race condition when
domain is dying by not allowing any new ops to succeed.
Signed-off-by: Dan Magenheimer <dan.magenheimer@xxxxxxxxxx>
---
xen/common/tmem.c | 12 ++++++++++++
xen/common/tmem_xen.c | 1 +
xen/include/xen/tmem_xen.h | 4 +++-
3 files changed, 16 insertions(+), 1 deletion(-)
diff -r 412a8c7d3721 -r bec27eb6f72c xen/common/tmem.c
--- a/xen/common/tmem.c Sat Nov 14 10:25:19 2009 +0000
+++ b/xen/common/tmem.c Sat Nov 14 10:32:59 2009 +0000
@@ -2229,6 +2229,12 @@ EXPORT long do_tmem_op(tmem_cli_op_t uop
DUP_START_CYC_COUNTER(flush,succ_get);
DUP_START_CYC_COUNTER(flush_obj,succ_get);
+ if ( client != NULL && tmh_client_is_dying(client) )
+ {
+ rc = -ENODEV;
+ goto out;
+ }
+
if ( unlikely(tmh_get_tmemop_from_client(&op, uops) != 0) )
{
printk("tmem: can't get tmem struct from %s\n",client_str);
@@ -2392,6 +2398,12 @@ EXPORT void tmem_destroy(void *v)
if ( client == NULL )
return;
+ if ( !tmh_client_is_dying(client) )
+ {
+ printk("tmem: tmem_destroy can only destroy dying client\n");
+ return;
+ }
+
if ( tmh_lock_all )
spin_lock(&tmem_spinlock);
else
diff -r 412a8c7d3721 -r bec27eb6f72c xen/common/tmem_xen.c
--- a/xen/common/tmem_xen.c Sat Nov 14 10:25:19 2009 +0000
+++ b/xen/common/tmem_xen.c Sat Nov 14 10:32:59 2009 +0000
@@ -314,6 +314,7 @@ EXPORT void tmh_client_destroy(tmh_clien
#ifndef __i386__
xmem_pool_destroy(tmh->persistent_pool);
#endif
+ put_domain(tmh->domain);
xfree(tmh);
}
diff -r 412a8c7d3721 -r bec27eb6f72c xen/include/xen/tmem_xen.h
--- a/xen/include/xen/tmem_xen.h Sat Nov 14 10:25:19 2009 +0000
+++ b/xen/include/xen/tmem_xen.h Sat Nov 14 10:32:59 2009 +0000
@@ -280,7 +280,7 @@ typedef struct page_info pfp_t;
/* this appears to be unreliable when a domain is being shut down */
static inline struct client *tmh_client_from_cli_id(cli_id_t cli_id)
{
- struct domain *d = get_domain_by_id(cli_id);
+ struct domain *d = get_domain_by_id(cli_id); /* incs d->refcnt! */
if (d == NULL)
return NULL;
return (struct client *)(d->tmem);
@@ -290,6 +290,8 @@ static inline struct client *tmh_client_
{
return (struct client *)(current->domain->tmem);
}
+
+#define tmh_client_is_dying(_client) (!!_client->tmh->domain->is_dying)
static inline cli_id_t tmh_get_cli_id_from_current(void)
{
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|