in google/gve/gve_main.c [1561:1599]
static int gve_set_xdp(struct gve_priv *priv, struct bpf_prog *prog,
struct netlink_ext_ack *extack)
{
struct bpf_prog *old_prog;
int err = 0;
u32 status;
old_prog = READ_ONCE(priv->xdp_prog);
if (!netif_running(priv->dev)) {
WRITE_ONCE(priv->xdp_prog, prog);
if (old_prog)
bpf_prog_put(old_prog);
return 0;
}
gve_turndown(priv);
if (!old_prog && prog) {
// Allocate XDP TX queues if an XDP program is
// being installed
err = gve_add_xdp_queues(priv);
if (err)
goto out;
} else if (old_prog && !prog) {
// Remove XDP TX queues if an XDP program is
// being uninstalled
err = gve_remove_xdp_queues(priv);
if (err)
goto out;
}
WRITE_ONCE(priv->xdp_prog, prog);
if (old_prog)
bpf_prog_put(old_prog);
out:
gve_turnup(priv);
status = ioread32be(&priv->reg_bar0->device_status);
gve_handle_link_status(priv, GVE_DEVICE_STATUS_LINK_STATUS_MASK & status);
return err;
}