Commit 9dbb1370 authored by Björn Töpel's avatar Björn Töpel Committed by Jeff Kirsher

i40e: clean zero-copy XDP Tx ring on shutdown/reset

When the zero-copy enabled XDP Tx ring is torn down, due to
configuration changes, outstanding frames on the hardware descriptor
ring are queued on the completion ring.

The completion ring has a back-pressure mechanism that will guarantee
that there is sufficient space on the ring.
Signed-off-by: default avatarBjörn Töpel <bjorn.topel@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 679b05c0
...@@ -636,13 +636,18 @@ void i40e_clean_tx_ring(struct i40e_ring *tx_ring) ...@@ -636,13 +636,18 @@ void i40e_clean_tx_ring(struct i40e_ring *tx_ring)
unsigned long bi_size; unsigned long bi_size;
u16 i; u16 i;
/* ring already cleared, nothing to do */ if (ring_is_xdp(tx_ring) && tx_ring->xsk_umem) {
if (!tx_ring->tx_bi) i40e_xsk_clean_tx_ring(tx_ring);
return; } else {
/* ring already cleared, nothing to do */
if (!tx_ring->tx_bi)
return;
/* Free all the Tx ring sk_buffs */ /* Free all the Tx ring sk_buffs */
for (i = 0; i < tx_ring->count; i++) for (i = 0; i < tx_ring->count; i++)
i40e_unmap_and_free_tx_resource(tx_ring, &tx_ring->tx_bi[i]); i40e_unmap_and_free_tx_resource(tx_ring,
&tx_ring->tx_bi[i]);
}
bi_size = sizeof(struct i40e_tx_buffer) * tx_ring->count; bi_size = sizeof(struct i40e_tx_buffer) * tx_ring->count;
memset(tx_ring->tx_bi, 0, bi_size); memset(tx_ring->tx_bi, 0, bi_size);
......
...@@ -87,4 +87,6 @@ static inline void i40e_arm_wb(struct i40e_ring *tx_ring, ...@@ -87,4 +87,6 @@ static inline void i40e_arm_wb(struct i40e_ring *tx_ring,
} }
} }
void i40e_xsk_clean_tx_ring(struct i40e_ring *tx_ring);
#endif /* I40E_TXRX_COMMON_ */ #endif /* I40E_TXRX_COMMON_ */
...@@ -830,3 +830,33 @@ int i40e_xsk_async_xmit(struct net_device *dev, u32 queue_id) ...@@ -830,3 +830,33 @@ int i40e_xsk_async_xmit(struct net_device *dev, u32 queue_id)
return 0; return 0;
} }
/**
* i40e_xsk_clean_xdp_ring - Clean the XDP Tx ring on shutdown
* @xdp_ring: XDP Tx ring
**/
void i40e_xsk_clean_tx_ring(struct i40e_ring *tx_ring)
{
u16 ntc = tx_ring->next_to_clean, ntu = tx_ring->next_to_use;
struct xdp_umem *umem = tx_ring->xsk_umem;
struct i40e_tx_buffer *tx_bi;
u32 xsk_frames = 0;
while (ntc != ntu) {
tx_bi = &tx_ring->tx_bi[ntc];
if (tx_bi->xdpf)
i40e_clean_xdp_tx_buffer(tx_ring, tx_bi);
else
xsk_frames++;
tx_bi->xdpf = NULL;
ntc++;
if (ntc >= tx_ring->count)
ntc = 0;
}
if (xsk_frames)
xsk_umem_complete_tx(umem, xsk_frames);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment