git: f236e544a2ff - main - ena: Properly unmap last socket chain in netmap

From: Osama Abboud <osamaabb_at_FreeBSD.org>
Date: Tue, 15 Oct 2024 17:43:14 UTC
The branch main has been updated by osamaabb:

URL: https://cgit.FreeBSD.org/src/commit/?id=f236e544a2ff685ae151f3232e3785a6a9aab035

commit f236e544a2ff685ae151f3232e3785a6a9aab035
Author:     Osama Abboud <osamaabb@amazon.com>
AuthorDate: 2024-08-07 06:24:20 +0000
Commit:     Osama Abboud <osamaabb@FreeBSD.org>
CommitDate: 2024-10-15 17:38:32 +0000

    ena: Properly unmap last socket chain in netmap
    
    In case ena_com_prepare_tx() fails within the netmap tx flow,
    the driver will unmap the last socket chain.
    Currently, the driver unmaps the wrong socket within
    ena_netmap_unmap_last_socket_chain().
    
    Illustration of the flow:
    
    1- ena_netmap_tx_frames()
    2- ena_netmap_tx_frame()
    3- ena_netmap_tx_map_slots()
    3.1- Map slot
    3.2- Advance to the next socket
    4- ena_com_prepare_tx()
    4.1- ena_com_prepare_tx() fails
    5- ena_netmap_unmap_last_socket_chain()
    
    In step 5, where the driver unmaps the socket, the netmap
    index already points at the next entry, meaning we're unmapping the
    wrong socket in case ena_com_prepare_tx() fails.
    In order to fix that, the driver should first update the netmap index to
    point at the previous entry and only then update the socket parameters.
    
    Approved by: cperciva (mentor)
    MFC after: 2 weeks
    Sponsored by: Amazon, Inc.
---
 sys/dev/ena/ena_netmap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/dev/ena/ena_netmap.c b/sys/dev/ena/ena_netmap.c
index 0666d7deb827..f14a4a9539d1 100644
--- a/sys/dev/ena/ena_netmap.c
+++ b/sys/dev/ena/ena_netmap.c
@@ -783,10 +783,10 @@ ena_netmap_unmap_last_socket_chain(struct ena_netmap_ctx *ctx,
 	/* Next, retain the sockets back to the userspace */
 	n = nm_info->sockets_used;
 	while (n--) {
+		ctx->nm_i = nm_prev(ctx->nm_i, ctx->lim);
 		ctx->slots[ctx->nm_i].buf_idx = nm_info->socket_buf_idx[n];
 		ctx->slots[ctx->nm_i].flags = NS_BUF_CHANGED;
 		nm_info->socket_buf_idx[n] = 0;
-		ctx->nm_i = nm_prev(ctx->nm_i, ctx->lim);
 	}
 	nm_info->sockets_used = 0;
 }