aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2014-04-04 14:53:40 -0400
committerDavid Vrabel <david.vrabel@citrix.com>2014-04-15 12:41:28 -0400
commit027bd7e89906a076225b23d1ca4b6702c84e72dc (patch)
tree622c4232c082e9641024b6e2117c3bc5182362a9 /drivers/xen
parente0fc17a936334c08b2729fff87168c03fdecf5b6 (diff)
xen/xenbus: Avoid synchronous wait on XenBus stalling shutdown/restart.
The 'read_reply' works with 'process_msg' to read of a reply in XenBus. 'process_msg' is running from within the 'xenbus' thread. Whenever a message shows up in XenBus it is put on a xs_state.reply_list list and 'read_reply' picks it up. The problem is if the backend domain or the xenstored process is killed. In which case 'xenbus' is still awaiting - and 'read_reply' if called - stuck forever waiting for the reply_list to have some contents. This is normally not a problem - as the backend domain can come back or the xenstored process can be restarted. However if the domain is in process of being powered off/restarted/halted - there is no point of waiting on it coming back - as we are effectively being terminated and should not impede the progress. This patch solves this problem by checking whether the guest is the right domain. If it is an initial domain and hurtling towards death - there is no point of continuing the wait. All other type of guests continue with their behavior (as Xenstore is expected to still be running in another domain). Fixes-Bug: http://bugs.xenproject.org/xen/bug/8 Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Reviewed-by: David Vrabel <david.vrabel@citrix.com> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/xenbus/xenbus_xs.c44
1 files changed, 41 insertions, 3 deletions
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c
index b6d5fff43d16..ba804f3d8278 100644
--- a/drivers/xen/xenbus/xenbus_xs.c
+++ b/drivers/xen/xenbus/xenbus_xs.c
@@ -50,6 +50,7 @@
50#include <xen/xenbus.h> 50#include <xen/xenbus.h>
51#include <xen/xen.h> 51#include <xen/xen.h>
52#include "xenbus_comms.h" 52#include "xenbus_comms.h"
53#include "xenbus_probe.h"
53 54
54struct xs_stored_msg { 55struct xs_stored_msg {
55 struct list_head list; 56 struct list_head list;
@@ -139,6 +140,29 @@ static int get_error(const char *errorstring)
139 return xsd_errors[i].errnum; 140 return xsd_errors[i].errnum;
140} 141}
141 142
143static bool xenbus_ok(void)
144{
145 switch (xen_store_domain_type) {
146 case XS_LOCAL:
147 switch (system_state) {
148 case SYSTEM_POWER_OFF:
149 case SYSTEM_RESTART:
150 case SYSTEM_HALT:
151 return false;
152 default:
153 break;
154 }
155 return true;
156 case XS_PV:
157 case XS_HVM:
158 /* FIXME: Could check that the remote domain is alive,
159 * but it is normally initial domain. */
160 return true;
161 default:
162 break;
163 }
164 return false;
165}
142static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len) 166static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
143{ 167{
144 struct xs_stored_msg *msg; 168 struct xs_stored_msg *msg;
@@ -148,9 +172,20 @@ static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
148 172
149 while (list_empty(&xs_state.reply_list)) { 173 while (list_empty(&xs_state.reply_list)) {
150 spin_unlock(&xs_state.reply_lock); 174 spin_unlock(&xs_state.reply_lock);
151 /* XXX FIXME: Avoid synchronous wait for response here. */ 175 if (xenbus_ok())
152 wait_event(xs_state.reply_waitq, 176 /* XXX FIXME: Avoid synchronous wait for response here. */
153 !list_empty(&xs_state.reply_list)); 177 wait_event_timeout(xs_state.reply_waitq,
178 !list_empty(&xs_state.reply_list),
179 msecs_to_jiffies(500));
180 else {
181 /*
182 * If we are in the process of being shut-down there is
183 * no point of trying to contact XenBus - it is either
184 * killed (xenstored application) or the other domain
185 * has been killed or is unreachable.
186 */
187 return ERR_PTR(-EIO);
188 }
154 spin_lock(&xs_state.reply_lock); 189 spin_lock(&xs_state.reply_lock);
155 } 190 }
156 191
@@ -215,6 +250,9 @@ void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
215 250
216 mutex_unlock(&xs_state.request_mutex); 251 mutex_unlock(&xs_state.request_mutex);
217 252
253 if (IS_ERR(ret))
254 return ret;
255
218 if ((msg->type == XS_TRANSACTION_END) || 256 if ((msg->type == XS_TRANSACTION_END) ||
219 ((req_msg.type == XS_TRANSACTION_START) && 257 ((req_msg.type == XS_TRANSACTION_START) &&
220 (msg->type == XS_ERROR))) 258 (msg->type == XS_ERROR)))