Commit 00acc505 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'hyperv-fixes-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux

Pull hyperv fixes from Wei Liu:
 "Two patches from Michael and Dexuan to fix vmbus hanging issues"

* tag 'hyperv-fixes-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux:
  Drivers: hv: vmbus: Add timeout to vmbus_wait_for_unload
  Drivers: hv: vmbus: hibernation: do not hang forever in vmbus_bus_resume()
parents fc4f28bb 911e1987
...@@ -731,7 +731,7 @@ static void vmbus_wait_for_unload(void) ...@@ -731,7 +731,7 @@ static void vmbus_wait_for_unload(void)
void *page_addr; void *page_addr;
struct hv_message *msg; struct hv_message *msg;
struct vmbus_channel_message_header *hdr; struct vmbus_channel_message_header *hdr;
u32 message_type; u32 message_type, i;
/* /*
* CHANNELMSG_UNLOAD_RESPONSE is always delivered to the CPU which was * CHANNELMSG_UNLOAD_RESPONSE is always delivered to the CPU which was
...@@ -741,8 +741,11 @@ static void vmbus_wait_for_unload(void) ...@@ -741,8 +741,11 @@ static void vmbus_wait_for_unload(void)
* functional and vmbus_unload_response() will complete * functional and vmbus_unload_response() will complete
* vmbus_connection.unload_event. If not, the last thing we can do is * vmbus_connection.unload_event. If not, the last thing we can do is
* read message pages for all CPUs directly. * read message pages for all CPUs directly.
*
* Wait no more than 10 seconds so that the panic path can't get
* hung forever in case the response message isn't seen.
*/ */
while (1) { for (i = 0; i < 1000; i++) {
if (completion_done(&vmbus_connection.unload_event)) if (completion_done(&vmbus_connection.unload_event))
break; break;
......
...@@ -2382,7 +2382,10 @@ static int vmbus_bus_suspend(struct device *dev) ...@@ -2382,7 +2382,10 @@ static int vmbus_bus_suspend(struct device *dev)
if (atomic_read(&vmbus_connection.nr_chan_close_on_suspend) > 0) if (atomic_read(&vmbus_connection.nr_chan_close_on_suspend) > 0)
wait_for_completion(&vmbus_connection.ready_for_suspend_event); wait_for_completion(&vmbus_connection.ready_for_suspend_event);
WARN_ON(atomic_read(&vmbus_connection.nr_chan_fixup_on_resume) != 0); if (atomic_read(&vmbus_connection.nr_chan_fixup_on_resume) != 0) {
pr_err("Can not suspend due to a previous failed resuming\n");
return -EBUSY;
}
mutex_lock(&vmbus_connection.channel_mutex); mutex_lock(&vmbus_connection.channel_mutex);
...@@ -2456,7 +2459,9 @@ static int vmbus_bus_resume(struct device *dev) ...@@ -2456,7 +2459,9 @@ static int vmbus_bus_resume(struct device *dev)
vmbus_request_offers(); vmbus_request_offers();
wait_for_completion(&vmbus_connection.ready_for_resume_event); if (wait_for_completion_timeout(
&vmbus_connection.ready_for_resume_event, 10 * HZ) == 0)
pr_err("Some vmbus device is missing after suspending?\n");
/* Reset the event for the next suspend. */ /* Reset the event for the next suspend. */
reinit_completion(&vmbus_connection.ready_for_suspend_event); reinit_completion(&vmbus_connection.ready_for_suspend_event);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment