RE: [PATCH][PATCH net-next] hv_netvsc: Add the support of hibernation
> From: Haiyang Zhang > Sent: Thursday, September 12, 2019 6:50 AM > > -Original Message- > > From: Dexuan Cui > > Sent: Wednesday, September 11, 2019 7:38 PM > > +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; > > + } > > + > > + cancel_work_sync(&nvdev->subchan_work); > > This looks redundant because netvsc_detach() cancels subchan_work. > - Haiyang You are right. I'll remove the superflous line cancel_work_sync(&nvdev->subchan_work); in netvsc_suspend() in v2. I'll wait for a few days before posting v2, in case people may have other comments. Thanks, -- Dexuan
RE: [PATCH][PATCH net-next] hv_netvsc: Add the support of hibernation
> -Original Message- > From: Dexuan Cui > Sent: Wednesday, September 11, 2019 7:38 PM > To: KY Srinivasan ; Haiyang Zhang > ; Stephen Hemminger > ; sas...@kernel.org; da...@davemloft.net; > linux-hyp...@vger.kernel.org; net...@vger.kernel.org; linux- > ker...@vger.kernel.org; Michael Kelley > Cc: Dexuan Cui > Subject: [PATCH][PATCH net-next] 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 > --- > > This patch is basically a pure Hyper-V specific change and it has a > build dependency on the commit 271b2224d42f ("Drivers: hv: vmbus: > Implement > suspend/resume for VSC drivers for hibernation"), which is on Sasha Levin's > Hyper-V tree's hyperv-next branch: > https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.k > ernel.org%2Fpub%2Fscm%2Flinux%2Fkernel%2Fgit%2Fhyperv%2Flinux.git%2 > Flog%2F%3Fh%3Dhyperv- > next&data=02%7C01%7Chaiyangz%40microsoft.com%7C0b84e40c446 > 648cc35fb08d737110e28%7C72f988bf86f141af91ab2d7cd011db47%7C1%7 > C0%7C637038418703112019&sdata=qd7DGFCJZ%2BDTix0VGcCe1JucV > O97E0gILpVpcxlA6EE%3D&reserved=0 > > I request this patch should go through Sasha's tree rather than the > net-next tree. > > drivers/net/hyperv/hyperv_net.h | 3 +++ > drivers/net/hyperv/netvsc_drv.c | 59 > + > 2 files changed, 62 insertions(+) > > diff --git a/drivers/net/hyperv/hyperv_net.h > b/drivers/net/hyperv/hyperv_net.h > index ecc9af0..b8763ee 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 afdcc56..f920959 100644 > --- a/drivers/net/hyperv/netvsc_drv.c > +++ b/drivers/net/hyperv/netvsc_drv.c > @@ -2392,6 +2392,63 @@ 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; > + } > + > + cancel_work_sync(&nvdev->subchan_work); This looks redundant because netvsc_detach() cancels subchan_work. Thanks, - Haiyang
[PATCH][PATCH net-next] 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 --- This patch is basically a pure Hyper-V specific change and it has a build dependency on the commit 271b2224d42f ("Drivers: hv: vmbus: Implement suspend/resume for VSC drivers for hibernation"), which is 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 I request this patch should go through Sasha's tree rather than the net-next tree. drivers/net/hyperv/hyperv_net.h | 3 +++ drivers/net/hyperv/netvsc_drv.c | 59 + 2 files changed, 62 insertions(+) diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index ecc9af0..b8763ee 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 afdcc56..f920959 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -2392,6 +2392,63 @@ 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; + } + + cancel_work_sync(&nvdev->subchan_work); + + 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 +2463,8 @@ static int netvsc_remove(struct hv_device *dev) .id_table = id_table, .probe = netvsc_probe, .remove = netvsc_remove, + .suspend = netvsc_suspend, + .resume = netvsc_resume, .driver = { .probe_type = PROBE_FORCE_SYNCHRONOUS, }, -- 1.8.3.1