diff mbox series

[v1,net,3/4] net: ena: Fix incorrect descriptor free behavior

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

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 942 this patch: 942
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers warning 7 maintainers not CCed: pabeni@redhat.com daniel@iogearbox.net hawk@kernel.org john.fastabend@gmail.com ast@kernel.org edumazet@google.com bpf@vger.kernel.org
netdev/build_clang success Errors and warnings before: 953 this patch: 953
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 953 this patch: 953
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 29 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-04-11--00-00 (tests: 959)

Commit Message

Arinzon, David April 10, 2024, 9:13 a.m. UTC
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>
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

Comments

Nelson, Shannon April 10, 2024, 9:52 p.m. UTC | #1
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 mbox series

Patch

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)