Exit code: 0 Wall time: 0.3 seconds Output: From 7691567e29d241f28d1525d99b11faa2d5831f3f Mon Sep 17 00:00:00 2001 From: Diego Fernando Mancera Gomez Date: Thu, 13 Aug 2026 23:03:56 -0600 Subject: [PATCH] net: stmmac: restore XDP configuration when reopen fails stmmac_xdp_set_prog() tears down the datapath of a running interface, replaces priv->xdp_prog and then ignores the return value of stmmac_xdp_open(). If reopening fails, the interface is left running without DMA descriptors, IRQs and queues while userspace is told the attach/detach succeeded. Propagate the reopen error and roll back the program swap on failure: quiesce the partially reopened datapath, restore the previous program, release the reference moved in for the new one, recompute the SPH state and try to reopen the device with the old configuration so the interface remains usable. Preserve the original reopen error and only log the failed restore attempt. Also update the XDP redirect-target feature only once the request succeeded. Fixes: ac746c8520d9 ("net: stmmac: enhance XDP ZC driver level switching performance") Signed-off-by: Diego Fernando Mancera Gomez diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c index d7e4db7224b0..c90a1eb2ed31 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c @@ -104,8 +104,10 @@ int stmmac_xdp_set_prog(struct stmmac_priv *priv, struct bpf_prog *prog, { struct net_device *dev = priv->dev; struct bpf_prog *old_prog; + struct bpf_prog *new_prog; bool need_update; bool if_running; + int ret = 0; if_running = netif_running(dev); @@ -117,25 +119,48 @@ int stmmac_xdp_set_prog(struct stmmac_priv *priv, struct bpf_prog *prog, return -EOPNOTSUPP; } - if (!prog) - xdp_features_clear_redirect_target(dev); - need_update = !!priv->xdp_prog != !!prog; if (if_running && need_update) stmmac_xdp_release(dev); old_prog = xchg(&priv->xdp_prog, prog); - if (old_prog) - bpf_prog_put(old_prog); /* Disable RX SPH for XDP operation */ priv->sph_active = priv->sph_capable && !stmmac_xdp_is_enabled(priv); - if (if_running && need_update) - stmmac_xdp_open(dev); + if (if_running && need_update) { + ret = stmmac_xdp_open(dev); + if (ret) { + /* stmmac_xdp_release() tore down the datapath and + * reopening failed. A failed open may leave the MAC + * and DMA running, so quiesce the device again, + * restore the previous program and try to reopen + * with it, while preserving the original error. + */ + stmmac_xdp_release(dev); + new_prog = xchg(&priv->xdp_prog, old_prog); + if (new_prog) + bpf_prog_put(new_prog); + old_prog = NULL; + + priv->sph_active = priv->sph_capable && + !stmmac_xdp_is_enabled(priv); + + if (stmmac_xdp_open(dev)) + netdev_err(dev, "failed to restore the previous XDP configuration\n"); + } + } + + if (old_prog) + bpf_prog_put(old_prog); + + if (ret) + return ret; if (prog) xdp_features_set_redirect_target(dev, false); + else + xdp_features_clear_redirect_target(dev); return 0; } -- 2.54.0.windows.1