netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH bpf-next 0/6] xsk: struct diet and cleanups
@ 2024-10-02 15:54 Maciej Fijalkowski
  2024-10-02 15:54 ` [PATCH bpf-next 1/6] xsk: get rid of xdp_buff_xsk::xskb_list_node Maciej Fijalkowski
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Maciej Fijalkowski @ 2024-10-02 15:54 UTC (permalink / raw)
  To: bpf, ast, daniel, andrii
  Cc: netdev, magnus.karlsson, bjorn, maciej.fijalkowski

Hi all,

this modest work brings back size of xdp_buff_xsk back to two cache
lines which in turn improves performance. Interestingly I was able to
observe on ice with HW rings sized to 512 around 12% better performance
when running xdpsock in l2fwd scenario. First three patches are behind
this. Other setups were not that impressive, I believe results may vary
based on the underlying CPU. Bottom line is that shrinking this struct
takes off a bit of work from CPU's shoulders.

Other three patches are rather cleanups.

Thanks,
Maciej



Maciej Fijalkowski (6):
  xsk: get rid of xdp_buff_xsk::xskb_list_node
  xsk: s/free_list_node/list_node
  xsk: get rid of xdp_buff_xsk::orig_addr
  xsk: carry a copy of xdp_zc_max_segs within xsk_buff_pool
  xsk: wrap duplicated code to function
  xsk: use xsk_buff_pool directly for cq functions

 include/net/xdp_sock_drv.h  | 14 +++++-----
 include/net/xsk_buff_pool.h | 23 +++++++++-------
 net/xdp/xsk.c               | 38 +++++++++++++-------------
 net/xdp/xsk_buff_pool.c     | 54 ++++++++++++++++++++-----------------
 net/xdp/xsk_queue.h         |  2 +-
 5 files changed, 69 insertions(+), 62 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH bpf-next 1/6] xsk: get rid of xdp_buff_xsk::xskb_list_node
  2024-10-02 15:54 [PATCH bpf-next 0/6] xsk: struct diet and cleanups Maciej Fijalkowski
@ 2024-10-02 15:54 ` Maciej Fijalkowski
  2024-10-04 12:08   ` Daniel Borkmann
  2024-10-02 15:54 ` [PATCH bpf-next 2/6] xsk: s/free_list_node/list_node Maciej Fijalkowski
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Maciej Fijalkowski @ 2024-10-02 15:54 UTC (permalink / raw)
  To: bpf, ast, daniel, andrii
  Cc: netdev, magnus.karlsson, bjorn, maciej.fijalkowski

Let's bring xdp_buff_xsk back to occupying 2 cachelines by removing
xskb_list_node - for the purpose of gathering the xskb frags
free_list_node can be used, head of the list (xsk_buff_pool::xskb_list)
stays as-is, just reuse the node ptr.

It is safe to do as a single xdp_buff_xsk can never reside in two
pool's lists simultaneously.

Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
---
 include/net/xdp_sock_drv.h  | 10 +++++-----
 include/net/xsk_buff_pool.h |  1 -
 net/xdp/xsk.c               |  4 ++--
 net/xdp/xsk_buff_pool.c     |  1 -
 4 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/include/net/xdp_sock_drv.h b/include/net/xdp_sock_drv.h
index 0a5dca2b2b3f..c897fedf259b 100644
--- a/include/net/xdp_sock_drv.h
+++ b/include/net/xdp_sock_drv.h
@@ -126,8 +126,8 @@ static inline void xsk_buff_free(struct xdp_buff *xdp)
 	if (likely(!xdp_buff_has_frags(xdp)))
 		goto out;
 
-	list_for_each_entry_safe(pos, tmp, xskb_list, xskb_list_node) {
-		list_del(&pos->xskb_list_node);
+	list_for_each_entry_safe(pos, tmp, xskb_list, free_list_node) {
+		list_del(&pos->free_list_node);
 		xp_free(pos);
 	}
 
@@ -140,7 +140,7 @@ static inline void xsk_buff_add_frag(struct xdp_buff *xdp)
 {
 	struct xdp_buff_xsk *frag = container_of(xdp, struct xdp_buff_xsk, xdp);
 
-	list_add_tail(&frag->xskb_list_node, &frag->pool->xskb_list);
+	list_add_tail(&frag->free_list_node, &frag->pool->xskb_list);
 }
 
 static inline struct xdp_buff *xsk_buff_get_frag(struct xdp_buff *first)
@@ -150,9 +150,9 @@ static inline struct xdp_buff *xsk_buff_get_frag(struct xdp_buff *first)
 	struct xdp_buff_xsk *frag;
 
 	frag = list_first_entry_or_null(&xskb->pool->xskb_list,
-					struct xdp_buff_xsk, xskb_list_node);
+					struct xdp_buff_xsk, free_list_node);
 	if (frag) {
-		list_del(&frag->xskb_list_node);
+		list_del(&frag->free_list_node);
 		ret = &frag->xdp;
 	}
 
diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h
index bacb33f1e3e5..aa7f1d0b3a5e 100644
--- a/include/net/xsk_buff_pool.h
+++ b/include/net/xsk_buff_pool.h
@@ -30,7 +30,6 @@ struct xdp_buff_xsk {
 	struct xsk_buff_pool *pool;
 	u64 orig_addr;
 	struct list_head free_list_node;
-	struct list_head xskb_list_node;
 };
 
 #define XSK_CHECK_PRIV_TYPE(t) BUILD_BUG_ON(sizeof(t) > offsetofend(struct xdp_buff_xsk, cb))
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 1140b2a120ca..9c93064349a8 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -171,14 +171,14 @@ static int xsk_rcv_zc(struct xdp_sock *xs, struct xdp_buff *xdp, u32 len)
 		return 0;
 
 	xskb_list = &xskb->pool->xskb_list;
-	list_for_each_entry_safe(pos, tmp, xskb_list, xskb_list_node) {
+	list_for_each_entry_safe(pos, tmp, xskb_list, free_list_node) {
 		if (list_is_singular(xskb_list))
 			contd = 0;
 		len = pos->xdp.data_end - pos->xdp.data;
 		err = __xsk_rcv_zc(xs, pos, len, contd);
 		if (err)
 			goto err;
-		list_del(&pos->xskb_list_node);
+		list_del(&pos->free_list_node);
 	}
 
 	return 0;
diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
index 521a2938e50a..e5368db7d18e 100644
--- a/net/xdp/xsk_buff_pool.c
+++ b/net/xdp/xsk_buff_pool.c
@@ -102,7 +102,6 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs,
 		xskb->pool = pool;
 		xskb->xdp.frame_sz = umem->chunk_size - umem->headroom;
 		INIT_LIST_HEAD(&xskb->free_list_node);
-		INIT_LIST_HEAD(&xskb->xskb_list_node);
 		if (pool->unaligned)
 			pool->free_heads[i] = xskb;
 		else
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH bpf-next 2/6] xsk: s/free_list_node/list_node
  2024-10-02 15:54 [PATCH bpf-next 0/6] xsk: struct diet and cleanups Maciej Fijalkowski
  2024-10-02 15:54 ` [PATCH bpf-next 1/6] xsk: get rid of xdp_buff_xsk::xskb_list_node Maciej Fijalkowski
@ 2024-10-02 15:54 ` Maciej Fijalkowski
  2024-10-02 15:54 ` [PATCH bpf-next 3/6] xsk: get rid of xdp_buff_xsk::orig_addr Maciej Fijalkowski
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Maciej Fijalkowski @ 2024-10-02 15:54 UTC (permalink / raw)
  To: bpf, ast, daniel, andrii
  Cc: netdev, magnus.karlsson, bjorn, maciej.fijalkowski

Now that free_list_node's purpose is two-folded, make it just a
'list_node'.

Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
---
 include/net/xdp_sock_drv.h  | 14 +++++++-------
 include/net/xsk_buff_pool.h |  2 +-
 net/xdp/xsk.c               |  4 ++--
 net/xdp/xsk_buff_pool.c     | 14 +++++++-------
 4 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/include/net/xdp_sock_drv.h b/include/net/xdp_sock_drv.h
index c897fedf259b..40085afd9160 100644
--- a/include/net/xdp_sock_drv.h
+++ b/include/net/xdp_sock_drv.h
@@ -126,8 +126,8 @@ static inline void xsk_buff_free(struct xdp_buff *xdp)
 	if (likely(!xdp_buff_has_frags(xdp)))
 		goto out;
 
-	list_for_each_entry_safe(pos, tmp, xskb_list, free_list_node) {
-		list_del(&pos->free_list_node);
+	list_for_each_entry_safe(pos, tmp, xskb_list, list_node) {
+		list_del(&pos->list_node);
 		xp_free(pos);
 	}
 
@@ -140,7 +140,7 @@ static inline void xsk_buff_add_frag(struct xdp_buff *xdp)
 {
 	struct xdp_buff_xsk *frag = container_of(xdp, struct xdp_buff_xsk, xdp);
 
-	list_add_tail(&frag->free_list_node, &frag->pool->xskb_list);
+	list_add_tail(&frag->list_node, &frag->pool->xskb_list);
 }
 
 static inline struct xdp_buff *xsk_buff_get_frag(struct xdp_buff *first)
@@ -150,9 +150,9 @@ static inline struct xdp_buff *xsk_buff_get_frag(struct xdp_buff *first)
 	struct xdp_buff_xsk *frag;
 
 	frag = list_first_entry_or_null(&xskb->pool->xskb_list,
-					struct xdp_buff_xsk, free_list_node);
+					struct xdp_buff_xsk, list_node);
 	if (frag) {
-		list_del(&frag->free_list_node);
+		list_del(&frag->list_node);
 		ret = &frag->xdp;
 	}
 
@@ -163,7 +163,7 @@ static inline void xsk_buff_del_tail(struct xdp_buff *tail)
 {
 	struct xdp_buff_xsk *xskb = container_of(tail, struct xdp_buff_xsk, xdp);
 
-	list_del(&xskb->xskb_list_node);
+	list_del(&xskb->list_node);
 }
 
 static inline struct xdp_buff *xsk_buff_get_tail(struct xdp_buff *first)
@@ -172,7 +172,7 @@ static inline struct xdp_buff *xsk_buff_get_tail(struct xdp_buff *first)
 	struct xdp_buff_xsk *frag;
 
 	frag = list_last_entry(&xskb->pool->xskb_list, struct xdp_buff_xsk,
-			       xskb_list_node);
+			       list_node);
 	return &frag->xdp;
 }
 
diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h
index aa7f1d0b3a5e..af8b6f776f86 100644
--- a/include/net/xsk_buff_pool.h
+++ b/include/net/xsk_buff_pool.h
@@ -29,7 +29,7 @@ struct xdp_buff_xsk {
 	dma_addr_t frame_dma;
 	struct xsk_buff_pool *pool;
 	u64 orig_addr;
-	struct list_head free_list_node;
+	struct list_head list_node;
 };
 
 #define XSK_CHECK_PRIV_TYPE(t) BUILD_BUG_ON(sizeof(t) > offsetofend(struct xdp_buff_xsk, cb))
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 9c93064349a8..520023405908 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -171,14 +171,14 @@ static int xsk_rcv_zc(struct xdp_sock *xs, struct xdp_buff *xdp, u32 len)
 		return 0;
 
 	xskb_list = &xskb->pool->xskb_list;
-	list_for_each_entry_safe(pos, tmp, xskb_list, free_list_node) {
+	list_for_each_entry_safe(pos, tmp, xskb_list, list_node) {
 		if (list_is_singular(xskb_list))
 			contd = 0;
 		len = pos->xdp.data_end - pos->xdp.data;
 		err = __xsk_rcv_zc(xs, pos, len, contd);
 		if (err)
 			goto err;
-		list_del(&pos->free_list_node);
+		list_del(&pos->list_node);
 	}
 
 	return 0;
diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
index e5368db7d18e..973557d5e4f7 100644
--- a/net/xdp/xsk_buff_pool.c
+++ b/net/xdp/xsk_buff_pool.c
@@ -101,7 +101,7 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs,
 		xskb = &pool->heads[i];
 		xskb->pool = pool;
 		xskb->xdp.frame_sz = umem->chunk_size - umem->headroom;
-		INIT_LIST_HEAD(&xskb->free_list_node);
+		INIT_LIST_HEAD(&xskb->list_node);
 		if (pool->unaligned)
 			pool->free_heads[i] = xskb;
 		else
@@ -549,8 +549,8 @@ struct xdp_buff *xp_alloc(struct xsk_buff_pool *pool)
 	} else {
 		pool->free_list_cnt--;
 		xskb = list_first_entry(&pool->free_list, struct xdp_buff_xsk,
-					free_list_node);
-		list_del_init(&xskb->free_list_node);
+					list_node);
+		list_del_init(&xskb->list_node);
 	}
 
 	xskb->xdp.data = xskb->xdp.data_hard_start + XDP_PACKET_HEADROOM;
@@ -616,8 +616,8 @@ static u32 xp_alloc_reused(struct xsk_buff_pool *pool, struct xdp_buff **xdp, u3
 
 	i = nb_entries;
 	while (i--) {
-		xskb = list_first_entry(&pool->free_list, struct xdp_buff_xsk, free_list_node);
-		list_del_init(&xskb->free_list_node);
+		xskb = list_first_entry(&pool->free_list, struct xdp_buff_xsk, list_node);
+		list_del_init(&xskb->list_node);
 
 		*xdp = &xskb->xdp;
 		xdp++;
@@ -687,11 +687,11 @@ EXPORT_SYMBOL(xp_can_alloc);
 
 void xp_free(struct xdp_buff_xsk *xskb)
 {
-	if (!list_empty(&xskb->free_list_node))
+	if (!list_empty(&xskb->list_node))
 		return;
 
 	xskb->pool->free_list_cnt++;
-	list_add(&xskb->free_list_node, &xskb->pool->free_list);
+	list_add(&xskb->list_node, &xskb->pool->free_list);
 }
 EXPORT_SYMBOL(xp_free);
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH bpf-next 3/6] xsk: get rid of xdp_buff_xsk::orig_addr
  2024-10-02 15:54 [PATCH bpf-next 0/6] xsk: struct diet and cleanups Maciej Fijalkowski
  2024-10-02 15:54 ` [PATCH bpf-next 1/6] xsk: get rid of xdp_buff_xsk::xskb_list_node Maciej Fijalkowski
  2024-10-02 15:54 ` [PATCH bpf-next 2/6] xsk: s/free_list_node/list_node Maciej Fijalkowski
@ 2024-10-02 15:54 ` Maciej Fijalkowski
  2024-10-02 15:54 ` [PATCH bpf-next 4/6] xsk: carry a copy of xdp_zc_max_segs within xsk_buff_pool Maciej Fijalkowski
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Maciej Fijalkowski @ 2024-10-02 15:54 UTC (permalink / raw)
  To: bpf, ast, daniel, andrii
  Cc: netdev, magnus.karlsson, bjorn, maciej.fijalkowski

Continue the process of dieting xdp_buff_xsk by removing orig_addr
member. It can be calculated from xdp->data_hard_start where it was
previously used, so it is not anything that has to be carried around in
struct used widely in hot path.

This has been used for initializing xdp_buff_xsk::frame_dma during pool
setup and as a shortcut in xp_get_handle() to retrieve address provided
to xsk Rx queue.

Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
---
 include/net/xsk_buff_pool.h | 19 +++++++++++--------
 net/xdp/xsk.c               |  2 +-
 net/xdp/xsk_buff_pool.c     |  4 +++-
 3 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h
index af8b6f776f86..468a23b1b4c5 100644
--- a/include/net/xsk_buff_pool.h
+++ b/include/net/xsk_buff_pool.h
@@ -28,7 +28,6 @@ struct xdp_buff_xsk {
 	dma_addr_t dma;
 	dma_addr_t frame_dma;
 	struct xsk_buff_pool *pool;
-	u64 orig_addr;
 	struct list_head list_node;
 };
 
@@ -119,7 +118,6 @@ void xp_free(struct xdp_buff_xsk *xskb);
 static inline void xp_init_xskb_addr(struct xdp_buff_xsk *xskb, struct xsk_buff_pool *pool,
 				     u64 addr)
 {
-	xskb->orig_addr = addr;
 	xskb->xdp.data_hard_start = pool->addrs + addr + pool->headroom;
 }
 
@@ -221,14 +219,19 @@ static inline void xp_release(struct xdp_buff_xsk *xskb)
 		xskb->pool->free_heads[xskb->pool->free_heads_cnt++] = xskb;
 }
 
-static inline u64 xp_get_handle(struct xdp_buff_xsk *xskb)
+static inline u64 xp_get_handle(struct xdp_buff_xsk *xskb,
+				struct xsk_buff_pool *pool)
 {
-	u64 offset = xskb->xdp.data - xskb->xdp.data_hard_start;
+	u64 orig_addr = xskb->xdp.data - pool->addrs;
+	u64 offset;
 
-	offset += xskb->pool->headroom;
-	if (!xskb->pool->unaligned)
-		return xskb->orig_addr + offset;
-	return xskb->orig_addr + (offset << XSK_UNALIGNED_BUF_OFFSET_SHIFT);
+	if (!pool->unaligned)
+		return orig_addr;
+
+	offset = xskb->xdp.data - xskb->xdp.data_hard_start;
+	orig_addr -= offset;
+	offset += pool->headroom;
+	return orig_addr + (offset << XSK_UNALIGNED_BUF_OFFSET_SHIFT);
 }
 
 static inline bool xp_tx_metadata_enabled(const struct xsk_buff_pool *pool)
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 520023405908..6c31c1de1619 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -141,7 +141,7 @@ static int __xsk_rcv_zc(struct xdp_sock *xs, struct xdp_buff_xsk *xskb, u32 len,
 	u64 addr;
 	int err;
 
-	addr = xp_get_handle(xskb);
+	addr = xp_get_handle(xskb, xskb->pool);
 	err = xskq_prod_reserve_desc(xs->rx, addr, len, flags);
 	if (err) {
 		xs->rx_queue_full++;
diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
index 973557d5e4f7..7ecd4ccd2473 100644
--- a/net/xdp/xsk_buff_pool.c
+++ b/net/xdp/xsk_buff_pool.c
@@ -416,8 +416,10 @@ static int xp_init_dma_info(struct xsk_buff_pool *pool, struct xsk_dma_map *dma_
 
 		for (i = 0; i < pool->heads_cnt; i++) {
 			struct xdp_buff_xsk *xskb = &pool->heads[i];
+			u64 orig_addr;
 
-			xp_init_xskb_dma(xskb, pool, dma_map->dma_pages, xskb->orig_addr);
+			orig_addr = xskb->xdp.data_hard_start - pool->addrs - pool->headroom;
+			xp_init_xskb_dma(xskb, pool, dma_map->dma_pages, orig_addr);
 		}
 	}
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH bpf-next 4/6] xsk: carry a copy of xdp_zc_max_segs within xsk_buff_pool
  2024-10-02 15:54 [PATCH bpf-next 0/6] xsk: struct diet and cleanups Maciej Fijalkowski
                   ` (2 preceding siblings ...)
  2024-10-02 15:54 ` [PATCH bpf-next 3/6] xsk: get rid of xdp_buff_xsk::orig_addr Maciej Fijalkowski
@ 2024-10-02 15:54 ` Maciej Fijalkowski
  2024-10-02 19:41   ` Vadim Fedorenko
  2024-10-02 15:54 ` [PATCH bpf-next 5/6] xsk: wrap duplicated code to function Maciej Fijalkowski
  2024-10-02 15:54 ` [PATCH bpf-next 6/6] xsk: use xsk_buff_pool directly for cq functions Maciej Fijalkowski
  5 siblings, 1 reply; 11+ messages in thread
From: Maciej Fijalkowski @ 2024-10-02 15:54 UTC (permalink / raw)
  To: bpf, ast, daniel, andrii
  Cc: netdev, magnus.karlsson, bjorn, maciej.fijalkowski

This so we avoid dereferencing struct net_device within hot path.

Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
---
 include/net/xsk_buff_pool.h | 1 +
 net/xdp/xsk_buff_pool.c     | 1 +
 net/xdp/xsk_queue.h         | 2 +-
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h
index 468a23b1b4c5..8223581d95f8 100644
--- a/include/net/xsk_buff_pool.h
+++ b/include/net/xsk_buff_pool.h
@@ -77,6 +77,7 @@ struct xsk_buff_pool {
 	u32 chunk_shift;
 	u32 frame_len;
 	u8 tx_metadata_len; /* inherited from umem */
+	u32 xdp_zc_max_segs;
 	u8 cached_need_wakeup;
 	bool uses_need_wakeup;
 	bool unaligned;
diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
index 7ecd4ccd2473..e946ba4a5ccf 100644
--- a/net/xdp/xsk_buff_pool.c
+++ b/net/xdp/xsk_buff_pool.c
@@ -229,6 +229,7 @@ int xp_assign_dev(struct xsk_buff_pool *pool,
 		goto err_unreg_xsk;
 	}
 	pool->umem->zc = true;
+	pool->xdp_zc_max_segs = netdev->xdp_zc_max_segs;
 	return 0;
 
 err_unreg_xsk:
diff --git a/net/xdp/xsk_queue.h b/net/xdp/xsk_queue.h
index 406b20dfee8d..46d87e961ad6 100644
--- a/net/xdp/xsk_queue.h
+++ b/net/xdp/xsk_queue.h
@@ -260,7 +260,7 @@ u32 xskq_cons_read_desc_batch(struct xsk_queue *q, struct xsk_buff_pool *pool,
 			nr_frags = 0;
 		} else {
 			nr_frags++;
-			if (nr_frags == pool->netdev->xdp_zc_max_segs) {
+			if (nr_frags == pool->xdp_zc_max_segs) {
 				nr_frags = 0;
 				break;
 			}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH bpf-next 5/6] xsk: wrap duplicated code to function
  2024-10-02 15:54 [PATCH bpf-next 0/6] xsk: struct diet and cleanups Maciej Fijalkowski
                   ` (3 preceding siblings ...)
  2024-10-02 15:54 ` [PATCH bpf-next 4/6] xsk: carry a copy of xdp_zc_max_segs within xsk_buff_pool Maciej Fijalkowski
@ 2024-10-02 15:54 ` Maciej Fijalkowski
  2024-10-02 15:54 ` [PATCH bpf-next 6/6] xsk: use xsk_buff_pool directly for cq functions Maciej Fijalkowski
  5 siblings, 0 replies; 11+ messages in thread
From: Maciej Fijalkowski @ 2024-10-02 15:54 UTC (permalink / raw)
  To: bpf, ast, daniel, andrii
  Cc: netdev, magnus.karlsson, bjorn, maciej.fijalkowski

Both allocation paths have exactly the same code responsible for getting
and initializing xskb. Pull it out to common function.

Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
---
 net/xdp/xsk_buff_pool.c | 34 ++++++++++++++++++----------------
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
index e946ba4a5ccf..ae71da7d2cd6 100644
--- a/net/xdp/xsk_buff_pool.c
+++ b/net/xdp/xsk_buff_pool.c
@@ -503,6 +503,22 @@ static bool xp_check_aligned(struct xsk_buff_pool *pool, u64 *addr)
 	return *addr < pool->addrs_cnt;
 }
 
+static struct xdp_buff_xsk *xp_get_xskb(struct xsk_buff_pool *pool, u64 addr)
+{
+	struct xdp_buff_xsk *xskb;
+
+	if (pool->unaligned) {
+		xskb = pool->free_heads[--pool->free_heads_cnt];
+		xp_init_xskb_addr(xskb, pool, addr);
+		if (pool->dma_pages)
+			xp_init_xskb_dma(xskb, pool, pool->dma_pages, addr);
+	} else {
+		xskb = &pool->heads[xp_aligned_extract_idx(pool, addr)];
+	}
+
+	return xskb;
+}
+
 static struct xdp_buff_xsk *__xp_alloc(struct xsk_buff_pool *pool)
 {
 	struct xdp_buff_xsk *xskb;
@@ -528,14 +544,7 @@ static struct xdp_buff_xsk *__xp_alloc(struct xsk_buff_pool *pool)
 		break;
 	}
 
-	if (pool->unaligned) {
-		xskb = pool->free_heads[--pool->free_heads_cnt];
-		xp_init_xskb_addr(xskb, pool, addr);
-		if (pool->dma_pages)
-			xp_init_xskb_dma(xskb, pool, pool->dma_pages, addr);
-	} else {
-		xskb = &pool->heads[xp_aligned_extract_idx(pool, addr)];
-	}
+	xskb = xp_get_xskb(pool, addr);
 
 	xskq_cons_release(pool->fq);
 	return xskb;
@@ -593,14 +602,7 @@ static u32 xp_alloc_new_from_fq(struct xsk_buff_pool *pool, struct xdp_buff **xd
 			continue;
 		}
 
-		if (pool->unaligned) {
-			xskb = pool->free_heads[--pool->free_heads_cnt];
-			xp_init_xskb_addr(xskb, pool, addr);
-			if (pool->dma_pages)
-				xp_init_xskb_dma(xskb, pool, pool->dma_pages, addr);
-		} else {
-			xskb = &pool->heads[xp_aligned_extract_idx(pool, addr)];
-		}
+		xskb = xp_get_xskb(pool, addr);
 
 		*xdp = &xskb->xdp;
 		xdp++;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH bpf-next 6/6] xsk: use xsk_buff_pool directly for cq functions
  2024-10-02 15:54 [PATCH bpf-next 0/6] xsk: struct diet and cleanups Maciej Fijalkowski
                   ` (4 preceding siblings ...)
  2024-10-02 15:54 ` [PATCH bpf-next 5/6] xsk: wrap duplicated code to function Maciej Fijalkowski
@ 2024-10-02 15:54 ` Maciej Fijalkowski
  5 siblings, 0 replies; 11+ messages in thread
