On 2025-05-21 at 10:25:03, Saurabh Sengar (ssen...@linux.microsoft.com) wrote: > The MANA driver's probe registers netdevice via the following call chain: > > mana_probe() > register_netdev() > register_netdevice() > > register_netdevice() calls notifier callback for netvsc driver, > holding the netdev mutex via netdev_lock_ops(). > > Further this netvsc notifier callback end up attempting to acquire the > same lock again in dev_xdp_propagate() leading to deadlock. > > netvsc_netdev_event() > netvsc_vf_setxdp() > dev_xdp_propagate() > > This deadlock was not observed so far because net_shaper_ops was never set, > and thus the lock was effectively a no-op in this case. Fix this by using > netif_xdp_propagate() instead of dev_xdp_propagate() to avoid recursive > locking in this path. > > Also, clean up the unregistration path by removing the unnecessary call to > netvsc_vf_setxdp(), since unregister_netdevice_many_notify() already > performs this cleanup via dev_xdp_uninstall(). > > Fixes: 97246d6d21c2 ("net: hold netdev instance lock during ndo_bpf") > Cc: sta...@vger.kernel.org > Signed-off-by: Saurabh Sengar <ssen...@linux.microsoft.com> > Tested-by: Erni Sri Satya Vennela <er...@linux.microsoft.com> > Reviewed-by: Haiyang Zhang <haiya...@microsoft.com>
Reviewed-by: Subbaraya Sundeep <sbha...@marvell.com> Thanks, Sundeep > --- > [V2] > - Modified commit message > > drivers/net/hyperv/netvsc_bpf.c | 2 +- > drivers/net/hyperv/netvsc_drv.c | 2 -- > net/core/dev.c | 1 + > 3 files changed, 2 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/hyperv/netvsc_bpf.c b/drivers/net/hyperv/netvsc_bpf.c > index e01c5997a551..1dd3755d9e6d 100644 > --- a/drivers/net/hyperv/netvsc_bpf.c > +++ b/drivers/net/hyperv/netvsc_bpf.c > @@ -183,7 +183,7 @@ int netvsc_vf_setxdp(struct net_device *vf_netdev, struct > bpf_prog *prog) > xdp.command = XDP_SETUP_PROG; > xdp.prog = prog; > > - ret = dev_xdp_propagate(vf_netdev, &xdp); > + ret = netif_xdp_propagate(vf_netdev, &xdp); > > if (ret && prog) > bpf_prog_put(prog); > diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c > index d8b169ac0343..ee3aaf9c10e6 100644 > --- a/drivers/net/hyperv/netvsc_drv.c > +++ b/drivers/net/hyperv/netvsc_drv.c > @@ -2462,8 +2462,6 @@ static int netvsc_unregister_vf(struct net_device > *vf_netdev) > > netdev_info(ndev, "VF unregistering: %s\n", vf_netdev->name); > > - netvsc_vf_setxdp(vf_netdev, NULL); > - > reinit_completion(&net_device_ctx->vf_add); > netdev_rx_handler_unregister(vf_netdev); > netdev_upper_dev_unlink(vf_netdev, ndev); > diff --git a/net/core/dev.c b/net/core/dev.c > index fccf2167b235..8c6c9d7fba26 100644 > --- a/net/core/dev.c > +++ b/net/core/dev.c > @@ -9953,6 +9953,7 @@ int netif_xdp_propagate(struct net_device *dev, struct > netdev_bpf *bpf) > > return dev->netdev_ops->ndo_bpf(dev, bpf); > } > +EXPORT_SYMBOL_GPL(netif_xdp_propagate); > > u32 dev_xdp_prog_id(struct net_device *dev, enum bpf_xdp_mode mode) > { > -- > 2.43.0 >