From: Alexander Lobakin <aleksander.lobakin@intel.com>
To: intel-wired-lan@lists.osuosl.org
Cc: Alexander Lobakin <aleksander.lobakin@intel.com>,
Michal Kubiak <michal.kubiak@intel.com>,
Maciej Fijalkowski <maciej.fijalkowski@intel.com>,
Tony Nguyen <anthony.l.nguyen@intel.com>,
Przemek Kitszel <przemyslaw.kitszel@intel.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Jesper Dangaard Brouer <hawk@kernel.org>,
John Fastabend <john.fastabend@gmail.com>,
Simon Horman <horms@kernel.org>,
bpf@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH iwl-next 16/16] libeth: xdp, xsk: access adjacent u32s as u64 where applicable
Date: Tue, 15 Apr 2025 19:28:25 +0200 [thread overview]
Message-ID: <20250415172825.3731091-17-aleksander.lobakin@intel.com> (raw)
In-Reply-To: <20250415172825.3731091-1-aleksander.lobakin@intel.com>
On 64-bit systems, writing/reading one u64 is faster than two u32s even
when they're are adjacent in a struct. The compilers won't guarantee
they will combine those; I observed both successful and unsuccessful
attempts with both GCC and Clang, and it's not easy to say what it
depends on.
There's a few places in libeth_xdp winning up to several percent from
combined access (both performance and object code size, especially
when unrolling). Add __LIBETH_WORD_ACCESS and use it there on LE.
Drivers are free to optimize HW-specific callbacks under the same
definition.
Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
---
include/net/libeth/xdp.h | 29 ++++++++++++++++++++++++++---
include/net/libeth/xsk.h | 10 +++++-----
2 files changed, 31 insertions(+), 8 deletions(-)
diff --git a/include/net/libeth/xdp.h b/include/net/libeth/xdp.h
index 85f058482fc7..6d15386aff31 100644
--- a/include/net/libeth/xdp.h
+++ b/include/net/libeth/xdp.h
@@ -464,6 +464,21 @@ struct libeth_xdp_tx_desc {
((const void *)(uintptr_t)(priv)); \
})
+/*
+ * On 64-bit systems, assigning one u64 is faster than two u32s. When ::len
+ * occupies lowest 32 bits (LE), whole ::opts can be assigned directly instead.
+ */
+#ifdef __LITTLE_ENDIAN
+#define __LIBETH_WORD_ACCESS 1
+#endif
+#ifdef __LIBETH_WORD_ACCESS
+#define __libeth_xdp_tx_len(flen, ...) \
+ .opts = ((flen) | FIELD_PREP(GENMASK_ULL(63, 32), (__VA_ARGS__ + 0)))
+#else
+#define __libeth_xdp_tx_len(flen, ...) \
+ .len = (flen), .flags = (__VA_ARGS__ + 0)
+#endif
+
/**
* libeth_xdp_tx_xmit_bulk - main XDP Tx function
* @bulk: array of frames to send
@@ -863,8 +878,7 @@ static inline u32 libeth_xdp_xmit_queue_head(struct libeth_xdp_tx_bulk *bq,
bq->bulk[bq->count++] = (typeof(*bq->bulk)){
.xdpf = xdpf,
- .len = xdpf->len,
- .flags = LIBETH_XDP_TX_FIRST,
+ __libeth_xdp_tx_len(xdpf->len, LIBETH_XDP_TX_FIRST),
};
if (!xdp_frame_has_frags(xdpf))
@@ -895,7 +909,7 @@ static inline bool libeth_xdp_xmit_queue_frag(struct libeth_xdp_tx_bulk *bq,
bq->bulk[bq->count++] = (typeof(*bq->bulk)){
.dma = dma,
- .len = skb_frag_size(frag),
+ __libeth_xdp_tx_len(skb_frag_size(frag)),
};
return true;
@@ -1253,6 +1267,7 @@ bool libeth_xdp_buff_add_frag(struct libeth_xdp_buff *xdp,
* Internal, use libeth_xdp_process_buff() instead. Initializes XDP buffer
* head with the Rx buffer data: data pointer, length, headroom, and
* truesize/tailroom. Zeroes the flags.
+ * Uses faster single u64 write instead of per-field access.
*/
static inline void libeth_xdp_prepare_buff(struct libeth_xdp_buff *xdp,
const struct libeth_fqe *fqe,
@@ -1260,7 +1275,15 @@ static inline void libeth_xdp_prepare_buff(struct libeth_xdp_buff *xdp,
{
const struct page *page = __netmem_to_page(fqe->netmem);
+#ifdef __LIBETH_WORD_ACCESS
+ static_assert(offsetofend(typeof(xdp->base), flags) -
+ offsetof(typeof(xdp->base), frame_sz) ==
+ sizeof(u64));
+
+ *(u64 *)&xdp->base.frame_sz = fqe->truesize;
+#else
xdp_init_buff(&xdp->base, fqe->truesize, xdp->base.rxq);
+#endif
xdp_prepare_buff(&xdp->base, page_address(page) + fqe->offset,
page->pp->p.offset, len, true);
}
diff --git a/include/net/libeth/xsk.h b/include/net/libeth/xsk.h
index 213778a68476..481a7b28e6f2 100644
--- a/include/net/libeth/xsk.h
+++ b/include/net/libeth/xsk.h
@@ -26,8 +26,8 @@ static inline bool libeth_xsk_tx_queue_head(struct libeth_xdp_tx_bulk *bq,
{
bq->bulk[bq->count++] = (typeof(*bq->bulk)){
.xsk = xdp,
- .len = xdp->base.data_end - xdp->data,
- .flags = LIBETH_XDP_TX_FIRST,
+ __libeth_xdp_tx_len(xdp->base.data_end - xdp->data,
+ LIBETH_XDP_TX_FIRST),
};
if (likely(!xdp_buff_has_frags(&xdp->base)))
@@ -48,7 +48,7 @@ static inline void libeth_xsk_tx_queue_frag(struct libeth_xdp_tx_bulk *bq,
{
bq->bulk[bq->count++] = (typeof(*bq->bulk)){
.xsk = frag,
- .len = frag->base.data_end - frag->data,
+ __libeth_xdp_tx_len(frag->base.data_end - frag->data),
};
}
@@ -199,7 +199,7 @@ __libeth_xsk_xmit_fill_buf_md(const struct xdp_desc *xdesc,
ctx = xsk_buff_raw_get_ctx(sq->pool, xdesc->addr);
desc = (typeof(desc)){
.addr = ctx.dma,
- .len = xdesc->len,
+ __libeth_xdp_tx_len(xdesc->len),
};
BUILD_BUG_ON(!__builtin_constant_p(tmo == libeth_xsktmo));
@@ -226,7 +226,7 @@ __libeth_xsk_xmit_fill_buf(const struct xdp_desc *xdesc,
{
return (struct libeth_xdp_tx_desc){
.addr = xsk_buff_raw_get_dma(sq->pool, xdesc->addr),
- .len = xdesc->len,
+ __libeth_xdp_tx_len(xdesc->len),
};
}
--
2.49.0
prev parent reply other threads:[~2025-04-15 17:30 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-15 17:28 [PATCH iwl-next 00/16] libeth: add libeth_xdp helper lib Alexander Lobakin
2025-04-15 17:28 ` [PATCH iwl-next 01/16] libeth: convert to netmem Alexander Lobakin
2025-04-16 6:54 ` [Intel-wired-lan] " Loktionov, Aleksandr
2025-04-17 12:26 ` Alexander Lobakin
2025-04-15 17:28 ` [PATCH iwl-next 02/16] libeth: support native XDP and register memory model Alexander Lobakin
2025-04-15 17:28 ` [PATCH iwl-next 03/16] libeth: xdp: add XDP_TX buffers sending Alexander Lobakin
2025-04-24 12:48 ` Maciej Fijalkowski
2025-05-13 14:58 ` Alexander Lobakin
2025-04-15 17:28 ` [PATCH iwl-next 04/16] libeth: xdp: add .ndo_xdp_xmit() helpers Alexander Lobakin
2025-04-24 13:06 ` Maciej Fijalkowski
2025-04-15 17:28 ` [PATCH iwl-next 05/16] libeth: xdp: add XDPSQE completion helpers Alexander Lobakin
2025-04-15 17:28 ` [PATCH iwl-next 06/16] libeth: xdp: add XDPSQ locking helpers Alexander Lobakin
2025-04-24 15:27 ` Maciej Fijalkowski
2025-04-15 17:28 ` [PATCH iwl-next 07/16] libeth: xdp: add XDPSQ cleanup timers Alexander Lobakin
2025-04-24 15:33 ` Maciej Fijalkowski
2025-04-15 17:28 ` [PATCH iwl-next 08/16] libeth: xdp: add helpers for preparing/processing &libeth_xdp_buff Alexander Lobakin
2025-04-15 17:28 ` [PATCH iwl-next 09/16] libeth: xdp: add XDP prog run and verdict result handling Alexander Lobakin
2025-04-15 17:28 ` [PATCH iwl-next 10/16] libeth: xdp: add templates for building driver-side callbacks Alexander Lobakin
2025-04-15 17:28 ` [PATCH iwl-next 11/16] libeth: xdp: add RSS hash hint and XDP features setup helpers Alexander Lobakin
2025-04-15 17:28 ` [PATCH iwl-next 12/16] libeth: xsk: add XSk XDP_TX sending helpers Alexander Lobakin
2025-04-15 17:28 ` [PATCH iwl-next 13/16] libeth: xsk: add XSk xmit functions Alexander Lobakin
2025-04-15 17:28 ` [PATCH iwl-next 14/16] libeth: xsk: add XSk Rx processing support Alexander Lobakin
2025-04-15 17:28 ` [PATCH iwl-next 15/16] libeth: xsk: add XSkFQ refill and XSk wakeup helpers Alexander Lobakin
2025-04-15 17:28 ` Alexander Lobakin [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250415172825.3731091-17-aleksander.lobakin@intel.com \
--to=aleksander.lobakin@intel.com \
--cc=andrew+netdev@lunn.ch \
--cc=anthony.l.nguyen@intel.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=hawk@kernel.org \
--cc=horms@kernel.org \
--cc=intel-wired-lan@lists.osuosl.org \
--cc=john.fastabend@gmail.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maciej.fijalkowski@intel.com \
--cc=michal.kubiak@intel.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=przemyslaw.kitszel@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®