[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <AM6PR0402MB36074BB67E6704F82D2003FBFF6A0@AM6PR0402MB3607.eurprd04.prod.outlook.com>
Date: Fri, 3 Jul 2020 02:45:00 +0000
From: Andy Duan <fugang.duan@....com>
To: Tobias Waldekranz <tobias@...dekranz.com>,
"davem@...emloft.net" <davem@...emloft.net>
CC: "netdev@...r.kernel.org" <netdev@...r.kernel.org>
Subject: RE: [EXT] [PATCH v2 net] net: ethernet: fec: prevent tx starvation
under high rx load
From: Tobias Waldekranz <tobias@...dekranz.com> Sent: Friday, July 3, 2020 4:58 AM
> In the ISR, we poll the event register for the queues in need of service and
> then enter polled mode. After this point, the event register will never be read
> again until we exit polled mode.
>
> In a scenario where a UDP flow is routed back out through the same interface,
> i.e. "router-on-a-stick" we'll typically only see an rx queue event initially.
> Once we start to process the incoming flow we'll be locked polled mode, but
> we'll never clean the tx rings since that event is never caught.
>
> Eventually the netdev watchdog will trip, causing all buffers to be dropped and
> then the process starts over again.
>
> Rework the NAPI poll to keep trying to consome the entire budget as long as
> new events are coming in, making sure to service all rx/tx queues, in priority
> order, on each pass.
>
> Fixes: 4d494cdc92b3 ("net: fec: change data structure to support
> multiqueue")
> Signed-off-by: Tobias Waldekranz <tobias@...dekranz.com>
> ---
>
> v1 -> v2:
> * Always do a full pass over all rx/tx queues as soon as any event is
> received, as suggested by David.
> * Keep dequeuing packets as long as events keep coming in and we're
> under budget.
>
> drivers/net/ethernet/freescale/fec.h | 5 --
> drivers/net/ethernet/freescale/fec_main.c | 94 ++++++++---------------
> 2 files changed, 31 insertions(+), 68 deletions(-)
>
> diff --git a/drivers/net/ethernet/freescale/fec.h
> b/drivers/net/ethernet/freescale/fec.h
> index a6cdd5b61921..d8d76da51c5e 100644
> --- a/drivers/net/ethernet/freescale/fec.h
> +++ b/drivers/net/ethernet/freescale/fec.h
> @@ -525,11 +525,6 @@ struct fec_enet_private {
> unsigned int total_tx_ring_size;
> unsigned int total_rx_ring_size;
>
> - unsigned long work_tx;
> - unsigned long work_rx;
> - unsigned long work_ts;
> - unsigned long work_mdio;
> -
> struct platform_device *pdev;
>
> int dev_id;
> diff --git a/drivers/net/ethernet/freescale/fec_main.c
> b/drivers/net/ethernet/freescale/fec_main.c
> index 2d0d313ee7c5..84589d464850 100644
> --- a/drivers/net/ethernet/freescale/fec_main.c
> +++ b/drivers/net/ethernet/freescale/fec_main.c
> @@ -75,8 +75,6 @@ static void fec_enet_itr_coal_init(struct net_device
> *ndev);
>
> #define DRIVER_NAME "fec"
>
> -#define FEC_ENET_GET_QUQUE(_x) ((_x == 0) ? 1 : ((_x == 1) ? 2 : 0))
> -
> /* Pause frame feild and FIFO threshold */
> #define FEC_ENET_FCE (1 << 5)
> #define FEC_ENET_RSEM_V 0x84
> @@ -1248,8 +1246,6 @@ fec_enet_tx_queue(struct net_device *ndev, u16
> queue_id)
>
> fep = netdev_priv(ndev);
>
> - queue_id = FEC_ENET_GET_QUQUE(queue_id);
> -
> txq = fep->tx_queue[queue_id];
> /* get next bdp of dirty_tx */
> nq = netdev_get_tx_queue(ndev, queue_id); @@ -1340,17
> +1336,14 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id)
> writel(0, txq->bd.reg_desc_active); }
>
> -static void
> -fec_enet_tx(struct net_device *ndev)
> +static void fec_enet_tx(struct net_device *ndev)
> {
> struct fec_enet_private *fep = netdev_priv(ndev);
> - u16 queue_id;
> - /* First process class A queue, then Class B and Best Effort queue */
> - for_each_set_bit(queue_id, &fep->work_tx,
> FEC_ENET_MAX_TX_QS) {
> - clear_bit(queue_id, &fep->work_tx);
> - fec_enet_tx_queue(ndev, queue_id);
> - }
> - return;
> + int i;
> +
> + /* Make sure that AVB queues are processed first. */
> + for (i = fep->num_rx_queues - 1; i >= 0; i--)
In fact, you already change the queue priority comparing before.
Before: queue1 (Audio) > queue2 (video) > queue0 (best effort)
Now: queue2 (video) > queue1 (Audio) > queue0 (best effort)
Other logic seems fine, but you should run stress test to avoid any
block issue since the driver cover more than 20 imx platforms.
Powered by blists - more mailing lists