* [PATCH net v2 0/3] xsk: pre-existing AF_XDP TX metadata fixes from Sashiko
@ 2026-08-13 19:07 Stanislav Fomichev
2026-08-13 19:07 ` [PATCH net v2 1/3] xsk: align TX metadata layout across ABIs Stanislav Fomichev
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Stanislav Fomichev @ 2026-08-13 19:07 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, anthony.l.nguyen,
przemyslaw.kitszel, andrew+netdev, saeedm, tariqt, mbloch,
maxime.chevallier, mcoquelin.stm32, alexandre.torgue,
aleksander.lobakin, horms, magnus.karlsson, maciej.fijalkowski,
sdf, ast, daniel, hawk, john.fastabend, witu, martin.lau,
yoong.siang.song, rohan.g.thomas, intel-wired-lan, linux-kernel,
linux-rdma, linux-stm32, linux-arm-kernel, bpf, leon
A few fixes to address pre-existing issues from Sashiko review.
Notes on the feedback from net-next v1 posting [0]:
- It correctly complains about ABI breakage for 32 bit systems, added
an explanation why I think we unlikely to have any 32 bit users with
launch time
- mlx5 batching (pre existing) - I think my point in the comment still
stays (that we do not make it worse)
- stmmac recycled descriptors (pre existing) - seems valid but I don't feel
confident sending a vibe-coded fix
- stmmac queueMaxSDU vs taprio offload - don't think this is real but
we can fix separately later if it is (the existing issue with breaking
xsk seems more real)
v2:
- target net, address clashiko feedback (mostly here and other commit
descriptions)
0: from https://netdev-ai.bots.linux.dev/sashiko/#/message/20260810184753.135756-1-sdf%40fomichev.me
Stanislav Fomichev (3):
xsk: align TX metadata layout across ABIs
xsk: honor XDP_TX_METADATA in zero-copy path
net: stmmac: skip queueMaxSDU check for AF_XDP
drivers/net/ethernet/intel/igc/igc_main.c | 3 ++-
.../ethernet/mellanox/mlx5/core/en/xsk/tx.c | 2 +-
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 10 ++-------
include/net/libeth/xsk.h | 2 +-
include/net/xdp_sock_drv.h | 22 +++++++++++--------
include/net/xsk_buff_pool.h | 3 ++-
include/uapi/linux/if_xdp.h | 1 +
net/xdp/xsk_buff_pool.c | 7 ++++--
tools/include/uapi/linux/if_xdp.h | 1 +
9 files changed, 28 insertions(+), 23 deletions(-)
--
2.53.0-Meta
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH net v2 1/3] xsk: align TX metadata layout across ABIs
2026-08-13 19:07 [PATCH net v2 0/3] xsk: pre-existing AF_XDP TX metadata fixes from Sashiko Stanislav Fomichev
@ 2026-08-13 19:07 ` Stanislav Fomichev
2026-08-13 19:07 ` [PATCH net v2 2/3] xsk: honor XDP_TX_METADATA in zero-copy path Stanislav Fomichev
2026-08-13 19:08 ` [PATCH net v2 3/3] net: stmmac: skip queueMaxSDU check for AF_XDP Stanislav Fomichev
2 siblings, 0 replies; 4+ messages in thread
From: Stanislav Fomichev @ 2026-08-13 19:07 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, anthony.l.nguyen,
przemyslaw.kitszel, andrew+netdev, saeedm, tariqt, mbloch,
maxime.chevallier, mcoquelin.stm32, alexandre.torgue,
aleksander.lobakin, horms, magnus.karlsson, maciej.fijalkowski,
sdf, ast, daniel, hawk, john.fastabend, witu, martin.lau,
yoong.siang.song, rohan.g.thomas, intel-wired-lan, linux-kernel,
linux-rdma, linux-stm32, linux-arm-kernel, bpf, leon
Add explicit padding before launch_time so xsk_tx_metadata has the same
layout on 32-bit and 64-bit systems.
On i386 and m68k, the old native 32-bit layout put launch_time at offset 12
and had a natural size of 20 bytes. Using sizeof(struct xsk_tx_metadata) as
tx_metadata_len was already rejected because the length must be a multiple
of eight, so the straightforward use of the interface was broken on those
ABIs. Userspace could still register a padded length of 24 bytes, though;
mixing the old and new layouts then silently reads launch_time from the
wrong offset and misprograms packet launch times. This intentionally
replaces that incompatible layout while the interface is still new.
Fixes: ca4419f15abd ("xsk: Add launch time hardware offload support to XDP Tx metadata")
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
---
include/uapi/linux/if_xdp.h | 1 +
tools/include/uapi/linux/if_xdp.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/include/uapi/linux/if_xdp.h b/include/uapi/linux/if_xdp.h
index 23a062781468..50d67df78911 100644
--- a/include/uapi/linux/if_xdp.h
+++ b/include/uapi/linux/if_xdp.h
@@ -149,6 +149,7 @@ struct xsk_tx_metadata {
__u16 csum_start;
/* Offset from csum_start where checksum should be stored. */
__u16 csum_offset;
+ __u32 reserved;
/* XDP_TXMD_FLAGS_LAUNCH_TIME */
/* Launch time in nanosecond against the PTP HW Clock */
diff --git a/tools/include/uapi/linux/if_xdp.h b/tools/include/uapi/linux/if_xdp.h
index 23a062781468..50d67df78911 100644
--- a/tools/include/uapi/linux/if_xdp.h
+++ b/tools/include/uapi/linux/if_xdp.h
@@ -149,6 +149,7 @@ struct xsk_tx_metadata {
__u16 csum_start;
/* Offset from csum_start where checksum should be stored. */
__u16 csum_offset;
+ __u32 reserved;
/* XDP_TXMD_FLAGS_LAUNCH_TIME */
/* Launch time in nanosecond against the PTP HW Clock */
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH net v2 2/3] xsk: honor XDP_TX_METADATA in zero-copy path
2026-08-13 19:07 [PATCH net v2 0/3] xsk: pre-existing AF_XDP TX metadata fixes from Sashiko Stanislav Fomichev
2026-08-13 19:07 ` [PATCH net v2 1/3] xsk: align TX metadata layout across ABIs Stanislav Fomichev
@ 2026-08-13 19:07 ` Stanislav Fomichev
2026-08-13 19:08 ` [PATCH net v2 3/3] net: stmmac: skip queueMaxSDU check for AF_XDP Stanislav Fomichev
2 siblings, 0 replies; 4+ messages in thread
From: Stanislav Fomichev @ 2026-08-13 19:07 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, anthony.l.nguyen,
przemyslaw.kitszel, andrew+netdev, saeedm, tariqt, mbloch,
maxime.chevallier, mcoquelin.stm32, alexandre.torgue,
aleksander.lobakin, horms, magnus.karlsson, maciej.fijalkowski,
sdf, ast, daniel, hawk, john.fastabend, witu, martin.lau,
yoong.siang.song, rohan.g.thomas, intel-wired-lan, linux-kernel,
linux-rdma, linux-stm32, linux-arm-kernel, bpf, leon
The zero-copy path reads TX metadata whenever the UMEM has metadata space,
even if the descriptor does not set XDP_TX_METADATA. Pass descriptor
options through the metadata helpers and ignore metadata unless the option
is set.
This does not fix the existing per-WQE metadata handling for mlx5 MPWQEs.
Only the descriptor that starts a session passes through
xsk_tx_metadata_request() and configures offload state shared by the batch.
Metadata on descriptors joining an open session is therefore not validated
and does not configure its requested offloads. In addition, a non-NULL
metadata pointer from such a descriptor is treated as a timestamp
completion request even when XDP_TXMD_FLAGS_TIMESTAMP is not set, so its
metadata union can be overwritten with an unrequested timestamp. Fixing
mixed metadata states within one MPWQE requires a separate change.
Fixes: 48eb03dd2630 ("xsk: Add TX timestamp and TX checksum offload support")
Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
---
drivers/net/ethernet/intel/igc/igc_main.c | 3 ++-
.../ethernet/mellanox/mlx5/core/en/xsk/tx.c | 2 +-
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 3 ++-
include/net/libeth/xsk.h | 2 +-
include/net/xdp_sock_drv.h | 22 +++++++++++--------
include/net/xsk_buff_pool.h | 3 ++-
net/xdp/xsk_buff_pool.c | 7 ++++--
7 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 39043d8ca1bf..59067939a586 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -3074,7 +3074,8 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring)
olinfo_status = xdp_desc.len << IGC_ADVTXD_PAYLEN_SHIFT;
dma = xsk_buff_raw_get_dma(pool, xdp_desc.addr);
- meta = xsk_buff_get_metadata(pool, xdp_desc.addr);
+ meta = xsk_buff_get_metadata(pool, xdp_desc.addr,
+ xdp_desc.options);
xsk_buff_raw_dma_sync_for_device(pool, dma, xdp_desc.len);
bi = &ring->tx_buffer_info[ntu];
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c
index 3d19dad8f868..d194eeddd7b5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c
@@ -99,7 +99,7 @@ bool mlx5e_xsk_tx(struct mlx5e_xdpsq *sq, unsigned int budget)
xdptxd.dma_addr = xsk_buff_raw_get_dma(pool, desc.addr);
xdptxd.data = xsk_buff_raw_get_data(pool, desc.addr);
xdptxd.len = desc.len;
- meta = xsk_buff_get_metadata(pool, desc.addr);
+ meta = xsk_buff_get_metadata(pool, desc.addr, desc.options);
xsk_buff_raw_dma_sync_for_device(pool, xdptxd.dma_addr, xdptxd.len);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index a71f0df26378..62de03e65a90 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2719,7 +2719,8 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
tx_desc = stmmac_get_tx_desc(priv, tx_q, entry);
dma_addr = xsk_buff_raw_get_dma(pool, xdp_desc.addr);
- meta = xsk_buff_get_metadata(pool, xdp_desc.addr);
+ meta = xsk_buff_get_metadata(pool, xdp_desc.addr,
+ xdp_desc.options);
xsk_buff_raw_dma_sync_for_device(pool, dma_addr, xdp_desc.len);
/* To return XDP buffer to XSK pool, we simple call
diff --git a/include/net/libeth/xsk.h b/include/net/libeth/xsk.h
index 5dcc0d7f65b7..a452b7828ce4 100644
--- a/include/net/libeth/xsk.h
+++ b/include/net/libeth/xsk.h
@@ -196,7 +196,7 @@ __libeth_xsk_xmit_fill_buf_md(const struct xdp_desc *xdesc,
struct libeth_xdp_tx_desc desc;
struct xdp_desc_ctx ctx;
- ctx = xsk_buff_raw_get_ctx(sq->pool, xdesc->addr);
+ ctx = xsk_buff_raw_get_ctx(sq->pool, xdesc->addr, xdesc->options);
desc = (typeof(desc)){
.addr = ctx.dma,
__libeth_xdp_tx_len(xdesc->len),
diff --git a/include/net/xdp_sock_drv.h b/include/net/xdp_sock_drv.h
index b344789f5df8..d94aeb506379 100644
--- a/include/net/xdp_sock_drv.h
+++ b/include/net/xdp_sock_drv.h
@@ -240,6 +240,7 @@ static inline void *xsk_buff_raw_get_data(struct xsk_buff_pool *pool, u64 addr)
* xsk_buff_raw_get_ctx - get &xdp_desc context
* @pool: XSk buff pool desc address belongs to
* @addr: desc address (from userspace)
+ * @options: desc options (from userspace)
*
* Wrapper for xp_raw_get_ctx() to be used in drivers, see its kdoc for
* details.
@@ -248,9 +249,9 @@ static inline void *xsk_buff_raw_get_data(struct xsk_buff_pool *pool, u64 addr)
* pointer, if it is present (initialized to %NULL otherwise).
*/
static inline struct xdp_desc_ctx
-xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr)
+xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr, u32 options)
{
- return xp_raw_get_ctx(pool, addr);
+ return xp_raw_get_ctx(pool, addr, options);
}
#define XDP_TXMD_FLAGS_VALID ( \
@@ -318,18 +319,20 @@ xsk_tx_metadata_request(const struct xsk_buff_pool *pool,
}
static inline struct xsk_tx_metadata *
-__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data)
+__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data,
+ unsigned int options)
{
- if (!pool->tx_metadata_len)
+ if (!pool->tx_metadata_len || !(options & XDP_TX_METADATA))
return NULL;
return data - pool->tx_metadata_len;
}
static inline struct xsk_tx_metadata *
-xsk_buff_get_metadata(struct xsk_buff_pool *pool, u64 addr)
+xsk_buff_get_metadata(struct xsk_buff_pool *pool, u64 addr, u32 options)
{
- return __xsk_buff_get_metadata(pool, xp_raw_get_data(pool, addr));
+ return __xsk_buff_get_metadata(pool, xp_raw_get_data(pool, addr),
+ options);
}
static inline void xsk_buff_dma_sync_for_cpu(struct xdp_buff *xdp)
@@ -510,7 +513,7 @@ static inline void *xsk_buff_raw_get_data(struct xsk_buff_pool *pool, u64 addr)
}
static inline struct xdp_desc_ctx
-xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr)
+xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr, u32 options)
{
return (struct xdp_desc_ctx){ };
}
@@ -530,13 +533,14 @@ xsk_tx_metadata_request(const struct xsk_buff_pool *pool,
}
static inline struct xsk_tx_metadata *
-__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data)
+__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data,
+ unsigned int options)
{
return NULL;
}
static inline struct xsk_tx_metadata *
-xsk_buff_get_metadata(struct xsk_buff_pool *pool, u64 addr)
+xsk_buff_get_metadata(struct xsk_buff_pool *pool, u64 addr, u32 options)
{
return NULL;
}
diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h
index 2bb1d122b1bc..a7df573784fd 100644
--- a/include/net/xsk_buff_pool.h
+++ b/include/net/xsk_buff_pool.h
@@ -154,7 +154,8 @@ struct xdp_desc_ctx {
struct xsk_tx_metadata *meta;
};
-struct xdp_desc_ctx xp_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr);
+struct xdp_desc_ctx xp_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr,
+ u32 options);
static inline dma_addr_t xp_get_dma(struct xdp_buff_xsk *xskb)
{
diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
index 78c14f106395..9d2d94f1fb75 100644
--- a/net/xdp/xsk_buff_pool.c
+++ b/net/xdp/xsk_buff_pool.c
@@ -763,6 +763,7 @@ EXPORT_SYMBOL(xp_raw_get_dma);
* xp_raw_get_ctx - get &xdp_desc context
* @pool: XSk buff pool desc address belongs to
* @addr: desc address (from userspace)
+ * @options: desc options (from userspace)
*
* Helper for getting desc's DMA address and metadata pointer, if present.
* Saves one call on hotpath and double calculation of the actual address.
@@ -771,14 +772,16 @@ EXPORT_SYMBOL(xp_raw_get_dma);
* Return: new &xdp_desc_ctx struct containing desc's DMA address and metadata
* pointer, if it is present (initialized to %NULL otherwise).
*/
-struct xdp_desc_ctx xp_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr)
+struct xdp_desc_ctx xp_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr,
+ u32 options)
{
struct xdp_desc_ctx ret;
addr = __xp_raw_get_addr(pool, addr);
ret.dma = __xp_raw_get_dma(pool, addr);
- ret.meta = __xsk_buff_get_metadata(pool, __xp_raw_get_data(pool, addr));
+ ret.meta = __xsk_buff_get_metadata(pool, __xp_raw_get_data(pool, addr),
+ options);
return ret;
}
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH net v2 3/3] net: stmmac: skip queueMaxSDU check for AF_XDP
2026-08-13 19:07 [PATCH net v2 0/3] xsk: pre-existing AF_XDP TX metadata fixes from Sashiko Stanislav Fomichev
2026-08-13 19:07 ` [PATCH net v2 1/3] xsk: align TX metadata layout across ABIs Stanislav Fomichev
2026-08-13 19:07 ` [PATCH net v2 2/3] xsk: honor XDP_TX_METADATA in zero-copy path Stanislav Fomichev
@ 2026-08-13 19:08 ` Stanislav Fomichev
2 siblings, 0 replies; 4+ messages in thread
From: Stanislav Fomichev @ 2026-08-13 19:08 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, anthony.l.nguyen,
przemyslaw.kitszel, andrew+netdev, saeedm, tariqt, mbloch,
maxime.chevallier, mcoquelin.stm32, alexandre.torgue,
aleksander.lobakin, horms, magnus.karlsson, maciej.fijalkowski,
sdf, ast, daniel, hawk, john.fastabend, witu, martin.lau,
yoong.siang.song, rohan.g.thomas, intel-wired-lan, linux-kernel,
linux-rdma, linux-stm32, linux-arm-kernel, bpf, leon
Commit c5c3e1bfc9e0 ("net: stmmac: Offload queueMaxSDU from tc-taprio")
was inspired by commit 92a0dcb8427d ("igc: offload queue max SDU from
tc-taprio"), but the igc change does not apply the check to AF_XDP.
xsk_tx_peek_desc() reserves a completion entry. Continuing without
queuing or completing the descriptor leaves the AF_XDP rings imbalanced,
so remove the check from the zero-copy path.
The assumptions is that AF_XDP zero-copy traffic bypasses the qdisc, so
taprio's queueMaxSDU check does not apply to this path.
Fixes: c5c3e1bfc9e0 ("net: stmmac: Offload queueMaxSDU from tc-taprio")
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 62de03e65a90..4a82f4351303 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2710,13 +2710,6 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
if (!xsk_tx_peek_desc(pool, &xdp_desc))
break;
- if (priv->est && priv->est->enable &&
- priv->est->max_sdu[queue] &&
- xdp_desc.len > priv->est->max_sdu[queue]) {
- priv->xstats.max_sdu_txq_drop[queue]++;
- continue;
- }
-
tx_desc = stmmac_get_tx_desc(priv, tx_q, entry);
dma_addr = xsk_buff_raw_get_dma(pool, xdp_desc.addr);
meta = xsk_buff_get_metadata(pool, xdp_desc.addr,
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-13 19:08 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-13 19:07 [PATCH net v2 0/3] xsk: pre-existing AF_XDP TX metadata fixes from Sashiko Stanislav Fomichev
2026-08-13 19:07 ` [PATCH net v2 1/3] xsk: align TX metadata layout across ABIs Stanislav Fomichev
2026-08-13 19:07 ` [PATCH net v2 2/3] xsk: honor XDP_TX_METADATA in zero-copy path Stanislav Fomichev
2026-08-13 19:08 ` [PATCH net v2 3/3] net: stmmac: skip queueMaxSDU check for AF_XDP Stanislav Fomichev
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox