Skip to content

Commit bf02d9f

Browse files
davidarinzonPaolo Abeni
authored andcommitted
net: ena: Fix incorrect descriptor free behavior
ENA has two types of TX queues: - queues which only process TX packets arriving from the network stack - queues which only process TX packets forwarded to it by XDP_REDIRECT or XDP_TX instructions The ena_free_tx_bufs() cycles through all descriptors in a TX queue and unmaps + frees every descriptor that hasn't been acknowledged yet by the device (uncompleted TX transactions). The function assumes that the processed TX queue is necessarily from the first category listed above and ends up using napi_consume_skb() for descriptors belonging to an XDP specific queue. This patch solves a bug in which, in case of a VF reset, the descriptors aren't freed correctly, leading to crashes. Fixes: 548c494 ("net: ena: Implement XDP_TX action") Signed-off-by: Shay Agroskin <shayagr@amazon.com> Signed-off-by: David Arinzon <darinzon@amazon.com> Reviewed-by: Shannon Nelson <shannon.nelson@amd.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent f7e4171 commit bf02d9f

1 file changed

Lines changed: 11 additions & 3 deletions

File tree

drivers/net/ethernet/amazon/ena/ena_netdev.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -718,8 +718,11 @@ void ena_unmap_tx_buff(struct ena_ring *tx_ring,
718718
static void ena_free_tx_bufs(struct ena_ring *tx_ring)
719719
{
720720
bool print_once = true;
721+
bool is_xdp_ring;
721722
u32 i;
722723

724+
is_xdp_ring = ENA_IS_XDP_INDEX(tx_ring->adapter, tx_ring->qid);
725+
723726
for (i = 0; i < tx_ring->ring_size; i++) {
724727
struct ena_tx_buffer *tx_info = &tx_ring->tx_buffer_info[i];
725728

@@ -739,10 +742,15 @@ static void ena_free_tx_bufs(struct ena_ring *tx_ring)
739742

740743
ena_unmap_tx_buff(tx_ring, tx_info);
741744

742-
dev_kfree_skb_any(tx_info->skb);
745+
if (is_xdp_ring)
746+
xdp_return_frame(tx_info->xdpf);
747+
else
748+
dev_kfree_skb_any(tx_info->skb);
743749
}
744-
netdev_tx_reset_queue(netdev_get_tx_queue(tx_ring->netdev,
745-
tx_ring->qid));
750+
751+
if (!is_xdp_ring)
752+
netdev_tx_reset_queue(netdev_get_tx_queue(tx_ring->netdev,
753+
tx_ring->qid));
746754
}
747755

748756
static void ena_free_all_tx_bufs(struct ena_adapter *adapter)

0 commit comments

Comments
 (0)