Skip to content

Commit f3d9f7f

Browse files
mfijalkokuba-moo
authored andcommitted
ixgbe: fix ndo_xdp_xmit() workloads
Currently ixgbe driver checks periodically in its watchdog subtask if there is anything to be transmitted (considering both Tx and XDP rings) under state of carrier not being 'ok'. Such event is interpreted as Tx hang and therefore results in interface reset. This is currently problematic for ndo_xdp_xmit() as it is allowed to produce descriptors when interface is going through reset or its carrier is turned off. Furthermore, XDP rings should not really be objects of Tx hang detection. This mechanism is rather a matter of ndo_tx_timeout() being called from dev_watchdog against Tx rings exposed to networking stack. Taking into account issues described above, let us have a two fold fix - do not respect XDP rings in local ixgbe watchdog and do not produce Tx descriptors in ndo_xdp_xmit callback when there is some problem with carrier currently. For now, keep the Tx hang checks in clean Tx irq routine, but adjust it to not execute for XDP rings. Cc: Tobias Böhm <tobias.boehm@hetzner-cloud.de> Reported-by: Marcus Wichelmann <marcus.wichelmann@hetzner-cloud.de> Closes: https://lore.kernel.org/netdev/eca1880f-253a-4955-afe6-732d7c6926ee@hetzner-cloud.de/ Fixes: 6453073 ("ixgbe: add initial support for xdp redirect") Fixes: 33fdc82 ("ixgbe: add support for XDP_TX action") Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Tested-by: Marcus Wichelmann <marcus.wichelmann@hetzner-cloud.de> Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> Link: https://patch.msgid.link/20250819222000.3504873-5-anthony.l.nguyen@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 4d4d9ef commit f3d9f7f

File tree

1 file changed

+11
-23
lines changed

1 file changed

+11
-23
lines changed

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -968,10 +968,6 @@ static void ixgbe_update_xoff_rx_lfc(struct ixgbe_adapter *adapter)
968968
for (i = 0; i < adapter->num_tx_queues; i++)
969969
clear_bit(__IXGBE_HANG_CHECK_ARMED,
970970
&adapter->tx_ring[i]->state);
971-
972-
for (i = 0; i < adapter->num_xdp_queues; i++)
973-
clear_bit(__IXGBE_HANG_CHECK_ARMED,
974-
&adapter->xdp_ring[i]->state);
975971
}
976972

977973
static void ixgbe_update_xoff_received(struct ixgbe_adapter *adapter)
@@ -1214,24 +1210,22 @@ static void ixgbe_pf_handle_tx_hang(struct ixgbe_ring *tx_ring,
12141210
struct ixgbe_adapter *adapter = netdev_priv(tx_ring->netdev);
12151211
struct ixgbe_hw *hw = &adapter->hw;
12161212

1217-
e_err(drv, "Detected Tx Unit Hang%s\n"
1213+
e_err(drv, "Detected Tx Unit Hang\n"
12181214
" Tx Queue <%d>\n"
12191215
" TDH, TDT <%x>, <%x>\n"
12201216
" next_to_use <%x>\n"
12211217
" next_to_clean <%x>\n"
12221218
"tx_buffer_info[next_to_clean]\n"
12231219
" time_stamp <%lx>\n"
12241220
" jiffies <%lx>\n",
1225-
ring_is_xdp(tx_ring) ? " (XDP)" : "",
12261221
tx_ring->queue_index,
12271222
IXGBE_READ_REG(hw, IXGBE_TDH(tx_ring->reg_idx)),
12281223
IXGBE_READ_REG(hw, IXGBE_TDT(tx_ring->reg_idx)),
12291224
tx_ring->next_to_use, next,
12301225
tx_ring->tx_buffer_info[next].time_stamp, jiffies);
12311226

1232-
if (!ring_is_xdp(tx_ring))
1233-
netif_stop_subqueue(tx_ring->netdev,
1234-
tx_ring->queue_index);
1227+
netif_stop_subqueue(tx_ring->netdev,
1228+
tx_ring->queue_index);
12351229
}
12361230

12371231
/**
@@ -1451,6 +1445,9 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
14511445
total_bytes);
14521446
adapter->tx_ipsec += total_ipsec;
14531447

1448+
if (ring_is_xdp(tx_ring))
1449+
return !!budget;
1450+
14541451
if (check_for_tx_hang(tx_ring) && ixgbe_check_tx_hang(tx_ring)) {
14551452
if (adapter->hw.mac.type == ixgbe_mac_e610)
14561453
ixgbe_handle_mdd_event(adapter, tx_ring);
@@ -1468,9 +1465,6 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
14681465
return true;
14691466
}
14701467

1471-
if (ring_is_xdp(tx_ring))
1472-
return !!budget;
1473-
14741468
#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
14751469
txq = netdev_get_tx_queue(tx_ring->netdev, tx_ring->queue_index);
14761470
if (!__netif_txq_completed_wake(txq, total_packets, total_bytes,
@@ -7974,12 +7968,9 @@ static void ixgbe_check_hang_subtask(struct ixgbe_adapter *adapter)
79747968
return;
79757969

79767970
/* Force detection of hung controller */
7977-
if (netif_carrier_ok(adapter->netdev)) {
7971+
if (netif_carrier_ok(adapter->netdev))
79787972
for (i = 0; i < adapter->num_tx_queues; i++)
79797973
set_check_for_tx_hang(adapter->tx_ring[i]);
7980-
for (i = 0; i < adapter->num_xdp_queues; i++)
7981-
set_check_for_tx_hang(adapter->xdp_ring[i]);
7982-
}
79837974

79847975
if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) {
79857976
/*
@@ -8199,13 +8190,6 @@ static bool ixgbe_ring_tx_pending(struct ixgbe_adapter *adapter)
81998190
return true;
82008191
}
82018192

8202-
for (i = 0; i < adapter->num_xdp_queues; i++) {
8203-
struct ixgbe_ring *ring = adapter->xdp_ring[i];
8204-
8205-
if (ring->next_to_use != ring->next_to_clean)
8206-
return true;
8207-
}
8208-
82098193
return false;
82108194
}
82118195

@@ -11005,6 +10989,10 @@ static int ixgbe_xdp_xmit(struct net_device *dev, int n,
1100510989
if (unlikely(test_bit(__IXGBE_DOWN, &adapter->state)))
1100610990
return -ENETDOWN;
1100710991

10992+
if (!netif_carrier_ok(adapter->netdev) ||
10993+
!netif_running(adapter->netdev))
10994+
return -ENETDOWN;
10995+
1100810996
if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
1100910997
return -EINVAL;
1101010998

0 commit comments

Comments
 (0)