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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-enetc-fix-some-issues-of-xdp'

Wei Fang says:

====================
net: enetc: fix some issues of XDP

We found some bugs when testing the XDP function of enetc driver,
and these bugs are easy to reproduce. This is not only causes XDP
to not work, but also the network cannot be restored after exiting
the XDP program. So the patch set is mainly to fix these bugs. For
details, please see the commit message of each patch.

v1: https://lore.kernel.org/bpf/20240919084104.661180-1-wei.fang@nxp.com/
v2: https://lore.kernel.org/netdev/20241008224806.2onzkt3gbslw5jxb@skbuf/
v3: https://lore.kernel.org/imx/20241009090327.146461-1-wei.fang@nxp.com/
====================

Link: https://patch.msgid.link/20241010092056.298128-1-wei.fang@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+44 -13
+43 -13
drivers/net/ethernet/freescale/enetc/enetc.c
··· 902 902 903 903 if (unlikely(tx_frm_cnt && netif_carrier_ok(ndev) && 904 904 __netif_subqueue_stopped(ndev, tx_ring->index) && 905 + !test_bit(ENETC_TX_DOWN, &priv->flags) && 905 906 (enetc_bd_unused(tx_ring) >= ENETC_TXBDS_MAX_NEEDED))) { 906 907 netif_wake_subqueue(ndev, tx_ring->index); 907 908 } ··· 1378 1377 int xdp_tx_bd_cnt, i, k; 1379 1378 int xdp_tx_frm_cnt = 0; 1380 1379 1380 + if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags))) 1381 + return -ENETDOWN; 1382 + 1381 1383 enetc_lock_mdio(); 1382 1384 1383 1385 tx_ring = priv->xdp_tx_ring[smp_processor_id()]; ··· 1525 1521 &rx_ring->rx_swbd[rx_ring_first]); 1526 1522 enetc_bdr_idx_inc(rx_ring, &rx_ring_first); 1527 1523 } 1528 - rx_ring->stats.xdp_drops++; 1529 1524 } 1530 1525 1531 1526 static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, ··· 1589 1586 fallthrough; 1590 1587 case XDP_DROP: 1591 1588 enetc_xdp_drop(rx_ring, orig_i, i); 1589 + rx_ring->stats.xdp_drops++; 1592 1590 break; 1593 1591 case XDP_PASS: 1594 1592 rxbd = orig_rxbd; ··· 1606 1602 break; 1607 1603 case XDP_TX: 1608 1604 tx_ring = priv->xdp_tx_ring[rx_ring->index]; 1605 + if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags))) { 1606 + enetc_xdp_drop(rx_ring, orig_i, i); 1607 + tx_ring->stats.xdp_tx_drops++; 1608 + break; 1609 + } 1610 + 1609 1611 xdp_tx_bd_cnt = enetc_rx_swbd_to_xdp_tx_swbd(xdp_tx_arr, 1610 1612 rx_ring, 1611 1613 orig_i, i); ··· 2233 2223 enetc_rxbdr_wr(hw, idx, ENETC_RBMR, rbmr); 2234 2224 } 2235 2225 2236 - static void enetc_enable_bdrs(struct enetc_ndev_priv *priv) 2226 + static void enetc_enable_rx_bdrs(struct enetc_ndev_priv *priv) 2227 + { 2228 + struct enetc_hw *hw = &priv->si->hw; 2229 + int i; 2230 + 2231 + for (i = 0; i < priv->num_rx_rings; i++) 2232 + enetc_enable_rxbdr(hw, priv->rx_ring[i]); 2233 + } 2234 + 2235 + static void enetc_enable_tx_bdrs(struct enetc_ndev_priv *priv) 2237 2236 { 2238 2237 struct enetc_hw *hw = &priv->si->hw; 2239 2238 int i; 2240 2239 2241 2240 for (i = 0; i < priv->num_tx_rings; i++) 2242 2241 enetc_enable_txbdr(hw, priv->tx_ring[i]); 2243 - 2244 - for (i = 0; i < priv->num_rx_rings; i++) 2245 - enetc_enable_rxbdr(hw, priv->rx_ring[i]); 2246 2242 } 2247 2243 2248 2244 static void enetc_disable_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring) ··· 2267 2251 enetc_txbdr_wr(hw, idx, ENETC_TBMR, 0); 2268 2252 } 2269 2253 2270 - static void enetc_disable_bdrs(struct enetc_ndev_priv *priv) 2254 + static void enetc_disable_rx_bdrs(struct enetc_ndev_priv *priv) 2255 + { 2256 + struct enetc_hw *hw = &priv->si->hw; 2257 + int i; 2258 + 2259 + for (i = 0; i < priv->num_rx_rings; i++) 2260 + enetc_disable_rxbdr(hw, priv->rx_ring[i]); 2261 + } 2262 + 2263 + static void enetc_disable_tx_bdrs(struct enetc_ndev_priv *priv) 2271 2264 { 2272 2265 struct enetc_hw *hw = &priv->si->hw; 2273 2266 int i; 2274 2267 2275 2268 for (i = 0; i < priv->num_tx_rings; i++) 2276 2269 enetc_disable_txbdr(hw, priv->tx_ring[i]); 2277 - 2278 - for (i = 0; i < priv->num_rx_rings; i++) 2279 - enetc_disable_rxbdr(hw, priv->rx_ring[i]); 2280 2270 } 2281 2271 2282 2272 static void enetc_wait_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring) ··· 2482 2460 enable_irq(irq); 2483 2461 } 2484 2462 2485 - enetc_enable_bdrs(priv); 2463 + enetc_enable_tx_bdrs(priv); 2464 + 2465 + enetc_enable_rx_bdrs(priv); 2486 2466 2487 2467 netif_tx_start_all_queues(ndev); 2468 + 2469 + clear_bit(ENETC_TX_DOWN, &priv->flags); 2488 2470 } 2489 2471 EXPORT_SYMBOL_GPL(enetc_start); 2490 2472 ··· 2546 2520 struct enetc_ndev_priv *priv = netdev_priv(ndev); 2547 2521 int i; 2548 2522 2523 + set_bit(ENETC_TX_DOWN, &priv->flags); 2524 + 2549 2525 netif_tx_stop_all_queues(ndev); 2550 2526 2551 - enetc_disable_bdrs(priv); 2527 + enetc_disable_rx_bdrs(priv); 2528 + 2529 + enetc_wait_bdrs(priv); 2530 + 2531 + enetc_disable_tx_bdrs(priv); 2552 2532 2553 2533 for (i = 0; i < priv->bdr_int_num; i++) { 2554 2534 int irq = pci_irq_vector(priv->si->pdev, ··· 2564 2532 napi_synchronize(&priv->int_vector[i]->napi); 2565 2533 napi_disable(&priv->int_vector[i]->napi); 2566 2534 } 2567 - 2568 - enetc_wait_bdrs(priv); 2569 2535 2570 2536 enetc_clear_interrupts(priv); 2571 2537 }
+1
drivers/net/ethernet/freescale/enetc/enetc.h
··· 325 325 326 326 enum enetc_flags_bit { 327 327 ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS = 0, 328 + ENETC_TX_DOWN, 328 329 }; 329 330 330 331 /* interrupt coalescing modes */