Gary Lin 02ec94
From: Ciara Loftus <ciara.loftus@intel.com>
Gary Lin 02ec94
Date: Wed, 31 Mar 2021 06:12:18 +0000
Gary Lin 02ec94
Subject: libbpf: Only create rx and tx XDP rings when necessary
Gary Lin 02ec94
Patch-mainline: v5.12-rc7
Gary Lin 02ec94
Git-commit: ca7a83e2487ad0bc9a3e0e7a8645354aa1782f13
Gary Lin 02ec94
References: bsc#1155518
Gary Lin 02ec94
Gary Lin 02ec94
Prior to this commit xsk_socket__create(_shared) always attempted to create
Gary Lin 02ec94
the rx and tx rings for the socket. However this causes an issue when the
Gary Lin 02ec94
socket being setup is that which shares the fd with the UMEM. If a
Gary Lin 02ec94
previous call to this function failed with this socket after the rings were
Gary Lin 02ec94
set up, a subsequent call would always fail because the rings are not torn
Gary Lin 02ec94
down after the first call and when we try to set them up again we encounter
Gary Lin 02ec94
an error because they already exist. Solve this by remembering whether the
Gary Lin 02ec94
rings were set up by introducing new bools to struct xsk_umem which
Gary Lin 02ec94
represent the ring setup status and using them to determine whether or
Gary Lin 02ec94
not to set up the rings.
Gary Lin 02ec94
Gary Lin 02ec94
Fixes: 1cad07884239 ("libbpf: add support for using AF_XDP sockets")
Gary Lin 02ec94
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
Gary Lin 02ec94
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Gary Lin 02ec94
Link: https://lore.kernel.org/bpf/20210331061218.1647-4-ciara.loftus@intel.com
Gary Lin 02ec94
Acked-by: Gary Lin <glin@suse.com>
Gary Lin 02ec94
---
Gary Lin 02ec94
 tools/lib/bpf/xsk.c |   13 +++++++++++--
Gary Lin 02ec94
 1 file changed, 11 insertions(+), 2 deletions(-)
Gary Lin 02ec94
Gary Lin 02ec94
--- a/tools/lib/bpf/xsk.c
Gary Lin 02ec94
+++ b/tools/lib/bpf/xsk.c
Gary Lin 02ec94
@@ -51,6 +51,8 @@ struct xsk_umem {
Gary Lin 02ec94
 	struct xsk_umem_config config;
Gary Lin 02ec94
 	int fd;
Gary Lin 02ec94
 	int refcount;
Gary Lin 02ec94
+	bool rx_ring_setup_done;
Gary Lin 02ec94
+	bool tx_ring_setup_done;
Gary Lin 02ec94
 };
Gary Lin 02ec94
 
Gary Lin 02ec94
 struct xsk_socket {
Gary Lin 02ec94
@@ -561,6 +563,7 @@ int xsk_socket__create(struct xsk_socket
Gary Lin 02ec94
 	struct xdp_mmap_offsets off;
Gary Lin 02ec94
 	struct xsk_socket *xsk;
Gary Lin 02ec94
 	int err;
Gary Lin 02ec94
+	bool rx_setup_done = false, tx_setup_done = false;
Gary Lin 02ec94
 
Gary Lin 02ec94
 	if (!umem || !xsk_ptr || !rx || !tx)
Gary Lin 02ec94
 		return -EFAULT;
Gary Lin 02ec94
@@ -582,6 +585,8 @@ int xsk_socket__create(struct xsk_socket
Gary Lin 02ec94
 		}
Gary Lin 02ec94
 	} else {
Gary Lin 02ec94
 		xsk->fd = umem->fd;
Gary Lin 02ec94
+		rx_setup_done = umem->rx_ring_setup_done;
Gary Lin 02ec94
+		tx_setup_done = umem->tx_ring_setup_done;
Gary Lin 02ec94
 	}
Gary Lin 02ec94
 
Gary Lin 02ec94
 	xsk->outstanding_tx = 0;
Gary Lin 02ec94
@@ -599,7 +604,7 @@ int xsk_socket__create(struct xsk_socket
Gary Lin 02ec94
 	if (err)
Gary Lin 02ec94
 		goto out_socket;
Gary Lin 02ec94
 
Gary Lin 02ec94
-	if (rx) {
Gary Lin 02ec94
+	if (rx && !rx_setup_done) {
Gary Lin 02ec94
 		err = setsockopt(xsk->fd, SOL_XDP, XDP_RX_RING,
Gary Lin 02ec94
 				 &xsk->config.rx_size,
Gary Lin 02ec94
 				 sizeof(xsk->config.rx_size));
Gary Lin 02ec94
@@ -607,8 +612,10 @@ int xsk_socket__create(struct xsk_socket
Gary Lin 02ec94
 			err = -errno;
Gary Lin 02ec94
 			goto out_socket;
Gary Lin 02ec94
 		}
Gary Lin 02ec94
+		if (xsk->fd == umem->fd)
Gary Lin 02ec94
+			umem->rx_ring_setup_done = true;
Gary Lin 02ec94
 	}
Gary Lin 02ec94
-	if (tx) {
Gary Lin 02ec94
+	if (tx && !tx_setup_done) {
Gary Lin 02ec94
 		err = setsockopt(xsk->fd, SOL_XDP, XDP_TX_RING,
Gary Lin 02ec94
 				 &xsk->config.tx_size,
Gary Lin 02ec94
 				 sizeof(xsk->config.tx_size));
Gary Lin 02ec94
@@ -616,6 +623,8 @@ int xsk_socket__create(struct xsk_socket
Gary Lin 02ec94
 			err = -errno;
Gary Lin 02ec94
 			goto out_socket;
Gary Lin 02ec94
 		}
Gary Lin 02ec94
+		if (xsk->fd == umem->fd)
Gary Lin 02ec94
+			umem->rx_ring_setup_done = true;
Gary Lin 02ec94
 	}
Gary Lin 02ec94
 
Gary Lin 02ec94
 	err = xsk_get_mmap_offsets(xsk->fd, &off;;