[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-3.1-testing] Avoid deadlock when unregistering a xenbus watch.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1206978517 -3600 # Node ID a7c923d6cf228ecb32619280488385b71377cf17 # Parent 456421041d9ab8ae56ee28b8e0228fd44f10837e Avoid deadlock when unregistering a xenbus watch. Watch handlers which run in a separate thread (XBWF_new_thread) should run without the xenbus_mutex held since kthread_run can block waiting for memory which causes a deadlock if further watches need to be unregistered in order to activate the swap device on resume. XBWF_new_thread cannot be safely unregistered anyway since the mutex only protects thread startup. Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> linux-2.6.18-xen changeset: 498:0637d22ed554eb0b9cecc7a74fa0a77a7c456497 linux-2.6.18-xen date: Fri Mar 28 09:49:22 2008 +0000 --- linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c | 31 ++++++++++++++------ 1 files changed, 23 insertions(+), 8 deletions(-) diff -r 456421041d9a -r a7c923d6cf22 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Mon Mar 31 16:48:17 2008 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Mon Mar 31 16:48:37 2008 +0100 @@ -629,6 +629,8 @@ void unregister_xenbus_watch(struct xenb char token[sizeof(watch) * 2 + 1]; int err; + BUG_ON(watch->flags & XBWF_new_thread); + sprintf(token, "%lX", (long)watch); down_read(&xs_state.watch_mutex); @@ -738,16 +740,29 @@ static int xenwatch_thread(void *unused) list_del(ent); spin_unlock(&watch_events_lock); - if (ent != &watch_events) { - msg = list_entry(ent, struct xs_stored_msg, list); - if (msg->u.watch.handle->flags & XBWF_new_thread) - kthread_run(xenwatch_handle_callback, - msg, "xenwatch_cb"); - else - xenwatch_handle_callback(msg); + if (ent == &watch_events) { + mutex_unlock(&xenwatch_mutex); + continue; } - mutex_unlock(&xenwatch_mutex); + msg = list_entry(ent, struct xs_stored_msg, list); + + /* + * Unlock the mutex before running an XBWF_new_thread + * handler. kthread_run can block which can deadlock + * against unregister_xenbus_watch() if we need to + * unregister other watches in order to make + * progress. This can occur on resume before the swap + * device is attached. + */ + if (msg->u.watch.handle->flags & XBWF_new_thread) { + mutex_unlock(&xenwatch_mutex); + kthread_run(xenwatch_handle_callback, + msg, "xenwatch_cb"); + } else { + xenwatch_handle_callback(msg); + mutex_unlock(&xenwatch_mutex); + } } return 0; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |