Message ID | 20240410091358.16289-4-darinzon@amazon.com (mailing list archive) |
---|---|
State | Accepted |
Commit | bf02d9fe00632d22fa91d34749c7aacf397b6cde |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | ENA driver bug fixes | expand |
On 4/10/2024 2:13 AM, darinzon@amazon.com wrote: > From: David Arinzon <darinzon@amazon.com> > > 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: 548c4940b9f1 ("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> > --- > drivers/net/ethernet/amazon/ena/ena_netdev.c | 14 +++++++++++--- > 1 file changed, 11 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c > index 59befc0f..be5acfa4 100644 > --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c > +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c > @@ -718,8 +718,11 @@ void ena_unmap_tx_buff(struct ena_ring *tx_ring, > static void ena_free_tx_bufs(struct ena_ring *tx_ring) > { > bool print_once = true; > + bool is_xdp_ring; > u32 i; > > + is_xdp_ring = ENA_IS_XDP_INDEX(tx_ring->adapter, tx_ring->qid); > + > for (i = 0; i < tx_ring->ring_size; i++) { > struct ena_tx_buffer *tx_info = &tx_ring->tx_buffer_info[i]; > > @@ -739,10 +742,15 @@ static void ena_free_tx_bufs(struct ena_ring *tx_ring) > > ena_unmap_tx_buff(tx_ring, tx_info); > > - dev_kfree_skb_any(tx_info->skb); > + if (is_xdp_ring) > + xdp_return_frame(tx_info->xdpf); > + else > + dev_kfree_skb_any(tx_info->skb); > } > - netdev_tx_reset_queue(netdev_get_tx_queue(tx_ring->netdev, > - tx_ring->qid)); > + > + if (!is_xdp_ring) > + netdev_tx_reset_queue(netdev_get_tx_queue(tx_ring->netdev, > + tx_ring->qid)); > } > > static void ena_free_all_tx_bufs(struct ena_adapter *adapter) > -- > 2.40.1 > >
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c index 59befc0f..be5acfa4 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c @@ -718,8 +718,11 @@ void ena_unmap_tx_buff(struct ena_ring *tx_ring, static void ena_free_tx_bufs(struct ena_ring *tx_ring) { bool print_once = true; + bool is_xdp_ring; u32 i; + is_xdp_ring = ENA_IS_XDP_INDEX(tx_ring->adapter, tx_ring->qid); + for (i = 0; i < tx_ring->ring_size; i++) { struct ena_tx_buffer *tx_info = &tx_ring->tx_buffer_info[i]; @@ -739,10 +742,15 @@ static void ena_free_tx_bufs(struct ena_ring *tx_ring) ena_unmap_tx_buff(tx_ring, tx_info); - dev_kfree_skb_any(tx_info->skb); + if (is_xdp_ring) + xdp_return_frame(tx_info->xdpf); + else + dev_kfree_skb_any(tx_info->skb); } - netdev_tx_reset_queue(netdev_get_tx_queue(tx_ring->netdev, - tx_ring->qid)); + + if (!is_xdp_ring) + netdev_tx_reset_queue(netdev_get_tx_queue(tx_ring->netdev, + tx_ring->qid)); } static void ena_free_all_tx_bufs(struct ena_adapter *adapter)