From: Maciej Fijalkowski @ 2024-10-02 15:54 UTC (permalink / raw)
  To: bpf, ast, daniel, andrii
  Cc: netdev, magnus.karlsson, bjorn, maciej.fijalkowski

Currently xsk_cq_{reserve_addr,submit,cancel}_locked() take xdp_sock as
an input argument but it is only used for pulling out xsk_buff_pool
pointer from it.

Change mentioned functions to take pool pointer as an input argument to
avoid unnecessary dereferences.

Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
---
 net/xdp/xsk.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 6c31c1de1619..7d7e37f53708 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -527,34 +527,34 @@ static int xsk_wakeup(struct xdp_sock *xs, u8 flags)
 	return dev->netdev_ops->ndo_xsk_wakeup(dev, xs->queue_id, flags);
 }
 
-static int xsk_cq_reserve_addr_locked(struct xdp_sock *xs, u64 addr)
+static int xsk_cq_reserve_addr_locked(struct xsk_buff_pool *pool, u64 addr)
 {
 	unsigned long flags;
 	int ret;
 
-	spin_lock_irqsave(&xs->pool->cq_lock, flags);
-	ret = xskq_prod_reserve_addr(xs->pool->cq, addr);
-	spin_unlock_irqrestore(&xs->pool->cq_lock, flags);
+	spin_lock_irqsave(&pool->cq_lock, flags);
+	ret = xskq_prod_reserve_addr(pool->cq, addr);
+	spin_unlock_irqrestore(&pool->cq_lock, flags);
 
 	return ret;
 }
 
