Commit 6123c668 authored by stephen hemminger's avatar stephen hemminger Committed by David S. Miller

netvsc: delay setup of VF device

When VF device is discovered, delay bring it automatically up in
order to allow userspace to some simple changes (like renaming).
Reported-by: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: default avatarStephen Hemminger <sthemmin@microsoft.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d18c2a1b
...@@ -723,7 +723,7 @@ struct net_device_context { ...@@ -723,7 +723,7 @@ struct net_device_context {
/* State to manage the associated VF interface. */ /* State to manage the associated VF interface. */
struct net_device __rcu *vf_netdev; struct net_device __rcu *vf_netdev;
struct netvsc_vf_pcpu_stats __percpu *vf_stats; struct netvsc_vf_pcpu_stats __percpu *vf_stats;
struct work_struct vf_takeover; struct delayed_work vf_takeover;
/* 1: allocated, serial number is valid. 0: not allocated */ /* 1: allocated, serial number is valid. 0: not allocated */
u32 vf_alloc; u32 vf_alloc;
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#define RING_SIZE_MIN 64 #define RING_SIZE_MIN 64
#define LINKCHANGE_INT (2 * HZ) #define LINKCHANGE_INT (2 * HZ)
#define VF_TAKEOVER_INT (HZ / 10)
static int ring_size = 128; static int ring_size = 128;
module_param(ring_size, int, S_IRUGO); module_param(ring_size, int, S_IRUGO);
...@@ -1559,7 +1560,9 @@ static int netvsc_vf_join(struct net_device *vf_netdev, ...@@ -1559,7 +1560,9 @@ static int netvsc_vf_join(struct net_device *vf_netdev,
/* set slave flag before open to prevent IPv6 addrconf */ /* set slave flag before open to prevent IPv6 addrconf */
vf_netdev->flags |= IFF_SLAVE; vf_netdev->flags |= IFF_SLAVE;
schedule_work(&ndev_ctx->vf_takeover); schedule_delayed_work(&ndev_ctx->vf_takeover, VF_TAKEOVER_INT);
call_netdevice_notifiers(NETDEV_JOIN, vf_netdev);
netdev_info(vf_netdev, "joined to %s\n", ndev->name); netdev_info(vf_netdev, "joined to %s\n", ndev->name);
return 0; return 0;
...@@ -1575,8 +1578,6 @@ static void __netvsc_vf_setup(struct net_device *ndev, ...@@ -1575,8 +1578,6 @@ static void __netvsc_vf_setup(struct net_device *ndev,
{ {
int ret; int ret;
call_netdevice_notifiers(NETDEV_JOIN, vf_netdev);
/* Align MTU of VF with master */ /* Align MTU of VF with master */
ret = dev_set_mtu(vf_netdev, ndev->mtu); ret = dev_set_mtu(vf_netdev, ndev->mtu);
if (ret) if (ret)
...@@ -1597,12 +1598,12 @@ static void __netvsc_vf_setup(struct net_device *ndev, ...@@ -1597,12 +1598,12 @@ static void __netvsc_vf_setup(struct net_device *ndev,
static void netvsc_vf_setup(struct work_struct *w) static void netvsc_vf_setup(struct work_struct *w)
{ {
struct net_device_context *ndev_ctx struct net_device_context *ndev_ctx
= container_of(w, struct net_device_context, vf_takeover); = container_of(w, struct net_device_context, vf_takeover.work);
struct net_device *ndev = hv_get_drvdata(ndev_ctx->device_ctx); struct net_device *ndev = hv_get_drvdata(ndev_ctx->device_ctx);
struct net_device *vf_netdev; struct net_device *vf_netdev;
if (!rtnl_trylock()) { if (!rtnl_trylock()) {
schedule_work(w); schedule_delayed_work(&ndev_ctx->vf_takeover, 0);
return; return;
} }
...@@ -1706,7 +1707,7 @@ static int netvsc_unregister_vf(struct net_device *vf_netdev) ...@@ -1706,7 +1707,7 @@ static int netvsc_unregister_vf(struct net_device *vf_netdev)
return NOTIFY_DONE; return NOTIFY_DONE;
net_device_ctx = netdev_priv(ndev); net_device_ctx = netdev_priv(ndev);
cancel_work_sync(&net_device_ctx->vf_takeover); cancel_delayed_work_sync(&net_device_ctx->vf_takeover);
netdev_info(ndev, "VF unregistering: %s\n", vf_netdev->name); netdev_info(ndev, "VF unregistering: %s\n", vf_netdev->name);
...@@ -1748,7 +1749,7 @@ static int netvsc_probe(struct hv_device *dev, ...@@ -1748,7 +1749,7 @@ static int netvsc_probe(struct hv_device *dev,
spin_lock_init(&net_device_ctx->lock); spin_lock_init(&net_device_ctx->lock);
INIT_LIST_HEAD(&net_device_ctx->reconfig_events); INIT_LIST_HEAD(&net_device_ctx->reconfig_events);
INIT_WORK(&net_device_ctx->vf_takeover, netvsc_vf_setup); INIT_DELAYED_WORK(&net_device_ctx->vf_takeover, netvsc_vf_setup);
net_device_ctx->vf_stats net_device_ctx->vf_stats
= netdev_alloc_pcpu_stats(struct netvsc_vf_pcpu_stats); = netdev_alloc_pcpu_stats(struct netvsc_vf_pcpu_stats);
......
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