| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/08/13 20:19 | flow | patch-triage |
3mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"KMSANReasoning": "",
"NeedsKMSAN": false,
"Reasoning": "The patch modifies the AF_XDP zero-copy TX metadata path to check the XDP_TX_METADATA option before accessing metadata. This logic is only implemented and reachable in specific hardware drivers (igc, mlx5, stmmac, idpf) which are not emulated in standard virtualized environments like QEMU. The patch also adds a reserved padding field to `struct xsk_tx_metadata` in the UAPI, which only alters a numeric constant (struct size) used in a length check in the generic XDP TX path, without introducing new functional logic worth fuzzing.",
"WorthFuzzing": false
} |
| 1/1 | 2026/08/13 20:19 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit fcab14997f2dc8ef4fcc3117aeba3e4fb6ab2172\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Thu Aug 13 20:19:05 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c\nindex 39043d8ca1bf4..59067939a586d 100644\n--- a/drivers/net/ethernet/intel/igc/igc_main.c\n+++ b/drivers/net/ethernet/intel/igc/igc_main.c\n@@ -3074,7 +3074,8 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring)\n \t\tolinfo_status = xdp_desc.len \u003c\u003c IGC_ADVTXD_PAYLEN_SHIFT;\n \n \t\tdma = xsk_buff_raw_get_dma(pool, xdp_desc.addr);\n-\t\tmeta = xsk_buff_get_metadata(pool, xdp_desc.addr);\n+\t\tmeta = xsk_buff_get_metadata(pool, xdp_desc.addr,\n+\t\t\t\t\t xdp_desc.options);\n \t\txsk_buff_raw_dma_sync_for_device(pool, dma, xdp_desc.len);\n \t\tbi = \u0026ring-\u003etx_buffer_info[ntu];\n \ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c\nindex 3d19dad8f8688..d194eeddd7b55 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c\n@@ -99,7 +99,7 @@ bool mlx5e_xsk_tx(struct mlx5e_xdpsq *sq, unsigned int budget)\n \t\txdptxd.dma_addr = xsk_buff_raw_get_dma(pool, desc.addr);\n \t\txdptxd.data = xsk_buff_raw_get_data(pool, desc.addr);\n \t\txdptxd.len = desc.len;\n-\t\tmeta = xsk_buff_get_metadata(pool, desc.addr);\n+\t\tmeta = xsk_buff_get_metadata(pool, desc.addr, desc.options);\n \n \t\txsk_buff_raw_dma_sync_for_device(pool, xdptxd.dma_addr, xdptxd.len);\n \ndiff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c\nindex a71f0df263785..4a82f4351303a 100644\n--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c\n+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c\n@@ -2710,16 +2710,10 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)\n \t\tif (!xsk_tx_peek_desc(pool, \u0026xdp_desc))\n \t\t\tbreak;\n \n-\t\tif (priv-\u003eest \u0026\u0026 priv-\u003eest-\u003eenable \u0026\u0026\n-\t\t priv-\u003eest-\u003emax_sdu[queue] \u0026\u0026\n-\t\t xdp_desc.len \u003e priv-\u003eest-\u003emax_sdu[queue]) {\n-\t\t\tpriv-\u003exstats.max_sdu_txq_drop[queue]++;\n-\t\t\tcontinue;\n-\t\t}\n-\n \t\ttx_desc = stmmac_get_tx_desc(priv, tx_q, entry);\n \t\tdma_addr = xsk_buff_raw_get_dma(pool, xdp_desc.addr);\n-\t\tmeta = xsk_buff_get_metadata(pool, xdp_desc.addr);\n+\t\tmeta = xsk_buff_get_metadata(pool, xdp_desc.addr,\n+\t\t\t\t\t xdp_desc.options);\n \t\txsk_buff_raw_dma_sync_for_device(pool, dma_addr, xdp_desc.len);\n \n \t\t/* To return XDP buffer to XSK pool, we simple call\ndiff --git a/include/net/libeth/xsk.h b/include/net/libeth/xsk.h\nindex 5dcc0d7f65b76..a452b7828ce4e 100644\n--- a/include/net/libeth/xsk.h\n+++ b/include/net/libeth/xsk.h\n@@ -196,7 +196,7 @@ __libeth_xsk_xmit_fill_buf_md(const struct xdp_desc *xdesc,\n \tstruct libeth_xdp_tx_desc desc;\n \tstruct xdp_desc_ctx ctx;\n \n-\tctx = xsk_buff_raw_get_ctx(sq-\u003epool, xdesc-\u003eaddr);\n+\tctx = xsk_buff_raw_get_ctx(sq-\u003epool, xdesc-\u003eaddr, xdesc-\u003eoptions);\n \tdesc = (typeof(desc)){\n \t\t.addr\t= ctx.dma,\n \t\t__libeth_xdp_tx_len(xdesc-\u003elen),\ndiff --git a/include/net/xdp_sock_drv.h b/include/net/xdp_sock_drv.h\nindex b344789f5df83..d94aeb506379c 100644\n--- a/include/net/xdp_sock_drv.h\n+++ b/include/net/xdp_sock_drv.h\n@@ -240,6 +240,7 @@ static inline void *xsk_buff_raw_get_data(struct xsk_buff_pool *pool, u64 addr)\n * xsk_buff_raw_get_ctx - get \u0026xdp_desc context\n * @pool: XSk buff pool desc address belongs to\n * @addr: desc address (from userspace)\n+ * @options: desc options (from userspace)\n *\n * Wrapper for xp_raw_get_ctx() to be used in drivers, see its kdoc for\n * details.\n@@ -248,9 +249,9 @@ static inline void *xsk_buff_raw_get_data(struct xsk_buff_pool *pool, u64 addr)\n * pointer, if it is present (initialized to %NULL otherwise).\n */\n static inline struct xdp_desc_ctx\n-xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr)\n+xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr, u32 options)\n {\n-\treturn xp_raw_get_ctx(pool, addr);\n+\treturn xp_raw_get_ctx(pool, addr, options);\n }\n \n #define XDP_TXMD_FLAGS_VALID ( \\\n@@ -318,18 +319,20 @@ xsk_tx_metadata_request(const struct xsk_buff_pool *pool,\n }\n \n static inline struct xsk_tx_metadata *\n-__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data)\n+__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data,\n+\t\t\tunsigned int options)\n {\n-\tif (!pool-\u003etx_metadata_len)\n+\tif (!pool-\u003etx_metadata_len || !(options \u0026 XDP_TX_METADATA))\n \t\treturn NULL;\n \n \treturn data - pool-\u003etx_metadata_len;\n }\n \n static inline struct xsk_tx_metadata *\n-xsk_buff_get_metadata(struct xsk_buff_pool *pool, u64 addr)\n+xsk_buff_get_metadata(struct xsk_buff_pool *pool, u64 addr, u32 options)\n {\n-\treturn __xsk_buff_get_metadata(pool, xp_raw_get_data(pool, addr));\n+\treturn __xsk_buff_get_metadata(pool, xp_raw_get_data(pool, addr),\n+\t\t\t\t options);\n }\n \n static inline void xsk_buff_dma_sync_for_cpu(struct xdp_buff *xdp)\n@@ -510,7 +513,7 @@ static inline void *xsk_buff_raw_get_data(struct xsk_buff_pool *pool, u64 addr)\n }\n \n static inline struct xdp_desc_ctx\n-xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr)\n+xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr, u32 options)\n {\n \treturn (struct xdp_desc_ctx){ };\n }\n@@ -530,13 +533,14 @@ xsk_tx_metadata_request(const struct xsk_buff_pool *pool,\n }\n \n static inline struct xsk_tx_metadata *\n-__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data)\n+__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data,\n+\t\t\tunsigned int options)\n {\n \treturn NULL;\n }\n \n static inline struct xsk_tx_metadata *\n-xsk_buff_get_metadata(struct xsk_buff_pool *pool, u64 addr)\n+xsk_buff_get_metadata(struct xsk_buff_pool *pool, u64 addr, u32 options)\n {\n \treturn NULL;\n }\ndiff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h\nindex 2bb1d122b1bc6..a7df573784fd6 100644\n--- a/include/net/xsk_buff_pool.h\n+++ b/include/net/xsk_buff_pool.h\n@@ -154,7 +154,8 @@ struct xdp_desc_ctx {\n \tstruct xsk_tx_metadata *meta;\n };\n \n-struct xdp_desc_ctx xp_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr);\n+struct xdp_desc_ctx xp_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr,\n+\t\t\t\t u32 options);\n \n static inline dma_addr_t xp_get_dma(struct xdp_buff_xsk *xskb)\n {\ndiff --git a/include/uapi/linux/if_xdp.h b/include/uapi/linux/if_xdp.h\nindex 23a0627814687..50d67df78911f 100644\n--- a/include/uapi/linux/if_xdp.h\n+++ b/include/uapi/linux/if_xdp.h\n@@ -149,6 +149,7 @@ struct xsk_tx_metadata {\n \t\t\t__u16 csum_start;\n \t\t\t/* Offset from csum_start where checksum should be stored. */\n \t\t\t__u16 csum_offset;\n+\t\t\t__u32 reserved;\n \n \t\t\t/* XDP_TXMD_FLAGS_LAUNCH_TIME */\n \t\t\t/* Launch time in nanosecond against the PTP HW Clock */\ndiff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c\nindex 78c14f1063957..9d2d94f1fb759 100644\n--- a/net/xdp/xsk_buff_pool.c\n+++ b/net/xdp/xsk_buff_pool.c\n@@ -763,6 +763,7 @@ EXPORT_SYMBOL(xp_raw_get_dma);\n * xp_raw_get_ctx - get \u0026xdp_desc context\n * @pool: XSk buff pool desc address belongs to\n * @addr: desc address (from userspace)\n+ * @options: desc options (from userspace)\n *\n * Helper for getting desc's DMA address and metadata pointer, if present.\n * Saves one call on hotpath and double calculation of the actual address.\n@@ -771,14 +772,16 @@ EXPORT_SYMBOL(xp_raw_get_dma);\n * Return: new \u0026xdp_desc_ctx struct containing desc's DMA address and metadata\n * pointer, if it is present (initialized to %NULL otherwise).\n */\n-struct xdp_desc_ctx xp_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr)\n+struct xdp_desc_ctx xp_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr,\n+\t\t\t\t u32 options)\n {\n \tstruct xdp_desc_ctx ret;\n \n \taddr = __xp_raw_get_addr(pool, addr);\n \n \tret.dma = __xp_raw_get_dma(pool, addr);\n-\tret.meta = __xsk_buff_get_metadata(pool, __xp_raw_get_data(pool, addr));\n+\tret.meta = __xsk_buff_get_metadata(pool, __xp_raw_get_data(pool, addr),\n+\t\t\t\t\t options);\n \n \treturn ret;\n }\ndiff --git a/tools/include/uapi/linux/if_xdp.h b/tools/include/uapi/linux/if_xdp.h\nindex 23a0627814687..50d67df78911f 100644\n--- a/tools/include/uapi/linux/if_xdp.h\n+++ b/tools/include/uapi/linux/if_xdp.h\n@@ -149,6 +149,7 @@ struct xsk_tx_metadata {\n \t\t\t__u16 csum_start;\n \t\t\t/* Offset from csum_start where checksum should be stored. */\n \t\t\t__u16 csum_offset;\n+\t\t\t__u32 reserved;\n \n \t\t\t/* XDP_TXMD_FLAGS_LAUNCH_TIME */\n \t\t\t/* Launch time in nanosecond against the PTP HW Clock */\n"
} |
| 2/1 | 2026/08/13 20:19 | agent | patch-evaluator |
3mModel:best-expensive Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the AF_XDP zero-copy TX metadata path to check the XDP_TX_METADATA option before accessing metadata. This logic is only implemented and reachable in specific hardware drivers (igc, mlx5, stmmac, idpf) which are not emulated in standard virtualized environments like QEMU. The patch also adds a reserved padding field to `struct xsk_tx_metadata` in the UAPI, which only alters a numeric constant (struct size) used in a length check in the generic XDP TX path, without introducing new functional logic worth fuzzing.",
"WorthFuzzing": false
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). - Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed, ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU. - Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove) that are executed only during PCI hot-unplug or sysfs driver unbind operations. If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. Prefer non-static, non-inlined API entrypoint functions over internal static helper functions (which are inlined by the compiler and do not have distinct symbol addresses). 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit fcab14997f2dc8ef4fcc3117aeba3e4fb6ab2172
Author: syz-cluster <triage@syzkaller.com>
Date: Thu Aug 13 20:19:05 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 39043d8ca1bf4..59067939a586d 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 3d19dad8f8688..d194eeddd7b55 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 a71f0df263785..4a82f4351303a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2710,16 +2710,10 @@ 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);
+ 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 5dcc0d7f65b76..a452b7828ce4e 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 b344789f5df83..d94aeb506379c 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 2bb1d122b1bc6..a7df573784fd6 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/include/uapi/linux/if_xdp.h b/include/uapi/linux/if_xdp.h
index 23a0627814687..50d67df78911f 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/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
index 78c14f1063957..9d2d94f1fb759 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;
}
diff --git a/tools/include/uapi/linux/if_xdp.h b/tools/include/uapi/linux/if_xdp.h
index 23a0627814687..50d67df78911f 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 */
|
| 3/2 | 2026/08/13 20:19 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 5461 output: 22 thoughts: 391 Thoughts: **Analyzing this XDP/AF_XDP Patch** Okay, so I'm looking at this patch and it's making some modifications to the XDP and AF_XDP socket code. Specifically, it seems to be tweaking how we're accessing metadata. They're adding checks using the `options` field from the XDP descriptor to see if `XDP_TX_METADATA` is present before calling `xsk_buff_get_metadata` and `xsk_buff_raw_get_ctx`. That makes sense, handling potential edge cases around metadata availability is always good. The addition of `__u32 reserved;` to `struct xsk_tx_metadata` looks like a forward-compatibility move, probably preparing for future features. Then, there's some code being removed from `stmmac_xdp_xmit_zc` related to `priv->est->max_sdu[queue]`. Not sure why that's being removed, I'll need to dig into that a bit more. My immediate thought is, can this code actually be hit in a virtualized environment? AF_XDP is a core networking feature, so it should be used in virtualized environments. The drivers being touched are `igc`, `mlx5`, and `stmmac`. I know `igc` and `mlx5` are common in virtualized scenarios, but `stmmac` is less typical. But hang on, the core AF_XDP code lives in `net/xdp/xsk_buff_pool.c` and `include/net/xdp_sock_drv.h`, and `stmmac` isn't necessarily directly in the critical path, but `veth` also uses AF_XDP! The problem here is `veth` isn't listed here as being modified! Need to check that. Okay, let's see where these functions are actually *used*. `xsk_buff_get_metadata` is called in `igc`, `mlx5`, and `stmmac`. I see these drivers being touched, but is `xsk_buff_raw_get_ctx` used *anywhere* else? I need to check to make sure it's not being used in `veth`, or another driver. I'll need to run a quick `grep` for both `xp_raw_get_ctx` and `xsk_buff_get_metadata` and make sure my assumptions are valid here. I need to make sure I am accounting for *all* the uses of these functions! |
| 4/2 | 2026/08/13 20:19 | tool | grepper |
0mArgs:{
"Expression": "xsk_buff_get_metadata"
}Results: {
"Output": "drivers/net/ethernet/intel/igc/igc_main.c=3037=static void igc_xdp_xmit_zc(struct igc_ring *ring)\n--\ndrivers/net/ethernet/intel/igc/igc_main.c-3076-\t\tdma = xsk_buff_raw_get_dma(pool, xdp_desc.addr);\ndrivers/net/ethernet/intel/igc/igc_main.c:3077:\t\tmeta = xsk_buff_get_metadata(pool, xdp_desc.addr,\ndrivers/net/ethernet/intel/igc/igc_main.c-3078-\t\t\t\t\t xdp_desc.options);\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c=66=bool mlx5e_xsk_tx(struct mlx5e_xdpsq *sq, unsigned int budget)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c-101-\t\txdptxd.len = desc.len;\ndrivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c:102:\t\tmeta = xsk_buff_get_metadata(pool, desc.addr, desc.options);\ndrivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c-103-\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=2677=static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-2714-\t\tdma_addr = xsk_buff_raw_get_dma(pool, xdp_desc.addr);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:2715:\t\tmeta = xsk_buff_get_metadata(pool, xdp_desc.addr,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-2716-\t\t\t\t\t xdp_desc.options);\n--\ninclude/net/xdp_sock_drv.h=321=static inline struct xsk_tx_metadata *\ninclude/net/xdp_sock_drv.h:322:__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data,\ninclude/net/xdp_sock_drv.h-323-\t\t\tunsigned int options)\n--\ninclude/net/xdp_sock_drv.h=331=static inline struct xsk_tx_metadata *\ninclude/net/xdp_sock_drv.h:332:xsk_buff_get_metadata(struct xsk_buff_pool *pool, u64 addr, u32 options)\ninclude/net/xdp_sock_drv.h-333-{\ninclude/net/xdp_sock_drv.h:334:\treturn __xsk_buff_get_metadata(pool, xp_raw_get_data(pool, addr),\ninclude/net/xdp_sock_drv.h-335-\t\t\t\t options);\n--\ninclude/net/xdp_sock_drv.h=535=static inline struct xsk_tx_metadata *\ninclude/net/xdp_sock_drv.h:536:__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data,\ninclude/net/xdp_sock_drv.h-537-\t\t\tunsigned int options)\n--\ninclude/net/xdp_sock_drv.h=542=static inline struct xsk_tx_metadata *\ninclude/net/xdp_sock_drv.h:543:xsk_buff_get_metadata(struct xsk_buff_pool *pool, u64 addr, u32 options)\ninclude/net/xdp_sock_drv.h-544-{\n--\nnet/xdp/xsk_buff_pool.c=775=struct xdp_desc_ctx xp_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr,\n--\nnet/xdp/xsk_buff_pool.c-782-\tret.dma = __xp_raw_get_dma(pool, addr);\nnet/xdp/xsk_buff_pool.c:783:\tret.meta = __xsk_buff_get_metadata(pool, __xp_raw_get_data(pool, addr),\nnet/xdp/xsk_buff_pool.c-784-\t\t\t\t\t options);\n"
} |
| 5/2 | 2026/08/13 20:19 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 7618 output: 29 thoughts: 141 Thoughts: Here's my thought process, as it stands: **Analyzing the XDP Socket Metadata Patch** Okay, so this patch is digging into the XDP socket metadata handling, specifically within the `__xsk_buff_get_metadata` function. I see it's in `include/net/xdp_sock_drv.h`, and the key modification seems to be checking the `options & XDP_TX_METADATA` bit. That's interesting, it's about whether we're going to transmit metadata with the XDP packet. Now, `__xsk_buff_get_metadata` is an *inline* function, so it's probably performance-critical. It's used by two other functions, `xsk_buff_get_metadata` (makes sense, that's the obvious call) and `xp_raw_get_ctx`. Alright, let's keep an eye on `xp_raw_get_ctx` – that could be important for understanding the full impact. Ah, there it is! `xp_raw_get_ctx` is, in turn, used by `__libeth_xsk_xmit_fill_buf_md` in `include/net/libeth/xsk.h`. That makes sense, `libeth` is handling ethernet frames in XDP. So now, I need to figure out *where* `__libeth_xsk_xmit_fill_buf_md` is being *called*. That's the next step to figure out the scope of this change. Is this a change to the core XDP logic, or is it more specific to a particular use case? |
| 6/2 | 2026/08/13 20:19 | tool | grepper |
0mArgs:{
"Expression": "__libeth_xsk_xmit_fill_buf_md"
}Results: {
"Output": "include/net/libeth/xsk.h=174=static const struct xsk_tx_metadata_ops __libeth_xsktmo = {\n--\ninclude/net/libeth/xsk.h-178-/**\ninclude/net/libeth/xsk.h:179: * __libeth_xsk_xmit_fill_buf_md - internal helper to prepare XSk xmit w/meta\ninclude/net/libeth/xsk.h-180- * @xdesc: \u0026xdp_desc from the XSk buffer pool\n--\ninclude/net/libeth/xsk.h=190=static __always_inline struct libeth_xdp_tx_desc\ninclude/net/libeth/xsk.h:191:__libeth_xsk_xmit_fill_buf_md(const struct xdp_desc *xdesc,\ninclude/net/libeth/xsk.h-192-\t\t\t const struct libeth_xdpsq *sq,\n--\ninclude/net/libeth/xsk.h=247=libeth_xsk_xmit_fill_buf(struct libeth_xdp_tx_frame frm, u32 i,\n--\ninclude/net/libeth/xsk.h-252-\tif (priv)\ninclude/net/libeth/xsk.h:253:\t\tdesc = __libeth_xsk_xmit_fill_buf_md(\u0026frm.desc, sq, priv);\ninclude/net/libeth/xsk.h-254-\telse\n"
} |
| 7/2 | 2026/08/13 20:19 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 8537 output: 26 thoughts: 44 Thoughts: Here's my summary, as though I'm thinking through this process: **Investigating the Usage of `libeth_xsk_xmit_fill_buf`** Okay, so I'm dealing with `libeth` and, specifically, I've got to understand how `libeth_xsk_xmit_fill_buf` is being used within that library. It's pretty straightforward, actually. The first thing I need to do is to track down all the instances where this function, `libeth_xsk_xmit_fill_buf`, is being called within the `libeth` code. Then I can understand its role in XSK transmission. Nothing complicated so far, just standard code analysis procedure! |
| 8/2 | 2026/08/13 20:19 | tool | grepper |
0mArgs:{
"Expression": "libeth_xsk_xmit_fill_buf"
}Results: {
"Output": "include/net/libeth/xsk.h=174=static const struct xsk_tx_metadata_ops __libeth_xsktmo = {\n--\ninclude/net/libeth/xsk.h-178-/**\ninclude/net/libeth/xsk.h:179: * __libeth_xsk_xmit_fill_buf_md - internal helper to prepare XSk xmit w/meta\ninclude/net/libeth/xsk.h-180- * @xdesc: \u0026xdp_desc from the XSk buffer pool\n--\ninclude/net/libeth/xsk.h-183- *\ninclude/net/libeth/xsk.h:184: * Same as __libeth_xsk_xmit_fill_buf(), but requests metadata pointer and\ninclude/net/libeth/xsk.h-185- * fills additional fields in \u0026libeth_xdp_tx_desc to ask for metadata offload.\n--\ninclude/net/libeth/xsk.h=190=static __always_inline struct libeth_xdp_tx_desc\ninclude/net/libeth/xsk.h:191:__libeth_xsk_xmit_fill_buf_md(const struct xdp_desc *xdesc,\ninclude/net/libeth/xsk.h-192-\t\t\t const struct libeth_xdpsq *sq,\n--\ninclude/net/libeth/xsk.h-215-/**\ninclude/net/libeth/xsk.h:216: * __libeth_xsk_xmit_fill_buf - internal helper to prepare XSk xmit w/o meta\ninclude/net/libeth/xsk.h-217- * @xdesc: \u0026xdp_desc from the XSk buffer pool\n--\ninclude/net/libeth/xsk.h=223=static inline struct libeth_xdp_tx_desc\ninclude/net/libeth/xsk.h:224:__libeth_xsk_xmit_fill_buf(const struct xdp_desc *xdesc,\ninclude/net/libeth/xsk.h-225-\t\t\t const struct libeth_xdpsq *sq)\n--\ninclude/net/libeth/xsk.h-233-/**\ninclude/net/libeth/xsk.h:234: * libeth_xsk_xmit_fill_buf - internal helper to prepare an XSk xmit\ninclude/net/libeth/xsk.h-235- * @frm: \u0026xdp_desc from the XSk buffer pool\n--\ninclude/net/libeth/xsk.h=246=static __always_inline struct libeth_xdp_tx_desc\ninclude/net/libeth/xsk.h:247:libeth_xsk_xmit_fill_buf(struct libeth_xdp_tx_frame frm, u32 i,\ninclude/net/libeth/xsk.h-248-\t\t\t const struct libeth_xdpsq *sq, u64 priv)\n--\ninclude/net/libeth/xsk.h-252-\tif (priv)\ninclude/net/libeth/xsk.h:253:\t\tdesc = __libeth_xsk_xmit_fill_buf_md(\u0026frm.desc, sq, priv);\ninclude/net/libeth/xsk.h-254-\telse\ninclude/net/libeth/xsk.h:255:\t\tdesc = __libeth_xsk_xmit_fill_buf(\u0026frm.desc, sq);\ninclude/net/libeth/xsk.h-256-\n--\ninclude/net/libeth/xsk.h=285=libeth_xsk_xmit_do_bulk(struct xsk_buff_pool *pool, void *xdpsq, u32 budget,\n--\ninclude/net/libeth/xsk.h-304-\t\t\t\tlibeth_xdp_ptr_to_priv(tmo), prep,\ninclude/net/libeth/xsk.h:305:\t\t\t\tlibeth_xsk_xmit_fill_buf, xmit);\ninclude/net/libeth/xsk.h-306-\tfinalize(xdpsq, n, true);\n"
} |
| 9/2 | 2026/08/13 20:19 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 9819 output: 26 thoughts: 28 Thoughts: Here's my take on those thoughts, tailored for an expert audience: **Investigating `libeth_xsk_xmit_do_bulk` Usage** Alright, so `libeth_xsk_xmit_do_bulk`... that rings a bell. It's popping up in a few drivers, and my immediate thought is, "Okay, let's get a handle on the landscape." I need to identify *precisely* which drivers are leveraging this. I'm thinking this might be a key indicator for XDP acceleration or some other performance-critical path. Knowing which NICs or virtual devices utilize this function directly impacts my understanding of its potential performance bottlenecks or optimizations. I’ll need to do a code search across the relevant trees. Hopefully, this is well-defined, and the usage is consistent across the implementation. After identifying all users of the function, I can begin to draw some conclusions, so I'm thinking I'll start there. |
| 10/2 | 2026/08/13 20:19 | tool | grepper |
0mArgs:{
"Expression": "libeth_xsk_xmit_do_bulk"
}Results: {
"Output": "drivers/net/ethernet/intel/idpf/xsk.c=316=bool idpf_xsk_xmit(struct idpf_tx_queue *xsksq)\n--\ndrivers/net/ethernet/intel/idpf/xsk.c-325-\ndrivers/net/ethernet/intel/idpf/xsk.c:326:\treturn libeth_xsk_xmit_do_bulk(xsksq-\u003epool, xsksq,\ndrivers/net/ethernet/intel/idpf/xsk.c-327-\t\t\t\t min(free - 1, xsksq-\u003ethresh),\n--\ninclude/net/libeth/xsk.h=247=libeth_xsk_xmit_fill_buf(struct libeth_xdp_tx_frame frm, u32 i,\n--\ninclude/net/libeth/xsk.h-264-/**\ninclude/net/libeth/xsk.h:265: * libeth_xsk_xmit_do_bulk - send XSk xmit frames\ninclude/net/libeth/xsk.h-266- * @pool: XSk buffer pool containing the frames to send\n--\ninclude/net/libeth/xsk.h=284=static __always_inline bool\ninclude/net/libeth/xsk.h:285:libeth_xsk_xmit_do_bulk(struct xsk_buff_pool *pool, void *xdpsq, u32 budget,\ninclude/net/libeth/xsk.h-286-\t\t\tconst struct xsk_tx_metadata_ops *tmo,\n"
} |
| 11/2 | 2026/08/13 20:19 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 10486 output: 21 thoughts: 439 Thoughts: **Analyzing the Implications of the XDP Patch** Okay, so this patch uses `idpf`, interesting. It looks like it's touching `stmmac_xdp_xmit_zc` in `stmmac_main.c`. Right, `stmmac`... STMicroelectronics Ethernet controllers. Now, the question is, can I even *reach* this thing in QEMU? I know there's a file for i.MX FEC, but `stmmac` is typically ARM. However, wait, it *does* have PCI bindings, `stmmac_pci.c`. QEMU might not even emulate that specific hardware, though... Let's step back. Does `veth` have anything to do with `xsk_buff_get_metadata`? No, it doesn't support XDP TX metadata. Okay, the plot thickens. This patch is also modifying `net/xdp/xsk_buff_pool.c` and `include/net/xdp_sock_drv.h`. So, it's messing with `xp_raw_get_ctx`. Hold on, is `xp_raw_get_ctx` used anywhere else? Let's check within `net/xdp/xsk_buff_pool.c` again. Aha, it seems the change modifies `xp_raw_get_ctx` to take `options` and pass it into `__xsk_buff_get_metadata`. The patch also added `__u32 reserved;` to `struct xsk_tx_metadata` in `include/uapi/linux/if_xdp.h`. A UAPI change. This is significant. Does this change ultimately impact the core AF_XDP code? Yes, `xp_raw_get_ctx` is exported, meaning it's usable outside. But is the kernel directly using `xsk_buff_get_metadata` or `xp_raw_get_ctx` elsewhere? I'll need to check the `net/xdp/` and `net/core/` directories for confirmation. |
| 12/2 | 2026/08/13 20:19 | tool | grepper |
0mArgs:{
"Expression": "xp_raw_get_ctx"
}Results: {
"Output": "include/net/xdp_sock_drv.h=234=static inline void *xsk_buff_raw_get_data(struct xsk_buff_pool *pool, u64 addr)\n--\ninclude/net/xdp_sock_drv.h-244- *\ninclude/net/xdp_sock_drv.h:245: * Wrapper for xp_raw_get_ctx() to be used in drivers, see its kdoc for\ninclude/net/xdp_sock_drv.h-246- * details.\n--\ninclude/net/xdp_sock_drv.h=252=xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr, u32 options)\ninclude/net/xdp_sock_drv.h-253-{\ninclude/net/xdp_sock_drv.h:254:\treturn xp_raw_get_ctx(pool, addr, options);\ninclude/net/xdp_sock_drv.h-255-}\n--\ninclude/net/xsk_buff_pool.h=152=struct xdp_desc_ctx {\n--\ninclude/net/xsk_buff_pool.h-156-\ninclude/net/xsk_buff_pool.h:157:struct xdp_desc_ctx xp_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr,\ninclude/net/xsk_buff_pool.h-158-\t\t\t\t u32 options);\n--\nnet/xdp/xsk_buff_pool.c=760=EXPORT_SYMBOL(xp_raw_get_dma);\n--\nnet/xdp/xsk_buff_pool.c-762-/**\nnet/xdp/xsk_buff_pool.c:763: * xp_raw_get_ctx - get \u0026xdp_desc context\nnet/xdp/xsk_buff_pool.c-764- * @pool: XSk buff pool desc address belongs to\n--\nnet/xdp/xsk_buff_pool.c-774- */\nnet/xdp/xsk_buff_pool.c:775:struct xdp_desc_ctx xp_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr,\nnet/xdp/xsk_buff_pool.c-776-\t\t\t\t u32 options)\n--\nnet/xdp/xsk_buff_pool.c-787-}\nnet/xdp/xsk_buff_pool.c:788:EXPORT_SYMBOL(xp_raw_get_ctx);\n"
} |
| 13/2 | 2026/08/13 20:19 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 12057 output: 24 thoughts: 301 Thoughts: **My Analysis of XSK Buffer Metadata Usage** Okay, so I'm tracing the usage of these XSK buffer functions. Specifically, `xp_raw_get_ctx` seems to be solely used within `xsk_buff_raw_get_ctx`, and that one is used in `__libeth_xsk_xmit_fill_buf_md`. I need to figure out the attack surface here. Then, `xsk_buff_get_metadata` is called in `igc`, `mlx5`, and `stmmac`. My immediate thought is: are these drivers even reachable within a standard QEMU environment, which is what I'm usually testing with? * `igc`... that's the Intel I225-LM/I225-V 2.5G Ethernet controller. QEMU doesn't emulate it; it sticks with `e1000`, `e1000e`, and `igb`. So, no joy there. * `mlx5`... that's Mellanox ConnectX-4/5/6. QEMU doesn't emulate that natively without VFIO or the hardware, which isn't the environment I'm focusing on. * `stmmac`... STMicroelectronics Ethernet. QEMU likely doesn't emulate it on standard x86_64, which is what Syzkaller, which I generally use, tests. It *might* be present on ARM emulations, but that's not the primary target. * Wait a minute, I missed `idpf`... that's Intel Infrastructure Data Path Function. QEMU definitely doesn't emulate that one. So the obvious question is: is there *anything* else calling either `xsk_buff_get_metadata` or `xsk_buff_raw_get_ctx` that I'm missing? I need to perform a more thorough search. Time to grep for `xsk_buff_raw_get_ctx`. Let's see what that turns up. |
| 14/2 | 2026/08/13 20:19 | tool | grepper |
0mArgs:{
"Expression": "xsk_buff_raw_get_ctx"
}Results: {
"Output": "include/net/libeth/xsk.h=191=__libeth_xsk_xmit_fill_buf_md(const struct xdp_desc *xdesc,\n--\ninclude/net/libeth/xsk.h-198-\ninclude/net/libeth/xsk.h:199:\tctx = xsk_buff_raw_get_ctx(sq-\u003epool, xdesc-\u003eaddr, xdesc-\u003eoptions);\ninclude/net/libeth/xsk.h-200-\tdesc = (typeof(desc)){\n--\ninclude/net/xdp_sock_drv.h=234=static inline void *xsk_buff_raw_get_data(struct xsk_buff_pool *pool, u64 addr)\n--\ninclude/net/xdp_sock_drv.h-239-/**\ninclude/net/xdp_sock_drv.h:240: * xsk_buff_raw_get_ctx - get \u0026xdp_desc context\ninclude/net/xdp_sock_drv.h-241- * @pool: XSk buff pool desc address belongs to\n--\ninclude/net/xdp_sock_drv.h=251=static inline struct xdp_desc_ctx\ninclude/net/xdp_sock_drv.h:252:xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr, u32 options)\ninclude/net/xdp_sock_drv.h-253-{\n--\ninclude/net/xdp_sock_drv.h=515=static inline struct xdp_desc_ctx\ninclude/net/xdp_sock_drv.h:516:xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr, u32 options)\ninclude/net/xdp_sock_drv.h-517-{\n"
} |
| 15/2 | 2026/08/13 20:19 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 13306 output: 21 thoughts: 414 Thoughts: **My Analysis of the XSK Buffer Flow and Potential Impact** Okay, let's break this down. `xsk_buff_raw_get_ctx` is, as far as I can see, *only* used within `__libeth_xsk_xmit_fill_buf_md`. And `__libeth_xsk_xmit_fill_buf_md` is exclusively called by `libeth_xsk_xmit_fill_buf`, which itself feeds into `libeth_xsk_xmit_do_bulk`, which is, for all intents and purposes, *only* used by `idpf`. So, this patch seems to be directly affecting the `igc`, `mlx5`, `stmmac`, and `idpf` drivers. The crucial question now: are any of these drivers emulated in QEMU in a way that would matter for standard syzkaller testing? Nope. Standard syzkaller testing doesn't touch those. Wait a minute, what about something like `veth`? Does it somehow indirectly use `xsk_buff_get_metadata`? No, that's not the case. What about `stmmac`, specifically? Can we reach it through some form of virtualization? No, `stmmac` is firmly rooted in physical hardware. Okay, I see it! There's a UAPI change in the `if_xdp.h` header: a new `reserved` field has been added to `struct xsk_tx_metadata`. I need to think carefully about the implications of this layout change. Now, does this alteration to the `struct xsk_tx_metadata` impact any core kernel code? This is the core question I need to consider to understand if the patch might introduce unexpected behavior. I'll need to meticulously check the places where `struct xsk_tx_metadata` is referenced within the kernel. |
| 16/2 | 2026/08/13 20:20 | tool | grepper |
0mArgs:{
"Expression": "struct xsk_tx_metadata"
}Results: {
"Output": "Documentation/networking/xsk-tx-metadata.rst=16=length is therefore the same for every socket that shares the same umem.\nDocumentation/networking/xsk-tx-metadata.rst:17:The metadata layout is a fixed UAPI, refer to ``struct xsk_tx_metadata`` in\nDocumentation/networking/xsk-tx-metadata.rst-18-``include/uapi/linux/if_xdp.h``. Thus, generally, the ``tx_metadata_len``\nDocumentation/networking/xsk-tx-metadata.rst:19:field above should contain ``sizeof(struct xsk_tx_metadata)``.\nDocumentation/networking/xsk-tx-metadata.rst-20-\n--\nDocumentation/networking/xsk-tx-metadata.rst=45=The flags field enables the particular offload:\n--\nDocumentation/networking/xsk-tx-metadata.rst-48- timestamp into ``completion.tx_timestamp`` field of\nDocumentation/networking/xsk-tx-metadata.rst:49: ``struct xsk_tx_metadata``.\nDocumentation/networking/xsk-tx-metadata.rst-50-- ``XDP_TXMD_FLAGS_CHECKSUM``: requests the device to calculate L4\n--\nDocumentation/networking/xsk-tx-metadata.rst-56- value of launch time is indicated by ``request.launch_time`` field of\nDocumentation/networking/xsk-tx-metadata.rst:57: ``struct xsk_tx_metadata``.\nDocumentation/networking/xsk-tx-metadata.rst-58-\n--\ndrivers/net/ethernet/intel/igc/igc.h=108=struct igc_tx_timestamp_request {\n--\ndrivers/net/ethernet/intel/igc/igc.h-119-\tu8 xsk_queue_index; /* Tx queue which requesting timestamp */\ndrivers/net/ethernet/intel/igc/igc.h:120:\tstruct xsk_tx_metadata_compl xsk_meta;\t/* ref to xsk Tx metadata */\ndrivers/net/ethernet/intel/igc/igc.h-121-};\n--\ndrivers/net/ethernet/intel/igc/igc.h=372=int igc_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags);\n--\ndrivers/net/ethernet/intel/igc/igc.h-374-/* AF_XDP TX metadata operations */\ndrivers/net/ethernet/intel/igc/igc.h:375:extern const struct xsk_tx_metadata_ops igc_xsk_tx_metadata_ops;\ndrivers/net/ethernet/intel/igc/igc.h-376-\n--\ndrivers/net/ethernet/intel/igc/igc.h=602=struct igc_metadata_request {\ndrivers/net/ethernet/intel/igc/igc.h-603-\tstruct igc_tx_buffer *tx_buffer;\ndrivers/net/ethernet/intel/igc/igc.h:604:\tstruct xsk_tx_metadata *meta;\ndrivers/net/ethernet/intel/igc/igc.h-605-\tstruct igc_ring *tx_ring;\n--\ndrivers/net/ethernet/intel/igc/igc_main.c=2993=static void igc_xsk_request_launch_time(u64 launch_time, void *_priv)\n--\ndrivers/net/ethernet/intel/igc/igc_main.c-3030-\ndrivers/net/ethernet/intel/igc/igc_main.c:3031:const struct xsk_tx_metadata_ops igc_xsk_tx_metadata_ops = {\ndrivers/net/ethernet/intel/igc/igc_main.c-3032-\t.tmo_request_timestamp\t\t= igc_xsk_request_timestamp,\n--\ndrivers/net/ethernet/intel/igc/igc_main.c=3037=static void igc_xdp_xmit_zc(struct igc_ring *ring)\n--\ndrivers/net/ethernet/intel/igc/igc_main.c-3064-\t\tstruct igc_metadata_request meta_req;\ndrivers/net/ethernet/intel/igc/igc_main.c:3065:\t\tstruct xsk_tx_metadata *meta = NULL;\ndrivers/net/ethernet/intel/igc/igc_main.c-3066-\t\tstruct igc_tx_buffer *bi;\n--\ndrivers/net/ethernet/intel/libeth/priv.h=15=struct xdp_frame_bulk;\ndrivers/net/ethernet/intel/libeth/priv.h-16-\ndrivers/net/ethernet/intel/libeth/priv.h:17:extern const struct xsk_tx_metadata_ops libeth_xsktmo_slow;\ndrivers/net/ethernet/intel/libeth/priv.h-18-\n--\ndrivers/net/ethernet/intel/libeth/xdp.c=390=void __libeth_xdp_set_features(struct net_device *dev,\n--\ndrivers/net/ethernet/intel/libeth/xdp.c-392-\t\t\t u32 zc_segs,\ndrivers/net/ethernet/intel/libeth/xdp.c:393:\t\t\t const struct xsk_tx_metadata_ops *tmo)\ndrivers/net/ethernet/intel/libeth/xdp.c-394-{\n--\ndrivers/net/ethernet/intel/libeth/xsk.c=14=void __cold libeth_xsk_tx_return_bulk(const struct libeth_xdp_tx_frame *bq,\n--\ndrivers/net/ethernet/intel/libeth/xsk.c-22-\ndrivers/net/ethernet/intel/libeth/xsk.c:23:const struct xsk_tx_metadata_ops libeth_xsktmo_slow = {\ndrivers/net/ethernet/intel/libeth/xsk.c-24-\t.tmo_request_checksum\t\t= libeth_xsktmo_req_csum,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en.h=480=struct mlx5e_xmit_data;\ndrivers/net/ethernet/mellanox/mlx5/core/en.h:481:struct xsk_tx_metadata;\ndrivers/net/ethernet/mellanox/mlx5/core/en.h-482-typedef int (*mlx5e_fp_xmit_xdp_frame_check)(struct mlx5e_xdpsq *);\ndrivers/net/ethernet/mellanox/mlx5/core/en.h=483=typedef bool (*mlx5e_fp_xmit_xdp_frame)(struct mlx5e_xdpsq *,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en.h-485-\t\t\t\t\tint,\ndrivers/net/ethernet/mellanox/mlx5/core/en.h:486:\t\t\t\t\tstruct xsk_tx_metadata **);\ndrivers/net/ethernet/mellanox/mlx5/core/en.h-487-\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.c=304=static void mlx5e_xsk_request_checksum(u16 csum_start, u16 csum_offset, void *priv)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.c-311-\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.c:312:const struct xsk_tx_metadata_ops mlx5e_xsk_tx_metadata_ops = {\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.c-313-\t.tmo_fill_timestamp\t\t= mlx5e_xsk_fill_timestamp,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.c=454=mlx5e_xmit_xdp_frame(struct mlx5e_xdpsq *sq, struct mlx5e_xmit_data *xdptxd,\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.c:455:\t\t int check_result, struct xsk_tx_metadata **meta);\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.c-456-\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.c=458=mlx5e_xmit_xdp_frame_mpwqe(struct mlx5e_xdpsq *sq, struct mlx5e_xmit_data *xdptxd,\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.c:459:\t\t\t int check_result, struct xsk_tx_metadata **meta)\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.c-460-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.c=540=mlx5e_xmit_xdp_frame(struct mlx5e_xdpsq *sq, struct mlx5e_xmit_data *xdptxd,\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.c:541:\t\t int check_result, struct xsk_tx_metadata **meta)\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.c-542-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.c=665=static void mlx5e_free_xdpsq_desc(struct mlx5e_xdpsq *sq,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.c-732-\t\t\t/* AF_XDP send */\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.c:733:\t\t\tstruct xsk_tx_metadata_compl *compl = NULL;\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.c-734-\t\t\tstruct mlx5e_xsk_tx_complete priv = {\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.h=84=union mlx5e_xdp_info {\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.h-94-\t} page;\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.h:95:\tstruct xsk_tx_metadata_compl xsk_meta;\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.h-96-};\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.h=111=extern const struct xdp_metadata_ops mlx5e_xdp_metadata_ops;\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.h:112:extern const struct xsk_tx_metadata_ops mlx5e_xsk_tx_metadata_ops;\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.h-113-\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.h=114=INDIRECT_CALLABLE_DECLARE(bool mlx5e_xmit_xdp_frame_mpwqe(struct mlx5e_xdpsq *sq,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.h-116-\t\t\t\t\t\t\t int check_result,\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.h:117:\t\t\t\t\t\t\t struct xsk_tx_metadata **meta));\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.h-118-INDIRECT_CALLABLE_DECLARE(bool mlx5e_xmit_xdp_frame(struct mlx5e_xdpsq *sq,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.h-120-\t\t\t\t\t\t int check_result,\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.h:121:\t\t\t\t\t\t struct xsk_tx_metadata **meta));\ndrivers/net/ethernet/mellanox/mlx5/core/en/xdp.h-122-INDIRECT_CALLABLE_DECLARE(int mlx5e_xmit_xdp_frame_check_mpwqe(struct mlx5e_xdpsq *sq));\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c=66=bool mlx5e_xsk_tx(struct mlx5e_xdpsq *sq, unsigned int budget)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c-68-\tstruct xsk_buff_pool *pool = sq-\u003exsk_pool;\ndrivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c:69:\tstruct xsk_tx_metadata *meta = NULL;\ndrivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c-70-\tunion mlx5e_xdp_info xdpi;\n--\ndrivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c-116-\t\t\tif (xp_tx_metadata_enabled(sq-\u003exsk_pool)) {\ndrivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c:117:\t\t\t\tstruct xsk_tx_metadata_compl compl;\ndrivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c-118-\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac.h=49=struct stmmac_tx_info {\ndrivers/net/ethernet/stmicro/stmmac/stmmac.h:50:\tstruct xsk_tx_metadata_compl xsk_meta;\ndrivers/net/ethernet/stmicro/stmmac/stmmac.h-51-\tdma_addr_t buf;\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=2661=static void stmmac_xsk_request_launch_time(u64 launch_time, void *_priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-2670-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:2671:static const struct xsk_tx_metadata_ops stmmac_xsk_tx_metadata_ops = {\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-2672-\t.tmo_request_timestamp\t\t= stmmac_xsk_request_timestamp,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=2677=static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-2696-\t\tstruct stmmac_metadata_request meta_req;\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:2697:\t\tstruct xsk_tx_metadata *meta = NULL;\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-2698-\t\tdma_addr_t dma_addr;\n--\ninclude/linux/netdevice.h=2149=struct net_device {\n--\ninclude/linux/netdevice.h-2256-\tconst struct xdp_metadata_ops *xdp_metadata_ops;\ninclude/linux/netdevice.h:2257:\tconst struct xsk_tx_metadata_ops *xsk_tx_metadata_ops;\ninclude/linux/netdevice.h-2258-\tunsigned short\t\tgflags;\n--\ninclude/linux/skbuff.h=579=void mm_unaccount_pinned_pages(struct mmpin *mmp);\n--\ninclude/linux/skbuff.h-585- */\ninclude/linux/skbuff.h:586:struct xsk_tx_metadata_compl {\ninclude/linux/skbuff.h-587-\t__u64 *tx_timestamp;\n--\ninclude/linux/skbuff.h=593=struct skb_shared_info {\n--\ninclude/linux/skbuff.h-603-\t\tstruct skb_shared_hwtstamps hwtstamps;\ninclude/linux/skbuff.h:604:\t\tstruct xsk_tx_metadata_compl xsk_meta;\ninclude/linux/skbuff.h-605-\t};\n--\ninclude/net/libeth/xdp.h=1821=void __libeth_xdp_set_features(struct net_device *dev,\n--\ninclude/net/libeth/xdp.h-1823-\t\t\t u32 zc_segs,\ninclude/net/libeth/xdp.h:1824:\t\t\t const struct xsk_tx_metadata_ops *tmo);\ninclude/net/libeth/xdp.h-1825-void libeth_xdp_set_redirect(struct net_device *dev, bool enable);\n--\ninclude/net/libeth/xsk.h=167=static inline void libeth_xsktmo_req_csum(u16 csum_start, u16 csum_offset,\n--\ninclude/net/libeth/xsk.h-173-/* Only to inline the callbacks below, use @libeth_xsktmo in drivers instead */\ninclude/net/libeth/xsk.h:174:static const struct xsk_tx_metadata_ops __libeth_xsktmo = {\ninclude/net/libeth/xsk.h-175-\t.tmo_request_checksum\t= libeth_xsktmo_req_csum,\n--\ninclude/net/libeth/xsk.h=191=__libeth_xsk_xmit_fill_buf_md(const struct xdp_desc *xdesc,\n--\ninclude/net/libeth/xsk.h-194-{\ninclude/net/libeth/xsk.h:195:\tconst struct xsk_tx_metadata_ops *tmo = libeth_xdp_priv_to_ptr(priv);\ninclude/net/libeth/xsk.h-196-\tstruct libeth_xdp_tx_desc desc;\n--\ninclude/net/libeth/xsk.h=285=libeth_xsk_xmit_do_bulk(struct xsk_buff_pool *pool, void *xdpsq, u32 budget,\ninclude/net/libeth/xsk.h:286:\t\t\tconst struct xsk_tx_metadata_ops *tmo,\ninclude/net/libeth/xsk.h-287-\t\t\tu32 (*prep)(void *xdpsq, struct libeth_xdpsq *sq),\n--\ninclude/net/xdp_sock.h=48=struct xdp_sock {\n--\ninclude/net/xdp_sock.h-116- */\ninclude/net/xdp_sock.h:117:struct xsk_tx_metadata_ops {\ninclude/net/xdp_sock.h-118-\tvoid\t(*tmo_request_timestamp)(void *priv);\n--\ninclude/net/xdp_sock.h=129=INDIRECT_CALLABLE_DECLARE(void xsk_destruct_skb(struct sk_buff *));\n--\ninclude/net/xdp_sock.h-134- * @meta: pointer to AF_XDP metadata area\ninclude/net/xdp_sock.h:135: * @compl: pointer to output struct xsk_tx_metadata_to_compl\ninclude/net/xdp_sock.h-136- *\n--\ninclude/net/xdp_sock.h-140- */\ninclude/net/xdp_sock.h:141:static inline void xsk_tx_metadata_to_compl(struct xsk_tx_metadata *meta,\ninclude/net/xdp_sock.h:142:\t\t\t\t\t struct xsk_tx_metadata_compl *compl)\ninclude/net/xdp_sock.h-143-{\n--\ninclude/net/xdp_sock.h-159- * @compl: pointer to completion metadata produced from xsk_tx_metadata_to_compl\ninclude/net/xdp_sock.h:160: * @ops: pointer to struct xsk_tx_metadata_ops\ninclude/net/xdp_sock.h-161- * @priv: pointer to driver-private aread\n--\ninclude/net/xdp_sock.h-165- */\ninclude/net/xdp_sock.h:166:static inline void xsk_tx_metadata_complete(struct xsk_tx_metadata_compl *compl,\ninclude/net/xdp_sock.h:167:\t\t\t\t\t const struct xsk_tx_metadata_ops *ops,\ninclude/net/xdp_sock.h-168-\t\t\t\t\t void *priv)\n--\ninclude/net/xdp_sock.h=195=static inline void xsk_destruct_skb(struct sk_buff *skb)\n--\ninclude/net/xdp_sock.h-199-\ninclude/net/xdp_sock.h:200:static inline void xsk_tx_metadata_to_compl(struct xsk_tx_metadata *meta,\ninclude/net/xdp_sock.h:201:\t\t\t\t\t struct xsk_tx_metadata_compl *compl)\ninclude/net/xdp_sock.h-202-{\n--\ninclude/net/xdp_sock.h-204-\ninclude/net/xdp_sock.h:205:static inline void xsk_tx_metadata_complete(struct xsk_tx_metadata_compl *compl,\ninclude/net/xdp_sock.h:206:\t\t\t\t\t const struct xsk_tx_metadata_ops *ops,\ninclude/net/xdp_sock.h-207-\t\t\t\t\t void *priv)\n--\ninclude/net/xdp_sock_drv.h=264=xsk_buff_valid_tx_metadata(const struct xsk_buff_pool *pool,\ninclude/net/xdp_sock_drv.h:265:\t\t\t const struct xsk_tx_metadata *meta, u64 *flags)\ninclude/net/xdp_sock_drv.h-266-{\n--\ninclude/net/xdp_sock_drv.h-269-\t\tif (pool-\u003etx_metadata_len \u003c\ninclude/net/xdp_sock_drv.h:270:\t\t offsetofend(struct xsk_tx_metadata, request.launch_time))\ninclude/net/xdp_sock_drv.h-271-\t\t\treturn false;\n--\ninclude/net/xdp_sock_drv.h-279- * @pmeta: pointer to pointer to AF_XDP metadata area\ninclude/net/xdp_sock_drv.h:280: * @ops: pointer to struct xsk_tx_metadata_ops\ninclude/net/xdp_sock_drv.h-281- * @priv: pointer to driver-private area\n--\ninclude/net/xdp_sock_drv.h=287=xsk_tx_metadata_request(const struct xsk_buff_pool *pool,\ninclude/net/xdp_sock_drv.h:288:\t\t\tstruct xsk_tx_metadata **pmeta,\ninclude/net/xdp_sock_drv.h:289:\t\t\tconst struct xsk_tx_metadata_ops *ops, void *priv)\ninclude/net/xdp_sock_drv.h-290-{\ninclude/net/xdp_sock_drv.h:291:\tconst struct xsk_tx_metadata *meta = *pmeta;\ninclude/net/xdp_sock_drv.h-292-\tu64 flags;\n--\ninclude/net/xdp_sock_drv.h-320-\ninclude/net/xdp_sock_drv.h:321:static inline struct xsk_tx_metadata *\ninclude/net/xdp_sock_drv.h-322-__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data,\n--\ninclude/net/xdp_sock_drv.h-330-\ninclude/net/xdp_sock_drv.h:331:static inline struct xsk_tx_metadata *\ninclude/net/xdp_sock_drv.h-332-xsk_buff_get_metadata(struct xsk_buff_pool *pool, u64 addr, u32 options)\n--\ninclude/net/xdp_sock_drv.h=522=xsk_buff_valid_tx_metadata(const struct xsk_buff_pool *pool,\ninclude/net/xdp_sock_drv.h:523:\t\t\t const struct xsk_tx_metadata *meta, u64 *flags)\ninclude/net/xdp_sock_drv.h-524-{\n--\ninclude/net/xdp_sock_drv.h=529=xsk_tx_metadata_request(const struct xsk_buff_pool *pool,\ninclude/net/xdp_sock_drv.h:530:\t\t\tstruct xsk_tx_metadata **pmeta,\ninclude/net/xdp_sock_drv.h:531:\t\t\tconst struct xsk_tx_metadata_ops *ops, void *priv)\ninclude/net/xdp_sock_drv.h-532-{\n--\ninclude/net/xdp_sock_drv.h-534-\ninclude/net/xdp_sock_drv.h:535:static inline struct xsk_tx_metadata *\ninclude/net/xdp_sock_drv.h-536-__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data,\n--\ninclude/net/xdp_sock_drv.h-541-\ninclude/net/xdp_sock_drv.h:542:static inline struct xsk_tx_metadata *\ninclude/net/xdp_sock_drv.h-543-xsk_buff_get_metadata(struct xsk_buff_pool *pool, u64 addr, u32 options)\n--\ninclude/net/xsk_buff_pool.h=25=struct xdp_buff_xsk {\n--\ninclude/net/xsk_buff_pool.h-34-#define XSK_CHECK_PRIV_TYPE(t) BUILD_BUG_ON(sizeof(t) \u003e offsetofend(struct xdp_buff_xsk, cb))\ninclude/net/xsk_buff_pool.h:35:#define XSK_TX_COMPL_FITS(t) BUILD_BUG_ON(sizeof(struct xsk_tx_metadata_compl) \u003e sizeof(t))\ninclude/net/xsk_buff_pool.h-36-\n--\ninclude/net/xsk_buff_pool.h=152=struct xdp_desc_ctx {\ninclude/net/xsk_buff_pool.h-153-\tdma_addr_t dma;\ninclude/net/xsk_buff_pool.h:154:\tstruct xsk_tx_metadata *meta;\ninclude/net/xsk_buff_pool.h-155-};\n--\ninclude/uapi/linux/if_xdp.h=102=struct xdp_options {\n--\ninclude/uapi/linux/if_xdp.h-120-/* Request transmit timestamp. Upon completion, put it into tx_timestamp\ninclude/uapi/linux/if_xdp.h:121: * field of struct xsk_tx_metadata.\ninclude/uapi/linux/if_xdp.h-122- */\n--\ninclude/uapi/linux/if_xdp.h-132- * transmission at a pre-determined time called launch time. The value of\ninclude/uapi/linux/if_xdp.h:133: * launch time is communicated via launch_time field of struct xsk_tx_metadata.\ninclude/uapi/linux/if_xdp.h-134- */\n--\ninclude/uapi/linux/if_xdp.h-140- */\ninclude/uapi/linux/if_xdp.h:141:struct xsk_tx_metadata {\ninclude/uapi/linux/if_xdp.h-142-\t__u64 flags;\n--\nnet/xdp/xsk.c=908=void xsk_destruct_skb(struct sk_buff *skb)\nnet/xdp/xsk.c-909-{\nnet/xdp/xsk.c:910:\tstruct xsk_tx_metadata_compl *compl = \u0026skb_shinfo(skb)-\u003exsk_meta;\nnet/xdp/xsk.c-911-\n--\nnet/xdp/xsk.c=964=static int xsk_skb_metadata(struct sk_buff *skb, void *buffer,\n--\nnet/xdp/xsk.c-967-{\nnet/xdp/xsk.c:968:\tstruct xsk_tx_metadata *meta = NULL;\nnet/xdp/xsk.c-969-\tu16 csum_start, csum_offset;\n--\ntools/include/uapi/linux/if_xdp.h=102=struct xdp_options {\n--\ntools/include/uapi/linux/if_xdp.h-120-/* Request transmit timestamp. Upon completion, put it into tx_timestamp\ntools/include/uapi/linux/if_xdp.h:121: * field of struct xsk_tx_metadata.\ntools/include/uapi/linux/if_xdp.h-122- */\n--\ntools/include/uapi/linux/if_xdp.h-132- * transmission at a pre-determined time called launch time. The value of\ntools/include/uapi/linux/if_xdp.h:133: * launch time is communicated via launch_time field of struct xsk_tx_metadata.\ntools/include/uapi/linux/if_xdp.h-134- */\n--\ntools/include/uapi/linux/if_xdp.h-140- */\ntools/include/uapi/linux/if_xdp.h:141:struct xsk_tx_metadata {\ntools/include/uapi/linux/if_xdp.h-142-\t__u64 flags;\n--\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c=59=static int open_xsk(int ifindex, struct xsk *xsk)\n--\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c-72-\t\t\t XDP_UMEM_TX_METADATA_LEN,\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c:73:\t\t.tx_metadata_len = sizeof(struct xsk_tx_metadata),\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c-74-\t};\n--\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c=136=static int generate_packet(struct xsk *xsk, __u16 dst_port)\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c-137-{\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c:138:\tstruct xsk_tx_metadata *meta;\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c-139-\tstruct xdp_desc *tx_desc;\n--\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c-151-\ttx_desc = xsk_ring_prod__tx_desc(\u0026xsk-\u003etx, idx);\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c:152:\ttx_desc-\u003eaddr = idx % (UMEM_NUM / 2) * UMEM_FRAME_SIZE + sizeof(struct xsk_tx_metadata);\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c-153-\tprintf(\"%p: tx_desc[%u]-\u003eaddr=%llx\\n\", xsk, idx, tx_desc-\u003eaddr);\n--\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c-155-\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c:156:\tmeta = data - sizeof(struct xsk_tx_metadata);\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c-157-\tmemset(meta, 0, sizeof(*meta));\n--\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c=227=static void complete_tx(struct xsk *xsk)\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c-228-{\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c:229:\tstruct xsk_tx_metadata *meta;\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c-230-\t__u64 addr;\n--\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c-239-\t\tdata = xsk_umem__get_data(xsk-\u003eumem_area, addr);\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c:240:\t\tmeta = data - sizeof(struct xsk_tx_metadata);\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c-241-\n--\ntools/testing/selftests/bpf/xdp_hw_metadata.c=92=static int open_xsk(int ifindex, struct xsk *xsk, __u32 queue_id)\n--\ntools/testing/selftests/bpf/xdp_hw_metadata.c-104-\t\t.flags = XDP_UMEM_TX_METADATA_LEN,\ntools/testing/selftests/bpf/xdp_hw_metadata.c:105:\t\t.tx_metadata_len = sizeof(struct xsk_tx_metadata),\ntools/testing/selftests/bpf/xdp_hw_metadata.c-106-\t};\n--\ntools/testing/selftests/bpf/xdp_hw_metadata.c=304=static bool complete_tx(struct xsk *xsk, clockid_t clock_id)\ntools/testing/selftests/bpf/xdp_hw_metadata.c-305-{\ntools/testing/selftests/bpf/xdp_hw_metadata.c:306:\tstruct xsk_tx_metadata *meta;\ntools/testing/selftests/bpf/xdp_hw_metadata.c-307-\t__u64 addr;\n--\ntools/testing/selftests/bpf/xdp_hw_metadata.c-315-\tdata = xsk_umem__get_data(xsk-\u003eumem_area, addr);\ntools/testing/selftests/bpf/xdp_hw_metadata.c:316:\tmeta = data - sizeof(struct xsk_tx_metadata);\ntools/testing/selftests/bpf/xdp_hw_metadata.c-317-\n--\ntools/testing/selftests/bpf/xdp_hw_metadata.c=352=static void ping_pong(struct xsk *xsk, void *rx_packet, clockid_t clock_id)\ntools/testing/selftests/bpf/xdp_hw_metadata.c-353-{\ntools/testing/selftests/bpf/xdp_hw_metadata.c:354:\tstruct xsk_tx_metadata *meta;\ntools/testing/selftests/bpf/xdp_hw_metadata.c-355-\tstruct ipv6hdr *ip6h = NULL;\n--\ntools/testing/selftests/bpf/xdp_hw_metadata.c-372-\ttx_desc = xsk_ring_prod__tx_desc(\u0026xsk-\u003etx, idx);\ntools/testing/selftests/bpf/xdp_hw_metadata.c:373:\ttx_desc-\u003eaddr = idx % (UMEM_NUM / 2) * UMEM_FRAME_SIZE + sizeof(struct xsk_tx_metadata);\ntools/testing/selftests/bpf/xdp_hw_metadata.c-374-\tdata = xsk_umem__get_data(xsk-\u003eumem_area, tx_desc-\u003eaddr);\ntools/testing/selftests/bpf/xdp_hw_metadata.c-375-\ntools/testing/selftests/bpf/xdp_hw_metadata.c:376:\tmeta = data - sizeof(struct xsk_tx_metadata);\ntools/testing/selftests/bpf/xdp_hw_metadata.c-377-\tmemset(meta, 0, sizeof(*meta));\n"
} |
| 17/2 | 2026/08/13 20:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 23696 output: 41 thoughts: 370 Thoughts: **My Initial Thoughts on the UAPI Change**
Okay, so the UAPI change is messing with `struct xsk_tx_metadata`. I see they've added `__u32 reserved;`. My first thought is, "Right, that's going to change `sizeof(struct xsk_tx_metadata)`." Which immediately leads me to, "Does this impact the core kernel? Are we going to have to account for this change?"
Let me check `xsk_buff_valid_tx_metadata` in `include/net/xdp_sock_drv.h`. Ah, here it is:
```c
if (pool->tx_metadata_len <
offsetofend(struct xsk_tx_metadata, request.launch_time))
return false;
```
It's a compile-time offset check, which is good, but now that `reserved` is added, `request.launch_time`'s offset will be different. That's a problem!
Wait, hold on a second. Let me look at the definition of `struct xsk_tx_metadata` again.
```c
struct xsk_tx_metadata {
__u64 flags;
/* XDP_TXMD_FLAGS_CHECKSUM */
struct {
/* Offset from desc->addr where checksumming should start. */
__u16 csum_start;
/* Offset from csum_start where checksum should be stored. */
__u16 csum_offset;
__u32 reserved;
} request;
/* XDP_TXMD_FLAGS_LAUNCH_TIME */
struct {
/* Launch time in nanosecond against the PTP HW Clock */
__u64 launch_time;
} request;
};
```
Is this struct really defining `request` multiple times? No, it's a union, or maybe an anonymous struct. That's a crucial detail. I need to make sure I'm interpreting this correctly. Let me jump over to `include/uapi/linux/if_xdp.h` to confirm the definition. I need to fully understand how this `request` field works before I can assess the kernel impact accurately.
|
| 18/2 | 2026/08/13 20:20 | tool | read-file |
0mArgs:{
"File": "include/uapi/linux/if_xdp.h",
"FirstLine": 135,
"LineCount": 50
}Results: {
"Contents": " 135:\t#define XDP_TXMD_FLAGS_LAUNCH_TIME\t\t(1 \u003c\u003c 2)\n 136:\t\n 137:\t/* AF_XDP offloads request. 'request' union member is consumed by the driver\n 138:\t * when the packet is being transmitted. 'completion' union member is\n 139:\t * filled by the driver when the transmit completion arrives.\n 140:\t */\n 141:\tstruct xsk_tx_metadata {\n 142:\t\t__u64 flags;\n 143:\t\n 144:\t\tunion {\n 145:\t\t\tstruct {\n 146:\t\t\t\t/* XDP_TXMD_FLAGS_CHECKSUM */\n 147:\t\n 148:\t\t\t\t/* Offset from desc-\u003eaddr where checksumming should start. */\n 149:\t\t\t\t__u16 csum_start;\n 150:\t\t\t\t/* Offset from csum_start where checksum should be stored. */\n 151:\t\t\t\t__u16 csum_offset;\n 152:\t\t\t\t__u32 reserved;\n 153:\t\n 154:\t\t\t\t/* XDP_TXMD_FLAGS_LAUNCH_TIME */\n 155:\t\t\t\t/* Launch time in nanosecond against the PTP HW Clock */\n 156:\t\t\t\t__u64 launch_time;\n 157:\t\t\t} request;\n 158:\t\n 159:\t\t\tstruct {\n 160:\t\t\t\t/* XDP_TXMD_FLAGS_TIMESTAMP */\n 161:\t\t\t\t__u64 tx_timestamp;\n 162:\t\t\t} completion;\n 163:\t\t};\n 164:\t};\n 165:\t\n 166:\t/* Rx/Tx descriptor */\n 167:\tstruct xdp_desc {\n 168:\t\t__u64 addr;\n 169:\t\t__u32 len;\n 170:\t\t__u32 options;\n 171:\t};\n 172:\t\n 173:\t/* UMEM descriptor is __u64 */\n 174:\t\n 175:\t/* Flag indicating that the packet continues with the buffer pointed out by the\n 176:\t * next frame in the ring. The end of the packet is signalled by setting this\n 177:\t * bit to zero. For single buffer packets, every descriptor has 'options' set\n 178:\t * to 0 and this maintains backward compatibility.\n 179:\t */\n 180:\t#define XDP_PKT_CONTD (1 \u003c\u003c 0)\n 181:\t\n 182:\t/* TX packet carries valid metadata. */\n 183:\t#define XDP_TX_METADATA (1 \u003c\u003c 1)\n 184:\t\n"
} |
| 19/2 | 2026/08/13 20:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 25314 output: 20 thoughts: 865 Thoughts: **Analyzing AF_XDP Metadata Handling and Alignment** Okay, so I'm looking at this code and immediately see a struct `request` nestled inside a `union`. The key here is the addition of `__u32 reserved;`. My brain immediately jumps to alignment. I know that `csum_start` and `csum_offset` are 2 bytes each. Before, `launch_time` (`__u64`) was probably directly after those, making its offset 4 bytes. That's a problem because, on 64-bit architectures, `__u64` needs 8-byte alignment. So, without padding, it's misaligned. Adding `__u32 reserved` explicitly aligns `launch_time`, shifting its offset to 8 bytes and ensuring proper memory layout, which makes this a UAPI fix. I then move on to the `__xsk_buff_get_metadata` function. The change there involves checking `options & XDP_TX_METADATA`. This is definitely a core change related to AF_XDP. But I need to think about where this is actually used, especially in virtualized environments like QEMU. The call sites are what matter. I see `__xsk_buff_get_metadata` is called by `xsk_buff_get_metadata` (used by `igc`, `mlx5`, `stmmac`) and `xp_raw_get_ctx` (used by a chain of functions ending with `idpf`). None of these drivers (`igc`, `mlx5`, `idpf`) are usually emulated in standard QEMU. Now, `stmmac`, that's the one I need to check. I need to confirm if it's enabled in the syzkaller configs. I need to go verify `drivers/net/ethernet/stmicro/stmmac/Kconfig`. |
| 20/2 | 2026/08/13 20:20 | tool | grepper |
0mArgs:{
"Expression": "config STMMAC_ETH"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/ethernet/stmicro/stmmac/Kconfig:2:config STMMAC_ETH\ndrivers/net/ethernet/stmicro/stmmac/Kconfig-3-\ttristate \"STMicroelectronics Multi-Gigabit Ethernet driver\"\n"
} |
| 21/2 | 2026/08/13 20:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 26713 output: 20 thoughts: 14 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience: **Checking for the `STMMAC_PCI` Flag** Okay, so I'm diving into this driver code, and first thing's first: gotta make sure we're dealing with a configuration that actually uses PCI for the STMMAC (STMicroelectronics Media Access Controller) device. My initial thought process? "Is `STMMAC_PCI` even defined?" I need to confirm if the code is structured to accommodate a PCI-based STMMAC instance. This check is crucial; it dictates the execution path and subsequent actions the driver will take. It's essentially the gatekeeper for PCI-specific initialization and resource allocation, so confirming this is essential before moving any further. If it's *not* defined, I'll need to adapt my analysis accordingly, as I'm likely looking at a different hardware setup or configuration altogether. This is the starting point for understanding how the device interacts with the system. |
| 22/2 | 2026/08/13 20:20 | tool | grepper |
0mArgs:{
"Expression": "config STMMAC_PCI"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/Kconfig=398=config DWMAC_MOTORCOMM\n--\ndrivers/net/ethernet/stmicro/stmmac/Kconfig-406-\ndrivers/net/ethernet/stmicro/stmmac/Kconfig:407:config STMMAC_PCI\ndrivers/net/ethernet/stmicro/stmmac/Kconfig-408-\ttristate \"STMMAC PCI bus support\"\n"
} |
| 23/2 | 2026/08/13 20:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 27084 output: 36 thoughts: 130 Thoughts: **Network Driver Considerations** Okay, so I'm thinking about the `STMMAC_PCI` driver. I know it exists, but I need to figure out how it's handled within QEMU. Does QEMU emulate it directly? Nope, doesn't look like it. I know QEMU emulates other network interfaces - `e1000`, `e1000e`, `igb`, `rtl8139`, `pcnet`, `ne2k_pci`, `vmxnet3`, and `virtio-net-pci` are familiar ones. But `STMMAC_PCI` isn't on the list. Now, my mind shifts to `veth`. It's a key virtual Ethernet device. I'm wondering about the implementation details. Specifically, I'm curious whether `veth` makes use of `xsk_buff_get_metadata` in its operation. To confirm this, I need to delve into the source code, so I'll check `drivers/net/veth.c`. That's where I'll find the answers I need. |
| 24/2 | 2026/08/13 20:20 | tool | grepper |
0mError:no matches Args: {
"Expression": "xsk_buff_get_metadata",
"PathPrefix": "drivers/net/veth.c"
}Results: {
"error": "no matches"
} |
| 25/2 | 2026/08/13 20:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 27509 output: 37 thoughts: 40 Thoughts: Okay, here's my attempt at summarizing those thoughts from a first-person, expert perspective: **Investigating eBPF Data Access** Hmm, so the question of whether `veth` uses something like a shared ring buffer or metadata access in the XDP context is still hanging. It doesn't look like it does based on my prior knowledge, but I need to be completely sure. I quickly rule out `veth`'s direct implementation. I need to dig deeper. My thoughts immediately jump to `net/xdp/xsk.c`. I know that's where the XDP socket implementation lives and is therefore where any XDP-related metadata handling is likely located. The critical piece of info I need to determine now is whether this `xsk_buff_get_metadata` function is used. If it is, then the mechanism is there, and I need to understand its usage. If not, I can continue to investigate other locations of potential access. I'll need to review the code to understand the context. |
| 26/2 | 2026/08/13 20:20 | tool | grepper |
0mError:no matches Args: {
"Expression": "xsk_buff_get_metadata",
"PathPrefix": "net/xdp/xsk.c"
}Results: {
"error": "no matches"
} |
| 27/2 | 2026/08/13 20:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 27818 output: 22 thoughts: 333 Thoughts: **My Analysis of XDP Data Path**
Okay, no. Let's re-evaluate this. I need to figure out where this metadata gets handled. I recall seeing `__xsk_buff_get_metadata` in `net/xdp/xsk_buff_pool.c` within `xp_raw_get_ctx`. Now, is `xp_raw_get_ctx` used anywhere else? Time to double-check. I did a quick grep already, and it looks like `xp_raw_get_ctx` is *only* used in `xsk_buff_raw_get_ctx` within `include/net/xdp_sock_drv.h`, which in turn, is only used by `__libeth_xsk_xmit_fill_buf_md`. I think I found it.
And, of course, `__libeth_xsk_xmit_fill_buf_md` is *solely* used in `idpf`. I knew it!
Hold on, I almost missed something. What about that change in `stmmac_xdp_xmit_zc`? That snippet...
```c
- 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;
- }
```
...removes the check for `max_sdu` in `stmmac_xdp_xmit_zc`. But, the `stmmac` driver isn't even reachable in QEMU. That's a dead end, then.
Let's broaden the search a bit. Is there *any* other driver I haven't considered? I need to look for `XDP_TX_METADATA` directly to see what else might be involved.
|
| 28/2 | 2026/08/13 20:20 | tool | grepper |
0mArgs:{
"Expression": "XDP_TX_METADATA"
}Results: {
"Output": "Documentation/networking/xsk-tx-metadata.rst=41=the ``xsk_tx_metadata``). For the frames that shouldn't carry\nDocumentation/networking/xsk-tx-metadata.rst:42:any metadata (i.e., the ones that don't have ``XDP_TX_METADATA`` option),\nDocumentation/networking/xsk-tx-metadata.rst-43-the metadata area is ignored by the kernel as well.\n--\nDocumentation/networking/xsk-tx-metadata.rst=59=Besides the flags above, in order to trigger the offloads, the first\nDocumentation/networking/xsk-tx-metadata.rst:60:packet's ``struct xdp_desc`` descriptor should set ``XDP_TX_METADATA``\nDocumentation/networking/xsk-tx-metadata.rst-61-bit in the ``options`` field. Also note that in a multi-buffer packet\n--\ninclude/net/xdp_sock_drv.h=322=__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data,\n--\ninclude/net/xdp_sock_drv.h-324-{\ninclude/net/xdp_sock_drv.h:325:\tif (!pool-\u003etx_metadata_len || !(options \u0026 XDP_TX_METADATA))\ninclude/net/xdp_sock_drv.h-326-\t\treturn NULL;\n--\ninclude/uapi/linux/if_xdp.h=167=struct xdp_desc {\n--\ninclude/uapi/linux/if_xdp.h-182-/* TX packet carries valid metadata. */\ninclude/uapi/linux/if_xdp.h:183:#define XDP_TX_METADATA (1 \u003c\u003c 1)\ninclude/uapi/linux/if_xdp.h-184-\n--\nnet/xdp/xsk.c=1009=static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,\n--\nnet/xdp/xsk.c-1030-\t\tskb_reserve(skb, hr);\nnet/xdp/xsk.c:1031:\t\tif (desc-\u003eoptions \u0026 XDP_TX_METADATA) {\nnet/xdp/xsk.c-1032-\t\t\terr = xsk_skb_metadata(skb, buffer, desc, pool, hr);\n--\nnet/xdp/xsk.c=1085=static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,\n--\nnet/xdp/xsk.c-1119-\nnet/xdp/xsk.c:1120:\t\t\tif (desc-\u003eoptions \u0026 XDP_TX_METADATA) {\nnet/xdp/xsk.c-1121-\t\t\t\terr = xsk_skb_metadata(skb, buffer, desc,\n--\nnet/xdp/xsk_queue.h=154=static inline bool xp_unused_options_set(u32 options)\nnet/xdp/xsk_queue.h-155-{\nnet/xdp/xsk_queue.h:156:\treturn options \u0026 ~(XDP_PKT_CONTD | XDP_TX_METADATA);\nnet/xdp/xsk_queue.h-157-}\n--\ntools/include/uapi/linux/if_xdp.h=167=struct xdp_desc {\n--\ntools/include/uapi/linux/if_xdp.h-182-/* TX packet carries valid metadata. */\ntools/include/uapi/linux/if_xdp.h:183:#define XDP_TX_METADATA (1 \u003c\u003c 1)\ntools/include/uapi/linux/if_xdp.h-184-\n--\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c=136=static int generate_packet(struct xsk *xsk, __u16 dst_port)\n--\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c-192-\ttx_desc-\u003elen = sizeof(*eth) + sizeof(*iph) + sizeof(*udph) + UDP_PAYLOAD_BYTES;\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c:193:\ttx_desc-\u003eoptions |= XDP_TX_METADATA;\ntools/testing/selftests/bpf/prog_tests/xdp_metadata.c-194-\txsk_ring_prod__submit(\u0026xsk-\u003etx, 1);\n--\ntools/testing/selftests/bpf/xdp_hw_metadata.c=352=static void ping_pong(struct xsk *xsk, void *rx_packet, clockid_t clock_id)\n--\ntools/testing/selftests/bpf/xdp_hw_metadata.c-437-\tmemcpy(data, rx_packet, len); /* don't share umem chunk for simplicity */\ntools/testing/selftests/bpf/xdp_hw_metadata.c:438:\ttx_desc-\u003eoptions |= XDP_TX_METADATA;\ntools/testing/selftests/bpf/xdp_hw_metadata.c-439-\ttx_desc-\u003elen = len;\n"
} |
| 29/2 | 2026/08/13 20:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 29946 output: 36 thoughts: 286 Thoughts: **XDP_TX_METADATA and the Implications of This Patch**
Okay, hold on a second. I just saw that `net/xdp/xsk.c` makes use of `XDP_TX_METADATA`. That's at line 1031, specifically:
```c
if (desc->options & XDP_TX_METADATA) {
err = xsk_skb_metadata(skb, buffer, desc, pool, hr);
}
```
But this patch doesn't *directly* touch `net/xdp/xsk.c`. The changes are in `include/net/xdp_sock_drv.h`, `include/net/xsk_buff_pool.h`, `net/xdp/xsk_buff_pool.c`, `include/uapi/linux/if_xdp.h`, `include/net/libeth/xsk.h`, and a few drivers: `igc`, `mlx5`, and `stmmac`. So, the question is, is there indirect impact?
The UAPI change in `include/uapi/linux/if_xdp.h` is where the potential gotcha is. There's a new `__u32 reserved;` field being added. Now, does *that* impact the `xsk_skb_metadata` function? That's the critical question. I need to take a closer look at `xsk_skb_metadata` in `net/xdp/xsk.c` to see if it relies on any of the structure or data that are in the include files that are being modified.
|
| 30/2 | 2026/08/13 20:20 | tool | grepper |
0mArgs:{
"Expression": "xsk_skb_metadata",
"PathPrefix": "net/xdp/xsk.c"
}Results: {
"Output": "net/xdp/xsk.c=955=static void xsk_drop_skb(struct sk_buff *skb)\n--\nnet/xdp/xsk.c-963-\nnet/xdp/xsk.c:964:static int xsk_skb_metadata(struct sk_buff *skb, void *buffer,\nnet/xdp/xsk.c-965-\t\t\t struct xdp_desc *desc, struct xsk_buff_pool *pool,\n--\nnet/xdp/xsk.c=1009=static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,\n--\nnet/xdp/xsk.c-1031-\t\tif (desc-\u003eoptions \u0026 XDP_TX_METADATA) {\nnet/xdp/xsk.c:1032:\t\t\terr = xsk_skb_metadata(skb, buffer, desc, pool, hr);\nnet/xdp/xsk.c-1033-\t\t\tif (unlikely(err)) {\n--\nnet/xdp/xsk.c=1085=static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,\n--\nnet/xdp/xsk.c-1120-\t\t\tif (desc-\u003eoptions \u0026 XDP_TX_METADATA) {\nnet/xdp/xsk.c:1121:\t\t\t\terr = xsk_skb_metadata(skb, buffer, desc,\nnet/xdp/xsk.c-1122-\t\t\t\t\t\t xs-\u003epool, hr);\n"
} |
| 31/2 | 2026/08/13 20:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 31041 output: 37 thoughts: 13 Thoughts: Okay, here's my interpretation of that thought process, assuming I'm deep in the weeds of network programming, possibly working with XDP: **Analyzing `xsk_skb_metadata`** Alright, time to dive into `xsk_skb_metadata`. That name immediately tells me we're looking at something crucial to the interaction between the XDP socket (XSK) and the kernel's SKB (Socket Buffer). This is where the magic happens, where the XDP program grabs or hands off control of packets. I need to understand this structure intimately. I suspect it's the glue holding together the XSK's efficient zero-copy mechanism with the more traditional SKB world. I'll need to pay close attention to the members within it. Probably looking at things like pointers to the packet data, the metadata flags, maybe some sort of index into the AF_XDP shared memory ring. Is there a descriptor? How is reference counting handled between XDP program and the SKB? Is this structure used in both the TX and RX paths, or is it specific to one direction? I bet there are nuances here around memory management, concurrency, and error handling. Got to start examining the actual struct definition and see how it's used within the various kernel functions... This will tell me more about its purpose. I'll need to trace its usage in both the RX and TX paths to get the bigger picture. Okay, let's get started. |
| 32/2 | 2026/08/13 20:20 | tool | read-file |
0mArgs:{
"File": "net/xdp/xsk.c",
"FirstLine": 964,
"LineCount": 40
}Results: {
"Contents": " 964:\tstatic int xsk_skb_metadata(struct sk_buff *skb, void *buffer,\n 965:\t\t\t\t struct xdp_desc *desc, struct xsk_buff_pool *pool,\n 966:\t\t\t\t u32 hr)\n 967:\t{\n 968:\t\tstruct xsk_tx_metadata *meta = NULL;\n 969:\t\tu16 csum_start, csum_offset;\n 970:\t\tu64 flags;\n 971:\t\n 972:\t\tif (unlikely(pool-\u003etx_metadata_len == 0))\n 973:\t\t\treturn -EINVAL;\n 974:\t\n 975:\t\tmeta = buffer - pool-\u003etx_metadata_len;\n 976:\t\tif (unlikely(!xsk_buff_valid_tx_metadata(pool, meta, \u0026flags)))\n 977:\t\t\treturn -EINVAL;\n 978:\t\n 979:\t\tif (flags \u0026 XDP_TXMD_FLAGS_CHECKSUM) {\n 980:\t\t\tcsum_start = READ_ONCE(meta-\u003erequest.csum_start);\n 981:\t\t\tcsum_offset = READ_ONCE(meta-\u003erequest.csum_offset);\n 982:\t\n 983:\t\t\tif (unlikely(csum_start + csum_offset +\n 984:\t\t\t\t sizeof(__sum16) \u003e desc-\u003elen))\n 985:\t\t\t\treturn -EINVAL;\n 986:\t\n 987:\t\t\tskb-\u003ecsum_start = hr + csum_start;\n 988:\t\t\tskb-\u003ecsum_offset = csum_offset;\n 989:\t\t\tskb-\u003eip_summed = CHECKSUM_PARTIAL;\n 990:\t\n 991:\t\t\tif (unlikely(pool-\u003etx_sw_csum)) {\n 992:\t\t\t\tint err;\n 993:\t\n 994:\t\t\t\terr = skb_checksum_help(skb);\n 995:\t\t\t\tif (err)\n 996:\t\t\t\t\treturn err;\n 997:\t\t\t}\n 998:\t\t}\n 999:\t\n1000:\t\tif (flags \u0026 XDP_TXMD_FLAGS_LAUNCH_TIME)\n1001:\t\t\tskb-\u003eskb_mstamp_ns = READ_ONCE(meta-\u003erequest.launch_time);\n1002:\t\tif (!(flags \u0026 XDP_TXMD_FLAGS_TIMESTAMP))\n1003:\t\t\tmeta = NULL;\n"
} |
| 33/2 | 2026/08/13 20:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 32058 output: 40 thoughts: 76 Thoughts: Here's my thought process, as it just occurred to me while analyzing this code snippet: **Diving into xsk_buff_valid_tx_metadata** Okay, so I see `xsk_skb_metadata` calls `xsk_buff_valid_tx_metadata`. My spider senses are tingling, I need to understand what that validation entails. Now, I vaguely recall seeing `xsk_buff_valid_tx_metadata` in `include/net/xdp_sock_drv.h`, that rings a bell. Let's head over to that include and take a closer look at its definition. I need to understand what `pool`, `meta`, and `flags` are all about in this context and how this validation function works. Hopefully, this sheds some light on the overall flow, specifically how the SKB metadata is being treated and its role in transmission. |
| 34/2 | 2026/08/13 20:21 | tool | read-file |
0mArgs:{
"File": "include/net/xdp_sock_drv.h",
"FirstLine": 264,
"LineCount": 20
}Results: {
"Contents": " 264:\txsk_buff_valid_tx_metadata(const struct xsk_buff_pool *pool,\n 265:\t\t\t\t const struct xsk_tx_metadata *meta, u64 *flags)\n 266:\t{\n 267:\t\t*flags = READ_ONCE(meta-\u003eflags);\n 268:\t\tif (*flags \u0026 XDP_TXMD_FLAGS_LAUNCH_TIME)\n 269:\t\t\tif (pool-\u003etx_metadata_len \u003c\n 270:\t\t\t offsetofend(struct xsk_tx_metadata, request.launch_time))\n 271:\t\t\t\treturn false;\n 272:\t\treturn !(*flags \u0026 ~XDP_TXMD_FLAGS_VALID);\n 273:\t}\n 274:\t\n 275:\t/**\n 276:\t * xsk_tx_metadata_request - Evaluate AF_XDP TX metadata at submission\n 277:\t * and call appropriate xsk_tx_metadata_ops operation.\n 278:\t * @pool: pointer to AF_XDP buffer pool, used to validate the metadata\n 279:\t * @pmeta: pointer to pointer to AF_XDP metadata area\n 280:\t * @ops: pointer to struct xsk_tx_metadata_ops\n 281:\t * @priv: pointer to driver-private area\n 282:\t *\n 283:\t * This function should be called by the networking device when\n"
} |
| 35/2 | 2026/08/13 20:21 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 32744 output: 30 thoughts: 1188 Thoughts: **Analyzing the XSK TX Metadata Change and Potential Impact**
Okay, so I'm digging into this XSK change related to `xsk_buff_valid_tx_metadata`. The crux of it seems to be that they've added a `reserved` field to the `xsk_tx_metadata` structure, which shifts the offset of `request.launch_time`. My immediate concern is that this could break compatibility if userspace code was compiled with the *old* structure definition. Specifically, if the user-space program relies on an older version of the XSK headers, where the `tx_metadata_len` it sets in `struct xdp_umem_reg` would be smaller than the actual new structure size.
I need to confirm that. I'm thinking, if they passed `sizeof(struct xsk_tx_metadata)` from the old header, that size would have been 12 bytes initially (or potentially 16 bytes due to padding). Now, with the reserved field, I have to figure out the exact size for both 32-bit and 64-bit architectures.
I'm thinking about the layout of the old `struct xsk_tx_metadata` struct:
```c
struct xsk_tx_metadata {
__u64 flags; // 8 bytes
union {
struct {
/* XDP_TXMD_FLAGS_CHECKSUM */
/* Offset from desc->addr where checksumming should start. */
__u16 csum_start; // 2 bytes
/* Offset from csum_start where checksum should be stored. */
__u16 csum_offset; // 2 bytes
/* XDP_TXMD_FLAGS_LAUNCH_TIME */
/* Launch time in nanosecond against the PTP HW Clock */
__u64 launch_time; // 8 bytes
} request; // 12 bytes, but with 8-byte alignment it is padded to 16 bytes?
```
I realize `__u64 launch_time` requires 8-byte alignment on 64-bit architectures. This means that on 64-bit architectures the compiler inserts padding. So in the old struct, the size of the request field was actually 16 bytes (padding after `csum_offset`). The entire structure's size would then be 8 (flags) + 16 (request) = 24 bytes. However, on 32-bit machines, `__u64` only requires 4-byte alignment, so the `request` structure is only 12 bytes, which would result in a total struct size of 8 + 12 = 20 bytes.
Now, with the addition of `__u32 reserved`, the `request` structure becomes:
```c
struct {
/* XDP_TXMD_FLAGS_CHECKSUM */
/* Offset from desc->addr where checksumming should start. */
__u16 csum_start; // 2 bytes
/* Offset from csum_start where checksum should be stored. */
__u16 csum_offset; // 2 bytes
__u32 reserved; // 4 bytes
/* XDP_TXMD_FLAGS_LAUNCH_TIME */
/* Launch time in nanosecond against the PTP HW Clock */
__u64 launch_time; // 8 bytes
} request; // 16 bytes
```
The `request` structure would be 2 + 2 + 4 + 8 = 16 bytes on both 32 and 64 bit architectures. Total size would be 8 (flags) + 16 (request) = 24 bytes.
So, this patch effectively fixes a 32-bit/64-bit ABI mismatch, cool!
Next, I need to understand if this UAPI change introduces any new execution paths that need to be fuzzed. The changed layout on 32-bit architectures, and explicit padding on 64-bit machines warrants closer inspection. Also, I noticed the patch modifies `__xsk_buff_get_metadata` to check `options & XDP_TX_METADATA`, which could be a change point.
I'm following the call chain: `__xsk_buff_get_metadata` is used in `xp_raw_get_ctx`, which is in turn used by `xsk_buff_raw_get_ctx` and finally in `__libeth_xsk_xmit_fill_buf_md`. I checked before if `xsk_buff_get_metadata` is used
|
| 36/2 | 2026/08/13 20:21 | tool | grepper |
0mArgs:{
"Expression": "xsk_buff_pool",
"PathPrefix": "drivers/net/"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 918 lines.\nUse more precise expression if possible.\n\ndrivers/net/ethernet/engleder/tsnep.h=80=struct tsnep_tx {\n--\ndrivers/net/ethernet/engleder/tsnep.h-92-\tint increment_owner_counter;\ndrivers/net/ethernet/engleder/tsnep.h:93:\tstruct xsk_buff_pool *xsk_pool;\ndrivers/net/ethernet/engleder/tsnep.h-94-\n--\ndrivers/net/ethernet/engleder/tsnep.h=115=struct tsnep_rx {\n--\ndrivers/net/ethernet/engleder/tsnep.h-130-\tstruct page **page_buffer;\ndrivers/net/ethernet/engleder/tsnep.h:131:\tstruct xsk_buff_pool *xsk_pool;\ndrivers/net/ethernet/engleder/tsnep.h-132-\tstruct xdp_buff **xdp_batch;\n--\ndrivers/net/ethernet/engleder/tsnep.h=231=int tsnep_xdp_setup_pool(struct tsnep_adapter *adapter,\ndrivers/net/ethernet/engleder/tsnep.h:232:\t\t\t struct xsk_buff_pool *pool, u16 queue_id);\ndrivers/net/ethernet/engleder/tsnep.h-233-\n--\ndrivers/net/ethernet/engleder/tsnep.h=260=u32 tsnep_get_irq_coalesce(struct tsnep_queue *queue);\ndrivers/net/ethernet/engleder/tsnep.h:261:int tsnep_enable_xsk(struct tsnep_queue *queue, struct xsk_buff_pool *pool);\ndrivers/net/ethernet/engleder/tsnep.h-262-void tsnep_disable_xsk(struct tsnep_queue *queue);\n--\ndrivers/net/ethernet/engleder/tsnep_main.c=2074=static int tsnep_netdev_close(struct net_device *netdev)\n--\ndrivers/net/ethernet/engleder/tsnep_main.c-2095-\ndrivers/net/ethernet/engleder/tsnep_main.c:2096:int tsnep_enable_xsk(struct tsnep_queue *queue, struct xsk_buff_pool *pool)\ndrivers/net/ethernet/engleder/tsnep_main.c-2097-{\n--\ndrivers/net/ethernet/engleder/tsnep_xdp.c=21=static int tsnep_xdp_enable_pool(struct tsnep_adapter *adapter,\ndrivers/net/ethernet/engleder/tsnep_xdp.c:22:\t\t\t\t struct xsk_buff_pool *pool, u16 queue_id)\ndrivers/net/ethernet/engleder/tsnep_xdp.c-23-{\n--\ndrivers/net/ethernet/engleder/tsnep_xdp.c=58=static int tsnep_xdp_disable_pool(struct tsnep_adapter *adapter, u16 queue_id)\ndrivers/net/ethernet/engleder/tsnep_xdp.c-59-{\ndrivers/net/ethernet/engleder/tsnep_xdp.c:60:\tstruct xsk_buff_pool *pool;\ndrivers/net/ethernet/engleder/tsnep_xdp.c-61-\tstruct tsnep_queue *queue;\n--\ndrivers/net/ethernet/engleder/tsnep_xdp.c=80=int tsnep_xdp_setup_pool(struct tsnep_adapter *adapter,\ndrivers/net/ethernet/engleder/tsnep_xdp.c:81:\t\t\t struct xsk_buff_pool *pool, u16 queue_id)\ndrivers/net/ethernet/engleder/tsnep_xdp.c-82-{\n--\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h=486=struct dpaa2_eth_channel {\n--\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h-506-\tint xsk_tx_pkts_sent;\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h:507:\tstruct xsk_buff_pool *xsk_pool;\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h-508-\tstruct dpaa2_eth_bp *bp;\n--\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h=846=int dpaa2_xsk_wakeup(struct net_device *dev, u32 qid, u32 flags);\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h:847:int dpaa2_xsk_setup_pool(struct net_device *dev, struct xsk_buff_pool *pool, u16 qid);\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h-848-\n--\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-xsk.c=173=static int dpaa2_xsk_disable_pool(struct net_device *dev, u16 qid)\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-xsk.c-174-{\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-xsk.c:175:\tstruct xsk_buff_pool *pool = xsk_get_pool_from_qid(dev, qid);\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-xsk.c-176-\tstruct dpaa2_eth_priv *priv = netdev_priv(dev);\n--\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-xsk.c=220=static int dpaa2_xsk_enable_pool(struct net_device *dev,\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-xsk.c:221:\t\t\t\t struct xsk_buff_pool *pool,\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-xsk.c-222-\t\t\t\t u16 qid)\n--\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-xsk.c-302-\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-xsk.c:303:int dpaa2_xsk_setup_pool(struct net_device *dev, struct xsk_buff_pool *pool, u16 qid)\ndrivers/net/ethernet/freescale/dpaa2/dpaa2-xsk.c-304-{\n--\ndrivers/net/ethernet/freescale/fec.h=541=struct fec_enet_priv_tx_q {\n--\ndrivers/net/ethernet/freescale/fec.h-544-\tstruct fec_tx_buffer tx_buf[TX_RING_SIZE];\ndrivers/net/ethernet/freescale/fec.h:545:\tstruct xsk_buff_pool *xsk_pool;\ndrivers/net/ethernet/freescale/fec.h-546-\n--\ndrivers/net/ethernet/freescale/fec.h=561=struct fec_enet_priv_rx_q {\n--\ndrivers/net/ethernet/freescale/fec.h-563-\tunion fec_rx_buffer rx_buf[RX_RING_SIZE];\ndrivers/net/ethernet/freescale/fec.h:564:\tstruct xsk_buff_pool *xsk_pool;\ndrivers/net/ethernet/freescale/fec.h-565-\n--\ndrivers/net/ethernet/freescale/fec_main.c=1482=static bool fec_enet_xsk_xmit(struct fec_enet_private *fep,\ndrivers/net/ethernet/freescale/fec_main.c:1483:\t\t\t struct xsk_buff_pool *pool,\ndrivers/net/ethernet/freescale/fec_main.c-1484-\t\t\t u32 queue)\n--\ndrivers/net/ethernet/freescale/fec_main.c=1565=static int fec_enet_tx_queue(struct fec_enet_private *fep,\n--\ndrivers/net/ethernet/freescale/fec_main.c-1719-\tif (txq-\u003exsk_pool) {\ndrivers/net/ethernet/freescale/fec_main.c:1720:\t\tstruct xsk_buff_pool *pool = txq-\u003exsk_pool;\ndrivers/net/ethernet/freescale/fec_main.c-1721-\n--\ndrivers/net/ethernet/freescale/fec_main.c=4420=fec_alloc_new_rxq_xsk(struct fec_enet_private *fep, int queue,\ndrivers/net/ethernet/freescale/fec_main.c:4421:\t\t struct xsk_buff_pool *pool)\ndrivers/net/ethernet/freescale/fec_main.c-4422-{\n--\ndrivers/net/ethernet/freescale/fec_main.c=4522=static int fec_xsk_restart_napi(struct fec_enet_private *fep,\ndrivers/net/ethernet/freescale/fec_main.c:4523:\t\t\t\tstruct xsk_buff_pool *pool,\ndrivers/net/ethernet/freescale/fec_main.c-4524-\t\t\t\tu16 queue)\n--\ndrivers/net/ethernet/freescale/fec_main.c=4561=static int fec_enable_xsk_pool(struct fec_enet_private *fep,\ndrivers/net/ethernet/freescale/fec_main.c:4562:\t\t\t struct xsk_buff_pool *pool,\ndrivers/net/ethernet/freescale/fec_main.c-4563-\t\t\t u16 queue)\n--\ndrivers/net/ethernet/freescale/fec_main.c=4592=static int fec_disable_xsk_pool(struct fec_enet_private *fep,\n--\ndrivers/net/ethernet/freescale/fec_main.c-4595-\tstruct fec_enet_priv_tx_q *txq = fep-\u003etx_queue[queue];\ndrivers/net/ethernet/freescale/fec_main.c:4596:\tstruct xsk_buff_pool *old_pool = txq-\u003exsk_pool;\ndrivers/net/ethernet/freescale/fec_main.c-4597-\tint err;\n--\ndrivers/net/ethernet/freescale/fec_main.c=4618=static int fec_setup_xsk_pool(struct fec_enet_private *fep,\ndrivers/net/ethernet/freescale/fec_main.c:4619:\t\t\t struct xsk_buff_pool *pool,\ndrivers/net/ethernet/freescale/fec_main.c-4620-\t\t\t u16 queue)\n--\ndrivers/net/ethernet/google/gve/gve.h=242=struct gve_rx_ring {\n--\ndrivers/net/ethernet/google/gve/gve.h-343-\tstruct xdp_rxq_info xdp_rxq;\ndrivers/net/ethernet/google/gve/gve.h:344:\tstruct xsk_buff_pool *xsk_pool;\ndrivers/net/ethernet/google/gve/gve.h-345-\tstruct page_frag_cache page_cache; /* Page cache to allocate XDP frames */\n--\ndrivers/net/ethernet/google/gve/gve.h=473=struct gve_tx_ring {\n--\ndrivers/net/ethernet/google/gve/gve.h-659-\tstruct u64_stats_sync statss; /* sync stats for 32bit archs */\ndrivers/net/ethernet/google/gve/gve.h:660:\tstruct xsk_buff_pool *xsk_pool;\ndrivers/net/ethernet/google/gve/gve.h-661-\tu64 xdp_xsk_sent;\n--\ndrivers/net/ethernet/google/gve/gve_main.c=1227=static int gve_reg_xsk_pool(struct gve_priv *priv, struct net_device *dev,\ndrivers/net/ethernet/google/gve/gve_main.c:1228:\t\t\t struct xsk_buff_pool *pool, u16 qid)\ndrivers/net/ethernet/google/gve/gve_main.c-1229-{\n--\ndrivers/net/ethernet/google/gve/gve_main.c=1250=static void gve_unreg_xdp_info(struct gve_priv *priv)\n--\ndrivers/net/ethernet/google/gve/gve_main.c-1266-\ndrivers/net/ethernet/google/gve/gve_main.c:1267:static struct xsk_buff_pool *gve_get_xsk_pool(struct gve_priv *priv, int qid)\ndrivers/net/ethernet/google/gve/gve_main.c-1268-{\n--\ndrivers/net/ethernet/google/gve/gve_main.c=1275=static int gve_reg_xdp_info(struct gve_priv *priv, struct net_device *dev)\n--\ndrivers/net/ethernet/google/gve/gve_main.c-1285-\tfor (i = 0; i \u003c priv-\u003erx_cfg.num_queues; i++) {\ndrivers/net/ethernet/google/gve/gve_main.c:1286:\t\tstruct xsk_buff_pool *xsk_pool;\ndrivers/net/ethernet/google/gve/gve_main.c-1287-\n--\ndrivers/net/ethernet/google/gve/gve_main.c=1629=static int gve_xsk_pool_enable(struct net_device *dev,\ndrivers/net/ethernet/google/gve/gve_main.c:1630:\t\t\t struct xsk_buff_pool *pool,\ndrivers/net/ethernet/google/gve/gve_main.c-1631-\t\t\t u16 qid)\n--\ndrivers/net/ethernet/google/gve/gve_main.c=1679=static int gve_xsk_pool_disable(struct net_device *dev,\n--\ndrivers/net/ethernet/google/gve/gve_main.c-1684-\tstruct napi_struct *napi_tx;\ndrivers/net/ethernet/google/gve/gve_main.c:1685:\tstruct xsk_buff_pool *pool;\ndrivers/net/ethernet/google/gve/gve_main.c-1686-\tint tx_qid;\n--\ndrivers/net/ethernet/google/gve/gve_tx_dqo.c=1084=static bool gve_xsk_tx_dqo(struct gve_priv *priv, struct gve_tx_ring *tx,\n--\ndrivers/net/ethernet/google/gve/gve_tx_dqo.c-1086-{\ndrivers/net/ethernet/google/gve/gve_tx_dqo.c:1087:\tstruct xsk_buff_pool *pool = tx-\u003exsk_pool;\ndrivers/net/ethernet/google/gve/gve_tx_dqo.c-1088-\tstruct xdp_desc desc;\n--\ndrivers/net/ethernet/intel/i40e/i40e_main.c=3402=static void i40e_config_xps_tx_ring(struct i40e_ring *ring)\n--\ndrivers/net/ethernet/intel/i40e/i40e_main.c-3423- **/\ndrivers/net/ethernet/intel/i40e/i40e_main.c:3424:static struct xsk_buff_pool *i40e_xsk_pool(struct i40e_ring *ring)\ndrivers/net/ethernet/intel/i40e/i40e_main.c-3425-{\n--\ndrivers/net/ethernet/intel/i40e/i40e_txrx.h=327=struct i40e_ring {\n--\ndrivers/net/ethernet/intel/i40e/i40e_txrx.h-401-\tstruct xdp_rxq_info xdp_rxq;\ndrivers/net/ethernet/intel/i40e/i40e_txrx.h:402:\tstruct xsk_buff_pool *xsk_pool;\ndrivers/net/ethernet/intel/i40e/i40e_txrx.h-403-} ____cacheline_internodealigned_in_smp;\n--\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c=82=static int i40e_xsk_pool_enable(struct i40e_vsi *vsi,\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c:83:\t\t\t\tstruct xsk_buff_pool *pool,\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c-84-\t\t\t\tu16 qid)\n--\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c=138=static int i40e_xsk_pool_disable(struct i40e_vsi *vsi, u16 qid)\n--\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c-140-\tstruct net_device *netdev = vsi-\u003enetdev;\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c:141:\tstruct xsk_buff_pool *pool;\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c-142-\tbool if_running;\n--\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c-182- **/\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c:183:int i40e_xsk_pool_setup(struct i40e_vsi *vsi, struct xsk_buff_pool *pool,\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c-184-\t\t\tu16 qid)\n--\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c=630=bool i40e_clean_xdp_tx_irq(struct i40e_vsi *vsi, struct i40e_ring *tx_ring)\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c-631-{\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c:632:\tstruct xsk_buff_pool *bp = tx_ring-\u003exsk_pool;\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c-633-\tu32 i, completed_frames, xsk_frames = 0;\n--\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c=746=void i40e_xsk_clean_tx_ring(struct i40e_ring *tx_ring)\n--\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c-748-\tu16 ntc = tx_ring-\u003enext_to_clean, ntu = tx_ring-\u003enext_to_use;\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c:749:\tstruct xsk_buff_pool *bp = tx_ring-\u003exsk_pool;\ndrivers/net/ethernet/intel/i40e/i40e_xsk.c-750-\tstruct i40e_tx_buffer *tx_bi;\n--\ndrivers/net/ethernet/intel/i40e/i40e_xsk.h=19=struct net_device;\ndrivers/net/ethernet/intel/i40e/i40e_xsk.h:20:struct xsk_buff_pool;\ndrivers/net/ethernet/intel/i40e/i40e_xsk.h-21-\n--\ndrivers/net/ethernet/intel/i40e/i40e_xsk.h=23=int i40e_queue_pair_enable(struct i40e_vsi *vsi, int queue_pair);\ndrivers/net/ethernet/intel/i40e/i40e_xsk.h:24:int i40e_xsk_pool_setup(struct i40e_vsi *vsi, struct xsk_buff_pool *pool,\ndrivers/net/ethernet/intel/i40e/i40e_xsk.h-25-\t\t\tu16 qid);\n--\ndrivers/net/ethernet/intel/ice/ice.h=782=static inline bool ice_is_txtime_cfg(const struct ice_tx_ring *ring)\n--\ndrivers/net/ethernet/intel/ice/ice.h-791- *\ndrivers/net/ethernet/intel/ice/ice.h:792: * Return: A pointer to xsk_buff_pool structure if there is a buffer pool\ndrivers/net/ethernet/intel/ice/ice.h-793- * attached and configured as zero-copy, NULL otherwise.\ndrivers/net/ethernet/intel/ice/ice.h-794- */\ndrivers/net/ethernet/intel/ice/ice.h:795:static inline struct xsk_buff_pool *ice_get_xp_from_qid(struct ice_vsi *vsi,\ndrivers/net/ethernet/intel/ice/ice.h-796-\t\t\t\t\t\t\tu16 qid)\ndrivers/net/ethernet/intel/ice/ice.h-797-{\ndrivers/net/ethernet/intel/ice/ice.h:798:\tstruct xsk_buff_pool *pool = xsk_get_pool_from_qid(vsi-\u003enetdev, qid);\ndrivers/net/ethernet/intel/ice/ice.h-799-\n--\ndrivers/net/ethernet/intel/ice/ice_txrx.c=1267=int ice_napi_poll(struct napi_struct *napi, int budget)\n--\ndrivers/net/ethernet/intel/ice/ice_txrx.c-1280-\tice_for_each_tx_ring(tx_ring, q_vector-\u003etx) {\ndrivers/net/ethernet/intel/ice/ice_txrx.c:1281:\t\tstruct xsk_buff_pool *xsk_pool = READ_ONCE(tx_ring-\u003exsk_pool);\ndrivers/net/ethernet/intel/ice/ice_txrx.c-1282-\t\tbool wd;\n--\ndrivers/net/ethernet/intel/ice/ice_txrx.c-1310-\tice_for_each_rx_ring(rx_ring, q_vector-\u003erx) {\ndrivers/net/ethernet/intel/ice/ice_txrx.c:1311:\t\tstruct xsk_buff_pool *xsk_pool = READ_ONCE(rx_ring-\u003exsk_pool);\ndrivers/net/ethernet/intel/ice/ice_txrx.c-1312-\t\tint cleaned;\n--\ndrivers/net/ethernet/intel/ice/ice_txrx.h=277=struct ice_rx_ring {\n--\ndrivers/net/ethernet/intel/ice/ice_txrx.h-304-\tstruct ice_tx_ring *xdp_ring;\ndrivers/net/ethernet/intel/ice/ice_txrx.h:305:\tstruct xsk_buff_pool *xsk_pool;\ndrivers/net/ethernet/intel/ice/ice_txrx.h-306-\n--\ndrivers/net/ethernet/intel/ice/ice_txrx.h=349=struct ice_tx_ring {\n--\ndrivers/net/ethernet/intel/ice/ice_txrx.h-364-\ndrivers/net/ethernet/intel/ice/ice_txrx.h:365:\tstruct xsk_buff_pool *xsk_pool;\ndrivers/net/ethernet/intel/ice/ice_txrx.h-366-\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.c=124=static int ice_xsk_pool_disable(struct ice_vsi *vsi, u16 qid)\ndrivers/net/ethernet/intel/ice/ice_xsk.c-125-{\ndrivers/net/ethernet/intel/ice/ice_xsk.c:126:\tstruct xsk_buff_pool *pool = xsk_get_pool_from_qid(vsi-\u003enetdev, qid);\ndrivers/net/ethernet/intel/ice/ice_xsk.c-127-\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.c=144=static int\ndrivers/net/ethernet/intel/ice/ice_xsk.c:145:ice_xsk_pool_enable(struct ice_vsi *vsi, struct xsk_buff_pool *pool, u16 qid)\ndrivers/net/ethernet/intel/ice/ice_xsk.c-146-{\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.c=174=ice_realloc_rx_xdp_bufs(struct ice_rx_ring *rx_ring, bool pool_present)\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.c-196- */\ndrivers/net/ethernet/intel/ice/ice_xsk.c:197:int ice_xsk_pool_setup(struct ice_vsi *vsi, struct xsk_buff_pool *pool, u16 qid)\ndrivers/net/ethernet/intel/ice/ice_xsk.c-198-{\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.c-259- */\ndrivers/net/ethernet/intel/ice/ice_xsk.c:260:static u16 ice_fill_rx_descs(struct xsk_buff_pool *pool, struct xdp_buff **xdp,\ndrivers/net/ethernet/intel/ice/ice_xsk.c-261-\t\t\t union ice_32b_rx_flex_desc *rx_desc, u16 count)\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.c=292=static bool __ice_alloc_rx_bufs_zc(struct ice_rx_ring *rx_ring,\ndrivers/net/ethernet/intel/ice/ice_xsk.c:293:\t\t\t\t struct xsk_buff_pool *xsk_pool, u16 count)\ndrivers/net/ethernet/intel/ice/ice_xsk.c-294-{\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.c=342=bool ice_alloc_rx_bufs_zc(struct ice_rx_ring *rx_ring,\ndrivers/net/ethernet/intel/ice/ice_xsk.c:343:\t\t\t struct xsk_buff_pool *xsk_pool, u16 count)\ndrivers/net/ethernet/intel/ice/ice_xsk.c-344-{\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.c=362=static u32 ice_clean_xdp_irq_zc(struct ice_tx_ring *xdp_ring,\ndrivers/net/ethernet/intel/ice/ice_xsk.c:363:\t\t\t\tstruct xsk_buff_pool *xsk_pool)\ndrivers/net/ethernet/intel/ice/ice_xsk.c-364-{\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.c=432=static int ice_xmit_xdp_tx_zc(struct xdp_buff *xdp,\ndrivers/net/ethernet/intel/ice/ice_xsk.c-433-\t\t\t struct ice_tx_ring *xdp_ring,\ndrivers/net/ethernet/intel/ice/ice_xsk.c:434:\t\t\t struct xsk_buff_pool *xsk_pool)\ndrivers/net/ethernet/intel/ice/ice_xsk.c-435-{\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.c-473-\t\ttx_desc-\u003ecmd_type_offset_bsz = ice_build_ctob(0, 0, size, 0);\ndrivers/net/ethernet/intel/ice/ice_xsk.c:474:\t\t/* account for each xdp_buff from xsk_buff_pool */\ndrivers/net/ethernet/intel/ice/ice_xsk.c-475-\t\txdp_ring-\u003exdp_tx_active++;\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.c=515=ice_run_xdp_zc(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,\ndrivers/net/ethernet/intel/ice/ice_xsk.c-516-\t struct bpf_prog *xdp_prog, struct ice_tx_ring *xdp_ring,\ndrivers/net/ethernet/intel/ice/ice_xsk.c:517:\t struct xsk_buff_pool *xsk_pool)\ndrivers/net/ethernet/intel/ice/ice_xsk.c-518-{\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.c=567=int ice_clean_rx_irq_zc(struct ice_rx_ring *rx_ring,\ndrivers/net/ethernet/intel/ice/ice_xsk.c:568:\t\t\tstruct xsk_buff_pool *xsk_pool,\ndrivers/net/ethernet/intel/ice/ice_xsk.c-569-\t\t\tint budget)\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.c=709=static void ice_xmit_pkt(struct ice_tx_ring *xdp_ring,\ndrivers/net/ethernet/intel/ice/ice_xsk.c:710:\t\t\t struct xsk_buff_pool *xsk_pool, struct xdp_desc *desc,\ndrivers/net/ethernet/intel/ice/ice_xsk.c-711-\t\t\t unsigned int *total_bytes)\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.c=734=static void ice_xmit_pkt_batch(struct ice_tx_ring *xdp_ring,\ndrivers/net/ethernet/intel/ice/ice_xsk.c:735:\t\t\t struct xsk_buff_pool *xsk_pool,\ndrivers/net/ethernet/intel/ice/ice_xsk.c-736-\t\t\t struct xdp_desc *descs,\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.c=769=static void ice_fill_tx_hw_ring(struct ice_tx_ring *xdp_ring,\ndrivers/net/ethernet/intel/ice/ice_xsk.c:770:\t\t\t\tstruct xsk_buff_pool *xsk_pool,\ndrivers/net/ethernet/intel/ice/ice_xsk.c-771-\t\t\t\tstruct xdp_desc *descs, u32 nb_pkts,\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.c-790- */\ndrivers/net/ethernet/intel/ice/ice_xsk.c:791:bool ice_xmit_zc(struct ice_tx_ring *xdp_ring, struct xsk_buff_pool *xsk_pool)\ndrivers/net/ethernet/intel/ice/ice_xsk.c-792-{\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.h=10=struct ice_vsi;\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.h-12-#ifdef CONFIG_XDP_SOCKETS\ndrivers/net/ethernet/intel/ice/ice_xsk.h:13:int ice_xsk_pool_setup(struct ice_vsi *vsi, struct xsk_buff_pool *pool,\ndrivers/net/ethernet/intel/ice/ice_xsk.h-14-\t\t u16 qid);\ndrivers/net/ethernet/intel/ice/ice_xsk.h=15=int ice_clean_rx_irq_zc(struct ice_rx_ring *rx_ring,\ndrivers/net/ethernet/intel/ice/ice_xsk.h:16:\t\t\tstruct xsk_buff_pool *xsk_pool,\ndrivers/net/ethernet/intel/ice/ice_xsk.h-17-\t\t\tint budget);\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.h=19=bool ice_alloc_rx_bufs_zc(struct ice_rx_ring *rx_ring,\ndrivers/net/ethernet/intel/ice/ice_xsk.h:20:\t\t\t struct xsk_buff_pool *xsk_pool, u16 count);\ndrivers/net/ethernet/intel/ice/ice_xsk.h-21-bool ice_xsk_any_rx_ring_ena(struct ice_vsi *vsi);\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.h=23=void ice_xsk_clean_xdp_ring(struct ice_tx_ring *xdp_ring);\ndrivers/net/ethernet/intel/ice/ice_xsk.h:24:bool ice_xmit_zc(struct ice_tx_ring *xdp_ring, struct xsk_buff_pool *xsk_pool);\ndrivers/net/ethernet/intel/ice/ice_xsk.h-25-int ice_realloc_rx_xdp_bufs(struct ice_rx_ring *rx_ring, bool pool_present);\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.h=34=static inline bool ice_xmit_zc(struct ice_tx_ring __always_unused *xdp_ring,\ndrivers/net/ethernet/intel/ice/ice_xsk.h:35:\t\t\t struct xsk_buff_pool __always_unused *xsk_pool)\ndrivers/net/ethernet/intel/ice/ice_xsk.h-36-{\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.h=41=ice_xsk_pool_setup(struct ice_vsi __always_unused *vsi,\ndrivers/net/ethernet/intel/ice/ice_xsk.h:42:\t\t struct xsk_buff_pool __always_unused *pool,\ndrivers/net/ethernet/intel/ice/ice_xsk.h-43-\t\t u16 __always_unused qid)\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.h=49=ice_clean_rx_irq_zc(struct ice_rx_ring __always_unused *rx_ring,\ndrivers/net/ethernet/intel/ice/ice_xsk.h:50:\t\t struct xsk_buff_pool __always_unused *xsk_pool,\ndrivers/net/ethernet/intel/ice/ice_xsk.h-51-\t\t int __always_unused budget)\n--\ndrivers/net/ethernet/intel/ice/ice_xsk.h=57=ice_alloc_rx_bufs_zc(struct ice_rx_ring __always_unused *rx_ring,\ndrivers/net/ethernet/intel/ice/ice_xsk.h:58:\t\t struct xsk_buff_pool __always_unused *xsk_pool,\ndrivers/net/ethernet/intel/ice/ice_xsk.h-59-\t\t u16 __always_unused count)\n--\ndrivers/net/ethernet/intel/idpf/idpf_txrx.h=517=struct idpf_rx_queue {\n--\ndrivers/net/ethernet/intel/idpf/idpf_txrx.h-563-\t\t\tstruct libeth_xdp_buff *xsk;\ndrivers/net/ethernet/intel/idpf/idpf_txrx.h:564:\t\t\tstruct xsk_buff_pool *pool;\ndrivers/net/ethernet/intel/idpf/idpf_txrx.h-565-\t\t};\n--\ndrivers/net/ethernet/intel/idpf/idpf_txrx.h=643=struct idpf_tx_queue {\n--\ndrivers/net/ethernet/intel/idpf/idpf_txrx.h-659-\t\tstruct device *dev;\ndrivers/net/ethernet/intel/idpf/idpf_txrx.h:660:\t\tstruct xsk_buff_pool *pool;\ndrivers/net/ethernet/intel/idpf/idpf_txrx.h-661-\t};\n--\ndrivers/net/ethernet/intel/idpf/idpf_txrx.h=720=libeth_cacheline_set_assert(struct idpf_tx_queue, 64,\n--\ndrivers/net/ethernet/intel/idpf/idpf_txrx.h-733- * @xsk_buf: \u0026xdp_buff for XSk Rx buffers\ndrivers/net/ethernet/intel/idpf/idpf_txrx.h:734: * @pool: \u0026xsk_buff_pool on XSk queues\ndrivers/net/ethernet/intel/idpf/idpf_txrx.h-735- * @hdr_buf: \u0026libeth_fqe for header buffers\n--\ndrivers/net/ethernet/intel/idpf/idpf_txrx.h=755=struct idpf_buf_queue {\n--\ndrivers/net/ethernet/intel/idpf/idpf_txrx.h-764-\t\t\tstruct libeth_xdp_buff **xsk_buf;\ndrivers/net/ethernet/intel/idpf/idpf_txrx.h:765:\t\t\tstruct xsk_buff_pool *pool;\ndrivers/net/ethernet/intel/idpf/idpf_txrx.h-766-\t\t};\n--\ndrivers/net/ethernet/intel/idpf/xsk.c=12=static void idpf_xsk_setup_rxq(const struct idpf_vport *vport,\n--\ndrivers/net/ethernet/intel/idpf/xsk.c-14-{\ndrivers/net/ethernet/intel/idpf/xsk.c:15:\tstruct xsk_buff_pool *pool;\ndrivers/net/ethernet/intel/idpf/xsk.c-16-\n--\ndrivers/net/ethernet/intel/idpf/xsk.c=26=static void idpf_xsk_setup_bufq(const struct idpf_vport *vport,\n--\ndrivers/net/ethernet/intel/idpf/xsk.c-29-\tconst struct idpf_q_vec_rsrc *rsrc = \u0026vport-\u003edflt_qv_rsrc;\ndrivers/net/ethernet/intel/idpf/xsk.c:30:\tstruct xsk_buff_pool *pool;\ndrivers/net/ethernet/intel/idpf/xsk.c-31-\tu32 qid = U32_MAX;\n--\ndrivers/net/ethernet/intel/idpf/xsk.c=54=static void idpf_xsk_setup_txq(const struct idpf_vport *vport,\n--\ndrivers/net/ethernet/intel/idpf/xsk.c-56-{\ndrivers/net/ethernet/intel/idpf/xsk.c:57:\tstruct xsk_buff_pool *pool;\ndrivers/net/ethernet/intel/idpf/xsk.c-58-\tu32 qid;\n--\ndrivers/net/ethernet/intel/idpf/xsk.c=79=static void idpf_xsk_setup_complq(const struct idpf_vport *vport,\n--\ndrivers/net/ethernet/intel/idpf/xsk.c-81-{\ndrivers/net/ethernet/intel/idpf/xsk.c:82:\tconst struct xsk_buff_pool *pool;\ndrivers/net/ethernet/intel/idpf/xsk.c-83-\tu32 qid;\n--\ndrivers/net/ethernet/intel/idpf/xsk.c=554=int idpf_xsk_pool_setup(struct idpf_vport *vport, struct netdev_bpf *bpf)\ndrivers/net/ethernet/intel/idpf/xsk.c-555-{\ndrivers/net/ethernet/intel/idpf/xsk.c:556:\tstruct xsk_buff_pool *pool = bpf-\u003exsk.pool;\ndrivers/net/ethernet/intel/idpf/xsk.c-557-\tu32 qid = bpf-\u003exsk.queue_id;\n--\ndrivers/net/ethernet/intel/igb/igb.h=319=struct igb_ring {\n--\ndrivers/net/ethernet/intel/igb/igb.h-364-\tstruct xdp_rxq_info xdp_rxq;\ndrivers/net/ethernet/intel/igb/igb.h:365:\tstruct xsk_buff_pool *xsk_pool;\ndrivers/net/ethernet/intel/igb/igb.h-366-} ____cacheline_internodealigned_in_smp;\n--\ndrivers/net/ethernet/intel/igb/igb.h=856=int igb_del_mac_steering_filter(struct igb_adapter *adapter,\n--\ndrivers/net/ethernet/intel/igb/igb.h-858-\ndrivers/net/ethernet/intel/igb/igb.h:859:struct xsk_buff_pool *igb_xsk_pool(struct igb_adapter *adapter,\ndrivers/net/ethernet/intel/igb/igb.h-860-\t\t\t\t struct igb_ring *ring);\ndrivers/net/ethernet/intel/igb/igb.h=861=int igb_xsk_pool_setup(struct igb_adapter *adapter,\ndrivers/net/ethernet/intel/igb/igb.h:862:\t\t struct xsk_buff_pool *pool,\ndrivers/net/ethernet/intel/igb/igb.h-863-\t\t u16 qid);\ndrivers/net/ethernet/intel/igb/igb.h=864=bool igb_alloc_rx_buffers_zc(struct igb_ring *rx_ring,\ndrivers/net/ethernet/intel/igb/igb.h:865:\t\t\t struct xsk_buff_pool *xsk_pool, u16 count);\ndrivers/net/ethernet/intel/igb/igb.h-866-void igb_clean_rx_ring_zc(struct igb_ring *rx_ring);\ndrivers/net/ethernet/intel/igb/igb.h=867=int igb_clean_rx_irq_zc(struct igb_q_vector *q_vector,\ndrivers/net/ethernet/intel/igb/igb.h:868:\t\t\tstruct xsk_buff_pool *xsk_pool, const int budget);\ndrivers/net/ethernet/intel/igb/igb.h:869:bool igb_xmit_zc(struct igb_ring *tx_ring, struct xsk_buff_pool *xsk_pool);\ndrivers/net/ethernet/intel/igb/igb.h-870-int igb_xsk_wakeup(struct net_device *dev, u32 qid, u32 flags);\n--\ndrivers/net/ethernet/intel/igb/igb_main.c=8278=static int igb_poll(struct napi_struct *napi, int budget)\n--\ndrivers/net/ethernet/intel/igb/igb_main.c-8282-\t\t\t\t\t\t napi);\ndrivers/net/ethernet/intel/igb/igb_main.c:8283:\tstruct xsk_buff_pool *xsk_pool;\ndrivers/net/ethernet/intel/igb/igb_main.c-8284-\tbool clean_complete = true;\n--\ndrivers/net/ethernet/intel/igb/igb_main.c=8327=static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)\n--\ndrivers/net/ethernet/intel/igb/igb_main.c-8335-\tstruct igb_tx_buffer *tx_buffer;\ndrivers/net/ethernet/intel/igb/igb_main.c:8336:\tstruct xsk_buff_pool *xsk_pool;\ndrivers/net/ethernet/intel/igb/igb_main.c-8337-\tint cpu = smp_processor_id();\n--\ndrivers/net/ethernet/intel/igb/igb_xsk.c=57=static void igb_txrx_ring_enable(struct igb_adapter *adapter, u16 qid)\n--\ndrivers/net/ethernet/intel/igb/igb_xsk.c-82-\ndrivers/net/ethernet/intel/igb/igb_xsk.c:83:struct xsk_buff_pool *igb_xsk_pool(struct igb_adapter *adapter,\ndrivers/net/ethernet/intel/igb/igb_xsk.c-84-\t\t\t\t struct igb_ring *ring)\n--\ndrivers/net/ethernet/intel/igb/igb_xsk.c-86-\tint qid = ring-\u003equeue_index;\ndrivers/net/ethernet/intel/igb/igb_xsk.c:87:\tstruct xsk_buff_pool *pool;\ndrivers/net/ethernet/intel/igb/igb_xsk.c-88-\n--\ndrivers/net/ethernet/intel/igb/igb_xsk.c=97=static int igb_xsk_pool_enable(struct igb_adapter *adapter,\ndrivers/net/ethernet/intel/igb/igb_xsk.c:98:\t\t\t struct xsk_buff_pool *pool,\ndrivers/net/ethernet/intel/igb/igb_xsk.c-99-\t\t\t u16 qid)\n--\ndrivers/net/ethernet/intel/igb/igb_xsk.c=139=static int igb_xsk_pool_disable(struct igb_adapter *adapter, u16 qid)\ndrivers/net/ethernet/intel/igb/igb_xsk.c-140-{\ndrivers/net/ethernet/intel/igb/igb_xsk.c:141:\tstruct xsk_buff_pool *pool;\ndrivers/net/ethernet/intel/igb/igb_xsk.c-142-\tstruct igb_ring *rx_ring;\n--\ndrivers/net/ethernet/intel/igb/igb_xsk.c=168=int igb_xsk_pool_setup(struct igb_adapter *adapter,\ndrivers/net/ethernet/intel/igb/igb_xsk.c:169:\t\t struct xsk_buff_pool *pool,\ndrivers/net/ethernet/intel/igb/igb_xsk.c-170-\t\t u16 qid)\n--\ndrivers/net/ethernet/intel/igb/igb_xsk.c-175-\ndrivers/net/ethernet/intel/igb/igb_xsk.c:176:static u16 igb_fill_rx_descs(struct xsk_buff_pool *pool, struct xdp_buff **xdp,\ndrivers/net/ethernet/intel/igb/igb_xsk.c-177-\t\t\t union e1000_adv_rx_desc *rx_desc, u16 count)\n--\ndrivers/net/ethernet/intel/igb/igb_xsk.c=200=bool igb_alloc_rx_buffers_zc(struct igb_ring *rx_ring,\ndrivers/net/ethernet/intel/igb/igb_xsk.c:201:\t\t\t struct xsk_buff_pool *xsk_pool, u16 count)\ndrivers/net/ethernet/intel/igb/igb_xsk.c-202-{\n--\ndrivers/net/ethernet/intel/igb/igb_xsk.c=294=static int igb_run_xdp_zc(struct igb_adapter *adapter, struct igb_ring *rx_ring,\ndrivers/net/ethernet/intel/igb/igb_xsk.c:295:\t\t\t struct xdp_buff *xdp, struct xsk_buff_pool *xsk_pool,\ndrivers/net/ethernet/intel/igb/igb_xsk.c-296-\t\t\t struct bpf_prog *xdp_prog)\n--\ndrivers/net/ethernet/intel/igb/igb_xsk.c=341=int igb_clean_rx_irq_zc(struct igb_q_vector *q_vector,\ndrivers/net/ethernet/intel/igb/igb_xsk.c:342:\t\t\tstruct xsk_buff_pool *xsk_pool, const int budget)\ndrivers/net/ethernet/intel/igb/igb_xsk.c-343-{\n--\ndrivers/net/ethernet/intel/igb/igb_xsk.c-464-\ndrivers/net/ethernet/intel/igb/igb_xsk.c:465:bool igb_xmit_zc(struct igb_ring *tx_ring, struct xsk_buff_pool *xsk_pool)\ndrivers/net/ethernet/intel/igb/igb_xsk.c-466-{\n--\ndrivers/net/ethernet/intel/igc/igc.h=147=struct igc_ring {\n--\ndrivers/net/ethernet/intel/igc/igc.h-203-\tstruct xdp_rxq_info xdp_rxq;\ndrivers/net/ethernet/intel/igc/igc.h:204:\tstruct xsk_buff_pool *xsk_pool;\ndrivers/net/ethernet/intel/igc/igc.h-205-} ____cacheline_internodealigned_in_smp;\n--\ndrivers/net/ethernet/intel/igc/igc_main.c=597=static int igc_setup_all_rx_resources(struct igc_adapter *adapter)\n--\ndrivers/net/ethernet/intel/igc/igc_main.c-614-\ndrivers/net/ethernet/intel/igc/igc_main.c:615:static struct xsk_buff_pool *igc_get_xsk_pool(struct igc_adapter *adapter,\ndrivers/net/ethernet/intel/igc/igc_main.c-616-\t\t\t\t\t struct igc_ring *ring)\n--\ndrivers/net/ethernet/intel/igc/igc_main.c=3037=static void igc_xdp_xmit_zc(struct igc_ring *ring)\ndrivers/net/ethernet/intel/igc/igc_main.c-3038-{\ndrivers/net/ethernet/intel/igc/igc_main.c:3039:\tstruct xsk_buff_pool *pool = ring-\u003exsk_pool;\ndrivers/net/ethernet/intel/igc/igc_main.c-3040-\tstruct netdev_queue *nq = txring_txq(ring);\n--\ndrivers/net/ethernet/intel/igc/igc_ptp.c=749=static void igc_ptp_tx_reg_to_stamp(struct igc_adapter *adapter,\n--\ndrivers/net/ethernet/intel/igc/igc_ptp.c-782-\tif (tstamp-\u003ebuffer_type == IGC_TX_BUFFER_TYPE_XSK) {\ndrivers/net/ethernet/intel/igc/igc_ptp.c:783:\t\tstruct xsk_buff_pool *xsk_pool;\ndrivers/net/ethernet/intel/igc/igc_ptp.c-784-\n--\ndrivers/net/ethernet/intel/igc/igc_xdp.c=56=static int igc_xdp_enable_pool(struct igc_adapter *adapter,\ndrivers/net/ethernet/intel/igc/igc_xdp.c:57:\t\t\t struct xsk_buff_pool *pool, u16 queue_id)\ndrivers/net/ethernet/intel/igc/igc_xdp.c-58-{\n--\ndrivers/net/ethernet/intel/igc/igc_xdp.c=118=static int igc_xdp_disable_pool(struct igc_adapter *adapter, u16 queue_id)\n--\ndrivers/net/ethernet/intel/igc/igc_xdp.c-120-\tstruct igc_ring *rx_ring, *tx_ring;\ndrivers/net/ethernet/intel/igc/igc_xdp.c:121:\tstruct xsk_buff_pool *pool;\ndrivers/net/ethernet/intel/igc/igc_xdp.c-122-\tstruct napi_struct *napi;\n--\ndrivers/net/ethernet/intel/igc/igc_xdp.c-158-\ndrivers/net/ethernet/intel/igc/igc_xdp.c:159:int igc_xdp_setup_pool(struct igc_adapter *adapter, struct xsk_buff_pool *pool,\ndrivers/net/ethernet/intel/igc/igc_xdp.c-160-\t\t u16 queue_id)\n--\ndrivers/net/ethernet/intel/igc/igc_xdp.h=7=int igc_xdp_set_prog(struct igc_adapter *adapter, struct bpf_prog *prog,\ndrivers/net/ethernet/intel/igc/igc_xdp.h-8-\t\t struct netlink_ext_ack *extack);\ndrivers/net/ethernet/intel/igc/igc_xdp.h:9:int igc_xdp_setup_pool(struct igc_adapter *adapter, struct xsk_buff_pool *pool,\ndrivers/net/ethernet/intel/igc/igc_xdp.h-10-\t\t u16 queue_id);\n--\ndrivers/net/ethernet/intel/ixgbe/ixgbe.h=357=struct ixgbe_ring {\n\n"
} |
| 37/2 | 2026/08/13 20:21 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 49137 output: 34 thoughts: 209 Thoughts: **My AF_XDP Driver Landscape** Okay, so I'm thinking about the drivers that currently support AF_XDP zero-copy. Let me see... I've got a mental list starting to form. There's `tsnep` - the Engleder TSN endpoint. Then there's the Freescale DPAA2, that's `dpaa2`. I remember `fec` from Freescale, too. And of course, `gve`, the Google Virtual NIC, it's pretty crucial. The usual suspects from Intel are in the mix: `i40e`, `ice`, `idpf`, `igb`, `igc`, and `ixgbe`. Then, of course, the ever-present Mellanox `mlx5`. And, I need to remember the `stmmac` driver from STMicroelectronics. Wait a second… `veth`? Virtual Ethernet? I could have sworn that I didn't think `veth` supported AF_XDP zero-copy. I could be mistaken, though. Maybe things have changed, or my memory's slipping. I should double-check that. Let's make sure it's correct. I need to take a look at the code. Time to dig into `drivers/net/veth.c` and confirm that it really supports AF_XDP. |
| 38/2 | 2026/08/13 20:21 | tool | grepper |
0mError:no matches Args: {
"Expression": "xsk_buff_pool",
"PathPrefix": "drivers/net/veth.c"
}Results: {
"error": "no matches"
} |
| 39/2 | 2026/08/13 20:21 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 49684 output: 30 thoughts: 64 Thoughts: Here's my take on the thought process: **Investigating veth and XSK Integration** Okay, hold on a second. I was under the impression that the Virtual Ethernet device, `veth`, would leverage the `xsk_buff_pool` for its zero-copy capabilities. But something's niggling at me... is that actually *true*? Let me clarify that mental model. Does `veth` actually *use* `xsk_buff_pool` directly? Or perhaps, could it be a more indirect connection, or possibly, zero-copy is achieved in a different way entirely? Hmmm. Right, time to get my hands dirty. I need to dive into the kernel source code to clarify this, specifically `drivers/net/veth.c`. That should give me the definitive answer and shed some light on how `veth` handles XDP sockets and zero-copy if it *is* using it. Let's see what the code reveals. |
| 40/2 | 2026/08/13 20:21 | tool | grepper |
0mError:no matches Args: {
"Expression": "xsk",
"PathPrefix": "drivers/net/veth.c"
}Results: {
"error": "no matches"
} |
| 41/2 | 2026/08/13 20:21 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 50001 output: 30 thoughts: 38 Thoughts: Okay, here's my interpretation of those thoughts, tailored for an expert audience, presented in the first person: **Investigating the XDP/veth Relationship** Hold on a second... I was under the impression that the virtual Ethernet device, `veth`, had some integration with XDP, perhaps through `xsk` sockets, but now that I'm thinking about it, that doesn't feel right. Let me double-check the source code for the veth driver. Right, it looks like I need to dive into `drivers/net/veth.c` to see how `veth` actually interacts, if at all, with XDP's capabilities. There must be a better way to check the source. |
| 42/2 | 2026/08/13 20:21 | tool | grepper |
0mArgs:{
"Expression": "xdp",
"PathPrefix": "drivers/net/veth.c"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 834 lines.\nUse more precise expression if possible.\n\ndrivers/net/veth.c-21-#include \u003cnet/xfrm.h\u003e\ndrivers/net/veth.c:22:#include \u003cnet/xdp.h\u003e\ndrivers/net/veth.c-23-#include \u003clinux/veth.h\u003e\n--\ndrivers/net/veth.c=43=struct veth_stats {\ndrivers/net/veth.c-44-\tu64\trx_drops;\ndrivers/net/veth.c:45:\t/* xdp */\ndrivers/net/veth.c:46:\tu64\txdp_packets;\ndrivers/net/veth.c:47:\tu64\txdp_bytes;\ndrivers/net/veth.c:48:\tu64\txdp_redirect;\ndrivers/net/veth.c:49:\tu64\txdp_drops;\ndrivers/net/veth.c:50:\tu64\txdp_tx;\ndrivers/net/veth.c:51:\tu64\txdp_tx_err;\ndrivers/net/veth.c:52:\tu64\tpeer_tq_xdp_xmit;\ndrivers/net/veth.c:53:\tu64\tpeer_tq_xdp_xmit_err;\ndrivers/net/veth.c-54-};\n--\ndrivers/net/veth.c=61=struct veth_rq {\ndrivers/net/veth.c:62:\tstruct napi_struct\txdp_napi;\ndrivers/net/veth.c:63:\tstruct napi_struct __rcu *napi; /* points to xdp_napi when the latter is initialized */\ndrivers/net/veth.c-64-\tstruct net_device\t*dev;\ndrivers/net/veth.c:65:\tstruct bpf_prog __rcu\t*xdp_prog;\ndrivers/net/veth.c:66:\tstruct xdp_mem_info\txdp_mem;\ndrivers/net/veth.c-67-\tstruct veth_rq_stats\tstats;\ndrivers/net/veth.c-68-\tbool\t\t\trx_notify_masked;\ndrivers/net/veth.c:69:\tstruct ptr_ring\t\txdp_ring;\ndrivers/net/veth.c:70:\tstruct xdp_rxq_info\txdp_rxq;\ndrivers/net/veth.c-71-\tstruct page_pool\t*page_pool;\n--\ndrivers/net/veth.c=74=struct veth_priv {\n--\ndrivers/net/veth.c-76-\tatomic64_t\t\tdropped;\ndrivers/net/veth.c:77:\tstruct bpf_prog\t\t*_xdp_prog;\ndrivers/net/veth.c-78-\tstruct veth_rq\t\t*rq;\n--\ndrivers/net/veth.c-81-\ndrivers/net/veth.c:82:struct veth_xdp_tx_bq {\ndrivers/net/veth.c:83:\tstruct xdp_frame *q[VETH_XDP_TX_BULK_SIZE];\ndrivers/net/veth.c-84-\tunsigned int count;\n--\ndrivers/net/veth.c=98=static const struct veth_q_stat_desc veth_rq_stats_desc[] = {\ndrivers/net/veth.c:99:\t{ \"xdp_packets\",\tVETH_RQ_STAT(xdp_packets) },\ndrivers/net/veth.c:100:\t{ \"xdp_bytes\",\t\tVETH_RQ_STAT(xdp_bytes) },\ndrivers/net/veth.c-101-\t{ \"drops\",\t\tVETH_RQ_STAT(rx_drops) },\ndrivers/net/veth.c:102:\t{ \"xdp_redirect\",\tVETH_RQ_STAT(xdp_redirect) },\ndrivers/net/veth.c:103:\t{ \"xdp_drops\",\t\tVETH_RQ_STAT(xdp_drops) },\ndrivers/net/veth.c:104:\t{ \"xdp_tx\",\t\tVETH_RQ_STAT(xdp_tx) },\ndrivers/net/veth.c:105:\t{ \"xdp_tx_errors\",\tVETH_RQ_STAT(xdp_tx_err) },\ndrivers/net/veth.c-106-};\n--\ndrivers/net/veth.c=110=static const struct veth_q_stat_desc veth_tq_stats_desc[] = {\ndrivers/net/veth.c:111:\t{ \"xdp_xmit\",\t\tVETH_RQ_STAT(peer_tq_xdp_xmit) },\ndrivers/net/veth.c:112:\t{ \"xdp_xmit_errors\",\tVETH_RQ_STAT(peer_tq_xdp_xmit_err) },\ndrivers/net/veth.c-113-};\n--\ndrivers/net/veth.c=117=static struct {\n--\ndrivers/net/veth.c-122-\ndrivers/net/veth.c:123:struct veth_xdp_buff {\ndrivers/net/veth.c:124:\tstruct xdp_buff xdp;\ndrivers/net/veth.c-125-\tstruct sk_buff *skb;\n--\ndrivers/net/veth.c=264=static const struct ethtool_ops veth_ethtool_ops = {\n--\ndrivers/net/veth.c-277-\ndrivers/net/veth.c:278:static bool veth_is_xdp_frame(void *ptr)\ndrivers/net/veth.c-279-{\n--\ndrivers/net/veth.c-282-\ndrivers/net/veth.c:283:static struct xdp_frame *veth_ptr_to_xdp(void *ptr)\ndrivers/net/veth.c-284-{\n--\ndrivers/net/veth.c-287-\ndrivers/net/veth.c:288:static void *veth_xdp_to_ptr(struct xdp_frame *xdp)\ndrivers/net/veth.c-289-{\ndrivers/net/veth.c:290:\treturn (void *)((unsigned long)xdp | VETH_XDP_FLAG);\ndrivers/net/veth.c-291-}\n--\ndrivers/net/veth.c=293=static void veth_ptr_free(void *ptr)\ndrivers/net/veth.c-294-{\ndrivers/net/veth.c:295:\tif (veth_is_xdp_frame(ptr))\ndrivers/net/veth.c:296:\t\txdp_return_frame(veth_ptr_to_xdp(ptr));\ndrivers/net/veth.c-297-\telse\n--\ndrivers/net/veth.c-300-\ndrivers/net/veth.c:301:static void __veth_xdp_flush(struct veth_rq *rq)\ndrivers/net/veth.c-302-{\n--\ndrivers/net/veth.c-305-\tif (!READ_ONCE(rq-\u003erx_notify_masked) \u0026\u0026\ndrivers/net/veth.c:306:\t napi_schedule_prep(\u0026rq-\u003exdp_napi)) {\ndrivers/net/veth.c-307-\t\tWRITE_ONCE(rq-\u003erx_notify_masked, true);\ndrivers/net/veth.c:308:\t\t__napi_schedule(\u0026rq-\u003exdp_napi);\ndrivers/net/veth.c-309-\t}\n--\ndrivers/net/veth.c-311-\ndrivers/net/veth.c:312:static int veth_xdp_rx(struct veth_rq *rq, struct sk_buff *skb)\ndrivers/net/veth.c-313-{\ndrivers/net/veth.c:314:\tif (unlikely(ptr_ring_produce(\u0026rq-\u003exdp_ring, skb)))\ndrivers/net/veth.c-315-\t\treturn NETDEV_TX_BUSY; /* signal qdisc layer */\n--\ndrivers/net/veth.c=320=static int veth_forward_skb(struct net_device *dev, struct sk_buff *skb,\ndrivers/net/veth.c:321:\t\t\t struct veth_rq *rq, bool xdp)\ndrivers/net/veth.c-322-{\ndrivers/net/veth.c:323:\treturn __dev_forward_skb(dev, skb) ?: xdp ?\ndrivers/net/veth.c:324:\t\tveth_xdp_rx(rq, skb) :\ndrivers/net/veth.c-325-\t\t__netif_rx(skb);\n--\ndrivers/net/veth.c=347=static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)\n--\ndrivers/net/veth.c-384-\t\telse\ndrivers/net/veth.c:385:\t\t\t__veth_xdp_flush(rq);\ndrivers/net/veth.c-386-\t\tbreak;\n--\ndrivers/net/veth.c-403-\t\t */\ndrivers/net/veth.c:404:\t\t__veth_xdp_flush(rq);\ndrivers/net/veth.c-405-\t\tbreak;\n--\ndrivers/net/veth.c=420=static void veth_stats_rx(struct veth_stats *result, struct net_device *dev)\n--\ndrivers/net/veth.c-424-\ndrivers/net/veth.c:425:\tresult-\u003epeer_tq_xdp_xmit_err = 0;\ndrivers/net/veth.c:426:\tresult-\u003exdp_packets = 0;\ndrivers/net/veth.c:427:\tresult-\u003exdp_tx_err = 0;\ndrivers/net/veth.c:428:\tresult-\u003exdp_bytes = 0;\ndrivers/net/veth.c-429-\tresult-\u003erx_drops = 0;\ndrivers/net/veth.c-430-\tfor (i = 0; i \u003c dev-\u003enum_rx_queues; i++) {\ndrivers/net/veth.c:431:\t\tu64 packets, bytes, drops, xdp_tx_err, peer_tq_xdp_xmit_err;\ndrivers/net/veth.c-432-\t\tstruct veth_rq_stats *stats = \u0026priv-\u003erq[i].stats;\n--\ndrivers/net/veth.c-436-\t\t\tstart = u64_stats_fetch_begin(\u0026stats-\u003esyncp);\ndrivers/net/veth.c:437:\t\t\tpeer_tq_xdp_xmit_err = stats-\u003evs.peer_tq_xdp_xmit_err;\ndrivers/net/veth.c:438:\t\t\txdp_tx_err = stats-\u003evs.xdp_tx_err;\ndrivers/net/veth.c:439:\t\t\tpackets = stats-\u003evs.xdp_packets;\ndrivers/net/veth.c:440:\t\t\tbytes = stats-\u003evs.xdp_bytes;\ndrivers/net/veth.c-441-\t\t\tdrops = stats-\u003evs.rx_drops;\ndrivers/net/veth.c-442-\t\t} while (u64_stats_fetch_retry(\u0026stats-\u003esyncp, start));\ndrivers/net/veth.c:443:\t\tresult-\u003epeer_tq_xdp_xmit_err += peer_tq_xdp_xmit_err;\ndrivers/net/veth.c:444:\t\tresult-\u003exdp_tx_err += xdp_tx_err;\ndrivers/net/veth.c:445:\t\tresult-\u003exdp_packets += packets;\ndrivers/net/veth.c:446:\t\tresult-\u003exdp_bytes += bytes;\ndrivers/net/veth.c-447-\t\tresult-\u003erx_drops += drops;\n--\ndrivers/net/veth.c=451=static void veth_get_stats64(struct net_device *dev,\n--\ndrivers/net/veth.c-461-\tveth_stats_rx(\u0026rx, dev);\ndrivers/net/veth.c:462:\ttot-\u003etx_dropped += rx.xdp_tx_err;\ndrivers/net/veth.c:463:\ttot-\u003erx_dropped = rx.rx_drops + rx.peer_tq_xdp_xmit_err;\ndrivers/net/veth.c:464:\ttot-\u003erx_bytes += rx.xdp_bytes;\ndrivers/net/veth.c:465:\ttot-\u003erx_packets += rx.xdp_packets;\ndrivers/net/veth.c-466-\n--\ndrivers/net/veth.c-476-\t\tveth_stats_rx(\u0026rx, peer);\ndrivers/net/veth.c:477:\t\ttot-\u003etx_dropped += rx.peer_tq_xdp_xmit_err;\ndrivers/net/veth.c:478:\t\ttot-\u003erx_dropped += rx.xdp_tx_err;\ndrivers/net/veth.c:479:\t\ttot-\u003etx_bytes += rx.xdp_bytes;\ndrivers/net/veth.c:480:\t\ttot-\u003etx_packets += rx.xdp_packets;\ndrivers/net/veth.c-481-\t}\n--\ndrivers/net/veth.c=495=static struct net_device *veth_peer_dev(struct net_device *dev)\n--\ndrivers/net/veth.c-502-\ndrivers/net/veth.c:503:static int veth_xdp_xmit(struct net_device *dev, int n,\ndrivers/net/veth.c:504:\t\t\t struct xdp_frame **frames,\ndrivers/net/veth.c-505-\t\t\t u32 flags, bool ndo_xmit)\n--\ndrivers/net/veth.c-523-\t/* The napi pointer is set if NAPI is enabled, which ensures that\ndrivers/net/veth.c:524:\t * xdp_ring is initialized on receive side and the peer device is up.\ndrivers/net/veth.c-525-\t */\n--\ndrivers/net/veth.c-530-\ndrivers/net/veth.c:531:\tspin_lock(\u0026rq-\u003exdp_ring.producer_lock);\ndrivers/net/veth.c-532-\tfor (i = 0; i \u003c n; i++) {\ndrivers/net/veth.c:533:\t\tstruct xdp_frame *frame = frames[i];\ndrivers/net/veth.c:534:\t\tvoid *ptr = veth_xdp_to_ptr(frame);\ndrivers/net/veth.c-535-\ndrivers/net/veth.c:536:\t\tif (unlikely(xdp_get_frame_len(frame) \u003e max_len ||\ndrivers/net/veth.c:537:\t\t\t __ptr_ring_produce(\u0026rq-\u003exdp_ring, ptr)))\ndrivers/net/veth.c-538-\t\t\tbreak;\n--\ndrivers/net/veth.c-540-\t}\ndrivers/net/veth.c:541:\tspin_unlock(\u0026rq-\u003exdp_ring.producer_lock);\ndrivers/net/veth.c-542-\ndrivers/net/veth.c-543-\tif (flags \u0026 XDP_XMIT_FLUSH)\ndrivers/net/veth.c:544:\t\t__veth_xdp_flush(rq);\ndrivers/net/veth.c-545-\n--\ndrivers/net/veth.c-548-\t\tu64_stats_update_begin(\u0026rq-\u003estats.syncp);\ndrivers/net/veth.c:549:\t\trq-\u003estats.vs.peer_tq_xdp_xmit += nxmit;\ndrivers/net/veth.c:550:\t\trq-\u003estats.vs.peer_tq_xdp_xmit_err += n - nxmit;\ndrivers/net/veth.c-551-\t\tu64_stats_update_end(\u0026rq-\u003estats.syncp);\n--\ndrivers/net/veth.c-559-\ndrivers/net/veth.c:560:static int veth_ndo_xdp_xmit(struct net_device *dev, int n,\ndrivers/net/veth.c:561:\t\t\t struct xdp_frame **frames, u32 flags)\ndrivers/net/veth.c-562-{\n--\ndrivers/net/veth.c-564-\ndrivers/net/veth.c:565:\terr = veth_xdp_xmit(dev, n, frames, flags, true);\ndrivers/net/veth.c-566-\tif (err \u003c 0) {\n--\ndrivers/net/veth.c-574-\ndrivers/net/veth.c:575:static void veth_xdp_flush_bq(struct veth_rq *rq, struct veth_xdp_tx_bq *bq)\ndrivers/net/veth.c-576-{\n--\ndrivers/net/veth.c-578-\ndrivers/net/veth.c:579:\tsent = veth_xdp_xmit(rq-\u003edev, bq-\u003ecount, bq-\u003eq, 0, false);\ndrivers/net/veth.c-580-\tif (sent \u003c 0) {\n--\ndrivers/net/veth.c-585-\tfor (i = sent; unlikely(i \u003c bq-\u003ecount); i++)\ndrivers/net/veth.c:586:\t\txdp_return_frame(bq-\u003eq[i]);\ndrivers/net/veth.c-587-\ndrivers/net/veth.c-588-\tdrops = bq-\u003ecount - sent;\ndrivers/net/veth.c:589:\ttrace_xdp_bulk_tx(rq-\u003edev, sent, drops, err);\ndrivers/net/veth.c-590-\ndrivers/net/veth.c-591-\tu64_stats_update_begin(\u0026rq-\u003estats.syncp);\ndrivers/net/veth.c:592:\trq-\u003estats.vs.xdp_tx += sent;\ndrivers/net/veth.c:593:\trq-\u003estats.vs.xdp_tx_err += drops;\ndrivers/net/veth.c-594-\tu64_stats_update_end(\u0026rq-\u003estats.syncp);\n--\ndrivers/net/veth.c-598-\ndrivers/net/veth.c:599:static void veth_xdp_flush(struct veth_rq *rq, struct veth_xdp_tx_bq *bq)\ndrivers/net/veth.c-600-{\n--\ndrivers/net/veth.c-605-\trcu_read_lock();\ndrivers/net/veth.c:606:\tveth_xdp_flush_bq(rq, bq);\ndrivers/net/veth.c-607-\trcv = rcu_dereference(priv-\u003epeer);\n--\ndrivers/net/veth.c-612-\trcv_rq = \u0026rcv_priv-\u003erq[veth_select_rxq(rcv)];\ndrivers/net/veth.c:613:\t/* xdp_ring is initialized on receive side? */\ndrivers/net/veth.c:614:\tif (unlikely(!rcu_access_pointer(rcv_rq-\u003exdp_prog)))\ndrivers/net/veth.c-615-\t\tgoto out;\ndrivers/net/veth.c-616-\ndrivers/net/veth.c:617:\t__veth_xdp_flush(rcv_rq);\ndrivers/net/veth.c-618-out:\n--\ndrivers/net/veth.c-621-\ndrivers/net/veth.c:622:static int veth_xdp_tx(struct veth_rq *rq, struct xdp_buff *xdp,\ndrivers/net/veth.c:623:\t\t struct veth_xdp_tx_bq *bq)\ndrivers/net/veth.c-624-{\ndrivers/net/veth.c:625:\tstruct xdp_frame *frame = xdp_convert_buff_to_frame(xdp);\ndrivers/net/veth.c-626-\n--\ndrivers/net/veth.c-630-\tif (unlikely(bq-\u003ecount == VETH_XDP_TX_BULK_SIZE))\ndrivers/net/veth.c:631:\t\tveth_xdp_flush_bq(rq, bq);\ndrivers/net/veth.c-632-\n--\ndrivers/net/veth.c-637-\ndrivers/net/veth.c:638:static struct xdp_frame *veth_xdp_rcv_one(struct veth_rq *rq,\ndrivers/net/veth.c:639:\t\t\t\t\t struct xdp_frame *frame,\ndrivers/net/veth.c:640:\t\t\t\t\t struct veth_xdp_tx_bq *bq,\ndrivers/net/veth.c-641-\t\t\t\t\t struct veth_stats *stats)\ndrivers/net/veth.c-642-{\ndrivers/net/veth.c:643:\tstruct xdp_frame orig_frame;\ndrivers/net/veth.c:644:\tstruct bpf_prog *xdp_prog;\ndrivers/net/veth.c-645-\ndrivers/net/veth.c-646-\trcu_read_lock();\ndrivers/net/veth.c:647:\txdp_prog = rcu_dereference(rq-\u003exdp_prog);\ndrivers/net/veth.c:648:\tif (likely(xdp_prog)) {\ndrivers/net/veth.c:649:\t\tstruct veth_xdp_buff vxbuf;\ndrivers/net/veth.c:650:\t\tstruct xdp_buff *xdp = \u0026vxbuf.xdp;\ndrivers/net/veth.c-651-\t\tu32 act;\ndrivers/net/veth.c-652-\ndrivers/net/veth.c:653:\t\txdp_convert_frame_to_buff(frame, xdp);\ndrivers/net/veth.c:654:\t\txdp-\u003erxq = \u0026rq-\u003exdp_rxq;\ndrivers/net/veth.c-655-\t\tvxbuf.skb = NULL;\ndrivers/net/veth.c-656-\ndrivers/net/veth.c:657:\t\tact = bpf_prog_run_xdp(xdp_prog, xdp);\ndrivers/net/veth.c-658-\n--\ndrivers/net/veth.c-660-\t\tcase XDP_PASS:\ndrivers/net/veth.c:661:\t\t\tif (xdp_update_frame_from_buff(xdp, frame))\ndrivers/net/veth.c:662:\t\t\t\tgoto err_xdp;\ndrivers/net/veth.c-663-\t\t\tbreak;\n--\ndrivers/net/veth.c-665-\t\t\torig_frame = *frame;\ndrivers/net/veth.c:666:\t\t\txdp-\u003erxq-\u003emem.type = frame-\u003emem_type;\ndrivers/net/veth.c:667:\t\t\tif (unlikely(veth_xdp_tx(rq, xdp, bq) \u003c 0)) {\ndrivers/net/veth.c:668:\t\t\t\ttrace_xdp_exception(rq-\u003edev, xdp_prog, act);\ndrivers/net/veth.c-669-\t\t\t\tframe = \u0026orig_frame;\ndrivers/net/veth.c-670-\t\t\t\tstats-\u003erx_drops++;\ndrivers/net/veth.c:671:\t\t\t\tgoto err_xdp;\ndrivers/net/veth.c-672-\t\t\t}\ndrivers/net/veth.c:673:\t\t\tstats-\u003exdp_tx++;\ndrivers/net/veth.c-674-\t\t\trcu_read_unlock();\ndrivers/net/veth.c:675:\t\t\tgoto xdp_xmit;\ndrivers/net/veth.c-676-\t\tcase XDP_REDIRECT:\ndrivers/net/veth.c-677-\t\t\torig_frame = *frame;\ndrivers/net/veth.c:678:\t\t\txdp-\u003erxq-\u003emem.type = frame-\u003emem_type;\ndrivers/net/veth.c:679:\t\t\tif (xdp_do_redirect(rq-\u003edev, xdp, xdp_prog)) {\ndrivers/net/veth.c-680-\t\t\t\tframe = \u0026orig_frame;\ndrivers/net/veth.c-681-\t\t\t\tstats-\u003erx_drops++;\ndrivers/net/veth.c:682:\t\t\t\tgoto err_xdp;\ndrivers/net/veth.c-683-\t\t\t}\ndrivers/net/veth.c:684:\t\t\tstats-\u003exdp_redirect++;\ndrivers/net/veth.c-685-\t\t\trcu_read_unlock();\ndrivers/net/veth.c:686:\t\t\tgoto xdp_xmit;\ndrivers/net/veth.c-687-\t\tdefault:\ndrivers/net/veth.c:688:\t\t\tbpf_warn_invalid_xdp_action(rq-\u003edev, xdp_prog, act);\ndrivers/net/veth.c-689-\t\t\tfallthrough;\ndrivers/net/veth.c-690-\t\tcase XDP_ABORTED:\ndrivers/net/veth.c:691:\t\t\ttrace_xdp_exception(rq-\u003edev, xdp_prog, act);\ndrivers/net/veth.c-692-\t\t\tfallthrough;\ndrivers/net/veth.c-693-\t\tcase XDP_DROP:\ndrivers/net/veth.c:694:\t\t\tstats-\u003exdp_drops++;\ndrivers/net/veth.c:695:\t\t\tgoto err_xdp;\ndrivers/net/veth.c-696-\t\t}\n--\ndrivers/net/veth.c-700-\treturn frame;\ndrivers/net/veth.c:701:err_xdp:\ndrivers/net/veth.c-702-\trcu_read_unlock();\ndrivers/net/veth.c:703:\txdp_return_frame(frame);\ndrivers/net/veth.c:704:xdp_xmit:\ndrivers/net/veth.c-705-\treturn NULL;\n--\ndrivers/net/veth.c-708-/* frames array contains VETH_XDP_BATCH at most */\ndrivers/net/veth.c:709:static void veth_xdp_rcv_bulk_skb(struct veth_rq *rq, void **frames,\ndrivers/net/veth.c:710:\t\t\t\t int n_xdpf, struct veth_xdp_tx_bq *bq,\ndrivers/net/veth.c-711-\t\t\t\t struct veth_stats *stats)\n--\ndrivers/net/veth.c-715-\ndrivers/net/veth.c:716:\tif (unlikely(!napi_skb_cache_get_bulk(skbs, n_xdpf))) {\ndrivers/net/veth.c:717:\t\tfor (i = 0; i \u003c n_xdpf; i++)\ndrivers/net/veth.c:718:\t\t\txdp_return_frame(frames[i]);\ndrivers/net/veth.c:719:\t\tstats-\u003erx_drops += n_xdpf;\ndrivers/net/veth.c-720-\n--\ndrivers/net/veth.c-723-\ndrivers/net/veth.c:724:\tfor (i = 0; i \u003c n_xdpf; i++) {\ndrivers/net/veth.c-725-\t\tstruct sk_buff *skb = skbs[i];\ndrivers/net/veth.c-726-\ndrivers/net/veth.c:727:\t\tskb = __xdp_build_skb_from_frame(frames[i], skb,\ndrivers/net/veth.c-728-\t\t\t\t\t\t rq-\u003edev);\ndrivers/net/veth.c-729-\t\tif (!skb) {\ndrivers/net/veth.c:730:\t\t\txdp_return_frame(frames[i]);\ndrivers/net/veth.c-731-\t\t\tstats-\u003erx_drops++;\n--\ndrivers/net/veth.c-733-\t\t}\ndrivers/net/veth.c:734:\t\tnapi_gro_receive(\u0026rq-\u003exdp_napi, skb);\ndrivers/net/veth.c-735-\t}\n--\ndrivers/net/veth.c-737-\ndrivers/net/veth.c:738:static void veth_xdp_get(struct xdp_buff *xdp)\ndrivers/net/veth.c-739-{\ndrivers/net/veth.c:740:\tstruct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp);\ndrivers/net/veth.c-741-\tint i;\ndrivers/net/veth.c-742-\ndrivers/net/veth.c:743:\tget_page(virt_to_page(xdp-\u003edata));\ndrivers/net/veth.c:744:\tif (likely(!xdp_buff_has_frags(xdp)))\ndrivers/net/veth.c-745-\t\treturn;\n--\ndrivers/net/veth.c-750-\ndrivers/net/veth.c:751:static int veth_convert_skb_to_xdp_buff(struct veth_rq *rq,\ndrivers/net/veth.c:752:\t\t\t\t\tstruct xdp_buff *xdp,\ndrivers/net/veth.c-753-\t\t\t\t\tstruct sk_buff **pskb)\n--\ndrivers/net/veth.c-769-\tframe_sz += SKB_DATA_ALIGN(sizeof(struct skb_shared_info));\ndrivers/net/veth.c:770:\txdp_init_buff(xdp, frame_sz, \u0026rq-\u003exdp_rxq);\ndrivers/net/veth.c:771:\txdp_prepare_buff(xdp, skb-\u003ehead, skb_headroom(skb),\ndrivers/net/veth.c-772-\t\t\t skb_headlen(skb), true);\n--\ndrivers/net/veth.c-774-\tif (skb_shinfo(skb)-\u003enr_frags) {\ndrivers/net/veth.c:775:\t\tskb_shinfo(skb)-\u003exdp_frags_size = skb-\u003edata_len;\ndrivers/net/veth.c:776:\t\txdp_buff_set_frags_flag(xdp);\ndrivers/net/veth.c-777-\t} else {\ndrivers/net/veth.c:778:\t\txdp_buff_clear_frags_flag(xdp);\ndrivers/net/veth.c-779-\t}\n--\ndrivers/net/veth.c-789-\ndrivers/net/veth.c:790:static struct sk_buff *veth_xdp_rcv_skb(struct veth_rq *rq,\ndrivers/net/veth.c-791-\t\t\t\t\tstruct sk_buff *skb,\ndrivers/net/veth.c:792:\t\t\t\t\tstruct veth_xdp_tx_bq *bq,\ndrivers/net/veth.c-793-\t\t\t\t\tstruct veth_stats *stats)\n--\ndrivers/net/veth.c-795-\tvoid *orig_data, *orig_data_end;\ndrivers/net/veth.c:796:\tstruct bpf_prog *xdp_prog;\ndrivers/net/veth.c:797:\tstruct veth_xdp_buff vxbuf;\ndrivers/net/veth.c:798:\tstruct xdp_buff *xdp = \u0026vxbuf.xdp;\ndrivers/net/veth.c-799-\tu32 act, metalen;\n--\ndrivers/net/veth.c-804-\trcu_read_lock();\ndrivers/net/veth.c:805:\txdp_prog = rcu_dereference(rq-\u003exdp_prog);\ndrivers/net/veth.c:806:\tif (unlikely(!xdp_prog)) {\ndrivers/net/veth.c-807-\t\trcu_read_unlock();\n--\ndrivers/net/veth.c-811-\t__skb_push(skb, skb-\u003edata - skb_mac_header(skb));\ndrivers/net/veth.c:812:\tif (veth_convert_skb_to_xdp_buff(rq, xdp, \u0026skb))\ndrivers/net/veth.c-813-\t\tgoto drop;\n--\ndrivers/net/veth.c-815-\ndrivers/net/veth.c:816:\torig_data = xdp-\u003edata;\ndrivers/net/veth.c:817:\torig_data_end = xdp-\u003edata_end;\ndrivers/net/veth.c-818-\ndrivers/net/veth.c:819:\tact = bpf_prog_run_xdp(xdp_prog, xdp);\ndrivers/net/veth.c-820-\n--\ndrivers/net/veth.c-824-\tcase XDP_TX:\ndrivers/net/veth.c:825:\t\tveth_xdp_get(xdp);\ndrivers/net/veth.c-826-\t\tconsume_skb(skb);\ndrivers/net/veth.c:827:\t\txdp-\u003erxq-\u003emem = rq-\u003exdp_mem;\ndrivers/net/veth.c:828:\t\tif (unlikely(veth_xdp_tx(rq, xdp, bq) \u003c 0)) {\ndrivers/net/veth.c:829:\t\t\ttrace_xdp_exception(rq-\u003edev, xdp_prog, act);\ndrivers/net/veth.c-830-\t\t\tstats-\u003erx_drops++;\ndrivers/net/veth.c:831:\t\t\tgoto err_xdp;\ndrivers/net/veth.c-832-\t\t}\ndrivers/net/veth.c:833:\t\tstats-\u003exdp_tx++;\ndrivers/net/veth.c-834-\t\trcu_read_unlock();\ndrivers/net/veth.c:835:\t\tgoto xdp_xmit;\ndrivers/net/veth.c-836-\tcase XDP_REDIRECT:\ndrivers/net/veth.c:837:\t\tveth_xdp_get(xdp);\ndrivers/net/veth.c-838-\t\tconsume_skb(skb);\ndrivers/net/veth.c:839:\t\txdp-\u003erxq-\u003emem = rq-\u003exdp_mem;\ndrivers/net/veth.c:840:\t\tif (xdp_do_redirect(rq-\u003edev, xdp, xdp_prog)) {\ndrivers/net/veth.c-841-\t\t\tstats-\u003erx_drops++;\ndrivers/net/veth.c:842:\t\t\tgoto err_xdp;\ndrivers/net/veth.c-843-\t\t}\ndrivers/net/veth.c:844:\t\tstats-\u003exdp_redirect++;\ndrivers/net/veth.c-845-\t\trcu_read_unlock();\ndrivers/net/veth.c:846:\t\tgoto xdp_xmit;\ndrivers/net/veth.c-847-\tdefault:\ndrivers/net/veth.c:848:\t\tbpf_warn_invalid_xdp_action(rq-\u003edev, xdp_prog, act);\ndrivers/net/veth.c-849-\t\tfallthrough;\ndrivers/net/veth.c-850-\tcase XDP_ABORTED:\ndrivers/net/veth.c:851:\t\ttrace_xdp_exception(rq-\u003edev, xdp_prog, act);\ndrivers/net/veth.c-852-\t\tfallthrough;\ndrivers/net/veth.c-853-\tcase XDP_DROP:\ndrivers/net/veth.c:854:\t\tstats-\u003exdp_drops++;\ndrivers/net/veth.c:855:\t\tgoto xdp_drop;\ndrivers/net/veth.c-856-\t}\n--\ndrivers/net/veth.c-858-\ndrivers/net/veth.c:859:\t/* check if bpf_xdp_adjust_head was used */\ndrivers/net/veth.c:860:\toff = orig_data - xdp-\u003edata;\ndrivers/net/veth.c-861-\tif (off \u003e 0)\n--\ndrivers/net/veth.c-868-\t/* XDP frag metadata (e.g. nr_frags) are updated in eBPF helpers\ndrivers/net/veth.c:869:\t * (e.g. bpf_xdp_adjust_tail). Remove the old fragment contribution\ndrivers/net/veth.c-870-\t * from skb-\u003elen before updating data_len, then add the new one back.\n--\ndrivers/net/veth.c-872-\tskb-\u003elen -= skb-\u003edata_len;\ndrivers/net/veth.c:873:\tif (xdp_buff_has_frags(xdp)) {\ndrivers/net/veth.c:874:\t\tskb-\u003edata_len = skb_shinfo(skb)-\u003exdp_frags_size;\ndrivers/net/veth.c-875-\t\tskb-\u003elen += skb-\u003edata_len;\n--\ndrivers/net/veth.c-880-\t/* Synchronize the skb tail with XDP's updated linear area. */\ndrivers/net/veth.c:881:\toff = xdp-\u003edata_end - orig_data_end;\ndrivers/net/veth.c-882-\tif (off != 0) {\ndrivers/net/veth.c:883:\t\tskb_set_tail_pointer(skb, xdp-\u003edata_end - xdp-\u003edata);\ndrivers/net/veth.c-884-\t\tskb-\u003elen += off; /* positive on grow, negative on shrink */\n--\ndrivers/net/veth.c-888-\ndrivers/net/veth.c:889:\tmetalen = xdp-\u003edata - xdp-\u003edata_meta;\ndrivers/net/veth.c-890-\tif (metalen)\n--\ndrivers/net/veth.c-895-\tstats-\u003erx_drops++;\ndrivers/net/veth.c:896:xdp_drop:\ndrivers/net/veth.c-897-\trcu_read_unlock();\n--\ndrivers/net/veth.c-899-\treturn NULL;\ndrivers/net/veth.c:900:err_xdp:\ndrivers/net/veth.c-901-\trcu_read_unlock();\ndrivers/net/veth.c:902:\txdp_return_buff(xdp);\ndrivers/net/veth.c:903:xdp_xmit:\ndrivers/net/veth.c-904-\treturn NULL;\n--\ndrivers/net/veth.c-906-\ndrivers/net/veth.c:907:static int veth_xdp_rcv(struct veth_rq *rq, int budget,\ndrivers/net/veth.c:908:\t\t\tstruct veth_xdp_tx_bq *bq,\ndrivers/net/veth.c-909-\t\t\tstruct veth_stats *stats)\ndrivers/net/veth.c-910-{\ndrivers/net/veth.c:911:\tint i, done = 0, n_xdpf = 0;\ndrivers/net/veth.c:912:\tvoid *xdpf[VETH_XDP_BATCH];\ndrivers/net/veth.c-913-\ndrivers/net/veth.c-914-\tfor (i = 0; i \u003c budget; i++) {\ndrivers/net/veth.c:915:\t\tvoid *ptr = __ptr_ring_consume(\u0026rq-\u003exdp_ring);\ndrivers/net/veth.c-916-\n--\ndrivers/net/veth.c-919-\ndrivers/net/veth.c:920:\t\tif (veth_is_xdp_frame(ptr)) {\ndrivers/net/veth.c:921:\t\t\t/* ndo_xdp_xmit */\ndrivers/net/veth.c:922:\t\t\tstruct xdp_frame *frame = veth_ptr_to_xdp(ptr);\ndrivers/net/veth.c-923-\ndrivers/net/veth.c:924:\t\t\tstats-\u003exdp_bytes += xdp_get_frame_len(frame);\ndrivers/net/veth.c:925:\t\t\tframe = veth_xdp_rcv_one(rq, frame, bq, stats);\ndrivers/net/veth.c-926-\t\t\tif (frame) {\ndrivers/net/veth.c-927-\t\t\t\t/* XDP_PASS */\ndrivers/net/veth.c:928:\t\t\t\txdpf[n_xdpf++] = frame;\ndrivers/net/veth.c:929:\t\t\t\tif (n_xdpf == VETH_XDP_BATCH) {\ndrivers/net/veth.c:930:\t\t\t\t\tveth_xdp_rcv_bulk_skb(rq, xdpf, n_xdpf,\ndrivers/net/veth.c-931-\t\t\t\t\t\t\t bq, stats);\ndrivers/net/veth.c:932:\t\t\t\t\tn_xdpf = 0;\ndrivers/net/veth.c-933-\t\t\t\t}\n--\ndrivers/net/veth.c-938-\ndrivers/net/veth.c:939:\t\t\tstats-\u003exdp_bytes += skb-\u003elen;\ndrivers/net/veth.c:940:\t\t\tskb = veth_xdp_rcv_skb(rq, skb, bq, stats);\ndrivers/net/veth.c-941-\t\t\tif (skb) {\n--\ndrivers/net/veth.c-944-\t\t\t\telse\ndrivers/net/veth.c:945:\t\t\t\t\tnapi_gro_receive(\u0026rq-\u003exdp_napi, skb);\ndrivers/net/veth.c-946-\t\t\t}\n\n"
} |
| 43/2 | 2026/08/13 20:21 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 61287 output: 40 thoughts: 360 Thoughts: **My Analysis of AF_XDP Zero-Copy Impact** Okay, so the `veth` interface, while XDP-capable, doesn't utilize the `xsk_buff_pool`, instead relying on `xdp_frame` and `xdp_buff`. That means the recent `xsk_buff_get_metadata` change won't affect it. Good. Let's quickly run through the other candidates: `macvlan`? Nope. Zero-copy AF_XDP is a no-go there. `virtio_net`? Still no. `tun`/`tap`? Negative. So, it looks like, at least initially, the only drivers that *do* support this zero-copy AF_XDP mechanism are physical NICs and a few specialized virtual ones: `tsnep` (FPGA endpoint) and `gve`, the Google Virtual NIC. Hang on… `gve`… that's interesting. Can I even reach `gve` within a QEMU environment? Probably not natively. However, syzkaller *might* be running on Google Compute Engine (GCE), where `gve` is the actual network interface! But, syzkaller typically runs tests *inside* a VM. If the VM is on GCE, it could theoretically have a `gve` interface, but syzkaller usually isolates with nested VMs (QEMU) or network namespaces with `veth` or `tun` devices. It's not usually fuzzing the host's `gve` device directly because that would tear down the network connection to the VM. Even if it did, the crucial point is: does `gve` *use* `xsk_buff_get_metadata`? That's the real question. Let's dig deeper and verify that. |
| 44/2 | 2026/08/13 20:21 | tool | grepper |
0mError:no matches Args: {
"Expression": "xsk_buff_get_metadata",
"PathPrefix": "drivers/net/ethernet/google/gve/"
}Results: {
"error": "no matches"
} |
| 45/2 | 2026/08/13 20:21 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 62092 output: 38 thoughts: 24 Thoughts: Okay, here's my take on those thoughts, framed as an expert's internal monologue: **Checking Dependency Usage** Alright, let's get down to brass tacks. I'm pretty sure I remember the `gve` library not utilizing the dependency in question, but it's always best to be absolutely certain. Before I move on with my own work, I need to verify that it's *not* a factor in `gve`'s operation. I'll need to double check the code. Now, if `gve` doesn't use it, my next step is to examine `tsnep`. I should investigate whether that library, which is related in functionality, actually depends on it. A quick search through the `tsnep` codebase is in order. It's important to know the relationships between all these tools. If either of those packages use it, that will drastically change what is necessary in my current development. |
| 46/2 | 2026/08/13 20:21 | tool | grepper |
0mError:no matches Args: {
"Expression": "xsk_buff_get_metadata",
"PathPrefix": "drivers/net/ethernet/engleder/"
}Results: {
"error": "no matches"
} |
| 47/2 | 2026/08/13 20:21 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 62369 output: 43 thoughts: 17 Thoughts: Okay, here's my summary, in the first person, as requested: **Assessing the Landscape** Nope. Not happening. My gut reaction is a hard "no" on this. I need to make sure I am fully dismissing this point though. Let's not just ignore this, let's go deeper and check if this actually is being used by the `dpaa2` system. I need to be sure before I move on. |
| 48/2 | 2026/08/13 20:21 | tool | grepper |
0mError:no matches Args: {
"Expression": "xsk_buff_get_metadata",
"PathPrefix": "drivers/net/ethernet/freescale/dpaa2/"
}Results: {
"error": "no matches"
} |
| 49/2 | 2026/08/13 20:21 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 62539 output: 40 thoughts: 15 Thoughts: Okay, here's my summary, presented as a direct thought process: **No. Let's Verify This Claim.** Alright, that's a flat "no." But, let's not just take that as the final answer, especially when dealing with [implied field - user's area of expertise, e.g., complex systems, data analysis, theoretical physics]. My gut says "no," but gut feelings aren't enough. I need to be *sure*. The next logical step is to see if this is being implemented anywhere, even in a small way. Specifically, I need to check if `fec` is utilizing whatever we're talking about. Is there any existing codebase or relevant documentation that would provide an answer here? That's where I need to start my search. A quick check of `fec` will either confirm this negative or give me an immediate jumping-off point for further investigation. |
| 50/2 | 2026/08/13 20:21 | tool | grepper |
0mError:no matches Args: {
"Expression": "xsk_buff_get_metadata",
"PathPrefix": "drivers/net/ethernet/freescale/fec"
}Results: {
"error": "no matches"
} |
| 51/2 | 2026/08/13 20:21 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 62802 output: 36 thoughts: 749 Thoughts: **Analyzing a Potential ABI Mismatch in XDP and AF_XDP** Okay, so I'm thinking about this code and the potential impact of this recent change. My initial thought is that `igc`, `mlx5`, `stmmac`, and `idpf` (through `libeth`) are the only drivers that use those `xsk_buff_get_metadata` or `xp_raw_get_ctx` functions. But, Syzkaller doesn't typically fuzz those in a way that would hit this particular area because it prefers things like `veth`, `tun`, `macvlan`, `vcan`, and `vxlan`. Then, wait a minute, there's that UAPI change. This patch is modifying `include/uapi/linux/if_xdp.h` specifically to change the size of `struct xsk_tx_metadata` on 32-bit architectures. My concern now centers around `net/xdp/xsk.c`, the core AF_XDP socket implementation. A user can set `tx_metadata_len` in `struct xdp_umem_reg` when creating an AF_XDP socket. Then, in `xsk_skb_metadata` it calls `xsk_buff_valid_tx_metadata`. The crucial check here uses `offsetofend` to determine if enough space is available. A 32-bit userspace program compiled with the *old* header would set `tx_metadata_len` to 20, but the *new* header makes `offsetofend` equal 24. Consequently, `xsk_buff_valid_tx_metadata` will return `false`, which leads to an `-EINVAL` from `xsk_skb_metadata`. So, the patch is fixing a 32-bit/64-bit ABI mismatch, but it also changes the behavior for any 32-bit programs using the old struct size. This is important to remember because such a change can break existing applications. I need to confirm if this is reachable in a virtualized environment. Because, if it is not, this may not be a valid concern. AF_XDP sockets (`AF_XDP`) *can* be created on any network interface, including `veth`. Okay, `veth` could be used. Wait... does `veth` even support `XDP_TX_METADATA`? This needs verification. Okay, let's see. Looking at `net/xdp/xsk.c`, `xsk_build_skb` and `xsk_build_skb_zerocopy` check `desc->options & XDP_TX_METADATA`. These functions are used when transmitting packets via AF_XDP sockets. If the socket is bound to `veth`, it'll use `xsk_build_skb` since `veth` does not support zero-copy AF_XDP. I should be able to verify this quickly. |
| 52/2 | 2026/08/13 20:22 | tool | grepper |
0mArgs:{
"Expression": "xsk_build_skb",
"PathPrefix": "net/xdp/xsk.c"
}Results: {
"Output": "net/xdp/xsk.c=964=static int xsk_skb_metadata(struct sk_buff *skb, void *buffer,\n--\nnet/xdp/xsk.c-1008-\nnet/xdp/xsk.c:1009:static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,\nnet/xdp/xsk.c-1010-\t\t\t\t\t struct xdp_desc *desc)\n--\nnet/xdp/xsk.c-1084-\nnet/xdp/xsk.c:1085:static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,\nnet/xdp/xsk.c-1086-\t\t\t\t struct xdp_desc *desc)\n--\nnet/xdp/xsk.c-1092-\tif (dev-\u003epriv_flags \u0026 IFF_TX_SKB_NO_LINEAR) {\nnet/xdp/xsk.c:1093:\t\tskb = xsk_build_skb_zerocopy(xs, desc);\nnet/xdp/xsk.c-1094-\t\tif (IS_ERR(skb)) {\n--\nnet/xdp/xsk.c=1191=static int __xsk_generic_xmit(struct sock *sk)\n--\nnet/xdp/xsk.c-1237-\nnet/xdp/xsk.c:1238:\t\tskb = xsk_build_skb(xs, \u0026desc);\nnet/xdp/xsk.c-1239-\t\tif (IS_ERR(skb)) {\n"
} |
| 53/2 | 2026/08/13 20:22 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 64668 output: 157 thoughts: 3163 Thoughts: **Analysis of XDP Zero-Copy TX Metadata Patch** Okay, so this patch seems focused on enhancing XDP zero-copy transmission, particularly the metadata handling. Initially, I saw that `__xsk_generic_xmit` is the key, calling `xsk_build_skb`, and crucially, `xsk_skb_metadata`, which is absolutely reachable even in virtual environments. This then goes to `xsk_buff_valid_tx_metadata`. My main question is whether any of the changes are functionally significant from a fuzzing perspective. I see a modification to the `xsk_tx_metadata` struct and, consequently, `xsk_buff_valid_tx_metadata` within `net/xdp/xsk.c` (through inline). This affects the `pool->tx_metadata_len` requirement - now 24 bytes minimum instead of 20 on 32-bit systems. I need to figure out if this struct layout change is a meaningful enough functional change to be worth fuzzing. The key question is whether it affects execution flow or is just a structural adjustment. My inclination is that it’s more of the latter, but I need to be precise. I also notice that `__xsk_buff_get_metadata` has changed in `include/net/xdp_sock_drv.h`, but it is only called by specific hardware drivers - `igc`, `mlx5`, `stmmac`, and `idpf`. These are not typically emulated in a standard QEMU setup which is what syzkaller is used with. So, realistically, this is a non-issue from my perspective. The stmmac changes are also not relevant. The core logic change looks like it is to make the `options` argument be passed to `xsk_buff_get_metadata` and includes a check for `options & XDP_TX_METADATA` before returning the metadata pointer. This prevents the usage of invalid metadata if the option isn't set. This affects the zero-copy TX path on specific hardware drivers, none of which are reachable for fuzzing. Now, that struct layout change, the only reachable alteration, only changes a numeric constant used in a size check. If the length is less than 24, we return `-EINVAL`, and the packet is dropped. It is a bound check, not logic change. Is this a new state machine or complex logic to fuzz? No, I wouldn’t consider this significant. It’s just the addition of padding. My previous experience indicates these struct padding fixes aren’t generally a fuzzing target because they're essentially just constant updates. Now, let's revisit `stmmac` again. I know QEMU uses `designware`, but is it the same? Turns out the driver is the DesignWare MAC. The question is whether or not that hardware is accessible, and also if zero-copy is supported. It’s a SysBus device, which doesn't fit the standard syzkaller configuration. After looking at the locations for the metadata: 1. `igc_main.c`: `meta = xsk_buff_get_metadata(pool, xdp_desc.addr, xdp_desc.options);` 2. `mlx5/core/en/xsk/tx.c`: `meta = xsk_buff_get_metadata(pool, desc.addr, desc.options);` 3. `stmmac_main.c`: `meta = xsk_buff_get_metadata(pool, xdp_desc.addr, xdp_desc.options);` and removed `max_sdu` check. 4. `include/net/libeth/xsk.h`: `ctx = xsk_buff_raw_get_ctx(sq->pool, xdesc->addr, xdesc->options);` 5. `include/net/xdp_sock_drv.h`: Added `options` argument to `xsk_buff_raw_get_ctx`, `__xsk_buff_get_metadata`, `xsk_buff_get_metadata`. Added `options & XDP_TX_METADATA` check. 6. `include/net/xsk_buff_pool.h`: Added `options` argument to `xp_raw_get_ctx`. 7. `include/uapi/linux/if_xdp.h`: Added `__u32 reserved;` to `struct xsk_tx_metadata`. 8. `net/xdp/xsk_buff_pool.c`: Added `options` argument to `xp_raw_get_ctx`. 9. `tools/include/uapi/linux/if_ |
| 54/2 | 2026/08/13 20:22 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch modifies the AF_XDP zero-copy TX metadata path to check the XDP_TX_METADATA option before accessing metadata. This logic is only implemented and reachable in specific hardware drivers (igc, mlx5, stmmac, idpf) which are not emulated in standard virtualized environments like QEMU. The patch also adds a reserved padding field to `struct xsk_tx_metadata` in the UAPI, which only alters a numeric constant (struct size) used in a length check in the generic XDP TX path, without introducing new functional logic worth fuzzing.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the AF_XDP zero-copy TX metadata path to check the XDP_TX_METADATA option before accessing metadata. This logic is only implemented and reachable in specific hardware drivers (igc, mlx5, stmmac, idpf) which are not emulated in standard virtualized environments like QEMU. The patch also adds a reserved padding field to `struct xsk_tx_metadata` in the UAPI, which only alters a numeric constant (struct size) used in a length check in the generic XDP TX path, without introducing new functional logic worth fuzzing.",
"WorthFuzzing": false
} |
| 55/1 | 2026/08/13 20:22 | action | If |
0mArgs:{
"WorthFuzzing": false
}Results: null |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|