Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hv_netvsc: Register VF in netvsc_probe if NET_DEVICE_REGISTER missed

If hv_netvsc driver is unloaded and reloaded, the NET_DEVICE_REGISTER
handler cannot perform VF register successfully as the register call
is received before netvsc_probe is finished. This is because we
register register_netdevice_notifier() very early( even before
vmbus_driver_register()).
To fix this, we try to register each such matching VF( if it is visible
as a netdevice) at the end of netvsc_probe.

Cc: stable@vger.kernel.org
Fixes: 85520856466e ("hv_netvsc: Fix race of register_netdevice_notifier and VF register")
Suggested-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Shradha Gupta and committed by
David S. Miller
9cae43da b09b58e3

+62 -20
+62 -20
drivers/net/hyperv/netvsc_drv.c
··· 42 42 #define LINKCHANGE_INT (2 * HZ) 43 43 #define VF_TAKEOVER_INT (HZ / 10) 44 44 45 + /* Macros to define the context of vf registration */ 46 + #define VF_REG_IN_PROBE 1 47 + #define VF_REG_IN_NOTIFIER 2 48 + 45 49 static unsigned int ring_size __ro_after_init = 128; 46 50 module_param(ring_size, uint, 0444); 47 51 MODULE_PARM_DESC(ring_size, "Ring buffer size (# of 4K pages)"); ··· 2189 2185 } 2190 2186 2191 2187 static int netvsc_vf_join(struct net_device *vf_netdev, 2192 - struct net_device *ndev) 2188 + struct net_device *ndev, int context) 2193 2189 { 2194 2190 struct net_device_context *ndev_ctx = netdev_priv(ndev); 2195 2191 int ret; ··· 2212 2208 goto upper_link_failed; 2213 2209 } 2214 2210 2215 - schedule_delayed_work(&ndev_ctx->vf_takeover, VF_TAKEOVER_INT); 2211 + /* If this registration is called from probe context vf_takeover 2212 + * is taken care of later in probe itself. 2213 + */ 2214 + if (context == VF_REG_IN_NOTIFIER) 2215 + schedule_delayed_work(&ndev_ctx->vf_takeover, VF_TAKEOVER_INT); 2216 2216 2217 2217 call_netdevice_notifiers(NETDEV_JOIN, vf_netdev); 2218 2218 ··· 2354 2346 return NOTIFY_DONE; 2355 2347 } 2356 2348 2357 - static int netvsc_register_vf(struct net_device *vf_netdev) 2349 + static int netvsc_register_vf(struct net_device *vf_netdev, int context) 2358 2350 { 2359 2351 struct net_device_context *net_device_ctx; 2360 2352 struct netvsc_device *netvsc_dev; ··· 2394 2386 2395 2387 netdev_info(ndev, "VF registering: %s\n", vf_netdev->name); 2396 2388 2397 - if (netvsc_vf_join(vf_netdev, ndev) != 0) 2389 + if (netvsc_vf_join(vf_netdev, ndev, context) != 0) 2398 2390 return NOTIFY_DONE; 2399 2391 2400 2392 dev_hold(vf_netdev); ··· 2492 2484 return NOTIFY_OK; 2493 2485 } 2494 2486 2487 + static int check_dev_is_matching_vf(struct net_device *event_ndev) 2488 + { 2489 + /* Skip NetVSC interfaces */ 2490 + if (event_ndev->netdev_ops == &device_ops) 2491 + return -ENODEV; 2492 + 2493 + /* Avoid non-Ethernet type devices */ 2494 + if (event_ndev->type != ARPHRD_ETHER) 2495 + return -ENODEV; 2496 + 2497 + /* Avoid Vlan dev with same MAC registering as VF */ 2498 + if (is_vlan_dev(event_ndev)) 2499 + return -ENODEV; 2500 + 2501 + /* Avoid Bonding master dev with same MAC registering as VF */ 2502 + if (netif_is_bond_master(event_ndev)) 2503 + return -ENODEV; 2504 + 2505 + return 0; 2506 + } 2507 + 2495 2508 static int netvsc_probe(struct hv_device *dev, 2496 2509 const struct hv_vmbus_device_id *dev_id) 2497 2510 { 2498 - struct net_device *net = NULL; 2511 + struct net_device *net = NULL, *vf_netdev; 2499 2512 struct net_device_context *net_device_ctx; 2500 2513 struct netvsc_device_info *device_info = NULL; 2501 2514 struct netvsc_device *nvdev; ··· 2628 2599 } 2629 2600 2630 2601 list_add(&net_device_ctx->list, &netvsc_dev_list); 2602 + 2603 + /* When the hv_netvsc driver is unloaded and reloaded, the 2604 + * NET_DEVICE_REGISTER for the vf device is replayed before probe 2605 + * is complete. This is because register_netdevice_notifier() gets 2606 + * registered before vmbus_driver_register() so that callback func 2607 + * is set before probe and we don't miss events like NETDEV_POST_INIT 2608 + * So, in this section we try to register the matching vf device that 2609 + * is present as a netdevice, knowing that its register call is not 2610 + * processed in the netvsc_netdev_notifier(as probing is progress and 2611 + * get_netvsc_byslot fails). 2612 + */ 2613 + for_each_netdev(dev_net(net), vf_netdev) { 2614 + ret = check_dev_is_matching_vf(vf_netdev); 2615 + if (ret != 0) 2616 + continue; 2617 + 2618 + if (net != get_netvsc_byslot(vf_netdev)) 2619 + continue; 2620 + 2621 + netvsc_prepare_bonding(vf_netdev); 2622 + netvsc_register_vf(vf_netdev, VF_REG_IN_PROBE); 2623 + __netvsc_vf_setup(net, vf_netdev); 2624 + break; 2625 + } 2631 2626 rtnl_unlock(); 2632 2627 2633 2628 netvsc_devinfo_put(device_info); ··· 2807 2754 unsigned long event, void *ptr) 2808 2755 { 2809 2756 struct net_device *event_dev = netdev_notifier_info_to_dev(ptr); 2757 + int ret = 0; 2810 2758 2811 - /* Skip our own events */ 2812 - if (event_dev->netdev_ops == &device_ops) 2813 - return NOTIFY_DONE; 2814 - 2815 - /* Avoid non-Ethernet type devices */ 2816 - if (event_dev->type != ARPHRD_ETHER) 2817 - return NOTIFY_DONE; 2818 - 2819 - /* Avoid Vlan dev with same MAC registering as VF */ 2820 - if (is_vlan_dev(event_dev)) 2821 - return NOTIFY_DONE; 2822 - 2823 - /* Avoid Bonding master dev with same MAC registering as VF */ 2824 - if (netif_is_bond_master(event_dev)) 2759 + ret = check_dev_is_matching_vf(event_dev); 2760 + if (ret != 0) 2825 2761 return NOTIFY_DONE; 2826 2762 2827 2763 switch (event) { 2828 2764 case NETDEV_POST_INIT: 2829 2765 return netvsc_prepare_bonding(event_dev); 2830 2766 case NETDEV_REGISTER: 2831 - return netvsc_register_vf(event_dev); 2767 + return netvsc_register_vf(event_dev, VF_REG_IN_NOTIFIER); 2832 2768 case NETDEV_UNREGISTER: 2833 2769 return netvsc_unregister_vf(event_dev); 2834 2770 case NETDEV_UP: