diff mbox series

[v2,net] hv_netvsc: Add the support of hibernation

Message ID 1569449034-29924-1-git-send-email-decui@microsoft.com
State Deferred
Delegated to: David Miller
Headers show
Series [v2,net] hv_netvsc: Add the support of hibernation | expand

Commit Message

Dexuan Cui Sept. 25, 2019, 10:04 p.m. UTC
The existing netvsc_detach() and netvsc_attach() APIs make it easy to
implement the suspend/resume callbacks.

Signed-off-by: Dexuan Cui <decui@microsoft.com>
---

This patch is basically a pure Hyper-V specific change. I request this
patch should go through Sasha's Hyper-V tree rather than the net tree.

Sasha's Hyper-V tree is here:
https://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git

Previously there was a dependency on the commit 271b2224d42f ("Drivers:
hv: vmbus: Implement suspend/resume for VSC drivers for hibernation"),
which was only on Sasha Levin's Hyper-V tree's hyperv-next branch:
https://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git/log/?h=hyperv-next
. Now the patch has been merged into Linus's master tree, but as of now,
the patch (271b2224d42f) has not appeared in the net.git tree, so IMO
it's better for this patch to go through the Hyper-V tree. The added
code in this patch is unlikely to cause a conflict.

In v2:
    Removed the superfluous "cancel_work_sync(&nvdev->subchan_work)".

    Changed the [PATCH net-next] to [PATCH net] in the Subject, because
    IMO this is more of a bug fix rather than a new feaure.

    No other change.

 drivers/net/hyperv/hyperv_net.h |  3 ++
 drivers/net/hyperv/netvsc_drv.c | 57 +++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

Comments

Haiyang Zhang Sept. 25, 2019, 10:23 p.m. UTC | #1
> -----Original Message-----
> From: Dexuan Cui <decui@microsoft.com>
> Sent: Wednesday, September 25, 2019 6:04 PM
> To: KY Srinivasan <kys@microsoft.com>; Haiyang Zhang
> <haiyangz@microsoft.com>; Stephen Hemminger
> <sthemmin@microsoft.com>; sashal@kernel.org; davem@davemloft.net;
> linux-hyperv@vger.kernel.org; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; Michael Kelley <mikelley@microsoft.com>
> Cc: Dexuan Cui <decui@microsoft.com>
> Subject: [PATCH v2][PATCH net] hv_netvsc: Add the support of hibernation
> 
> The existing netvsc_detach() and netvsc_attach() APIs make it easy to
> implement the suspend/resume callbacks.
> 
> Signed-off-by: Dexuan Cui <decui@microsoft.com>

Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
Dexuan Cui Sept. 27, 2019, 4:39 a.m. UTC | #2
> From: linux-hyperv-owner@vger.kernel.org
> <linux-hyperv-owner@vger.kernel.org> On Behalf Of kbuild test robot
> Sent: Thursday, September 26, 2019 9:18 PM
> 
> Hi Dexuan,
> 
> Thank you for the patch! Yet something to improve:
> 
> [auto build test ERROR on net/master]
> 
> 'netvsc_drv.shutdown')
> >> drivers/net/hyperv/netvsc_drv.c:2487:3: error: 'struct hv_driver' has no
> member named 'resume'; did you mean 'remove'?
>      .resume = netvsc_resume,
>       ^~~~~~

This is a false alarm. Your code base needs to be merged with the latest 
Linus's tree, which has the prerequisite patch:
271b2224d42f ("Drivers: hv: vmbus: Implement suspend/resume for VSC drivers for hibernation")

Thanks,
-- Dexuan
Sasha Levin Oct. 1, 2019, 6:59 p.m. UTC | #3
On Wed, Sep 25, 2019 at 10:23:28PM +0000, Haiyang Zhang wrote:
>
>
>> -----Original Message-----
>> From: Dexuan Cui <decui@microsoft.com>
>> Sent: Wednesday, September 25, 2019 6:04 PM
>> To: KY Srinivasan <kys@microsoft.com>; Haiyang Zhang
>> <haiyangz@microsoft.com>; Stephen Hemminger
>> <sthemmin@microsoft.com>; sashal@kernel.org; davem@davemloft.net;
>> linux-hyperv@vger.kernel.org; netdev@vger.kernel.org; linux-
>> kernel@vger.kernel.org; Michael Kelley <mikelley@microsoft.com>
>> Cc: Dexuan Cui <decui@microsoft.com>
>> Subject: [PATCH v2][PATCH net] hv_netvsc: Add the support of hibernation
>>
>> The existing netvsc_detach() and netvsc_attach() APIs make it easy to
>> implement the suspend/resume callbacks.
>>
>> Signed-off-by: Dexuan Cui <decui@microsoft.com>
>
>Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>

Queued up for hyperv-next, thanks!

--
Thanks,
Sasha
diff mbox series

Patch

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index ecc9af050387..b8763ee4c0d0 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -952,6 +952,9 @@  struct net_device_context {
 	u32 vf_alloc;
 	/* Serial number of the VF to team with */
 	u32 vf_serial;
+
+	/* Used to temporarily save the config info across hibernation */
+	struct netvsc_device_info *saved_netvsc_dev_info;
 };
 
 /* Per channel data */
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index afdcc5664ea6..53a9451a58a7 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -2392,6 +2392,61 @@  static int netvsc_remove(struct hv_device *dev)
 	return 0;
 }
 
+static int netvsc_suspend(struct hv_device *dev)
+{
+	struct net_device_context *ndev_ctx;
+	struct net_device *vf_netdev, *net;
+	struct netvsc_device *nvdev;
+	int ret;
+
+	net = hv_get_drvdata(dev);
+
+	ndev_ctx = netdev_priv(net);
+	cancel_delayed_work_sync(&ndev_ctx->dwork);
+
+	rtnl_lock();
+
+	nvdev = rtnl_dereference(ndev_ctx->nvdev);
+	if (nvdev == NULL) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev);
+	if (vf_netdev)
+		netvsc_unregister_vf(vf_netdev);
+
+	/* Save the current config info */
+	ndev_ctx->saved_netvsc_dev_info = netvsc_devinfo_get(nvdev);
+
+	ret = netvsc_detach(net, nvdev);
+out:
+	rtnl_unlock();
+
+	return ret;
+}
+
+static int netvsc_resume(struct hv_device *dev)
+{
+	struct net_device *net = hv_get_drvdata(dev);
+	struct net_device_context *net_device_ctx;
+	struct netvsc_device_info *device_info;
+	int ret;
+
+	rtnl_lock();
+
+	net_device_ctx = netdev_priv(net);
+	device_info = net_device_ctx->saved_netvsc_dev_info;
+
+	ret = netvsc_attach(net, device_info);
+
+	rtnl_unlock();
+
+	kfree(device_info);
+	net_device_ctx->saved_netvsc_dev_info = NULL;
+
+	return ret;
+}
 static const struct hv_vmbus_device_id id_table[] = {
 	/* Network guid */
 	{ HV_NIC_GUID, },
@@ -2406,6 +2461,8 @@  static struct  hv_driver netvsc_drv = {
 	.id_table = id_table,
 	.probe = netvsc_probe,
 	.remove = netvsc_remove,
+	.suspend = netvsc_suspend,
+	.resume = netvsc_resume,
 	.driver = {
 		.probe_type = PROBE_FORCE_SYNCHRONOUS,
 	},