Skip to content

Commit bd0b2e7

Browse files
Jakub Kicinskiborkmann
authored andcommitted
net: xdp: make the stack take care of the tear down
Since day one of XDP drivers had to remember to free the program on the remove path. This leads to code duplication and is error prone. Make the stack query the installed programs on unregister and if something is installed, remove the program. Freeing of program attached to XDP generic is moved from free_netdev() as well. Because the remove will now be called before notifiers are invoked, BPF offload state of the program will not get destroyed before uninstall. Signed-off-by: Jakub Kicinski <[email protected]> Reviewed-by: Simon Horman <[email protected]> Reviewed-by: Quentin Monnet <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]>
1 parent 92f0292 commit bd0b2e7

File tree

7 files changed

+22
-30
lines changed

7 files changed

+22
-30
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7800,8 +7800,6 @@ static void bnxt_remove_one(struct pci_dev *pdev)
78007800
bnxt_dcb_free(bp);
78017801
kfree(bp->edev);
78027802
bp->edev = NULL;
7803-
if (bp->xdp_prog)
7804-
bpf_prog_put(bp->xdp_prog);
78057803
bnxt_cleanup_pci(bp);
78067804
free_netdev(dev);
78077805
}

drivers/net/ethernet/mellanox/mlx5/core/en_main.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4308,9 +4308,6 @@ static void mlx5e_nic_cleanup(struct mlx5e_priv *priv)
43084308
{
43094309
mlx5e_ipsec_cleanup(priv);
43104310
mlx5e_vxlan_cleanup(priv);
4311-
4312-
if (priv->channels.params.xdp_prog)
4313-
bpf_prog_put(priv->channels.params.xdp_prog);
43144311
}
43154312

43164313
static int mlx5e_init_nic_rx(struct mlx5e_priv *priv)

drivers/net/ethernet/netronome/nfp/bpf/main.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,6 @@ static const char *nfp_bpf_extra_cap(struct nfp_app *app, struct nfp_net *nn)
8282
return nfp_net_ebpf_capable(nn) ? "BPF" : "";
8383
}
8484

85-
static void nfp_bpf_vnic_free(struct nfp_app *app, struct nfp_net *nn)
86-
{
87-
if (nn->dp.bpf_offload_xdp)
88-
nfp_bpf_xdp_offload(app, nn, NULL);
89-
}
90-
9185
static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type,
9286
void *type_data, void *cb_priv)
9387
{
@@ -168,7 +162,6 @@ const struct nfp_app_type app_bpf = {
168162
.extra_cap = nfp_bpf_extra_cap,
169163

170164
.vnic_alloc = nfp_app_nic_vnic_alloc,
171-
.vnic_free = nfp_bpf_vnic_free,
172165

173166
.setup_tc = nfp_bpf_setup_tc,
174167
.tc_busy = nfp_bpf_tc_busy,

drivers/net/ethernet/netronome/nfp/nfp_net_common.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3562,9 +3562,6 @@ struct nfp_net *nfp_net_alloc(struct pci_dev *pdev, bool needs_netdev,
35623562
*/
35633563
void nfp_net_free(struct nfp_net *nn)
35643564
{
3565-
if (nn->xdp_prog)
3566-
bpf_prog_put(nn->xdp_prog);
3567-
35683565
if (nn->dp.netdev)
35693566
free_netdev(nn->dp.netdev);
35703567
else

drivers/net/ethernet/qlogic/qede/qede_main.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,10 +1068,6 @@ static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode)
10681068

10691069
pci_set_drvdata(pdev, NULL);
10701070

1071-
/* Release edev's reference to XDP's bpf if such exist */
1072-
if (edev->xdp_prog)
1073-
bpf_prog_put(edev->xdp_prog);
1074-
10751071
/* Use global ops since we've freed edev */
10761072
qed_ops->common->slowpath_stop(cdev);
10771073
if (system_state == SYSTEM_POWER_OFF)

drivers/net/tun.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,6 @@ static void tun_detach(struct tun_file *tfile, bool clean)
673673
static void tun_detach_all(struct net_device *dev)
674674
{
675675
struct tun_struct *tun = netdev_priv(dev);
676-
struct bpf_prog *xdp_prog = rtnl_dereference(tun->xdp_prog);
677676
struct tun_file *tfile, *tmp;
678677
int i, n = tun->numqueues;
679678

@@ -708,9 +707,6 @@ static void tun_detach_all(struct net_device *dev)
708707
}
709708
BUG_ON(tun->numdisabled != 0);
710709

711-
if (xdp_prog)
712-
bpf_prog_put(xdp_prog);
713-
714710
if (tun->flags & IFF_PERSIST)
715711
module_put(THIS_MODULE);
716712
}

net/core/dev.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7110,6 +7110,27 @@ static int dev_xdp_install(struct net_device *dev, bpf_op_t bpf_op,
71107110
return bpf_op(dev, &xdp);
71117111
}
71127112

7113+
static void dev_xdp_uninstall(struct net_device *dev)
7114+
{
7115+
struct netdev_bpf xdp;
7116+
bpf_op_t ndo_bpf;
7117+
7118+
/* Remove generic XDP */
7119+
WARN_ON(dev_xdp_install(dev, generic_xdp_install, NULL, 0, NULL));
7120+
7121+
/* Remove from the driver */
7122+
ndo_bpf = dev->netdev_ops->ndo_bpf;
7123+
if (!ndo_bpf)
7124+
return;
7125+
7126+
__dev_xdp_query(dev, ndo_bpf, &xdp);
7127+
if (xdp.prog_attached == XDP_ATTACHED_NONE)
7128+
return;
7129+
7130+
/* Program removal should always succeed */
7131+
WARN_ON(dev_xdp_install(dev, ndo_bpf, NULL, xdp.prog_flags, NULL));
7132+
}
7133+
71137134
/**
71147135
* dev_change_xdp_fd - set or clear a bpf program for a device rx path
71157136
* @dev: device
@@ -7240,6 +7261,7 @@ static void rollback_registered_many(struct list_head *head)
72407261
/* Shutdown queueing discipline. */
72417262
dev_shutdown(dev);
72427263

7264+
dev_xdp_uninstall(dev);
72437265

72447266
/* Notify protocols, that we are about to destroy
72457267
* this device. They should clean all the things.
@@ -8199,7 +8221,6 @@ EXPORT_SYMBOL(alloc_netdev_mqs);
81998221
void free_netdev(struct net_device *dev)
82008222
{
82018223
struct napi_struct *p, *n;
8202-
struct bpf_prog *prog;
82038224

82048225
might_sleep();
82058226
netif_free_tx_queues(dev);
@@ -8218,12 +8239,6 @@ void free_netdev(struct net_device *dev)
82188239
free_percpu(dev->pcpu_refcnt);
82198240
dev->pcpu_refcnt = NULL;
82208241

8221-
prog = rcu_dereference_protected(dev->xdp_prog, 1);
8222-
if (prog) {
8223-
bpf_prog_put(prog);
8224-
static_key_slow_dec(&generic_xdp_needed);
8225-
}
8226-
82278242
/* Compatibility with error handling in drivers */
82288243
if (dev->reg_state == NETREG_UNINITIALIZED) {
82298244
netdev_freemem(dev);

0 commit comments

Comments
 (0)