* [PATCH V2 net 0/4] net: fec: fix some issues of ndo_xdp_xmit()
@ 2023-07-06 8:10 wei.fang
2023-07-06 8:10 ` [PATCH V2 net 1/4] net: fec: dynamically set the NETDEV_XDP_ACT_NDO_XMIT feature of XDP wei.fang
` (5 more replies)
0 siblings, 6 replies; 10+ messages in thread
From: wei.fang @ 2023-07-06 8:10 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, ast, daniel, hawk, john.fastabend,
shenwei.wang, xiaoning.wang, netdev
Cc: linux-imx, linux-kernel, bpf
From: Wei Fang <wei.fang@nxp.com>
We encountered some issues when testing the ndo_xdp_xmit() interface
of the fec driver on i.MX8MP and i.MX93 platforms. These issues are
easy to reproduce, and the specific reproduction steps are as follows.
step1: The ethernet port of a board (board A) is connected to the EQOS
port of i.MX8MP/i.MX93, and the FEC port of i.MX8MP/i.MX93 is connected
to another ethernet port, such as a switch port.
step2: Board A uses the pktgen_sample03_burst_single_flow.sh to generate
and send packets to i.MX8MP/i.MX93. The command is shown below.
./pktgen_sample03_burst_single_flow.sh -i eth0 -d 192.168.6.8 -m \
56:bf:0d:68:b0:9e -s 1500
step3: i.MX8MP/i.MX93 use the xdp_redirect bfp program to redirect the
XDP frames from EQOS port to FEC port. The command is shown below.
./xdp_redirect eth1 eth0
After a few moments, the warning or error logs will be printed in the
console, for more details, please refer to the commit message of each
patch.
Wei Fang (4):
net: fec: dynamically set the NETDEV_XDP_ACT_NDO_XMIT feature of XDP
net: fec: recycle pages for transmitted XDP frames
net: fec: increase the size of tx ring and update tx_wake_threshold
net: fec: use netdev_err_once() instead of netdev_err()
drivers/net/ethernet/freescale/fec.h | 17 ++-
drivers/net/ethernet/freescale/fec_main.c | 166 +++++++++++++++-------
2 files changed, 127 insertions(+), 56 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH V2 net 1/4] net: fec: dynamically set the NETDEV_XDP_ACT_NDO_XMIT feature of XDP
2023-07-06 8:10 [PATCH V2 net 0/4] net: fec: fix some issues of ndo_xdp_xmit() wei.fang
@ 2023-07-06 8:10 ` wei.fang
2023-07-06 8:10 ` [PATCH V2 net 2/4] net: fec: recycle pages for transmitted XDP frames wei.fang
` (4 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: wei.fang @ 2023-07-06 8:10 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, ast, daniel, hawk, john.fastabend,
shenwei.wang, xiaoning.wang, netdev
Cc: linux-imx, linux-kernel, bpf
From: Wei Fang <wei.fang@nxp.com>
When a XDP program is installed or uninstalled, fec_restart() will
be invoked to reset MAC and buffer descriptor rings. It's reasonable
not to transmit any packet during the process of reset. However, the
NETDEV_XDP_ACT_NDO_XMIT bit of xdp_features is enabled by default,
that is to say, it's possible that the fec_enet_xdp_xmit() will be
invoked even if the process of reset is not finished. In this case,
the redirected XDP frames might be dropped and available transmit BDs
may be incorrectly deemed insufficient. So this patch disable the
NETDEV_XDP_ACT_NDO_XMIT feature by default and dynamically configure
this feature when the bpf program is installed or uninstalled.
Fixes: e4ac7cc6e5a4 ("net: fec: turn on XDP features")
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
V2 change:
No change.
---
drivers/net/ethernet/freescale/fec_main.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 8fbe47703d47..9ce0319b33c3 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -3732,12 +3732,18 @@ static int fec_enet_bpf(struct net_device *dev, struct netdev_bpf *bpf)
if (fep->quirks & FEC_QUIRK_SWAP_FRAME)
return -EOPNOTSUPP;
+ if (!bpf->prog)
+ xdp_features_clear_redirect_target(dev);
+
if (is_run) {
napi_disable(&fep->napi);
netif_tx_disable(dev);
}
old_prog = xchg(&fep->xdp_prog, bpf->prog);
+ if (old_prog)
+ bpf_prog_put(old_prog);
+
fec_restart(dev);
if (is_run) {
@@ -3745,8 +3751,8 @@ static int fec_enet_bpf(struct net_device *dev, struct netdev_bpf *bpf)
netif_tx_start_all_queues(dev);
}
- if (old_prog)
- bpf_prog_put(old_prog);
+ if (bpf->prog)
+ xdp_features_set_redirect_target(dev, false);
return 0;
@@ -4016,8 +4022,7 @@ static int fec_enet_init(struct net_device *ndev)
if (!(fep->quirks & FEC_QUIRK_SWAP_FRAME))
ndev->xdp_features = NETDEV_XDP_ACT_BASIC |
- NETDEV_XDP_ACT_REDIRECT |
- NETDEV_XDP_ACT_NDO_XMIT;
+ NETDEV_XDP_ACT_REDIRECT;
fec_restart(ndev);
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH V2 net 2/4] net: fec: recycle pages for transmitted XDP frames
2023-07-06 8:10 [PATCH V2 net 0/4] net: fec: fix some issues of ndo_xdp_xmit() wei.fang
2023-07-06 8:10 ` [PATCH V2 net 1/4] net: fec: dynamically set the NETDEV_XDP_ACT_NDO_XMIT feature of XDP wei.fang
@ 2023-07-06 8:10 ` wei.fang
2023-07-06 11:59 ` Alexander Lobakin
2023-07-06 8:10 ` [PATCH V2 net 3/4] net: fec: increase the size of tx ring and update tx_wake_threshold wei.fang
` (3 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: wei.fang @ 2023-07-06 8:10 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, ast, daniel, hawk, john.fastabend,
shenwei.wang, xiaoning.wang, netdev
Cc: linux-imx, linux-kernel, bpf
From: Wei Fang <wei.fang@nxp.com>
Once the XDP frames have been successfully transmitted through the
ndo_xdp_xmit() interface, it's the driver responsibility to free
the frames so that the page_pool can recycle the pages and reuse
them. However, this action is not implemented in the fec driver.
This leads to a user-visible problem that the console will print
the following warning log.
[ 157.568851] page_pool_release_retry() stalled pool shutdown 1389 inflight 60 sec
[ 217.983446] page_pool_release_retry() stalled pool shutdown 1389 inflight 120 sec
[ 278.399006] page_pool_release_retry() stalled pool shutdown 1389 inflight 181 sec
[ 338.812885] page_pool_release_retry() stalled pool shutdown 1389 inflight 241 sec
[ 399.226946] page_pool_release_retry() stalled pool shutdown 1389 inflight 302 sec
Therefore, to solve this issue, we free XDP frames via xdp_return_frame()
while cleaning the tx BD ring.
Fixes: 6d6b39f180b8 ("net: fec: add initial XDP support")
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
V2 change:
No change.
---
drivers/net/ethernet/freescale/fec.h | 15 ++-
drivers/net/ethernet/freescale/fec_main.c | 148 +++++++++++++++-------
2 files changed, 115 insertions(+), 48 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 9939ccafb556..8c0226d061fe 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -544,10 +544,23 @@ enum {
XDP_STATS_TOTAL,
};
+enum fec_txbuf_type {
+ FEC_TXBUF_T_SKB,
+ FEC_TXBUF_T_XDP_NDO,
+};
+
+struct fec_tx_buffer {
+ union {
+ struct sk_buff *skb;
+ struct xdp_frame *xdp;
+ };
+ enum fec_txbuf_type type;
+};
+
struct fec_enet_priv_tx_q {
struct bufdesc_prop bd;
unsigned char *tx_bounce[TX_RING_SIZE];
- struct sk_buff *tx_skbuff[TX_RING_SIZE];
+ struct fec_tx_buffer tx_buf[TX_RING_SIZE];
unsigned short tx_stop_threshold;
unsigned short tx_wake_threshold;
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 9ce0319b33c3..940d3afe1d24 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -397,7 +397,7 @@ static void fec_dump(struct net_device *ndev)
fec16_to_cpu(bdp->cbd_sc),
fec32_to_cpu(bdp->cbd_bufaddr),
fec16_to_cpu(bdp->cbd_datlen),
- txq->tx_skbuff[index]);
+ txq->tx_buf[index].skb);
bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
index++;
} while (bdp != txq->bd.base);
@@ -654,7 +654,7 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
index = fec_enet_get_bd_index(last_bdp, &txq->bd);
/* Save skb pointer */
- txq->tx_skbuff[index] = skb;
+ txq->tx_buf[index].skb = skb;
/* Make sure the updates to rest of the descriptor are performed before
* transferring ownership.
@@ -672,9 +672,7 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
skb_tx_timestamp(skb);
- /* Make sure the update to bdp and tx_skbuff are performed before
- * txq->bd.cur.
- */
+ /* Make sure the update to bdp is performed before txq->bd.cur. */
wmb();
txq->bd.cur = bdp;
@@ -862,7 +860,7 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq,
}
/* Save skb pointer */
- txq->tx_skbuff[index] = skb;
+ txq->tx_buf[index].skb = skb;
skb_tx_timestamp(skb);
txq->bd.cur = bdp;
@@ -952,16 +950,33 @@ static void fec_enet_bd_init(struct net_device *dev)
for (i = 0; i < txq->bd.ring_size; i++) {
/* Initialize the BD for every fragment in the page. */
bdp->cbd_sc = cpu_to_fec16(0);
- if (bdp->cbd_bufaddr &&
- !IS_TSO_HEADER(txq, fec32_to_cpu(bdp->cbd_bufaddr)))
- dma_unmap_single(&fep->pdev->dev,
- fec32_to_cpu(bdp->cbd_bufaddr),
- fec16_to_cpu(bdp->cbd_datlen),
- DMA_TO_DEVICE);
- if (txq->tx_skbuff[i]) {
- dev_kfree_skb_any(txq->tx_skbuff[i]);
- txq->tx_skbuff[i] = NULL;
+ if (txq->tx_buf[i].type == FEC_TXBUF_T_SKB) {
+ if (bdp->cbd_bufaddr &&
+ !IS_TSO_HEADER(txq, fec32_to_cpu(bdp->cbd_bufaddr)))
+ dma_unmap_single(&fep->pdev->dev,
+ fec32_to_cpu(bdp->cbd_bufaddr),
+ fec16_to_cpu(bdp->cbd_datlen),
+ DMA_TO_DEVICE);
+ if (txq->tx_buf[i].skb) {
+ dev_kfree_skb_any(txq->tx_buf[i].skb);
+ txq->tx_buf[i].skb = NULL;
+ }
+ } else {
+ if (bdp->cbd_bufaddr)
+ dma_unmap_single(&fep->pdev->dev,
+ fec32_to_cpu(bdp->cbd_bufaddr),
+ fec16_to_cpu(bdp->cbd_datlen),
+ DMA_TO_DEVICE);
+
+ if (txq->tx_buf[i].xdp) {
+ xdp_return_frame(txq->tx_buf[i].xdp);
+ txq->tx_buf[i].xdp = NULL;
+ }
+
+ /* restore default tx buffer type: FEC_TXBUF_T_SKB */
+ txq->tx_buf[i].type = FEC_TXBUF_T_SKB;
}
+
bdp->cbd_bufaddr = cpu_to_fec32(0);
bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
}
@@ -1360,6 +1375,7 @@ static void
fec_enet_tx_queue(struct net_device *ndev, u16 queue_id)
{
struct fec_enet_private *fep;
+ struct xdp_frame *xdpf;
struct bufdesc *bdp;
unsigned short status;
struct sk_buff *skb;
@@ -1387,16 +1403,31 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id)
index = fec_enet_get_bd_index(bdp, &txq->bd);
- skb = txq->tx_skbuff[index];
- txq->tx_skbuff[index] = NULL;
- if (!IS_TSO_HEADER(txq, fec32_to_cpu(bdp->cbd_bufaddr)))
- dma_unmap_single(&fep->pdev->dev,
- fec32_to_cpu(bdp->cbd_bufaddr),
- fec16_to_cpu(bdp->cbd_datlen),
- DMA_TO_DEVICE);
- bdp->cbd_bufaddr = cpu_to_fec32(0);
- if (!skb)
- goto skb_done;
+ if (txq->tx_buf[index].type == FEC_TXBUF_T_SKB) {
+ skb = txq->tx_buf[index].skb;
+ txq->tx_buf[index].skb = NULL;
+ if (bdp->cbd_bufaddr &&
+ !IS_TSO_HEADER(txq, fec32_to_cpu(bdp->cbd_bufaddr)))
+ dma_unmap_single(&fep->pdev->dev,
+ fec32_to_cpu(bdp->cbd_bufaddr),
+ fec16_to_cpu(bdp->cbd_datlen),
+ DMA_TO_DEVICE);
+ bdp->cbd_bufaddr = cpu_to_fec32(0);
+ if (!skb)
+ goto tx_buf_done;
+ } else {
+ xdpf = txq->tx_buf[index].xdp;
+ if (bdp->cbd_bufaddr)
+ dma_unmap_single(&fep->pdev->dev,
+ fec32_to_cpu(bdp->cbd_bufaddr),
+ fec16_to_cpu(bdp->cbd_datlen),
+ DMA_TO_DEVICE);
+ bdp->cbd_bufaddr = cpu_to_fec32(0);
+ if (!xdpf) {
+ txq->tx_buf[index].type = FEC_TXBUF_T_SKB;
+ goto tx_buf_done;
+ }
+ }
/* Check for errors. */
if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC |
@@ -1415,21 +1446,11 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id)
ndev->stats.tx_carrier_errors++;
} else {
ndev->stats.tx_packets++;
- ndev->stats.tx_bytes += skb->len;
- }
- /* NOTE: SKBTX_IN_PROGRESS being set does not imply it's we who
- * are to time stamp the packet, so we still need to check time
- * stamping enabled flag.
- */
- if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS &&
- fep->hwts_tx_en) &&
- fep->bufdesc_ex) {
- struct skb_shared_hwtstamps shhwtstamps;
- struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
-
- fec_enet_hwtstamp(fep, fec32_to_cpu(ebdp->ts), &shhwtstamps);
- skb_tstamp_tx(skb, &shhwtstamps);
+ if (txq->tx_buf[index].type == FEC_TXBUF_T_SKB)
+ ndev->stats.tx_bytes += skb->len;
+ else
+ ndev->stats.tx_bytes += xdpf->len;
}
/* Deferred means some collisions occurred during transmit,
@@ -1438,10 +1459,32 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id)
if (status & BD_ENET_TX_DEF)
ndev->stats.collisions++;
- /* Free the sk buffer associated with this last transmit */
- dev_kfree_skb_any(skb);
-skb_done:
- /* Make sure the update to bdp and tx_skbuff are performed
+ if (txq->tx_buf[index].type == FEC_TXBUF_T_SKB) {
+ /* NOTE: SKBTX_IN_PROGRESS being set does not imply it's we who
+ * are to time stamp the packet, so we still need to check time
+ * stamping enabled flag.
+ */
+ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS &&
+ fep->hwts_tx_en) && fep->bufdesc_ex) {
+ struct skb_shared_hwtstamps shhwtstamps;
+ struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
+
+ fec_enet_hwtstamp(fep, fec32_to_cpu(ebdp->ts), &shhwtstamps);
+ skb_tstamp_tx(skb, &shhwtstamps);
+ }
+
+ /* Free the sk buffer associated with this last transmit */
+ dev_kfree_skb_any(skb);
+ } else {
+ xdp_return_frame(xdpf);
+
+ txq->tx_buf[index].xdp = NULL;
+ /* restore default tx buffer type: FEC_TXBUF_T_SKB */
+ txq->tx_buf[index].type = FEC_TXBUF_T_SKB;
+ }
+
+tx_buf_done:
+ /* Make sure the update to bdp and tx_buf are performed
* before dirty_tx
*/
wmb();
@@ -3249,9 +3292,19 @@ static void fec_enet_free_buffers(struct net_device *ndev)
for (i = 0; i < txq->bd.ring_size; i++) {
kfree(txq->tx_bounce[i]);
txq->tx_bounce[i] = NULL;
- skb = txq->tx_skbuff[i];
- txq->tx_skbuff[i] = NULL;
- dev_kfree_skb(skb);
+
+ if (txq->tx_buf[i].type == FEC_TXBUF_T_SKB) {
+ skb = txq->tx_buf[i].skb;
+ txq->tx_buf[i].skb = NULL;
+ dev_kfree_skb(skb);
+ } else {
+ if (txq->tx_buf[i].xdp) {
+ xdp_return_frame(txq->tx_buf[i].xdp);
+ txq->tx_buf[i].xdp = NULL;
+ }
+
+ txq->tx_buf[i].type = FEC_TXBUF_T_SKB;
+ }
}
}
}
@@ -3817,7 +3870,8 @@ static int fec_enet_txq_xmit_frame(struct fec_enet_private *fep,
ebdp->cbd_esc = cpu_to_fec32(estatus);
}
- txq->tx_skbuff[index] = NULL;
+ txq->tx_buf[index].type = FEC_TXBUF_T_XDP_NDO;
+ txq->tx_buf[index].xdp = frame;
/* Make sure the updates to rest of the descriptor are performed before
* transferring ownership.
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH V2 net 3/4] net: fec: increase the size of tx ring and update tx_wake_threshold
2023-07-06 8:10 [PATCH V2 net 0/4] net: fec: fix some issues of ndo_xdp_xmit() wei.fang
2023-07-06 8:10 ` [PATCH V2 net 1/4] net: fec: dynamically set the NETDEV_XDP_ACT_NDO_XMIT feature of XDP wei.fang
2023-07-06 8:10 ` [PATCH V2 net 2/4] net: fec: recycle pages for transmitted XDP frames wei.fang
@ 2023-07-06 8:10 ` wei.fang
2023-07-06 8:10 ` [PATCH V2 net 4/4] net: fec: use netdev_err_once() instead of netdev_err() wei.fang
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: wei.fang @ 2023-07-06 8:10 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, ast, daniel, hawk, john.fastabend,
shenwei.wang, xiaoning.wang, netdev
Cc: linux-imx, linux-kernel, bpf
From: Wei Fang <wei.fang@nxp.com>
When the XDP feature is enabled and with heavy XDP frames to be
transmitted, there is a considerable probability that available
tx BDs are insufficient. This will lead to some XDP frames to be
discarded and the "NOT enough BD for SG!" error log will appear
in the console (as shown below).
[ 160.013112] fec 30be0000.ethernet eth0: NOT enough BD for SG!
[ 160.023116] fec 30be0000.ethernet eth0: NOT enough BD for SG!
[ 160.028926] fec 30be0000.ethernet eth0: NOT enough BD for SG!
[ 160.038946] fec 30be0000.ethernet eth0: NOT enough BD for SG!
[ 160.044758] fec 30be0000.ethernet eth0: NOT enough BD for SG!
In the case of heavy XDP traffic, sometimes the speed of recycling
tx BDs may be slower than the speed of sending XDP frames. There
may be several specific reasons, such as the interrupt is not
responsed in time, the efficiency of the NAPI callback function is
too low due to all the queues (tx queues and rx queues) share the
same NAPI, and so on.
After trying various methods, I think that increase the size of tx
BD ring is simple and effective. Maybe the best resolution is that
allocate NAPI for each queue to improve the efficiency of the NAPI
callback, but this change is a bit big and I didn't try this method.
Perheps this method will be implemented in a future patch.
This patch also updates the tx_wake_threshold of tx ring which is
related to the size of tx ring in the previous logic. Otherwise,
the tx_wake_threshold will be too high (403 BDs), which is more
likely to impact the slow path in the case of heavy XDP traffic,
because XDP path and slow path share the tx BD rings. According
to Jakub's suggestion, the tx_wake_threshold is at least equal to
tx_stop_threshold + 2 * MAX_SKB_FRAGS, if a queue of hundreds of
entries is overflowing, we should be able to apply a hysteresis
of a few tens of entries.
Fixes: 6d6b39f180b8 ("net: fec: add initial XDP support")
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
V2 change:
1. Keep the tx_stop_threshold unchanged and change the
tx_wake_threshold to tx_stop_threshold + 2 * MAX_SKB_FRAGS.
2. Split the change, the netdev_err_once() is moved to a
separate patch.
3. Modify the commit message and subject ppropriately.
---
drivers/net/ethernet/freescale/fec.h | 2 +-
drivers/net/ethernet/freescale/fec_main.c | 3 +--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 8c0226d061fe..63a053dea819 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -355,7 +355,7 @@ struct bufdesc_ex {
#define RX_RING_SIZE (FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES)
#define FEC_ENET_TX_FRSIZE 2048
#define FEC_ENET_TX_FRPPG (PAGE_SIZE / FEC_ENET_TX_FRSIZE)
-#define TX_RING_SIZE 512 /* Must be power of two */
+#define TX_RING_SIZE 1024 /* Must be power of two */
#define TX_RING_MOD_MASK 511 /* for this to work */
#define BD_ENET_RX_INT 0x00800000
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 940d3afe1d24..c59576ab8c7a 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -3349,8 +3349,7 @@ static int fec_enet_alloc_queue(struct net_device *ndev)
fep->total_tx_ring_size += fep->tx_queue[i]->bd.ring_size;
txq->tx_stop_threshold = FEC_MAX_SKB_DESCS;
- txq->tx_wake_threshold =
- (txq->bd.ring_size - txq->tx_stop_threshold) / 2;
+ txq->tx_wake_threshold = FEC_MAX_SKB_DESCS + 2 * MAX_SKB_FRAGS;
txq->tso_hdrs = dma_alloc_coherent(&fep->pdev->dev,
txq->bd.ring_size * TSO_HEADER_SIZE,
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH V2 net 4/4] net: fec: use netdev_err_once() instead of netdev_err()
2023-07-06 8:10 [PATCH V2 net 0/4] net: fec: fix some issues of ndo_xdp_xmit() wei.fang
` (2 preceding siblings ...)
2023-07-06 8:10 ` [PATCH V2 net 3/4] net: fec: increase the size of tx ring and update tx_wake_threshold wei.fang
@ 2023-07-06 8:10 ` wei.fang
2023-07-06 11:51 ` [PATCH V2 net 0/4] net: fec: fix some issues of ndo_xdp_xmit() Alexander Lobakin
2023-07-11 8:50 ` patchwork-bot+netdevbpf
5 siblings, 0 replies; 10+ messages in thread
From: wei.fang @ 2023-07-06 8:10 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, ast, daniel, hawk, john.fastabend,
shenwei.wang, xiaoning.wang, netdev
Cc: linux-imx, linux-kernel, bpf
From: Wei Fang <wei.fang@nxp.com>
In the case of heavy XDP traffic to be transmitted, the console
will print the error log continuously if there are lack of enough
BDs to accommodate the frames. The log looks like below.
[ 160.013112] fec 30be0000.ethernet eth0: NOT enough BD for SG!
[ 160.023116] fec 30be0000.ethernet eth0: NOT enough BD for SG!
[ 160.028926] fec 30be0000.ethernet eth0: NOT enough BD for SG!
[ 160.038946] fec 30be0000.ethernet eth0: NOT enough BD for SG!
[ 160.044758] fec 30be0000.ethernet eth0: NOT enough BD for SG!
Not only will this log be replicated and redundant, it will also
degrade XDP performance. So we use netdev_err_once() instead of
netdev_err() now.
Fixes: 6d6b39f180b8 ("net: fec: add initial XDP support")
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
V2 change:
This is a new patch which is separated from the patch 3.
---
drivers/net/ethernet/freescale/fec_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index c59576ab8c7a..ec9e4bdb0c06 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -3836,7 +3836,7 @@ static int fec_enet_txq_xmit_frame(struct fec_enet_private *fep,
entries_free = fec_enet_get_free_txdesc_num(txq);
if (entries_free < MAX_SKB_FRAGS + 1) {
- netdev_err(fep->netdev, "NOT enough BD for SG!\n");
+ netdev_err_once(fep->netdev, "NOT enough BD for SG!\n");
return -EBUSY;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH V2 net 0/4] net: fec: fix some issues of ndo_xdp_xmit()
2023-07-06 8:10 [PATCH V2 net 0/4] net: fec: fix some issues of ndo_xdp_xmit() wei.fang
` (3 preceding siblings ...)
2023-07-06 8:10 ` [PATCH V2 net 4/4] net: fec: use netdev_err_once() instead of netdev_err() wei.fang
@ 2023-07-06 11:51 ` Alexander Lobakin
2023-07-11 8:50 ` patchwork-bot+netdevbpf
5 siblings, 0 replies; 10+ messages in thread
From: Alexander Lobakin @ 2023-07-06 11:51 UTC (permalink / raw)
To: wei.fang
Cc: davem, edumazet, kuba, pabeni, ast, daniel, hawk, john.fastabend,
shenwei.wang, xiaoning.wang, netdev, linux-imx, linux-kernel, bpf
From: Wei Fang <wei.fang@nxp.com>
Date: Thu, 6 Jul 2023 16:10:08 +0800
> From: Wei Fang <wei.fang@nxp.com>
Please sync your Git commit author settings wrt Git email settings, so
that there wouldn't be "From:" for your own commits.
>
> We encountered some issues when testing the ndo_xdp_xmit() interface
> of the fec driver on i.MX8MP and i.MX93 platforms. These issues are
> easy to reproduce, and the specific reproduction steps are as follows.
>
> step1: The ethernet port of a board (board A) is connected to the EQOS
> port of i.MX8MP/i.MX93, and the FEC port of i.MX8MP/i.MX93 is connected
> to another ethernet port, such as a switch port.
>
> step2: Board A uses the pktgen_sample03_burst_single_flow.sh to generate
> and send packets to i.MX8MP/i.MX93. The command is shown below.
> ./pktgen_sample03_burst_single_flow.sh -i eth0 -d 192.168.6.8 -m \
> 56:bf:0d:68:b0:9e -s 1500
>
> step3: i.MX8MP/i.MX93 use the xdp_redirect bfp program to redirect the
> XDP frames from EQOS port to FEC port. The command is shown below.
> ./xdp_redirect eth1 eth0
>
> After a few moments, the warning or error logs will be printed in the
> console, for more details, please refer to the commit message of each
> patch.
>
> Wei Fang (4):
> net: fec: dynamically set the NETDEV_XDP_ACT_NDO_XMIT feature of XDP
> net: fec: recycle pages for transmitted XDP frames
> net: fec: increase the size of tx ring and update tx_wake_threshold
> net: fec: use netdev_err_once() instead of netdev_err()
>
> drivers/net/ethernet/freescale/fec.h | 17 ++-
> drivers/net/ethernet/freescale/fec_main.c | 166 +++++++++++++++-------
> 2 files changed, 127 insertions(+), 56 deletions(-)
Thanks,
Olek
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH V2 net 2/4] net: fec: recycle pages for transmitted XDP frames
2023-07-06 8:10 ` [PATCH V2 net 2/4] net: fec: recycle pages for transmitted XDP frames wei.fang
@ 2023-07-06 11:59 ` Alexander Lobakin
2023-07-07 1:54 ` Wei Fang
0 siblings, 1 reply; 10+ messages in thread
From: Alexander Lobakin @ 2023-07-06 11:59 UTC (permalink / raw)
To: wei.fang
Cc: davem, edumazet, kuba, pabeni, ast, daniel, hawk, john.fastabend,
shenwei.wang, xiaoning.wang, netdev, linux-imx, linux-kernel, bpf
From: Wei Fang <wei.fang@nxp.com>
Date: Thu, 6 Jul 2023 16:10:10 +0800
> From: Wei Fang <wei.fang@nxp.com>
>
> Once the XDP frames have been successfully transmitted through the
> ndo_xdp_xmit() interface, it's the driver responsibility to free
> the frames so that the page_pool can recycle the pages and reuse
> them. However, this action is not implemented in the fec driver.
> This leads to a user-visible problem that the console will print
> the following warning log.
[...]
> + if (txq->tx_buf[i].xdp) {
> + xdp_return_frame(txq->tx_buf[i].xdp);
> + txq->tx_buf[i].xdp = NULL;
> + }
> +
> + /* restore default tx buffer type: FEC_TXBUF_T_SKB */
> + txq->tx_buf[i].type = FEC_TXBUF_T_SKB;
Here and in the related places below: maybe set ::type dynamically when
sending to either SKB or XDP instead of setting it only for XDP and then
restoring each time?
> }
> +
> bdp->cbd_bufaddr = cpu_to_fec32(0);
> bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
> }
[...]
Thanks,
Olek
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [PATCH V2 net 2/4] net: fec: recycle pages for transmitted XDP frames
2023-07-06 11:59 ` Alexander Lobakin
@ 2023-07-07 1:54 ` Wei Fang
2023-07-10 12:58 ` Alexander Lobakin
0 siblings, 1 reply; 10+ messages in thread
From: Wei Fang @ 2023-07-07 1:54 UTC (permalink / raw)
To: Alexander Lobakin
Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, ast@kernel.org, daniel@iogearbox.net,
hawk@kernel.org, john.fastabend@gmail.com, Shenwei Wang,
Clark Wang, netdev@vger.kernel.org, dl-linux-imx,
linux-kernel@vger.kernel.org, bpf@vger.kernel.org
> -----Original Message-----
> From: Alexander Lobakin <aleksander.lobakin@intel.com>
> Sent: 2023年7月6日 19:59
> To: Wei Fang <wei.fang@nxp.com>
> Cc: davem@davemloft.net; edumazet@google.com; kuba@kernel.org;
> pabeni@redhat.com; ast@kernel.org; daniel@iogearbox.net;
> hawk@kernel.org; john.fastabend@gmail.com; Shenwei Wang
> <shenwei.wang@nxp.com>; Clark Wang <xiaoning.wang@nxp.com>;
> netdev@vger.kernel.org; dl-linux-imx <linux-imx@nxp.com>;
> linux-kernel@vger.kernel.org; bpf@vger.kernel.org
> Subject: Re: [PATCH V2 net 2/4] net: fec: recycle pages for transmitted XDP
> frames
>
> From: Wei Fang <wei.fang@nxp.com>
> Date: Thu, 6 Jul 2023 16:10:10 +0800
>
> > From: Wei Fang <wei.fang@nxp.com>
> >
> > Once the XDP frames have been successfully transmitted through the
> > ndo_xdp_xmit() interface, it's the driver responsibility to free the
> > frames so that the page_pool can recycle the pages and reuse them.
> > However, this action is not implemented in the fec driver.
> > This leads to a user-visible problem that the console will print the
> > following warning log.
>
> [...]
>
> > + if (txq->tx_buf[i].xdp) {
> > + xdp_return_frame(txq->tx_buf[i].xdp);
> > + txq->tx_buf[i].xdp = NULL;
> > + }
> > +
> > + /* restore default tx buffer type: FEC_TXBUF_T_SKB */
> > + txq->tx_buf[i].type = FEC_TXBUF_T_SKB;
>
> Here and in the related places below: maybe set ::type dynamically when
> sending to either SKB or XDP instead of setting it only for XDP and then
> restoring each time?
I also considered this method. but when the skb has frags or needs to be TSO,
only the last tx_buf of the skb needs to store the skb pointer, but all the tx_buf
of the skb needs to set the type explicitly, I think it is a bit mess and not concise.
So I restore the type to default when recycle the BDs. Anyway, it;s just a difference
in implement, if you guys insist it's better to set the type explicitly, I will modify
the patch. Thanks!
>
> > }
> > +
> > bdp->cbd_bufaddr = cpu_to_fec32(0);
> > bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
> > }
> [...]
>
> Thanks,
> Olek
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH V2 net 2/4] net: fec: recycle pages for transmitted XDP frames
2023-07-07 1:54 ` Wei Fang
@ 2023-07-10 12:58 ` Alexander Lobakin
0 siblings, 0 replies; 10+ messages in thread
From: Alexander Lobakin @ 2023-07-10 12:58 UTC (permalink / raw)
To: Wei Fang
Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, ast@kernel.org, daniel@iogearbox.net,
hawk@kernel.org, john.fastabend@gmail.com, Shenwei Wang,
Clark Wang, netdev@vger.kernel.org, dl-linux-imx,
linux-kernel@vger.kernel.org, bpf@vger.kernel.org
From: Wei Fang <wei.fang@nxp.com>
Date: Fri, 7 Jul 2023 01:54:04 +0000
>> -----Original Message-----
>> From: Alexander Lobakin <aleksander.lobakin@intel.com>
>> Sent: 2023年7月6日 19:59
>> To: Wei Fang <wei.fang@nxp.com>
>> Cc: davem@davemloft.net; edumazet@google.com; kuba@kernel.org;
>> pabeni@redhat.com; ast@kernel.org; daniel@iogearbox.net;
>> hawk@kernel.org; john.fastabend@gmail.com; Shenwei Wang
>> <shenwei.wang@nxp.com>; Clark Wang <xiaoning.wang@nxp.com>;
>> netdev@vger.kernel.org; dl-linux-imx <linux-imx@nxp.com>;
>> linux-kernel@vger.kernel.org; bpf@vger.kernel.org
>> Subject: Re: [PATCH V2 net 2/4] net: fec: recycle pages for transmitted XDP
>> frames
>>
>> From: Wei Fang <wei.fang@nxp.com>
>> Date: Thu, 6 Jul 2023 16:10:10 +0800
>>
>>> From: Wei Fang <wei.fang@nxp.com>
>>>
>>> Once the XDP frames have been successfully transmitted through the
>>> ndo_xdp_xmit() interface, it's the driver responsibility to free the
>>> frames so that the page_pool can recycle the pages and reuse them.
>>> However, this action is not implemented in the fec driver.
>>> This leads to a user-visible problem that the console will print the
>>> following warning log.
>>
>> [...]
>>
>>> + if (txq->tx_buf[i].xdp) {
>>> + xdp_return_frame(txq->tx_buf[i].xdp);
>>> + txq->tx_buf[i].xdp = NULL;
>>> + }
>>> +
>>> + /* restore default tx buffer type: FEC_TXBUF_T_SKB */
>>> + txq->tx_buf[i].type = FEC_TXBUF_T_SKB;
>>
>> Here and in the related places below: maybe set ::type dynamically when
>> sending to either SKB or XDP instead of setting it only for XDP and then
>> restoring each time?
> I also considered this method. but when the skb has frags or needs to be TSO,
> only the last tx_buf of the skb needs to store the skb pointer, but all the tx_buf
> of the skb needs to set the type explicitly, I think it is a bit mess and not concise.
> So I restore the type to default when recycle the BDs. Anyway, it;s just a difference
> in implement, if you guys insist it's better to set the type explicitly, I will modify
> the patch. Thanks!
Just more of personal preference, no problems. Moreover, your
explanation makes sense to me.
>>
>>> }
>>> +
>>> bdp->cbd_bufaddr = cpu_to_fec32(0);
>>> bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
>>> }
>> [...]
>>
>> Thanks,
>> Olek
Thanks,
Olek
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH V2 net 0/4] net: fec: fix some issues of ndo_xdp_xmit()
2023-07-06 8:10 [PATCH V2 net 0/4] net: fec: fix some issues of ndo_xdp_xmit() wei.fang
` (4 preceding siblings ...)
2023-07-06 11:51 ` [PATCH V2 net 0/4] net: fec: fix some issues of ndo_xdp_xmit() Alexander Lobakin
@ 2023-07-11 8:50 ` patchwork-bot+netdevbpf
5 siblings, 0 replies; 10+ messages in thread
From: patchwork-bot+netdevbpf @ 2023-07-11 8:50 UTC (permalink / raw)
To: Wei Fang
Cc: davem, edumazet, kuba, pabeni, ast, daniel, hawk, john.fastabend,
shenwei.wang, xiaoning.wang, netdev, linux-imx, linux-kernel, bpf
Hello:
This series was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Thu, 6 Jul 2023 16:10:08 +0800 you wrote:
> From: Wei Fang <wei.fang@nxp.com>
>
> We encountered some issues when testing the ndo_xdp_xmit() interface
> of the fec driver on i.MX8MP and i.MX93 platforms. These issues are
> easy to reproduce, and the specific reproduction steps are as follows.
>
> step1: The ethernet port of a board (board A) is connected to the EQOS
> port of i.MX8MP/i.MX93, and the FEC port of i.MX8MP/i.MX93 is connected
> to another ethernet port, such as a switch port.
>
> [...]
Here is the summary with links:
- [V2,net,1/4] net: fec: dynamically set the NETDEV_XDP_ACT_NDO_XMIT feature of XDP
https://git.kernel.org/netdev/net/c/be7ecbe7ec7d
- [V2,net,2/4] net: fec: recycle pages for transmitted XDP frames
https://git.kernel.org/netdev/net/c/20f797399035
- [V2,net,3/4] net: fec: increase the size of tx ring and update tx_wake_threshold
https://git.kernel.org/netdev/net/c/56b3c6ba53d0
- [V2,net,4/4] net: fec: use netdev_err_once() instead of netdev_err()
https://git.kernel.org/netdev/net/c/84a109471987
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2023-07-11 8:50 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-07-06 8:10 [PATCH V2 net 0/4] net: fec: fix some issues of ndo_xdp_xmit() wei.fang
2023-07-06 8:10 ` [PATCH V2 net 1/4] net: fec: dynamically set the NETDEV_XDP_ACT_NDO_XMIT feature of XDP wei.fang
2023-07-06 8:10 ` [PATCH V2 net 2/4] net: fec: recycle pages for transmitted XDP frames wei.fang
2023-07-06 11:59 ` Alexander Lobakin
2023-07-07 1:54 ` Wei Fang
2023-07-10 12:58 ` Alexander Lobakin
2023-07-06 8:10 ` [PATCH V2 net 3/4] net: fec: increase the size of tx ring and update tx_wake_threshold wei.fang
2023-07-06 8:10 ` [PATCH V2 net 4/4] net: fec: use netdev_err_once() instead of netdev_err() wei.fang
2023-07-06 11:51 ` [PATCH V2 net 0/4] net: fec: fix some issues of ndo_xdp_xmit() Alexander Lobakin
2023-07-11 8:50 ` patchwork-bot+netdevbpf
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).