-static void xsk_cq_submit_locked(struct xdp_sock *xs, u32 n)
+static void xsk_cq_submit_locked(struct xsk_buff_pool *pool, u32 n)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&xs->pool->cq_lock, flags);
-	xskq_prod_submit_n(xs->pool->cq, n);
-	spin_unlock_irqrestore(&xs->pool->cq_lock, flags);
+	spin_lock_irqsave(&pool->cq_lock, flags);
+	xskq_prod_submit_n(pool->cq, n);
+	spin_unlock_irqrestore(&pool->cq_lock, flags);
 }
 
-static void xsk_cq_cancel_locked(struct xdp_sock *xs, u32 n)
+static void xsk_cq_cancel_locked(struct xsk_buff_pool *pool, u32 n)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&xs->pool->cq_lock, flags);
-	xskq_prod_cancel_n(xs->pool->cq, n);
-	spin_unlock_irqrestore(&xs->pool->cq_lock, flags);
+	spin_lock_irqsave(&pool->cq_lock, flags);
+	xskq_prod_cancel_n(pool->cq, n);
+	spin_unlock_irqrestore(&pool->cq_lock, flags);
 }
 
 static u32 xsk_get_num_desc(struct sk_buff *skb)
@@ -571,7 +571,7 @@ static void xsk_destruct_skb(struct sk_buff *skb)
 		*compl->tx_timestamp = ktime_get_tai_fast_ns();
 	}
 
-	xsk_cq_submit_locked(xdp_sk(skb->sk), xsk_get_num_desc(skb));
+	xsk_cq_submit_locked(xdp_sk(skb->sk)->pool, xsk_get_num_desc(skb));
 	sock_wfree(skb);
 }
 
@@ -587,7 +587,7 @@ static void xsk_consume_skb(struct sk_buff *skb)
 	struct xdp_sock *xs = xdp_sk(skb->sk);
 
 	skb->destructor = sock_wfree;
-	xsk_cq_cancel_locked(xs, xsk_get_num_desc(skb));
+	xsk_cq_cancel_locked(xs->pool, xsk_get_num_desc(skb));
 	/* Free skb without triggering the perf drop trace */
 	consume_skb(skb);
 	xs->skb = NULL;
@@ -765,7 +765,7 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
 		xskq_cons_release(xs->tx);
 	} else {
 		/* Let application retry */
-		xsk_cq_cancel_locked(xs, 1);
+		xsk_cq_cancel_locked(xs->pool, 1);
 	}
 
 	return ERR_PTR(err);
@@ -802,7 +802,7 @@ static int __xsk_generic_xmit(struct sock *sk)
 		 * if there is space in it. This avoids having to implement
 		 * any buffering in the Tx path.
 		 */
-		if (xsk_cq_reserve_addr_locked(xs, desc.addr))
+		if (xsk_cq_reserve_addr_locked(xs->pool, desc.addr))
 			goto out;
 
 		skb = xsk_build_skb(xs, &desc);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next 4/6] xsk: carry a copy of xdp_zc_max_segs within xsk_buff_pool
  2024-10-02 15:54 ` [PATCH bpf-next 4/6] xsk: carry a copy of xdp_zc_max_segs within xsk_buff_pool Maciej Fijalkowski
@ 2024-10-02 19:41   ` Vadim Fedorenko
  2024-10-03 11:47     ` Maciej Fijalkowski
  0 siblings, 1 reply; 11+ messages in thread
From: Vadim Fedorenko @ 2024-10-02 19:41 UTC (permalink / raw)
  To: Maciej Fijalkowski, bpf, ast, daniel, andrii
  Cc: netdev, magnus.karlsson, bjorn

On 02/10/2024 16:54, Maciej Fijalkowski wrote:
> This so we avoid dereferencing struct net_device within hot path.
> 
> Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
> ---
>   include/net/xsk_buff_pool.h | 1 +
>   net/xdp/xsk_buff_pool.c     | 1 +
>   net/xdp/xsk_queue.h         | 2 +-
>   3 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h
> index 468a23b1b4c5..8223581d95f8 100644
> --- a/include/net/xsk_buff_pool.h
> +++ b/include/net/xsk_buff_pool.h
> @@ -77,6 +77,7 @@ struct xsk_buff_pool {
>   	u32 chunk_shift;
>   	u32 frame_len;
>   	u8 tx_metadata_len; /* inherited from umem */
> +	u32 xdp_zc_max_segs;

It's better not to make holes in the struct. And looks like it's better
to move it closer to free_list_cnt to put it on the same cache line with
tx_descs which is accessed earlier in xskq_cons_read_desc_batch()
(though the last point is not strict because both cache lines should be
hot at the moment)

>   	u8 cached_need_wakeup;
>   	bool uses_need_wakeup;
>   	bool unaligned;



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next 4/6] xsk: carry a copy of xdp_zc_max_segs within xsk_buff_pool
  2024-10-02 19:41   ` Vadim Fedorenko
