* [RFC ixgbe 0/2] ixgbe: Implement support for ndo_xdp_xmit in skb mode and fix CPU to ring assignment
@ 2025-10-09 19:28 Nabil S. Alramli
2025-10-09 19:28 ` [RFC ixgbe 1/2] ixgbe: Implement support for ndo_xdp_xmit in skb mode Nabil S. Alramli
2025-10-09 19:28 ` [RFC ixgbe 2/2] ixgbe: Fix CPU to ring assignment Nabil S. Alramli
0 siblings, 2 replies; 6+ messages in thread
From: Nabil S. Alramli @ 2025-10-09 19:28 UTC (permalink / raw)
To: anthony.l.nguyen, przemyslaw.kitszel
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, ast, daniel, hawk,
john.fastabend, lishujin, xingwanli, intel-wired-lan, netdev,
linux-kernel, bpf, team-kernel, khubert, nalramli, dev
Hello Kyle,
Please take a look at this patch that I plan to submit upstream, let me
know if you agree.
Hello ixgbe maintainers,
This patch is a RFC to add the ability to transmit packets using
BPF_F_TEST_XDP_LIVE_FRAMES in skb mode to the ixgbe driver. Today this
functionality does not exist because the ndo_xdp_xmit operation handler,
ixgbe_xdp_xmit, expects a native XDP program in adapter->xdp_prog. This
results in a no-op essentially. To add this support, I use the tx_ring
instead of the xdp_ring and allocate a skb based on the xdpf, and then use
dev_direct_xmit to queue the xdp for tansmission.
May I get feedback on the idea and the approach in this patch?
Thank you.
Nabil S. Alramli (2):
ixgbe: Implement support for ndo_xdp_xmit in skb mode
ixgbe: Fix CPU to ring assignment
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 16 +++----
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 43 +++++++++++++++++--
2 files changed, 47 insertions(+), 12 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [RFC ixgbe 1/2] ixgbe: Implement support for ndo_xdp_xmit in skb mode
2025-10-09 19:28 [RFC ixgbe 0/2] ixgbe: Implement support for ndo_xdp_xmit in skb mode and fix CPU to ring assignment Nabil S. Alramli
@ 2025-10-09 19:28 ` Nabil S. Alramli
2025-11-03 16:38 ` Maciej Fijalkowski
2025-10-09 19:28 ` [RFC ixgbe 2/2] ixgbe: Fix CPU to ring assignment Nabil S. Alramli
1 sibling, 1 reply; 6+ messages in thread
From: Nabil S. Alramli @ 2025-10-09 19:28 UTC (permalink / raw)
To: anthony.l.nguyen, przemyslaw.kitszel
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, ast, daniel, hawk,
john.fastabend, lishujin, xingwanli, intel-wired-lan, netdev,
linux-kernel, bpf, team-kernel, khubert, nalramli, dev
This commit adds support for `ndo_xdp_xmit` in skb mode in the ixgbe
ethernet driver, by allowing the call to continue to transmit the packets
using `dev_direct_xmit`.
Previously, the driver did not support the operation in skb mode. The
handler `ixgbe_xdp_xmit` had the following condition:
```
ring = adapter->xdp_prog ? ixgbe_determine_xdp_ring(adapter) : NULL;
if (unlikely(!ring))
return -ENXIO;
```
That only works in native mode. In skb mode, `adapter->xdp_prog == NULL` so
the call returned an error, which prevented the ability to send packets
using `bpf_prog_test_run_opts` with the `BPF_F_TEST_XDP_LIVE_FRAMES` flag.
Signed-off-by: Nabil S. Alramli <dev@nalramli.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 8 ++++
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 43 +++++++++++++++++--
2 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index e6a380d4929b..26c378853755 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -846,6 +846,14 @@ struct ixgbe_ring *ixgbe_determine_xdp_ring(struct ixgbe_adapter *adapter)
return adapter->xdp_ring[index];
}
+static inline
+struct ixgbe_ring *ixgbe_determine_tx_ring(struct ixgbe_adapter *adapter)
+{
+ int index = ixgbe_determine_xdp_q_idx(smp_processor_id());
+
+ return adapter->tx_ring[index];
+}
+
static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter)
{
switch (adapter->hw.mac.type) {
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 467f81239e12..fed70cbdb1b2 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -10748,7 +10748,8 @@ static int ixgbe_xdp_xmit(struct net_device *dev, int n,
/* During program transitions its possible adapter->xdp_prog is assigned
* but ring has not been configured yet. In this case simply abort xmit.
*/
- ring = adapter->xdp_prog ? ixgbe_determine_xdp_ring(adapter) : NULL;
+ ring = adapter->xdp_prog ? ixgbe_determine_xdp_ring(adapter) :
+ ixgbe_determine_tx_ring(adapter);
if (unlikely(!ring))
return -ENXIO;
@@ -10762,9 +10763,43 @@ static int ixgbe_xdp_xmit(struct net_device *dev, int n,
struct xdp_frame *xdpf = frames[i];
int err;
- err = ixgbe_xmit_xdp_ring(ring, xdpf);
- if (err != IXGBE_XDP_TX)
- break;
+ if (adapter->xdp_prog) {
+ err = ixgbe_xmit_xdp_ring(ring, xdpf);
+ if (err != IXGBE_XDP_TX)
+ break;
+ } else {
+ struct xdp_buff xdp = {0};
+ unsigned int metasize = 0;
+ unsigned int size = 0;
+ unsigned int truesize = 0;
+ struct sk_buff *skb = NULL;
+
+ xdp_convert_frame_to_buff(xdpf, &xdp);
+ size = xdp.data_end - xdp.data;
+ metasize = xdp.data - xdp.data_meta;
+ truesize = SKB_DATA_ALIGN(xdp.data_end - xdp.data_hard_start) +
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+
+ skb = napi_alloc_skb(&ring->q_vector->napi, truesize);
+ if (likely(skb)) {
+ skb_reserve(skb, xdp.data - xdp.data_hard_start);
+ skb_put_data(skb, xdp.data, size);
+ build_skb_around(skb, skb->data, truesize);
+ if (metasize)
+ skb_metadata_set(skb, metasize);
+ skb->dev = dev;
+ skb->queue_mapping = ring->queue_index;
+
+ err = dev_direct_xmit(skb, ring->queue_index);
+ if (!dev_xmit_complete(err))
+ break;
+ } else {
+ break;
+ }
+
+ xdp_return_frame_rx_napi(xdpf);
+ }
+
nxmit++;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [RFC ixgbe 2/2] ixgbe: Fix CPU to ring assignment
2025-10-09 19:28 [RFC ixgbe 0/2] ixgbe: Implement support for ndo_xdp_xmit in skb mode and fix CPU to ring assignment Nabil S. Alramli
2025-10-09 19:28 ` [RFC ixgbe 1/2] ixgbe: Implement support for ndo_xdp_xmit in skb mode Nabil S. Alramli
@ 2025-10-09 19:28 ` Nabil S. Alramli
1 sibling, 0 replies; 6+ messages in thread
From: Nabil S. Alramli @ 2025-10-09 19:28 UTC (permalink / raw)
To: anthony.l.nguyen, przemyslaw.kitszel
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, ast, daniel, hawk,
john.fastabend, lishujin, xingwanli, intel-wired-lan, netdev,
linux-kernel, bpf, team-kernel, khubert, nalramli, dev
The ixgbe driver uses ixgbe_determine_*_ring to determine the CPU mapping
of transmit rings. Those helper functions have a hard-coded number of
rings equal to IXGBE_MAX_XDP_QS, which is set to 64. However, this does
not take into account the number of actual rings configured, which could
be lower. This results in NULL being returned, if the modulus operation
falls into a ring that is not configured. Instead, use the actual number
of configured rings.
Signed-off-by: Nabil S. Alramli <dev@nalramli.com>
Fixes: 4fe815850bdc ("ixgbe: let the xdpdrv work with more than 64 cpus")
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 26c378853755..e2c09545bad1 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -830,18 +830,10 @@ struct ixgbe_adapter {
spinlock_t vfs_lock;
};
-static inline int ixgbe_determine_xdp_q_idx(int cpu)
-{
- if (static_key_enabled(&ixgbe_xdp_locking_key))
- return cpu % IXGBE_MAX_XDP_QS;
- else
- return cpu;
-}
-
static inline
struct ixgbe_ring *ixgbe_determine_xdp_ring(struct ixgbe_adapter *adapter)
{
- int index = ixgbe_determine_xdp_q_idx(smp_processor_id());
+ int index = smp_processor_id() % adapter->num_xdp_queues;
return adapter->xdp_ring[index];
}
@@ -849,7 +841,7 @@ struct ixgbe_ring *ixgbe_determine_xdp_ring(struct ixgbe_adapter *adapter)
static inline
struct ixgbe_ring *ixgbe_determine_tx_ring(struct ixgbe_adapter *adapter)
{
- int index = ixgbe_determine_xdp_q_idx(smp_processor_id());
+ int index = smp_processor_id() % adapter->num_tx_queues;
return adapter->tx_ring[index];
}
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [RFC ixgbe 1/2] ixgbe: Implement support for ndo_xdp_xmit in skb mode
2025-10-09 19:28 ` [RFC ixgbe 1/2] ixgbe: Implement support for ndo_xdp_xmit in skb mode Nabil S. Alramli
@ 2025-11-03 16:38 ` Maciej Fijalkowski
2025-11-03 17:40 ` Nabil S. Alramli
0 siblings, 1 reply; 6+ messages in thread
From: Maciej Fijalkowski @ 2025-11-03 16:38 UTC (permalink / raw)
To: Nabil S. Alramli
Cc: anthony.l.nguyen, przemyslaw.kitszel, andrew+netdev, davem,
edumazet, kuba, pabeni, ast, daniel, hawk, john.fastabend,
lishujin, xingwanli, intel-wired-lan, netdev, linux-kernel, bpf,
team-kernel, khubert, nalramli
On Thu, Oct 09, 2025 at 03:28:30PM -0400, Nabil S. Alramli wrote:
> This commit adds support for `ndo_xdp_xmit` in skb mode in the ixgbe
> ethernet driver, by allowing the call to continue to transmit the packets
> using `dev_direct_xmit`.
>
> Previously, the driver did not support the operation in skb mode. The
> handler `ixgbe_xdp_xmit` had the following condition:
>
> ```
> ring = adapter->xdp_prog ? ixgbe_determine_xdp_ring(adapter) : NULL;
> if (unlikely(!ring))
> return -ENXIO;
> ```
>
> That only works in native mode. In skb mode, `adapter->xdp_prog == NULL` so
> the call returned an error, which prevented the ability to send packets
> using `bpf_prog_test_run_opts` with the `BPF_F_TEST_XDP_LIVE_FRAMES` flag.
Hi Nabil,
What stops you from loading a dummy XDP program to interface? This has
been an approach that we follow when we want to use anything that utilizes
XDP resources (XDP Tx queues).
>
> Signed-off-by: Nabil S. Alramli <dev@nalramli.com>
> ---
> drivers/net/ethernet/intel/ixgbe/ixgbe.h | 8 ++++
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 43 +++++++++++++++++--
> 2 files changed, 47 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> index e6a380d4929b..26c378853755 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> @@ -846,6 +846,14 @@ struct ixgbe_ring *ixgbe_determine_xdp_ring(struct ixgbe_adapter *adapter)
> return adapter->xdp_ring[index];
> }
>
> +static inline
> +struct ixgbe_ring *ixgbe_determine_tx_ring(struct ixgbe_adapter *adapter)
> +{
> + int index = ixgbe_determine_xdp_q_idx(smp_processor_id());
> +
> + return adapter->tx_ring[index];
> +}
> +
> static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter)
> {
> switch (adapter->hw.mac.type) {
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> index 467f81239e12..fed70cbdb1b2 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> @@ -10748,7 +10748,8 @@ static int ixgbe_xdp_xmit(struct net_device *dev, int n,
> /* During program transitions its possible adapter->xdp_prog is assigned
> * but ring has not been configured yet. In this case simply abort xmit.
> */
> - ring = adapter->xdp_prog ? ixgbe_determine_xdp_ring(adapter) : NULL;
> + ring = adapter->xdp_prog ? ixgbe_determine_xdp_ring(adapter) :
> + ixgbe_determine_tx_ring(adapter);
> if (unlikely(!ring))
> return -ENXIO;
>
> @@ -10762,9 +10763,43 @@ static int ixgbe_xdp_xmit(struct net_device *dev, int n,
> struct xdp_frame *xdpf = frames[i];
> int err;
>
> - err = ixgbe_xmit_xdp_ring(ring, xdpf);
> - if (err != IXGBE_XDP_TX)
> - break;
> + if (adapter->xdp_prog) {
> + err = ixgbe_xmit_xdp_ring(ring, xdpf);
> + if (err != IXGBE_XDP_TX)
> + break;
> + } else {
> + struct xdp_buff xdp = {0};
> + unsigned int metasize = 0;
> + unsigned int size = 0;
> + unsigned int truesize = 0;
> + struct sk_buff *skb = NULL;
> +
> + xdp_convert_frame_to_buff(xdpf, &xdp);
> + size = xdp.data_end - xdp.data;
> + metasize = xdp.data - xdp.data_meta;
> + truesize = SKB_DATA_ALIGN(xdp.data_end - xdp.data_hard_start) +
> + SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> +
> + skb = napi_alloc_skb(&ring->q_vector->napi, truesize);
> + if (likely(skb)) {
> + skb_reserve(skb, xdp.data - xdp.data_hard_start);
> + skb_put_data(skb, xdp.data, size);
> + build_skb_around(skb, skb->data, truesize);
> + if (metasize)
> + skb_metadata_set(skb, metasize);
> + skb->dev = dev;
> + skb->queue_mapping = ring->queue_index;
> +
> + err = dev_direct_xmit(skb, ring->queue_index);
> + if (!dev_xmit_complete(err))
> + break;
> + } else {
> + break;
> + }
> +
> + xdp_return_frame_rx_napi(xdpf);
> + }
> +
> nxmit++;
> }
>
> --
> 2.43.0
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC ixgbe 1/2] ixgbe: Implement support for ndo_xdp_xmit in skb mode
2025-11-03 16:38 ` Maciej Fijalkowski
@ 2025-11-03 17:40 ` Nabil S. Alramli
2025-11-03 18:54 ` Maciej Fijalkowski
0 siblings, 1 reply; 6+ messages in thread
From: Nabil S. Alramli @ 2025-11-03 17:40 UTC (permalink / raw)
To: Maciej Fijalkowski
Cc: anthony.l.nguyen, przemyslaw.kitszel, andrew+netdev, davem,
edumazet, kuba, pabeni, ast, daniel, hawk, john.fastabend,
lishujin, xingwanli, intel-wired-lan, netdev, linux-kernel, bpf,
team-kernel, khubert, nalramli
On 11/3/25 11:38, Maciej Fijalkowski wrote:
> On Thu, Oct 09, 2025 at 03:28:30PM -0400, Nabil S. Alramli wrote:
>> This commit adds support for `ndo_xdp_xmit` in skb mode in the ixgbe
>> ethernet driver, by allowing the call to continue to transmit the packets
>> using `dev_direct_xmit`.
>>
>> Previously, the driver did not support the operation in skb mode. The
>> handler `ixgbe_xdp_xmit` had the following condition:
>>
>> ```
>> ring = adapter->xdp_prog ? ixgbe_determine_xdp_ring(adapter) : NULL;
>> if (unlikely(!ring))
>> return -ENXIO;
>> ```
>>
>> That only works in native mode. In skb mode, `adapter->xdp_prog == NULL` so
>> the call returned an error, which prevented the ability to send packets
>> using `bpf_prog_test_run_opts` with the `BPF_F_TEST_XDP_LIVE_FRAMES` flag.
>
> Hi Nabil,
>
> What stops you from loading a dummy XDP program to interface? This has
> been an approach that we follow when we want to use anything that utilizes
> XDP resources (XDP Tx queues).
>
Hi Maciej,
Thank you for your response. In one use case we have multiple XDP programs
already loaded on an interface in SKB mode using the dispatcher, and we want
to use bpf_prog_test_run_opts to egress packets from another XDP program. We
want to avoid having to unload the dispatcher or be forced to use it in native
mode. Without this patch, that does not seem possible currently, correct?
>>
>> Signed-off-by: Nabil S. Alramli <dev@nalramli.com>
>> ---
>> drivers/net/ethernet/intel/ixgbe/ixgbe.h | 8 ++++
>> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 43 +++++++++++++++++--
>> 2 files changed, 47 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
>> index e6a380d4929b..26c378853755 100644
>> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
>> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
>> @@ -846,6 +846,14 @@ struct ixgbe_ring *ixgbe_determine_xdp_ring(struct ixgbe_adapter *adapter)
>> return adapter->xdp_ring[index];
>> }
>>
>> +static inline
>> +struct ixgbe_ring *ixgbe_determine_tx_ring(struct ixgbe_adapter *adapter)
>> +{
>> + int index = ixgbe_determine_xdp_q_idx(smp_processor_id());
>> +
>> + return adapter->tx_ring[index];
>> +}
>> +
>> static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter)
>> {
>> switch (adapter->hw.mac.type) {
>> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
>> index 467f81239e12..fed70cbdb1b2 100644
>> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
>> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
>> @@ -10748,7 +10748,8 @@ static int ixgbe_xdp_xmit(struct net_device *dev, int n,
>> /* During program transitions its possible adapter->xdp_prog is assigned
>> * but ring has not been configured yet. In this case simply abort xmit.
>> */
>> - ring = adapter->xdp_prog ? ixgbe_determine_xdp_ring(adapter) : NULL;
>> + ring = adapter->xdp_prog ? ixgbe_determine_xdp_ring(adapter) :
>> + ixgbe_determine_tx_ring(adapter);
>> if (unlikely(!ring))
>> return -ENXIO;
>>
>> @@ -10762,9 +10763,43 @@ static int ixgbe_xdp_xmit(struct net_device *dev, int n,
>> struct xdp_frame *xdpf = frames[i];
>> int err;
>>
>> - err = ixgbe_xmit_xdp_ring(ring, xdpf);
>> - if (err != IXGBE_XDP_TX)
>> - break;
>> + if (adapter->xdp_prog) {
>> + err = ixgbe_xmit_xdp_ring(ring, xdpf);
>> + if (err != IXGBE_XDP_TX)
>> + break;
>> + } else {
>> + struct xdp_buff xdp = {0};
>> + unsigned int metasize = 0;
>> + unsigned int size = 0;
>> + unsigned int truesize = 0;
>> + struct sk_buff *skb = NULL;
>> +
>> + xdp_convert_frame_to_buff(xdpf, &xdp);
>> + size = xdp.data_end - xdp.data;
>> + metasize = xdp.data - xdp.data_meta;
>> + truesize = SKB_DATA_ALIGN(xdp.data_end - xdp.data_hard_start) +
>> + SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
>> +
>> + skb = napi_alloc_skb(&ring->q_vector->napi, truesize);
>> + if (likely(skb)) {
>> + skb_reserve(skb, xdp.data - xdp.data_hard_start);
>> + skb_put_data(skb, xdp.data, size);
>> + build_skb_around(skb, skb->data, truesize);
>> + if (metasize)
>> + skb_metadata_set(skb, metasize);
>> + skb->dev = dev;
>> + skb->queue_mapping = ring->queue_index;
>> +
>> + err = dev_direct_xmit(skb, ring->queue_index);
>> + if (!dev_xmit_complete(err))
>> + break;
>> + } else {
>> + break;
>> + }
>> +
>> + xdp_return_frame_rx_napi(xdpf);
>> + }
>> +
>> nxmit++;
>> }
>>
>> --
>> 2.43.0
>>
>>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC ixgbe 1/2] ixgbe: Implement support for ndo_xdp_xmit in skb mode
2025-11-03 17:40 ` Nabil S. Alramli
@ 2025-11-03 18:54 ` Maciej Fijalkowski
0 siblings, 0 replies; 6+ messages in thread
From: Maciej Fijalkowski @ 2025-11-03 18:54 UTC (permalink / raw)
To: Nabil S. Alramli
Cc: anthony.l.nguyen, przemyslaw.kitszel, andrew+netdev, davem,
edumazet, kuba, pabeni, ast, daniel, hawk, john.fastabend,
lishujin, xingwanli, intel-wired-lan, netdev, linux-kernel, bpf,
team-kernel, khubert, nalramli
On Mon, Nov 03, 2025 at 12:40:14PM -0500, Nabil S. Alramli wrote:
> On 11/3/25 11:38, Maciej Fijalkowski wrote:
> > On Thu, Oct 09, 2025 at 03:28:30PM -0400, Nabil S. Alramli wrote:
> >> This commit adds support for `ndo_xdp_xmit` in skb mode in the ixgbe
> >> ethernet driver, by allowing the call to continue to transmit the packets
> >> using `dev_direct_xmit`.
> >>
> >> Previously, the driver did not support the operation in skb mode. The
> >> handler `ixgbe_xdp_xmit` had the following condition:
> >>
> >> ```
> >> ring = adapter->xdp_prog ? ixgbe_determine_xdp_ring(adapter) : NULL;
> >> if (unlikely(!ring))
> >> return -ENXIO;
> >> ```
> >>
> >> That only works in native mode. In skb mode, `adapter->xdp_prog == NULL` so
> >> the call returned an error, which prevented the ability to send packets
> >> using `bpf_prog_test_run_opts` with the `BPF_F_TEST_XDP_LIVE_FRAMES` flag.
> >
> > Hi Nabil,
> >
> > What stops you from loading a dummy XDP program to interface? This has
> > been an approach that we follow when we want to use anything that utilizes
> > XDP resources (XDP Tx queues).
> >
>
> Hi Maciej,
>
> Thank you for your response. In one use case we have multiple XDP programs
> already loaded on an interface in SKB mode using the dispatcher, and we want
> to use bpf_prog_test_run_opts to egress packets from another XDP program. We
> want to avoid having to unload the dispatcher or be forced to use it in native
> mode. Without this patch, that does not seem possible currently, correct?
Why does it have to be bpf_prog_test_run_opts?
You're trying to use an interface which was designed for native XDP from a
different layer. Generic XDP has support for redirect and tx.
>
> >>
> >> Signed-off-by: Nabil S. Alramli <dev@nalramli.com>
> >> ---
> >> drivers/net/ethernet/intel/ixgbe/ixgbe.h | 8 ++++
> >> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 43 +++++++++++++++++--
> >> 2 files changed, 47 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> >> index e6a380d4929b..26c378853755 100644
> >> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> >> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> >> @@ -846,6 +846,14 @@ struct ixgbe_ring *ixgbe_determine_xdp_ring(struct ixgbe_adapter *adapter)
> >> return adapter->xdp_ring[index];
> >> }
> >>
> >> +static inline
> >> +struct ixgbe_ring *ixgbe_determine_tx_ring(struct ixgbe_adapter *adapter)
> >> +{
> >> + int index = ixgbe_determine_xdp_q_idx(smp_processor_id());
> >> +
> >> + return adapter->tx_ring[index];
> >> +}
> >> +
> >> static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter)
> >> {
> >> switch (adapter->hw.mac.type) {
> >> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> >> index 467f81239e12..fed70cbdb1b2 100644
> >> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> >> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> >> @@ -10748,7 +10748,8 @@ static int ixgbe_xdp_xmit(struct net_device *dev, int n,
> >> /* During program transitions its possible adapter->xdp_prog is assigned
> >> * but ring has not been configured yet. In this case simply abort xmit.
> >> */
> >> - ring = adapter->xdp_prog ? ixgbe_determine_xdp_ring(adapter) : NULL;
> >> + ring = adapter->xdp_prog ? ixgbe_determine_xdp_ring(adapter) :
> >> + ixgbe_determine_tx_ring(adapter);
> >> if (unlikely(!ring))
> >> return -ENXIO;
> >>
> >> @@ -10762,9 +10763,43 @@ static int ixgbe_xdp_xmit(struct net_device *dev, int n,
> >> struct xdp_frame *xdpf = frames[i];
> >> int err;
> >>
> >> - err = ixgbe_xmit_xdp_ring(ring, xdpf);
> >> - if (err != IXGBE_XDP_TX)
> >> - break;
> >> + if (adapter->xdp_prog) {
> >> + err = ixgbe_xmit_xdp_ring(ring, xdpf);
> >> + if (err != IXGBE_XDP_TX)
> >> + break;
> >> + } else {
> >> + struct xdp_buff xdp = {0};
> >> + unsigned int metasize = 0;
> >> + unsigned int size = 0;
> >> + unsigned int truesize = 0;
> >> + struct sk_buff *skb = NULL;
> >> +
> >> + xdp_convert_frame_to_buff(xdpf, &xdp);
> >> + size = xdp.data_end - xdp.data;
> >> + metasize = xdp.data - xdp.data_meta;
> >> + truesize = SKB_DATA_ALIGN(xdp.data_end - xdp.data_hard_start) +
> >> + SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> >> +
> >> + skb = napi_alloc_skb(&ring->q_vector->napi, truesize);
> >> + if (likely(skb)) {
> >> + skb_reserve(skb, xdp.data - xdp.data_hard_start);
> >> + skb_put_data(skb, xdp.data, size);
> >> + build_skb_around(skb, skb->data, truesize);
> >> + if (metasize)
> >> + skb_metadata_set(skb, metasize);
> >> + skb->dev = dev;
> >> + skb->queue_mapping = ring->queue_index;
> >> +
> >> + err = dev_direct_xmit(skb, ring->queue_index);
> >> + if (!dev_xmit_complete(err))
> >> + break;
> >> + } else {
> >> + break;
> >> + }
> >> +
> >> + xdp_return_frame_rx_napi(xdpf);
> >> + }
> >> +
> >> nxmit++;
> >> }
> >>
> >> --
> >> 2.43.0
> >>
> >>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-11-03 18:55 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-09 19:28 [RFC ixgbe 0/2] ixgbe: Implement support for ndo_xdp_xmit in skb mode and fix CPU to ring assignment Nabil S. Alramli
2025-10-09 19:28 ` [RFC ixgbe 1/2] ixgbe: Implement support for ndo_xdp_xmit in skb mode Nabil S. Alramli
2025-11-03 16:38 ` Maciej Fijalkowski
2025-11-03 17:40 ` Nabil S. Alramli
2025-11-03 18:54 ` Maciej Fijalkowski
2025-10-09 19:28 ` [RFC ixgbe 2/2] ixgbe: Fix CPU to ring assignment Nabil S. Alramli
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).