Commit 00acc505 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -731,7 +731,7 @@ static void vmbus_wait_for_unload(void)
	void *page_addr;
	struct hv_message *msg;
	struct vmbus_channel_message_header *hdr;
	u32 message_type;
	u32 message_type, i;

	/*
	 * CHANNELMSG_UNLOAD_RESPONSE is always delivered to the CPU which was
@@ -741,8 +741,11 @@ static void vmbus_wait_for_unload(void)
	 * functional and vmbus_unload_response() will complete
	 * vmbus_connection.unload_event. If not, the last thing we can do is
	 * 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))
			break;

+7 −2
Original line number Diff line number Diff line
@@ -2382,7 +2382,10 @@ static int vmbus_bus_suspend(struct device *dev)
	if (atomic_read(&vmbus_connection.nr_chan_close_on_suspend) > 0)
		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);

@@ -2456,7 +2459,9 @@ static int vmbus_bus_resume(struct device *dev)

	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. */
	reinit_completion(&vmbus_connection.ready_for_suspend_event);