@ 2024-10-03 11:47     ` Maciej Fijalkowski
  0 siblings, 0 replies; 11+ messages in thread
From: Maciej Fijalkowski @ 2024-10-03 11:47 UTC (permalink / raw)
  To: Vadim Fedorenko; +Cc: bpf, ast, daniel, andrii, netdev, magnus.karlsson, bjorn

On Wed, Oct 02, 2024 at 08:41:33PM +0100, Vadim Fedorenko wrote:
> On 02/10/2024 16:54, Maciej Fijalkowski wrote:
> > This so we avoid dereferencing struct net_device within hot path.
> > 
> > Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
> > ---
> >   include/net/xsk_buff_pool.h | 1 +
> >   net/xdp/xsk_buff_pool.c     | 1 +
> >   net/xdp/xsk_queue.h         | 2 +-
> >   3 files changed, 3 insertions(+), 1 deletion(-)
> > 
> > diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h
> > index 468a23b1b4c5..8223581d95f8 100644
> > --- a/include/net/xsk_buff_pool.h
> > +++ b/include/net/xsk_buff_pool.h
> > @@ -77,6 +77,7 @@ struct xsk_buff_pool {
> >   	u32 chunk_shift;
> >   	u32 frame_len;
> >   	u8 tx_metadata_len; /* inherited from umem */
> > +	u32 xdp_zc_max_segs;
> 
> It's better not to make holes in the struct. And looks like it's better
> to move it closer to free_list_cnt to put it on the same cache line with
> tx_descs which is accessed earlier in xskq_cons_read_desc_batch()
> (though the last point is not strict because both cache lines should be
> hot at the moment)

Hi Vadim,

Yeah I agree placement is awkward, i'll move this above tx_metadata_len to
keep booleans together. CL is correct though as ::unaligned is accessed
when parsing/validating descs so as you said, both these CLs are supposed
to be hot.

Thanks for review! Will send a v2.

> 
> >   	u8 cached_need_wakeup;
> >   	bool uses_need_wakeup;
> >   	bool unaligned;
> 
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next 1/6] xsk: get rid of xdp_buff_xsk::xskb_list_node
  2024-10-02 15:54 ` [PATCH bpf-next 1/6] xsk: get rid of xdp_buff_xsk::xskb_list_node Maciej Fijalkowski
