linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Dexuan Cui <decui@microsoft.com>
To: "linux-hyperv@vger.kernel.org" <linux-hyperv@vger.kernel.org>,
	"gregkh@linuxfoundation.org" <gregkh@linuxfoundation.org>,
	Stephen Hemminger <sthemmin@microsoft.com>,
	Sasha Levin <Alexander.Levin@microsoft.com>,
	"sashal@kernel.org" <sashal@kernel.org>,
	Haiyang Zhang <haiyangz@microsoft.com>,
	KY Srinivasan <kys@microsoft.com>,
	Michael Kelley <mikelley@microsoft.com>,
	"tglx@linutronix.de" <tglx@linutronix.de>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Dexuan Cui <decui@microsoft.com>
Subject: [PATCH v3 10/12] Drivers: hv: vmbus: Clean up hv_sock channels by force upon suspend
Date: Tue, 20 Aug 2019 01:52:07 +0000	[thread overview]
Message-ID: <1566265863-21252-11-git-send-email-decui@microsoft.com> (raw)
In-Reply-To: <1566265863-21252-1-git-send-email-decui@microsoft.com>

Fake RESCIND_CHANNEL messages to clean up hv_sock channels by force for
hibernation. There is no better method to clean up the channels since
some of the channels may still be referenced by the userspace apps when
hiberantin is triggered: in this case, the "rescind" fields of the
channels are set, and the apps will thoroughly destroy the channels
after hibernation.

Signed-off-by: Dexuan Cui <decui@microsoft.com>
---
 drivers/hv/vmbus_drv.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index ce9974b..2bea669 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -24,6 +24,7 @@
 #include <linux/sched/task_stack.h>
 
 #include <asm/mshyperv.h>
+#include <linux/delay.h>
 #include <linux/notifier.h>
 #include <linux/ptrace.h>
 #include <linux/screen_info.h>
@@ -1069,6 +1070,41 @@ void vmbus_on_msg_dpc(unsigned long data)
 	vmbus_signal_eom(msg, message_type);
 }
 
+/*
+ * Fake RESCIND_CHANNEL messages to clean up hv_sock channels by force for
+ * hibernation, because hv_sock connections can not persist across hibernation.
+ */
+static void vmbus_force_channel_rescinded(struct vmbus_channel *channel)
+{
+	struct onmessage_work_context *ctx;
+	struct vmbus_channel_rescind_offer *rescind;
+
+	WARN_ON(!is_hvsock_channel(channel));
+
+	/*
+	 * sizeof(*ctx) is small and the allocation should really not fail,
+	 * otherwise the state of the hv_sock connections ends up in limbo.
+	 */
+	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL | __GFP_NOFAIL);
+
+	/*
+	 * So far, these are not really used by Linux. Just set them to the
+	 * reasonable values conforming to the definitions of the fields.
+	 */
+	ctx->msg.header.message_type = 1;
+	ctx->msg.header.payload_size = sizeof(*rescind);
+
+	/* These values are actually used by Linux. */
+	rescind = (struct vmbus_channel_rescind_offer *)ctx->msg.u.payload;
+	rescind->header.msgtype = CHANNELMSG_RESCIND_CHANNELOFFER;
+	rescind->child_relid = channel->offermsg.child_relid;
+
+	INIT_WORK(&ctx->work, vmbus_onmessage_work);
+
+	queue_work_on(vmbus_connection.connect_cpu,
+		      vmbus_connection.work_queue,
+		      &ctx->work);
+}
 
 /*
  * Direct callback for channels using other deferred processing
@@ -2091,6 +2127,25 @@ static int vmbus_acpi_add(struct acpi_device *device)
 
 static int vmbus_bus_suspend(struct device *dev)
 {
+	struct vmbus_channel *channel;
+
+	while (atomic_read(&vmbus_connection.offer_in_progress) != 0) {
+		/*
+		 * We wait here until any channel offer is currently
+		 * being processed.
+		 */
+		msleep(1);
+	}
+
+	mutex_lock(&vmbus_connection.channel_mutex);
+	list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
+		if (!is_hvsock_channel(channel))
+			continue;
+
+		vmbus_force_channel_rescinded(channel);
+	}
+	mutex_unlock(&vmbus_connection.channel_mutex);
+
 	vmbus_initiate_unload(false);
 
 	vmbus_connection.conn_state = DISCONNECTED;
-- 
1.8.3.1


  parent reply	other threads:[~2019-08-20  1:52 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-20  1:51 [PATCH v3 00/12] Enhance the hv_vmbus driver to support hibernation Dexuan Cui
2019-08-20  1:51 ` [PATCH v3 01/12] x86/hyper-v: Suspend/resume the hypercall page for hibernation Dexuan Cui
2019-08-20  1:51 ` [PATCH v3 02/12] x86/hyper-v: Implement hv_is_hibernation_supported() Dexuan Cui
2019-08-23 19:50   ` Michael Kelley
2019-08-30 23:37     ` Dexuan Cui
2019-08-20  1:52 ` [PATCH v3 03/12] clocksource/drivers: Suspend/resume Hyper-V clocksource for hibernation Dexuan Cui
2019-08-20  1:52 ` [PATCH v3 04/12] Drivers: hv: vmbus: Break out synic enable and disable operations Dexuan Cui
2019-08-20  1:52 ` [PATCH v3 05/12] Drivers: hv: vmbus: Suspend/resume the synic for hibernation Dexuan Cui
2019-08-20  1:52 ` [PATCH v3 06/12] Drivers: hv: vmbus: Add a helper function is_sub_channel() Dexuan Cui
2019-08-23 19:51   ` Michael Kelley
2019-08-20  1:52 ` [PATCH v3 07/12] Drivers: hv: vmbus: Implement suspend/resume for VSC drivers for hibernation Dexuan Cui
2019-08-20  1:52 ` [PATCH v3 08/12] Drivers: hv: vmbus: Ignore the offers when resuming from hibernation Dexuan Cui
2019-08-23 19:56   ` Michael Kelley
2019-08-31  0:23     ` Dexuan Cui
2019-08-20  1:52 ` [PATCH v3 09/12] Drivers: hv: vmbus: Suspend/resume the vmbus itself for hibernation Dexuan Cui
2019-08-20  1:52 ` Dexuan Cui [this message]
2019-08-23 20:02   ` [PATCH v3 10/12] Drivers: hv: vmbus: Clean up hv_sock channels by force upon suspend Michael Kelley
2019-08-31  2:00     ` Dexuan Cui
2019-08-20  1:52 ` [PATCH v3 11/12] Drivers: hv: vmbus: Suspend after cleaning up hv_sock and sub channels Dexuan Cui
2019-08-23 20:16   ` Michael Kelley
2019-08-31  2:54     ` Dexuan Cui
2019-08-20  1:52 ` [PATCH v3 12/12] Drivers: hv: vmbus: Resume after fixing up old primary channels Dexuan Cui
2019-08-23 20:25   ` Michael Kelley
2019-08-31  4:37     ` Dexuan Cui
2019-08-31  5:08       ` Dexuan Cui

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1566265863-21252-11-git-send-email-decui@microsoft.com \
    --to=decui@microsoft.com \
    --cc=Alexander.Levin@microsoft.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=haiyangz@microsoft.com \
    --cc=kys@microsoft.com \
    --cc=linux-hyperv@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mikelley@microsoft.com \
    --cc=sashal@kernel.org \
    --cc=sthemmin@microsoft.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).