@ 2024-10-04 12:08   ` Daniel Borkmann
  2024-10-07 12:16     ` Maciej Fijalkowski
  0 siblings, 1 reply; 11+ messages in thread
From: Daniel Borkmann @ 2024-10-04 12:08 UTC (permalink / raw)
  To: Maciej Fijalkowski, bpf, ast, andrii; +Cc: netdev, magnus.karlsson, bjorn

On 10/2/24 5:54 PM, Maciej Fijalkowski wrote:
> Let's bring xdp_buff_xsk back to occupying 2 cachelines by removing
> xskb_list_node - for the purpose of gathering the xskb frags
> free_list_node can be used, head of the list (xsk_buff_pool::xskb_list)
> stays as-is, just reuse the node ptr.
> 
> It is safe to do as a single xdp_buff_xsk can never reside in two
> pool's lists simultaneously.
> 
> Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>

Given you send v2 anyway, pls also double check the clang errors from netdev CI:
https://netdev.bots.linux.dev/static/nipa/894909/13820003/build_clang/summary

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH bpf-next 1/6] xsk: get rid of xdp_buff_xsk::xskb_list_node
  2024-10-04 12:08   ` Daniel Borkmann
@ 2024-10-07 12:16     ` Maciej Fijalkowski
  0 siblings, 0 replies; 11+ messages in thread
From: Maciej Fijalkowski @ 2024-10-07 12:16 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: bpf, ast, andrii, netdev, magnus.karlsson, bjorn

On Fri, Oct 04, 2024 at 02:08:38PM +0200, Daniel Borkmann wrote:
> On 10/2/24 5:54 PM, Maciej Fijalkowski wrote:
> > Let's bring xdp_buff_xsk back to occupying 2 cachelines by removing
> > xskb_list_node - for the purpose of gathering the xskb frags
> > free_list_node can be used, head of the list (xsk_buff_pool::xskb_list)
> > stays as-is, just reuse the node ptr.
> > 
> > It is safe to do as a single xdp_buff_xsk can never reside in two
> > pool's lists simultaneously.
> > 
> > Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
> 
> Given you send v2 anyway, pls also double check the clang errors from netdev CI:
> https://netdev.bots.linux.dev/static/nipa/894909/13820003/build_clang/summary

Thanks, fixed in v2.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2024-10-07 12:16 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-02 15:54 [PATCH bpf-next 0/6] xsk: struct diet and cleanups Maciej Fijalkowski
2024-10-02 15:54 ` [PATCH bpf-next 1/6] xsk: get rid of xdp_buff_xsk::xskb_list_node Maciej Fijalkowski
2024-10-04 12:08   ` Daniel Borkmann
2024-10-07 12:16     ` Maciej Fijalkowski
2024-10-02 15:54 ` [PATCH bpf-next 2/6] xsk: s/free_list_node/list_node Maciej Fijalkowski
2024-10-02 15:54 ` [PATCH bpf-next 3/6] xsk: get rid of xdp_buff_xsk::orig_addr Maciej Fijalkowski
2024-10-02 15:54 ` [PATCH bpf-next 4/6] xsk: carry a copy of xdp_zc_max_segs within xsk_buff_pool Maciej Fijalkowski
2024-10-02 19:41   ` Vadim Fedorenko
2024-10-03 11:47     ` Maciej Fijalkowski
2024-10-02 15:54 ` [PATCH bpf-next 5/6] xsk: wrap duplicated code to function Maciej Fijalkowski
2024-10-02 15:54 ` [PATCH bpf-next 6/6] xsk: use xsk_buff_pool directly for cq functions Maciej Fijalkowski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).